ALSA: usb-audio: Fix mixer controls' USB interface for Kingston HyperX Amp (0951...
authorChris Wulff <crwulff@gmail.com>
Sat, 14 Mar 2020 16:54:48 +0000 (12:54 -0400)
committerTakashi Iwai <tiwai@suse.de>
Sat, 14 Mar 2020 17:24:19 +0000 (18:24 +0100)
Use the USB interface of the mixer that the control
was created on instead of the default control interface.

This fixes the Kingston HyperX AMP (0951:16d8) which has
controls on two interfaces.

Signed-off-by: Chris Wulff <crwulff@gmail.com>
Link: https://lore.kernel.org/r/20200314165449.4086-2-crwulff@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/mixer.c

index d5c7283f6e9ff55c48b74ba00f69ecb4704db8c7..721d12130d0cb4aae2b943e8fb75153212032331 100644 (file)
@@ -292,6 +292,11 @@ static int uac2_ctl_value_size(int val_type)
  * retrieve a mixer value
  */
 
+static inline int mixer_ctrl_intf(struct usb_mixer_interface *mixer)
+{
+       return get_iface_desc(mixer->hostif)->bInterfaceNumber;
+}
+
 static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
                            int validx, int *value_ret)
 {
@@ -306,7 +311,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
                return -EIO;
 
        while (timeout-- > 0) {
-               idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
+               idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
                err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
                                      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
                                      validx, idx, buf, val_len);
@@ -354,7 +359,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
        if (ret)
                goto error;
 
-       idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
+       idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
        ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
                              USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
                              validx, idx, buf, size);
@@ -479,7 +484,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
                return -EIO;
 
        while (timeout-- > 0) {
-               idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
+               idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
                err = snd_usb_ctl_msg(chip->dev,
                                      usb_sndctrlpipe(chip->dev, 0), request,
                                      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
@@ -1209,7 +1214,7 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
                    get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
                        usb_audio_err(cval->head.mixer->chip,
                                      "%d:%d: cannot get min/max values for control %d (id %d)\n",
-                                  cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip),
+                                  cval->head.id, mixer_ctrl_intf(cval->head.mixer),
                                                               cval->control, cval->head.id);
                        return -EINVAL;
                }
@@ -1428,7 +1433,7 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
        if (ret)
                goto error;
 
-       idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
+       idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
        if (cval->head.mixer->protocol == UAC_VERSION_2) {
                struct uac2_connectors_ctl_blk uac2_conn;
 
@@ -3219,7 +3224,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
        list_for_each_entry(mixer, &chip->mixer_list, list) {
                snd_iprintf(buffer,
                        "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
-                               chip->usb_id, snd_usb_ctrl_intf(chip),
+                               chip->usb_id, mixer_ctrl_intf(mixer),
                                mixer->ignore_ctl_error);
                snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
                for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {