aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/6fire/chip.c5
-rw-r--r--sound/usb/caiaq/device.c6
-rw-r--r--sound/usb/card.c28
-rw-r--r--sound/usb/hiface/chip.c10
-rw-r--r--sound/usb/misc/ua101.c7
-rw-r--r--sound/usb/mixer.c101
-rw-r--r--sound/usb/mixer.h7
-rw-r--r--sound/usb/usx2y/us122l.c11
-rw-r--r--sound/usb/usx2y/usbusx2y.c13
-rw-r--r--sound/usb/usx2y/usbusx2y.h2
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c60
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c76
12 files changed, 192 insertions, 134 deletions
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index 66edc4a7917f..e0fe0d92db8c 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -124,8 +124,8 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
124 snd_printk(KERN_ERR PREFIX "can't set first interface.\n"); 124 snd_printk(KERN_ERR PREFIX "can't set first interface.\n");
125 return -EIO; 125 return -EIO;
126 } 126 }
127 ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE, 127 ret = snd_card_new(&intf->dev, index[regidx], id[regidx],
128 sizeof(struct sfire_chip), &card); 128 THIS_MODULE, sizeof(struct sfire_chip), &card);
129 if (ret < 0) { 129 if (ret < 0) {
130 snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n"); 130 snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n");
131 return ret; 131 return ret;
@@ -134,7 +134,6 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
134 strcpy(card->shortname, "TerraTec DMX6FireUSB"); 134 strcpy(card->shortname, "TerraTec DMX6FireUSB");
135 sprintf(card->longname, "%s at %d:%d", card->shortname, 135 sprintf(card->longname, "%s at %d:%d", card->shortname,
136 device->bus->busnum, device->devnum); 136 device->bus->busnum, device->devnum);
137 snd_card_set_dev(card, &intf->dev);
138 137
139 chip = card->private_data; 138 chip = card->private_data;
140 chips[regidx] = chip; 139 chips[regidx] = chip;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index bc55f708a696..b871ba407e4e 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -418,8 +418,9 @@ static int create_card(struct usb_device *usb_dev,
418 if (devnum >= SNDRV_CARDS) 418 if (devnum >= SNDRV_CARDS)
419 return -ENODEV; 419 return -ENODEV;
420 420
421 err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, 421 err = snd_card_new(&intf->dev,
422 sizeof(struct snd_usb_caiaqdev), &card); 422 index[devnum], id[devnum], THIS_MODULE,
423 sizeof(struct snd_usb_caiaqdev), &card);
423 if (err < 0) 424 if (err < 0)
424 return err; 425 return err;
425 426
@@ -429,7 +430,6 @@ static int create_card(struct usb_device *usb_dev,
429 cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor), 430 cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
430 le16_to_cpu(usb_dev->descriptor.idProduct)); 431 le16_to_cpu(usb_dev->descriptor.idProduct));
431 spin_lock_init(&cdev->spinlock); 432 spin_lock_init(&cdev->spinlock);
432 snd_card_set_dev(card, &intf->dev);
433 433
434 *cardp = card; 434 *cardp = card;
435 return 0; 435 return 0;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index d979050e6a6a..0cfdc2d3b631 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -328,7 +328,8 @@ static void remove_trailing_spaces(char *str)
328/* 328/*
329 * create a chip instance and set its names. 329 * create a chip instance and set its names.
330 */ 330 */
331static int snd_usb_audio_create(struct usb_device *dev, int idx, 331static int snd_usb_audio_create(struct usb_interface *intf,
332 struct usb_device *dev, int idx,
332 const struct snd_usb_audio_quirk *quirk, 333 const struct snd_usb_audio_quirk *quirk,
333 struct snd_usb_audio **rchip) 334 struct snd_usb_audio **rchip)
334{ 335{
@@ -354,7 +355,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
354 return -ENXIO; 355 return -ENXIO;
355 } 356 }
356 357
357 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card); 358 err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
359 0, &card);
358 if (err < 0) { 360 if (err < 0) {
359 snd_printk(KERN_ERR "cannot create card instance %d\n", idx); 361 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
360 return err; 362 return err;
@@ -513,10 +515,10 @@ snd_usb_audio_probe(struct usb_device *dev,
513 if (enable[i] && ! usb_chip[i] && 515 if (enable[i] && ! usb_chip[i] &&
514 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && 516 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
515 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { 517 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
516 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) { 518 if (snd_usb_audio_create(intf, dev, i, quirk,
519 &chip) < 0) {
517 goto __error; 520 goto __error;
518 } 521 }
519 snd_card_set_dev(chip->card, &intf->dev);
520 chip->pm_intf = intf; 522 chip->pm_intf = intf;
521 break; 523 break;
522 } 524 }
@@ -691,12 +693,12 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
691 } 693 }
692 694
693 list_for_each_entry(mixer, &chip->mixer_list, list) 695 list_for_each_entry(mixer, &chip->mixer_list, list)
694 snd_usb_mixer_inactivate(mixer); 696 snd_usb_mixer_suspend(mixer);
695 697
696 return 0; 698 return 0;
697} 699}
698 700
699static int usb_audio_resume(struct usb_interface *intf) 701static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
700{ 702{
701 struct snd_usb_audio *chip = usb_get_intfdata(intf); 703 struct snd_usb_audio *chip = usb_get_intfdata(intf);
702 struct usb_mixer_interface *mixer; 704 struct usb_mixer_interface *mixer;
@@ -711,7 +713,7 @@ static int usb_audio_resume(struct usb_interface *intf)
711 * we just notify and restart the mixers 713 * we just notify and restart the mixers
712 */ 714 */
713 list_for_each_entry(mixer, &chip->mixer_list, list) { 715 list_for_each_entry(mixer, &chip->mixer_list, list) {
714 err = snd_usb_mixer_activate(mixer); 716 err = snd_usb_mixer_resume(mixer, reset_resume);
715 if (err < 0) 717 if (err < 0)
716 goto err_out; 718 goto err_out;
717 } 719 }
@@ -723,9 +725,20 @@ static int usb_audio_resume(struct usb_interface *intf)
723err_out: 725err_out:
724 return err; 726 return err;
725} 727}
728
729static int usb_audio_resume(struct usb_interface *intf)
730{
731 return __usb_audio_resume(intf, false);
732}
733
734static int usb_audio_reset_resume(struct usb_interface *intf)
735{
736 return __usb_audio_resume(intf, true);
737}
726#else 738#else
727#define usb_audio_suspend NULL 739#define usb_audio_suspend NULL
728#define usb_audio_resume NULL 740#define usb_audio_resume NULL
741#define usb_audio_reset_resume NULL
729#endif /* CONFIG_PM */ 742#endif /* CONFIG_PM */
730 743
731static struct usb_device_id usb_audio_ids [] = { 744static struct usb_device_id usb_audio_ids [] = {
@@ -747,6 +760,7 @@ static struct usb_driver usb_audio_driver = {
747 .disconnect = usb_audio_disconnect, 760 .disconnect = usb_audio_disconnect,
748 .suspend = usb_audio_suspend, 761 .suspend = usb_audio_suspend,
749 .resume = usb_audio_resume, 762 .resume = usb_audio_resume,
763 .reset_resume = usb_audio_reset_resume,
750 .id_table = usb_audio_ids, 764 .id_table = usb_audio_ids,
751 .supports_autosuspend = 1, 765 .supports_autosuspend = 1,
752}; 766};
diff --git a/sound/usb/hiface/chip.c b/sound/usb/hiface/chip.c
index b0dcb3924ce5..2670d646bda9 100644
--- a/sound/usb/hiface/chip.c
+++ b/sound/usb/hiface/chip.c
@@ -64,7 +64,8 @@ struct hiface_vendor_quirk {
64 u8 extra_freq; 64 u8 extra_freq;
65}; 65};
66 66
67static int hiface_chip_create(struct usb_device *device, int idx, 67static int hiface_chip_create(struct usb_interface *intf,
68 struct usb_device *device, int idx,
68 const struct hiface_vendor_quirk *quirk, 69 const struct hiface_vendor_quirk *quirk,
69 struct hiface_chip **rchip) 70 struct hiface_chip **rchip)
70{ 71{
@@ -76,7 +77,8 @@ static int hiface_chip_create(struct usb_device *device, int idx,
76 *rchip = NULL; 77 *rchip = NULL;
77 78
78 /* if we are here, card can be registered in alsa. */ 79 /* if we are here, card can be registered in alsa. */
79 ret = snd_card_create(index[idx], id[idx], THIS_MODULE, sizeof(*chip), &card); 80 ret = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
81 sizeof(*chip), &card);
80 if (ret < 0) { 82 if (ret < 0) {
81 dev_err(&device->dev, "cannot create alsa card.\n"); 83 dev_err(&device->dev, "cannot create alsa card.\n");
82 return ret; 84 return ret;
@@ -132,12 +134,10 @@ static int hiface_chip_probe(struct usb_interface *intf,
132 goto err; 134 goto err;
133 } 135 }
134 136
135 ret = hiface_chip_create(device, i, quirk, &chip); 137 ret = hiface_chip_create(intf, device, i, quirk, &chip);
136 if (ret < 0) 138 if (ret < 0)
137 goto err; 139 goto err;
138 140
139 snd_card_set_dev(chip->card, &intf->dev);
140
141 ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0); 141 ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
142 if (ret < 0) 142 if (ret < 0)
143 goto err_chip_destroy; 143 goto err_chip_destroy;
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 509315937f25..a1bab149df4d 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -1243,8 +1243,9 @@ static int ua101_probe(struct usb_interface *interface,
1243 mutex_unlock(&devices_mutex); 1243 mutex_unlock(&devices_mutex);
1244 return -ENOENT; 1244 return -ENOENT;
1245 } 1245 }
1246 err = snd_card_create(index[card_index], id[card_index], THIS_MODULE, 1246 err = snd_card_new(&interface->dev,
1247 sizeof(*ua), &card); 1247 index[card_index], id[card_index], THIS_MODULE,
1248 sizeof(*ua), &card);
1248 if (err < 0) { 1249 if (err < 0) {
1249 mutex_unlock(&devices_mutex); 1250 mutex_unlock(&devices_mutex);
1250 return err; 1251 return err;
@@ -1283,8 +1284,6 @@ static int ua101_probe(struct usb_interface *interface,
1283 } 1284 }
1284 } 1285 }
1285 1286
1286 snd_card_set_dev(card, &interface->dev);
1287
1288 err = detect_usb_format(ua); 1287 err = detect_usb_format(ua);
1289 if (err < 0) 1288 if (err < 0)
1290 goto probe_error; 1289 goto probe_error;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 44b0ba4feab3..8c152b02da5a 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2299,26 +2299,6 @@ requeue:
2299 } 2299 }
2300} 2300}
2301 2301
2302/* stop any bus activity of a mixer */
2303void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
2304{
2305 usb_kill_urb(mixer->urb);
2306 usb_kill_urb(mixer->rc_urb);
2307}
2308
2309int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
2310{
2311 int err;
2312
2313 if (mixer->urb) {
2314 err = usb_submit_urb(mixer->urb, GFP_NOIO);
2315 if (err < 0)
2316 return err;
2317 }
2318
2319 return 0;
2320}
2321
2322/* create the handler for the optional status interrupt endpoint */ 2302/* create the handler for the optional status interrupt endpoint */
2323static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) 2303static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
2324{ 2304{
@@ -2393,7 +2373,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2393 2373
2394 snd_usb_mixer_apply_create_quirk(mixer); 2374 snd_usb_mixer_apply_create_quirk(mixer);
2395 2375
2396 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); 2376 err = snd_device_new(chip->card, SNDRV_DEV_CODEC, mixer, &dev_ops);
2397 if (err < 0) 2377 if (err < 0)
2398 goto _error; 2378 goto _error;
2399 2379
@@ -2417,3 +2397,82 @@ void snd_usb_mixer_disconnect(struct list_head *p)
2417 usb_kill_urb(mixer->urb); 2397 usb_kill_urb(mixer->urb);
2418 usb_kill_urb(mixer->rc_urb); 2398 usb_kill_urb(mixer->rc_urb);
2419} 2399}
2400
2401#ifdef CONFIG_PM
2402/* stop any bus activity of a mixer */
2403static void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
2404{
2405 usb_kill_urb(mixer->urb);
2406 usb_kill_urb(mixer->rc_urb);
2407}
2408
2409static int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
2410{
2411 int err;
2412
2413 if (mixer->urb) {
2414 err = usb_submit_urb(mixer->urb, GFP_NOIO);
2415 if (err < 0)
2416 return err;
2417 }
2418
2419 return 0;
2420}
2421
2422int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer)
2423{
2424 snd_usb_mixer_inactivate(mixer);
2425 return 0;
2426}
2427
2428static int restore_mixer_value(struct usb_mixer_elem_info *cval)
2429{
2430 int c, err, idx;
2431
2432 if (cval->cmask) {
2433 idx = 0;
2434 for (c = 0; c < MAX_CHANNELS; c++) {
2435 if (!(cval->cmask & (1 << c)))
2436 continue;
2437 if (cval->cached & (1 << c)) {
2438 err = set_cur_mix_value(cval, c + 1, idx,
2439 cval->cache_val[idx]);
2440 if (err < 0)
2441 return err;
2442 }
2443 idx++;
2444 }
2445 } else {
2446 /* master */
2447 if (cval->cached) {
2448 err = set_cur_mix_value(cval, 0, 0, *cval->cache_val);
2449 if (err < 0)
2450 return err;
2451 }
2452 }
2453
2454 return 0;
2455}
2456
2457int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
2458{
2459 struct usb_mixer_elem_info *cval;
2460 int id, err;
2461
2462 /* FIXME: any mixer quirks? */
2463
2464 if (reset_resume) {
2465 /* restore cached mixer values */
2466 for (id = 0; id < MAX_ID_ELEMS; id++) {
2467 for (cval = mixer->id_elems[id]; cval;
2468 cval = cval->next_id_elem) {
2469 err = restore_mixer_value(cval);
2470 if (err < 0)
2471 return err;
2472 }
2473 }
2474 }
2475
2476 return snd_usb_mixer_activate(mixer);
2477}
2478#endif
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index aab80df201bd..73b1f649447b 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -63,8 +63,6 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
63 63
64int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 64int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
65 int request, int validx, int value_set); 65 int request, int validx, int value_set);
66void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer);
67int snd_usb_mixer_activate(struct usb_mixer_interface *mixer);
68 66
69int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, 67int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
70 struct snd_kcontrol *kctl); 68 struct snd_kcontrol *kctl);
@@ -72,4 +70,9 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
72int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 70int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
73 unsigned int size, unsigned int __user *_tlv); 71 unsigned int size, unsigned int __user *_tlv);
74 72
73#ifdef CONFIG_PM
74int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer);
75int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume);
76#endif
77
75#endif /* __USBMIXER_H */ 78#endif /* __USBMIXER_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 999550bbad40..cf5dc33f4a6d 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -535,7 +535,9 @@ static void snd_us122l_free(struct snd_card *card)
535 snd_us122l_card_used[index] = 0; 535 snd_us122l_card_used[index] = 0;
536} 536}
537 537
538static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) 538static int usx2y_create_card(struct usb_device *device,
539 struct usb_interface *intf,
540 struct snd_card **cardp)
539{ 541{
540 int dev; 542 int dev;
541 struct snd_card *card; 543 struct snd_card *card;
@@ -546,8 +548,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
546 break; 548 break;
547 if (dev >= SNDRV_CARDS) 549 if (dev >= SNDRV_CARDS)
548 return -ENODEV; 550 return -ENODEV;
549 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 551 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
550 sizeof(struct us122l), &card); 552 sizeof(struct us122l), &card);
551 if (err < 0) 553 if (err < 0)
552 return err; 554 return err;
553 snd_us122l_card_used[US122L(card)->card_index = dev] = 1; 555 snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
@@ -578,11 +580,10 @@ static int us122l_usb_probe(struct usb_interface *intf,
578 struct snd_card *card; 580 struct snd_card *card;
579 int err; 581 int err;
580 582
581 err = usx2y_create_card(device, &card); 583 err = usx2y_create_card(device, intf, &card);
582 if (err < 0) 584 if (err < 0)
583 return err; 585 return err;
584 586
585 snd_card_set_dev(card, &intf->dev);
586 if (!us122l_create_card(card)) { 587 if (!us122l_create_card(card)) {
587 snd_card_free(card); 588 snd_card_free(card);
588 return -EINVAL; 589 return -EINVAL;
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 5a51b18c50fe..91e0e2a4808c 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -332,7 +332,9 @@ static struct usb_device_id snd_usX2Y_usb_id_table[] = {
332 { /* terminator */ } 332 { /* terminator */ }
333}; 333};
334 334
335static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) 335static int usX2Y_create_card(struct usb_device *device,
336 struct usb_interface *intf,
337 struct snd_card **cardp)
336{ 338{
337 int dev; 339 int dev;
338 struct snd_card * card; 340 struct snd_card * card;
@@ -343,15 +345,15 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
343 break; 345 break;
344 if (dev >= SNDRV_CARDS) 346 if (dev >= SNDRV_CARDS)
345 return -ENODEV; 347 return -ENODEV;
346 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 348 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
347 sizeof(struct usX2Ydev), &card); 349 sizeof(struct usX2Ydev), &card);
348 if (err < 0) 350 if (err < 0)
349 return err; 351 return err;
350 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1; 352 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
351 card->private_free = snd_usX2Y_card_private_free; 353 card->private_free = snd_usX2Y_card_private_free;
352 usX2Y(card)->dev = device; 354 usX2Y(card)->dev = device;
353 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); 355 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
354 mutex_init(&usX2Y(card)->prepare_mutex); 356 mutex_init(&usX2Y(card)->pcm_mutex);
355 INIT_LIST_HEAD(&usX2Y(card)->midi_list); 357 INIT_LIST_HEAD(&usX2Y(card)->midi_list);
356 strcpy(card->driver, "USB "NAME_ALLCAPS""); 358 strcpy(card->driver, "USB "NAME_ALLCAPS"");
357 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 359 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
@@ -382,10 +384,9 @@ static int usX2Y_usb_probe(struct usb_device *device,
382 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) 384 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
383 return -EINVAL; 385 return -EINVAL;
384 386
385 err = usX2Y_create_card(device, &card); 387 err = usX2Y_create_card(device, intf, &card);
386 if (err < 0) 388 if (err < 0)
387 return err; 389 return err;
388 snd_card_set_dev(card, &intf->dev);
389 if ((err = usX2Y_hwdep_new(card, device)) < 0 || 390 if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
390 (err = snd_card_register(card)) < 0) { 391 (err = snd_card_register(card)) < 0) {
391 snd_card_free(card); 392 snd_card_free(card);
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index e43c0a86441a..6ae6b0806938 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -36,7 +36,7 @@ struct usX2Ydev {
36 unsigned int rate, 36 unsigned int rate,
37 format; 37 format;
38 int chip_status; 38 int chip_status;
39 struct mutex prepare_mutex; 39 struct mutex pcm_mutex;
40 struct us428ctls_sharedmem *us428ctls_sharedmem; 40 struct us428ctls_sharedmem *us428ctls_sharedmem;
41 int wait_iso_frame; 41 int wait_iso_frame;
42 wait_queue_head_t us428ctls_wait_queue_head; 42 wait_queue_head_t us428ctls_wait_queue_head;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 6234a51625b1..a63330dd1407 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -752,36 +752,44 @@ static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
752 unsigned int rate = params_rate(hw_params); 752 unsigned int rate = params_rate(hw_params);
753 snd_pcm_format_t format = params_format(hw_params); 753 snd_pcm_format_t format = params_format(hw_params);
754 struct snd_card *card = substream->pstr->pcm->card; 754 struct snd_card *card = substream->pstr->pcm->card;
755 struct list_head *list; 755 struct usX2Ydev *dev = usX2Y(card);
756 int i;
756 757
758 mutex_lock(&usX2Y(card)->pcm_mutex);
757 snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params); 759 snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
758 // all pcm substreams off one usX2Y have to operate at the same rate & format 760 /* all pcm substreams off one usX2Y have to operate at the same
759 list_for_each(list, &card->devices) { 761 * rate & format
760 struct snd_device *dev; 762 */
761 struct snd_pcm *pcm; 763 for (i = 0; i < dev->pcm_devs * 2; i++) {
762 int s; 764 struct snd_usX2Y_substream *subs = dev->subs[i];
763 dev = snd_device(list); 765 struct snd_pcm_substream *test_substream;
764 if (dev->type != SNDRV_DEV_PCM) 766
767 if (!subs)
768 continue;
769 test_substream = subs->pcm_substream;
770 if (!test_substream || test_substream == substream ||
771 !test_substream->runtime)
765 continue; 772 continue;
766 pcm = dev->device_data; 773 if ((test_substream->runtime->format &&
767 for (s = 0; s < 2; ++s) { 774 test_substream->runtime->format != format) ||
768 struct snd_pcm_substream *test_substream; 775 (test_substream->runtime->rate &&
769 test_substream = pcm->streams[s].substream; 776 test_substream->runtime->rate != rate)) {
770 if (test_substream && test_substream != substream && 777 err = -EINVAL;
771 test_substream->runtime && 778 goto error;
772 ((test_substream->runtime->format &&
773 test_substream->runtime->format != format) ||
774 (test_substream->runtime->rate &&
775 test_substream->runtime->rate != rate)))
776 return -EINVAL;
777 } 779 }
778 } 780 }
779 if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) { 781
782 err = snd_pcm_lib_malloc_pages(substream,
783 params_buffer_bytes(hw_params));
784 if (err < 0) {
780 snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", 785 snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
781 substream, params_buffer_bytes(hw_params), err); 786 substream, params_buffer_bytes(hw_params), err);
782 return err; 787 goto error;
783 } 788 }
784 return 0; 789
790 error:
791 mutex_unlock(&usX2Y(card)->pcm_mutex);
792 return err;
785} 793}
786 794
787/* 795/*
@@ -791,7 +799,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
791{ 799{
792 struct snd_pcm_runtime *runtime = substream->runtime; 800 struct snd_pcm_runtime *runtime = substream->runtime;
793 struct snd_usX2Y_substream *subs = runtime->private_data; 801 struct snd_usX2Y_substream *subs = runtime->private_data;
794 mutex_lock(&subs->usX2Y->prepare_mutex); 802 mutex_lock(&subs->usX2Y->pcm_mutex);
795 snd_printdd("snd_usX2Y_hw_free(%p)\n", substream); 803 snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
796 804
797 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 805 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -812,7 +820,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
812 usX2Y_urbs_release(subs); 820 usX2Y_urbs_release(subs);
813 } 821 }
814 } 822 }
815 mutex_unlock(&subs->usX2Y->prepare_mutex); 823 mutex_unlock(&subs->usX2Y->pcm_mutex);
816 return snd_pcm_lib_free_pages(substream); 824 return snd_pcm_lib_free_pages(substream);
817} 825}
818/* 826/*
@@ -829,7 +837,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
829 int err = 0; 837 int err = 0;
830 snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); 838 snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
831 839
832 mutex_lock(&usX2Y->prepare_mutex); 840 mutex_lock(&usX2Y->pcm_mutex);
833 usX2Y_subs_prepare(subs); 841 usX2Y_subs_prepare(subs);
834// Start hardware streams 842// Start hardware streams
835// SyncStream first.... 843// SyncStream first....
@@ -849,7 +857,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
849 err = usX2Y_urbs_start(subs); 857 err = usX2Y_urbs_start(subs);
850 858
851 up_prepare_mutex: 859 up_prepare_mutex:
852 mutex_unlock(&usX2Y->prepare_mutex); 860 mutex_unlock(&usX2Y->pcm_mutex);
853 return err; 861 return err;
854} 862}
855 863
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 814d0e887c62..90766a92e7fd 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -358,7 +358,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
358 struct snd_pcm_runtime *runtime = substream->runtime; 358 struct snd_pcm_runtime *runtime = substream->runtime;
359 struct snd_usX2Y_substream *subs = runtime->private_data, 359 struct snd_usX2Y_substream *subs = runtime->private_data,
360 *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; 360 *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
361 mutex_lock(&subs->usX2Y->prepare_mutex); 361 mutex_lock(&subs->usX2Y->pcm_mutex);
362 snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream); 362 snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
363 363
364 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 364 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -387,7 +387,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
387 usX2Y_usbpcm_urbs_release(cap_subs2); 387 usX2Y_usbpcm_urbs_release(cap_subs2);
388 } 388 }
389 } 389 }
390 mutex_unlock(&subs->usX2Y->prepare_mutex); 390 mutex_unlock(&subs->usX2Y->pcm_mutex);
391 return snd_pcm_lib_free_pages(substream); 391 return snd_pcm_lib_free_pages(substream);
392} 392}
393 393
@@ -493,7 +493,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
493 memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm)); 493 memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
494 } 494 }
495 495
496 mutex_lock(&usX2Y->prepare_mutex); 496 mutex_lock(&usX2Y->pcm_mutex);
497 usX2Y_subs_prepare(subs); 497 usX2Y_subs_prepare(subs);
498// Start hardware streams 498// Start hardware streams
499// SyncStream first.... 499// SyncStream first....
@@ -534,7 +534,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
534 usX2Y->hwdep_pcm_shm->capture_iso_start = -1; 534 usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
535 535
536 up_prepare_mutex: 536 up_prepare_mutex:
537 mutex_unlock(&usX2Y->prepare_mutex); 537 mutex_unlock(&usX2Y->pcm_mutex);
538 return err; 538 return err;
539} 539}
540 540
@@ -600,59 +600,30 @@ static struct snd_pcm_ops snd_usX2Y_usbpcm_ops =
600}; 600};
601 601
602 602
603static int usX2Y_pcms_lock_check(struct snd_card *card) 603static int usX2Y_pcms_busy_check(struct snd_card *card)
604{ 604{
605 struct list_head *list; 605 struct usX2Ydev *dev = usX2Y(card);
606 struct snd_device *dev; 606 int i;
607 struct snd_pcm *pcm;
608 int err = 0;
609 list_for_each(list, &card->devices) {
610 dev = snd_device(list);
611 if (dev->type != SNDRV_DEV_PCM)
612 continue;
613 pcm = dev->device_data;
614 mutex_lock(&pcm->open_mutex);
615 }
616 list_for_each(list, &card->devices) {
617 int s;
618 dev = snd_device(list);
619 if (dev->type != SNDRV_DEV_PCM)
620 continue;
621 pcm = dev->device_data;
622 for (s = 0; s < 2; ++s) {
623 struct snd_pcm_substream *substream;
624 substream = pcm->streams[s].substream;
625 if (substream && SUBSTREAM_BUSY(substream))
626 err = -EBUSY;
627 }
628 }
629 return err;
630}
631
632 607
633static void usX2Y_pcms_unlock(struct snd_card *card) 608 for (i = 0; i < dev->pcm_devs * 2; i++) {
634{ 609 struct snd_usX2Y_substream *subs = dev->subs[i];
635 struct list_head *list; 610 if (subs && subs->pcm_substream &&
636 struct snd_device *dev; 611 SUBSTREAM_BUSY(subs->pcm_substream))
637 struct snd_pcm *pcm; 612 return -EBUSY;
638 list_for_each(list, &card->devices) {
639 dev = snd_device(list);
640 if (dev->type != SNDRV_DEV_PCM)
641 continue;
642 pcm = dev->device_data;
643 mutex_unlock(&pcm->open_mutex);
644 } 613 }
614 return 0;
645} 615}
646 616
647
648static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file) 617static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
649{ 618{
650 // we need to be the first
651 struct snd_card *card = hw->card; 619 struct snd_card *card = hw->card;
652 int err = usX2Y_pcms_lock_check(card); 620 int err;
653 if (0 == err) 621
622 mutex_lock(&usX2Y(card)->pcm_mutex);
623 err = usX2Y_pcms_busy_check(card);
624 if (!err)
654 usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS; 625 usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
655 usX2Y_pcms_unlock(card); 626 mutex_unlock(&usX2Y(card)->pcm_mutex);
656 return err; 627 return err;
657} 628}
658 629
@@ -660,10 +631,13 @@ static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
660static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file) 631static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
661{ 632{
662 struct snd_card *card = hw->card; 633 struct snd_card *card = hw->card;
663 int err = usX2Y_pcms_lock_check(card); 634 int err;
664 if (0 == err) 635
636 mutex_lock(&usX2Y(card)->pcm_mutex);
637 err = usX2Y_pcms_busy_check(card);
638 if (!err)
665 usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS; 639 usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
666 usX2Y_pcms_unlock(card); 640 mutex_unlock(&usX2Y(card)->pcm_mutex);
667 return err; 641 return err;
668} 642}
669 643