aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiang Zhe <zhe.jiang@intel.com>2007-11-12 06:57:03 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:21 -0500
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 e02d3bac2096..992568368ef4 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
2135{ 2135{
2136 struct sigmatel_spec *spec = codec->spec; 2136 struct sigmatel_spec *spec = codec->spec;
2137 int err; 2137 int err;
2138 int hp_speaker_swap = 0;
2138 2139
2139 if ((err = snd_hda_parse_pin_def_config(codec, 2140 if ((err = snd_hda_parse_pin_def_config(codec,
2140 &spec->autocfg, 2141 &spec->autocfg,
@@ -2143,6 +2144,24 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2143 if (! spec->autocfg.line_outs) 2144 if (! spec->autocfg.line_outs)
2144 return 0; /* can't find valid pin config */ 2145 return 0; /* can't find valid pin config */
2145 2146
2147 /* If we have no real line-out pin and multiple hp-outs, HPs should
2148 * be set up as multi-channel outputs.
2149 */
2150 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
2151 spec->autocfg.hp_outs > 1) {
2152 /* Copy hp_outs to line_outs, backup line_outs in
2153 * speaker_outs so that the following routines can handle
2154 * HP pins as primary outputs.
2155 */
2156 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
2157 sizeof(spec->autocfg.line_out_pins));
2158 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
2159 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
2160 sizeof(spec->autocfg.hp_pins));
2161 spec->autocfg.line_outs = spec->autocfg.hp_outs;
2162 hp_speaker_swap = 1;
2163 }
2164
2146 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 2165 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2147 return err; 2166 return err;
2148 if (spec->multiout.num_dacs == 0) 2167 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
2154 if (err < 0) 2173 if (err < 0)
2155 return err; 2174 return err;
2156 2175
2176 if (hp_speaker_swap == 1) {
2177 /* Restore the hp_outs and line_outs */
2178 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
2179 sizeof(spec->autocfg.line_out_pins));
2180 spec->autocfg.hp_outs = spec->autocfg.line_outs;
2181 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
2182 sizeof(spec->autocfg.speaker_pins));
2183 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
2184 memset(spec->autocfg.speaker_pins, 0,
2185 sizeof(spec->autocfg.speaker_pins));
2186 spec->autocfg.speaker_outs = 0;
2187 }
2188
2157 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); 2189 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
2158 2190
2159 if (err < 0) 2191 if (err < 0)