Skip to content

Commit

Permalink
ALSA: usb-audio: add control index offset
Browse files Browse the repository at this point in the history
Currently, channel IDs exceeding 31 (0x1f) cannot be used.
The channel ID is derived from the cmask. Extending cmask
to a 64-bit type would only allow it to go up to 63 (0x3f).
Some devices have channel IDs exceeding that as well.
To address that, add an offset to the mixer element which
is then accounted for in the UAC set/get functions.

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Eldad Zack authored and Takashi Iwai committed Nov 29, 2012
1 parent 28acb12 commit 9f81410
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
4 changes: 4 additions & 0 deletions sound/usb/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v

static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
validx += cval->idx_off;

return (cval->mixer->protocol == UAC_VERSION_1) ?
get_ctl_value_v1(cval, request, validx, value_ret) :
get_ctl_value_v2(cval, request, validx, value_ret);
Expand Down Expand Up @@ -432,6 +434,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
unsigned char buf[2];
int idx = 0, val_len, err, timeout = 10;

validx += cval->idx_off;

if (cval->mixer->protocol == UAC_VERSION_1) {
val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
} else { /* UAC_VERSION_2 */
Expand Down
1 change: 1 addition & 0 deletions sound/usb/mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct usb_mixer_elem_info {
unsigned int id;
unsigned int control; /* CS or ICN (high byte) */
unsigned int cmask; /* channel mask bitmap: 0 = master */
unsigned int idx_off; /* Control index offset */
unsigned int ch_readonly;
unsigned int master_readonly;
int channels;
Expand Down
16 changes: 15 additions & 1 deletion sound/usb/mixer_quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
* Since there doesn't seem to be a devices that needs a multichannel
* version, we keep it mono for simplicity.
*/
static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer,
unsigned int unitid,
unsigned int control,
unsigned int cmask,
int val_type,
unsigned int idx_off,
const char *name,
snd_kcontrol_tlv_rw_t *tlv_callback)
{
Expand All @@ -85,6 +86,7 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
cval->channels = 1;
cval->control = control;
cval->cmask = cmask;
cval->idx_off = idx_off;

/* get_min_max() is called only for integer volumes later,
* so provide a short-cut for booleans */
Expand Down Expand Up @@ -120,6 +122,18 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
return 0;
}

static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
unsigned int unitid,
unsigned int control,
unsigned int cmask,
int val_type,
const char *name,
snd_kcontrol_tlv_rw_t *tlv_callback)
{
return snd_create_std_mono_ctl_offset(mixer, unitid, control, cmask,
val_type, 0 /* Offset */, name, tlv_callback);
}

/*
* Create a set of standard UAC controls from a table
*/
Expand Down

0 comments on commit 9f81410

Please sign in to comment.