ALSA: usb-audio: fix control messages for USB_RECIP_INTERFACE
authorDaniel Mack <daniel@caiaq.de>
Fri, 11 Jun 2010 15:34:20 +0000 (17:34 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 11 Jun 2010 16:05:38 +0000 (18:05 +0200)
Control messages directed to an interface must have the interface number
set in the lower 8 bits of wIndex. This wasn't done correctly for some
clock and mixer messages.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Reported-by: Alex Lee <alexlee188@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/clock.c
sound/usb/format.c
sound/usb/helper.h

index b7aadd614c70b378f6724f31d8883e82b2ced48c..b5855114667ef4976d0250630bc17dd3891fe912 100644 (file)
@@ -103,7 +103,8 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i
        ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
                              UAC2_CS_CUR,
                              USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-                             UAC2_CX_CLOCK_SELECTOR << 8, selector_id << 8,
+                             UAC2_CX_CLOCK_SELECTOR << 8,
+                             snd_usb_ctrl_intf(chip) | (selector_id << 8),
                              &buf, sizeof(buf), 1000);
 
        if (ret < 0)
@@ -120,7 +121,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
 
        err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
                              USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
-                             UAC2_CS_CONTROL_CLOCK_VALID << 8, source_id << 8,
+                             UAC2_CS_CONTROL_CLOCK_VALID << 8,
+                             snd_usb_ctrl_intf(chip) | (source_id << 8),
                              &data, sizeof(data), 1000);
 
        if (err < 0) {
@@ -269,7 +271,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
        data[3] = rate >> 24;
        if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
                                   USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                  UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
+                                  UAC2_CS_CONTROL_SAM_FREQ << 8,
+                                  snd_usb_ctrl_intf(chip) | (clock << 8),
                                   data, sizeof(data), 1000)) < 0) {
                snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
                           dev->devnum, iface, fmt->altsetting, rate);
@@ -278,7 +281,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 
        if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
                                   USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
-                                  UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
+                                  UAC2_CS_CONTROL_SAM_FREQ << 8,
+                                  snd_usb_ctrl_intf(chip) | (clock << 8),
                                   data, sizeof(data), 1000)) < 0) {
                snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
                           dev->devnum, iface, fmt->altsetting);
index df5b29fed00028b587fbe36b18c13c332c8aff31..8eccf17a4ac67ddd7390e2550a0a256b8ebd8def 100644 (file)
@@ -227,7 +227,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
        /* get the number of sample rates first by only fetching 2 bytes */
        ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
                              USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
-                             UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
+                             UAC2_CS_CONTROL_SAM_FREQ << 8,
+                             snd_usb_ctrl_intf(chip) | (clock << 8),
                              tmp, sizeof(tmp), 1000);
 
        if (ret < 0) {
@@ -247,7 +248,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
        /* now get the full information */
        ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
                              USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
-                             UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
+                             UAC2_CS_CONTROL_SAM_FREQ << 8,
+                             snd_usb_ctrl_intf(chip) | (clock << 8),
                              data, data_size, 1000);
 
        if (ret < 0) {
index a6b0e51b3a9a2ebae41cb03d3ca80e06e4a07b09..09bd943c43bf736c72c915ce99f41180b6be88b9 100644 (file)
@@ -28,5 +28,9 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
 #define snd_usb_get_speed(dev) ((dev)->speed)
 #endif
 
+static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
+{
+       return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
+}
 
 #endif /* __USBAUDIO_HELPER_H */