diff options
-rw-r--r-- | sound/i2c/other/ak4xxx-adda.c | 72 | ||||
-rw-r--r-- | sound/pci/ice1712/revo.c | 2 |
2 files changed, 73 insertions, 1 deletions
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 7d562f08420..d76d8b078a8 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c @@ -472,6 +472,57 @@ static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol, return change; } +static int ak4xxx_switch_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 ak4xxx_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); + int shift = AK_GET_SHIFT(kcontrol->private_value); + int invert = AK_GET_INVERT(kcontrol->private_value); + unsigned char val = snd_akm4xxx_get(ak, chip, addr); + + if (invert) + val = ! val; + ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0; + return 0; +} + +static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); + int shift = AK_GET_SHIFT(kcontrol->private_value); + int invert = AK_GET_INVERT(kcontrol->private_value); + long flag = ucontrol->value.integer.value[0]; + unsigned char val, oval; + int change; + + if (invert) + flag = ! flag; + oval = snd_akm4xxx_get(ak, chip, addr); + if (flag) + val = oval | (1<<shift); + else + val = oval & ~(1<<shift); + change = (oval != val); + if (change) + snd_akm4xxx_write(ak, chip, addr, val); + return change; +} + /* * build AK4xxx controls */ @@ -621,6 +672,27 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) SNDRV_CTL_ELEM_ACCESS_WRITE)); if (err < 0) goto __error; + + memset(ctl, 0, sizeof(*ctl)); + if (ak->channel_names == NULL) + strcpy(ctl->id.name, "Capture Switch"); + else + strcpy(ctl->id.name, ak->channel_names[1]); + ctl->id.index = ak->idx_offset * 2; + ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + ctl->count = 1; + ctl->info = ak4xxx_switch_info; + ctl->get = ak4xxx_switch_get; + ctl->put = ak4xxx_switch_put; + /* register 2, bit 0 (SMUTE): 0 = normal operation, 1 = mute */ + ctl->private_value = + AK_COMPOSE(0, 2, 0, 0) | AK_INVERT; + ctl->private_data = ak; + err = snd_ctl_add(ak->card, + snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| + SNDRV_CTL_ELEM_ACCESS_WRITE)); + if (err < 0) + goto __error; } if (ak->type == SND_AK4355 || ak->type == SND_AK4358) diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index ef64be49a89..1134a57f9e6 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -99,7 +99,7 @@ static char *revo51_channel_names[] = {"PCM Playback Volume", "PCM Center Playba "PCM LFE Playback Volume", "PCM Rear Playback Volume"}; static unsigned int revo51_adc_num_stereo[] = {2}; -static char *revo51_adc_channel_names[] = {"PCM Capture Volume"}; +static char *revo51_adc_channel_names[] = {"PCM Capture Volume","PCM Capture Switch"}; static struct snd_akm4xxx akm_revo_front __devinitdata = { .type = SND_AK4381, |