aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/usb/card.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2020-03-25 11:33:20 +0100
committerTakashi Iwai <tiwai@suse.de>2020-03-26 10:47:39 +0100
commitb70038ef4feae9c5c9d01de4cd799ae52ccafc08 (patch)
treefd25d22b634b3721b738e14a36e93ddf3cd3b36b /sound/usb/card.c
parentALSA: usb-audio: Rewrite registration quirk handling (diff)
downloadwireguard-linux-b70038ef4feae9c5c9d01de4cd799ae52ccafc08.tar.xz
wireguard-linux-b70038ef4feae9c5c9d01de4cd799ae52ccafc08.zip
ALSA: usb-audio: Add delayed_register option
Add a new option for specifying the quirk for delayed registration of the certain device. A list of devices can be passed in a form ID:IFACE,ID:IFACE,ID:IFACE,.... where ID is the 32bit hex number combo of vendor and device IDs and IFACE is the interface number to trigger the register. When a matching device is probed, the card registration is delayed until the given interface is probed. It's needed for syncing the registration until the last interface when multiple interfaces are provided for the same card. Link: https://lore.kernel.org/r/20200325103322.2508-3-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/card.c')
-rw-r--r--sound/usb/card.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 55d563a8154d..951134238669 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 */
@@ -665,7 +683,8 @@ static int usb_audio_probe(struct usb_interface *intf,
/* 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)) {
+ if (!snd_usb_registration_quirk(chip, ifnum) &&
+ !check_delayed_register_option(chip, ifnum)) {
err = snd_card_register(chip->card);
if (err < 0)
goto __error;