* [PATCH 14/14] ALSA: usb-audio: scarlett2: Remove hard-coded USB #defines
@ 2021-06-20 16:46 Geoffrey D. Bennett
0 siblings, 0 replies; only message in thread
From: Geoffrey D. Bennett @ 2021-06-20 16:46 UTC (permalink / raw)
To: alsa-devel, Takashi Iwai; +Cc: Hin-Tak Leung, Vladimir Sadovnikov
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;
--
2.31.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2021-06-20 16:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-06-20 16:46 [PATCH 14/14] ALSA: usb-audio: scarlett2: Remove hard-coded USB #defines Geoffrey D. Bennett
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.