[alsa-devel] [RFC] virtual master control (3/3)
Takashi Iwai
tiwai at suse.de
Fri Nov 23 18:33:10 CET 2007
[PATCH] AC97 virtual master control
This patch adds the virtual master control to AC97-related drivers.
It's needed for surround outputs.
At this moment, it's added when vmaster=1 option is given to either
snd-intel8x0, snd-atiixp or snd-via82xx driver.
For automatic addition of vmaster control, we'll need to resolve the
following
- whether the vmaster is really needed (most machines have only front
output)
- disable AD-mode on AD codecs (to back to the normal AC97 volume
control mode)
---
diff -r 5c48888d1307 include/ac97_codec.h
--- a/include/ac97_codec.h Tue Sep 18 15:48:30 2007 +0200
+++ b/include/ac97_codec.h Tue Sep 18 15:48:48 2007 +0200
@@ -595,6 +595,7 @@ struct ac97_quirk {
int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override);
int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate);
+int snd_ac97_add_vmaster(struct snd_ac97 *ac97);
/*
* PCM allocation
diff -r 5c48888d1307 pci/Kconfig
--- a/pci/Kconfig Tue Sep 18 15:48:30 2007 +0200
+++ b/pci/Kconfig Tue Sep 18 15:48:48 2007 +0200
@@ -59,6 +59,7 @@ config SND_ATIIXP
tristate "ATI IXP AC97 Controller"
depends on SND
select SND_AC97_CODEC
+ select SND_VMASTER
help
Say Y here to include support for the integrated AC97 sound
device on motherboards with ATI chipsets (ATI IXP 150/200/250/
@@ -664,6 +665,7 @@ config SND_INTEL8X0
tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller"
depends on SND
select SND_AC97_CODEC
+ select SND_VMASTER
help
Say Y here to include support for the integrated AC97 sound
device on motherboards with Intel/SiS/nVidia/AMD chipsets, or
@@ -835,6 +837,7 @@ config SND_VIA82XX
depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
+ select SND_VMASTER
help
Say Y here to include support for the integrated AC97 sound
device on motherboards with VIA chipsets.
diff -r 5c48888d1307 pci/ac97/ac97_codec.c
--- a/pci/ac97/ac97_codec.c Tue Sep 18 15:48:30 2007 +0200
+++ b/pci/ac97/ac97_codec.c Tue Sep 18 15:48:48 2007 +0200
@@ -2871,6 +2871,65 @@ int snd_ac97_tune_hardware(struct snd_ac
EXPORT_SYMBOL(snd_ac97_tune_hardware);
+#ifdef CONFIG_SND_VMASTER
+/*
+ * create a virtual master control (if surround is supported)
+ */
+static const char *slave_items[] = {
+ "Front", "Surround", "Center", "LFE", "Side", "Headphone", "Mono",
+ NULL
+};
+
+static int add_vmaster(struct snd_ac97 *ac97, char *suffix, int has_tlv)
+{
+ struct snd_kcontrol *sctl;
+ struct snd_kcontrol *kctl;
+ const unsigned int *tlv = NULL;
+ char name[32];
+ const char **s;
+ int err;
+
+ sctl = ctl_find(ac97, "Surround", suffix);
+ if (!sctl)
+ return 0; /* no surrounds */
+ if (has_tlv)
+ tlv = find_db_scale((sctl->private_value >> 16) & 0xff);
+
+ if (snd_ac97_rename_ctl(ac97, "Master", "Front", suffix) < 0)
+ return 0; /* front already exists */
+ snd_ac97_rename_ctl(ac97, "Master Mono", "Mono", suffix);
+
+ sprintf(name, "Master %s", suffix);
+ 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 = slave_items; *s; s++) {
+ sctl = ctl_find(ac97, *s, suffix);
+ if (!sctl)
+ continue;
+ err = snd_ctl_add_slave(kctl, sctl);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+int snd_ac97_add_vmaster(struct snd_ac97 *ac97)
+{
+ int err;
+ err = add_vmaster(ac97, "Playback Volume", 1);
+ if (err < 0)
+ return err;
+ return add_vmaster(ac97, "Playback Switch", 0);
+}
+
+EXPORT_SYMBOL(snd_ac97_add_vmaster);
+#endif
+
/*
* INIT part
*/
diff -r 5c48888d1307 pci/atiixp.c
--- a/pci/atiixp.c Tue Sep 18 15:48:30 2007 +0200
+++ b/pci/atiixp.c Tue Sep 18 15:48:48 2007 +0200
@@ -46,6 +46,7 @@ static char *ac97_quirk;
static char *ac97_quirk;
static int spdif_aclink = 1;
static int ac97_codec = -1;
+static int vmaster;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
@@ -59,6 +60,8 @@ MODULE_PARM_DESC(ac97_codec, "Specify co
MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing.");
module_param(spdif_aclink, bool, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
+module_param(vmaster, bool, 0444);
+MODULE_PARM_DESC(vmaster, "Add a virtual master volume if needed.");
/* just for backward compatibility */
static int enable;
@@ -1442,6 +1445,8 @@ static int __devinit snd_atiixp_mixer_ne
}
snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
+ if (vmaster)
+ snd_ac97_add_vmaster(chip->ac97[0]);
return 0;
}
diff -r 5c48888d1307 pci/intel8x0.c
--- a/pci/intel8x0.c Tue Sep 18 15:48:30 2007 +0200
+++ b/pci/intel8x0.c Tue Sep 18 15:48:48 2007 +0200
@@ -72,6 +72,7 @@ static int buggy_irq = -1; /* auto-check
static int buggy_irq = -1; /* auto-check */
static int xbox;
static int spdif_aclink = -1;
+static int vmaster;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
@@ -89,6 +90,8 @@ MODULE_PARM_DESC(xbox, "Set to 1 for Xbo
MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
module_param(spdif_aclink, int, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
+module_param(vmaster, bool, 0444);
+MODULE_PARM_DESC(vmaster, "Add a virtual master volume if needed.");
/* just for backward compatibility */
static int enable;
@@ -2149,6 +2152,8 @@ static int __devinit snd_intel8x0_mixer(
}
/* tune up the primary codec */
snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
+ if (vmaster)
+ snd_ac97_add_vmaster(chip->ac97[0]);
/* enable separate SDINs for ICH4 */
if (chip->device_type == DEVICE_INTEL_ICH4)
pbus->isdin = 1;
diff -r 5c48888d1307 pci/via82xx.c
--- a/pci/via82xx.c Tue Sep 18 15:48:30 2007 +0200
+++ b/pci/via82xx.c Tue Sep 18 15:48:48 2007 +0200
@@ -86,6 +86,7 @@ static int ac97_clock = 48000;
static int ac97_clock = 48000;
static char *ac97_quirk;
static int dxs_support;
+static int vmaster;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
@@ -103,6 +104,8 @@ MODULE_PARM_DESC(ac97_quirk, "AC'97 work
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
module_param(dxs_support, int, 0444);
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
+module_param(vmaster, bool, 0444);
+MODULE_PARM_DESC(vmaster, "Add a virtual master volume if needed.");
/* just for backward compatibility */
static int enable;
@@ -1820,6 +1823,8 @@ static int __devinit snd_via82xx_mixer_n
return err;
snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
+ if (vmaster)
+ snd_ac97_add_vmaster(chip->ac97);
if (chip->chip_type != TYPE_VIA686) {
/* use slot 10/11 */
More information about the Alsa-devel
mailing list