aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/card.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /sound/usb/card.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'sound/usb/card.c')
-rw-r--r--sound/usb/card.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index ccf95cfe186..d8f2bf40145 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -25,6 +25,9 @@
25 * 25 *
26 * NOTES: 26 * NOTES:
27 * 27 *
28 * - async unlink should be used for avoiding the sleep inside lock.
29 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
30 * oops. in such a cse, pass async_unlink=0 option.
28 * - the linked URBs would be preferred but not used so far because of 31 * - the linked URBs would be preferred but not used so far because of
29 * the instability of unlinking. 32 * the instability of unlinking.
30 * - type II is not supported properly. there is no device which supports 33 * - type II is not supported properly. there is no device which supports
@@ -44,7 +47,6 @@
44#include <linux/mutex.h> 47#include <linux/mutex.h>
45#include <linux/usb/audio.h> 48#include <linux/usb/audio.h>
46#include <linux/usb/audio-v2.h> 49#include <linux/usb/audio-v2.h>
47#include <linux/module.h>
48 50
49#include <sound/control.h> 51#include <sound/control.h>
50#include <sound/core.h> 52#include <sound/core.h>
@@ -63,9 +65,9 @@
63#include "helper.h" 65#include "helper.h"
64#include "debug.h" 66#include "debug.h"
65#include "pcm.h" 67#include "pcm.h"
68#include "urb.h"
66#include "format.h" 69#include "format.h"
67#include "power.h" 70#include "power.h"
68#include "stream.h"
69 71
70MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); 72MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
71MODULE_DESCRIPTION("USB Audio"); 73MODULE_DESCRIPTION("USB Audio");
@@ -75,13 +77,14 @@ MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
75 77
76static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 78static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
77static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 79static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
78static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ 80static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
79/* Vendor/product IDs for this card */ 81/* Vendor/product IDs for this card */
80static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; 82static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
81static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; 83static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
82static int nrpacks = 8; /* max. number of packets per urb */ 84static int nrpacks = 8; /* max. number of packets per urb */
85static int async_unlink = 1;
83static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ 86static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
84static bool ignore_ctl_error; 87static int ignore_ctl_error;
85 88
86module_param_array(index, int, NULL, 0444); 89module_param_array(index, int, NULL, 0444);
87MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); 90MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -95,6 +98,8 @@ module_param_array(pid, int, NULL, 0444);
95MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); 98MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
96module_param(nrpacks, int, 0644); 99module_param(nrpacks, int, 0644);
97MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); 100MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
101module_param(async_unlink, bool, 0444);
102MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
98module_param_array(device_setup, int, NULL, 0444); 103module_param_array(device_setup, int, NULL, 0444);
99MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); 104MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
100module_param(ignore_ctl_error, bool, 0444); 105module_param(ignore_ctl_error, bool, 0444);
@@ -125,9 +130,8 @@ static void snd_usb_stream_disconnect(struct list_head *head)
125 subs = &as->substream[idx]; 130 subs = &as->substream[idx];
126 if (!subs->num_formats) 131 if (!subs->num_formats)
127 continue; 132 continue;
133 snd_usb_release_substream_urbs(subs, 1);
128 subs->interface = -1; 134 subs->interface = -1;
129 subs->data_endpoint = NULL;
130 subs->sync_endpoint = NULL;
131 } 135 }
132} 136}
133 137
@@ -181,7 +185,7 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int
181 return -EINVAL; 185 return -EINVAL;
182 } 186 }
183 187
184 if (! snd_usb_parse_audio_interface(chip, interface)) { 188 if (! snd_usb_parse_audio_endpoints(chip, interface)) {
185 usb_set_interface(dev, interface, 0); /* reset the current interface */ 189 usb_set_interface(dev, interface, 0); /* reset the current interface */
186 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); 190 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
187 return -EINVAL; 191 return -EINVAL;
@@ -271,7 +275,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
271 275
272static int snd_usb_audio_free(struct snd_usb_audio *chip) 276static int snd_usb_audio_free(struct snd_usb_audio *chip)
273{ 277{
274 mutex_destroy(&chip->mutex);
275 kfree(chip); 278 kfree(chip);
276 return 0; 279 return 0;
277} 280}
@@ -332,19 +335,18 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
332 return -ENOMEM; 335 return -ENOMEM;
333 } 336 }
334 337
335 mutex_init(&chip->mutex); 338 mutex_init(&chip->shutdown_mutex);
336 init_rwsem(&chip->shutdown_rwsem);
337 chip->index = idx; 339 chip->index = idx;
338 chip->dev = dev; 340 chip->dev = dev;
339 chip->card = card; 341 chip->card = card;
340 chip->setup = device_setup[idx]; 342 chip->setup = device_setup[idx];
341 chip->nrpacks = nrpacks; 343 chip->nrpacks = nrpacks;
344 chip->async_unlink = async_unlink;
342 chip->probing = 1; 345 chip->probing = 1;
343 346
344 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 347 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
345 le16_to_cpu(dev->descriptor.idProduct)); 348 le16_to_cpu(dev->descriptor.idProduct));
346 INIT_LIST_HEAD(&chip->pcm_list); 349 INIT_LIST_HEAD(&chip->pcm_list);
347 INIT_LIST_HEAD(&chip->ep_list);
348 INIT_LIST_HEAD(&chip->midi_list); 350 INIT_LIST_HEAD(&chip->midi_list);
349 INIT_LIST_HEAD(&chip->mixer_list); 351 INIT_LIST_HEAD(&chip->mixer_list);
350 352
@@ -546,17 +548,15 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
546 struct snd_usb_audio *chip) 548 struct snd_usb_audio *chip)
547{ 549{
548 struct snd_card *card; 550 struct snd_card *card;
549 struct list_head *p, *n; 551 struct list_head *p;
550 552
551 if (chip == (void *)-1L) 553 if (chip == (void *)-1L)
552 return; 554 return;
553 555
554 card = chip->card; 556 card = chip->card;
555 down_write(&chip->shutdown_rwsem);
556 chip->shutdown = 1;
557 up_write(&chip->shutdown_rwsem);
558
559 mutex_lock(&register_mutex); 557 mutex_lock(&register_mutex);
558 mutex_lock(&chip->shutdown_mutex);
559 chip->shutdown = 1;
560 chip->num_interfaces--; 560 chip->num_interfaces--;
561 if (chip->num_interfaces <= 0) { 561 if (chip->num_interfaces <= 0) {
562 snd_card_disconnect(card); 562 snd_card_disconnect(card);
@@ -564,10 +564,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
564 list_for_each(p, &chip->pcm_list) { 564 list_for_each(p, &chip->pcm_list) {
565 snd_usb_stream_disconnect(p); 565 snd_usb_stream_disconnect(p);
566 } 566 }
567 /* release the endpoint resources */
568 list_for_each_safe(p, n, &chip->ep_list) {
569 snd_usb_endpoint_free(p);
570 }
571 /* release the midi resources */ 567 /* release the midi resources */
572 list_for_each(p, &chip->midi_list) { 568 list_for_each(p, &chip->midi_list) {
573 snd_usbmidi_disconnect(p); 569 snd_usbmidi_disconnect(p);
@@ -577,9 +573,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
577 snd_usb_mixer_disconnect(p); 573 snd_usb_mixer_disconnect(p);
578 } 574 }
579 usb_chip[chip->index] = NULL; 575 usb_chip[chip->index] = NULL;
576 mutex_unlock(&chip->shutdown_mutex);
580 mutex_unlock(&register_mutex); 577 mutex_unlock(&register_mutex);
581 snd_card_free_when_closed(card); 578 snd_card_free_when_closed(card);
582 } else { 579 } else {
580 mutex_unlock(&chip->shutdown_mutex);
583 mutex_unlock(&register_mutex); 581 mutex_unlock(&register_mutex);
584 } 582 }
585} 583}
@@ -611,20 +609,16 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
611{ 609{
612 int err = -ENODEV; 610 int err = -ENODEV;
613 611
614 down_read(&chip->shutdown_rwsem);
615 if (!chip->shutdown && !chip->probing) 612 if (!chip->shutdown && !chip->probing)
616 err = usb_autopm_get_interface(chip->pm_intf); 613 err = usb_autopm_get_interface(chip->pm_intf);
617 up_read(&chip->shutdown_rwsem);
618 614
619 return err; 615 return err;
620} 616}
621 617
622void snd_usb_autosuspend(struct snd_usb_audio *chip) 618void snd_usb_autosuspend(struct snd_usb_audio *chip)
623{ 619{
624 down_read(&chip->shutdown_rwsem);
625 if (!chip->shutdown && !chip->probing) 620 if (!chip->shutdown && !chip->probing)
626 usb_autopm_put_interface(chip->pm_intf); 621 usb_autopm_put_interface(chip->pm_intf);
627 up_read(&chip->shutdown_rwsem);
628} 622}
629 623
630static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) 624static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
@@ -637,14 +631,12 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
637 if (chip == (void *)-1L) 631 if (chip == (void *)-1L)
638 return 0; 632 return 0;
639 633
640 if (!PMSG_IS_AUTO(message)) { 634 if (!(message.event & PM_EVENT_AUTO)) {
641 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 635 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
642 if (!chip->num_suspended_intf++) { 636 if (!chip->num_suspended_intf++) {
643 list_for_each(p, &chip->pcm_list) { 637 list_for_each(p, &chip->pcm_list) {
644 as = list_entry(p, struct snd_usb_stream, list); 638 as = list_entry(p, struct snd_usb_stream, list);
645 snd_pcm_suspend_all(as->pcm); 639 snd_pcm_suspend_all(as->pcm);
646 as->substream[0].need_setup_ep =
647 as->substream[1].need_setup_ep = true;
648 } 640 }
649 } 641 }
650 } else { 642 } else {