aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-01-10 10:53:55 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:54 -0500
commit2134ea4f37d36addbe86d4901f6c67a22a5db006 (patch)
tree804d187d5c46d71246db2d8919a59e2e7feef956 /sound/pci/hda
parent3b0a5f22d4649433a5842ffc7313803292e95718 (diff)
[ALSA] hda-codec - Add virtual master controls
Add master controls using vmaster to codecs that have no real hardware master volume registers. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_codec.c60
-rw-r--r--sound/pci/hda/hda_local.h7
-rw-r--r--sound/pci/hda/patch_analog.c69
-rw-r--r--sound/pci/hda/patch_realtek.c111
-rw-r--r--sound/pci/hda/patch_sigmatel.c48
5 files changed, 276 insertions, 19 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a2b40dc372c9..caacc58c0813 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1012,6 +1012,66 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1012 return 0; 1012 return 0;
1013} 1013}
1014 1014
1015/*
1016 * set (static) TLV for virtual master volume; recalculated as max 0dB
1017 */
1018void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1019 unsigned int *tlv)
1020{
1021 u32 caps;
1022 int nums, step;
1023
1024 caps = query_amp_caps(codec, nid, dir);
1025 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1026 step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1027 step = (step + 1) * 25;
1028 tlv[0] = SNDRV_CTL_TLVT_DB_SCALE;
1029 tlv[1] = 2 * sizeof(unsigned int);
1030 tlv[2] = -nums * step;
1031 tlv[3] = step;
1032}
1033
1034/* find a mixer control element with the given name */
1035struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1036 const char *name)
1037{
1038 struct snd_ctl_elem_id id;
1039 memset(&id, 0, sizeof(id));
1040 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1041 strcpy(id.name, name);
1042 return snd_ctl_find_id(codec->bus->card, &id);
1043}
1044
1045/* create a virtual master control and add slaves */
1046int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1047 unsigned int *tlv, const char **slaves)
1048{
1049 struct snd_kcontrol *kctl;
1050 const char **s;
1051 int err;
1052
1053 kctl = snd_ctl_make_virtual_master(name, tlv);
1054 if (!kctl)
1055 return -ENOMEM;
1056 err = snd_ctl_add(codec->bus->card, kctl);
1057 if (err < 0)
1058 return err;
1059
1060 for (s = slaves; *s; s++) {
1061 struct snd_kcontrol *sctl;
1062
1063 sctl = snd_hda_find_mixer_ctl(codec, *s);
1064 if (!sctl) {
1065 snd_printdd("Cannot find slave %s, skipped\n", *s);
1066 continue;
1067 }
1068 err = snd_ctl_add_slave(kctl, sctl);
1069 if (err < 0)
1070 return err;
1071 }
1072 return 0;
1073}
1074
1015/* switch */ 1075/* switch */
1016int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, 1076int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1017 struct snd_ctl_elem_info *uinfo) 1077 struct snd_ctl_elem_info *uinfo)
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index e09f41bd6b2a..ddc61a1d1153 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -90,6 +90,13 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
90void snd_hda_codec_resume_amp(struct hda_codec *codec); 90void snd_hda_codec_resume_amp(struct hda_codec *codec);
91#endif 91#endif
92 92
93void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
94 unsigned int *tlv);
95struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
96 const char *name);
97int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
98 unsigned int *tlv, const char **slaves);
99
93/* amp value bits */ 100/* amp value bits */
94#define HDA_AMP_MUTE 0x80 101#define HDA_AMP_MUTE 0x80
95#define HDA_AMP_UNMUTE 0x00 102#define HDA_AMP_UNMUTE 0x00
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 6664a0688ef5..b0755407be9d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -78,6 +78,11 @@ struct ad198x_spec {
78#ifdef CONFIG_SND_HDA_POWER_SAVE 78#ifdef CONFIG_SND_HDA_POWER_SAVE
79 struct hda_loopback_check loopback; 79 struct hda_loopback_check loopback;
80#endif 80#endif
81 /* for virtual master */
82 hda_nid_t vmaster_nid;
83 u32 vmaster_tlv[4];
84 const char **slave_vols;
85 const char **slave_sws;
81}; 86};
82 87
83/* 88/*
@@ -125,6 +130,28 @@ static int ad198x_init(struct hda_codec *codec)
125 return 0; 130 return 0;
126} 131}
127 132
133static const char *ad_slave_vols[] = {
134 "Front Playback Volume",
135 "Surround Playback Volume",
136 "Center Playback Volume",
137 "LFE Playback Volume",
138 "Side Playback Volume",
139 "Headphone Playback Volume",
140 "Mono Playback Volume",
141 NULL
142};
143
144static const char *ad_slave_sws[] = {
145 "Front Playback Switch",
146 "Surround Playback Switch",
147 "Center Playback Switch",
148 "LFE Playback Switch",
149 "Side Playback Switch",
150 "Headphone Playback Switch",
151 "Mono Playback Switch",
152 NULL
153};
154
128static int ad198x_build_controls(struct hda_codec *codec) 155static int ad198x_build_controls(struct hda_codec *codec)
129{ 156{
130 struct ad198x_spec *spec = codec->spec; 157 struct ad198x_spec *spec = codec->spec;
@@ -146,6 +173,27 @@ static int ad198x_build_controls(struct hda_codec *codec)
146 if (err < 0) 173 if (err < 0)
147 return err; 174 return err;
148 } 175 }
176
177 /* if we have no master control, let's create it */
178 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
179 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
180 HDA_OUTPUT, spec->vmaster_tlv);
181 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
182 spec->vmaster_tlv,
183 (spec->slave_vols ?
184 spec->slave_vols : ad_slave_vols));
185 if (err < 0)
186 return err;
187 }
188 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
189 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
190 NULL,
191 (spec->slave_sws ?
192 spec->slave_sws : ad_slave_sws));
193 if (err < 0)
194 return err;
195 }
196
149 return 0; 197 return 0;
150} 198}
151 199
@@ -899,6 +947,7 @@ static int patch_ad1986a(struct hda_codec *codec)
899#ifdef CONFIG_SND_HDA_POWER_SAVE 947#ifdef CONFIG_SND_HDA_POWER_SAVE
900 spec->loopback.amplist = ad1986a_loopbacks; 948 spec->loopback.amplist = ad1986a_loopbacks;
901#endif 949#endif
950 spec->vmaster_nid = 0x1b;
902 951
903 codec->patch_ops = ad198x_patch_ops; 952 codec->patch_ops = ad198x_patch_ops;
904 953
@@ -1141,6 +1190,7 @@ static int patch_ad1983(struct hda_codec *codec)
1141#ifdef CONFIG_SND_HDA_POWER_SAVE 1190#ifdef CONFIG_SND_HDA_POWER_SAVE
1142 spec->loopback.amplist = ad1983_loopbacks; 1191 spec->loopback.amplist = ad1983_loopbacks;
1143#endif 1192#endif
1193 spec->vmaster_nid = 0x05;
1144 1194
1145 codec->patch_ops = ad198x_patch_ops; 1195 codec->patch_ops = ad198x_patch_ops;
1146 1196
@@ -1537,6 +1587,7 @@ static int patch_ad1981(struct hda_codec *codec)
1537#ifdef CONFIG_SND_HDA_POWER_SAVE 1587#ifdef CONFIG_SND_HDA_POWER_SAVE
1538 spec->loopback.amplist = ad1981_loopbacks; 1588 spec->loopback.amplist = ad1981_loopbacks;
1539#endif 1589#endif
1590 spec->vmaster_nid = 0x05;
1540 1591
1541 codec->patch_ops = ad198x_patch_ops; 1592 codec->patch_ops = ad198x_patch_ops;
1542 1593
@@ -2850,6 +2901,7 @@ static int patch_ad1988(struct hda_codec *codec)
2850#ifdef CONFIG_SND_HDA_POWER_SAVE 2901#ifdef CONFIG_SND_HDA_POWER_SAVE
2851 spec->loopback.amplist = ad1988_loopbacks; 2902 spec->loopback.amplist = ad1988_loopbacks;
2852#endif 2903#endif
2904 spec->vmaster_nid = 0x04;
2853 2905
2854 return 0; 2906 return 0;
2855} 2907}
@@ -3016,6 +3068,19 @@ static struct hda_amp_list ad1884_loopbacks[] = {
3016}; 3068};
3017#endif 3069#endif
3018 3070
3071static const char *ad1884_slave_vols[] = {
3072 "PCM Playback Volume",
3073 "Mic Playback Volume",
3074 "Mono Playback Volume",
3075 "Front Mic Playback Volume",
3076 "Mic Playback Volume",
3077 "CD Playback Volume",
3078 "Internal Mic Playback Volume",
3079 "Docking Mic Playback Volume"
3080 "Beep Playback Volume",
3081 NULL
3082};
3083
3019static int patch_ad1884(struct hda_codec *codec) 3084static int patch_ad1884(struct hda_codec *codec)
3020{ 3085{
3021 struct ad198x_spec *spec; 3086 struct ad198x_spec *spec;
@@ -3043,6 +3108,9 @@ static int patch_ad1884(struct hda_codec *codec)
3043#ifdef CONFIG_SND_HDA_POWER_SAVE 3108#ifdef CONFIG_SND_HDA_POWER_SAVE
3044 spec->loopback.amplist = ad1884_loopbacks; 3109 spec->loopback.amplist = ad1884_loopbacks;
3045#endif 3110#endif
3111 spec->vmaster_nid = 0x04;
3112 /* we need to cover all playback volumes */
3113 spec->slave_vols = ad1884_slave_vols;
3046 3114
3047 codec->patch_ops = ad198x_patch_ops; 3115 codec->patch_ops = ad198x_patch_ops;
3048 3116
@@ -3485,6 +3553,7 @@ static int patch_ad1882(struct hda_codec *codec)
3485#ifdef CONFIG_SND_HDA_POWER_SAVE 3553#ifdef CONFIG_SND_HDA_POWER_SAVE
3486 spec->loopback.amplist = ad1882_loopbacks; 3554 spec->loopback.amplist = ad1882_loopbacks;
3487#endif 3555#endif
3556 spec->vmaster_nid = 0x04;
3488 3557
3489 codec->patch_ops = ad198x_patch_ops; 3558 codec->patch_ops = ad198x_patch_ops;
3490 3559
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9184586c9721..4bc7f3daeab0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -262,6 +262,9 @@ struct alc_spec {
262 unsigned int sense_updated: 1; 262 unsigned int sense_updated: 1;
263 unsigned int jack_present: 1; 263 unsigned int jack_present: 1;
264 264
265 /* for virtual master */
266 hda_nid_t vmaster_nid;
267 u32 vmaster_tlv[4];
265#ifdef CONFIG_SND_HDA_POWER_SAVE 268#ifdef CONFIG_SND_HDA_POWER_SAVE
266 struct hda_loopback_check loopback; 269 struct hda_loopback_check loopback;
267#endif 270#endif
@@ -1309,8 +1312,8 @@ static hda_nid_t alc880_f1734_dac_nids[1] = {
1309static struct snd_kcontrol_new alc880_f1734_mixer[] = { 1312static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1310 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1313 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1311 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 1314 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1312 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1315 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1313 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 1316 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1314 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1317 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1315 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1318 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1316 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -1408,10 +1411,10 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1408 1411
1409/* Uniwill */ 1412/* Uniwill */
1410static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 1413static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1411 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1414 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1412 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1415 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1413 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1416 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1414 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1417 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1415 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 1418 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1419 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1420 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
@@ -1451,16 +1454,50 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1451}; 1454};
1452 1455
1453static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 1456static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1454 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1457 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1455 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), 1458 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1456 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1459 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1457 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), 1460 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1460 { } /* end */ 1463 { } /* end */
1461}; 1464};
1462 1465
1463/* 1466/*
1467 * virtual master controls
1468 */
1469
1470/*
1471 * slave controls for virtual master
1472 */
1473static const char *alc_slave_vols[] = {
1474 "Front Playback Volume",
1475 "Surround Playback Volume",
1476 "Center Playback Volume",
1477 "LFE Playback Volume",
1478 "Side Playback Volume",
1479 "Headphone Playback Volume",
1480 "Speaker Playback Volume",
1481 "Mono Playback Volume",
1482 "iSpeaker Playback Volume",
1483 "Line-Out Playback Volume",
1484 NULL,
1485};
1486
1487static const char *alc_slave_sws[] = {
1488 "Front Playback Switch",
1489 "Surround Playback Switch",
1490 "Center Playback Switch",
1491 "LFE Playback Switch",
1492 "Side Playback Switch",
1493 "Headphone Playback Switch",
1494 "Speaker Playback Switch",
1495 "Mono Playback Switch",
1496 "iSpeaker Playback Switch",
1497 NULL,
1498};
1499
1500/*
1464 * build control elements 1501 * build control elements
1465 */ 1502 */
1466static int alc_build_controls(struct hda_codec *codec) 1503static int alc_build_controls(struct hda_codec *codec)
@@ -1486,6 +1523,23 @@ static int alc_build_controls(struct hda_codec *codec)
1486 if (err < 0) 1523 if (err < 0)
1487 return err; 1524 return err;
1488 } 1525 }
1526
1527 /* if we have no master control, let's create it */
1528 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1529 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1530 HDA_OUTPUT, spec->vmaster_tlv);
1531 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1532 spec->vmaster_tlv, alc_slave_vols);
1533 if (err < 0)
1534 return err;
1535 }
1536 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1537 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1538 NULL, alc_slave_sws);
1539 if (err < 0)
1540 return err;
1541 }
1542
1489 return 0; 1543 return 0;
1490} 1544}
1491 1545
@@ -2034,8 +2088,8 @@ static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2034 2088
2035static struct snd_kcontrol_new alc880_lg_mixer[] = { 2089static struct snd_kcontrol_new alc880_lg_mixer[] = {
2036 /* FIXME: it's not really "master" but front channels */ 2090 /* FIXME: it's not really "master" but front channels */
2037 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2091 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2038 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), 2092 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2039 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2093 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2040 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 2094 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 2095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
@@ -3592,6 +3646,8 @@ static int patch_alc880(struct hda_codec *codec)
3592 } 3646 }
3593 } 3647 }
3594 3648
3649 spec->vmaster_nid = 0x0c;
3650
3595 codec->patch_ops = alc_patch_ops; 3651 codec->patch_ops = alc_patch_ops;
3596 if (board_config == ALC880_AUTO) 3652 if (board_config == ALC880_AUTO)
3597 spec->init_hook = alc880_auto_init; 3653 spec->init_hook = alc880_auto_init;
@@ -4969,6 +5025,8 @@ static int patch_alc260(struct hda_codec *codec)
4969 spec->stream_digital_playback = &alc260_pcm_digital_playback; 5025 spec->stream_digital_playback = &alc260_pcm_digital_playback;
4970 spec->stream_digital_capture = &alc260_pcm_digital_capture; 5026 spec->stream_digital_capture = &alc260_pcm_digital_capture;
4971 5027
5028 spec->vmaster_nid = 0x08;
5029
4972 codec->patch_ops = alc_patch_ops; 5030 codec->patch_ops = alc_patch_ops;
4973 if (board_config == ALC260_AUTO) 5031 if (board_config == ALC260_AUTO)
4974 spec->init_hook = alc260_auto_init; 5032 spec->init_hook = alc260_auto_init;
@@ -5169,15 +5227,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
5169}; 5227};
5170 5228
5171static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 5229static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5172 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT), 5230 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5173 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT), 5231 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5174 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT), 5232 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5175 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT), 5233 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5176 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT), 5234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5177 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT), 5235 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 5236 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5179 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 5237 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5180 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT), 5238 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5181 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 5239 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5182 { } /* end */ 5240 { } /* end */
5183}; 5241};
@@ -6181,6 +6239,8 @@ static int patch_alc882(struct hda_codec *codec)
6181 } 6239 }
6182 } 6240 }
6183 6241
6242 spec->vmaster_nid = 0x0c;
6243
6184 codec->patch_ops = alc_patch_ops; 6244 codec->patch_ops = alc_patch_ops;
6185 if (board_config == ALC882_AUTO) 6245 if (board_config == ALC882_AUTO)
6186 spec->init_hook = alc882_auto_init; 6246 spec->init_hook = alc882_auto_init;
@@ -7763,6 +7823,8 @@ static int patch_alc883(struct hda_codec *codec)
7763 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 7823 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7764 } 7824 }
7765 7825
7826 spec->vmaster_nid = 0x0c;
7827
7766 codec->patch_ops = alc_patch_ops; 7828 codec->patch_ops = alc_patch_ops;
7767 if (board_config == ALC883_AUTO) 7829 if (board_config == ALC883_AUTO)
7768 spec->init_hook = alc883_auto_init; 7830 spec->init_hook = alc883_auto_init;
@@ -9123,6 +9185,8 @@ static int patch_alc262(struct hda_codec *codec)
9123 } 9185 }
9124 } 9186 }
9125 9187
9188 spec->vmaster_nid = 0x0c;
9189
9126 codec->patch_ops = alc_patch_ops; 9190 codec->patch_ops = alc_patch_ops;
9127 if (board_config == ALC262_AUTO) 9191 if (board_config == ALC262_AUTO)
9128 spec->init_hook = alc262_auto_init; 9192 spec->init_hook = alc262_auto_init;
@@ -9848,6 +9912,9 @@ static int patch_alc268(struct hda_codec *codec)
9848 } 9912 }
9849 } 9913 }
9850 } 9914 }
9915
9916 spec->vmaster_nid = 0x02;
9917
9851 codec->patch_ops = alc_patch_ops; 9918 codec->patch_ops = alc_patch_ops;
9852 if (board_config == ALC268_AUTO) 9919 if (board_config == ALC268_AUTO)
9853 spec->init_hook = alc268_auto_init; 9920 spec->init_hook = alc268_auto_init;
@@ -11358,6 +11425,8 @@ static int patch_alc861(struct hda_codec *codec)
11358 spec->stream_digital_playback = &alc861_pcm_digital_playback; 11425 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11359 spec->stream_digital_capture = &alc861_pcm_digital_capture; 11426 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11360 11427
11428 spec->vmaster_nid = 0x03;
11429
11361 codec->patch_ops = alc_patch_ops; 11430 codec->patch_ops = alc_patch_ops;
11362 if (board_config == ALC861_AUTO) 11431 if (board_config == ALC861_AUTO)
11363 spec->init_hook = alc861_auto_init; 11432 spec->init_hook = alc861_auto_init;
@@ -12334,6 +12403,8 @@ static int patch_alc861vd(struct hda_codec *codec)
12334 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 12403 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12335 spec->num_mixers++; 12404 spec->num_mixers++;
12336 12405
12406 spec->vmaster_nid = 0x02;
12407
12337 codec->patch_ops = alc_patch_ops; 12408 codec->patch_ops = alc_patch_ops;
12338 12409
12339 if (board_config == ALC861VD_AUTO) 12410 if (board_config == ALC861VD_AUTO)
@@ -13305,6 +13376,8 @@ static int patch_alc662(struct hda_codec *codec)
13305 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 13376 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13306 } 13377 }
13307 13378
13379 spec->vmaster_nid = 0x02;
13380
13308 codec->patch_ops = alc_patch_ops; 13381 codec->patch_ops = alc_patch_ops;
13309 if (board_config == ALC662_AUTO) 13382 if (board_config == ALC662_AUTO)
13310 spec->init_hook = alc662_auto_init; 13383 spec->init_hook = alc662_auto_init;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a0af8680dd0d..190e112f2f8e 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -170,6 +170,9 @@ struct sigmatel_spec {
170 struct snd_kcontrol_new *kctl_alloc; 170 struct snd_kcontrol_new *kctl_alloc;
171 struct hda_input_mux private_dimux; 171 struct hda_input_mux private_dimux;
172 struct hda_input_mux private_imux; 172 struct hda_input_mux private_imux;
173
174 /* virtual master */
175 unsigned int vmaster_tlv[4];
173}; 176};
174 177
175static hda_nid_t stac9200_adc_nids[1] = { 178static hda_nid_t stac9200_adc_nids[1] = {
@@ -794,6 +797,34 @@ static struct snd_kcontrol_new stac_dmux_mixer = {
794 .put = stac92xx_dmux_enum_put, 797 .put = stac92xx_dmux_enum_put,
795}; 798};
796 799
800static const char *slave_vols[] = {
801 "Front Playback Volume",
802 "Surround Playback Volume",
803 "Center Playback Volume",
804 "LFE Playback Volume",
805 "Side Playback Volume",
806 "Headphone Playback Volume",
807 "Headphone Playback Volume",
808 "Speaker Playback Volume",
809 "External Speaker Playback Volume",
810 "Speaker2 Playback Volume",
811 NULL
812};
813
814static const char *slave_sws[] = {
815 "Front Playback Switch",
816 "Surround Playback Switch",
817 "Center Playback Switch",
818 "LFE Playback Switch",
819 "Side Playback Switch",
820 "Headphone Playback Switch",
821 "Headphone Playback Switch",
822 "Speaker Playback Switch",
823 "External Speaker Playback Switch",
824 "Speaker2 Playback Switch",
825 NULL
826};
827
797static int stac92xx_build_controls(struct hda_codec *codec) 828static int stac92xx_build_controls(struct hda_codec *codec)
798{ 829{
799 struct sigmatel_spec *spec = codec->spec; 830 struct sigmatel_spec *spec = codec->spec;
@@ -827,6 +858,23 @@ static int stac92xx_build_controls(struct hda_codec *codec)
827 if (err < 0) 858 if (err < 0)
828 return err; 859 return err;
829 } 860 }
861
862 /* if we have no master control, let's create it */
863 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
864 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
865 HDA_OUTPUT, spec->vmaster_tlv);
866 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
867 spec->vmaster_tlv, slave_vols);
868 if (err < 0)
869 return err;
870 }
871 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
872 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
873 NULL, slave_sws);
874 if (err < 0)
875 return err;
876 }
877
830 return 0; 878 return 0;
831} 879}
832 880