diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-07-28 08:47:34 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 04:39:32 -0400 |
commit | 4e195a7b78618c89b06547f3140e67a69ec23272 (patch) | |
tree | c371937f6d62e7b6c316ba9507906258b0454d10 | |
parent | 35aec4e2affb99d52b4b744ddb09767eb6e05580 (diff) |
[ALSA] Fix noisy output with shared channel mode with hd-audio
- Fix the wrong initialization of num_dacs when changing the channel
mode between 2 and multi-channel modes. It must be evaluated
after calling snd_hda_ch_mode_put()
- Added the similar check of num_dacs fix in Realtek code.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r-- | sound/pci/hda/patch_analog.c | 8 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 27 |
2 files changed, 29 insertions, 6 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 8955397cca6f..077f1ce01ee1 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1647,10 +1647,12 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
1647 | { | 1647 | { |
1648 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1648 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1649 | struct ad198x_spec *spec = codec->spec; | 1649 | struct ad198x_spec *spec = codec->spec; |
1650 | if (spec->need_dac_fix) | 1650 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
1651 | spec->num_channel_mode, | ||
1652 | &spec->multiout.max_channels); | ||
1653 | if (! err && spec->need_dac_fix) | ||
1651 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | 1654 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; |
1652 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 1655 | return err; |
1653 | spec->num_channel_mode, &spec->multiout.max_channels); | ||
1654 | } | 1656 | } |
1655 | 1657 | ||
1656 | /* 6-stack mode */ | 1658 | /* 6-stack mode */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 378e5f111e34..991f1079116b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -155,6 +155,7 @@ struct alc_spec { | |||
155 | /* channel model */ | 155 | /* channel model */ |
156 | const struct hda_channel_mode *channel_mode; | 156 | const struct hda_channel_mode *channel_mode; |
157 | int num_channel_mode; | 157 | int num_channel_mode; |
158 | int need_dac_fix; | ||
158 | 159 | ||
159 | /* PCM information */ | 160 | /* PCM information */ |
160 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ | 161 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
@@ -192,6 +193,7 @@ struct alc_config_preset { | |||
192 | hda_nid_t dig_in_nid; | 193 | hda_nid_t dig_in_nid; |
193 | unsigned int num_channel_mode; | 194 | unsigned int num_channel_mode; |
194 | const struct hda_channel_mode *channel_mode; | 195 | const struct hda_channel_mode *channel_mode; |
196 | int need_dac_fix; | ||
195 | unsigned int num_mux_defs; | 197 | unsigned int num_mux_defs; |
196 | const struct hda_input_mux *input_mux; | 198 | const struct hda_input_mux *input_mux; |
197 | void (*unsol_event)(struct hda_codec *, unsigned int); | 199 | void (*unsol_event)(struct hda_codec *, unsigned int); |
@@ -264,9 +266,12 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
264 | { | 266 | { |
265 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 267 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
266 | struct alc_spec *spec = codec->spec; | 268 | struct alc_spec *spec = codec->spec; |
267 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 269 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
268 | spec->num_channel_mode, | 270 | spec->num_channel_mode, |
269 | &spec->multiout.max_channels); | 271 | &spec->multiout.max_channels); |
272 | if (! err && spec->need_dac_fix) | ||
273 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
274 | return err; | ||
270 | } | 275 | } |
271 | 276 | ||
272 | /* | 277 | /* |
@@ -546,6 +551,7 @@ static void setup_preset(struct alc_spec *spec, | |||
546 | 551 | ||
547 | spec->channel_mode = preset->channel_mode; | 552 | spec->channel_mode = preset->channel_mode; |
548 | spec->num_channel_mode = preset->num_channel_mode; | 553 | spec->num_channel_mode = preset->num_channel_mode; |
554 | spec->need_dac_fix = preset->need_dac_fix; | ||
549 | 555 | ||
550 | spec->multiout.max_channels = spec->channel_mode[0].channels; | 556 | spec->multiout.max_channels = spec->channel_mode[0].channels; |
551 | 557 | ||
@@ -2278,6 +2284,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2278 | .dac_nids = alc880_dac_nids, | 2284 | .dac_nids = alc880_dac_nids, |
2279 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 2285 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
2280 | .channel_mode = alc880_threestack_modes, | 2286 | .channel_mode = alc880_threestack_modes, |
2287 | .need_dac_fix = 1, | ||
2281 | .input_mux = &alc880_capture_source, | 2288 | .input_mux = &alc880_capture_source, |
2282 | }, | 2289 | }, |
2283 | [ALC880_3ST_DIG] = { | 2290 | [ALC880_3ST_DIG] = { |
@@ -2288,6 +2295,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2288 | .dig_out_nid = ALC880_DIGOUT_NID, | 2295 | .dig_out_nid = ALC880_DIGOUT_NID, |
2289 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 2296 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
2290 | .channel_mode = alc880_threestack_modes, | 2297 | .channel_mode = alc880_threestack_modes, |
2298 | .need_dac_fix = 1, | ||
2291 | .input_mux = &alc880_capture_source, | 2299 | .input_mux = &alc880_capture_source, |
2292 | }, | 2300 | }, |
2293 | [ALC880_TCL_S700] = { | 2301 | [ALC880_TCL_S700] = { |
@@ -2380,6 +2388,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2380 | .dac_nids = alc880_asus_dac_nids, | 2388 | .dac_nids = alc880_asus_dac_nids, |
2381 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | 2389 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2382 | .channel_mode = alc880_asus_modes, | 2390 | .channel_mode = alc880_asus_modes, |
2391 | .need_dac_fix = 1, | ||
2383 | .input_mux = &alc880_capture_source, | 2392 | .input_mux = &alc880_capture_source, |
2384 | }, | 2393 | }, |
2385 | [ALC880_ASUS_DIG] = { | 2394 | [ALC880_ASUS_DIG] = { |
@@ -2391,6 +2400,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2391 | .dig_out_nid = ALC880_DIGOUT_NID, | 2400 | .dig_out_nid = ALC880_DIGOUT_NID, |
2392 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | 2401 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2393 | .channel_mode = alc880_asus_modes, | 2402 | .channel_mode = alc880_asus_modes, |
2403 | .need_dac_fix = 1, | ||
2394 | .input_mux = &alc880_capture_source, | 2404 | .input_mux = &alc880_capture_source, |
2395 | }, | 2405 | }, |
2396 | [ALC880_ASUS_DIG2] = { | 2406 | [ALC880_ASUS_DIG2] = { |
@@ -2402,6 +2412,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2402 | .dig_out_nid = ALC880_DIGOUT_NID, | 2412 | .dig_out_nid = ALC880_DIGOUT_NID, |
2403 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | 2413 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2404 | .channel_mode = alc880_asus_modes, | 2414 | .channel_mode = alc880_asus_modes, |
2415 | .need_dac_fix = 1, | ||
2405 | .input_mux = &alc880_capture_source, | 2416 | .input_mux = &alc880_capture_source, |
2406 | }, | 2417 | }, |
2407 | [ALC880_ASUS_W1V] = { | 2418 | [ALC880_ASUS_W1V] = { |
@@ -2413,6 +2424,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2413 | .dig_out_nid = ALC880_DIGOUT_NID, | 2424 | .dig_out_nid = ALC880_DIGOUT_NID, |
2414 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | 2425 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2415 | .channel_mode = alc880_asus_modes, | 2426 | .channel_mode = alc880_asus_modes, |
2427 | .need_dac_fix = 1, | ||
2416 | .input_mux = &alc880_capture_source, | 2428 | .input_mux = &alc880_capture_source, |
2417 | }, | 2429 | }, |
2418 | [ALC880_UNIWILL_DIG] = { | 2430 | [ALC880_UNIWILL_DIG] = { |
@@ -2423,6 +2435,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2423 | .dig_out_nid = ALC880_DIGOUT_NID, | 2435 | .dig_out_nid = ALC880_DIGOUT_NID, |
2424 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | 2436 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2425 | .channel_mode = alc880_asus_modes, | 2437 | .channel_mode = alc880_asus_modes, |
2438 | .need_dac_fix = 1, | ||
2426 | .input_mux = &alc880_capture_source, | 2439 | .input_mux = &alc880_capture_source, |
2427 | }, | 2440 | }, |
2428 | [ALC880_CLEVO] = { | 2441 | [ALC880_CLEVO] = { |
@@ -2434,6 +2447,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2434 | .hp_nid = 0x03, | 2447 | .hp_nid = 0x03, |
2435 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 2448 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
2436 | .channel_mode = alc880_threestack_modes, | 2449 | .channel_mode = alc880_threestack_modes, |
2450 | .need_dac_fix = 1, | ||
2437 | .input_mux = &alc880_capture_source, | 2451 | .input_mux = &alc880_capture_source, |
2438 | }, | 2452 | }, |
2439 | [ALC880_LG] = { | 2453 | [ALC880_LG] = { |
@@ -2445,6 +2459,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2445 | .dig_out_nid = ALC880_DIGOUT_NID, | 2459 | .dig_out_nid = ALC880_DIGOUT_NID, |
2446 | .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), | 2460 | .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), |
2447 | .channel_mode = alc880_lg_ch_modes, | 2461 | .channel_mode = alc880_lg_ch_modes, |
2462 | .need_dac_fix = 1, | ||
2448 | .input_mux = &alc880_lg_capture_source, | 2463 | .input_mux = &alc880_lg_capture_source, |
2449 | .unsol_event = alc880_lg_unsol_event, | 2464 | .unsol_event = alc880_lg_unsol_event, |
2450 | .init_hook = alc880_lg_automute, | 2465 | .init_hook = alc880_lg_automute, |
@@ -4437,6 +4452,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
4437 | .dig_in_nid = ALC882_DIGIN_NID, | 4452 | .dig_in_nid = ALC882_DIGIN_NID, |
4438 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | 4453 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), |
4439 | .channel_mode = alc882_ch_modes, | 4454 | .channel_mode = alc882_ch_modes, |
4455 | .need_dac_fix = 1, | ||
4440 | .input_mux = &alc882_capture_source, | 4456 | .input_mux = &alc882_capture_source, |
4441 | }, | 4457 | }, |
4442 | [ALC882_6ST_DIG] = { | 4458 | [ALC882_6ST_DIG] = { |
@@ -5075,6 +5091,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
5075 | .dig_in_nid = ALC883_DIGIN_NID, | 5091 | .dig_in_nid = ALC883_DIGIN_NID, |
5076 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | 5092 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), |
5077 | .channel_mode = alc883_3ST_6ch_modes, | 5093 | .channel_mode = alc883_3ST_6ch_modes, |
5094 | .need_dac_fix = 1, | ||
5078 | .input_mux = &alc883_capture_source, | 5095 | .input_mux = &alc883_capture_source, |
5079 | }, | 5096 | }, |
5080 | [ALC883_3ST_6ch] = { | 5097 | [ALC883_3ST_6ch] = { |
@@ -5086,6 +5103,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
5086 | .adc_nids = alc883_adc_nids, | 5103 | .adc_nids = alc883_adc_nids, |
5087 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | 5104 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), |
5088 | .channel_mode = alc883_3ST_6ch_modes, | 5105 | .channel_mode = alc883_3ST_6ch_modes, |
5106 | .need_dac_fix = 1, | ||
5089 | .input_mux = &alc883_capture_source, | 5107 | .input_mux = &alc883_capture_source, |
5090 | }, | 5108 | }, |
5091 | [ALC883_6ST_DIG] = { | 5109 | [ALC883_6ST_DIG] = { |
@@ -6554,6 +6572,7 @@ static struct alc_config_preset alc861_presets[] = { | |||
6554 | .dac_nids = alc861_dac_nids, | 6572 | .dac_nids = alc861_dac_nids, |
6555 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | 6573 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), |
6556 | .channel_mode = alc861_threestack_modes, | 6574 | .channel_mode = alc861_threestack_modes, |
6575 | .need_dac_fix = 1, | ||
6557 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | 6576 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), |
6558 | .adc_nids = alc861_adc_nids, | 6577 | .adc_nids = alc861_adc_nids, |
6559 | .input_mux = &alc861_capture_source, | 6578 | .input_mux = &alc861_capture_source, |
@@ -6566,6 +6585,7 @@ static struct alc_config_preset alc861_presets[] = { | |||
6566 | .dig_out_nid = ALC861_DIGOUT_NID, | 6585 | .dig_out_nid = ALC861_DIGOUT_NID, |
6567 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | 6586 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), |
6568 | .channel_mode = alc861_threestack_modes, | 6587 | .channel_mode = alc861_threestack_modes, |
6588 | .need_dac_fix = 1, | ||
6569 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | 6589 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), |
6570 | .adc_nids = alc861_adc_nids, | 6590 | .adc_nids = alc861_adc_nids, |
6571 | .input_mux = &alc861_capture_source, | 6591 | .input_mux = &alc861_capture_source, |
@@ -6589,6 +6609,7 @@ static struct alc_config_preset alc861_presets[] = { | |||
6589 | .dac_nids = alc660_dac_nids, | 6609 | .dac_nids = alc660_dac_nids, |
6590 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | 6610 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), |
6591 | .channel_mode = alc861_threestack_modes, | 6611 | .channel_mode = alc861_threestack_modes, |
6612 | .need_dac_fix = 1, | ||
6592 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | 6613 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), |
6593 | .adc_nids = alc861_adc_nids, | 6614 | .adc_nids = alc861_adc_nids, |
6594 | .input_mux = &alc861_capture_source, | 6615 | .input_mux = &alc861_capture_source, |