On Sat, Mar 22, 2008 at 10:09:23AM +0100, Takashi Iwai wrote: > At Fri, 21 Mar 2008 15:08:55 -0400, > Daniel Jacobowitz wrote: > > > > On Wed, Jan 30, 2008 at 04:27:07PM +0100, Takashi Iwai wrote: > > > Because HD-audio is the only user, so far. I don't want to expand the > > > core stuff (and kconfig) unless really needed. > > > > I said I'd want this for ice1724 / vt1616, and I finally got time to > > do it. What do you think of this patch? I'm happily using it. > > Well, don't forget to check HG version before you submit a patch :) Whoops! This version works with the hg tree. The new snd_ac97_add_vmaster is mostly similar to the hda version so it might make sense to put that in vmaster.c instead. From: Daniel Jacobowitz <dan@xxxxxxxxxxxxxxxx> Enable VMASTER for VT1616 / VT1617A. Signed-off-by: Daniel Jacobowitz <dan@xxxxxxxxxxxxxxxx> diff -r 0d5f43585ca7 drivers/Kconfig --- a/drivers/Kconfig Sat Mar 22 10:26:05 2008 +0100 +++ b/drivers/Kconfig Sat Mar 22 11:02:16 2008 -0400 @@ -44,6 +44,7 @@ config SND_AC97_CODEC tristate select SND_PCM select AC97_BUS + select SND_VMASTER config SND_DUMMY tristate "Dummy (/dev/null) soundcard" diff -r 0d5f43585ca7 pci/ac97/ac97_patch.c --- a/pci/ac97/ac97_patch.c Sat Mar 22 10:26:05 2008 +0100 +++ b/pci/ac97/ac97_patch.c Sat Mar 22 11:02:16 2008 -0400 @@ -3332,8 +3332,66 @@ AC97_SINGLE("Downmix Surround to Front", 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)) @@ -3341,6 +3399,24 @@ static int patch_vt1616_specific(struct 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; } -- Daniel Jacobowitz CodeSourcery _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel