From bcecd9bd96a5ba598e4b671a55f05b32284987da Mon Sep 17 00:00:00 2001 From: Jiang Zhe Date: Mon, 12 Nov 2007 12:57:03 +0100 Subject: [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 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) 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) -- cgit v1.2.3-70-g09d2