summaryrefslogtreecommitdiff
path: root/sound/usb/card.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/card.c')
-rw-r--r--sound/usb/card.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 827fb0bc8b56..fd6fd1726ea0 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -72,6 +72,7 @@ static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
static bool ignore_ctl_error;
static bool autoclock = true;
static char *quirk_alias[SNDRV_CARDS];
+static char *delayed_register[SNDRV_CARDS];
bool snd_usb_use_vmalloc = true;
bool snd_usb_skip_validation;
@@ -95,6 +96,8 @@ module_param(autoclock, bool, 0444);
MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes).");
module_param_array(quirk_alias, charp, NULL, 0444);
MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef.");
+module_param_array(delayed_register, charp, NULL, 0444);
+MODULE_PARM_DESC(delayed_register, "Quirk for delayed registration, given by id:iface, e.g. 0123abcd:4.");
module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444);
MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes).");
module_param_named(skip_validation, snd_usb_skip_validation, bool, 0444);
@@ -525,6 +528,21 @@ 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)
+{
+ int i;
+ unsigned int id, inum;
+
+ for (i = 0; i < ARRAY_SIZE(delayed_register); i++) {
+ if (delayed_register[i] &&
+ sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 &&
+ id == chip->usb_id)
+ return inum != iface;
+ }
+
+ return false;
+}
+
static const struct usb_device_id usb_audio_ids[]; /* defined below */
/* look for the corresponding quirk */
@@ -662,10 +680,22 @@ static int usb_audio_probe(struct usb_interface *intf,
goto __error;
}
- /* we are allowed to call snd_card_register() many times */
- err = snd_card_register(chip->card);
- if (err < 0)
- goto __error;
+ if (chip->need_delayed_register) {
+ dev_info(&dev->dev,
+ "Found post-registration device assignment: %08x:%02x\n",
+ chip->usb_id, ifnum);
+ 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
+ */
+ if (!snd_usb_registration_quirk(chip, ifnum) &&
+ !check_delayed_register_option(chip, ifnum)) {
+ err = snd_card_register(chip->card);
+ if (err < 0)
+ goto __error;
+ }
if (quirk && quirk->shares_media_device) {
/* don't want to fail when snd_media_device_create() fails */