aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r--sound/usb/usbaudio.c46
1 files changed, 20 insertions, 26 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index ac5666f4c6d5..967b823eace0 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -123,7 +123,6 @@ struct audioformat {
123 unsigned int rate_min, rate_max; /* min/max rates */ 123 unsigned int rate_min, rate_max; /* min/max rates */
124 unsigned int nr_rates; /* number of rate table entries */ 124 unsigned int nr_rates; /* number of rate table entries */
125 unsigned int *rate_table; /* rate table */ 125 unsigned int *rate_table; /* rate table */
126 unsigned int needs_knot; /* any unusual rates? */
127}; 126};
128 127
129struct snd_usb_substream; 128struct snd_usb_substream;
@@ -1309,7 +1308,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1309 1308
1310 /* close the old interface */ 1309 /* close the old interface */
1311 if (subs->interface >= 0 && subs->interface != fmt->iface) { 1310 if (subs->interface >= 0 && subs->interface != fmt->iface) {
1312 usb_set_interface(subs->dev, subs->interface, 0); 1311 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
1312 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
1313 dev->devnum, fmt->iface, fmt->altsetting);
1314 return -EIO;
1315 }
1313 subs->interface = -1; 1316 subs->interface = -1;
1314 subs->format = 0; 1317 subs->format = 0;
1315 } 1318 }
@@ -1761,7 +1764,7 @@ static int check_hw_params_convention(struct snd_usb_substream *subs)
1761 channels[f->format] |= (1 << f->channels); 1764 channels[f->format] |= (1 << f->channels);
1762 rates[f->format] |= f->rates; 1765 rates[f->format] |= f->rates;
1763 /* needs knot? */ 1766 /* needs knot? */
1764 if (f->needs_knot) 1767 if (f->rates & SNDRV_PCM_RATE_KNOT)
1765 goto __out; 1768 goto __out;
1766 } 1769 }
1767 /* check whether channels and rates match for all formats */ 1770 /* check whether channels and rates match for all formats */
@@ -1817,7 +1820,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1817 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) 1820 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
1818 return 0; 1821 return 0;
1819 count += fp->nr_rates; 1822 count += fp->nr_rates;
1820 if (fp->needs_knot) 1823 if (fp->rates & SNDRV_PCM_RATE_KNOT)
1821 needs_knot = 1; 1824 needs_knot = 1;
1822 } 1825 }
1823 if (!needs_knot) 1826 if (!needs_knot)
@@ -2453,7 +2456,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2453 unsigned char *fmt, int offset) 2456 unsigned char *fmt, int offset)
2454{ 2457{
2455 int nr_rates = fmt[offset]; 2458 int nr_rates = fmt[offset];
2456 int found; 2459
2457 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { 2460 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2458 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2461 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
2459 chip->dev->devnum, fp->iface, fp->altsetting); 2462 chip->dev->devnum, fp->iface, fp->altsetting);
@@ -2464,20 +2467,15 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2464 /* 2467 /*
2465 * build the rate table and bitmap flags 2468 * build the rate table and bitmap flags
2466 */ 2469 */
2467 int r, idx, c; 2470 int r, idx;
2468 unsigned int nonzero_rates = 0; 2471 unsigned int nonzero_rates = 0;
2469 /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */ 2472
2470 static unsigned int conv_rates[] = {
2471 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
2472 64000, 88200, 96000, 176400, 192000
2473 };
2474 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); 2473 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2475 if (fp->rate_table == NULL) { 2474 if (fp->rate_table == NULL) {
2476 snd_printk(KERN_ERR "cannot malloc\n"); 2475 snd_printk(KERN_ERR "cannot malloc\n");
2477 return -1; 2476 return -1;
2478 } 2477 }
2479 2478
2480 fp->needs_knot = 0;
2481 fp->nr_rates = nr_rates; 2479 fp->nr_rates = nr_rates;
2482 fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); 2480 fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
2483 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { 2481 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
@@ -2493,23 +2491,12 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2493 fp->rate_min = rate; 2491 fp->rate_min = rate;
2494 else if (rate > fp->rate_max) 2492 else if (rate > fp->rate_max)
2495 fp->rate_max = rate; 2493 fp->rate_max = rate;
2496 found = 0; 2494 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2497 for (c = 0; c < (int)ARRAY_SIZE(conv_rates); c++) {
2498 if (rate == conv_rates[c]) {
2499 found = 1;
2500 fp->rates |= (1 << c);
2501 break;
2502 }
2503 }
2504 if (!found)
2505 fp->needs_knot = 1;
2506 } 2495 }
2507 if (!nonzero_rates) { 2496 if (!nonzero_rates) {
2508 hwc_debug("All rates were zero. Skipping format!\n"); 2497 hwc_debug("All rates were zero. Skipping format!\n");
2509 return -1; 2498 return -1;
2510 } 2499 }
2511 if (fp->needs_knot)
2512 fp->rates |= SNDRV_PCM_RATE_KNOT;
2513 } else { 2500 } else {
2514 /* continuous rates */ 2501 /* continuous rates */
2515 fp->rates = SNDRV_PCM_RATE_CONTINUOUS; 2502 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
@@ -2857,6 +2844,10 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
2857 /* skip non-supported classes */ 2844 /* skip non-supported classes */
2858 continue; 2845 continue;
2859 } 2846 }
2847 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
2848 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
2849 continue;
2850 }
2860 if (! parse_audio_endpoints(chip, j)) { 2851 if (! parse_audio_endpoints(chip, j)) {
2861 usb_set_interface(dev, j, 0); /* reset the current interface */ 2852 usb_set_interface(dev, j, 0); /* reset the current interface */
2862 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); 2853 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
@@ -3399,7 +3390,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
3399 3390
3400 *rchip = NULL; 3391 *rchip = NULL;
3401 3392
3402 if (snd_usb_get_speed(dev) != USB_SPEED_FULL && 3393 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
3394 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
3403 snd_usb_get_speed(dev) != USB_SPEED_HIGH) { 3395 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
3404 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev)); 3396 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
3405 return -ENXIO; 3397 return -ENXIO;
@@ -3473,7 +3465,9 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
3473 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); 3465 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
3474 3466
3475 strlcat(card->longname, 3467 strlcat(card->longname,
3476 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" : ", high speed", 3468 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
3469 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
3470 ", high speed",
3477 sizeof(card->longname)); 3471 sizeof(card->longname));
3478 3472
3479 snd_usb_audio_create_proc(chip); 3473 snd_usb_audio_create_proc(chip);