summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiang Zhe <zhe.jiang@intel.com>2007-11-12 12:57:03 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:21 +0100
commitbcecd9bd96a5ba598e4b671a55f05b32284987da (patch)
tree105b5ba6f7bfbd23615520c638d688b2840b14b4
parent7f9310c1c98abfd85d070f9122695901531e48a4 (diff)
[ALSA] hda-codec - Add workaround for multiple HPs
Dell laptops have multiple HP jacks that can be used for multi-channel outputs. The current auto pincfg handles the speaker as the primary output and thus cannot handle the multi-channel configuration for such cases. This patch adds a workaround to fix this issue by swapping the HP and speaker during multi-channel setup routines. Signed-off-by: Jiang Zhe <zhe.jiang@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--sound/pci/hda/patch_sigmatel.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e02d3bac209..992568368ef 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2135,6 +2135,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
{
struct sigmatel_spec *spec = codec->spec;
int err;
+ int hp_speaker_swap = 0;
if ((err = snd_hda_parse_pin_def_config(codec,
&spec->autocfg,
@@ -2143,6 +2144,24 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
if (! spec->autocfg.line_outs)
return 0; /* can't find valid pin config */
+ /* If we have no real line-out pin and multiple hp-outs, HPs should
+ * be set up as multi-channel outputs.
+ */
+ if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
+ spec->autocfg.hp_outs > 1) {
+ /* Copy hp_outs to line_outs, backup line_outs in
+ * speaker_outs so that the following routines can handle
+ * HP pins as primary outputs.
+ */
+ memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
+ sizeof(spec->autocfg.line_out_pins));
+ spec->autocfg.speaker_outs = spec->autocfg.line_outs;
+ memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
+ sizeof(spec->autocfg.hp_pins));
+ spec->autocfg.line_outs = spec->autocfg.hp_outs;
+ hp_speaker_swap = 1;
+ }
+
if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
return err;
if (spec->multiout.num_dacs == 0)
@@ -2154,6 +2173,19 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
if (err < 0)
return err;
+ if (hp_speaker_swap == 1) {
+ /* Restore the hp_outs and line_outs */
+ memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
+ sizeof(spec->autocfg.line_out_pins));
+ spec->autocfg.hp_outs = spec->autocfg.line_outs;
+ memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
+ sizeof(spec->autocfg.speaker_pins));
+ spec->autocfg.line_outs = spec->autocfg.speaker_outs;
+ memset(spec->autocfg.speaker_pins, 0,
+ sizeof(spec->autocfg.speaker_pins));
+ spec->autocfg.speaker_outs = 0;
+ }
+
err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
if (err < 0)