Commit 6c0a2078 authored by Geoffrey D. Bennett's avatar Geoffrey D. Bennett Committed by Takashi Iwai
Browse files

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: default avatarGeoffrey D. Bennett <g@b4.vu>
Link: https://lore.kernel.org/r/20210620164652.GA9237@m.b4.vu


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 29672631
Loading
Loading
Loading
Loading
+55 −19
Original line number Diff line number Diff line
@@ -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;