At Sat, 21 Jul 2007 17:10:08 -0700 (PDT), Trent Piepho wrote: > > This patch adds mute controls for the analog output channels. It does this > by sending SPI commands to the DAC on cards like the SB live 24-bit / > Audigy SE that have an SPI DAC. > [2 <text/plain; US-ASCII (base64)>] > # HG changeset patch > # User Trent Piepho <xyzzy@xxxxxxxxxxxxx> > # Date 1185062879 25200 > # Node ID 2c3514f4607b69271148337af15be55d3205af70 > # Parent 04b7771f7c31709e9d1883264bcde7e34781a590 > ca0106: Add analog mute controls for cards with SPI DAC > > Add four mute controls for the analog output channels for cards that use > a spi dac, like SB0570 SB Live! 24-bit / Audigy SE. The Wolfson dac > doesn't support muting each channel 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 de-emphasis, DAC power down, phase inversion, and other > features. Thanks, the patch looks almost fine, but please fix the following minor issues: - Try to avoid a magic number, e.g. >> 9. - put callback should return 0 for non-changed value, a positive (usually 1) when the value is changed, and a negative error code for errors. - Try to keep lines within 80 chars (to follow the standard coding style). I know that other codes there are not, but don't care now. We'll fix them later, too. Takashi > > diff -r 04b7771f7c31 -r 2c3514f4607b pci/ca0106/ca0106.h > --- a/pci/ca0106/ca0106.h Fri Jul 20 10:52:46 2007 +0200 > +++ b/pci/ca0106/ca0106.h Sat Jul 21 17:07:59 2007 -0700 > @@ -611,6 +611,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 +629,5 @@ void snd_ca0106_ptr_write(struct snd_ca0 > > 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 -r 04b7771f7c31 -r 2c3514f4607b pci/ca0106/ca0106_main.c > --- a/pci/ca0106/ca0106_main.c Fri Jul 20 10:52:46 2007 +0200 > +++ b/pci/ca0106/ca0106_main.c Sat Jul 21 17:07:59 2007 -0700 > @@ -1475,8 +1475,11 @@ static int __devinit snd_ca0106_create(i > int size, n; > > size = ARRAY_SIZE(spi_dac_init); > - for (n=0; n < size; n++) > + for (n=0; n < size; n++) { > snd_ca0106_spi_write(chip, spi_dac_init[n]); > + if ((spi_dac_init[n]>>9) < ARRAY_SIZE(chip->spi_dac_reg)) > + chip->spi_dac_reg[spi_dac_init[n]>>9] = spi_dac_init[n]; > + } > } > > if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, > diff -r 04b7771f7c31 -r 2c3514f4607b pci/ca0106/ca0106_mixer.c > --- a/pci/ca0106/ca0106_mixer.c Fri Jul 20 10:52:46 2007 +0200 > +++ b/pci/ca0106/ca0106_mixer.c Sat Jul 21 17:07:59 2007 -0700 > @@ -470,6 +470,41 @@ static int snd_ca0106_i2c_volume_put(str > return change; > } > > +static int spi_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) > +{ > + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; > + uinfo->count = 1; > + uinfo->value.integer.min = 0; > + uinfo->value.integer.max = 1; > + return 0; > +} > + > +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 >> 9; > + unsigned int bit = kcontrol->private_value & 0x1ff; > + > + 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 >> 9; > + unsigned int bit = kcontrol->private_value & 0x1ff; > + int ret; > + > + if (ucontrol->value.integer.value[0]) > + emu->spi_dac_reg[reg] &= ~bit; > + else > + 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, \ > @@ -560,6 +595,23 @@ static struct snd_kcontrol_new snd_ca010 > I2C_VOLUME("Mic Capture Volume", 1), > I2C_VOLUME("Line in Capture Volume", 2), > 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<<9) | (1<<bit) \ > +} > + > +static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[] __devinitdata = { > + SPI_SWITCH("Analog Front Playback Switch", 15, 2), > + SPI_SWITCH("Analog Rear Playback Switch", 9, 3), > + SPI_SWITCH("Analog Center/LFE Playback Switch", 9, 5), > + SPI_SWITCH("Analog Side Playback Switch", 9, 4), > }; > > static int __devinit remove_ctl(struct snd_card *card, const char *name) > @@ -658,6 +710,13 @@ int __devinit snd_ca0106_mixer(struct sn > 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; > } > > [3 <text/plain; us-ascii (7bit)>] > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@xxxxxxxxxxxxxxxx > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel