aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ca0106/ca0106_mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ca0106/ca0106_mixer.c')
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index a135b9c4c3c8..7fbfe17438b4 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk> 2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit 3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4 * Version: 0.0.17 4 * Version: 0.0.18
5 * 5 *
6 * FEATURES currently supported: 6 * FEATURES currently supported:
7 * See ca0106_main.c for features. 7 * See ca0106_main.c for features.
@@ -39,6 +39,8 @@
39 * Modified Copyright message. 39 * Modified Copyright message.
40 * 0.0.17 40 * 0.0.17
41 * Implement Mic and Line in Capture. 41 * Implement Mic and Line in Capture.
42 * 0.0.18
43 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
42 * 44 *
43 * This code was initally based on code from ALSA's emu10k1x.c which is: 45 * This code was initally based on code from ALSA's emu10k1x.c which is:
44 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 46 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
@@ -462,6 +464,42 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
462 return change; 464 return change;
463} 465}
464 466
467#define spi_mute_info snd_ctl_boolean_mono_info
468
469static int spi_mute_get(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
471{
472 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
473 unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
474 unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
475
476 ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
477 return 0;
478}
479
480static int spi_mute_put(struct snd_kcontrol *kcontrol,
481 struct snd_ctl_elem_value *ucontrol)
482{
483 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
484 unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
485 unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
486 int ret;
487
488 ret = emu->spi_dac_reg[reg] & bit;
489 if (ucontrol->value.integer.value[0]) {
490 if (!ret) /* bit already cleared, do nothing */
491 return 0;
492 emu->spi_dac_reg[reg] &= ~bit;
493 } else {
494 if (ret) /* bit already set, do nothing */
495 return 0;
496 emu->spi_dac_reg[reg] |= bit;
497 }
498
499 ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
500 return ret ? -1 : 1;
501}
502
465#define CA_VOLUME(xname,chid,reg) \ 503#define CA_VOLUME(xname,chid,reg) \
466{ \ 504{ \
467 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 505 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -554,6 +592,28 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata =
554 I2C_VOLUME("Aux Capture Volume", 3), 592 I2C_VOLUME("Aux Capture Volume", 3),
555}; 593};
556 594
595#define SPI_SWITCH(xname,reg,bit) \
596{ \
597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
598 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
599 .info = spi_mute_info, \
600 .get = spi_mute_get, \
601 .put = spi_mute_put, \
602 .private_value = (reg<<SPI_REG_SHIFT) | (1<<bit) \
603}
604
605static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[]
606__devinitdata = {
607 SPI_SWITCH("Analog Front Playback Switch",
608 SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
609 SPI_SWITCH("Analog Rear Playback Switch",
610 SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
611 SPI_SWITCH("Analog Center/LFE Playback Switch",
612 SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
613 SPI_SWITCH("Analog Side Playback Switch",
614 SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
615};
616
557static int __devinit remove_ctl(struct snd_card *card, const char *name) 617static int __devinit remove_ctl(struct snd_card *card, const char *name)
558{ 618{
559 struct snd_ctl_elem_id id; 619 struct snd_ctl_elem_id id;
@@ -650,6 +710,13 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
650 if (err < 0) 710 if (err < 0)
651 return err; 711 return err;
652 } 712 }
713 if (emu->details->spi_dac == 1) {
714 for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_spi_dac_ctls); i++) {
715 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_spi_dac_ctls[i], emu));
716 if (err < 0)
717 return err;
718 }
719 }
653 return 0; 720 return 0;
654} 721}
655 722