diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/usbaudio.c | 202 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 | ||||
-rw-r--r-- | sound/usb/usbmixer.c | 2 | ||||
-rw-r--r-- | sound/usb/usbquirks.h | 32 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2yaudio.c | 2 | ||||
-rw-r--r-- | sound/usb/usx2y/usx2yhwdeppcm.c | 2 |
6 files changed, 175 insertions, 66 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 67202b9eeb77..4dfb91d4398a 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -186,6 +186,7 @@ struct snd_usb_substream { | |||
186 | u64 formats; /* format bitmasks (all or'ed) */ | 186 | u64 formats; /* format bitmasks (all or'ed) */ |
187 | unsigned int num_formats; /* number of supported audio formats (list) */ | 187 | unsigned int num_formats; /* number of supported audio formats (list) */ |
188 | struct list_head fmt_list; /* format list */ | 188 | struct list_head fmt_list; /* format list */ |
189 | struct snd_pcm_hw_constraint_list rate_list; /* limited rates */ | ||
189 | spinlock_t lock; | 190 | spinlock_t lock; |
190 | 191 | ||
191 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ | 192 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ |
@@ -253,7 +254,7 @@ static int prepare_capture_sync_urb(struct snd_usb_substream *subs, | |||
253 | struct urb *urb) | 254 | struct urb *urb) |
254 | { | 255 | { |
255 | unsigned char *cp = urb->transfer_buffer; | 256 | unsigned char *cp = urb->transfer_buffer; |
256 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 257 | struct snd_urb_ctx *ctx = urb->context; |
257 | 258 | ||
258 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 259 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
259 | urb->iso_frame_desc[0].length = 3; | 260 | urb->iso_frame_desc[0].length = 3; |
@@ -275,7 +276,7 @@ static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs, | |||
275 | struct urb *urb) | 276 | struct urb *urb) |
276 | { | 277 | { |
277 | unsigned char *cp = urb->transfer_buffer; | 278 | unsigned char *cp = urb->transfer_buffer; |
278 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 279 | struct snd_urb_ctx *ctx = urb->context; |
279 | 280 | ||
280 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 281 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
281 | urb->iso_frame_desc[0].length = 4; | 282 | urb->iso_frame_desc[0].length = 4; |
@@ -313,7 +314,7 @@ static int prepare_capture_urb(struct snd_usb_substream *subs, | |||
313 | struct urb *urb) | 314 | struct urb *urb) |
314 | { | 315 | { |
315 | int i, offs; | 316 | int i, offs; |
316 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 317 | struct snd_urb_ctx *ctx = urb->context; |
317 | 318 | ||
318 | offs = 0; | 319 | offs = 0; |
319 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 320 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
@@ -391,6 +392,16 @@ static int retire_capture_urb(struct snd_usb_substream *subs, | |||
391 | return 0; | 392 | return 0; |
392 | } | 393 | } |
393 | 394 | ||
395 | /* | ||
396 | * Process after capture complete when paused. Nothing to do. | ||
397 | */ | ||
398 | static int retire_paused_capture_urb(struct snd_usb_substream *subs, | ||
399 | struct snd_pcm_runtime *runtime, | ||
400 | struct urb *urb) | ||
401 | { | ||
402 | return 0; | ||
403 | } | ||
404 | |||
394 | 405 | ||
395 | /* | 406 | /* |
396 | * prepare urb for full speed playback sync pipe | 407 | * prepare urb for full speed playback sync pipe |
@@ -402,7 +413,7 @@ static int prepare_playback_sync_urb(struct snd_usb_substream *subs, | |||
402 | struct snd_pcm_runtime *runtime, | 413 | struct snd_pcm_runtime *runtime, |
403 | struct urb *urb) | 414 | struct urb *urb) |
404 | { | 415 | { |
405 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 416 | struct snd_urb_ctx *ctx = urb->context; |
406 | 417 | ||
407 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 418 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
408 | urb->iso_frame_desc[0].length = 3; | 419 | urb->iso_frame_desc[0].length = 3; |
@@ -420,7 +431,7 @@ static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs, | |||
420 | struct snd_pcm_runtime *runtime, | 431 | struct snd_pcm_runtime *runtime, |
421 | struct urb *urb) | 432 | struct urb *urb) |
422 | { | 433 | { |
423 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 434 | struct snd_urb_ctx *ctx = urb->context; |
424 | 435 | ||
425 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 436 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
426 | urb->iso_frame_desc[0].length = 4; | 437 | urb->iso_frame_desc[0].length = 4; |
@@ -493,13 +504,13 @@ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) | |||
493 | } | 504 | } |
494 | 505 | ||
495 | /* | 506 | /* |
496 | * Prepare urb for streaming before playback starts. | 507 | * Prepare urb for streaming before playback starts or when paused. |
497 | * | 508 | * |
498 | * We don't yet have data, so we send a frame of silence. | 509 | * We don't have any data, so we send a frame of silence. |
499 | */ | 510 | */ |
500 | static int prepare_startup_playback_urb(struct snd_usb_substream *subs, | 511 | static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, |
501 | struct snd_pcm_runtime *runtime, | 512 | struct snd_pcm_runtime *runtime, |
502 | struct urb *urb) | 513 | struct urb *urb) |
503 | { | 514 | { |
504 | unsigned int i, offs, counts; | 515 | unsigned int i, offs, counts; |
505 | struct snd_urb_ctx *ctx = urb->context; | 516 | struct snd_urb_ctx *ctx = urb->context; |
@@ -537,7 +548,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, | |||
537 | unsigned int counts; | 548 | unsigned int counts; |
538 | unsigned long flags; | 549 | unsigned long flags; |
539 | int period_elapsed = 0; | 550 | int period_elapsed = 0; |
540 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 551 | struct snd_urb_ctx *ctx = urb->context; |
541 | 552 | ||
542 | stride = runtime->frame_bits >> 3; | 553 | stride = runtime->frame_bits >> 3; |
543 | 554 | ||
@@ -622,7 +633,7 @@ static int retire_playback_urb(struct snd_usb_substream *subs, | |||
622 | */ | 633 | */ |
623 | static struct snd_urb_ops audio_urb_ops[2] = { | 634 | static struct snd_urb_ops audio_urb_ops[2] = { |
624 | { | 635 | { |
625 | .prepare = prepare_startup_playback_urb, | 636 | .prepare = prepare_nodata_playback_urb, |
626 | .retire = retire_playback_urb, | 637 | .retire = retire_playback_urb, |
627 | .prepare_sync = prepare_playback_sync_urb, | 638 | .prepare_sync = prepare_playback_sync_urb, |
628 | .retire_sync = retire_playback_sync_urb, | 639 | .retire_sync = retire_playback_sync_urb, |
@@ -637,7 +648,7 @@ static struct snd_urb_ops audio_urb_ops[2] = { | |||
637 | 648 | ||
638 | static struct snd_urb_ops audio_urb_ops_high_speed[2] = { | 649 | static struct snd_urb_ops audio_urb_ops_high_speed[2] = { |
639 | { | 650 | { |
640 | .prepare = prepare_startup_playback_urb, | 651 | .prepare = prepare_nodata_playback_urb, |
641 | .retire = retire_playback_urb, | 652 | .retire = retire_playback_urb, |
642 | .prepare_sync = prepare_playback_sync_urb_hs, | 653 | .prepare_sync = prepare_playback_sync_urb_hs, |
643 | .retire_sync = retire_playback_sync_urb_hs, | 654 | .retire_sync = retire_playback_sync_urb_hs, |
@@ -655,7 +666,7 @@ static struct snd_urb_ops audio_urb_ops_high_speed[2] = { | |||
655 | */ | 666 | */ |
656 | static void snd_complete_urb(struct urb *urb) | 667 | static void snd_complete_urb(struct urb *urb) |
657 | { | 668 | { |
658 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 669 | struct snd_urb_ctx *ctx = urb->context; |
659 | struct snd_usb_substream *subs = ctx->subs; | 670 | struct snd_usb_substream *subs = ctx->subs; |
660 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; | 671 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; |
661 | int err = 0; | 672 | int err = 0; |
@@ -678,7 +689,7 @@ static void snd_complete_urb(struct urb *urb) | |||
678 | */ | 689 | */ |
679 | static void snd_complete_sync_urb(struct urb *urb) | 690 | static void snd_complete_sync_urb(struct urb *urb) |
680 | { | 691 | { |
681 | struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; | 692 | struct snd_urb_ctx *ctx = urb->context; |
682 | struct snd_usb_substream *subs = ctx->subs; | 693 | struct snd_usb_substream *subs = ctx->subs; |
683 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; | 694 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; |
684 | int err = 0; | 695 | int err = 0; |
@@ -925,10 +936,14 @@ static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream, | |||
925 | 936 | ||
926 | switch (cmd) { | 937 | switch (cmd) { |
927 | case SNDRV_PCM_TRIGGER_START: | 938 | case SNDRV_PCM_TRIGGER_START: |
939 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
928 | subs->ops.prepare = prepare_playback_urb; | 940 | subs->ops.prepare = prepare_playback_urb; |
929 | return 0; | 941 | return 0; |
930 | case SNDRV_PCM_TRIGGER_STOP: | 942 | case SNDRV_PCM_TRIGGER_STOP: |
931 | return deactivate_urbs(subs, 0, 0); | 943 | return deactivate_urbs(subs, 0, 0); |
944 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
945 | subs->ops.prepare = prepare_nodata_playback_urb; | ||
946 | return 0; | ||
932 | default: | 947 | default: |
933 | return -EINVAL; | 948 | return -EINVAL; |
934 | } | 949 | } |
@@ -944,9 +959,16 @@ static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream, | |||
944 | 959 | ||
945 | switch (cmd) { | 960 | switch (cmd) { |
946 | case SNDRV_PCM_TRIGGER_START: | 961 | case SNDRV_PCM_TRIGGER_START: |
962 | subs->ops.retire = retire_capture_urb; | ||
947 | return start_urbs(subs, substream->runtime); | 963 | return start_urbs(subs, substream->runtime); |
948 | case SNDRV_PCM_TRIGGER_STOP: | 964 | case SNDRV_PCM_TRIGGER_STOP: |
949 | return deactivate_urbs(subs, 0, 0); | 965 | return deactivate_urbs(subs, 0, 0); |
966 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
967 | subs->ops.retire = retire_paused_capture_urb; | ||
968 | return 0; | ||
969 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
970 | subs->ops.retire = retire_capture_urb; | ||
971 | return 0; | ||
950 | default: | 972 | default: |
951 | return -EINVAL; | 973 | return -EINVAL; |
952 | } | 974 | } |
@@ -1408,7 +1430,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
1408 | static int snd_usb_hw_params(struct snd_pcm_substream *substream, | 1430 | static int snd_usb_hw_params(struct snd_pcm_substream *substream, |
1409 | struct snd_pcm_hw_params *hw_params) | 1431 | struct snd_pcm_hw_params *hw_params) |
1410 | { | 1432 | { |
1411 | struct snd_usb_substream *subs = (struct snd_usb_substream *)substream->runtime->private_data; | 1433 | struct snd_usb_substream *subs = substream->runtime->private_data; |
1412 | struct audioformat *fmt; | 1434 | struct audioformat *fmt; |
1413 | unsigned int channels, rate, format; | 1435 | unsigned int channels, rate, format; |
1414 | int ret, changed; | 1436 | int ret, changed; |
@@ -1464,7 +1486,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
1464 | */ | 1486 | */ |
1465 | static int snd_usb_hw_free(struct snd_pcm_substream *substream) | 1487 | static int snd_usb_hw_free(struct snd_pcm_substream *substream) |
1466 | { | 1488 | { |
1467 | struct snd_usb_substream *subs = (struct snd_usb_substream *)substream->runtime->private_data; | 1489 | struct snd_usb_substream *subs = substream->runtime->private_data; |
1468 | 1490 | ||
1469 | subs->cur_audiofmt = NULL; | 1491 | subs->cur_audiofmt = NULL; |
1470 | subs->cur_rate = 0; | 1492 | subs->cur_rate = 0; |
@@ -1505,33 +1527,20 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
1505 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | 1527 | /* for playback, submit the URBs now; otherwise, the first hwptr_done |
1506 | * updates for all URBs would happen at the same time when starting */ | 1528 | * updates for all URBs would happen at the same time when starting */ |
1507 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) { | 1529 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) { |
1508 | subs->ops.prepare = prepare_startup_playback_urb; | 1530 | subs->ops.prepare = prepare_nodata_playback_urb; |
1509 | return start_urbs(subs, runtime); | 1531 | return start_urbs(subs, runtime); |
1510 | } else | 1532 | } else |
1511 | return 0; | 1533 | return 0; |
1512 | } | 1534 | } |
1513 | 1535 | ||
1514 | static struct snd_pcm_hardware snd_usb_playback = | 1536 | static struct snd_pcm_hardware snd_usb_hardware = |
1515 | { | 1537 | { |
1516 | .info = SNDRV_PCM_INFO_MMAP | | 1538 | .info = SNDRV_PCM_INFO_MMAP | |
1517 | SNDRV_PCM_INFO_MMAP_VALID | | 1539 | SNDRV_PCM_INFO_MMAP_VALID | |
1518 | SNDRV_PCM_INFO_BATCH | | 1540 | SNDRV_PCM_INFO_BATCH | |
1519 | SNDRV_PCM_INFO_INTERLEAVED | | 1541 | SNDRV_PCM_INFO_INTERLEAVED | |
1520 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | 1542 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1521 | .buffer_bytes_max = 1024 * 1024, | 1543 | SNDRV_PCM_INFO_PAUSE, |
1522 | .period_bytes_min = 64, | ||
1523 | .period_bytes_max = 512 * 1024, | ||
1524 | .periods_min = 2, | ||
1525 | .periods_max = 1024, | ||
1526 | }; | ||
1527 | |||
1528 | static struct snd_pcm_hardware snd_usb_capture = | ||
1529 | { | ||
1530 | .info = SNDRV_PCM_INFO_MMAP | | ||
1531 | SNDRV_PCM_INFO_MMAP_VALID | | ||
1532 | SNDRV_PCM_INFO_BATCH | | ||
1533 | SNDRV_PCM_INFO_INTERLEAVED | | ||
1534 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
1535 | .buffer_bytes_max = 1024 * 1024, | 1544 | .buffer_bytes_max = 1024 * 1024, |
1536 | .period_bytes_min = 64, | 1545 | .period_bytes_min = 64, |
1537 | .period_bytes_max = 512 * 1024, | 1546 | .period_bytes_max = 512 * 1024, |
@@ -1810,28 +1819,33 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) | |||
1810 | static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | 1819 | static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, |
1811 | struct snd_usb_substream *subs) | 1820 | struct snd_usb_substream *subs) |
1812 | { | 1821 | { |
1813 | struct list_head *p; | 1822 | struct audioformat *fp; |
1814 | struct snd_pcm_hw_constraint_list constraints_rates; | 1823 | int count = 0, needs_knot = 0; |
1815 | int err; | 1824 | int err; |
1816 | 1825 | ||
1817 | list_for_each(p, &subs->fmt_list) { | 1826 | list_for_each_entry(fp, &subs->fmt_list, list) { |
1818 | struct audioformat *fp; | 1827 | if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) |
1819 | fp = list_entry(p, struct audioformat, list); | 1828 | return 0; |
1820 | 1829 | count += fp->nr_rates; | |
1821 | if (!fp->needs_knot) | 1830 | if (fp->needs_knot) |
1822 | continue; | 1831 | needs_knot = 1; |
1823 | |||
1824 | constraints_rates.count = fp->nr_rates; | ||
1825 | constraints_rates.list = fp->rate_table; | ||
1826 | constraints_rates.mask = 0; | ||
1827 | |||
1828 | err = snd_pcm_hw_constraint_list(runtime, 0, | ||
1829 | SNDRV_PCM_HW_PARAM_RATE, | ||
1830 | &constraints_rates); | ||
1831 | |||
1832 | if (err < 0) | ||
1833 | return err; | ||
1834 | } | 1832 | } |
1833 | if (!needs_knot) | ||
1834 | return 0; | ||
1835 | |||
1836 | subs->rate_list.count = count; | ||
1837 | subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); | ||
1838 | subs->rate_list.mask = 0; | ||
1839 | count = 0; | ||
1840 | list_for_each_entry(fp, &subs->fmt_list, list) { | ||
1841 | int i; | ||
1842 | for (i = 0; i < fp->nr_rates; i++) | ||
1843 | subs->rate_list.list[count++] = fp->rate_table[i]; | ||
1844 | } | ||
1845 | err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | ||
1846 | &subs->rate_list); | ||
1847 | if (err < 0) | ||
1848 | return err; | ||
1835 | 1849 | ||
1836 | return 0; | 1850 | return 0; |
1837 | } | 1851 | } |
@@ -1904,8 +1918,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1904 | return 0; | 1918 | return 0; |
1905 | } | 1919 | } |
1906 | 1920 | ||
1907 | static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction, | 1921 | static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) |
1908 | struct snd_pcm_hardware *hw) | ||
1909 | { | 1922 | { |
1910 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 1923 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
1911 | struct snd_pcm_runtime *runtime = substream->runtime; | 1924 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1913,7 +1926,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction, | |||
1913 | 1926 | ||
1914 | subs->interface = -1; | 1927 | subs->interface = -1; |
1915 | subs->format = 0; | 1928 | subs->format = 0; |
1916 | runtime->hw = *hw; | 1929 | runtime->hw = snd_usb_hardware; |
1917 | runtime->private_data = subs; | 1930 | runtime->private_data = subs; |
1918 | subs->pcm_substream = substream; | 1931 | subs->pcm_substream = substream; |
1919 | return setup_hw_info(runtime, subs); | 1932 | return setup_hw_info(runtime, subs); |
@@ -1934,7 +1947,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | |||
1934 | 1947 | ||
1935 | static int snd_usb_playback_open(struct snd_pcm_substream *substream) | 1948 | static int snd_usb_playback_open(struct snd_pcm_substream *substream) |
1936 | { | 1949 | { |
1937 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK, &snd_usb_playback); | 1950 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK); |
1938 | } | 1951 | } |
1939 | 1952 | ||
1940 | static int snd_usb_playback_close(struct snd_pcm_substream *substream) | 1953 | static int snd_usb_playback_close(struct snd_pcm_substream *substream) |
@@ -1944,7 +1957,7 @@ static int snd_usb_playback_close(struct snd_pcm_substream *substream) | |||
1944 | 1957 | ||
1945 | static int snd_usb_capture_open(struct snd_pcm_substream *substream) | 1958 | static int snd_usb_capture_open(struct snd_pcm_substream *substream) |
1946 | { | 1959 | { |
1947 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE, &snd_usb_capture); | 1960 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE); |
1948 | } | 1961 | } |
1949 | 1962 | ||
1950 | static int snd_usb_capture_close(struct snd_pcm_substream *substream) | 1963 | static int snd_usb_capture_close(struct snd_pcm_substream *substream) |
@@ -2231,6 +2244,7 @@ static void free_substream(struct snd_usb_substream *subs) | |||
2231 | kfree(fp->rate_table); | 2244 | kfree(fp->rate_table); |
2232 | kfree(fp); | 2245 | kfree(fp); |
2233 | } | 2246 | } |
2247 | kfree(subs->rate_list.list); | ||
2234 | } | 2248 | } |
2235 | 2249 | ||
2236 | 2250 | ||
@@ -2456,6 +2470,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform | |||
2456 | * build the rate table and bitmap flags | 2470 | * build the rate table and bitmap flags |
2457 | */ | 2471 | */ |
2458 | int r, idx, c; | 2472 | int r, idx, c; |
2473 | unsigned int nonzero_rates = 0; | ||
2459 | /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */ | 2474 | /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */ |
2460 | static unsigned int conv_rates[] = { | 2475 | static unsigned int conv_rates[] = { |
2461 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, | 2476 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, |
@@ -2471,7 +2486,14 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform | |||
2471 | fp->nr_rates = nr_rates; | 2486 | fp->nr_rates = nr_rates; |
2472 | fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); | 2487 | fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); |
2473 | for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { | 2488 | for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { |
2474 | unsigned int rate = fp->rate_table[r] = combine_triple(&fmt[idx]); | 2489 | unsigned int rate = combine_triple(&fmt[idx]); |
2490 | /* C-Media CM6501 mislabels its 96 kHz altsetting */ | ||
2491 | if (rate == 48000 && nr_rates == 1 && | ||
2492 | chip->usb_id == USB_ID(0x0d8c, 0x0201) && | ||
2493 | fp->altsetting == 5 && fp->maxpacksize == 392) | ||
2494 | rate = 96000; | ||
2495 | fp->rate_table[r] = rate; | ||
2496 | nonzero_rates |= rate; | ||
2475 | if (rate < fp->rate_min) | 2497 | if (rate < fp->rate_min) |
2476 | fp->rate_min = rate; | 2498 | fp->rate_min = rate; |
2477 | else if (rate > fp->rate_max) | 2499 | else if (rate > fp->rate_max) |
@@ -2487,6 +2509,10 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform | |||
2487 | if (!found) | 2509 | if (!found) |
2488 | fp->needs_knot = 1; | 2510 | fp->needs_knot = 1; |
2489 | } | 2511 | } |
2512 | if (!nonzero_rates) { | ||
2513 | hwc_debug("All rates were zero. Skipping format!\n"); | ||
2514 | return -1; | ||
2515 | } | ||
2490 | if (fp->needs_knot) | 2516 | if (fp->needs_knot) |
2491 | fp->rates |= SNDRV_PCM_RATE_KNOT; | 2517 | fp->rates |= SNDRV_PCM_RATE_KNOT; |
2492 | } else { | 2518 | } else { |
@@ -3051,6 +3077,58 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip, | |||
3051 | return 0; | 3077 | return 0; |
3052 | } | 3078 | } |
3053 | 3079 | ||
3080 | /* | ||
3081 | * Create a stream for an Edirol UA-101 interface. | ||
3082 | * Copy, paste and modify from Edirol UA-1000 | ||
3083 | */ | ||
3084 | static int create_ua101_quirk(struct snd_usb_audio *chip, | ||
3085 | struct usb_interface *iface, | ||
3086 | const struct snd_usb_audio_quirk *quirk) | ||
3087 | { | ||
3088 | static const struct audioformat ua101_format = { | ||
3089 | .format = SNDRV_PCM_FORMAT_S32_LE, | ||
3090 | .fmt_type = USB_FORMAT_TYPE_I, | ||
3091 | .altsetting = 1, | ||
3092 | .altset_idx = 1, | ||
3093 | .attributes = 0, | ||
3094 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | ||
3095 | }; | ||
3096 | struct usb_host_interface *alts; | ||
3097 | struct usb_interface_descriptor *altsd; | ||
3098 | struct audioformat *fp; | ||
3099 | int stream, err; | ||
3100 | |||
3101 | if (iface->num_altsetting != 2) | ||
3102 | return -ENXIO; | ||
3103 | alts = &iface->altsetting[1]; | ||
3104 | altsd = get_iface_desc(alts); | ||
3105 | if (alts->extralen != 18 || alts->extra[1] != USB_DT_CS_INTERFACE || | ||
3106 | altsd->bNumEndpoints != 1) | ||
3107 | return -ENXIO; | ||
3108 | |||
3109 | fp = kmemdup(&ua101_format, sizeof(*fp), GFP_KERNEL); | ||
3110 | if (!fp) | ||
3111 | return -ENOMEM; | ||
3112 | |||
3113 | fp->channels = alts->extra[11]; | ||
3114 | fp->iface = altsd->bInterfaceNumber; | ||
3115 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | ||
3116 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | ||
3117 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
3118 | fp->rate_max = fp->rate_min = combine_triple(&alts->extra[15]); | ||
3119 | |||
3120 | stream = (fp->endpoint & USB_DIR_IN) | ||
3121 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | ||
3122 | err = add_audio_endpoint(chip, stream, fp); | ||
3123 | if (err < 0) { | ||
3124 | kfree(fp); | ||
3125 | return err; | ||
3126 | } | ||
3127 | /* FIXME: playback must be synchronized to capture */ | ||
3128 | usb_set_interface(chip->dev, fp->iface, 0); | ||
3129 | return 0; | ||
3130 | } | ||
3131 | |||
3054 | static int snd_usb_create_quirk(struct snd_usb_audio *chip, | 3132 | static int snd_usb_create_quirk(struct snd_usb_audio *chip, |
3055 | struct usb_interface *iface, | 3133 | struct usb_interface *iface, |
3056 | const struct snd_usb_audio_quirk *quirk); | 3134 | const struct snd_usb_audio_quirk *quirk); |
@@ -3232,6 +3310,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
3232 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 3310 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
3233 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, | 3311 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, |
3234 | [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, | 3312 | [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, |
3313 | [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, | ||
3235 | }; | 3314 | }; |
3236 | 3315 | ||
3237 | if (quirk->type < QUIRK_TYPE_COUNT) { | 3316 | if (quirk->type < QUIRK_TYPE_COUNT) { |
@@ -3280,6 +3359,7 @@ static void snd_usb_audio_create_proc(struct snd_usb_audio *chip) | |||
3280 | 3359 | ||
3281 | static int snd_usb_audio_free(struct snd_usb_audio *chip) | 3360 | static int snd_usb_audio_free(struct snd_usb_audio *chip) |
3282 | { | 3361 | { |
3362 | usb_chip[chip->index] = NULL; | ||
3283 | kfree(chip); | 3363 | kfree(chip); |
3284 | return 0; | 3364 | return 0; |
3285 | } | 3365 | } |
@@ -3541,7 +3621,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | |||
3541 | list_for_each(p, &chip->mixer_list) { | 3621 | list_for_each(p, &chip->mixer_list) { |
3542 | snd_usb_mixer_disconnect(p); | 3622 | snd_usb_mixer_disconnect(p); |
3543 | } | 3623 | } |
3544 | usb_chip[chip->index] = NULL; | ||
3545 | mutex_unlock(®ister_mutex); | 3624 | mutex_unlock(®ister_mutex); |
3546 | snd_card_free_when_closed(card); | 3625 | snd_card_free_when_closed(card); |
3547 | } else { | 3626 | } else { |
@@ -3577,8 +3656,7 @@ static int __init snd_usb_audio_init(void) | |||
3577 | printk(KERN_WARNING "invalid nrpacks value.\n"); | 3656 | printk(KERN_WARNING "invalid nrpacks value.\n"); |
3578 | return -EINVAL; | 3657 | return -EINVAL; |
3579 | } | 3658 | } |
3580 | usb_register(&usb_audio_driver); | 3659 | return usb_register(&usb_audio_driver); |
3581 | return 0; | ||
3582 | } | 3660 | } |
3583 | 3661 | ||
3584 | 3662 | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 0f4b2b8541d6..2272f45a1867 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -159,6 +159,7 @@ enum quirk_type { | |||
159 | QUIRK_AUDIO_FIXED_ENDPOINT, | 159 | QUIRK_AUDIO_FIXED_ENDPOINT, |
160 | QUIRK_AUDIO_EDIROL_UA700_UA25, | 160 | QUIRK_AUDIO_EDIROL_UA700_UA25, |
161 | QUIRK_AUDIO_EDIROL_UA1000, | 161 | QUIRK_AUDIO_EDIROL_UA1000, |
162 | QUIRK_AUDIO_EDIROL_UA101, | ||
162 | 163 | ||
163 | QUIRK_TYPE_COUNT | 164 | QUIRK_TYPE_COUNT |
164 | }; | 165 | }; |
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index e74eb1bc8d87..7b3bf3545a3b 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -1526,7 +1526,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi | |||
1526 | namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); | 1526 | namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); |
1527 | if (! namelist[i]) { | 1527 | if (! namelist[i]) { |
1528 | snd_printk(KERN_ERR "cannot malloc\n"); | 1528 | snd_printk(KERN_ERR "cannot malloc\n"); |
1529 | while (--i > 0) | 1529 | while (i--) |
1530 | kfree(namelist[i]); | 1530 | kfree(namelist[i]); |
1531 | kfree(namelist); | 1531 | kfree(namelist); |
1532 | kfree(cval); | 1532 | kfree(cval); |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index a7e9563a01df..25b4ab4f61e7 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -1098,7 +1098,37 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1098 | } | 1098 | } |
1099 | } | 1099 | } |
1100 | }, | 1100 | }, |
1101 | /* TODO: add Edirol UA-101 support */ | 1101 | /* Roland UA-101 in High-Speed Mode only */ |
1102 | { | ||
1103 | USB_DEVICE(0x0582, 0x007d), | ||
1104 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1105 | .vendor_name = "Roland", | ||
1106 | .product_name = "UA-101", | ||
1107 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1108 | .type = QUIRK_COMPOSITE, | ||
1109 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1110 | { | ||
1111 | .ifnum = 0, | ||
1112 | .type = QUIRK_AUDIO_EDIROL_UA101 | ||
1113 | }, | ||
1114 | { | ||
1115 | .ifnum = 1, | ||
1116 | .type = QUIRK_AUDIO_EDIROL_UA101 | ||
1117 | }, | ||
1118 | { | ||
1119 | .ifnum = 2, | ||
1120 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1121 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1122 | .out_cables = 0x0001, | ||
1123 | .in_cables = 0x0001 | ||
1124 | } | ||
1125 | }, | ||
1126 | { | ||
1127 | .ifnum = -1 | ||
1128 | } | ||
1129 | } | ||
1130 | } | ||
1131 | }, | ||
1102 | { | 1132 | { |
1103 | /* has ID 0x0081 when not in "Advanced Driver" mode */ | 1133 | /* has ID 0x0081 when not in "Advanced Driver" mode */ |
1104 | USB_DEVICE(0x0582, 0x0080), | 1134 | USB_DEVICE(0x0582, 0x0080), |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 367f8a32a665..0a352e46862f 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -322,7 +322,7 @@ static void i_usX2Y_urb_complete(struct urb *urb) | |||
322 | usX2Y_error_urb_status(usX2Y, subs, urb); | 322 | usX2Y_error_urb_status(usX2Y, subs, urb); |
323 | return; | 323 | return; |
324 | } | 324 | } |
325 | if (likely(urb->start_frame == usX2Y->wait_iso_frame)) | 325 | if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) |
326 | subs->completed_urb = urb; | 326 | subs->completed_urb = urb; |
327 | else { | 327 | else { |
328 | usX2Y_error_sequence(usX2Y, subs, urb); | 328 | usX2Y_error_sequence(usX2Y, subs, urb); |
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 8f3e35e24e72..a5e7bcd7ca2e 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c | |||
@@ -243,7 +243,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) | |||
243 | usX2Y_error_urb_status(usX2Y, subs, urb); | 243 | usX2Y_error_urb_status(usX2Y, subs, urb); |
244 | return; | 244 | return; |
245 | } | 245 | } |
246 | if (likely(urb->start_frame == usX2Y->wait_iso_frame)) | 246 | if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF))) |
247 | subs->completed_urb = urb; | 247 | subs->completed_urb = urb; |
248 | else { | 248 | else { |
249 | usX2Y_error_sequence(usX2Y, subs, urb); | 249 | usX2Y_error_sequence(usX2Y, subs, urb); |