diff options
author | Daniel Jacobowitz <dan@codesourcery.com> | 2008-05-07 06:05:10 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-05-19 07:19:14 -0400 |
commit | 87af38dafe4f930921b9217c21ec6d72cad56bcc (patch) | |
tree | 6b884fca1319aff9ff9f311b9a8586ad531f175a | |
parent | 1894c59fdb63692f5ba2576875cc558b856935ca (diff) |
[ALSA] ac97 - Add virtual master control to VT1616/VT1617A codec.
Enable VMASTER for VT1616 / VT1617A codec.
Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | sound/drivers/Kconfig | 1 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 76 |
2 files changed, 77 insertions, 0 deletions
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 602b58e3b55d..159137bf4c11 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig | |||
@@ -58,6 +58,7 @@ config SND_AC97_CODEC | |||
58 | tristate | 58 | tristate |
59 | select SND_PCM | 59 | select SND_PCM |
60 | select AC97_BUS | 60 | select AC97_BUS |
61 | select SND_VMASTER | ||
61 | 62 | ||
62 | config SND_DUMMY | 63 | config SND_DUMMY |
63 | tristate "Dummy (/dev/null) soundcard" | 64 | tristate "Dummy (/dev/null) soundcard" |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 1292dcee072d..92817f7d46d2 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -3352,8 +3352,66 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), | |||
3352 | AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), | 3352 | AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), |
3353 | }; | 3353 | }; |
3354 | 3354 | ||
3355 | static const char *slave_vols_vt1616[] = { | ||
3356 | "Front Playback Volume", | ||
3357 | "Surround Playback Volume", | ||
3358 | "Center Playback Volume", | ||
3359 | "LFE Playback Volume", | ||
3360 | NULL | ||
3361 | }; | ||
3362 | |||
3363 | static const char *slave_sws_vt1616[] = { | ||
3364 | "Front Playback Switch", | ||
3365 | "Surround Playback Switch", | ||
3366 | "Center Playback Switch", | ||
3367 | "LFE Playback Switch", | ||
3368 | NULL | ||
3369 | }; | ||
3370 | |||
3371 | /* find a mixer control element with the given name */ | ||
3372 | static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, | ||
3373 | const char *name) | ||
3374 | { | ||
3375 | struct snd_ctl_elem_id id; | ||
3376 | memset(&id, 0, sizeof(id)); | ||
3377 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
3378 | strcpy(id.name, name); | ||
3379 | return snd_ctl_find_id(ac97->bus->card, &id); | ||
3380 | } | ||
3381 | |||
3382 | /* create a virtual master control and add slaves */ | ||
3383 | int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, | ||
3384 | const unsigned int *tlv, const char **slaves) | ||
3385 | { | ||
3386 | struct snd_kcontrol *kctl; | ||
3387 | const char **s; | ||
3388 | int err; | ||
3389 | |||
3390 | kctl = snd_ctl_make_virtual_master(name, tlv); | ||
3391 | if (!kctl) | ||
3392 | return -ENOMEM; | ||
3393 | err = snd_ctl_add(ac97->bus->card, kctl); | ||
3394 | if (err < 0) | ||
3395 | return err; | ||
3396 | |||
3397 | for (s = slaves; *s; s++) { | ||
3398 | struct snd_kcontrol *sctl; | ||
3399 | |||
3400 | sctl = snd_ac97_find_mixer_ctl(ac97, *s); | ||
3401 | if (!sctl) { | ||
3402 | snd_printdd("Cannot find slave %s, skipped\n", *s); | ||
3403 | continue; | ||
3404 | } | ||
3405 | err = snd_ctl_add_slave(kctl, sctl); | ||
3406 | if (err < 0) | ||
3407 | return err; | ||
3408 | } | ||
3409 | return 0; | ||
3410 | } | ||
3411 | |||
3355 | static int patch_vt1616_specific(struct snd_ac97 * ac97) | 3412 | static int patch_vt1616_specific(struct snd_ac97 * ac97) |
3356 | { | 3413 | { |
3414 | struct snd_kcontrol *kctl; | ||
3357 | int err; | 3415 | int err; |
3358 | 3416 | ||
3359 | if (snd_ac97_try_bit(ac97, 0x5a, 9)) | 3417 | if (snd_ac97_try_bit(ac97, 0x5a, 9)) |
@@ -3361,6 +3419,24 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97) | |||
3361 | return err; | 3419 | return err; |
3362 | if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0) | 3420 | if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0) |
3363 | return err; | 3421 | return err; |
3422 | |||
3423 | /* There is already a misnamed master switch. Rename it. */ | ||
3424 | kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume"); | ||
3425 | if (!kctl) | ||
3426 | return -EINVAL; | ||
3427 | |||
3428 | snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback"); | ||
3429 | |||
3430 | err = snd_ac97_add_vmaster(ac97, "Master Playback Volume", | ||
3431 | kctl->tlv.p, slave_vols_vt1616); | ||
3432 | if (err < 0) | ||
3433 | return err; | ||
3434 | |||
3435 | err = snd_ac97_add_vmaster(ac97, "Master Playback Switch", | ||
3436 | NULL, slave_sws_vt1616); | ||
3437 | if (err < 0) | ||
3438 | return err; | ||
3439 | |||
3364 | return 0; | 3440 | return 0; |
3365 | } | 3441 | } |
3366 | 3442 | ||