diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/6fire/chip.c | 5 | ||||
-rw-r--r-- | sound/usb/caiaq/device.c | 6 | ||||
-rw-r--r-- | sound/usb/card.c | 28 | ||||
-rw-r--r-- | sound/usb/hiface/chip.c | 10 | ||||
-rw-r--r-- | sound/usb/misc/ua101.c | 7 | ||||
-rw-r--r-- | sound/usb/mixer.c | 101 | ||||
-rw-r--r-- | sound/usb/mixer.h | 7 | ||||
-rw-r--r-- | sound/usb/usx2y/us122l.c | 11 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2y.c | 13 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2y.h | 2 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2yaudio.c | 60 | ||||
-rw-r--r-- | sound/usb/usx2y/usx2yhwdeppcm.c | 76 |
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 | */ |
331 | static int snd_usb_audio_create(struct usb_device *dev, int idx, | 331 | static 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 | ||
699 | static int usb_audio_resume(struct usb_interface *intf) | 701 | static 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) | |||
723 | err_out: | 725 | err_out: |
724 | return err; | 726 | return err; |
725 | } | 727 | } |
728 | |||
729 | static int usb_audio_resume(struct usb_interface *intf) | ||
730 | { | ||
731 | return __usb_audio_resume(intf, false); | ||
732 | } | ||
733 | |||
734 | static 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 | ||
731 | static struct usb_device_id usb_audio_ids [] = { | 744 | static 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 | ||
67 | static int hiface_chip_create(struct usb_device *device, int idx, | 67 | static 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 */ | ||
2303 | void 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 | |||
2309 | int 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 */ |
2323 | static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) | 2303 | static 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 */ | ||
2403 | static 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 | |||
2409 | static 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 | |||
2422 | int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer) | ||
2423 | { | ||
2424 | snd_usb_mixer_inactivate(mixer); | ||
2425 | return 0; | ||
2426 | } | ||
2427 | |||
2428 | static 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 | |||
2457 | int 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 | ||
64 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | 64 | int 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); |
66 | void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer); | ||
67 | int snd_usb_mixer_activate(struct usb_mixer_interface *mixer); | ||
68 | 66 | ||
69 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | 67 | int 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, | |||
72 | int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | 70 | int 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 | ||
74 | int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); | ||
75 | int 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 | ||
538 | static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) | 538 | static 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 | ||
335 | static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) | 335 | static 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 | ||
603 | static int usX2Y_pcms_lock_check(struct snd_card *card) | 603 | static 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 | ||
633 | static 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 | |||
648 | static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file) | 617 | static 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) | |||
660 | static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file) | 631 | static 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 | ||