diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/caiaq/audio.c | 103 | ||||
-rw-r--r-- | sound/usb/caiaq/device.c | 109 | ||||
-rw-r--r-- | sound/usb/caiaq/device.h | 1 | ||||
-rw-r--r-- | sound/usb/caiaq/midi.c | 24 | ||||
-rw-r--r-- | sound/usb/usbaudio.c | 41 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 2 | ||||
-rw-r--r-- | sound/usb/usbmidi.c | 12 | ||||
-rw-r--r-- | sound/usb/usbquirks.h | 45 | ||||
-rw-r--r-- | sound/usb/usx2y/us122l.c | 12 | ||||
-rw-r--r-- | sound/usb/usx2y/usb_stream.c | 67 | ||||
-rw-r--r-- | sound/usb/usx2y/usbusx2yaudio.c | 3 |
11 files changed, 259 insertions, 160 deletions
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 3f45c0fe61ab..8f9b60c5d74c 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -42,10 +42,10 @@ | |||
42 | (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) | 42 | (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) |
43 | 43 | ||
44 | static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { | 44 | static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { |
45 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 45 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
46 | SNDRV_PCM_INFO_BLOCK_TRANSFER), | 46 | SNDRV_PCM_INFO_BLOCK_TRANSFER), |
47 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | 47 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, |
48 | .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | 48 | .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | |
49 | SNDRV_PCM_RATE_96000), | 49 | SNDRV_PCM_RATE_96000), |
50 | .rate_min = 44100, | 50 | .rate_min = 44100, |
51 | .rate_max = 0, /* will overwrite later */ | 51 | .rate_max = 0, /* will overwrite later */ |
@@ -68,7 +68,7 @@ activate_substream(struct snd_usb_caiaqdev *dev, | |||
68 | dev->sub_capture[sub->number] = sub; | 68 | dev->sub_capture[sub->number] = sub; |
69 | } | 69 | } |
70 | 70 | ||
71 | static void | 71 | static void |
72 | deactivate_substream(struct snd_usb_caiaqdev *dev, | 72 | deactivate_substream(struct snd_usb_caiaqdev *dev, |
73 | struct snd_pcm_substream *sub) | 73 | struct snd_pcm_substream *sub) |
74 | { | 74 | { |
@@ -118,7 +118,7 @@ static int stream_start(struct snd_usb_caiaqdev *dev) | |||
118 | return -EPIPE; | 118 | return -EPIPE; |
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
@@ -129,7 +129,7 @@ static void stream_stop(struct snd_usb_caiaqdev *dev) | |||
129 | debug("%s(%p)\n", __func__, dev); | 129 | debug("%s(%p)\n", __func__, dev); |
130 | if (!dev->streaming) | 130 | if (!dev->streaming) |
131 | return; | 131 | return; |
132 | 132 | ||
133 | dev->streaming = 0; | 133 | dev->streaming = 0; |
134 | 134 | ||
135 | for (i = 0; i < N_URBS; i++) { | 135 | for (i = 0; i < N_URBS; i++) { |
@@ -154,7 +154,7 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) | |||
154 | debug("%s(%p)\n", __func__, substream); | 154 | debug("%s(%p)\n", __func__, substream); |
155 | if (all_substreams_zero(dev->sub_playback) && | 155 | if (all_substreams_zero(dev->sub_playback) && |
156 | all_substreams_zero(dev->sub_capture)) { | 156 | all_substreams_zero(dev->sub_capture)) { |
157 | /* when the last client has stopped streaming, | 157 | /* when the last client has stopped streaming, |
158 | * all sample rates are allowed again */ | 158 | * all sample rates are allowed again */ |
159 | stream_stop(dev); | 159 | stream_stop(dev); |
160 | dev->pcm_info.rates = dev->samplerates; | 160 | dev->pcm_info.rates = dev->samplerates; |
@@ -194,27 +194,31 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
194 | struct snd_pcm_runtime *runtime = substream->runtime; | 194 | struct snd_pcm_runtime *runtime = substream->runtime; |
195 | 195 | ||
196 | debug("%s(%p)\n", __func__, substream); | 196 | debug("%s(%p)\n", __func__, substream); |
197 | 197 | ||
198 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 198 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
199 | dev->period_out_count[index] = BYTES_PER_SAMPLE + 1; | ||
199 | dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; | 200 | dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; |
200 | else | 201 | } else { |
201 | dev->audio_in_buf_pos[index] = BYTES_PER_SAMPLE; | 202 | int in_pos = (dev->spec.data_alignment == 2) ? 0 : 2; |
202 | 203 | dev->period_in_count[index] = BYTES_PER_SAMPLE + in_pos; | |
204 | dev->audio_in_buf_pos[index] = BYTES_PER_SAMPLE + in_pos; | ||
205 | } | ||
206 | |||
203 | if (dev->streaming) | 207 | if (dev->streaming) |
204 | return 0; | 208 | return 0; |
205 | 209 | ||
206 | /* the first client that opens a stream defines the sample rate | 210 | /* the first client that opens a stream defines the sample rate |
207 | * setting for all subsequent calls, until the last client closed. */ | 211 | * setting for all subsequent calls, until the last client closed. */ |
208 | for (i=0; i < ARRAY_SIZE(rates); i++) | 212 | for (i=0; i < ARRAY_SIZE(rates); i++) |
209 | if (runtime->rate == rates[i]) | 213 | if (runtime->rate == rates[i]) |
210 | dev->pcm_info.rates = 1 << i; | 214 | dev->pcm_info.rates = 1 << i; |
211 | 215 | ||
212 | snd_pcm_limit_hw_rates(runtime); | 216 | snd_pcm_limit_hw_rates(runtime); |
213 | 217 | ||
214 | bytes_per_sample = BYTES_PER_SAMPLE; | 218 | bytes_per_sample = BYTES_PER_SAMPLE; |
215 | if (dev->spec.data_alignment == 2) | 219 | if (dev->spec.data_alignment == 2) |
216 | bytes_per_sample++; | 220 | bytes_per_sample++; |
217 | 221 | ||
218 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) | 222 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) |
219 | * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; | 223 | * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; |
220 | 224 | ||
@@ -229,7 +233,7 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
229 | ret = stream_start(dev); | 233 | ret = stream_start(dev); |
230 | if (ret) | 234 | if (ret) |
231 | return ret; | 235 | return ret; |
232 | 236 | ||
233 | dev->output_running = 0; | 237 | dev->output_running = 0; |
234 | wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); | 238 | wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); |
235 | if (!dev->output_running) { | 239 | if (!dev->output_running) { |
@@ -270,7 +274,7 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | |||
270 | return SNDRV_PCM_POS_XRUN; | 274 | return SNDRV_PCM_POS_XRUN; |
271 | 275 | ||
272 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 276 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
273 | return bytes_to_frames(sub->runtime, | 277 | return bytes_to_frames(sub->runtime, |
274 | dev->audio_out_buf_pos[index]); | 278 | dev->audio_out_buf_pos[index]); |
275 | else | 279 | else |
276 | return bytes_to_frames(sub->runtime, | 280 | return bytes_to_frames(sub->runtime, |
@@ -288,7 +292,7 @@ static struct snd_pcm_ops snd_usb_caiaq_ops = { | |||
288 | .trigger = snd_usb_caiaq_pcm_trigger, | 292 | .trigger = snd_usb_caiaq_pcm_trigger, |
289 | .pointer = snd_usb_caiaq_pcm_pointer | 293 | .pointer = snd_usb_caiaq_pcm_pointer |
290 | }; | 294 | }; |
291 | 295 | ||
292 | static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, | 296 | static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, |
293 | struct snd_pcm_substream **subs) | 297 | struct snd_pcm_substream **subs) |
294 | { | 298 | { |
@@ -300,8 +304,7 @@ static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, | |||
300 | if (!sub) | 304 | if (!sub) |
301 | continue; | 305 | continue; |
302 | 306 | ||
303 | pb = frames_to_bytes(sub->runtime, | 307 | pb = snd_pcm_lib_period_bytes(sub); |
304 | sub->runtime->period_size); | ||
305 | cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | 308 | cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
306 | &dev->period_out_count[stream] : | 309 | &dev->period_out_count[stream] : |
307 | &dev->period_in_count[stream]; | 310 | &dev->period_in_count[stream]; |
@@ -331,7 +334,7 @@ static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, | |||
331 | struct snd_pcm_runtime *rt = sub->runtime; | 334 | struct snd_pcm_runtime *rt = sub->runtime; |
332 | char *audio_buf = rt->dma_area; | 335 | char *audio_buf = rt->dma_area; |
333 | int sz = frames_to_bytes(rt, rt->buffer_size); | 336 | int sz = frames_to_bytes(rt, rt->buffer_size); |
334 | audio_buf[dev->audio_in_buf_pos[stream]++] | 337 | audio_buf[dev->audio_in_buf_pos[stream]++] |
335 | = usb_buf[i]; | 338 | = usb_buf[i]; |
336 | dev->period_in_count[stream]++; | 339 | dev->period_in_count[stream]++; |
337 | if (dev->audio_in_buf_pos[stream] == sz) | 340 | if (dev->audio_in_buf_pos[stream] == sz) |
@@ -352,14 +355,14 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, | |||
352 | 355 | ||
353 | for (i = 0; i < iso->actual_length;) { | 356 | for (i = 0; i < iso->actual_length;) { |
354 | if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { | 357 | if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { |
355 | for (stream = 0; | 358 | for (stream = 0; |
356 | stream < dev->n_streams; | 359 | stream < dev->n_streams; |
357 | stream++, i++) { | 360 | stream++, i++) { |
358 | if (dev->first_packet) | 361 | if (dev->first_packet) |
359 | continue; | 362 | continue; |
360 | 363 | ||
361 | check_byte = MAKE_CHECKBYTE(dev, stream, i); | 364 | check_byte = MAKE_CHECKBYTE(dev, stream, i); |
362 | 365 | ||
363 | if ((usb_buf[i] & 0x3f) != check_byte) | 366 | if ((usb_buf[i] & 0x3f) != check_byte) |
364 | dev->input_panic = 1; | 367 | dev->input_panic = 1; |
365 | 368 | ||
@@ -408,21 +411,21 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev, | |||
408 | } | 411 | } |
409 | 412 | ||
410 | if ((dev->input_panic || dev->output_panic) && !dev->warned) { | 413 | if ((dev->input_panic || dev->output_panic) && !dev->warned) { |
411 | debug("streaming error detected %s %s\n", | 414 | debug("streaming error detected %s %s\n", |
412 | dev->input_panic ? "(input)" : "", | 415 | dev->input_panic ? "(input)" : "", |
413 | dev->output_panic ? "(output)" : ""); | 416 | dev->output_panic ? "(output)" : ""); |
414 | dev->warned = 1; | 417 | dev->warned = 1; |
415 | } | 418 | } |
416 | } | 419 | } |
417 | 420 | ||
418 | static void fill_out_urb(struct snd_usb_caiaqdev *dev, | 421 | static void fill_out_urb(struct snd_usb_caiaqdev *dev, |
419 | struct urb *urb, | 422 | struct urb *urb, |
420 | const struct usb_iso_packet_descriptor *iso) | 423 | const struct usb_iso_packet_descriptor *iso) |
421 | { | 424 | { |
422 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | 425 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
423 | struct snd_pcm_substream *sub; | 426 | struct snd_pcm_substream *sub; |
424 | int stream, i; | 427 | int stream, i; |
425 | 428 | ||
426 | for (i = 0; i < iso->length;) { | 429 | for (i = 0; i < iso->length;) { |
427 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | 430 | for (stream = 0; stream < dev->n_streams; stream++, i++) { |
428 | sub = dev->sub_playback[stream]; | 431 | sub = dev->sub_playback[stream]; |
@@ -442,7 +445,7 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev, | |||
442 | 445 | ||
443 | /* fill in the check bytes */ | 446 | /* fill in the check bytes */ |
444 | if (dev->spec.data_alignment == 2 && | 447 | if (dev->spec.data_alignment == 2 && |
445 | i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == | 448 | i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == |
446 | (dev->n_streams * CHANNELS_PER_STREAM)) | 449 | (dev->n_streams * CHANNELS_PER_STREAM)) |
447 | for (stream = 0; stream < dev->n_streams; stream++, i++) | 450 | for (stream = 0; stream < dev->n_streams; stream++, i++) |
448 | usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); | 451 | usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); |
@@ -451,7 +454,7 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev, | |||
451 | 454 | ||
452 | static void read_completed(struct urb *urb) | 455 | static void read_completed(struct urb *urb) |
453 | { | 456 | { |
454 | struct snd_usb_caiaq_cb_info *info = urb->context; | 457 | struct snd_usb_caiaq_cb_info *info = urb->context; |
455 | struct snd_usb_caiaqdev *dev; | 458 | struct snd_usb_caiaqdev *dev; |
456 | struct urb *out; | 459 | struct urb *out; |
457 | int frame, len, send_it = 0, outframe = 0; | 460 | int frame, len, send_it = 0, outframe = 0; |
@@ -476,7 +479,7 @@ static void read_completed(struct urb *urb) | |||
476 | out->iso_frame_desc[outframe].length = len; | 479 | out->iso_frame_desc[outframe].length = len; |
477 | out->iso_frame_desc[outframe].actual_length = 0; | 480 | out->iso_frame_desc[outframe].actual_length = 0; |
478 | out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; | 481 | out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; |
479 | 482 | ||
480 | if (len > 0) { | 483 | if (len > 0) { |
481 | spin_lock(&dev->spinlock); | 484 | spin_lock(&dev->spinlock); |
482 | fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); | 485 | fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); |
@@ -495,14 +498,14 @@ static void read_completed(struct urb *urb) | |||
495 | out->transfer_flags = URB_ISO_ASAP; | 498 | out->transfer_flags = URB_ISO_ASAP; |
496 | usb_submit_urb(out, GFP_ATOMIC); | 499 | usb_submit_urb(out, GFP_ATOMIC); |
497 | } | 500 | } |
498 | 501 | ||
499 | /* re-submit inbound urb */ | 502 | /* re-submit inbound urb */ |
500 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { | 503 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
501 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; | 504 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; |
502 | urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; | 505 | urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; |
503 | urb->iso_frame_desc[frame].actual_length = 0; | 506 | urb->iso_frame_desc[frame].actual_length = 0; |
504 | } | 507 | } |
505 | 508 | ||
506 | urb->number_of_packets = FRAMES_PER_URB; | 509 | urb->number_of_packets = FRAMES_PER_URB; |
507 | urb->transfer_flags = URB_ISO_ASAP; | 510 | urb->transfer_flags = URB_ISO_ASAP; |
508 | usb_submit_urb(urb, GFP_ATOMIC); | 511 | usb_submit_urb(urb, GFP_ATOMIC); |
@@ -526,7 +529,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | |||
526 | struct usb_device *usb_dev = dev->chip.dev; | 529 | struct usb_device *usb_dev = dev->chip.dev; |
527 | unsigned int pipe; | 530 | unsigned int pipe; |
528 | 531 | ||
529 | pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? | 532 | pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? |
530 | usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : | 533 | usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : |
531 | usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); | 534 | usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); |
532 | 535 | ||
@@ -545,25 +548,25 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | |||
545 | return urbs; | 548 | return urbs; |
546 | } | 549 | } |
547 | 550 | ||
548 | urbs[i]->transfer_buffer = | 551 | urbs[i]->transfer_buffer = |
549 | kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); | 552 | kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); |
550 | if (!urbs[i]->transfer_buffer) { | 553 | if (!urbs[i]->transfer_buffer) { |
551 | log("unable to kmalloc() transfer buffer, OOM!?\n"); | 554 | log("unable to kmalloc() transfer buffer, OOM!?\n"); |
552 | *ret = -ENOMEM; | 555 | *ret = -ENOMEM; |
553 | return urbs; | 556 | return urbs; |
554 | } | 557 | } |
555 | 558 | ||
556 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { | 559 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
557 | struct usb_iso_packet_descriptor *iso = | 560 | struct usb_iso_packet_descriptor *iso = |
558 | &urbs[i]->iso_frame_desc[frame]; | 561 | &urbs[i]->iso_frame_desc[frame]; |
559 | 562 | ||
560 | iso->offset = BYTES_PER_FRAME * frame; | 563 | iso->offset = BYTES_PER_FRAME * frame; |
561 | iso->length = BYTES_PER_FRAME; | 564 | iso->length = BYTES_PER_FRAME; |
562 | } | 565 | } |
563 | 566 | ||
564 | urbs[i]->dev = usb_dev; | 567 | urbs[i]->dev = usb_dev; |
565 | urbs[i]->pipe = pipe; | 568 | urbs[i]->pipe = pipe; |
566 | urbs[i]->transfer_buffer_length = FRAMES_PER_URB | 569 | urbs[i]->transfer_buffer_length = FRAMES_PER_URB |
567 | * BYTES_PER_FRAME; | 570 | * BYTES_PER_FRAME; |
568 | urbs[i]->context = &dev->data_cb_info[i]; | 571 | urbs[i]->context = &dev->data_cb_info[i]; |
569 | urbs[i]->interval = 1; | 572 | urbs[i]->interval = 1; |
@@ -587,7 +590,7 @@ static void free_urbs(struct urb **urbs) | |||
587 | for (i = 0; i < N_URBS; i++) { | 590 | for (i = 0; i < N_URBS; i++) { |
588 | if (!urbs[i]) | 591 | if (!urbs[i]) |
589 | continue; | 592 | continue; |
590 | 593 | ||
591 | usb_kill_urb(urbs[i]); | 594 | usb_kill_urb(urbs[i]); |
592 | kfree(urbs[i]->transfer_buffer); | 595 | kfree(urbs[i]->transfer_buffer); |
593 | usb_free_urb(urbs[i]); | 596 | usb_free_urb(urbs[i]); |
@@ -600,11 +603,11 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
600 | { | 603 | { |
601 | int i, ret; | 604 | int i, ret; |
602 | 605 | ||
603 | dev->n_audio_in = max(dev->spec.num_analog_audio_in, | 606 | dev->n_audio_in = max(dev->spec.num_analog_audio_in, |
604 | dev->spec.num_digital_audio_in) / | 607 | dev->spec.num_digital_audio_in) / |
605 | CHANNELS_PER_STREAM; | 608 | CHANNELS_PER_STREAM; |
606 | dev->n_audio_out = max(dev->spec.num_analog_audio_out, | 609 | dev->n_audio_out = max(dev->spec.num_analog_audio_out, |
607 | dev->spec.num_digital_audio_out) / | 610 | dev->spec.num_digital_audio_out) / |
608 | CHANNELS_PER_STREAM; | 611 | CHANNELS_PER_STREAM; |
609 | dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); | 612 | dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); |
610 | 613 | ||
@@ -617,7 +620,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
617 | return -EINVAL; | 620 | return -EINVAL; |
618 | } | 621 | } |
619 | 622 | ||
620 | ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, | 623 | ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, |
621 | dev->n_audio_out, dev->n_audio_in, &dev->pcm); | 624 | dev->n_audio_out, dev->n_audio_in, &dev->pcm); |
622 | 625 | ||
623 | if (ret < 0) { | 626 | if (ret < 0) { |
@@ -630,7 +633,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
630 | 633 | ||
631 | memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); | 634 | memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); |
632 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); | 635 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); |
633 | 636 | ||
634 | memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, | 637 | memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, |
635 | sizeof(snd_usb_caiaq_pcm_hardware)); | 638 | sizeof(snd_usb_caiaq_pcm_hardware)); |
636 | 639 | ||
@@ -649,9 +652,9 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
649 | break; | 652 | break; |
650 | } | 653 | } |
651 | 654 | ||
652 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, | 655 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, |
653 | &snd_usb_caiaq_ops); | 656 | &snd_usb_caiaq_ops); |
654 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, | 657 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, |
655 | &snd_usb_caiaq_ops); | 658 | &snd_usb_caiaq_ops); |
656 | 659 | ||
657 | snd_pcm_lib_preallocate_pages_for_all(dev->pcm, | 660 | snd_pcm_lib_preallocate_pages_for_all(dev->pcm, |
@@ -660,7 +663,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
660 | MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); | 663 | MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); |
661 | 664 | ||
662 | dev->data_cb_info = | 665 | dev->data_cb_info = |
663 | kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, | 666 | kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, |
664 | GFP_KERNEL); | 667 | GFP_KERNEL); |
665 | 668 | ||
666 | if (!dev->data_cb_info) | 669 | if (!dev->data_cb_info) |
@@ -670,14 +673,14 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | |||
670 | dev->data_cb_info[i].dev = dev; | 673 | dev->data_cb_info[i].dev = dev; |
671 | dev->data_cb_info[i].index = i; | 674 | dev->data_cb_info[i].index = i; |
672 | } | 675 | } |
673 | 676 | ||
674 | dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); | 677 | dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); |
675 | if (ret < 0) { | 678 | if (ret < 0) { |
676 | kfree(dev->data_cb_info); | 679 | kfree(dev->data_cb_info); |
677 | free_urbs(dev->data_urbs_in); | 680 | free_urbs(dev->data_urbs_in); |
678 | return ret; | 681 | return ret; |
679 | } | 682 | } |
680 | 683 | ||
681 | dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); | 684 | dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); |
682 | if (ret < 0) { | 685 | if (ret < 0) { |
683 | kfree(dev->data_cb_info); | 686 | kfree(dev->data_cb_info); |
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 6d517705da0e..0e5db719de24 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "input.h" | 35 | #include "input.h" |
36 | 36 | ||
37 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 37 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
38 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.13"); | 38 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.17"); |
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | 40 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," |
41 | "{Native Instruments, RigKontrol3}," | 41 | "{Native Instruments, RigKontrol3}," |
@@ -79,7 +79,7 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
79 | { | 79 | { |
80 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 80 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
81 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 81 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
82 | .idProduct = USB_PID_RIGKONTROL2 | 82 | .idProduct = USB_PID_RIGKONTROL2 |
83 | }, | 83 | }, |
84 | { | 84 | { |
85 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 85 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
@@ -197,7 +197,7 @@ int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev, | |||
197 | 197 | ||
198 | if (buffer && len > 0) | 198 | if (buffer && len > 0) |
199 | memcpy(dev->ep1_out_buf+1, buffer, len); | 199 | memcpy(dev->ep1_out_buf+1, buffer, len); |
200 | 200 | ||
201 | dev->ep1_out_buf[0] = command; | 201 | dev->ep1_out_buf[0] = command; |
202 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), | 202 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), |
203 | dev->ep1_out_buf, len+1, &actual_len, 200); | 203 | dev->ep1_out_buf, len+1, &actual_len, 200); |
@@ -208,7 +208,7 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | |||
208 | { | 208 | { |
209 | int ret; | 209 | int ret; |
210 | char tmp[5]; | 210 | char tmp[5]; |
211 | 211 | ||
212 | switch (rate) { | 212 | switch (rate) { |
213 | case 44100: tmp[0] = SAMPLERATE_44100; break; | 213 | case 44100: tmp[0] = SAMPLERATE_44100; break; |
214 | case 48000: tmp[0] = SAMPLERATE_48000; break; | 214 | case 48000: tmp[0] = SAMPLERATE_48000; break; |
@@ -237,12 +237,12 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | |||
237 | 237 | ||
238 | if (ret) | 238 | if (ret) |
239 | return ret; | 239 | return ret; |
240 | 240 | ||
241 | if (!wait_event_timeout(dev->ep1_wait_queue, | 241 | if (!wait_event_timeout(dev->ep1_wait_queue, |
242 | dev->audio_parm_answer >= 0, HZ)) | 242 | dev->audio_parm_answer >= 0, HZ)) |
243 | return -EPIPE; | 243 | return -EPIPE; |
244 | 244 | ||
245 | if (dev->audio_parm_answer != 1) | 245 | if (dev->audio_parm_answer != 1) |
246 | debug("unable to set the device's audio params\n"); | 246 | debug("unable to set the device's audio params\n"); |
247 | else | 247 | else |
248 | dev->bpp = bpp; | 248 | dev->bpp = bpp; |
@@ -250,8 +250,8 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | |||
250 | return dev->audio_parm_answer == 1 ? 0 : -EINVAL; | 250 | return dev->audio_parm_answer == 1 ? 0 : -EINVAL; |
251 | } | 251 | } |
252 | 252 | ||
253 | int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, | 253 | int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *dev, |
254 | int digital, int analog, int erp) | 254 | int digital, int analog, int erp) |
255 | { | 255 | { |
256 | char tmp[3] = { digital, analog, erp }; | 256 | char tmp[3] = { digital, analog, erp }; |
257 | return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG, | 257 | return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG, |
@@ -262,7 +262,7 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) | |||
262 | { | 262 | { |
263 | int ret; | 263 | int ret; |
264 | char val[4]; | 264 | char val[4]; |
265 | 265 | ||
266 | /* device-specific startup specials */ | 266 | /* device-specific startup specials */ |
267 | switch (dev->chip.usb_id) { | 267 | switch (dev->chip.usb_id) { |
268 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 268 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
@@ -314,7 +314,7 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) | |||
314 | dev->control_state, 1); | 314 | dev->control_state, 1); |
315 | break; | 315 | break; |
316 | } | 316 | } |
317 | 317 | ||
318 | if (dev->spec.num_analog_audio_out + | 318 | if (dev->spec.num_analog_audio_out + |
319 | dev->spec.num_analog_audio_in + | 319 | dev->spec.num_analog_audio_in + |
320 | dev->spec.num_digital_audio_out + | 320 | dev->spec.num_digital_audio_out + |
@@ -323,7 +323,7 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) | |||
323 | if (ret < 0) | 323 | if (ret < 0) |
324 | log("Unable to set up audio system (ret=%d)\n", ret); | 324 | log("Unable to set up audio system (ret=%d)\n", ret); |
325 | } | 325 | } |
326 | 326 | ||
327 | if (dev->spec.num_midi_in + | 327 | if (dev->spec.num_midi_in + |
328 | dev->spec.num_midi_out > 0) { | 328 | dev->spec.num_midi_out > 0) { |
329 | ret = snd_usb_caiaq_midi_init(dev); | 329 | ret = snd_usb_caiaq_midi_init(dev); |
@@ -363,7 +363,7 @@ static int create_card(struct usb_device* usb_dev, struct snd_card **cardp) | |||
363 | if (devnum >= SNDRV_CARDS) | 363 | if (devnum >= SNDRV_CARDS) |
364 | return -ENODEV; | 364 | return -ENODEV; |
365 | 365 | ||
366 | err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, | 366 | err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, |
367 | sizeof(struct snd_usb_caiaqdev), &card); | 367 | sizeof(struct snd_usb_caiaqdev), &card); |
368 | if (err < 0) | 368 | if (err < 0) |
369 | return err; | 369 | return err; |
@@ -382,11 +382,11 @@ static int create_card(struct usb_device* usb_dev, struct snd_card **cardp) | |||
382 | 382 | ||
383 | static int __devinit init_card(struct snd_usb_caiaqdev *dev) | 383 | static int __devinit init_card(struct snd_usb_caiaqdev *dev) |
384 | { | 384 | { |
385 | char *c; | 385 | char *c, usbpath[32]; |
386 | struct usb_device *usb_dev = dev->chip.dev; | 386 | struct usb_device *usb_dev = dev->chip.dev; |
387 | struct snd_card *card = dev->chip.card; | 387 | struct snd_card *card = dev->chip.card; |
388 | int err, len; | 388 | int err, len; |
389 | 389 | ||
390 | if (usb_set_interface(usb_dev, 0, 1) != 0) { | 390 | if (usb_set_interface(usb_dev, 0, 1) != 0) { |
391 | log("can't set alt interface.\n"); | 391 | log("can't set alt interface.\n"); |
392 | return -EIO; | 392 | return -EIO; |
@@ -395,19 +395,19 @@ static int __devinit init_card(struct snd_usb_caiaqdev *dev) | |||
395 | usb_init_urb(&dev->ep1_in_urb); | 395 | usb_init_urb(&dev->ep1_in_urb); |
396 | usb_init_urb(&dev->midi_out_urb); | 396 | usb_init_urb(&dev->midi_out_urb); |
397 | 397 | ||
398 | usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, | 398 | usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, |
399 | usb_rcvbulkpipe(usb_dev, 0x1), | 399 | usb_rcvbulkpipe(usb_dev, 0x1), |
400 | dev->ep1_in_buf, EP1_BUFSIZE, | 400 | dev->ep1_in_buf, EP1_BUFSIZE, |
401 | usb_ep1_command_reply_dispatch, dev); | 401 | usb_ep1_command_reply_dispatch, dev); |
402 | 402 | ||
403 | usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, | 403 | usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, |
404 | usb_sndbulkpipe(usb_dev, 0x1), | 404 | usb_sndbulkpipe(usb_dev, 0x1), |
405 | dev->midi_out_buf, EP1_BUFSIZE, | 405 | dev->midi_out_buf, EP1_BUFSIZE, |
406 | snd_usb_caiaq_midi_output_done, dev); | 406 | snd_usb_caiaq_midi_output_done, dev); |
407 | 407 | ||
408 | init_waitqueue_head(&dev->ep1_wait_queue); | 408 | init_waitqueue_head(&dev->ep1_wait_queue); |
409 | init_waitqueue_head(&dev->prepare_wait_queue); | 409 | init_waitqueue_head(&dev->prepare_wait_queue); |
410 | 410 | ||
411 | if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) | 411 | if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) |
412 | return -EIO; | 412 | return -EIO; |
413 | 413 | ||
@@ -420,47 +420,52 @@ static int __devinit init_card(struct snd_usb_caiaqdev *dev) | |||
420 | 420 | ||
421 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, | 421 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, |
422 | dev->vendor_name, CAIAQ_USB_STR_LEN); | 422 | dev->vendor_name, CAIAQ_USB_STR_LEN); |
423 | 423 | ||
424 | usb_string(usb_dev, usb_dev->descriptor.iProduct, | 424 | usb_string(usb_dev, usb_dev->descriptor.iProduct, |
425 | dev->product_name, CAIAQ_USB_STR_LEN); | 425 | dev->product_name, CAIAQ_USB_STR_LEN); |
426 | 426 | ||
427 | usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, | 427 | strlcpy(card->driver, MODNAME, sizeof(card->driver)); |
428 | dev->serial, CAIAQ_USB_STR_LEN); | 428 | strlcpy(card->shortname, dev->product_name, sizeof(card->shortname)); |
429 | 429 | strlcpy(card->mixername, dev->product_name, sizeof(card->mixername)); | |
430 | /* terminate serial string at first white space occurence */ | 430 | |
431 | c = strchr(dev->serial, ' '); | 431 | /* if the id was not passed as module option, fill it with a shortened |
432 | if (c) | 432 | * version of the product string which does not contain any |
433 | *c = '\0'; | 433 | * whitespaces */ |
434 | 434 | ||
435 | strcpy(card->driver, MODNAME); | 435 | if (*card->id == '\0') { |
436 | strcpy(card->shortname, dev->product_name); | 436 | char id[sizeof(card->id)]; |
437 | 437 | ||
438 | len = snprintf(card->longname, sizeof(card->longname), | 438 | memset(id, 0, sizeof(id)); |
439 | "%s %s (serial %s, ", | 439 | |
440 | dev->vendor_name, dev->product_name, dev->serial); | 440 | for (c = card->shortname, len = 0; |
441 | 441 | *c && len < sizeof(card->id); c++) | |
442 | if (len < sizeof(card->longname) - 2) | 442 | if (*c != ' ') |
443 | len += usb_make_path(usb_dev, card->longname + len, | 443 | id[len++] = *c; |
444 | sizeof(card->longname) - len); | 444 | |
445 | 445 | snd_card_set_id(card, id); | |
446 | card->longname[len++] = ')'; | 446 | } |
447 | card->longname[len] = '\0'; | 447 | |
448 | usb_make_path(usb_dev, usbpath, sizeof(usbpath)); | ||
449 | snprintf(card->longname, sizeof(card->longname), | ||
450 | "%s %s (%s)", | ||
451 | dev->vendor_name, dev->product_name, usbpath); | ||
452 | |||
448 | setup_card(dev); | 453 | setup_card(dev); |
449 | return 0; | 454 | return 0; |
450 | } | 455 | } |
451 | 456 | ||
452 | static int __devinit snd_probe(struct usb_interface *intf, | 457 | static int __devinit snd_probe(struct usb_interface *intf, |
453 | const struct usb_device_id *id) | 458 | const struct usb_device_id *id) |
454 | { | 459 | { |
455 | int ret; | 460 | int ret; |
456 | struct snd_card *card; | 461 | struct snd_card *card; |
457 | struct usb_device *device = interface_to_usbdev(intf); | 462 | struct usb_device *device = interface_to_usbdev(intf); |
458 | 463 | ||
459 | ret = create_card(device, &card); | 464 | ret = create_card(device, &card); |
460 | 465 | ||
461 | if (ret < 0) | 466 | if (ret < 0) |
462 | return ret; | 467 | return ret; |
463 | 468 | ||
464 | usb_set_intfdata(intf, card); | 469 | usb_set_intfdata(intf, card); |
465 | ret = init_card(caiaqdev(card)); | 470 | ret = init_card(caiaqdev(card)); |
466 | if (ret < 0) { | 471 | if (ret < 0) { |
@@ -468,7 +473,7 @@ static int __devinit snd_probe(struct usb_interface *intf, | |||
468 | snd_card_free(card); | 473 | snd_card_free(card); |
469 | return ret; | 474 | return ret; |
470 | } | 475 | } |
471 | 476 | ||
472 | return 0; | 477 | return 0; |
473 | } | 478 | } |
474 | 479 | ||
@@ -489,10 +494,10 @@ static void snd_disconnect(struct usb_interface *intf) | |||
489 | snd_usb_caiaq_input_free(dev); | 494 | snd_usb_caiaq_input_free(dev); |
490 | #endif | 495 | #endif |
491 | snd_usb_caiaq_audio_free(dev); | 496 | snd_usb_caiaq_audio_free(dev); |
492 | 497 | ||
493 | usb_kill_urb(&dev->ep1_in_urb); | 498 | usb_kill_urb(&dev->ep1_in_urb); |
494 | usb_kill_urb(&dev->midi_out_urb); | 499 | usb_kill_urb(&dev->midi_out_urb); |
495 | 500 | ||
496 | snd_card_free(card); | 501 | snd_card_free(card); |
497 | usb_reset_device(interface_to_usbdev(intf)); | 502 | usb_reset_device(interface_to_usbdev(intf)); |
498 | } | 503 | } |
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index 4cce1ad7493d..ece73514854e 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
@@ -81,7 +81,6 @@ struct snd_usb_caiaqdev { | |||
81 | 81 | ||
82 | char vendor_name[CAIAQ_USB_STR_LEN]; | 82 | char vendor_name[CAIAQ_USB_STR_LEN]; |
83 | char product_name[CAIAQ_USB_STR_LEN]; | 83 | char product_name[CAIAQ_USB_STR_LEN]; |
84 | char serial[CAIAQ_USB_STR_LEN]; | ||
85 | 84 | ||
86 | int n_streams, n_audio_in, n_audio_out; | 85 | int n_streams, n_audio_in, n_audio_out; |
87 | int streaming, first_packet, output_running; | 86 | int streaming, first_packet, output_running; |
diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c index 8fa8cd88d763..538e8c00d31a 100644 --- a/sound/usb/caiaq/midi.c +++ b/sound/usb/caiaq/midi.c | |||
@@ -40,7 +40,7 @@ static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *subst | |||
40 | 40 | ||
41 | if (!dev) | 41 | if (!dev) |
42 | return; | 42 | return; |
43 | 43 | ||
44 | dev->midi_receive_substream = up ? substream : NULL; | 44 | dev->midi_receive_substream = up ? substream : NULL; |
45 | } | 45 | } |
46 | 46 | ||
@@ -64,18 +64,18 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev, | |||
64 | struct snd_rawmidi_substream *substream) | 64 | struct snd_rawmidi_substream *substream) |
65 | { | 65 | { |
66 | int len, ret; | 66 | int len, ret; |
67 | 67 | ||
68 | dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; | 68 | dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; |
69 | dev->midi_out_buf[1] = 0; /* port */ | 69 | dev->midi_out_buf[1] = 0; /* port */ |
70 | len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3, | 70 | len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3, |
71 | EP1_BUFSIZE - 3); | 71 | EP1_BUFSIZE - 3); |
72 | 72 | ||
73 | if (len <= 0) | 73 | if (len <= 0) |
74 | return; | 74 | return; |
75 | 75 | ||
76 | dev->midi_out_buf[2] = len; | 76 | dev->midi_out_buf[2] = len; |
77 | dev->midi_out_urb.transfer_buffer_length = len+3; | 77 | dev->midi_out_urb.transfer_buffer_length = len+3; |
78 | 78 | ||
79 | ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); | 79 | ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); |
80 | if (ret < 0) | 80 | if (ret < 0) |
81 | log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed," | 81 | log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed," |
@@ -88,7 +88,7 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev, | |||
88 | static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) | 88 | static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) |
89 | { | 89 | { |
90 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; | 90 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; |
91 | 91 | ||
92 | if (up) { | 92 | if (up) { |
93 | dev->midi_out_substream = substream; | 93 | dev->midi_out_substream = substream; |
94 | if (!dev->midi_out_active) | 94 | if (!dev->midi_out_active) |
@@ -113,12 +113,12 @@ static struct snd_rawmidi_ops snd_usb_caiaq_midi_input = | |||
113 | .trigger = snd_usb_caiaq_midi_input_trigger, | 113 | .trigger = snd_usb_caiaq_midi_input_trigger, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, | 116 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, |
117 | int port, const char *buf, int len) | 117 | int port, const char *buf, int len) |
118 | { | 118 | { |
119 | if (!dev->midi_receive_substream) | 119 | if (!dev->midi_receive_substream) |
120 | return; | 120 | return; |
121 | 121 | ||
122 | snd_rawmidi_receive(dev->midi_receive_substream, buf, len); | 122 | snd_rawmidi_receive(dev->midi_receive_substream, buf, len); |
123 | } | 123 | } |
124 | 124 | ||
@@ -142,16 +142,16 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) | |||
142 | 142 | ||
143 | if (device->spec.num_midi_out > 0) { | 143 | if (device->spec.num_midi_out > 0) { |
144 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | 144 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; |
145 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | 145 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, |
146 | &snd_usb_caiaq_midi_output); | 146 | &snd_usb_caiaq_midi_output); |
147 | } | 147 | } |
148 | 148 | ||
149 | if (device->spec.num_midi_in > 0) { | 149 | if (device->spec.num_midi_in > 0) { |
150 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | 150 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; |
151 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | 151 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, |
152 | &snd_usb_caiaq_midi_input); | 152 | &snd_usb_caiaq_midi_input); |
153 | } | 153 | } |
154 | 154 | ||
155 | device->rmidi = rmidi; | 155 | device->rmidi = rmidi; |
156 | 156 | ||
157 | return 0; | 157 | return 0; |
@@ -160,7 +160,7 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) | |||
160 | void snd_usb_caiaq_midi_output_done(struct urb* urb) | 160 | void snd_usb_caiaq_midi_output_done(struct urb* urb) |
161 | { | 161 | { |
162 | struct snd_usb_caiaqdev *dev = urb->context; | 162 | struct snd_usb_caiaqdev *dev = urb->context; |
163 | 163 | ||
164 | dev->midi_out_active = 0; | 164 | dev->midi_out_active = 0; |
165 | if (urb->status != 0) | 165 | if (urb->status != 0) |
166 | return; | 166 | return; |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 823296d7d578..c7b902358b7b 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -627,6 +627,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, | |||
627 | subs->hwptr_done += offs; | 627 | subs->hwptr_done += offs; |
628 | if (subs->hwptr_done >= runtime->buffer_size) | 628 | if (subs->hwptr_done >= runtime->buffer_size) |
629 | subs->hwptr_done -= runtime->buffer_size; | 629 | subs->hwptr_done -= runtime->buffer_size; |
630 | runtime->delay += offs; | ||
630 | spin_unlock_irqrestore(&subs->lock, flags); | 631 | spin_unlock_irqrestore(&subs->lock, flags); |
631 | urb->transfer_buffer_length = offs * stride; | 632 | urb->transfer_buffer_length = offs * stride; |
632 | if (period_elapsed) | 633 | if (period_elapsed) |
@@ -636,12 +637,22 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, | |||
636 | 637 | ||
637 | /* | 638 | /* |
638 | * process after playback data complete | 639 | * process after playback data complete |
639 | * - nothing to do | 640 | * - decrease the delay count again |
640 | */ | 641 | */ |
641 | static int retire_playback_urb(struct snd_usb_substream *subs, | 642 | static int retire_playback_urb(struct snd_usb_substream *subs, |
642 | struct snd_pcm_runtime *runtime, | 643 | struct snd_pcm_runtime *runtime, |
643 | struct urb *urb) | 644 | struct urb *urb) |
644 | { | 645 | { |
646 | unsigned long flags; | ||
647 | int stride = runtime->frame_bits >> 3; | ||
648 | int processed = urb->transfer_buffer_length / stride; | ||
649 | |||
650 | spin_lock_irqsave(&subs->lock, flags); | ||
651 | if (processed > runtime->delay) | ||
652 | runtime->delay = 0; | ||
653 | else | ||
654 | runtime->delay -= processed; | ||
655 | spin_unlock_irqrestore(&subs->lock, flags); | ||
645 | return 0; | 656 | return 0; |
646 | } | 657 | } |
647 | 658 | ||
@@ -1520,6 +1531,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
1520 | subs->hwptr_done = 0; | 1531 | subs->hwptr_done = 0; |
1521 | subs->transfer_done = 0; | 1532 | subs->transfer_done = 0; |
1522 | subs->phase = 0; | 1533 | subs->phase = 0; |
1534 | runtime->delay = 0; | ||
1523 | 1535 | ||
1524 | /* clear urbs (to be sure) */ | 1536 | /* clear urbs (to be sure) */ |
1525 | deactivate_urbs(subs, 0, 1); | 1537 | deactivate_urbs(subs, 0, 1); |
@@ -3279,6 +3291,25 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | |||
3279 | return snd_usb_cm106_write_int_reg(dev, 2, 0x8004); | 3291 | return snd_usb_cm106_write_int_reg(dev, 2, 0x8004); |
3280 | } | 3292 | } |
3281 | 3293 | ||
3294 | /* | ||
3295 | * C-Media CM6206 is based on CM106 with two additional | ||
3296 | * registers that are not documented in the data sheet. | ||
3297 | * Values here are chosen based on sniffing USB traffic | ||
3298 | * under Windows. | ||
3299 | */ | ||
3300 | static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) | ||
3301 | { | ||
3302 | int err, reg; | ||
3303 | int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; | ||
3304 | |||
3305 | for (reg = 0; reg < ARRAY_SIZE(val); reg++) { | ||
3306 | err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]); | ||
3307 | if (err < 0) | ||
3308 | return err; | ||
3309 | } | ||
3310 | |||
3311 | return err; | ||
3312 | } | ||
3282 | 3313 | ||
3283 | /* | 3314 | /* |
3284 | * Setup quirks | 3315 | * Setup quirks |
@@ -3347,7 +3378,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
3347 | [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, | 3378 | [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, |
3348 | [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, | 3379 | [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, |
3349 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, | 3380 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, |
3350 | [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, | 3381 | [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface, |
3351 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, | 3382 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, |
3352 | [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, | 3383 | [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, |
3353 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 3384 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
@@ -3565,6 +3596,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
3565 | goto __err_val; | 3596 | goto __err_val; |
3566 | } | 3597 | } |
3567 | 3598 | ||
3599 | /* C-Media CM6206 / CM106-Like Sound Device */ | ||
3600 | if (id == USB_ID(0x0d8c, 0x0102)) { | ||
3601 | if (snd_usb_cm6206_boot_quirk(dev) < 0) | ||
3602 | goto __err_val; | ||
3603 | } | ||
3604 | |||
3568 | /* | 3605 | /* |
3569 | * found a config. now register to ALSA | 3606 | * found a config. now register to ALSA |
3570 | */ | 3607 | */ |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 36e4f7a29adc..8e7f78941ba6 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -153,7 +153,7 @@ enum quirk_type { | |||
153 | QUIRK_MIDI_YAMAHA, | 153 | QUIRK_MIDI_YAMAHA, |
154 | QUIRK_MIDI_MIDIMAN, | 154 | QUIRK_MIDI_MIDIMAN, |
155 | QUIRK_MIDI_NOVATION, | 155 | QUIRK_MIDI_NOVATION, |
156 | QUIRK_MIDI_RAW, | 156 | QUIRK_MIDI_FASTLANE, |
157 | QUIRK_MIDI_EMAGIC, | 157 | QUIRK_MIDI_EMAGIC, |
158 | QUIRK_MIDI_CME, | 158 | QUIRK_MIDI_CME, |
159 | QUIRK_MIDI_US122L, | 159 | QUIRK_MIDI_US122L, |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 26bad373fe65..2fb35cc22a30 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -1778,8 +1778,18 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1778 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; | 1778 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; |
1779 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 1779 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1780 | break; | 1780 | break; |
1781 | case QUIRK_MIDI_RAW: | 1781 | case QUIRK_MIDI_FASTLANE: |
1782 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; | 1782 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; |
1783 | /* | ||
1784 | * Interface 1 contains isochronous endpoints, but with the same | ||
1785 | * numbers as in interface 0. Since it is interface 1 that the | ||
1786 | * USB core has most recently seen, these descriptors are now | ||
1787 | * associated with the endpoint numbers. This will foul up our | ||
1788 | * attempts to submit bulk/interrupt URBs to the endpoints in | ||
1789 | * interface 0, so we have to make sure that the USB core looks | ||
1790 | * again at interface 0 by calling usb_set_interface() on it. | ||
1791 | */ | ||
1792 | usb_set_interface(umidi->chip->dev, 0, 0); | ||
1783 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 1793 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1784 | break; | 1794 | break; |
1785 | case QUIRK_MIDI_EMAGIC: | 1795 | case QUIRK_MIDI_EMAGIC: |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 647ef5029651..f6f201eb24ce 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -1470,6 +1470,41 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1470 | } | 1470 | } |
1471 | }, | 1471 | }, |
1472 | { | 1472 | { |
1473 | /* Edirol M-16DX */ | ||
1474 | /* FIXME: This quirk gives a good-working capture stream but the | ||
1475 | * playback seems problematic because of lacking of sync | ||
1476 | * with capture stream. It needs to sync with the capture | ||
1477 | * clock. As now, you'll get frequent sound distortions | ||
1478 | * via the playback. | ||
1479 | */ | ||
1480 | USB_DEVICE(0x0582, 0x00c4), | ||
1481 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1482 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1483 | .type = QUIRK_COMPOSITE, | ||
1484 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1485 | { | ||
1486 | .ifnum = 0, | ||
1487 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1488 | }, | ||
1489 | { | ||
1490 | .ifnum = 1, | ||
1491 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1492 | }, | ||
1493 | { | ||
1494 | .ifnum = 2, | ||
1495 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1496 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1497 | .out_cables = 0x0001, | ||
1498 | .in_cables = 0x0001 | ||
1499 | } | ||
1500 | }, | ||
1501 | { | ||
1502 | .ifnum = -1 | ||
1503 | } | ||
1504 | } | ||
1505 | } | ||
1506 | }, | ||
1507 | { | ||
1473 | /* BOSS GT-10 */ | 1508 | /* BOSS GT-10 */ |
1474 | USB_DEVICE(0x0582, 0x00da), | 1509 | USB_DEVICE(0x0582, 0x00da), |
1475 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1510 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
@@ -1868,7 +1903,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1868 | .data = & (const struct snd_usb_audio_quirk[]) { | 1903 | .data = & (const struct snd_usb_audio_quirk[]) { |
1869 | { | 1904 | { |
1870 | .ifnum = 0, | 1905 | .ifnum = 0, |
1871 | .type = QUIRK_MIDI_RAW | 1906 | .type = QUIRK_MIDI_FASTLANE |
1872 | }, | 1907 | }, |
1873 | { | 1908 | { |
1874 | .ifnum = 1, | 1909 | .ifnum = 1, |
@@ -1951,6 +1986,14 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1951 | } | 1986 | } |
1952 | }, | 1987 | }, |
1953 | { | 1988 | { |
1989 | USB_DEVICE(0x0ccd, 0x0028), | ||
1990 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1991 | .vendor_name = "TerraTec", | ||
1992 | .product_name = "Aureon5.1MkII", | ||
1993 | .ifnum = QUIRK_NO_INTERFACE | ||
1994 | } | ||
1995 | }, | ||
1996 | { | ||
1954 | USB_DEVICE(0x0ccd, 0x0035), | 1997 | USB_DEVICE(0x0ccd, 0x0035), |
1955 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1998 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1956 | .vendor_name = "Miditech", | 1999 | .vendor_name = "Miditech", |
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index 012ff1f6f8af..a5aae9d67f31 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c | |||
@@ -474,6 +474,14 @@ static bool us122l_create_card(struct snd_card *card) | |||
474 | return true; | 474 | return true; |
475 | } | 475 | } |
476 | 476 | ||
477 | static void snd_us122l_free(struct snd_card *card) | ||
478 | { | ||
479 | struct us122l *us122l = US122L(card); | ||
480 | int index = us122l->chip.index; | ||
481 | if (index >= 0 && index < SNDRV_CARDS) | ||
482 | snd_us122l_card_used[index] = 0; | ||
483 | } | ||
484 | |||
477 | static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) | 485 | static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) |
478 | { | 486 | { |
479 | int dev; | 487 | int dev; |
@@ -490,7 +498,7 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp) | |||
490 | if (err < 0) | 498 | if (err < 0) |
491 | return err; | 499 | return err; |
492 | snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; | 500 | snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; |
493 | 501 | card->private_free = snd_us122l_free; | |
494 | US122L(card)->chip.dev = device; | 502 | US122L(card)->chip.dev = device; |
495 | US122L(card)->chip.card = card; | 503 | US122L(card)->chip.card = card; |
496 | mutex_init(&US122L(card)->mutex); | 504 | mutex_init(&US122L(card)->mutex); |
@@ -584,7 +592,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf) | |||
584 | } | 592 | } |
585 | 593 | ||
586 | usb_put_intf(intf); | 594 | usb_put_intf(intf); |
587 | usb_put_dev(US122L(card)->chip.dev); | 595 | usb_put_dev(us122l->chip.dev); |
588 | 596 | ||
589 | while (atomic_read(&us122l->mmap_count)) | 597 | while (atomic_read(&us122l->mmap_count)) |
590 | msleep(500); | 598 | msleep(500); |
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index 24393dafcb6e..12ae0340adc0 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c | |||
@@ -33,32 +33,26 @@ static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk) | |||
33 | static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb) | 33 | static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb) |
34 | { | 34 | { |
35 | struct usb_stream *s = sk->s; | 35 | struct usb_stream *s = sk->s; |
36 | unsigned l = 0; | 36 | int pack, lb = 0; |
37 | int pack; | 37 | |
38 | 38 | for (pack = 0; pack < sk->n_o_ps; pack++) { | |
39 | urb->iso_frame_desc[0].offset = 0; | 39 | int l = usb_stream_next_packet_size(sk); |
40 | urb->iso_frame_desc[0].length = usb_stream_next_packet_size(sk); | 40 | if (s->idle_outsize + lb + l > s->period_size) |
41 | sk->out_phase = sk->out_phase_peeked; | ||
42 | urb->transfer_buffer_length = urb->iso_frame_desc[0].length; | ||
43 | |||
44 | for (pack = 1; pack < sk->n_o_ps; pack++) { | ||
45 | l = usb_stream_next_packet_size(sk); | ||
46 | if (s->idle_outsize + urb->transfer_buffer_length + l > | ||
47 | s->period_size) | ||
48 | goto check; | 41 | goto check; |
49 | 42 | ||
50 | sk->out_phase = sk->out_phase_peeked; | 43 | sk->out_phase = sk->out_phase_peeked; |
51 | urb->iso_frame_desc[pack].offset = urb->transfer_buffer_length; | 44 | urb->iso_frame_desc[pack].offset = lb; |
52 | urb->iso_frame_desc[pack].length = l; | 45 | urb->iso_frame_desc[pack].length = l; |
53 | urb->transfer_buffer_length += l; | 46 | lb += l; |
54 | } | 47 | } |
55 | snd_printdd(KERN_DEBUG "%i\n", urb->transfer_buffer_length); | 48 | snd_printdd(KERN_DEBUG "%i\n", lb); |
56 | 49 | ||
57 | check: | 50 | check: |
58 | urb->number_of_packets = pack; | 51 | urb->number_of_packets = pack; |
59 | s->idle_outsize += urb->transfer_buffer_length - s->period_size; | 52 | urb->transfer_buffer_length = lb; |
53 | s->idle_outsize += lb - s->period_size; | ||
60 | snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize, | 54 | snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize, |
61 | urb->transfer_buffer_length, s->period_size); | 55 | lb, s->period_size); |
62 | } | 56 | } |
63 | 57 | ||
64 | static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, | 58 | static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, |
@@ -282,21 +276,20 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk, | |||
282 | struct usb_stream *s = sk->s; | 276 | struct usb_stream *s = sk->s; |
283 | struct urb *io; | 277 | struct urb *io; |
284 | struct usb_iso_packet_descriptor *id, *od; | 278 | struct usb_iso_packet_descriptor *id, *od; |
285 | int p, l = 0; | 279 | int p = 0, lb = 0, l = 0; |
286 | 280 | ||
287 | io = sk->idle_outurb; | 281 | io = sk->idle_outurb; |
288 | od = io->iso_frame_desc; | 282 | od = io->iso_frame_desc; |
289 | io->transfer_buffer_length = 0; | ||
290 | 283 | ||
291 | for (p = 0; s->sync_packet < 0; ++p, ++s->sync_packet) { | 284 | for (; s->sync_packet < 0; ++p, ++s->sync_packet) { |
292 | struct urb *ii = sk->completed_inurb; | 285 | struct urb *ii = sk->completed_inurb; |
293 | id = ii->iso_frame_desc + | 286 | id = ii->iso_frame_desc + |
294 | ii->number_of_packets + s->sync_packet; | 287 | ii->number_of_packets + s->sync_packet; |
295 | l = id->actual_length; | 288 | l = id->actual_length; |
296 | 289 | ||
297 | od[p].length = l; | 290 | od[p].length = l; |
298 | od[p].offset = io->transfer_buffer_length; | 291 | od[p].offset = lb; |
299 | io->transfer_buffer_length += l; | 292 | lb += l; |
300 | } | 293 | } |
301 | 294 | ||
302 | for (; | 295 | for (; |
@@ -304,38 +297,38 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk, | |||
304 | ++p, ++s->sync_packet) { | 297 | ++p, ++s->sync_packet) { |
305 | l = inurb->iso_frame_desc[s->sync_packet].actual_length; | 298 | l = inurb->iso_frame_desc[s->sync_packet].actual_length; |
306 | 299 | ||
307 | if (s->idle_outsize + io->transfer_buffer_length + l > | 300 | if (s->idle_outsize + lb + l > s->period_size) |
308 | s->period_size) | ||
309 | goto check_ok; | 301 | goto check_ok; |
310 | 302 | ||
311 | od[p].length = l; | 303 | od[p].length = l; |
312 | od[p].offset = io->transfer_buffer_length; | 304 | od[p].offset = lb; |
313 | io->transfer_buffer_length += l; | 305 | lb += l; |
314 | } | 306 | } |
315 | 307 | ||
316 | check_ok: | 308 | check_ok: |
317 | s->sync_packet -= inurb->number_of_packets; | 309 | s->sync_packet -= inurb->number_of_packets; |
318 | if (s->sync_packet < -2 || s->sync_packet > 0) { | 310 | if (unlikely(s->sync_packet < -2 || s->sync_packet > 0)) { |
319 | snd_printk(KERN_WARNING "invalid sync_packet = %i;" | 311 | snd_printk(KERN_WARNING "invalid sync_packet = %i;" |
320 | " p=%i nop=%i %i %x %x %x > %x\n", | 312 | " p=%i nop=%i %i %x %x %x > %x\n", |
321 | s->sync_packet, p, inurb->number_of_packets, | 313 | s->sync_packet, p, inurb->number_of_packets, |
322 | s->idle_outsize + io->transfer_buffer_length + l, | 314 | s->idle_outsize + lb + l, |
323 | s->idle_outsize, io->transfer_buffer_length, l, | 315 | s->idle_outsize, lb, l, |
324 | s->period_size); | 316 | s->period_size); |
325 | return -1; | 317 | return -1; |
326 | } | 318 | } |
327 | if (io->transfer_buffer_length % s->cfg.frame_size) { | 319 | if (unlikely(lb % s->cfg.frame_size)) { |
328 | snd_printk(KERN_WARNING"invalid outsize = %i\n", | 320 | snd_printk(KERN_WARNING"invalid outsize = %i\n", |
329 | io->transfer_buffer_length); | 321 | lb); |
330 | return -1; | 322 | return -1; |
331 | } | 323 | } |
332 | s->idle_outsize += io->transfer_buffer_length - s->period_size; | 324 | s->idle_outsize += lb - s->period_size; |
333 | io->number_of_packets = p; | 325 | io->number_of_packets = p; |
334 | if (s->idle_outsize > 0) { | 326 | io->transfer_buffer_length = lb; |
335 | snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize); | 327 | if (s->idle_outsize <= 0) |
336 | return -1; | 328 | return 0; |
337 | } | 329 | |
338 | return 0; | 330 | snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize); |
331 | return -1; | ||
339 | } | 332 | } |
340 | 333 | ||
341 | static void prepare_inurb(int number_of_packets, struct urb *iu) | 334 | static void prepare_inurb(int number_of_packets, struct urb *iu) |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 9a608fa85155..dd1ab6177840 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -870,7 +870,8 @@ static struct snd_pcm_hardware snd_usX2Y_2c = | |||
870 | { | 870 | { |
871 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 871 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
872 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 872 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
873 | SNDRV_PCM_INFO_MMAP_VALID), | 873 | SNDRV_PCM_INFO_MMAP_VALID | |
874 | SNDRV_PCM_INFO_BATCH), | ||
874 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, | 875 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, |
875 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | 876 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, |
876 | .rate_min = 44100, | 877 | .rate_min = 44100, |