Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b18cd538a92247307247a53f57c477edbcedbb79
Commit:     b18cd538a92247307247a53f57c477edbcedbb79
Parent:     69b311a4dabc9163288be1fe993cb7db47541e67
Author:     Trent Piepho <[EMAIL PROTECTED]>
AuthorDate: Tue Jul 24 12:06:16 2007 +0200
Committer:  Jaroslav Kysela <[EMAIL PROTECTED]>
CommitDate: Tue Oct 16 15:57:55 2007 +0200

    [ALSA] ca0106: Add analog mute controls for cards with SPI DAC
    
    Add four mute controls for the analog output channels for cards that use
    an SPI DAC, like the SB0570 SB Live! 24-bit / Audigy SE.  The Wolfson DAC
    doesn't support muting left/right so the controls are mono.
    The chip state struct gets a 32-byte array to act as a shadow of the spi
    dac registers.  Only two registers are used for mute, but more would be
    needed for analog gain, de-emphasis, DAC power down, phase inversion, and
    other features.
    
    Signed-off-by: Trent Piepho <[EMAIL PROTECTED]>
    Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>
    Signed-off-by: Jaroslav Kysela <[EMAIL PROTECTED]>
---
 sound/pci/ca0106/ca0106.h       |   47 +++++++++++++++++++++++++-
 sound/pci/ca0106/ca0106_main.c  |   11 +++++-
 sound/pci/ca0106/ca0106_mixer.c |   69 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 122 insertions(+), 5 deletions(-)

diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index a0420bc..7ad03c6 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <[EMAIL PROTECTED]>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.21
+ *  Version: 0.0.22
  *
  *  FEATURES currently supported:
  *    See ca0106_main.c for features.
@@ -47,6 +47,8 @@
  *    Added GPIO info for SB Live 24bit.
  *  0.0.21
  *   Implement support for Line-in capture on SB Live 24bit.
+ *  0.0.22
+ *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
  *
  *
  *  This code was initally based on code from ALSA's emu10k1x.c which is:
@@ -552,6 +554,44 @@
 #define CONTROL_CENTER_LFE_CHANNEL 1
 #define CONTROL_UNKNOWN_CHANNEL 2
 
+
+/* Based on WM8768 Datasheet Rev 4.2 page 32 */
+#define SPI_REG_MASK   0x1ff   /* 16-bit SPI writes have a 7-bit address */
+#define SPI_REG_SHIFT  9       /* followed by 9 bits of data */
+
+/* They really do label the bit for the 4th channel "4" and not "3" */
+#define SPI_DMUTE0_REG         9
+#define SPI_DMUTE1_REG         9
+#define SPI_DMUTE2_REG         9
+#define SPI_DMUTE4_REG         15
+#define SPI_DMUTE0_BIT         3
+#define SPI_DMUTE1_BIT         4
+#define SPI_DMUTE2_BIT         5
+#define SPI_DMUTE4_BIT         2
+
+#define SPI_PHASE0_REG         3
+#define SPI_PHASE1_REG         3
+#define SPI_PHASE2_REG         3
+#define SPI_PHASE4_REG         15
+#define SPI_PHASE0_BIT         6
+#define SPI_PHASE1_BIT         7
+#define SPI_PHASE2_BIT         8
+#define SPI_PHASE4_BIT         3
+
+#define SPI_PDWN_REG           2       /* power down all DACs */
+#define SPI_PDWN_BIT           2
+#define SPI_DACD0_REG          10      /* power down individual DACs */
+#define SPI_DACD1_REG          10
+#define SPI_DACD2_REG          10
+#define SPI_DACD4_REG          15
+#define SPI_DACD0_BIT          1
+#define SPI_DACD1_BIT          2
+#define SPI_DACD2_BIT          3
+#define SPI_DACD4_BIT          1
+
+#define SPI_PWRDNALL_REG       10      /* power down everything */
+#define SPI_PWRDNALL_BIT       4
+
 #include "ca_midi.h"
 
 struct snd_ca0106;
@@ -611,6 +651,8 @@ struct snd_ca0106 {
 
        struct snd_ca_midi midi;
        struct snd_ca_midi midi2;
+
+       u16 spi_dac_reg[16];
 };
 
 int snd_ca0106_mixer(struct snd_ca0106 *emu);
@@ -627,4 +669,5 @@ void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
 
 int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
 
-
+int snd_ca0106_spi_write(struct snd_ca0106 * emu,
+                                  unsigned int data);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 58ffa0c..512fda9 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <[EMAIL PROTECTED]>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.23
+ *  Version: 0.0.24
  *
  *  FEATURES currently supported:
  *    Front, Rear and Center/LFE.
@@ -79,6 +79,8 @@
  *    Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit 
without AC97. From kiksen, bug #901
  *  0.0.23
  *    Implement support for Line-in capture on SB Live 24bit.
+ *  0.0.24
+ *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
  *
  *  BUGS:
  *    Some stability problems when unloading the snd-ca0106 kernel module.
@@ -1484,8 +1486,13 @@ static int __devinit snd_ca0106_create(int dev, struct 
snd_card *card,
                int size, n;
 
                size = ARRAY_SIZE(spi_dac_init);
-               for (n=0; n < size; n++)
+               for (n = 0; n < size; n++) {
+                       int reg = spi_dac_init[n] >> SPI_REG_SHIFT;
+
                        snd_ca0106_spi_write(chip, spi_dac_init[n]);
+                       if (reg < ARRAY_SIZE(chip->spi_dac_reg))
+                               chip->spi_dac_reg[reg] = spi_dac_init[n];
+               }
        }
 
        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index a135b9c..7fbfe17 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <[EMAIL PROTECTED]>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.17
+ *  Version: 0.0.18
  *
  *  FEATURES currently supported:
  *    See ca0106_main.c for features.
@@ -39,6 +39,8 @@
  *    Modified Copyright message.
  *  0.0.17
  *    Implement Mic and Line in Capture.
+ *  0.0.18
+ *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
  *
  *  This code was initally based on code from ALSA's emu10k1x.c which is:
  *  Copyright (c) by Francisco Moraes <[EMAIL PROTECTED]>
@@ -462,6 +464,42 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol 
*kcontrol,
        return change;
 }
 
+#define spi_mute_info  snd_ctl_boolean_mono_info
+
+static int spi_mute_get(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
+       unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
+       unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
+
+       ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
+       return 0;
+}
+
+static int spi_mute_put(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
+       unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
+       unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
+       int ret;
+
+       ret = emu->spi_dac_reg[reg] & bit;
+       if (ucontrol->value.integer.value[0]) {
+               if (!ret)       /* bit already cleared, do nothing */
+                       return 0;
+               emu->spi_dac_reg[reg] &= ~bit;
+       } else {
+               if (ret)        /* bit already set, do nothing */
+                       return 0;
+               emu->spi_dac_reg[reg] |= bit;
+       }
+
+       ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
+       return ret ? -1 : 1;
+}
+
 #define CA_VOLUME(xname,chid,reg) \
 {                                                              \
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,     \
@@ -554,6 +592,28 @@ static struct snd_kcontrol_new 
snd_ca0106_volume_i2c_adc_ctls[] __devinitdata =
         I2C_VOLUME("Aux Capture Volume", 3),
 };
 
+#define SPI_SWITCH(xname,reg,bit) \
+{                                                              \
+       .iface  = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,    \
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,              \
+       .info   = spi_mute_info,                                \
+       .get    = spi_mute_get,                                 \
+       .put    = spi_mute_put,                                 \
+       .private_value = (reg<<SPI_REG_SHIFT) | (1<<bit)        \
+}
+
+static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[]
+__devinitdata = {
+       SPI_SWITCH("Analog Front Playback Switch",
+                  SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
+       SPI_SWITCH("Analog Rear Playback Switch",
+                  SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
+       SPI_SWITCH("Analog Center/LFE Playback Switch",
+                  SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
+       SPI_SWITCH("Analog Side Playback Switch",
+                  SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
+};
+
 static int __devinit remove_ctl(struct snd_card *card, const char *name)
 {
        struct snd_ctl_elem_id id;
@@ -650,6 +710,13 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
                if (err < 0)
                        return err;
        }
+       if (emu->details->spi_dac == 1) {
+               for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_spi_dac_ctls); 
i++) {
+                       err = snd_ctl_add(card, 
snd_ctl_new1(&snd_ca0106_volume_spi_dac_ctls[i], emu));
+                       if (err < 0)
+                               return err;
+               }
+       }
         return 0;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to