diff options
Diffstat (limited to 'sound/pci/ctxfi')
-rw-r--r-- | sound/pci/ctxfi/ctmixer.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index fac783f585fc..796156e4bd38 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -18,11 +18,12 @@ #include "ctmixer.h" #include "ctamixer.h" +#include <linux/slab.h> #include <sound/core.h> #include <sound/control.h> #include <sound/asoundef.h> #include <sound/pcm.h> -#include <linux/slab.h> +#include <sound/tlv.h> enum CT_SUM_CTL { SUM_IN_F, @@ -292,6 +293,7 @@ set_switch_state(struct ct_mixer *mixer, mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START)); } +#if 0 /* not used */ /* Map integer value ranging from 0 to 65535 to 14-bit float value ranging * from 2^-6 to (1+1023/1024) */ static unsigned int uint16_to_float14(unsigned int x) @@ -331,6 +333,12 @@ static unsigned int float14_to_uint16(unsigned int x) return x; } +#endif /* not used */ + +#define VOL_SCALE 0x1c +#define VOL_MAX 0x100 + +static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1); static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -338,8 +346,7 @@ static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; uinfo->value.integer.min = 0; - uinfo->value.integer.max = 43690; - uinfo->value.integer.step = 128; + uinfo->value.integer.max = VOL_MAX; return 0; } @@ -349,15 +356,18 @@ static int ct_alsa_mix_volume_get(struct snd_kcontrol *kcontrol, { struct ct_atc *atc = snd_kcontrol_chip(kcontrol); enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); - struct amixer *amixer = NULL; - int i = 0; + struct amixer *amixer; + int i, val; for (i = 0; i < 2; i++) { amixer = ((struct ct_mixer *)atc->mixer)-> amixers[type*CHN_NUM+i]; - /* Convert 14-bit float-point scale to 16-bit integer volume */ - ucontrol->value.integer.value[i] = - (float14_to_uint16(amixer->ops->get_scale(amixer)) & 0xffff); + val = amixer->ops->get_scale(amixer) / VOL_SCALE; + if (val < 0) + val = 0; + else if (val > VOL_MAX) + val = VOL_MAX; + ucontrol->value.integer.value[i] = val; } return 0; @@ -369,16 +379,19 @@ static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol, struct ct_atc *atc = snd_kcontrol_chip(kcontrol); struct ct_mixer *mixer = atc->mixer; enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); - struct amixer *amixer = NULL; - int i = 0, j = 0, change = 0, val = 0; + struct amixer *amixer; + int i, j, val, oval, change = 0; for (i = 0; i < 2; i++) { - /* Convert 16-bit integer volume to 14-bit float-point scale */ - val = (ucontrol->value.integer.value[i] & 0xffff); + val = ucontrol->value.integer.value[i]; + if (val < 0) + val = 0; + else if (val > VOL_MAX) + val = VOL_MAX; + val *= VOL_SCALE; amixer = mixer->amixers[type*CHN_NUM+i]; - if ((float14_to_uint16(amixer->ops->get_scale(amixer)) & 0xff80) - != (val & 0xff80)) { - val = uint16_to_float14(val); + oval = amixer->ops->get_scale(amixer); + if (val != oval) { amixer->ops->set_scale(amixer, val); amixer->ops->commit_write(amixer); change = 1; @@ -398,11 +411,13 @@ static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol, } static struct snd_kcontrol_new vol_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .info = ct_alsa_mix_volume_info, .get = ct_alsa_mix_volume_get, - .put = ct_alsa_mix_volume_put + .put = ct_alsa_mix_volume_put, + .tlv = { .p = ct_vol_db_scale }, }; static void |