diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/card.c | 32 | ||||
-rw-r--r-- | sound/usb/line6/driver.h | 2 | ||||
-rw-r--r-- | sound/usb/pcm.c | 40 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 76 | ||||
-rw-r--r-- | sound/usb/quirks.c | 344 | ||||
-rw-r--r-- | sound/usb/quirks.h | 2 | ||||
-rw-r--r-- | sound/usb/stream.c | 6 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 |
8 files changed, 414 insertions, 89 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 706d249a9ad6..3aea241435fb 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -690,7 +690,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id) return false; } -static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface) +static int check_delayed_register_option(struct snd_usb_audio *chip) { int i; unsigned int id, inum; @@ -699,14 +699,31 @@ static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface) if (delayed_register[i] && sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 && id == chip->usb_id) - return iface < inum; + return inum; } - return false; + return -1; } static const struct usb_device_id usb_audio_ids[]; /* defined below */ +/* look for the last interface that matches with our ids and remember it */ +static void find_last_interface(struct snd_usb_audio *chip) +{ + struct usb_host_config *config = chip->dev->actconfig; + struct usb_interface *intf; + int i; + + if (!config) + return; + for (i = 0; i < config->desc.bNumInterfaces; i++) { + intf = config->interface[i]; + if (usb_match_id(intf, usb_audio_ids)) + chip->last_iface = intf->altsetting[0].desc.bInterfaceNumber; + } + usb_audio_dbg(chip, "Found last interface = %d\n", chip->last_iface); +} + /* look for the corresponding quirk */ static const struct snd_usb_audio_quirk * get_alias_quirk(struct usb_device *dev, unsigned int id) @@ -813,6 +830,7 @@ static int usb_audio_probe(struct usb_interface *intf, err = -ENODEV; goto __error; } + find_last_interface(chip); } if (chip->num_interfaces >= MAX_CARD_INTERFACES) { @@ -862,11 +880,11 @@ static int usb_audio_probe(struct usb_interface *intf, chip->need_delayed_register = false; /* clear again */ } - /* we are allowed to call snd_card_register() many times, but first - * check to see if a device needs to skip it or do anything special + /* register card if we reach to the last interface or to the specified + * one given via option */ - if (!snd_usb_registration_quirk(chip, ifnum) && - !check_delayed_register_option(chip, ifnum)) { + if (check_delayed_register_option(chip) == ifnum || + chip->last_iface == ifnum) { err = snd_card_register(chip->card); if (err < 0) goto __error; diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index ecf3a2b39c7e..dbb1d90d3647 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -193,8 +193,6 @@ extern int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, int size); extern int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, int size); -extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count); extern int line6_version_request_async(struct usb_line6 *line6); extern int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, unsigned datalen); diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index b604f7e95e82..4ed53a3dc922 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -433,35 +433,6 @@ static void close_endpoints(struct snd_usb_audio *chip, } } -static int configure_endpoints(struct snd_usb_audio *chip, - struct snd_usb_substream *subs) -{ - int err; - - if (subs->data_endpoint->need_setup) { - /* stop any running stream beforehand */ - if (stop_endpoints(subs, false)) - sync_pending_stops(subs); - if (subs->sync_endpoint) { - err = snd_usb_endpoint_prepare(chip, subs->sync_endpoint); - if (err < 0) - return err; - } - err = snd_usb_endpoint_prepare(chip, subs->data_endpoint); - if (err < 0) - return err; - snd_usb_set_format_quirk(subs, subs->cur_audiofmt); - } else { - if (subs->sync_endpoint) { - err = snd_usb_endpoint_prepare(chip, subs->sync_endpoint); - if (err < 0) - return err; - } - } - - return 0; -} - /* * hw_params callback * @@ -640,9 +611,18 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) goto unlock; } - ret = configure_endpoints(chip, subs); + if (subs->sync_endpoint) { + ret = snd_usb_endpoint_prepare(chip, subs->sync_endpoint); + if (ret < 0) + goto unlock; + } + + ret = snd_usb_endpoint_prepare(chip, subs->data_endpoint); if (ret < 0) goto unlock; + else if (ret > 0) + snd_usb_set_format_quirk(subs, subs->cur_audiofmt); + ret = 0; /* reset the pointer */ subs->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size); diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index f93201a830b5..06dfdd45cff8 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2985,6 +2985,82 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, +/* DIGIDESIGN MBOX 3 */ +{ + USB_DEVICE(0x0dba, 0x5000), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Digidesign", + .product_name = "Mbox 3", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_IGNORE_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_IGNORE_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S24_3LE, + .channels = 4, + .iface = 2, + .altsetting = 1, + .altset_idx = 1, + .attributes = 0x00, + .endpoint = 0x01, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { + 48000 + } + } + }, + { + .ifnum = 3, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S24_3LE, + .channels = 4, + .iface = 3, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x81, + .attributes = 0x00, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .maxpacksize = 0x009c, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { + 48000 + } + } + }, + { + .ifnum = 4, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = &(const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } + } + } +}, { /* Tascam US122 MKII - playback-only support */ USB_DEVICE_VENDOR_SPEC(0x0644, 0x8021), diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 5b4d8f5eade2..eadac586bcc8 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1020,6 +1020,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev) return 0; } +static void mbox3_setup_48_24_magic(struct usb_device *dev) +{ + /* The Mbox 3 is "little endian" */ + /* max volume is: 0x0000. */ + /* min volume is: 0x0080 (shown in little endian form) */ + + + /* Load 48000Hz rate into buffer */ + u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00}; + + /* Set 48000Hz sample rate */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed? + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 0x01, 0x21, 0x0100, 0x8101, &com_buff, 4); + + /* Deactivate Tuner */ + /* on = 0x01*/ + /* off = 0x00*/ + com_buff[0] = 0x00; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1); + + /* Set clock source to Internal (as opposed to S/PDIF) */ + com_buff[0] = 0x01; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0100, 0x8001, &com_buff, 1); + + /* Mute the hardware loopbacks to start the device in a known state. */ + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* Analogue input 1 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0110, 0x4001, &com_buff, 2); + /* Analogue input 1 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0111, 0x4001, &com_buff, 2); + /* Analogue input 2 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0114, 0x4001, &com_buff, 2); + /* Analogue input 2 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0115, 0x4001, &com_buff, 2); + /* Analogue input 3 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0118, 0x4001, &com_buff, 2); + /* Analogue input 3 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0119, 0x4001, &com_buff, 2); + /* Analogue input 4 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x011c, 0x4001, &com_buff, 2); + /* Analogue input 4 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x011d, 0x4001, &com_buff, 2); + + /* Set software sends to output */ + com_buff[0] = 0x00; + com_buff[1] = 0x00; + /* Analogue software return 1 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0100, 0x4001, &com_buff, 2); + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* Analogue software return 1 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0101, 0x4001, &com_buff, 2); + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* Analogue software return 2 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0104, 0x4001, &com_buff, 2); + com_buff[0] = 0x00; + com_buff[1] = 0x00; + /* Analogue software return 2 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0105, 0x4001, &com_buff, 2); + + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* Analogue software return 3 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0108, 0x4001, &com_buff, 2); + /* Analogue software return 3 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0109, 0x4001, &com_buff, 2); + /* Analogue software return 4 left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x010c, 0x4001, &com_buff, 2); + /* Analogue software return 4 right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x010d, 0x4001, &com_buff, 2); + + /* Return to muting sends */ + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* Analogue fx return left channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0120, 0x4001, &com_buff, 2); + /* Analogue fx return right channel: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0121, 0x4001, &com_buff, 2); + + /* Analogue software input 1 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0100, 0x4201, &com_buff, 2); + /* Analogue software input 2 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0101, 0x4201, &com_buff, 2); + /* Analogue software input 3 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0102, 0x4201, &com_buff, 2); + /* Analogue software input 4 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0103, 0x4201, &com_buff, 2); + /* Analogue input 1 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0104, 0x4201, &com_buff, 2); + /* Analogue input 2 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0105, 0x4201, &com_buff, 2); + /* Analogue input 3 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0106, 0x4201, &com_buff, 2); + /* Analogue input 4 fx send: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0107, 0x4201, &com_buff, 2); + + /* Toggle allowing host control */ + com_buff[0] = 0x02; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 3, 0x21, 0x0000, 0x2001, &com_buff, 1); + + /* Do not dim fx returns */ + com_buff[0] = 0x00; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 3, 0x21, 0x0002, 0x2001, &com_buff, 1); + + /* Do not set fx returns to mono */ + com_buff[0] = 0x00; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 3, 0x21, 0x0001, 0x2001, &com_buff, 1); + + /* Mute the S/PDIF hardware loopback + * same odd volume logic here as above + */ + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* S/PDIF hardware input 1 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0112, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 1 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0113, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 2 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0116, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 2 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0117, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 3 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x011a, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 3 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x011b, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 4 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x011e, 0x4001, &com_buff, 2); + /* S/PDIF hardware input 4 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x011f, 0x4001, &com_buff, 2); + /* S/PDIF software return 1 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0102, 0x4001, &com_buff, 2); + /* S/PDIF software return 1 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0103, 0x4001, &com_buff, 2); + /* S/PDIF software return 2 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0106, 0x4001, &com_buff, 2); + /* S/PDIF software return 2 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0107, 0x4001, &com_buff, 2); + + com_buff[0] = 0x00; + com_buff[1] = 0x00; + /* S/PDIF software return 3 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x010a, 0x4001, &com_buff, 2); + + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* S/PDIF software return 3 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x010b, 0x4001, &com_buff, 2); + /* S/PDIF software return 4 left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x010e, 0x4001, &com_buff, 2); + + com_buff[0] = 0x00; + com_buff[1] = 0x00; + /* S/PDIF software return 4 right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x010f, 0x4001, &com_buff, 2); + + com_buff[0] = 0x00; + com_buff[1] = 0x80; + /* S/PDIF fx returns left channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0122, 0x4001, &com_buff, 2); + /* S/PDIF fx returns right channel */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0123, 0x4001, &com_buff, 2); + + /* Set the dropdown "Effect" to the first option */ + /* Room1 = 0x00 */ + /* Room2 = 0x01 */ + /* Room3 = 0x02 */ + /* Hall 1 = 0x03 */ + /* Hall 2 = 0x04 */ + /* Plate = 0x05 */ + /* Delay = 0x06 */ + /* Echo = 0x07 */ + com_buff[0] = 0x00; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0200, 0x4301, &com_buff, 1); /* max is 0xff */ + /* min is 0x00 */ + + + /* Set the effect duration to 0 */ + /* max is 0xffff */ + /* min is 0x0000 */ + com_buff[0] = 0x00; + com_buff[1] = 0x00; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0400, 0x4301, &com_buff, 2); + + /* Set the effect volume and feedback to 0 */ + /* max is 0xff */ + /* min is 0x00 */ + com_buff[0] = 0x00; + /* feedback: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0500, 0x4301, &com_buff, 1); + /* volume: */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 1, 0x21, 0x0300, 0x4301, &com_buff, 1); + + /* Set soft button hold duration */ + /* 0x03 = 250ms */ + /* 0x05 = 500ms DEFAULT */ + /* 0x08 = 750ms */ + /* 0x0a = 1sec */ + com_buff[0] = 0x05; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 3, 0x21, 0x0005, 0x2001, &com_buff, 1); + + /* Use dim LEDs for button of state */ + com_buff[0] = 0x00; + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), + 3, 0x21, 0x0004, 0x2001, &com_buff, 1); +} + +#define MBOX3_DESCRIPTOR_SIZE 464 + +static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) +{ + struct usb_host_config *config = dev->actconfig; + int err; + int descriptor_size; + + descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength); + + if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) { + dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size); + return -ENODEV; + } + + dev_dbg(&dev->dev, "device initialised!\n"); + + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, + &dev->descriptor, sizeof(dev->descriptor)); + config = dev->actconfig; + if (err < 0) + dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); + + err = usb_reset_configuration(dev); + if (err < 0) + dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); + dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n", + le16_to_cpu(get_cfg_desc(config)->wTotalLength)); + + mbox3_setup_48_24_magic(dev); + dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz"); + + return 0; /* Successful boot */ +} #define MICROBOOK_BUF_SIZE 128 @@ -1324,6 +1622,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, case USB_ID(0x0dba, 0x3000): /* Digidesign Mbox 2 */ return snd_usb_mbox2_boot_quirk(dev); + case USB_ID(0x0dba, 0x5000): + /* Digidesign Mbox 3 */ + return snd_usb_mbox3_boot_quirk(dev); + case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */ case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */ @@ -1729,48 +2031,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, } /* - * registration quirk: - * the registration is skipped if a device matches with the given ID, - * unless the interface reaches to the defined one. This is for delaying - * the registration until the last known interface, so that the card and - * devices appear at the same time. - */ - -struct registration_quirk { - unsigned int usb_id; /* composed via USB_ID() */ - unsigned int interface; /* the interface to trigger register */ -}; - -#define REG_QUIRK_ENTRY(vendor, product, iface) \ - { .usb_id = USB_ID(vendor, product), .interface = (iface) } - -static const struct registration_quirk registration_quirks[] = { - REG_QUIRK_ENTRY(0x0951, 0x16d8, 2), /* Kingston HyperX AMP */ - REG_QUIRK_ENTRY(0x0951, 0x16ed, 2), /* Kingston HyperX Cloud Alpha S */ - REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */ - REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */ - REG_QUIRK_ENTRY(0x0ecb, 0x1f47, 2), /* JBL Quantum 800 */ - REG_QUIRK_ENTRY(0x0ecb, 0x1f4c, 2), /* JBL Quantum 400 */ - REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */ - REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */ - REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */ - { 0 } /* terminator */ -}; - -/* return true if skipping registration */ -bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface) -{ - const struct registration_quirk *q; - - for (q = registration_quirks; q->usb_id; q++) - if (chip->usb_id == q->usb_id) - return iface < q->interface; - - /* Register as normal */ - return false; -} - -/* * driver behavior quirk flags */ struct usb_audio_quirk_flags_table { diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 31abb7cb01a5..f9bfd5ac7bab 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h @@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, struct audioformat *fp, int stream); -bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface); - void snd_usb_init_quirk_flags(struct snd_usb_audio *chip); #endif /* __USBAUDIO_QUIRKS_H */ diff --git a/sound/usb/stream.c b/sound/usb/stream.c index f10f4e6d3fb8..f75601ca2d52 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -1222,12 +1222,6 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, if (err < 0) return err; } - - /* try to set the interface... */ - usb_set_interface(chip->dev, iface_no, 0); - snd_usb_init_pitch(chip, fp); - snd_usb_init_sample_rate(chip, fp, fp->rate_max); - usb_set_interface(chip->dev, iface_no, altno); } return 0; } diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index ffbb4b0d09a0..2c6575029b1c 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -37,6 +37,7 @@ struct snd_usb_audio { unsigned int quirk_flags; unsigned int need_delayed_register:1; /* warn for delayed registration */ int num_interfaces; + int last_iface; int num_suspended_intf; int sample_rate_read_error; |