aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c167
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 */
2033static 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
5193static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 5189static 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
6516static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 6516static 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;