aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_conexant.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-03-10 09:30:40 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-10 10:13:17 -0400
commitdd5746a85cb21ea5b3afca0b569586a05aa56846 (patch)
tree56efed83d982a2176b2c4826e9a3c42e5693ea0d /sound/pci/hda/patch_conexant.c
parent6dfc0d2c4b9a5455c60e0b9ee95bbf22fc516cef (diff)
ALSA: hda - Create vmaster for conexant codecs
Instead of binding volumes, create a virtual master volume for Conexant codecs. This allows separate HP and speaker volume controls. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r--sound/pci/hda/patch_conexant.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 1938e92e1f03..e1476d6d8b39 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -58,6 +58,7 @@ struct conexant_spec {
58 58
59 struct snd_kcontrol_new *mixers[5]; 59 struct snd_kcontrol_new *mixers[5];
60 int num_mixers; 60 int num_mixers;
61 hda_nid_t vmaster_nid;
61 62
62 const struct hda_verb *init_verbs[5]; /* initialization verbs 63 const struct hda_verb *init_verbs[5]; /* initialization verbs
63 * don't forget NULL 64 * don't forget NULL
@@ -462,6 +463,18 @@ static void conexant_free(struct hda_codec *codec)
462 kfree(codec->spec); 463 kfree(codec->spec);
463} 464}
464 465
466static const char *slave_vols[] = {
467 "Headphone Playback Volume",
468 "Speaker Playback Volume",
469 NULL
470};
471
472static const char *slave_sws[] = {
473 "Headphone Playback Switch",
474 "Speaker Playback Switch",
475 NULL
476};
477
465static int conexant_build_controls(struct hda_codec *codec) 478static int conexant_build_controls(struct hda_codec *codec)
466{ 479{
467 struct conexant_spec *spec = codec->spec; 480 struct conexant_spec *spec = codec->spec;
@@ -489,6 +502,26 @@ static int conexant_build_controls(struct hda_codec *codec)
489 if (err < 0) 502 if (err < 0)
490 return err; 503 return err;
491 } 504 }
505
506 /* if we have no master control, let's create it */
507 if (spec->vmaster_nid &&
508 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
509 unsigned int vmaster_tlv[4];
510 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
511 HDA_OUTPUT, vmaster_tlv);
512 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
513 vmaster_tlv, slave_vols);
514 if (err < 0)
515 return err;
516 }
517 if (spec->vmaster_nid &&
518 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
519 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
520 NULL, slave_sws);
521 if (err < 0)
522 return err;
523 }
524
492 return 0; 525 return 0;
493} 526}
494 527
@@ -1182,16 +1215,6 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1182 return 1; 1215 return 1;
1183} 1216}
1184 1217
1185/* bind volumes of both NID 0x13 (Headphones) and 0x1d (Speakers) */
1186static struct hda_bind_ctls cxt5047_bind_master_vol = {
1187 .ops = &snd_hda_bind_vol,
1188 .values = {
1189 HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
1190 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
1191 0
1192 },
1193};
1194
1195/* mute internal speaker if HP is plugged */ 1218/* mute internal speaker if HP is plugged */
1196static void cxt5047_hp_automute(struct hda_codec *codec) 1219static void cxt5047_hp_automute(struct hda_codec *codec)
1197{ 1220{
@@ -1311,7 +1334,8 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = {
1311 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), 1334 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1312 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), 1335 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1313 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), 1336 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1314 HDA_BIND_VOL("Master Playback Volume", &cxt5047_bind_master_vol), 1337 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
1315 { 1339 {
1316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1340 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1317 .name = "Master Playback Switch", 1341 .name = "Master Playback Switch",
@@ -1631,6 +1655,7 @@ static int patch_cxt5047(struct hda_codec *codec)
1631 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; 1655 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1632#endif 1656#endif
1633 } 1657 }
1658 spec->vmaster_nid = 0x13;
1634 return 0; 1659 return 0;
1635} 1660}
1636 1661