diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 167 |
1 files changed, 87 insertions, 80 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 39c08bb670d1..63011133e3fb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -442,8 +442,9 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, | |||
442 | change = pinctl != alc_pin_mode_values[val]; | 442 | change = pinctl != alc_pin_mode_values[val]; |
443 | if (change) { | 443 | if (change) { |
444 | /* Set pin mode to that requested */ | 444 | /* Set pin mode to that requested */ |
445 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, | 445 | snd_hda_codec_write_cache(codec, nid, 0, |
446 | alc_pin_mode_values[val]); | 446 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
447 | alc_pin_mode_values[val]); | ||
447 | 448 | ||
448 | /* Also enable the retasking pin's input/output as required | 449 | /* Also enable the retasking pin's input/output as required |
449 | * for the requested pin mode. Enum values of 2 or less are | 450 | * for the requested pin mode. Enum values of 2 or less are |
@@ -456,19 +457,23 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, | |||
456 | * this turns out to be necessary in the future. | 457 | * this turns out to be necessary in the future. |
457 | */ | 458 | */ |
458 | if (val <= 2) { | 459 | if (val <= 2) { |
459 | snd_hda_codec_write(codec, nid, 0, | 460 | snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, |
460 | AC_VERB_SET_AMP_GAIN_MUTE, | 461 | 0x80, 0x80); |
461 | AMP_OUT_MUTE); | 462 | snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, |
462 | snd_hda_codec_write(codec, nid, 0, | 463 | 0x80, 0x80); |
463 | AC_VERB_SET_AMP_GAIN_MUTE, | 464 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0, |
464 | AMP_IN_UNMUTE(0)); | 465 | 0x80, 0x00); |
466 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0, | ||
467 | 0x80, 0x00); | ||
465 | } else { | 468 | } else { |
466 | snd_hda_codec_write(codec, nid, 0, | 469 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0, |
467 | AC_VERB_SET_AMP_GAIN_MUTE, | 470 | 0x80, 0x80); |
468 | AMP_IN_MUTE(0)); | 471 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0, |
469 | snd_hda_codec_write(codec, nid, 0, | 472 | 0x80, 0x80); |
470 | AC_VERB_SET_AMP_GAIN_MUTE, | 473 | snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, |
471 | AMP_OUT_UNMUTE); | 474 | 0x80, 0x00); |
475 | snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, | ||
476 | 0x80, 0x00); | ||
472 | } | 477 | } |
473 | } | 478 | } |
474 | return change; | 479 | return change; |
@@ -520,7 +525,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, | |||
520 | gpio_data &= ~mask; | 525 | gpio_data &= ~mask; |
521 | else | 526 | else |
522 | gpio_data |= mask; | 527 | gpio_data |= mask; |
523 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); | 528 | snd_hda_codec_write_cache(codec, nid, 0, |
529 | AC_VERB_SET_GPIO_DATA, gpio_data); | ||
524 | 530 | ||
525 | return change; | 531 | return change; |
526 | } | 532 | } |
@@ -573,8 +579,8 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, | |||
573 | ctrl_data &= ~mask; | 579 | ctrl_data &= ~mask; |
574 | else | 580 | else |
575 | ctrl_data |= mask; | 581 | ctrl_data |= mask; |
576 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | 582 | snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, |
577 | ctrl_data); | 583 | ctrl_data); |
578 | 584 | ||
579 | return change; | 585 | return change; |
580 | } | 586 | } |
@@ -2026,27 +2032,6 @@ static void alc_unsol_event(struct hda_codec *codec, unsigned int res) | |||
2026 | spec->unsol_event(codec, res); | 2032 | spec->unsol_event(codec, res); |
2027 | } | 2033 | } |
2028 | 2034 | ||
2029 | #ifdef CONFIG_PM | ||
2030 | /* | ||
2031 | * resume | ||
2032 | */ | ||
2033 | static int alc_resume(struct hda_codec *codec) | ||
2034 | { | ||
2035 | struct alc_spec *spec = codec->spec; | ||
2036 | int i; | ||
2037 | |||
2038 | alc_init(codec); | ||
2039 | for (i = 0; i < spec->num_mixers; i++) | ||
2040 | snd_hda_resume_ctls(codec, spec->mixers[i]); | ||
2041 | if (spec->multiout.dig_out_nid) | ||
2042 | snd_hda_resume_spdif_out(codec); | ||
2043 | if (spec->dig_in_nid) | ||
2044 | snd_hda_resume_spdif_in(codec); | ||
2045 | |||
2046 | return 0; | ||
2047 | } | ||
2048 | #endif | ||
2049 | |||
2050 | /* | 2035 | /* |
2051 | * Analog playback callbacks | 2036 | * Analog playback callbacks |
2052 | */ | 2037 | */ |
@@ -2278,9 +2263,6 @@ static struct hda_codec_ops alc_patch_ops = { | |||
2278 | .init = alc_init, | 2263 | .init = alc_init, |
2279 | .free = alc_free, | 2264 | .free = alc_free, |
2280 | .unsol_event = alc_unsol_event, | 2265 | .unsol_event = alc_unsol_event, |
2281 | #ifdef CONFIG_PM | ||
2282 | .resume = alc_resume, | ||
2283 | #endif | ||
2284 | }; | 2266 | }; |
2285 | 2267 | ||
2286 | 2268 | ||
@@ -2377,11 +2359,15 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, | |||
2377 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 2359 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
2378 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; | 2360 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; |
2379 | if (old_ctl != new_ctl) { | 2361 | if (old_ctl != new_ctl) { |
2380 | snd_hda_codec_write(codec, nid, 0, | 2362 | int val; |
2381 | AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); | 2363 | snd_hda_codec_write_cache(codec, nid, 0, |
2382 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 2364 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
2383 | (ucontrol->value.enumerated.item[0] >= 3 ? | 2365 | new_ctl); |
2384 | 0xb080 : 0xb000)); | 2366 | val = ucontrol->value.enumerated.item[0] >= 3 ? 0x80 : 0x00; |
2367 | snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, | ||
2368 | 0x80, val); | ||
2369 | snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, | ||
2370 | 0x80, val); | ||
2385 | return 1; | 2371 | return 1; |
2386 | } | 2372 | } |
2387 | return 0; | 2373 | return 0; |
@@ -2424,7 +2410,8 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, | |||
2424 | sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; | 2410 | sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; |
2425 | if (ucontrol->value.enumerated.item[0] != sel) { | 2411 | if (ucontrol->value.enumerated.item[0] != sel) { |
2426 | sel = ucontrol->value.enumerated.item[0] & 3; | 2412 | sel = ucontrol->value.enumerated.item[0] & 3; |
2427 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel); | 2413 | snd_hda_codec_write_cache(codec, nid, 0, |
2414 | AC_VERB_SET_CONNECT_SEL, sel); | ||
2428 | return 1; | 2415 | return 1; |
2429 | } | 2416 | } |
2430 | return 0; | 2417 | return 0; |
@@ -4054,13 +4041,17 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec) | |||
4054 | present = snd_hda_codec_read(codec, 0x0f, 0, | 4041 | present = snd_hda_codec_read(codec, 0x0f, 0, |
4055 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 4042 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
4056 | if (present) { | 4043 | if (present) { |
4057 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); | 4044 | snd_hda_codec_write_cache(codec, 0x01, 0, |
4058 | snd_hda_codec_write(codec, 0x0f, 0, | 4045 | AC_VERB_SET_GPIO_DATA, 1); |
4059 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | 4046 | snd_hda_codec_write_cache(codec, 0x0f, 0, |
4047 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
4048 | PIN_HP); | ||
4060 | } else { | 4049 | } else { |
4061 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | 4050 | snd_hda_codec_write_cache(codec, 0x01, 0, |
4062 | snd_hda_codec_write(codec, 0x0f, 0, | 4051 | AC_VERB_SET_GPIO_DATA, 0); |
4063 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 4052 | snd_hda_codec_write_cache(codec, 0x0f, 0, |
4053 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
4054 | PIN_OUT); | ||
4064 | } | 4055 | } |
4065 | } | 4056 | } |
4066 | 4057 | ||
@@ -4797,12 +4788,16 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
4797 | idx = ucontrol->value.enumerated.item[0]; | 4788 | idx = ucontrol->value.enumerated.item[0]; |
4798 | if (idx >= imux->num_items) | 4789 | if (idx >= imux->num_items) |
4799 | idx = imux->num_items - 1; | 4790 | idx = imux->num_items - 1; |
4800 | if (*cur_val == idx && !codec->in_resume) | 4791 | if (*cur_val == idx) |
4801 | return 0; | 4792 | return 0; |
4802 | for (i = 0; i < imux->num_items; i++) { | 4793 | for (i = 0; i < imux->num_items; i++) { |
4803 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 4794 | unsigned int v = (i == idx) ? 0x00 : 0x80; |
4804 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 4795 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, |
4805 | v | (imux->items[i].index << 8)); | 4796 | imux->items[i].index, |
4797 | 0x80, v); | ||
4798 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, | ||
4799 | imux->items[i].index, | ||
4800 | 0x80, v); | ||
4806 | } | 4801 | } |
4807 | *cur_val = idx; | 4802 | *cur_val = idx; |
4808 | return 1; | 4803 | return 1; |
@@ -5187,7 +5182,8 @@ static void alc882_targa_automute(struct hda_codec *codec) | |||
5187 | 0x80, present ? 0x80 : 0); | 5182 | 0x80, present ? 0x80 : 0); |
5188 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | 5183 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, |
5189 | 0x80, present ? 0x80 : 0); | 5184 | 0x80, present ? 0x80 : 0); |
5190 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); | 5185 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
5186 | present ? 1 : 3); | ||
5191 | } | 5187 | } |
5192 | 5188 | ||
5193 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | 5189 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -5777,12 +5773,16 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
5777 | idx = ucontrol->value.enumerated.item[0]; | 5773 | idx = ucontrol->value.enumerated.item[0]; |
5778 | if (idx >= imux->num_items) | 5774 | if (idx >= imux->num_items) |
5779 | idx = imux->num_items - 1; | 5775 | idx = imux->num_items - 1; |
5780 | if (*cur_val == idx && !codec->in_resume) | 5776 | if (*cur_val == idx) |
5781 | return 0; | 5777 | return 0; |
5782 | for (i = 0; i < imux->num_items; i++) { | 5778 | for (i = 0; i < imux->num_items; i++) { |
5783 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 5779 | unsigned int v = (i == idx) ? 0x00 : 0x80; |
5784 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 5780 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, |
5785 | v | (imux->items[i].index << 8)); | 5781 | imux->items[i].index, |
5782 | 0x80, v); | ||
5783 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, | ||
5784 | imux->items[i].index, | ||
5785 | 0x80, v); | ||
5786 | } | 5786 | } |
5787 | *cur_val = idx; | 5787 | *cur_val = idx; |
5788 | return 1; | 5788 | return 1; |
@@ -6509,8 +6509,8 @@ static void alc883_tagra_automute(struct hda_codec *codec) | |||
6509 | 0x80, bits); | 6509 | 0x80, bits); |
6510 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | 6510 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, |
6511 | 0x80, bits); | 6511 | 0x80, bits); |
6512 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, | 6512 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
6513 | present ? 1 : 3); | 6513 | present ? 1 : 3); |
6514 | } | 6514 | } |
6515 | 6515 | ||
6516 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | 6516 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -7510,8 +7510,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, | |||
7510 | 0x80, valp[0] ? 0 : 0x80); | 7510 | 0x80, valp[0] ? 0 : 0x80); |
7511 | change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | 7511 | change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, |
7512 | 0x80, valp[1] ? 0 : 0x80); | 7512 | 0x80, valp[1] ? 0 : 0x80); |
7513 | if (change || codec->in_resume) | 7513 | if (change) |
7514 | alc262_fujitsu_automute(codec, codec->in_resume); | 7514 | alc262_fujitsu_automute(codec, 0); |
7515 | return change; | 7515 | return change; |
7516 | } | 7516 | } |
7517 | 7517 | ||
@@ -8328,14 +8328,17 @@ static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
8328 | idx = ucontrol->value.enumerated.item[0]; | 8328 | idx = ucontrol->value.enumerated.item[0]; |
8329 | if (idx >= imux->num_items) | 8329 | if (idx >= imux->num_items) |
8330 | idx = imux->num_items - 1; | 8330 | idx = imux->num_items - 1; |
8331 | if (*cur_val == idx && !codec->in_resume) | 8331 | if (*cur_val == idx) |
8332 | return 0; | 8332 | return 0; |
8333 | for (i = 0; i < imux->num_items; i++) { | 8333 | for (i = 0; i < imux->num_items; i++) { |
8334 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 8334 | unsigned int v = (i == idx) ? 0x00 : 0x80; |
8335 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 8335 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, |
8336 | v | (imux->items[i].index << 8)); | 8336 | imux->items[i].index, 0x80, v); |
8337 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, | 8337 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, |
8338 | idx ); | 8338 | imux->items[i].index, 0x80, v); |
8339 | snd_hda_codec_write_cache(codec, nid, 0, | ||
8340 | AC_VERB_SET_CONNECT_SEL, | ||
8341 | idx ); | ||
8339 | } | 8342 | } |
8340 | *cur_val = idx; | 8343 | *cur_val = idx; |
8341 | return 1; | 8344 | return 1; |
@@ -9916,12 +9919,14 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
9916 | idx = ucontrol->value.enumerated.item[0]; | 9919 | idx = ucontrol->value.enumerated.item[0]; |
9917 | if (idx >= imux->num_items) | 9920 | if (idx >= imux->num_items) |
9918 | idx = imux->num_items - 1; | 9921 | idx = imux->num_items - 1; |
9919 | if (*cur_val == idx && !codec->in_resume) | 9922 | if (*cur_val == idx) |
9920 | return 0; | 9923 | return 0; |
9921 | for (i = 0; i < imux->num_items; i++) { | 9924 | for (i = 0; i < imux->num_items; i++) { |
9922 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 9925 | unsigned int v = (i == idx) ? 0x00 : 0x80; |
9923 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 9926 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, |
9924 | v | (imux->items[i].index << 8)); | 9927 | imux->items[i].index, 0x80, v); |
9928 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, | ||
9929 | imux->items[i].index, 0x80, v); | ||
9925 | } | 9930 | } |
9926 | *cur_val = idx; | 9931 | *cur_val = idx; |
9927 | return 1; | 9932 | return 1; |
@@ -10847,12 +10852,14 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
10847 | idx = ucontrol->value.enumerated.item[0]; | 10852 | idx = ucontrol->value.enumerated.item[0]; |
10848 | if (idx >= imux->num_items) | 10853 | if (idx >= imux->num_items) |
10849 | idx = imux->num_items - 1; | 10854 | idx = imux->num_items - 1; |
10850 | if (*cur_val == idx && !codec->in_resume) | 10855 | if (*cur_val == idx) |
10851 | return 0; | 10856 | return 0; |
10852 | for (i = 0; i < imux->num_items; i++) { | 10857 | for (i = 0; i < imux->num_items; i++) { |
10853 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 10858 | unsigned int v = (i == idx) ? 0x00 : 0x80; |
10854 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 10859 | snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, |
10855 | v | (imux->items[i].index << 8)); | 10860 | imux->items[i].index, 0x80, v); |
10861 | snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, | ||
10862 | imux->items[i].index, 0x80, v); | ||
10856 | } | 10863 | } |
10857 | *cur_val = idx; | 10864 | *cur_val = idx; |
10858 | return 1; | 10865 | return 1; |