From a215d6b0766d7377d29d4087103370f5951803b2 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 7 May 2008 12:05:10 +0200 Subject: [PATCH] --- yaml --- r: 99021 b: refs/heads/master c: 87af38dafe4f930921b9217c21ec6d72cad56bcc h: refs/heads/master i: 99019: 84c2d8faf55785e942e05745192ef3cef1137ab1 v: v3 --- [refs] | 2 +- trunk/sound/drivers/Kconfig | 1 + trunk/sound/pci/ac97/ac97_patch.c | 76 +++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 5ae79e223f98..179171386b8e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1894c59fdb63692f5ba2576875cc558b856935ca +refs/heads/master: 87af38dafe4f930921b9217c21ec6d72cad56bcc diff --git a/trunk/sound/drivers/Kconfig b/trunk/sound/drivers/Kconfig index 602b58e3b55d..159137bf4c11 100644 --- a/trunk/sound/drivers/Kconfig +++ b/trunk/sound/drivers/Kconfig @@ -58,6 +58,7 @@ config SND_AC97_CODEC tristate select SND_PCM select AC97_BUS + select SND_VMASTER config SND_DUMMY tristate "Dummy (/dev/null) soundcard" diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index 1292dcee072d..92817f7d46d2 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -3352,8 +3352,66 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), }; +static const char *slave_vols_vt1616[] = { + "Front Playback Volume", + "Surround Playback Volume", + "Center Playback Volume", + "LFE Playback Volume", + NULL +}; + +static const char *slave_sws_vt1616[] = { + "Front Playback Switch", + "Surround Playback Switch", + "Center Playback Switch", + "LFE Playback Switch", + NULL +}; + +/* find a mixer control element with the given name */ +static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, + const char *name) +{ + struct snd_ctl_elem_id id; + memset(&id, 0, sizeof(id)); + id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + strcpy(id.name, name); + return snd_ctl_find_id(ac97->bus->card, &id); +} + +/* create a virtual master control and add slaves */ +int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, + const unsigned int *tlv, const char **slaves) +{ + struct snd_kcontrol *kctl; + const char **s; + int err; + + kctl = snd_ctl_make_virtual_master(name, tlv); + if (!kctl) + return -ENOMEM; + err = snd_ctl_add(ac97->bus->card, kctl); + if (err < 0) + return err; + + for (s = slaves; *s; s++) { + struct snd_kcontrol *sctl; + + sctl = snd_ac97_find_mixer_ctl(ac97, *s); + if (!sctl) { + snd_printdd("Cannot find slave %s, skipped\n", *s); + continue; + } + err = snd_ctl_add_slave(kctl, sctl); + if (err < 0) + return err; + } + return 0; +} + static int patch_vt1616_specific(struct snd_ac97 * ac97) { + struct snd_kcontrol *kctl; int err; if (snd_ac97_try_bit(ac97, 0x5a, 9)) @@ -3361,6 +3419,24 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97) return err; if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0) return err; + + /* There is already a misnamed master switch. Rename it. */ + kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume"); + if (!kctl) + return -EINVAL; + + snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback"); + + err = snd_ac97_add_vmaster(ac97, "Master Playback Volume", + kctl->tlv.p, slave_vols_vt1616); + if (err < 0) + return err; + + err = snd_ac97_add_vmaster(ac97, "Master Playback Switch", + NULL, slave_sws_vt1616); + if (err < 0) + return err; + return 0; }