diff options
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 79 |
1 files changed, 33 insertions, 46 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8f3cdb37a0ec..c2db0f959681 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -107,7 +107,7 @@ MODULE_PARM_DESC(ignore_ctl_error, | |||
107 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ | 107 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ |
108 | #define MAX_URBS 8 | 108 | #define MAX_URBS 8 |
109 | #define SYNC_URBS 4 /* always four urbs for sync */ | 109 | #define SYNC_URBS 4 /* always four urbs for sync */ |
110 | #define MIN_PACKS_URB 1 /* minimum 1 packet per urb */ | 110 | #define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */ |
111 | 111 | ||
112 | struct audioformat { | 112 | struct audioformat { |
113 | struct list_head list; | 113 | struct list_head list; |
@@ -525,7 +525,7 @@ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) | |||
525 | /* | 525 | /* |
526 | * Prepare urb for streaming before playback starts or when paused. | 526 | * Prepare urb for streaming before playback starts or when paused. |
527 | * | 527 | * |
528 | * We don't have any data, so we send a frame of silence. | 528 | * We don't have any data, so we send silence. |
529 | */ | 529 | */ |
530 | static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, | 530 | static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, |
531 | struct snd_pcm_runtime *runtime, | 531 | struct snd_pcm_runtime *runtime, |
@@ -537,13 +537,13 @@ static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, | |||
537 | 537 | ||
538 | offs = 0; | 538 | offs = 0; |
539 | urb->dev = ctx->subs->dev; | 539 | urb->dev = ctx->subs->dev; |
540 | urb->number_of_packets = subs->packs_per_ms; | 540 | for (i = 0; i < ctx->packets; ++i) { |
541 | for (i = 0; i < subs->packs_per_ms; ++i) { | ||
542 | counts = snd_usb_audio_next_packet_size(subs); | 541 | counts = snd_usb_audio_next_packet_size(subs); |
543 | urb->iso_frame_desc[i].offset = offs * stride; | 542 | urb->iso_frame_desc[i].offset = offs * stride; |
544 | urb->iso_frame_desc[i].length = counts * stride; | 543 | urb->iso_frame_desc[i].length = counts * stride; |
545 | offs += counts; | 544 | offs += counts; |
546 | } | 545 | } |
546 | urb->number_of_packets = ctx->packets; | ||
547 | urb->transfer_buffer_length = offs * stride; | 547 | urb->transfer_buffer_length = offs * stride; |
548 | memset(urb->transfer_buffer, | 548 | memset(urb->transfer_buffer, |
549 | subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, | 549 | subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, |
@@ -1034,9 +1034,9 @@ static void release_substream_urbs(struct snd_usb_substream *subs, int force) | |||
1034 | static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes, | 1034 | static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes, |
1035 | unsigned int rate, unsigned int frame_bits) | 1035 | unsigned int rate, unsigned int frame_bits) |
1036 | { | 1036 | { |
1037 | unsigned int maxsize, n, i; | 1037 | unsigned int maxsize, i; |
1038 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; | 1038 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; |
1039 | unsigned int npacks[MAX_URBS], urb_packs, total_packs, packs_per_ms; | 1039 | unsigned int urb_packs, total_packs, packs_per_ms; |
1040 | 1040 | ||
1041 | /* calculate the frequency in 16.16 format */ | 1041 | /* calculate the frequency in 16.16 format */ |
1042 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | 1042 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
@@ -1070,8 +1070,7 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1070 | subs->packs_per_ms = packs_per_ms; | 1070 | subs->packs_per_ms = packs_per_ms; |
1071 | 1071 | ||
1072 | if (is_playback) { | 1072 | if (is_playback) { |
1073 | urb_packs = nrpacks; | 1073 | urb_packs = max(nrpacks, 1); |
1074 | urb_packs = max(urb_packs, (unsigned int)MIN_PACKS_URB); | ||
1075 | urb_packs = min(urb_packs, (unsigned int)MAX_PACKS); | 1074 | urb_packs = min(urb_packs, (unsigned int)MAX_PACKS); |
1076 | } else | 1075 | } else |
1077 | urb_packs = 1; | 1076 | urb_packs = 1; |
@@ -1079,7 +1078,7 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1079 | 1078 | ||
1080 | /* decide how many packets to be used */ | 1079 | /* decide how many packets to be used */ |
1081 | if (is_playback) { | 1080 | if (is_playback) { |
1082 | unsigned int minsize; | 1081 | unsigned int minsize, maxpacks; |
1083 | /* determine how small a packet can be */ | 1082 | /* determine how small a packet can be */ |
1084 | minsize = (subs->freqn >> (16 - subs->datainterval)) | 1083 | minsize = (subs->freqn >> (16 - subs->datainterval)) |
1085 | * (frame_bits >> 3); | 1084 | * (frame_bits >> 3); |
@@ -1092,8 +1091,13 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1092 | total_packs = (total_packs + packs_per_ms - 1) | 1091 | total_packs = (total_packs + packs_per_ms - 1) |
1093 | & ~(packs_per_ms - 1); | 1092 | & ~(packs_per_ms - 1); |
1094 | /* we need at least two URBs for queueing */ | 1093 | /* we need at least two URBs for queueing */ |
1095 | if (total_packs < 2 * MIN_PACKS_URB * packs_per_ms) | 1094 | if (total_packs < 2 * packs_per_ms) { |
1096 | total_packs = 2 * MIN_PACKS_URB * packs_per_ms; | 1095 | total_packs = 2 * packs_per_ms; |
1096 | } else { | ||
1097 | /* and we don't want too long a queue either */ | ||
1098 | maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); | ||
1099 | total_packs = min(total_packs, maxpacks); | ||
1100 | } | ||
1097 | } else { | 1101 | } else { |
1098 | total_packs = MAX_URBS * urb_packs; | 1102 | total_packs = MAX_URBS * urb_packs; |
1099 | } | 1103 | } |
@@ -1102,31 +1106,11 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1102 | /* too much... */ | 1106 | /* too much... */ |
1103 | subs->nurbs = MAX_URBS; | 1107 | subs->nurbs = MAX_URBS; |
1104 | total_packs = MAX_URBS * urb_packs; | 1108 | total_packs = MAX_URBS * urb_packs; |
1105 | } | 1109 | } else if (subs->nurbs < 2) { |
1106 | n = total_packs; | ||
1107 | for (i = 0; i < subs->nurbs; i++) { | ||
1108 | npacks[i] = n > urb_packs ? urb_packs : n; | ||
1109 | n -= urb_packs; | ||
1110 | } | ||
1111 | if (subs->nurbs <= 1) { | ||
1112 | /* too little - we need at least two packets | 1110 | /* too little - we need at least two packets |
1113 | * to ensure contiguous playback/capture | 1111 | * to ensure contiguous playback/capture |
1114 | */ | 1112 | */ |
1115 | subs->nurbs = 2; | 1113 | subs->nurbs = 2; |
1116 | npacks[0] = (total_packs + 1) / 2; | ||
1117 | npacks[1] = total_packs - npacks[0]; | ||
1118 | } else if (npacks[subs->nurbs-1] < MIN_PACKS_URB * packs_per_ms) { | ||
1119 | /* the last packet is too small.. */ | ||
1120 | if (subs->nurbs > 2) { | ||
1121 | /* merge to the first one */ | ||
1122 | npacks[0] += npacks[subs->nurbs - 1]; | ||
1123 | subs->nurbs--; | ||
1124 | } else { | ||
1125 | /* divide to two */ | ||
1126 | subs->nurbs = 2; | ||
1127 | npacks[0] = (total_packs + 1) / 2; | ||
1128 | npacks[1] = total_packs - npacks[0]; | ||
1129 | } | ||
1130 | } | 1114 | } |
1131 | 1115 | ||
1132 | /* allocate and initialize data urbs */ | 1116 | /* allocate and initialize data urbs */ |
@@ -1134,7 +1118,8 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1134 | struct snd_urb_ctx *u = &subs->dataurb[i]; | 1118 | struct snd_urb_ctx *u = &subs->dataurb[i]; |
1135 | u->index = i; | 1119 | u->index = i; |
1136 | u->subs = subs; | 1120 | u->subs = subs; |
1137 | u->packets = npacks[i]; | 1121 | u->packets = (i + 1) * total_packs / subs->nurbs |
1122 | - i * total_packs / subs->nurbs; | ||
1138 | u->buffer_size = maxsize * u->packets; | 1123 | u->buffer_size = maxsize * u->packets; |
1139 | if (subs->fmt_type == USB_FORMAT_TYPE_II) | 1124 | if (subs->fmt_type == USB_FORMAT_TYPE_II) |
1140 | u->packets++; /* for transfer delimiter */ | 1125 | u->packets++; /* for transfer delimiter */ |
@@ -1292,14 +1277,14 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface, | |||
1292 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, | 1277 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, |
1293 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | 1278 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, |
1294 | SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { | 1279 | SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { |
1295 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n", | 1280 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", |
1296 | dev->devnum, iface, fmt->altsetting, rate, ep); | 1281 | dev->devnum, iface, fmt->altsetting, rate, ep); |
1297 | return err; | 1282 | return err; |
1298 | } | 1283 | } |
1299 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, | 1284 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, |
1300 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, | 1285 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, |
1301 | SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { | 1286 | SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { |
1302 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep 0x%x\n", | 1287 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", |
1303 | dev->devnum, iface, fmt->altsetting, ep); | 1288 | dev->devnum, iface, fmt->altsetting, ep); |
1304 | return 0; /* some devices don't support reading */ | 1289 | return 0; /* some devices don't support reading */ |
1305 | } | 1290 | } |
@@ -1431,9 +1416,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
1431 | subs->cur_audiofmt = fmt; | 1416 | subs->cur_audiofmt = fmt; |
1432 | 1417 | ||
1433 | #if 0 | 1418 | #if 0 |
1434 | printk("setting done: format = %d, rate = %d..%d, channels = %d\n", | 1419 | printk(KERN_DEBUG |
1420 | "setting done: format = %d, rate = %d..%d, channels = %d\n", | ||
1435 | fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels); | 1421 | fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels); |
1436 | printk(" datapipe = 0x%0x, syncpipe = 0x%0x\n", | 1422 | printk(KERN_DEBUG |
1423 | " datapipe = 0x%0x, syncpipe = 0x%0x\n", | ||
1437 | subs->datapipe, subs->syncpipe); | 1424 | subs->datapipe, subs->syncpipe); |
1438 | #endif | 1425 | #endif |
1439 | 1426 | ||
@@ -1468,7 +1455,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
1468 | channels = params_channels(hw_params); | 1455 | channels = params_channels(hw_params); |
1469 | fmt = find_format(subs, format, rate, channels); | 1456 | fmt = find_format(subs, format, rate, channels); |
1470 | if (!fmt) { | 1457 | if (!fmt) { |
1471 | snd_printd(KERN_DEBUG "cannot set format: format = 0x%x, rate = %d, channels = %d\n", | 1458 | snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n", |
1472 | format, rate, channels); | 1459 | format, rate, channels); |
1473 | return -EINVAL; | 1460 | return -EINVAL; |
1474 | } | 1461 | } |
@@ -1795,7 +1782,7 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) | |||
1795 | if (rates[f->format] && rates[f->format] != f->rates) | 1782 | if (rates[f->format] && rates[f->format] != f->rates) |
1796 | goto __out; | 1783 | goto __out; |
1797 | } | 1784 | } |
1798 | channels[f->format] |= (1 << f->channels); | 1785 | channels[f->format] |= 1 << (f->channels - 1); |
1799 | rates[f->format] |= f->rates; | 1786 | rates[f->format] |= f->rates; |
1800 | /* needs knot? */ | 1787 | /* needs knot? */ |
1801 | if (f->rates & SNDRV_PCM_RATE_KNOT) | 1788 | if (f->rates & SNDRV_PCM_RATE_KNOT) |
@@ -1822,7 +1809,7 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) | |||
1822 | continue; | 1809 | continue; |
1823 | for (i = 0; i < 32; i++) { | 1810 | for (i = 0; i < 32; i++) { |
1824 | if (f->rates & (1 << i)) | 1811 | if (f->rates & (1 << i)) |
1825 | channels[i] |= (1 << f->channels); | 1812 | channels[i] |= 1 << (f->channels - 1); |
1826 | } | 1813 | } |
1827 | } | 1814 | } |
1828 | cmaster = 0; | 1815 | cmaster = 0; |
@@ -1919,7 +1906,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1919 | * in the current code assume the 1ms period. | 1906 | * in the current code assume the 1ms period. |
1920 | */ | 1907 | */ |
1921 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, | 1908 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, |
1922 | 1000 * MIN_PACKS_URB, | 1909 | 1000, |
1923 | /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); | 1910 | /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); |
1924 | 1911 | ||
1925 | err = check_hw_params_convention(subs); | 1912 | err = check_hw_params_convention(subs); |
@@ -2160,7 +2147,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
2160 | fp = list_entry(p, struct audioformat, list); | 2147 | fp = list_entry(p, struct audioformat, list); |
2161 | snd_iprintf(buffer, " Interface %d\n", fp->iface); | 2148 | snd_iprintf(buffer, " Interface %d\n", fp->iface); |
2162 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); | 2149 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); |
2163 | snd_iprintf(buffer, " Format: 0x%x\n", fp->format); | 2150 | snd_iprintf(buffer, " Format: %#x\n", fp->format); |
2164 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); | 2151 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); |
2165 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", | 2152 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", |
2166 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, | 2153 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, |
@@ -2180,7 +2167,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
2180 | snd_iprintf(buffer, "\n"); | 2167 | snd_iprintf(buffer, "\n"); |
2181 | } | 2168 | } |
2182 | // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); | 2169 | // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); |
2183 | // snd_iprintf(buffer, " EP Attribute = 0x%x\n", fp->attributes); | 2170 | // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes); |
2184 | } | 2171 | } |
2185 | } | 2172 | } |
2186 | 2173 | ||
@@ -2621,7 +2608,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat | |||
2621 | fp->format = SNDRV_PCM_FORMAT_MPEG; | 2608 | fp->format = SNDRV_PCM_FORMAT_MPEG; |
2622 | break; | 2609 | break; |
2623 | default: | 2610 | default: |
2624 | snd_printd(KERN_INFO "%d:%u:%d : unknown format tag 0x%x is detected. processed as MPEG.\n", | 2611 | snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n", |
2625 | chip->dev->devnum, fp->iface, fp->altsetting, format); | 2612 | chip->dev->devnum, fp->iface, fp->altsetting, format); |
2626 | fp->format = SNDRV_PCM_FORMAT_MPEG; | 2613 | fp->format = SNDRV_PCM_FORMAT_MPEG; |
2627 | break; | 2614 | break; |
@@ -2819,7 +2806,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2819 | continue; | 2806 | continue; |
2820 | } | 2807 | } |
2821 | 2808 | ||
2822 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint); | 2809 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); |
2823 | err = add_audio_endpoint(chip, stream, fp); | 2810 | err = add_audio_endpoint(chip, stream, fp); |
2824 | if (err < 0) { | 2811 | if (err < 0) { |
2825 | kfree(fp->rate_table); | 2812 | kfree(fp->rate_table); |
@@ -3766,7 +3753,7 @@ static int usb_audio_resume(struct usb_interface *intf) | |||
3766 | 3753 | ||
3767 | static int __init snd_usb_audio_init(void) | 3754 | static int __init snd_usb_audio_init(void) |
3768 | { | 3755 | { |
3769 | if (nrpacks < MIN_PACKS_URB || nrpacks > MAX_PACKS) { | 3756 | if (nrpacks < 1 || nrpacks > MAX_PACKS) { |
3770 | printk(KERN_WARNING "invalid nrpacks value.\n"); | 3757 | printk(KERN_WARNING "invalid nrpacks value.\n"); |
3771 | return -EINVAL; | 3758 | return -EINVAL; |
3772 | } | 3759 | } |