[PATCH 14/14] ALSA: usb-audio: scarlett2: Remove hard-coded USB #defines
Remove the hard-coded interface number and related constants for the vendor-specific interface and look them up from the USB endpoint descriptor.
Signed-off-by: Geoffrey D. Bennett g@b4.vu --- sound/usb/mixer_scarlett_gen2.c | 74 ++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 19 deletions(-)
diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c index 45fd540920b9..2e1937b072ee 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett_gen2.c @@ -230,6 +230,10 @@ struct scarlett2_data { struct mutex data_mutex; /* lock access to this data */ struct delayed_work work; const struct scarlett2_device_info *info; + __u8 bInterfaceNumber; + __u8 bEndpointAddress; + __u16 wMaxPacketSize; + __u8 bInterval; int num_mux_srcs; int num_mux_dsts; u16 scarlett2_seq; @@ -444,12 +448,6 @@ static int scarlett2_get_port_start_num(const struct scarlett2_ports *ports,
/*** USB Interactions ***/
-/* Vendor-Specific Interface, Endpoint, MaxPacketSize, Interval */ -#define SCARLETT2_USB_VENDOR_SPECIFIC_INTERFACE 5 -#define SCARLETT2_USB_INTERRUPT_ENDPOINT 4 -#define SCARLETT2_USB_INTERRUPT_MAX_DATA 64 -#define SCARLETT2_USB_INTERRUPT_INTERVAL 3 - /* Interrupt flags for dim/mute button and monitor changes */ #define SCARLETT2_USB_NOTIFY_DIM_MUTE 0x00200000 #define SCARLETT2_USB_NOTIFY_MONITOR 0x00400000 @@ -615,7 +613,7 @@ static int scarlett2_usb( SCARLETT2_USB_VENDOR_SPECIFIC_CMD_REQ, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 0, - SCARLETT2_USB_VENDOR_SPECIFIC_INTERFACE, + private->bInterfaceNumber, req, req_buf_size);
@@ -635,7 +633,7 @@ static int scarlett2_usb( SCARLETT2_USB_VENDOR_SPECIFIC_CMD_RESP, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 0, - SCARLETT2_USB_VENDOR_SPECIFIC_INTERFACE, + private->bInterfaceNumber, resp, resp_buf_size);
@@ -1886,12 +1884,45 @@ static void scarlett2_count_mux_io(struct scarlett2_data *private) private->num_mux_dsts = dsts; }
-/* Initialise private data and sequence number */ +/* Look through the interface descriptors for the Focusrite Control + * interface (bInterfaceClass = 255 Vendor Specific Class) and set + * bInterfaceNumber, bEndpointAddress, wMaxPacketSize, and bInterval + * in private + */ +static int scarlett2_find_fc_interface(struct usb_device *dev, + struct scarlett2_data *private) +{ + struct usb_host_config *config = dev->actconfig; + int i; + + for (i = 0; i < config->desc.bNumInterfaces; i++) { + struct usb_interface *intf = config->interface[i]; + struct usb_interface_descriptor *desc = + &intf->altsetting[0].desc; + struct usb_endpoint_descriptor *epd; + + if (desc->bInterfaceClass != 255) + continue; + + epd = get_endpoint(intf->altsetting, 0); + private->bInterfaceNumber = desc->bInterfaceNumber; + private->bEndpointAddress = epd->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + private->wMaxPacketSize = le16_to_cpu(epd->wMaxPacketSize); + private->bInterval = epd->bInterval; + return 0; + } + + return -EINVAL; +} + +/* Initialise private data, sequence number, and get the USB data */ static int scarlett2_init_private(struct usb_mixer_interface *mixer, const struct scarlett2_device_info *info) { struct scarlett2_data *private = kzalloc(sizeof(struct scarlett2_data), GFP_KERNEL); + int err;
if (!private) return -ENOMEM; @@ -1899,13 +1930,19 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer, mutex_init(&private->usb_mutex); mutex_init(&private->data_mutex); INIT_DELAYED_WORK(&private->work, scarlett2_config_save_work); + + mixer->private_data = private; + mixer->private_free = scarlett2_private_free; + mixer->private_suspend = scarlett2_private_suspend; + private->info = info; scarlett2_count_mux_io(private); private->scarlett2_seq = 0; private->mixer = mixer; - mixer->private_data = private; - mixer->private_free = scarlett2_private_free; - mixer->private_suspend = scarlett2_private_suspend; + + err = scarlett2_find_fc_interface(mixer->chip->dev, private); + if (err < 0) + return err;
/* Initialise the sequence number used for the proprietary commands */ return scarlett2_usb(mixer, SCARLETT2_USB_INIT_SEQ, NULL, 0, NULL, 0); @@ -2050,8 +2087,8 @@ static void scarlett2_notify(struct urb *urb) static int scarlett2_init_notify(struct usb_mixer_interface *mixer) { struct usb_device *dev = mixer->chip->dev; - unsigned int pipe = usb_rcvintpipe(dev, - SCARLETT2_USB_INTERRUPT_ENDPOINT); + struct scarlett2_data *private = mixer->private_data; + unsigned int pipe = usb_rcvintpipe(dev, private->bEndpointAddress); void *transfer_buffer;
if (mixer->urb) { @@ -2067,14 +2104,13 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer) if (!mixer->urb) return -ENOMEM;
- transfer_buffer = kmalloc(SCARLETT2_USB_INTERRUPT_MAX_DATA, GFP_KERNEL); + transfer_buffer = kmalloc(private->wMaxPacketSize, GFP_KERNEL); if (!transfer_buffer) return -ENOMEM;
usb_fill_int_urb(mixer->urb, dev, pipe, - transfer_buffer, SCARLETT2_USB_INTERRUPT_MAX_DATA, - scarlett2_notify, mixer, - SCARLETT2_USB_INTERRUPT_INTERVAL); + transfer_buffer, private->wMaxPacketSize, + scarlett2_notify, mixer, private->bInterval);
return usb_submit_urb(mixer->urb, GFP_KERNEL); } @@ -2084,7 +2120,7 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer, { int err;
- /* Initialise private data and sequence number */ + /* Initialise private data, sequence number, and get the USB data */ err = scarlett2_init_private(mixer, info); if (err < 0) return err;
participants (1)
-
Geoffrey D. Bennett