aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbmixer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-07-14 09:18:19 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:37:54 -0400
commit7bc5ba7e02f63a5732fdf99e7471f54738f6f918 (patch)
tree8b170e80155eaa18951fde3c2e974aede253cab5 /sound/usb/usbmixer.c
parent6a65d793b0a82c7e190d9fd92a479401b6a127ca (diff)
[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/usbmixer.c')
-rw-r--r--sound/usb/usbmixer.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 491e975a0c87..e516d6adbb22 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -37,6 +37,7 @@
37#include <sound/control.h> 37#include <sound/control.h>
38#include <sound/hwdep.h> 38#include <sound/hwdep.h>
39#include <sound/info.h> 39#include <sound/info.h>
40#include <sound/tlv.h>
40 41
41#include "usbaudio.h" 42#include "usbaudio.h"
42 43
@@ -416,6 +417,26 @@ static inline int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channe
416 return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value); 417 return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value);
417} 418}
418 419
420/*
421 * TLV callback for mixer volume controls
422 */
423static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
424 unsigned int size, unsigned int __user *_tlv)
425{
426 struct usb_mixer_elem_info *cval = kcontrol->private_data;
427 DECLARE_TLV_DB_SCALE(scale, 0, 0, 0);
428
429 if (size < sizeof(scale))
430 return -ENOMEM;
431 /* USB descriptions contain the dB scale in 1/256 dB unit
432 * while ALSA TLV contains in 1/100 dB unit
433 */
434 scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256;
435 scale[3] = (convert_signed_value(cval, cval->res) * 100) / 256;
436 if (copy_to_user(_tlv, scale, sizeof(scale)))
437 return -EFAULT;
438 return 0;
439}
419 440
420/* 441/*
421 * parser routines begin here... 442 * parser routines begin here...
@@ -933,6 +954,12 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
933 } 954 }
934 strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume", 955 strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume",
935 sizeof(kctl->id.name)); 956 sizeof(kctl->id.name));
957 if (control == USB_FEATURE_VOLUME) {
958 kctl->tlv.c = mixer_vol_tlv;
959 kctl->vd[0].access |=
960 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
961 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
962 }
936 break; 963 break;
937 964
938 default: 965 default: