diff options
Diffstat (limited to 'sound/usb/card.c')
-rw-r--r-- | sound/usb/card.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 1764b9302d46..26268ffb8274 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -387,6 +387,14 @@ static const struct usb_audio_device_name usb_audio_names[] = { DEVICE_NAME(0x05e1, 0x0408, "Syntek", "STK1160"), DEVICE_NAME(0x05e1, 0x0480, "Hauppauge", "Woodbury"), + /* ASUS ROG Zenith II: this machine has also two devices, one for + * the front headphone and another for the rest + */ + PROFILE_NAME(0x0b05, 0x1915, "ASUS", "Zenith II Front Headphone", + "Zenith-II-Front-Headphone"), + PROFILE_NAME(0x0b05, 0x1916, "ASUS", "Zenith II Main Audio", + "Zenith-II-Main-Audio"), + /* ASUS ROG Strix */ PROFILE_NAME(0x0b05, 0x1917, "Realtek", "ALC1220-VB-DT", "Realtek-ALC1220-VB-Desktop"), @@ -635,6 +643,7 @@ static int snd_usb_audio_create(struct usb_interface *intf, INIT_LIST_HEAD(&chip->pcm_list); INIT_LIST_HEAD(&chip->ep_list); INIT_LIST_HEAD(&chip->iface_ref_list); + INIT_LIST_HEAD(&chip->clock_ref_list); INIT_LIST_HEAD(&chip->midi_list); INIT_LIST_HEAD(&chip->mixer_list); @@ -681,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; @@ -690,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 inum != iface; + 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) @@ -716,6 +742,18 @@ get_alias_quirk(struct usb_device *dev, unsigned int id) return NULL; } +/* register card if we reach to the last interface or to the specified + * one given via option + */ +static int try_to_register_card(struct snd_usb_audio *chip, int ifnum) +{ + if (check_delayed_register_option(chip) == ifnum || + chip->last_iface == ifnum || + usb_interface_claimed(usb_ifnum_to_if(chip->dev, chip->last_iface))) + return snd_card_register(chip->card); + return 0; +} + /* * probe the active usb device * @@ -804,6 +842,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) { @@ -853,15 +892,9 @@ 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 - */ - if (!snd_usb_registration_quirk(chip, ifnum) && - !check_delayed_register_option(chip, ifnum)) { - err = snd_card_register(chip->card); - if (err < 0) - goto __error; - } + err = try_to_register_card(chip, ifnum); + if (err < 0) + goto __error_no_register; if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) { /* don't want to fail when snd_media_device_create() fails */ @@ -880,6 +913,11 @@ static int usb_audio_probe(struct usb_interface *intf, return 0; __error: + /* in the case of error in secondary interface, still try to register */ + if (chip) + try_to_register_card(chip, ifnum); + + __error_no_register: if (chip) { /* chip->active is inside the chip->card object, * decrement before memory is possibly returned. @@ -987,8 +1025,6 @@ void snd_usb_unlock_shutdown(struct snd_usb_audio *chip) wake_up(&chip->shutdown_wait); } -#ifdef CONFIG_PM - int snd_usb_autoresume(struct snd_usb_audio *chip) { int i, err; @@ -1100,11 +1136,6 @@ err_out: atomic_dec(&chip->active); /* allow autopm after this point */ return err; } -#else -#define usb_audio_suspend NULL -#define usb_audio_resume NULL -#define usb_audio_resume NULL -#endif /* CONFIG_PM */ static const struct usb_device_id usb_audio_ids [] = { #include "quirks-table.h" |