aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
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/patch_realtek.c
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/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c111
1 files changed, 92 insertions, 19 deletions
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;