summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_generic.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-04-30 09:00:33 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-30 09:00:33 -0300
commitaad797c89903d570c17f6affc770eb98afd74e62 (patch)
treebddefd4242b0efba1068b5260f831c2697ba4037 /sound/pci/hda/hda_generic.c
parentc95789ecd5a979fd718ae09763df3fa50dd97a91 (diff)
parentc1be5a5b1b355d40e6cf79cc979eb66dafa24ad1 (diff)
Merge tag 'v3.9' into v4l_for_linus
Linux 3.9 * tag 'v3.9': (1099 commits) Linux 3.9 vm: add no-mmu vm_iomap_memory() stub efivars: only check for duplicates on the registered list TTY: fix atime/mtime regression aio: fix possible invalid memory access when DEBUG is enabled parisc: use spin_lock_irqsave/spin_unlock_irqrestore for PTE updates parisc: disable -mlong-calls compiler option for kernel modules parisc: uaccess: fix compiler warnings caused by __put_user casting parisc: Change kunmap macro to static inline function parisc: Provide __ucmpdi2 to resolve undefined references in 32 bit builds. sparc64: Fix missing put_cpu_var() in tlb_batch_add_one() when not batching. Revert "gpio: pxa: set initcall level to module init" efi: Check EFI revision in setup_efi_vars x86, efi: Fix a build warning Revert "MIPS: page.h: Provide more readable definition for PAGE_MASK." kernel/hz.bc: ignore. Linux 3.9-rc8 events: Protect access via task_subsys_state_check() net: fix incorrect credentials passing x86, microcode: Verify the family before dispatching microcode patching ...
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r--sound/pci/hda/hda_generic.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 78897d05d80..2dbe767be16 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -740,7 +740,7 @@ EXPORT_SYMBOL_HDA(snd_hda_activate_path);
static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
{
struct hda_gen_spec *spec = codec->spec;
- bool changed;
+ bool changed = false;
int i;
if (!spec->power_down_unused || path->active)
@@ -995,6 +995,8 @@ enum {
BAD_NO_EXTRA_SURR_DAC = 0x101,
/* Primary DAC shared with main surrounds */
BAD_SHARED_SURROUND = 0x100,
+ /* No independent HP possible */
+ BAD_NO_INDEP_HP = 0x40,
/* Primary DAC shared with main CLFE */
BAD_SHARED_CLFE = 0x10,
/* Primary DAC shared with extra surrounds */
@@ -1392,6 +1394,43 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
return snd_hda_get_path_idx(codec, path);
}
+/* check whether the independent HP is available with the current config */
+static bool indep_hp_possible(struct hda_codec *codec)
+{
+ struct hda_gen_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ struct nid_path *path;
+ int i, idx;
+
+ if (cfg->line_out_type == AUTO_PIN_HP_OUT)
+ idx = spec->out_paths[0];
+ else
+ idx = spec->hp_paths[0];
+ path = snd_hda_get_path_from_idx(codec, idx);
+ if (!path)
+ return false;
+
+ /* assume no path conflicts unless aamix is involved */
+ if (!spec->mixer_nid || !is_nid_contained(path, spec->mixer_nid))
+ return true;
+
+ /* check whether output paths contain aamix */
+ for (i = 0; i < cfg->line_outs; i++) {
+ if (spec->out_paths[i] == idx)
+ break;
+ path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
+ if (path && is_nid_contained(path, spec->mixer_nid))
+ return false;
+ }
+ for (i = 0; i < cfg->speaker_outs; i++) {
+ path = snd_hda_get_path_from_idx(codec, spec->speaker_paths[i]);
+ if (path && is_nid_contained(path, spec->mixer_nid))
+ return false;
+ }
+
+ return true;
+}
+
/* fill the empty entries in the dac array for speaker/hp with the
* shared dac pointed by the paths
*/
@@ -1545,6 +1584,9 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
badness += BAD_MULTI_IO;
}
+ if (spec->indep_hp && !indep_hp_possible(codec))
+ badness += BAD_NO_INDEP_HP;
+
/* re-fill the shared DAC for speaker / headphone */
if (cfg->line_out_type != AUTO_PIN_HP_OUT)
refill_shared_dacs(codec, cfg->hp_outs,
@@ -1758,6 +1800,10 @@ static int parse_output_paths(struct hda_codec *codec)
cfg->speaker_pins, val);
}
+ /* clear indep_hp flag if not available */
+ if (spec->indep_hp && !indep_hp_possible(codec))
+ spec->indep_hp = 0;
+
kfree(best_cfg);
return 0;
}