aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/azt3328.c3
-rw-r--r--sound/pci/hda/hda_codec.c14
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_jack.c24
-rw-r--r--sound/pci/hda/patch_ca0132.c33
-rw-r--r--sound/pci/hda/patch_cirrus.c10
-rw-r--r--sound/pci/hda/patch_conexant.c24
-rw-r--r--sound/pci/hda/patch_realtek.c114
-rw-r--r--sound/pci/hda/patch_sigmatel.c6
-rw-r--r--sound/pci/hda/patch_via.c287
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c25
12 files changed, 314 insertions, 235 deletions
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 95ffa6a9db6..496f14c1a73 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2684,10 +2684,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2684 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 2684 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2685 if (err < 0) 2685 if (err < 0)
2686 goto out_err; 2686 goto out_err;
2687 opl3->private_data = chip;
2687 } 2688 }
2688 2689
2689 opl3->private_data = chip;
2690
2691 sprintf(card->longname, "%s at 0x%lx, irq %i", 2690 sprintf(card->longname, "%s at 0x%lx, irq %i",
2692 card->shortname, chip->ctrl_io, chip->irq); 2691 card->shortname, chip->ctrl_io, chip->irq);
2693 2692
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 4df72c0e8c3..684307372d7 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1447,7 +1447,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1447 for (i = 0; i < c->cvt_setups.used; i++) { 1447 for (i = 0; i < c->cvt_setups.used; i++) {
1448 p = snd_array_elem(&c->cvt_setups, i); 1448 p = snd_array_elem(&c->cvt_setups, i);
1449 if (!p->active && p->stream_tag == stream_tag && 1449 if (!p->active && p->stream_tag == stream_tag &&
1450 get_wcaps_type(get_wcaps(codec, p->nid)) == type) 1450 get_wcaps_type(get_wcaps(c, p->nid)) == type)
1451 p->dirty = 1; 1451 p->dirty = 1;
1452 } 1452 }
1453 } 1453 }
@@ -1759,7 +1759,11 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
1759 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; 1759 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
1760 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; 1760 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
1761 parm |= index << AC_AMP_SET_INDEX_SHIFT; 1761 parm |= index << AC_AMP_SET_INDEX_SHIFT;
1762 parm |= val; 1762 if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
1763 (info->amp_caps & AC_AMPCAP_MIN_MUTE))
1764 ; /* set the zero value as a fake mute */
1765 else
1766 parm |= val;
1763 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); 1767 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
1764 info->vol[ch] = val; 1768 info->vol[ch] = val;
1765} 1769}
@@ -2026,7 +2030,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2026 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); 2030 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
2027 val1 += ofs; 2031 val1 += ofs;
2028 val1 = ((int)val1) * ((int)val2); 2032 val1 = ((int)val1) * ((int)val2);
2029 if (min_mute) 2033 if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
2030 val2 |= TLV_DB_SCALE_MUTE; 2034 val2 |= TLV_DB_SCALE_MUTE;
2031 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) 2035 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
2032 return -EFAULT; 2036 return -EFAULT;
@@ -5114,7 +5118,7 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
5114 const char *pfx = "", *sfx = ""; 5118 const char *pfx = "", *sfx = "";
5115 5119
5116 /* handle as a speaker if it's a fixed line-out */ 5120 /* handle as a speaker if it's a fixed line-out */
5117 if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) 5121 if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
5118 name = "Speaker"; 5122 name = "Speaker";
5119 /* check the location */ 5123 /* check the location */
5120 switch (attr) { 5124 switch (attr) {
@@ -5173,7 +5177,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
5173 5177
5174 switch (get_defcfg_device(def_conf)) { 5178 switch (get_defcfg_device(def_conf)) {
5175 case AC_JACK_LINE_OUT: 5179 case AC_JACK_LINE_OUT:
5176 return fill_audio_out_name(codec, nid, cfg, "Line-Out", 5180 return fill_audio_out_name(codec, nid, cfg, "Line Out",
5177 label, maxlen, indexp); 5181 label, maxlen, indexp);
5178 case AC_JACK_SPEAKER: 5182 case AC_JACK_SPEAKER:
5179 return fill_audio_out_name(codec, nid, cfg, "Speaker", 5183 return fill_audio_out_name(codec, nid, cfg, "Speaker",
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e9f71dc0d46..f0f1943a4b2 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -298,6 +298,9 @@ enum {
298#define AC_AMPCAP_MUTE (1<<31) /* mute capable */ 298#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
299#define AC_AMPCAP_MUTE_SHIFT 31 299#define AC_AMPCAP_MUTE_SHIFT 31
300 300
301/* driver-specific amp-caps: using bits 24-30 */
302#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
303
301/* Connection list */ 304/* Connection list */
302#define AC_CLIST_LENGTH (0x7f<<0) 305#define AC_CLIST_LENGTH (0x7f<<0)
303#define AC_CLIST_LONG (1<<7) 306#define AC_CLIST_LONG (1<<7)
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index d8a35da0803..9d819c4b492 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -282,7 +282,8 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
282EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 282EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
283 283
284static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 284static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
285 const struct auto_pin_cfg *cfg) 285 const struct auto_pin_cfg *cfg,
286 char *lastname, int *lastidx)
286{ 287{
287 unsigned int def_conf, conn; 288 unsigned int def_conf, conn;
288 char name[44]; 289 char name[44];
@@ -298,6 +299,10 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
298 return 0; 299 return 0;
299 300
300 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); 301 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
302 if (!strcmp(name, lastname) && idx == *lastidx)
303 idx++;
304 strncpy(lastname, name, 44);
305 *lastidx = idx;
301 err = snd_hda_jack_add_kctl(codec, nid, name, idx); 306 err = snd_hda_jack_add_kctl(codec, nid, name, idx);
302 if (err < 0) 307 if (err < 0)
303 return err; 308 return err;
@@ -311,41 +316,42 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
311 const struct auto_pin_cfg *cfg) 316 const struct auto_pin_cfg *cfg)
312{ 317{
313 const hda_nid_t *p; 318 const hda_nid_t *p;
314 int i, err; 319 int i, err, lastidx = 0;
320 char lastname[44] = "";
315 321
316 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 322 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
317 err = add_jack_kctl(codec, *p, cfg); 323 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
318 if (err < 0) 324 if (err < 0)
319 return err; 325 return err;
320 } 326 }
321 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 327 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
322 if (*p == *cfg->line_out_pins) /* might be duplicated */ 328 if (*p == *cfg->line_out_pins) /* might be duplicated */
323 break; 329 break;
324 err = add_jack_kctl(codec, *p, cfg); 330 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
325 if (err < 0) 331 if (err < 0)
326 return err; 332 return err;
327 } 333 }
328 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 334 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
329 if (*p == *cfg->line_out_pins) /* might be duplicated */ 335 if (*p == *cfg->line_out_pins) /* might be duplicated */
330 break; 336 break;
331 err = add_jack_kctl(codec, *p, cfg); 337 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
332 if (err < 0) 338 if (err < 0)
333 return err; 339 return err;
334 } 340 }
335 for (i = 0; i < cfg->num_inputs; i++) { 341 for (i = 0; i < cfg->num_inputs; i++) {
336 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); 342 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx);
337 if (err < 0) 343 if (err < 0)
338 return err; 344 return err;
339 } 345 }
340 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 346 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
341 err = add_jack_kctl(codec, *p, cfg); 347 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
342 if (err < 0) 348 if (err < 0)
343 return err; 349 return err;
344 } 350 }
345 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); 351 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx);
346 if (err < 0) 352 if (err < 0)
347 return err; 353 return err;
348 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); 354 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx);
349 if (err < 0) 355 if (err < 0)
350 return err; 356 return err;
351 return 0; 357 return 0;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 35abe3c6290..21d91d580da 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
728 728
729 err = chipio_read(codec, REG_CODEC_MUTE, &data); 729 err = chipio_read(codec, REG_CODEC_MUTE, &data);
730 if (err < 0) 730 if (err < 0)
731 return err; 731 goto exit;
732 732
733 /* *valp 0 is mute, 1 is unmute */ 733 /* *valp 0 is mute, 1 is unmute */
734 data = (data & 0x7f) | (*valp ? 0 : 0x80); 734 data = (data & 0x7f) | (*valp ? 0 : 0x80);
735 chipio_write(codec, REG_CODEC_MUTE, data); 735 err = chipio_write(codec, REG_CODEC_MUTE, data);
736 if (err < 0) 736 if (err < 0)
737 return err; 737 goto exit;
738 738
739 spec->curr_hp_switch = *valp; 739 spec->curr_hp_switch = *valp;
740 740
741 exit:
741 snd_hda_power_down(codec); 742 snd_hda_power_down(codec);
742 return 1; 743 return err < 0 ? err : 1;
743} 744}
744 745
745static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, 746static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
770 771
771 err = chipio_read(codec, REG_CODEC_MUTE, &data); 772 err = chipio_read(codec, REG_CODEC_MUTE, &data);
772 if (err < 0) 773 if (err < 0)
773 return err; 774 goto exit;
774 775
775 /* *valp 0 is mute, 1 is unmute */ 776 /* *valp 0 is mute, 1 is unmute */
776 data = (data & 0xef) | (*valp ? 0 : 0x10); 777 data = (data & 0xef) | (*valp ? 0 : 0x10);
777 chipio_write(codec, REG_CODEC_MUTE, data); 778 err = chipio_write(codec, REG_CODEC_MUTE, data);
778 if (err < 0) 779 if (err < 0)
779 return err; 780 goto exit;
780 781
781 spec->curr_speaker_switch = *valp; 782 spec->curr_speaker_switch = *valp;
782 783
784 exit:
783 snd_hda_power_down(codec); 785 snd_hda_power_down(codec);
784 return 1; 786 return err < 0 ? err : 1;
785} 787}
786 788
787static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, 789static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
819 821
820 err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); 822 err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
821 if (err < 0) 823 if (err < 0)
822 return err; 824 goto exit;
823 825
824 val = 31 - left_vol; 826 val = 31 - left_vol;
825 data = (data & 0xe0) | val; 827 data = (data & 0xe0) | val;
826 chipio_write(codec, REG_CODEC_HP_VOL_L, data); 828 err = chipio_write(codec, REG_CODEC_HP_VOL_L, data);
827 if (err < 0) 829 if (err < 0)
828 return err; 830 goto exit;
829 831
830 val = 31 - right_vol; 832 val = 31 - right_vol;
831 data = (data & 0xe0) | val; 833 data = (data & 0xe0) | val;
832 chipio_write(codec, REG_CODEC_HP_VOL_R, data); 834 err = chipio_write(codec, REG_CODEC_HP_VOL_R, data);
833 if (err < 0) 835 if (err < 0)
834 return err; 836 goto exit;
835 837
836 spec->curr_hp_volume[0] = left_vol; 838 spec->curr_hp_volume[0] = left_vol;
837 spec->curr_hp_volume[1] = right_vol; 839 spec->curr_hp_volume[1] = right_vol;
838 840
841 exit:
839 snd_hda_power_down(codec); 842 snd_hda_power_down(codec);
840 return 1; 843 return err < 0 ? err : 1;
841} 844}
842 845
843static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) 846static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
936 if (err < 0) 939 if (err < 0)
937 return err; 940 return err;
938 err = add_in_volume(codec, spec->dig_in, "IEC958"); 941 err = add_in_volume(codec, spec->dig_in, "IEC958");
942 if (err < 0)
943 return err;
939 } 944 }
940 return 0; 945 return 0;
941} 946}
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 0e99357e822..c83ccdba1e5 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -609,7 +609,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
609 "Front Speaker", "Surround Speaker", "Bass Speaker" 609 "Front Speaker", "Surround Speaker", "Bass Speaker"
610 }; 610 };
611 static const char * const line_outs[] = { 611 static const char * const line_outs[] = {
612 "Front Line-Out", "Surround Line-Out", "Bass Line-Out" 612 "Front Line Out", "Surround Line Out", "Bass Line Out"
613 }; 613 };
614 614
615 fix_volume_caps(codec, dac); 615 fix_volume_caps(codec, dac);
@@ -635,7 +635,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
635 if (num_ctls > 1) 635 if (num_ctls > 1)
636 name = line_outs[idx]; 636 name = line_outs[idx];
637 else 637 else
638 name = "Line-Out"; 638 name = "Line Out";
639 break; 639 break;
640 } 640 }
641 641
@@ -988,8 +988,10 @@ static void cs_automic(struct hda_codec *codec)
988 change_cur_input(codec, !spec->automic_idx, 0); 988 change_cur_input(codec, !spec->automic_idx, 0);
989 } else { 989 } else {
990 if (present) { 990 if (present) {
991 spec->last_input = spec->cur_input; 991 if (spec->cur_input != spec->automic_idx) {
992 spec->cur_input = spec->automic_idx; 992 spec->last_input = spec->cur_input;
993 spec->cur_input = spec->automic_idx;
994 }
993 } else { 995 } else {
994 spec->cur_input = spec->last_input; 996 spec->cur_input = spec->last_input;
995 } 997 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a7a5733aa4d..d29d6d37790 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3482,7 +3482,7 @@ static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3482 "Disabled", "Enabled" 3482 "Disabled", "Enabled"
3483 }; 3483 };
3484 static const char * const texts3[] = { 3484 static const char * const texts3[] = {
3485 "Disabled", "Speaker Only", "Line-Out+Speaker" 3485 "Disabled", "Speaker Only", "Line Out+Speaker"
3486 }; 3486 };
3487 const char * const *texts; 3487 const char * const *texts;
3488 3488
@@ -4079,7 +4079,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4079 err = snd_hda_ctl_add(codec, nid, kctl); 4079 err = snd_hda_ctl_add(codec, nid, kctl);
4080 if (err < 0) 4080 if (err < 0)
4081 return err; 4081 return err;
4082 if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE)) 4082 if (!(query_amp_caps(codec, nid, hda_dir) &
4083 (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
4083 break; 4084 break;
4084 } 4085 }
4085 return 0; 4086 return 0;
@@ -4379,6 +4380,22 @@ static const struct snd_pci_quirk cxt_fixups[] = {
4379 {} 4380 {}
4380}; 4381};
4381 4382
4383/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
4384 * can be created (bko#42825)
4385 */
4386static void add_cx5051_fake_mutes(struct hda_codec *codec)
4387{
4388 static hda_nid_t out_nids[] = {
4389 0x10, 0x11, 0
4390 };
4391 hda_nid_t *p;
4392
4393 for (p = out_nids; *p; p++)
4394 snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
4395 AC_AMPCAP_MIN_MUTE |
4396 query_amp_caps(codec, *p, HDA_OUTPUT));
4397}
4398
4382static int patch_conexant_auto(struct hda_codec *codec) 4399static int patch_conexant_auto(struct hda_codec *codec)
4383{ 4400{
4384 struct conexant_spec *spec; 4401 struct conexant_spec *spec;
@@ -4397,6 +4414,9 @@ static int patch_conexant_auto(struct hda_codec *codec)
4397 case 0x14f15045: 4414 case 0x14f15045:
4398 spec->single_adc_amp = 1; 4415 spec->single_adc_amp = 1;
4399 break; 4416 break;
4417 case 0x14f15051:
4418 add_cx5051_fake_mutes(codec);
4419 break;
4400 } 4420 }
4401 4421
4402 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); 4422 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0db1dc49382..f286bb8fda1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -80,6 +80,8 @@ enum {
80 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ 80 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
81}; 81};
82 82
83#define MAX_VOL_NIDS 0x40
84
83struct alc_spec { 85struct alc_spec {
84 /* codec parameterization */ 86 /* codec parameterization */
85 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 87 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -118,8 +120,8 @@ struct alc_spec {
118 const hda_nid_t *capsrc_nids; 120 const hda_nid_t *capsrc_nids;
119 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 121 hda_nid_t dig_in_nid; /* digital-in NID; optional */
120 hda_nid_t mixer_nid; /* analog-mixer NID */ 122 hda_nid_t mixer_nid; /* analog-mixer NID */
121 DECLARE_BITMAP(vol_ctls, 0x20 << 1); 123 DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
122 DECLARE_BITMAP(sw_ctls, 0x20 << 1); 124 DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
123 125
124 /* capture setup for dynamic dual-adc switch */ 126 /* capture setup for dynamic dual-adc switch */
125 hda_nid_t cur_adc; 127 hda_nid_t cur_adc;
@@ -177,6 +179,7 @@ struct alc_spec {
177 unsigned int detect_lo:1; /* Line-out detection enabled */ 179 unsigned int detect_lo:1; /* Line-out detection enabled */
178 unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ 180 unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
179 unsigned int automute_lo_possible:1; /* there are line outs and HP */ 181 unsigned int automute_lo_possible:1; /* there are line outs and HP */
182 unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
180 183
181 /* other flags */ 184 /* other flags */
182 unsigned int no_analog :1; /* digital I/O only */ 185 unsigned int no_analog :1; /* digital I/O only */
@@ -495,13 +498,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
495 498
496 for (i = 0; i < num_pins; i++) { 499 for (i = 0; i < num_pins; i++) {
497 hda_nid_t nid = pins[i]; 500 hda_nid_t nid = pins[i];
501 unsigned int val;
498 if (!nid) 502 if (!nid)
499 break; 503 break;
500 switch (spec->automute_mode) { 504 switch (spec->automute_mode) {
501 case ALC_AUTOMUTE_PIN: 505 case ALC_AUTOMUTE_PIN:
506 /* don't reset VREF value in case it's controlling
507 * the amp (see alc861_fixup_asus_amp_vref_0f())
508 */
509 if (spec->keep_vref_in_automute) {
510 val = snd_hda_codec_read(codec, nid, 0,
511 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
512 val &= ~PIN_HP;
513 } else
514 val = 0;
515 val |= pin_bits;
502 snd_hda_codec_write(codec, nid, 0, 516 snd_hda_codec_write(codec, nid, 0,
503 AC_VERB_SET_PIN_WIDGET_CONTROL, 517 AC_VERB_SET_PIN_WIDGET_CONTROL,
504 pin_bits); 518 val);
505 break; 519 break;
506 case ALC_AUTOMUTE_AMP: 520 case ALC_AUTOMUTE_AMP:
507 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 521 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
@@ -788,7 +802,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
788 "Disabled", "Enabled" 802 "Disabled", "Enabled"
789 }; 803 };
790 static const char * const texts3[] = { 804 static const char * const texts3[] = {
791 "Disabled", "Speaker Only", "Line-Out+Speaker" 805 "Disabled", "Speaker Only", "Line Out+Speaker"
792 }; 806 };
793 const char * const *texts; 807 const char * const *texts;
794 808
@@ -1842,7 +1856,9 @@ static const char * const alc_slave_vols[] = {
1842 "Headphone Playback Volume", 1856 "Headphone Playback Volume",
1843 "Speaker Playback Volume", 1857 "Speaker Playback Volume",
1844 "Mono Playback Volume", 1858 "Mono Playback Volume",
1845 "Line-Out Playback Volume", 1859 "Line Out Playback Volume",
1860 "CLFE Playback Volume",
1861 "Bass Speaker Playback Volume",
1846 "PCM Playback Volume", 1862 "PCM Playback Volume",
1847 NULL, 1863 NULL,
1848}; 1864};
@@ -1857,7 +1873,9 @@ static const char * const alc_slave_sws[] = {
1857 "Speaker Playback Switch", 1873 "Speaker Playback Switch",
1858 "Mono Playback Switch", 1874 "Mono Playback Switch",
1859 "IEC958 Playback Switch", 1875 "IEC958 Playback Switch",
1860 "Line-Out Playback Switch", 1876 "Line Out Playback Switch",
1877 "CLFE Playback Switch",
1878 "Bass Speaker Playback Switch",
1861 "PCM Playback Switch", 1879 "PCM Playback Switch",
1862 NULL, 1880 NULL,
1863}; 1881};
@@ -2306,7 +2324,7 @@ static int alc_build_pcms(struct hda_codec *codec)
2306 "%s Analog", codec->chip_name); 2324 "%s Analog", codec->chip_name);
2307 info->name = spec->stream_name_analog; 2325 info->name = spec->stream_name_analog;
2308 2326
2309 if (spec->multiout.dac_nids > 0) { 2327 if (spec->multiout.num_dacs > 0) {
2310 p = spec->stream_analog_playback; 2328 p = spec->stream_analog_playback;
2311 if (!p) 2329 if (!p)
2312 p = &alc_pcm_analog_playback; 2330 p = &alc_pcm_analog_playback;
@@ -3133,7 +3151,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3133static inline unsigned int get_ctl_pos(unsigned int data) 3151static inline unsigned int get_ctl_pos(unsigned int data)
3134{ 3152{
3135 hda_nid_t nid = get_amp_nid_(data); 3153 hda_nid_t nid = get_amp_nid_(data);
3136 unsigned int dir = get_amp_direction_(data); 3154 unsigned int dir;
3155 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3156 return 0;
3157 dir = get_amp_direction_(data);
3137 return (nid << 1) | dir; 3158 return (nid << 1) | dir;
3138} 3159}
3139 3160
@@ -3776,7 +3797,7 @@ static void alc_auto_init_input_src(struct hda_codec *codec)
3776 else 3797 else
3777 nums = spec->num_adc_nids; 3798 nums = spec->num_adc_nids;
3778 for (c = 0; c < nums; c++) 3799 for (c = 0; c < nums; c++)
3779 alc_mux_select(codec, 0, spec->cur_mux[c], true); 3800 alc_mux_select(codec, c, spec->cur_mux[c], true);
3780} 3801}
3781 3802
3782/* add mic boosts if needed */ 3803/* add mic boosts if needed */
@@ -4358,6 +4379,7 @@ enum {
4358 ALC882_FIXUP_ACER_ASPIRE_8930G, 4379 ALC882_FIXUP_ACER_ASPIRE_8930G,
4359 ALC882_FIXUP_ASPIRE_8930G_VERBS, 4380 ALC882_FIXUP_ASPIRE_8930G_VERBS,
4360 ALC885_FIXUP_MACPRO_GPIO, 4381 ALC885_FIXUP_MACPRO_GPIO,
4382 ALC889_FIXUP_DAC_ROUTE,
4361}; 4383};
4362 4384
4363static void alc889_fixup_coef(struct hda_codec *codec, 4385static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4411,6 +4433,31 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
4411 alc882_gpio_mute(codec, 1, 0); 4433 alc882_gpio_mute(codec, 1, 0);
4412} 4434}
4413 4435
4436/* Fix the connection of some pins for ALC889:
4437 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
4438 * work correctly (bko#42740)
4439 */
4440static void alc889_fixup_dac_route(struct hda_codec *codec,
4441 const struct alc_fixup *fix, int action)
4442{
4443 if (action == ALC_FIXUP_ACT_PRE_PROBE) {
4444 /* fake the connections during parsing the tree */
4445 hda_nid_t conn1[2] = { 0x0c, 0x0d };
4446 hda_nid_t conn2[2] = { 0x0e, 0x0f };
4447 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
4448 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
4449 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
4450 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
4451 } else if (action == ALC_FIXUP_ACT_PROBE) {
4452 /* restore the connections */
4453 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
4454 snd_hda_override_conn_list(codec, 0x14, 5, conn);
4455 snd_hda_override_conn_list(codec, 0x15, 5, conn);
4456 snd_hda_override_conn_list(codec, 0x18, 5, conn);
4457 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
4458 }
4459}
4460
4414static const struct alc_fixup alc882_fixups[] = { 4461static const struct alc_fixup alc882_fixups[] = {
4415 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 4462 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
4416 .type = ALC_FIXUP_PINS, 4463 .type = ALC_FIXUP_PINS,
@@ -4558,6 +4605,10 @@ static const struct alc_fixup alc882_fixups[] = {
4558 .type = ALC_FIXUP_FUNC, 4605 .type = ALC_FIXUP_FUNC,
4559 .v.func = alc885_fixup_macpro_gpio, 4606 .v.func = alc885_fixup_macpro_gpio,
4560 }, 4607 },
4608 [ALC889_FIXUP_DAC_ROUTE] = {
4609 .type = ALC_FIXUP_FUNC,
4610 .v.func = alc889_fixup_dac_route,
4611 },
4561}; 4612};
4562 4613
4563static const struct snd_pci_quirk alc882_fixup_tbl[] = { 4614static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4582,6 +4633,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
4582 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 4633 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
4583 ALC882_FIXUP_ACER_ASPIRE_4930G), 4634 ALC882_FIXUP_ACER_ASPIRE_4930G),
4584 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), 4635 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
4636 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
4585 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), 4637 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
4586 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), 4638 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
4587 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), 4639 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
@@ -4735,7 +4787,6 @@ enum {
4735 ALC262_FIXUP_FSC_H270, 4787 ALC262_FIXUP_FSC_H270,
4736 ALC262_FIXUP_HP_Z200, 4788 ALC262_FIXUP_HP_Z200,
4737 ALC262_FIXUP_TYAN, 4789 ALC262_FIXUP_TYAN,
4738 ALC262_FIXUP_TOSHIBA_RX1,
4739 ALC262_FIXUP_LENOVO_3000, 4790 ALC262_FIXUP_LENOVO_3000,
4740 ALC262_FIXUP_BENQ, 4791 ALC262_FIXUP_BENQ,
4741 ALC262_FIXUP_BENQ_T31, 4792 ALC262_FIXUP_BENQ_T31,
@@ -4765,16 +4816,6 @@ static const struct alc_fixup alc262_fixups[] = {
4765 { } 4816 { }
4766 } 4817 }
4767 }, 4818 },
4768 [ALC262_FIXUP_TOSHIBA_RX1] = {
4769 .type = ALC_FIXUP_PINS,
4770 .v.pins = (const struct alc_pincfg[]) {
4771 { 0x14, 0x90170110 }, /* speaker */
4772 { 0x15, 0x0421101f }, /* HP */
4773 { 0x1a, 0x40f000f0 }, /* N/A */
4774 { 0x1b, 0x40f000f0 }, /* N/A */
4775 { 0x1e, 0x40f000f0 }, /* N/A */
4776 }
4777 },
4778 [ALC262_FIXUP_LENOVO_3000] = { 4819 [ALC262_FIXUP_LENOVO_3000] = {
4779 .type = ALC_FIXUP_VERBS, 4820 .type = ALC_FIXUP_VERBS,
4780 .v.verbs = (const struct hda_verb[]) { 4821 .v.verbs = (const struct hda_verb[]) {
@@ -4807,8 +4848,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4807 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), 4848 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
4808 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), 4849 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
4809 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), 4850 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
4810 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
4811 ALC262_FIXUP_TOSHIBA_RX1),
4812 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), 4851 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
4813 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), 4852 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
4814 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), 4853 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
@@ -5377,7 +5416,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5377 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 5416 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5378 ALC269_FIXUP_AMIC), 5417 ALC269_FIXUP_AMIC),
5379 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), 5418 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
5380 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC),
5381 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), 5419 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5382 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), 5420 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5383 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), 5421 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
@@ -5589,6 +5627,25 @@ enum {
5589 PINFIX_ASUS_A6RP, 5627 PINFIX_ASUS_A6RP,
5590}; 5628};
5591 5629
5630/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
5631static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5632 const struct alc_fixup *fix, int action)
5633{
5634 struct alc_spec *spec = codec->spec;
5635 unsigned int val;
5636
5637 if (action != ALC_FIXUP_ACT_INIT)
5638 return;
5639 val = snd_hda_codec_read(codec, 0x0f, 0,
5640 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5641 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
5642 val |= AC_PINCTL_IN_EN;
5643 val |= AC_PINCTL_VREF_50;
5644 snd_hda_codec_write(codec, 0x0f, 0,
5645 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5646 spec->keep_vref_in_automute = 1;
5647}
5648
5592static const struct alc_fixup alc861_fixups[] = { 5649static const struct alc_fixup alc861_fixups[] = {
5593 [PINFIX_FSC_AMILO_PI1505] = { 5650 [PINFIX_FSC_AMILO_PI1505] = {
5594 .type = ALC_FIXUP_PINS, 5651 .type = ALC_FIXUP_PINS,
@@ -5599,17 +5656,14 @@ static const struct alc_fixup alc861_fixups[] = {
5599 } 5656 }
5600 }, 5657 },
5601 [PINFIX_ASUS_A6RP] = { 5658 [PINFIX_ASUS_A6RP] = {
5602 .type = ALC_FIXUP_VERBS, 5659 .type = ALC_FIXUP_FUNC,
5603 .v.verbs = (const struct hda_verb[]) { 5660 .v.func = alc861_fixup_asus_amp_vref_0f,
5604 /* node 0x0f VREF seems controlling the master output */
5605 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
5606 { }
5607 },
5608 }, 5661 },
5609}; 5662};
5610 5663
5611static const struct snd_pci_quirk alc861_fixup_tbl[] = { 5664static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5612 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP), 5665 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
5666 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),
5613 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 5667 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
5614 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 5668 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
5615 {} 5669 {}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 948f0be2f4f..9dbb5735d77 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4629,7 +4629,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4629 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; 4629 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
4630 if (no_hp_sensing(spec, i)) 4630 if (no_hp_sensing(spec, i))
4631 continue; 4631 continue;
4632 if (presence) 4632 if (1 /*presence*/)
4633 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); 4633 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
4634#if 0 /* FIXME */ 4634#if 0 /* FIXME */
4635/* Resetting the pinctl like below may lead to (a sort of) regressions 4635/* Resetting the pinctl like below may lead to (a sort of) regressions
@@ -5078,9 +5078,9 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5078 spec->gpio_dir, spec->gpio_data); 5078 spec->gpio_dir, spec->gpio_data);
5079 } else { 5079 } else {
5080 notmtd_lvl = spec->gpio_led_polarity ? 5080 notmtd_lvl = spec->gpio_led_polarity ?
5081 AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD; 5081 AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
5082 muted_lvl = spec->gpio_led_polarity ? 5082 muted_lvl = spec->gpio_led_polarity ?
5083 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; 5083 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50;
5084 spec->vref_led = muted ? muted_lvl : notmtd_lvl; 5084 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5085 stac_vrefout_set(codec, spec->vref_mute_led_nid, 5085 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5086 spec->vref_led); 5086 spec->vref_led);
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 03e63fed9ca..dff9a00ee8f 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -199,6 +199,9 @@ struct via_spec {
199 unsigned int no_pin_power_ctl; 199 unsigned int no_pin_power_ctl;
200 enum VIA_HDA_CODEC codec_type; 200 enum VIA_HDA_CODEC codec_type;
201 201
202 /* analog low-power control */
203 bool alc_mode;
204
202 /* smart51 setup */ 205 /* smart51 setup */
203 unsigned int smart51_nums; 206 unsigned int smart51_nums;
204 hda_nid_t smart51_pins[2]; 207 hda_nid_t smart51_pins[2];
@@ -663,6 +666,9 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
663 /* init input-src */ 666 /* init input-src */
664 for (i = 0; i < spec->num_adc_nids; i++) { 667 for (i = 0; i < spec->num_adc_nids; i++) {
665 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; 668 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
669 /* secondary ADCs must have the unique MUX */
670 if (i > 0 && !spec->mux_nids[i])
671 break;
666 if (spec->mux_nids[adc_idx]) { 672 if (spec->mux_nids[adc_idx]) {
667 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; 673 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
668 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, 674 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
@@ -687,6 +693,15 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
687 } 693 }
688} 694}
689 695
696static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
697 unsigned int parm)
698{
699 if (snd_hda_codec_read(codec, nid, 0,
700 AC_VERB_GET_POWER_STATE, 0) == parm)
701 return;
702 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
703}
704
690static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, 705static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
691 unsigned int *affected_parm) 706 unsigned int *affected_parm)
692{ 707{
@@ -709,7 +724,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
709 } else 724 } else
710 parm = AC_PWRST_D3; 725 parm = AC_PWRST_D3;
711 726
712 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 727 update_power_state(codec, nid, parm);
713} 728}
714 729
715static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, 730static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
@@ -749,6 +764,7 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
749 return 0; 764 return 0;
750 spec->no_pin_power_ctl = val; 765 spec->no_pin_power_ctl = val;
751 set_widgets_power_state(codec); 766 set_widgets_power_state(codec);
767 analog_low_current_mode(codec);
752 return 1; 768 return 1;
753} 769}
754 770
@@ -1036,13 +1052,19 @@ static bool is_aa_path_mute(struct hda_codec *codec)
1036} 1052}
1037 1053
1038/* enter/exit analog low-current mode */ 1054/* enter/exit analog low-current mode */
1039static void analog_low_current_mode(struct hda_codec *codec) 1055static void __analog_low_current_mode(struct hda_codec *codec, bool force)
1040{ 1056{
1041 struct via_spec *spec = codec->spec; 1057 struct via_spec *spec = codec->spec;
1042 bool enable; 1058 bool enable;
1043 unsigned int verb, parm; 1059 unsigned int verb, parm;
1044 1060
1045 enable = is_aa_path_mute(codec) && (spec->opened_streams != 0); 1061 if (spec->no_pin_power_ctl)
1062 enable = false;
1063 else
1064 enable = is_aa_path_mute(codec) && !spec->opened_streams;
1065 if (enable == spec->alc_mode && !force)
1066 return;
1067 spec->alc_mode = enable;
1046 1068
1047 /* decide low current mode's verb & parameter */ 1069 /* decide low current mode's verb & parameter */
1048 switch (spec->codec_type) { 1070 switch (spec->codec_type) {
@@ -1074,6 +1096,11 @@ static void analog_low_current_mode(struct hda_codec *codec)
1074 snd_hda_codec_write(codec, codec->afg, 0, verb, parm); 1096 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1075} 1097}
1076 1098
1099static void analog_low_current_mode(struct hda_codec *codec)
1100{
1101 return __analog_low_current_mode(codec, false);
1102}
1103
1077/* 1104/*
1078 * generic initialization of ADC, input mixers and output mixers 1105 * generic initialization of ADC, input mixers and output mixers
1079 */ 1106 */
@@ -1446,6 +1473,7 @@ static int via_build_controls(struct hda_codec *codec)
1446 struct snd_kcontrol *kctl; 1473 struct snd_kcontrol *kctl;
1447 int err, i; 1474 int err, i;
1448 1475
1476 spec->no_pin_power_ctl = 1;
1449 if (spec->set_widgets_power_state) 1477 if (spec->set_widgets_power_state)
1450 if (!via_clone_control(spec, &via_pin_power_ctl_enum)) 1478 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1451 return -ENOMEM; 1479 return -ENOMEM;
@@ -1499,10 +1527,6 @@ static int via_build_controls(struct hda_codec *codec)
1499 return err; 1527 return err;
1500 } 1528 }
1501 1529
1502 /* init power states */
1503 set_widgets_power_state(codec);
1504 analog_low_current_mode(codec);
1505
1506 via_free_kctls(codec); /* no longer needed */ 1530 via_free_kctls(codec); /* no longer needed */
1507 1531
1508 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 1532 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
@@ -2295,10 +2319,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
2295 2319
2296 if (mux) { 2320 if (mux) {
2297 /* switch to D0 beofre change index */ 2321 /* switch to D0 beofre change index */
2298 if (snd_hda_codec_read(codec, mux, 0, 2322 update_power_state(codec, mux, AC_PWRST_D0);
2299 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
2300 snd_hda_codec_write(codec, mux, 0,
2301 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2302 snd_hda_codec_write(codec, mux, 0, 2323 snd_hda_codec_write(codec, mux, 0,
2303 AC_VERB_SET_CONNECT_SEL, 2324 AC_VERB_SET_CONNECT_SEL,
2304 spec->inputs[cur].mux_idx); 2325 spec->inputs[cur].mux_idx);
@@ -2776,6 +2797,10 @@ static int via_init(struct hda_codec *codec)
2776 for (i = 0; i < spec->num_iverbs; i++) 2797 for (i = 0; i < spec->num_iverbs; i++)
2777 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2798 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2778 2799
2800 /* init power states */
2801 set_widgets_power_state(codec);
2802 __analog_low_current_mode(codec, true);
2803
2779 via_auto_init_multi_out(codec); 2804 via_auto_init_multi_out(codec);
2780 via_auto_init_hp_out(codec); 2805 via_auto_init_hp_out(codec);
2781 via_auto_init_speaker_out(codec); 2806 via_auto_init_speaker_out(codec);
@@ -2922,9 +2947,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2922 if (imux_is_smixer) 2947 if (imux_is_smixer)
2923 parm = AC_PWRST_D0; 2948 parm = AC_PWRST_D0;
2924 /* SW0 (17h), AIW 0/1 (13h/14h) */ 2949 /* SW0 (17h), AIW 0/1 (13h/14h) */
2925 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); 2950 update_power_state(codec, 0x17, parm);
2926 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); 2951 update_power_state(codec, 0x13, parm);
2927 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); 2952 update_power_state(codec, 0x14, parm);
2928 2953
2929 /* outputs */ 2954 /* outputs */
2930 /* PW0 (19h), SW1 (18h), AOW1 (11h) */ 2955 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
@@ -2932,8 +2957,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2932 set_pin_power_state(codec, 0x19, &parm); 2957 set_pin_power_state(codec, 0x19, &parm);
2933 if (spec->smart51_enabled) 2958 if (spec->smart51_enabled)
2934 set_pin_power_state(codec, 0x1b, &parm); 2959 set_pin_power_state(codec, 0x1b, &parm);
2935 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); 2960 update_power_state(codec, 0x18, parm);
2936 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); 2961 update_power_state(codec, 0x11, parm);
2937 2962
2938 /* PW6 (22h), SW2 (26h), AOW2 (24h) */ 2963 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
2939 if (is_8ch) { 2964 if (is_8ch) {
@@ -2941,20 +2966,16 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2941 set_pin_power_state(codec, 0x22, &parm); 2966 set_pin_power_state(codec, 0x22, &parm);
2942 if (spec->smart51_enabled) 2967 if (spec->smart51_enabled)
2943 set_pin_power_state(codec, 0x1a, &parm); 2968 set_pin_power_state(codec, 0x1a, &parm);
2944 snd_hda_codec_write(codec, 0x26, 0, 2969 update_power_state(codec, 0x26, parm);
2945 AC_VERB_SET_POWER_STATE, parm); 2970 update_power_state(codec, 0x24, parm);
2946 snd_hda_codec_write(codec, 0x24, 0,
2947 AC_VERB_SET_POWER_STATE, parm);
2948 } else if (codec->vendor_id == 0x11064397) { 2971 } else if (codec->vendor_id == 0x11064397) {
2949 /* PW7(23h), SW2(27h), AOW2(25h) */ 2972 /* PW7(23h), SW2(27h), AOW2(25h) */
2950 parm = AC_PWRST_D3; 2973 parm = AC_PWRST_D3;
2951 set_pin_power_state(codec, 0x23, &parm); 2974 set_pin_power_state(codec, 0x23, &parm);
2952 if (spec->smart51_enabled) 2975 if (spec->smart51_enabled)
2953 set_pin_power_state(codec, 0x1a, &parm); 2976 set_pin_power_state(codec, 0x1a, &parm);
2954 snd_hda_codec_write(codec, 0x27, 0, 2977 update_power_state(codec, 0x27, parm);
2955 AC_VERB_SET_POWER_STATE, parm); 2978 update_power_state(codec, 0x25, parm);
2956 snd_hda_codec_write(codec, 0x25, 0,
2957 AC_VERB_SET_POWER_STATE, parm);
2958 } 2979 }
2959 2980
2960 /* PW 3/4/7 (1ch/1dh/23h) */ 2981 /* PW 3/4/7 (1ch/1dh/23h) */
@@ -2966,17 +2987,13 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2966 set_pin_power_state(codec, 0x23, &parm); 2987 set_pin_power_state(codec, 0x23, &parm);
2967 2988
2968 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ 2989 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
2969 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, 2990 update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
2970 imux_is_smixer ? AC_PWRST_D0 : parm); 2991 update_power_state(codec, 0x10, parm);
2971 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2972 if (is_8ch) { 2992 if (is_8ch) {
2973 snd_hda_codec_write(codec, 0x25, 0, 2993 update_power_state(codec, 0x25, parm);
2974 AC_VERB_SET_POWER_STATE, parm); 2994 update_power_state(codec, 0x27, parm);
2975 snd_hda_codec_write(codec, 0x27, 0,
2976 AC_VERB_SET_POWER_STATE, parm);
2977 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) 2995 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
2978 snd_hda_codec_write(codec, 0x25, 0, 2996 update_power_state(codec, 0x25, parm);
2979 AC_VERB_SET_POWER_STATE, parm);
2980} 2997}
2981 2998
2982static int patch_vt1708S(struct hda_codec *codec); 2999static int patch_vt1708S(struct hda_codec *codec);
@@ -3149,10 +3166,10 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec)
3149 if (imux_is_smixer) 3166 if (imux_is_smixer)
3150 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ 3167 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
3151 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ 3168 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
3152 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); 3169 update_power_state(codec, 0x13, parm);
3153 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); 3170 update_power_state(codec, 0x12, parm);
3154 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); 3171 update_power_state(codec, 0x1f, parm);
3155 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); 3172 update_power_state(codec, 0x20, parm);
3156 3173
3157 /* outputs */ 3174 /* outputs */
3158 /* PW 3/4 (16h/17h) */ 3175 /* PW 3/4 (16h/17h) */
@@ -3160,10 +3177,9 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec)
3160 set_pin_power_state(codec, 0x17, &parm); 3177 set_pin_power_state(codec, 0x17, &parm);
3161 set_pin_power_state(codec, 0x16, &parm); 3178 set_pin_power_state(codec, 0x16, &parm);
3162 /* MW0 (1ah), AOW 0/1 (10h/1dh) */ 3179 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
3163 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, 3180 update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm);
3164 imux_is_smixer ? AC_PWRST_D0 : parm); 3181 update_power_state(codec, 0x10, parm);
3165 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); 3182 update_power_state(codec, 0x1d, parm);
3166 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
3167} 3183}
3168 3184
3169static int patch_vt1702(struct hda_codec *codec) 3185static int patch_vt1702(struct hda_codec *codec)
@@ -3228,52 +3244,48 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
3228 if (imux_is_smixer) 3244 if (imux_is_smixer)
3229 parm = AC_PWRST_D0; 3245 parm = AC_PWRST_D0;
3230 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ 3246 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
3231 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); 3247 update_power_state(codec, 0x1e, parm);
3232 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); 3248 update_power_state(codec, 0x1f, parm);
3233 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); 3249 update_power_state(codec, 0x10, parm);
3234 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); 3250 update_power_state(codec, 0x11, parm);
3235 3251
3236 /* outputs */ 3252 /* outputs */
3237 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ 3253 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
3238 parm = AC_PWRST_D3; 3254 parm = AC_PWRST_D3;
3239 set_pin_power_state(codec, 0x27, &parm); 3255 set_pin_power_state(codec, 0x27, &parm);
3240 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); 3256 update_power_state(codec, 0x1a, parm);
3241 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); 3257 update_power_state(codec, 0xb, parm);
3242 3258
3243 /* PW2 (26h), AOW2 (ah) */ 3259 /* PW2 (26h), AOW2 (ah) */
3244 parm = AC_PWRST_D3; 3260 parm = AC_PWRST_D3;
3245 set_pin_power_state(codec, 0x26, &parm); 3261 set_pin_power_state(codec, 0x26, &parm);
3246 if (spec->smart51_enabled) 3262 if (spec->smart51_enabled)
3247 set_pin_power_state(codec, 0x2b, &parm); 3263 set_pin_power_state(codec, 0x2b, &parm);
3248 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); 3264 update_power_state(codec, 0xa, parm);
3249 3265
3250 /* PW0 (24h), AOW0 (8h) */ 3266 /* PW0 (24h), AOW0 (8h) */
3251 parm = AC_PWRST_D3; 3267 parm = AC_PWRST_D3;
3252 set_pin_power_state(codec, 0x24, &parm); 3268 set_pin_power_state(codec, 0x24, &parm);
3253 if (!spec->hp_independent_mode) /* check for redirected HP */ 3269 if (!spec->hp_independent_mode) /* check for redirected HP */
3254 set_pin_power_state(codec, 0x28, &parm); 3270 set_pin_power_state(codec, 0x28, &parm);
3255 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); 3271 update_power_state(codec, 0x8, parm);
3256 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ 3272 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
3257 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, 3273 update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
3258 imux_is_smixer ? AC_PWRST_D0 : parm);
3259 3274
3260 /* PW1 (25h), AOW1 (9h) */ 3275 /* PW1 (25h), AOW1 (9h) */
3261 parm = AC_PWRST_D3; 3276 parm = AC_PWRST_D3;
3262 set_pin_power_state(codec, 0x25, &parm); 3277 set_pin_power_state(codec, 0x25, &parm);
3263 if (spec->smart51_enabled) 3278 if (spec->smart51_enabled)
3264 set_pin_power_state(codec, 0x2a, &parm); 3279 set_pin_power_state(codec, 0x2a, &parm);
3265 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); 3280 update_power_state(codec, 0x9, parm);
3266 3281
3267 if (spec->hp_independent_mode) { 3282 if (spec->hp_independent_mode) {
3268 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ 3283 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
3269 parm = AC_PWRST_D3; 3284 parm = AC_PWRST_D3;
3270 set_pin_power_state(codec, 0x28, &parm); 3285 set_pin_power_state(codec, 0x28, &parm);
3271 snd_hda_codec_write(codec, 0x1b, 0, 3286 update_power_state(codec, 0x1b, parm);
3272 AC_VERB_SET_POWER_STATE, parm); 3287 update_power_state(codec, 0x34, parm);
3273 snd_hda_codec_write(codec, 0x34, 0, 3288 update_power_state(codec, 0xc, parm);
3274 AC_VERB_SET_POWER_STATE, parm);
3275 snd_hda_codec_write(codec, 0xc, 0,
3276 AC_VERB_SET_POWER_STATE, parm);
3277 } 3289 }
3278} 3290}
3279 3291
@@ -3433,8 +3445,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3433 if (imux_is_smixer) 3445 if (imux_is_smixer)
3434 parm = AC_PWRST_D0; 3446 parm = AC_PWRST_D0;
3435 /* SW0 (17h), AIW0(13h) */ 3447 /* SW0 (17h), AIW0(13h) */
3436 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); 3448 update_power_state(codec, 0x17, parm);
3437 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); 3449 update_power_state(codec, 0x13, parm);
3438 3450
3439 parm = AC_PWRST_D3; 3451 parm = AC_PWRST_D3;
3440 set_pin_power_state(codec, 0x1e, &parm); 3452 set_pin_power_state(codec, 0x1e, &parm);
@@ -3442,12 +3454,11 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3442 if (spec->dmic_enabled) 3454 if (spec->dmic_enabled)
3443 set_pin_power_state(codec, 0x22, &parm); 3455 set_pin_power_state(codec, 0x22, &parm);
3444 else 3456 else
3445 snd_hda_codec_write(codec, 0x22, 0, 3457 update_power_state(codec, 0x22, AC_PWRST_D3);
3446 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3447 3458
3448 /* SW2(26h), AIW1(14h) */ 3459 /* SW2(26h), AIW1(14h) */
3449 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); 3460 update_power_state(codec, 0x26, parm);
3450 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); 3461 update_power_state(codec, 0x14, parm);
3451 3462
3452 /* outputs */ 3463 /* outputs */
3453 /* PW0 (19h), SW1 (18h), AOW1 (11h) */ 3464 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
@@ -3456,8 +3467,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3456 /* Smart 5.1 PW2(1bh) */ 3467 /* Smart 5.1 PW2(1bh) */
3457 if (spec->smart51_enabled) 3468 if (spec->smart51_enabled)
3458 set_pin_power_state(codec, 0x1b, &parm); 3469 set_pin_power_state(codec, 0x1b, &parm);
3459 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); 3470 update_power_state(codec, 0x18, parm);
3460 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); 3471 update_power_state(codec, 0x11, parm);
3461 3472
3462 /* PW7 (23h), SW3 (27h), AOW3 (25h) */ 3473 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
3463 parm = AC_PWRST_D3; 3474 parm = AC_PWRST_D3;
@@ -3465,12 +3476,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3465 /* Smart 5.1 PW1(1ah) */ 3476 /* Smart 5.1 PW1(1ah) */
3466 if (spec->smart51_enabled) 3477 if (spec->smart51_enabled)
3467 set_pin_power_state(codec, 0x1a, &parm); 3478 set_pin_power_state(codec, 0x1a, &parm);
3468 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); 3479 update_power_state(codec, 0x27, parm);
3469 3480
3470 /* Smart 5.1 PW5(1eh) */ 3481 /* Smart 5.1 PW5(1eh) */
3471 if (spec->smart51_enabled) 3482 if (spec->smart51_enabled)
3472 set_pin_power_state(codec, 0x1e, &parm); 3483 set_pin_power_state(codec, 0x1e, &parm);
3473 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); 3484 update_power_state(codec, 0x25, parm);
3474 3485
3475 /* Mono out */ 3486 /* Mono out */
3476 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ 3487 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
@@ -3486,9 +3497,9 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3486 mono_out = 1; 3497 mono_out = 1;
3487 } 3498 }
3488 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; 3499 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
3489 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); 3500 update_power_state(codec, 0x28, parm);
3490 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); 3501 update_power_state(codec, 0x29, parm);
3491 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); 3502 update_power_state(codec, 0x2a, parm);
3492 3503
3493 /* PW 3/4 (1ch/1dh) */ 3504 /* PW 3/4 (1ch/1dh) */
3494 parm = AC_PWRST_D3; 3505 parm = AC_PWRST_D3;
@@ -3496,15 +3507,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3496 set_pin_power_state(codec, 0x1d, &parm); 3507 set_pin_power_state(codec, 0x1d, &parm);
3497 /* HP Independent Mode, power on AOW3 */ 3508 /* HP Independent Mode, power on AOW3 */
3498 if (spec->hp_independent_mode) 3509 if (spec->hp_independent_mode)
3499 snd_hda_codec_write(codec, 0x25, 0, 3510 update_power_state(codec, 0x25, parm);
3500 AC_VERB_SET_POWER_STATE, parm);
3501 3511
3502 /* force to D0 for internal Speaker */ 3512 /* force to D0 for internal Speaker */
3503 /* MW0 (16h), AOW0 (10h) */ 3513 /* MW0 (16h), AOW0 (10h) */
3504 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, 3514 update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
3505 imux_is_smixer ? AC_PWRST_D0 : parm); 3515 update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm);
3506 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
3507 mono_out ? AC_PWRST_D0 : parm);
3508} 3516}
3509 3517
3510static int patch_vt1716S(struct hda_codec *codec) 3518static int patch_vt1716S(struct hda_codec *codec)
@@ -3580,54 +3588,45 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
3580 set_pin_power_state(codec, 0x2b, &parm); 3588 set_pin_power_state(codec, 0x2b, &parm);
3581 parm = AC_PWRST_D0; 3589 parm = AC_PWRST_D0;
3582 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ 3590 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
3583 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); 3591 update_power_state(codec, 0x1e, parm);
3584 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); 3592 update_power_state(codec, 0x1f, parm);
3585 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); 3593 update_power_state(codec, 0x10, parm);
3586 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); 3594 update_power_state(codec, 0x11, parm);
3587 3595
3588 /* outputs */ 3596 /* outputs */
3589 /* AOW0 (8h)*/ 3597 /* AOW0 (8h)*/
3590 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); 3598 update_power_state(codec, 0x8, parm);
3591 3599
3592 if (spec->codec_type == VT1802) { 3600 if (spec->codec_type == VT1802) {
3593 /* PW4 (28h), MW4 (18h), MUX4(38h) */ 3601 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3594 parm = AC_PWRST_D3; 3602 parm = AC_PWRST_D3;
3595 set_pin_power_state(codec, 0x28, &parm); 3603 set_pin_power_state(codec, 0x28, &parm);
3596 snd_hda_codec_write(codec, 0x18, 0, 3604 update_power_state(codec, 0x18, parm);
3597 AC_VERB_SET_POWER_STATE, parm); 3605 update_power_state(codec, 0x38, parm);
3598 snd_hda_codec_write(codec, 0x38, 0,
3599 AC_VERB_SET_POWER_STATE, parm);
3600 } else { 3606 } else {
3601 /* PW4 (26h), MW4 (1ch), MUX4(37h) */ 3607 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
3602 parm = AC_PWRST_D3; 3608 parm = AC_PWRST_D3;
3603 set_pin_power_state(codec, 0x26, &parm); 3609 set_pin_power_state(codec, 0x26, &parm);
3604 snd_hda_codec_write(codec, 0x1c, 0, 3610 update_power_state(codec, 0x1c, parm);
3605 AC_VERB_SET_POWER_STATE, parm); 3611 update_power_state(codec, 0x37, parm);
3606 snd_hda_codec_write(codec, 0x37, 0,
3607 AC_VERB_SET_POWER_STATE, parm);
3608 } 3612 }
3609 3613
3610 if (spec->codec_type == VT1802) { 3614 if (spec->codec_type == VT1802) {
3611 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ 3615 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3612 parm = AC_PWRST_D3; 3616 parm = AC_PWRST_D3;
3613 set_pin_power_state(codec, 0x25, &parm); 3617 set_pin_power_state(codec, 0x25, &parm);
3614 snd_hda_codec_write(codec, 0x15, 0, 3618 update_power_state(codec, 0x15, parm);
3615 AC_VERB_SET_POWER_STATE, parm); 3619 update_power_state(codec, 0x35, parm);
3616 snd_hda_codec_write(codec, 0x35, 0,
3617 AC_VERB_SET_POWER_STATE, parm);
3618 } else { 3620 } else {
3619 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ 3621 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
3620 parm = AC_PWRST_D3; 3622 parm = AC_PWRST_D3;
3621 set_pin_power_state(codec, 0x25, &parm); 3623 set_pin_power_state(codec, 0x25, &parm);
3622 snd_hda_codec_write(codec, 0x19, 0, 3624 update_power_state(codec, 0x19, parm);
3623 AC_VERB_SET_POWER_STATE, parm); 3625 update_power_state(codec, 0x35, parm);
3624 snd_hda_codec_write(codec, 0x35, 0,
3625 AC_VERB_SET_POWER_STATE, parm);
3626 } 3626 }
3627 3627
3628 if (spec->hp_independent_mode) 3628 if (spec->hp_independent_mode)
3629 snd_hda_codec_write(codec, 0x9, 0, 3629 update_power_state(codec, 0x9, AC_PWRST_D0);
3630 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3631 3630
3632 /* Class-D */ 3631 /* Class-D */
3633 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ 3632 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
@@ -3637,12 +3636,10 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
3637 set_pin_power_state(codec, 0x24, &parm); 3636 set_pin_power_state(codec, 0x24, &parm);
3638 parm = present ? AC_PWRST_D3 : AC_PWRST_D0; 3637 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
3639 if (spec->codec_type == VT1802) 3638 if (spec->codec_type == VT1802)
3640 snd_hda_codec_write(codec, 0x14, 0, 3639 update_power_state(codec, 0x14, parm);
3641 AC_VERB_SET_POWER_STATE, parm);
3642 else 3640 else
3643 snd_hda_codec_write(codec, 0x18, 0, 3641 update_power_state(codec, 0x18, parm);
3644 AC_VERB_SET_POWER_STATE, parm); 3642 update_power_state(codec, 0x34, parm);
3645 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
3646 3643
3647 /* Mono Out */ 3644 /* Mono Out */
3648 present = snd_hda_jack_detect(codec, 0x26); 3645 present = snd_hda_jack_detect(codec, 0x26);
@@ -3650,28 +3647,20 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
3650 parm = present ? AC_PWRST_D3 : AC_PWRST_D0; 3647 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
3651 if (spec->codec_type == VT1802) { 3648 if (spec->codec_type == VT1802) {
3652 /* PW15 (33h), MW8(1ch), MUX8(3ch) */ 3649 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
3653 snd_hda_codec_write(codec, 0x33, 0, 3650 update_power_state(codec, 0x33, parm);
3654 AC_VERB_SET_POWER_STATE, parm); 3651 update_power_state(codec, 0x1c, parm);
3655 snd_hda_codec_write(codec, 0x1c, 0, 3652 update_power_state(codec, 0x3c, parm);
3656 AC_VERB_SET_POWER_STATE, parm);
3657 snd_hda_codec_write(codec, 0x3c, 0,
3658 AC_VERB_SET_POWER_STATE, parm);
3659 } else { 3653 } else {
3660 /* PW15 (31h), MW8(17h), MUX8(3bh) */ 3654 /* PW15 (31h), MW8(17h), MUX8(3bh) */
3661 snd_hda_codec_write(codec, 0x31, 0, 3655 update_power_state(codec, 0x31, parm);
3662 AC_VERB_SET_POWER_STATE, parm); 3656 update_power_state(codec, 0x17, parm);
3663 snd_hda_codec_write(codec, 0x17, 0, 3657 update_power_state(codec, 0x3b, parm);
3664 AC_VERB_SET_POWER_STATE, parm);
3665 snd_hda_codec_write(codec, 0x3b, 0,
3666 AC_VERB_SET_POWER_STATE, parm);
3667 } 3658 }
3668 /* MW9 (21h) */ 3659 /* MW9 (21h) */
3669 if (imux_is_smixer || !is_aa_path_mute(codec)) 3660 if (imux_is_smixer || !is_aa_path_mute(codec))
3670 snd_hda_codec_write(codec, 0x21, 0, 3661 update_power_state(codec, 0x21, AC_PWRST_D0);
3671 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3672 else 3662 else
3673 snd_hda_codec_write(codec, 0x21, 0, 3663 update_power_state(codec, 0x21, AC_PWRST_D3);
3674 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3675} 3664}
3676 3665
3677/* patch for vt2002P */ 3666/* patch for vt2002P */
@@ -3731,30 +3720,28 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3731 set_pin_power_state(codec, 0x2b, &parm); 3720 set_pin_power_state(codec, 0x2b, &parm);
3732 parm = AC_PWRST_D0; 3721 parm = AC_PWRST_D0;
3733 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ 3722 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
3734 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); 3723 update_power_state(codec, 0x1e, parm);
3735 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); 3724 update_power_state(codec, 0x1f, parm);
3736 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); 3725 update_power_state(codec, 0x10, parm);
3737 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); 3726 update_power_state(codec, 0x11, parm);
3738 3727
3739 /* outputs */ 3728 /* outputs */
3740 /* AOW0 (8h)*/ 3729 /* AOW0 (8h)*/
3741 snd_hda_codec_write(codec, 0x8, 0, 3730 update_power_state(codec, 0x8, AC_PWRST_D0);
3742 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3743 3731
3744 /* PW4 (28h), MW4 (18h), MUX4(38h) */ 3732 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3745 parm = AC_PWRST_D3; 3733 parm = AC_PWRST_D3;
3746 set_pin_power_state(codec, 0x28, &parm); 3734 set_pin_power_state(codec, 0x28, &parm);
3747 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); 3735 update_power_state(codec, 0x18, parm);
3748 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); 3736 update_power_state(codec, 0x38, parm);
3749 3737
3750 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ 3738 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3751 parm = AC_PWRST_D3; 3739 parm = AC_PWRST_D3;
3752 set_pin_power_state(codec, 0x25, &parm); 3740 set_pin_power_state(codec, 0x25, &parm);
3753 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); 3741 update_power_state(codec, 0x15, parm);
3754 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); 3742 update_power_state(codec, 0x35, parm);
3755 if (spec->hp_independent_mode) 3743 if (spec->hp_independent_mode)
3756 snd_hda_codec_write(codec, 0x9, 0, 3744 update_power_state(codec, 0x9, AC_PWRST_D0);
3757 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3758 3745
3759 /* Internal Speaker */ 3746 /* Internal Speaker */
3760 /* PW0 (24h), MW0(14h), MUX0(34h) */ 3747 /* PW0 (24h), MW0(14h), MUX0(34h) */
@@ -3763,15 +3750,11 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3763 parm = AC_PWRST_D3; 3750 parm = AC_PWRST_D3;
3764 set_pin_power_state(codec, 0x24, &parm); 3751 set_pin_power_state(codec, 0x24, &parm);
3765 if (present) { 3752 if (present) {
3766 snd_hda_codec_write(codec, 0x14, 0, 3753 update_power_state(codec, 0x14, AC_PWRST_D3);
3767 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3754 update_power_state(codec, 0x34, AC_PWRST_D3);
3768 snd_hda_codec_write(codec, 0x34, 0,
3769 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3770 } else { 3755 } else {
3771 snd_hda_codec_write(codec, 0x14, 0, 3756 update_power_state(codec, 0x14, AC_PWRST_D0);
3772 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 3757 update_power_state(codec, 0x34, AC_PWRST_D0);
3773 snd_hda_codec_write(codec, 0x34, 0,
3774 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3775 } 3758 }
3776 3759
3777 3760
@@ -3782,26 +3765,20 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3782 parm = AC_PWRST_D3; 3765 parm = AC_PWRST_D3;
3783 set_pin_power_state(codec, 0x31, &parm); 3766 set_pin_power_state(codec, 0x31, &parm);
3784 if (present) { 3767 if (present) {
3785 snd_hda_codec_write(codec, 0x1c, 0, 3768 update_power_state(codec, 0x1c, AC_PWRST_D3);
3786 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3769 update_power_state(codec, 0x3c, AC_PWRST_D3);
3787 snd_hda_codec_write(codec, 0x3c, 0, 3770 update_power_state(codec, 0x3e, AC_PWRST_D3);
3788 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3789 snd_hda_codec_write(codec, 0x3e, 0,
3790 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3791 } else { 3771 } else {
3792 snd_hda_codec_write(codec, 0x1c, 0, 3772 update_power_state(codec, 0x1c, AC_PWRST_D0);
3793 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 3773 update_power_state(codec, 0x3c, AC_PWRST_D0);
3794 snd_hda_codec_write(codec, 0x3c, 0, 3774 update_power_state(codec, 0x3e, AC_PWRST_D0);
3795 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3796 snd_hda_codec_write(codec, 0x3e, 0,
3797 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3798 } 3775 }
3799 3776
3800 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ 3777 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
3801 parm = AC_PWRST_D3; 3778 parm = AC_PWRST_D3;
3802 set_pin_power_state(codec, 0x33, &parm); 3779 set_pin_power_state(codec, 0x33, &parm);
3803 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); 3780 update_power_state(codec, 0x1d, parm);
3804 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); 3781 update_power_state(codec, 0x3d, parm);
3805 3782
3806} 3783}
3807 3784
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 9f3b01bb72c..e0a4263baa2 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2102,6 +2102,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
2102 }, 2102 },
2103 { 2103 {
2104 .subvendor = 0x161f, 2104 .subvendor = 0x161f,
2105 .subdevice = 0x202f,
2106 .name = "Gateway M520",
2107 .type = AC97_TUNE_INV_EAPD
2108 },
2109 {
2110 .subvendor = 0x161f,
2105 .subdevice = 0x203a, 2111 .subdevice = 0x203a,
2106 .name = "Gateway 4525GZ", /* AD1981B */ 2112 .name = "Gateway 4525GZ", /* AD1981B */
2107 .type = AC97_TUNE_INV_EAPD 2113 .type = AC97_TUNE_INV_EAPD
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 26c7e8bcb22..c0dbb52d45b 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl,
618 mutex_lock(&chip->mutex); 618 mutex_lock(&chip->mutex);
619 reg = oxygen_read_ac97(chip, codec, index); 619 reg = oxygen_read_ac97(chip, codec, index);
620 mutex_unlock(&chip->mutex); 620 mutex_unlock(&chip->mutex);
621 value->value.integer.value[0] = 31 - (reg & 0x1f); 621 if (!stereo) {
622 if (stereo) 622 value->value.integer.value[0] = 31 - (reg & 0x1f);
623 value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); 623 } else {
624 value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
625 value->value.integer.value[1] = 31 - (reg & 0x1f);
626 }
624 return 0; 627 return 0;
625} 628}
626 629
@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
636 639
637 mutex_lock(&chip->mutex); 640 mutex_lock(&chip->mutex);
638 oldreg = oxygen_read_ac97(chip, codec, index); 641 oldreg = oxygen_read_ac97(chip, codec, index);
639 newreg = oldreg; 642 if (!stereo) {
640 newreg = (newreg & ~0x1f) | 643 newreg = oldreg & ~0x1f;
641 (31 - (value->value.integer.value[0] & 0x1f)); 644 newreg |= 31 - (value->value.integer.value[0] & 0x1f);
642 if (stereo) 645 } else {
643 newreg = (newreg & ~0x1f00) | 646 newreg = oldreg & ~0x1f1f;
644 ((31 - (value->value.integer.value[1] & 0x1f)) << 8); 647 newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
645 else 648 newreg |= 31 - (value->value.integer.value[1] & 0x1f);
646 newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); 649 }
647 change = newreg != oldreg; 650 change = newreg != oldreg;
648 if (change) 651 if (change)
649 oxygen_write_ac97(chip, codec, index, newreg); 652 oxygen_write_ac97(chip, codec, index, newreg);