diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-07-14 13:18:19 (GMT) |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 08:37:54 (GMT) |
commit | 7bc5ba7e02f63a5732fdf99e7471f54738f6f918 (patch) | |
tree | 8b170e80155eaa18951fde3c2e974aede253cab5 /sound/usb | |
parent | 6a65d793b0a82c7e190d9fd92a479401b6a127ca (diff) | |
download | linux-7bc5ba7e02f63a5732fdf99e7471f54738f6f918.tar.xz |
[ALSA] Add TLV support to snd-usb-audio driver
Added TLV-read support to snd-usb-audio driver for passing
the volume dB scale information to user-space.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/usbmixer.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 491e975..e516d6a 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -37,6 +37,7 @@ #include <sound/control.h> #include <sound/hwdep.h> #include <sound/info.h> +#include <sound/tlv.h> #include "usbaudio.h" @@ -416,6 +417,26 @@ static inline int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channe return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value); } +/* + * TLV callback for mixer volume controls + */ +static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *_tlv) +{ + struct usb_mixer_elem_info *cval = kcontrol->private_data; + DECLARE_TLV_DB_SCALE(scale, 0, 0, 0); + + if (size < sizeof(scale)) + return -ENOMEM; + /* USB descriptions contain the dB scale in 1/256 dB unit + * while ALSA TLV contains in 1/100 dB unit + */ + scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256; + scale[3] = (convert_signed_value(cval, cval->res) * 100) / 256; + if (copy_to_user(_tlv, scale, sizeof(scale))) + return -EFAULT; + return 0; +} /* * parser routines begin here... @@ -933,6 +954,12 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, } strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume", sizeof(kctl->id.name)); + if (control == USB_FEATURE_VOLUME) { + kctl->tlv.c = mixer_vol_tlv; + kctl->vd[0].access |= + SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + } break; default: |