diff options
author | Jiang Zhe <zhe.jiang@intel.com> | 2007-11-12 12:57:03 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 17:29:21 +0100 |
commit | bcecd9bd96a5ba598e4b671a55f05b32284987da (patch) | |
tree | 105b5ba6f7bfbd23615520c638d688b2840b14b4 | |
parent | 7f9310c1c98abfd85d070f9122695901531e48a4 (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.c | 32 |
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) |