Loading sound/drivers/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -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" Loading sound/pci/ac97/ac97_patch.c +76 −0 Original line number Diff line number Diff line Loading @@ -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)) Loading @@ -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; } Loading Loading
sound/drivers/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -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" Loading
sound/pci/ac97/ac97_patch.c +76 −0 Original line number Diff line number Diff line Loading @@ -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)) Loading @@ -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; } Loading