1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) 2006-2008 Daniel Mack, Karsten Wiese |
4 | */ |
5 | |
6 | #include <linux/device.h> |
7 | #include <linux/spinlock.h> |
8 | #include <linux/slab.h> |
9 | #include <linux/init.h> |
10 | #include <linux/usb.h> |
11 | #include <sound/core.h> |
12 | #include <sound/pcm.h> |
13 | |
14 | #include "device.h" |
15 | #include "audio.h" |
16 | |
17 | #define N_URBS 32 |
18 | #define CLOCK_DRIFT_TOLERANCE 5 |
19 | #define FRAMES_PER_URB 8 |
20 | #define BYTES_PER_FRAME 512 |
21 | #define CHANNELS_PER_STREAM 2 |
22 | #define BYTES_PER_SAMPLE 3 |
23 | #define BYTES_PER_SAMPLE_USB 4 |
24 | #define MAX_BUFFER_SIZE (128*1024) |
25 | #define MAX_ENDPOINT_SIZE 512 |
26 | |
27 | #define ENDPOINT_CAPTURE 2 |
28 | #define ENDPOINT_PLAYBACK 6 |
29 | |
30 | #define MAKE_CHECKBYTE(cdev,stream,i) \ |
31 | (stream << 1) | (~(i / (cdev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) |
32 | |
33 | static const struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { |
34 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
35 | SNDRV_PCM_INFO_BLOCK_TRANSFER), |
36 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, |
37 | .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | |
38 | SNDRV_PCM_RATE_96000), |
39 | .rate_min = 44100, |
40 | .rate_max = 0, /* will overwrite later */ |
41 | .channels_min = CHANNELS_PER_STREAM, |
42 | .channels_max = CHANNELS_PER_STREAM, |
43 | .buffer_bytes_max = MAX_BUFFER_SIZE, |
44 | .period_bytes_min = 128, |
45 | .period_bytes_max = MAX_BUFFER_SIZE, |
46 | .periods_min = 1, |
47 | .periods_max = 1024, |
48 | }; |
49 | |
50 | static void |
51 | activate_substream(struct snd_usb_caiaqdev *cdev, |
52 | struct snd_pcm_substream *sub) |
53 | { |
54 | spin_lock(lock: &cdev->spinlock); |
55 | |
56 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
57 | cdev->sub_playback[sub->number] = sub; |
58 | else |
59 | cdev->sub_capture[sub->number] = sub; |
60 | |
61 | spin_unlock(lock: &cdev->spinlock); |
62 | } |
63 | |
64 | static void |
65 | deactivate_substream(struct snd_usb_caiaqdev *cdev, |
66 | struct snd_pcm_substream *sub) |
67 | { |
68 | unsigned long flags; |
69 | spin_lock_irqsave(&cdev->spinlock, flags); |
70 | |
71 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
72 | cdev->sub_playback[sub->number] = NULL; |
73 | else |
74 | cdev->sub_capture[sub->number] = NULL; |
75 | |
76 | spin_unlock_irqrestore(lock: &cdev->spinlock, flags); |
77 | } |
78 | |
79 | static int |
80 | all_substreams_zero(struct snd_pcm_substream **subs) |
81 | { |
82 | int i; |
83 | for (i = 0; i < MAX_STREAMS; i++) |
84 | if (subs[i] != NULL) |
85 | return 0; |
86 | return 1; |
87 | } |
88 | |
89 | static int stream_start(struct snd_usb_caiaqdev *cdev) |
90 | { |
91 | int i, ret; |
92 | struct device *dev = caiaqdev_to_dev(cdev); |
93 | |
94 | dev_dbg(dev, "%s(%p)\n" , __func__, cdev); |
95 | |
96 | if (cdev->streaming) |
97 | return -EINVAL; |
98 | |
99 | memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback)); |
100 | memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture)); |
101 | cdev->input_panic = 0; |
102 | cdev->output_panic = 0; |
103 | cdev->first_packet = 4; |
104 | cdev->streaming = 1; |
105 | cdev->warned = 0; |
106 | |
107 | for (i = 0; i < N_URBS; i++) { |
108 | ret = usb_submit_urb(urb: cdev->data_urbs_in[i], GFP_ATOMIC); |
109 | if (ret) { |
110 | dev_err(dev, "unable to trigger read #%d! (ret %d)\n" , |
111 | i, ret); |
112 | cdev->streaming = 0; |
113 | return -EPIPE; |
114 | } |
115 | } |
116 | |
117 | return 0; |
118 | } |
119 | |
120 | static void stream_stop(struct snd_usb_caiaqdev *cdev) |
121 | { |
122 | int i; |
123 | struct device *dev = caiaqdev_to_dev(cdev); |
124 | |
125 | dev_dbg(dev, "%s(%p)\n" , __func__, cdev); |
126 | if (!cdev->streaming) |
127 | return; |
128 | |
129 | cdev->streaming = 0; |
130 | |
131 | for (i = 0; i < N_URBS; i++) { |
132 | usb_kill_urb(urb: cdev->data_urbs_in[i]); |
133 | |
134 | if (test_bit(i, &cdev->outurb_active_mask)) |
135 | usb_kill_urb(urb: cdev->data_urbs_out[i]); |
136 | } |
137 | |
138 | cdev->outurb_active_mask = 0; |
139 | } |
140 | |
141 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) |
142 | { |
143 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); |
144 | struct device *dev = caiaqdev_to_dev(cdev); |
145 | |
146 | dev_dbg(dev, "%s(%p)\n" , __func__, substream); |
147 | substream->runtime->hw = cdev->pcm_info; |
148 | snd_pcm_limit_hw_rates(runtime: substream->runtime); |
149 | |
150 | return 0; |
151 | } |
152 | |
153 | static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) |
154 | { |
155 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); |
156 | struct device *dev = caiaqdev_to_dev(cdev); |
157 | |
158 | dev_dbg(dev, "%s(%p)\n" , __func__, substream); |
159 | if (all_substreams_zero(subs: cdev->sub_playback) && |
160 | all_substreams_zero(subs: cdev->sub_capture)) { |
161 | /* when the last client has stopped streaming, |
162 | * all sample rates are allowed again */ |
163 | stream_stop(cdev); |
164 | cdev->pcm_info.rates = cdev->samplerates; |
165 | } |
166 | |
167 | return 0; |
168 | } |
169 | |
170 | static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) |
171 | { |
172 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); |
173 | deactivate_substream(cdev, sub); |
174 | return 0; |
175 | } |
176 | |
177 | /* this should probably go upstream */ |
178 | #if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 |
179 | #error "Change this table" |
180 | #endif |
181 | |
182 | static const unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, |
183 | 48000, 64000, 88200, 96000, 176400, 192000 }; |
184 | |
185 | static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) |
186 | { |
187 | int bytes_per_sample, bpp, ret, i; |
188 | int index = substream->number; |
189 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); |
190 | struct snd_pcm_runtime *runtime = substream->runtime; |
191 | struct device *dev = caiaqdev_to_dev(cdev); |
192 | |
193 | dev_dbg(dev, "%s(%p)\n" , __func__, substream); |
194 | |
195 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
196 | int out_pos; |
197 | |
198 | switch (cdev->spec.data_alignment) { |
199 | case 0: |
200 | case 2: |
201 | out_pos = BYTES_PER_SAMPLE + 1; |
202 | break; |
203 | case 3: |
204 | default: |
205 | out_pos = 0; |
206 | break; |
207 | } |
208 | |
209 | cdev->period_out_count[index] = out_pos; |
210 | cdev->audio_out_buf_pos[index] = out_pos; |
211 | } else { |
212 | int in_pos; |
213 | |
214 | switch (cdev->spec.data_alignment) { |
215 | case 0: |
216 | in_pos = BYTES_PER_SAMPLE + 2; |
217 | break; |
218 | case 2: |
219 | in_pos = BYTES_PER_SAMPLE; |
220 | break; |
221 | case 3: |
222 | default: |
223 | in_pos = 0; |
224 | break; |
225 | } |
226 | |
227 | cdev->period_in_count[index] = in_pos; |
228 | cdev->audio_in_buf_pos[index] = in_pos; |
229 | } |
230 | |
231 | if (cdev->streaming) |
232 | return 0; |
233 | |
234 | /* the first client that opens a stream defines the sample rate |
235 | * setting for all subsequent calls, until the last client closed. */ |
236 | for (i=0; i < ARRAY_SIZE(rates); i++) |
237 | if (runtime->rate == rates[i]) |
238 | cdev->pcm_info.rates = 1 << i; |
239 | |
240 | snd_pcm_limit_hw_rates(runtime); |
241 | |
242 | bytes_per_sample = BYTES_PER_SAMPLE; |
243 | if (cdev->spec.data_alignment >= 2) |
244 | bytes_per_sample++; |
245 | |
246 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) |
247 | * bytes_per_sample * CHANNELS_PER_STREAM * cdev->n_streams; |
248 | |
249 | if (bpp > MAX_ENDPOINT_SIZE) |
250 | bpp = MAX_ENDPOINT_SIZE; |
251 | |
252 | ret = snd_usb_caiaq_set_audio_params(cdev, rate: runtime->rate, |
253 | depth: runtime->sample_bits, bbp: bpp); |
254 | if (ret) |
255 | return ret; |
256 | |
257 | ret = stream_start(cdev); |
258 | if (ret) |
259 | return ret; |
260 | |
261 | cdev->output_running = 0; |
262 | wait_event_timeout(cdev->prepare_wait_queue, cdev->output_running, HZ); |
263 | if (!cdev->output_running) { |
264 | stream_stop(cdev); |
265 | return -EPIPE; |
266 | } |
267 | |
268 | return 0; |
269 | } |
270 | |
271 | static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) |
272 | { |
273 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); |
274 | struct device *dev = caiaqdev_to_dev(cdev); |
275 | |
276 | dev_dbg(dev, "%s(%p) cmd %d\n" , __func__, sub, cmd); |
277 | |
278 | switch (cmd) { |
279 | case SNDRV_PCM_TRIGGER_START: |
280 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
281 | activate_substream(cdev, sub); |
282 | break; |
283 | case SNDRV_PCM_TRIGGER_STOP: |
284 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
285 | deactivate_substream(cdev, sub); |
286 | break; |
287 | default: |
288 | return -EINVAL; |
289 | } |
290 | |
291 | return 0; |
292 | } |
293 | |
294 | static snd_pcm_uframes_t |
295 | snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) |
296 | { |
297 | int index = sub->number; |
298 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); |
299 | snd_pcm_uframes_t ptr; |
300 | |
301 | spin_lock(lock: &cdev->spinlock); |
302 | |
303 | if (cdev->input_panic || cdev->output_panic) { |
304 | ptr = SNDRV_PCM_POS_XRUN; |
305 | goto unlock; |
306 | } |
307 | |
308 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
309 | ptr = bytes_to_frames(runtime: sub->runtime, |
310 | size: cdev->audio_out_buf_pos[index]); |
311 | else |
312 | ptr = bytes_to_frames(runtime: sub->runtime, |
313 | size: cdev->audio_in_buf_pos[index]); |
314 | |
315 | unlock: |
316 | spin_unlock(lock: &cdev->spinlock); |
317 | return ptr; |
318 | } |
319 | |
320 | /* operators for both playback and capture */ |
321 | static const struct snd_pcm_ops snd_usb_caiaq_ops = { |
322 | .open = snd_usb_caiaq_substream_open, |
323 | .close = snd_usb_caiaq_substream_close, |
324 | .hw_free = snd_usb_caiaq_pcm_hw_free, |
325 | .prepare = snd_usb_caiaq_pcm_prepare, |
326 | .trigger = snd_usb_caiaq_pcm_trigger, |
327 | .pointer = snd_usb_caiaq_pcm_pointer, |
328 | }; |
329 | |
330 | static void check_for_elapsed_periods(struct snd_usb_caiaqdev *cdev, |
331 | struct snd_pcm_substream **subs) |
332 | { |
333 | int stream, pb, *cnt; |
334 | struct snd_pcm_substream *sub; |
335 | |
336 | for (stream = 0; stream < cdev->n_streams; stream++) { |
337 | sub = subs[stream]; |
338 | if (!sub) |
339 | continue; |
340 | |
341 | pb = snd_pcm_lib_period_bytes(substream: sub); |
342 | cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
343 | &cdev->period_out_count[stream] : |
344 | &cdev->period_in_count[stream]; |
345 | |
346 | if (*cnt >= pb) { |
347 | snd_pcm_period_elapsed(substream: sub); |
348 | *cnt %= pb; |
349 | } |
350 | } |
351 | } |
352 | |
353 | static void read_in_urb_mode0(struct snd_usb_caiaqdev *cdev, |
354 | const struct urb *urb, |
355 | const struct usb_iso_packet_descriptor *iso) |
356 | { |
357 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
358 | struct snd_pcm_substream *sub; |
359 | int stream, i; |
360 | |
361 | if (all_substreams_zero(subs: cdev->sub_capture)) |
362 | return; |
363 | |
364 | for (i = 0; i < iso->actual_length;) { |
365 | for (stream = 0; stream < cdev->n_streams; stream++, i++) { |
366 | sub = cdev->sub_capture[stream]; |
367 | if (sub) { |
368 | struct snd_pcm_runtime *rt = sub->runtime; |
369 | char *audio_buf = rt->dma_area; |
370 | int sz = frames_to_bytes(runtime: rt, size: rt->buffer_size); |
371 | audio_buf[cdev->audio_in_buf_pos[stream]++] |
372 | = usb_buf[i]; |
373 | cdev->period_in_count[stream]++; |
374 | if (cdev->audio_in_buf_pos[stream] == sz) |
375 | cdev->audio_in_buf_pos[stream] = 0; |
376 | } |
377 | } |
378 | } |
379 | } |
380 | |
381 | static void read_in_urb_mode2(struct snd_usb_caiaqdev *cdev, |
382 | const struct urb *urb, |
383 | const struct usb_iso_packet_descriptor *iso) |
384 | { |
385 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
386 | unsigned char check_byte; |
387 | struct snd_pcm_substream *sub; |
388 | int stream, i; |
389 | |
390 | for (i = 0; i < iso->actual_length;) { |
391 | if (i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { |
392 | for (stream = 0; |
393 | stream < cdev->n_streams; |
394 | stream++, i++) { |
395 | if (cdev->first_packet) |
396 | continue; |
397 | |
398 | check_byte = MAKE_CHECKBYTE(cdev, stream, i); |
399 | |
400 | if ((usb_buf[i] & 0x3f) != check_byte) |
401 | cdev->input_panic = 1; |
402 | |
403 | if (usb_buf[i] & 0x80) |
404 | cdev->output_panic = 1; |
405 | } |
406 | } |
407 | cdev->first_packet = 0; |
408 | |
409 | for (stream = 0; stream < cdev->n_streams; stream++, i++) { |
410 | sub = cdev->sub_capture[stream]; |
411 | if (cdev->input_panic) |
412 | usb_buf[i] = 0; |
413 | |
414 | if (sub) { |
415 | struct snd_pcm_runtime *rt = sub->runtime; |
416 | char *audio_buf = rt->dma_area; |
417 | int sz = frames_to_bytes(runtime: rt, size: rt->buffer_size); |
418 | audio_buf[cdev->audio_in_buf_pos[stream]++] = |
419 | usb_buf[i]; |
420 | cdev->period_in_count[stream]++; |
421 | if (cdev->audio_in_buf_pos[stream] == sz) |
422 | cdev->audio_in_buf_pos[stream] = 0; |
423 | } |
424 | } |
425 | } |
426 | } |
427 | |
428 | static void read_in_urb_mode3(struct snd_usb_caiaqdev *cdev, |
429 | const struct urb *urb, |
430 | const struct usb_iso_packet_descriptor *iso) |
431 | { |
432 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
433 | struct device *dev = caiaqdev_to_dev(cdev); |
434 | int stream, i; |
435 | |
436 | /* paranoia check */ |
437 | if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM)) |
438 | return; |
439 | |
440 | for (i = 0; i < iso->actual_length;) { |
441 | for (stream = 0; stream < cdev->n_streams; stream++) { |
442 | struct snd_pcm_substream *sub = cdev->sub_capture[stream]; |
443 | char *audio_buf = NULL; |
444 | int c, n, sz = 0; |
445 | |
446 | if (sub && !cdev->input_panic) { |
447 | struct snd_pcm_runtime *rt = sub->runtime; |
448 | audio_buf = rt->dma_area; |
449 | sz = frames_to_bytes(runtime: rt, size: rt->buffer_size); |
450 | } |
451 | |
452 | for (c = 0; c < CHANNELS_PER_STREAM; c++) { |
453 | /* 3 audio data bytes, followed by 1 check byte */ |
454 | if (audio_buf) { |
455 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { |
456 | audio_buf[cdev->audio_in_buf_pos[stream]++] = usb_buf[i+n]; |
457 | |
458 | if (cdev->audio_in_buf_pos[stream] == sz) |
459 | cdev->audio_in_buf_pos[stream] = 0; |
460 | } |
461 | |
462 | cdev->period_in_count[stream] += BYTES_PER_SAMPLE; |
463 | } |
464 | |
465 | i += BYTES_PER_SAMPLE; |
466 | |
467 | if (usb_buf[i] != ((stream << 1) | c) && |
468 | !cdev->first_packet) { |
469 | if (!cdev->input_panic) |
470 | dev_warn(dev, " EXPECTED: %02x got %02x, c %d, stream %d, i %d\n" , |
471 | ((stream << 1) | c), usb_buf[i], c, stream, i); |
472 | cdev->input_panic = 1; |
473 | } |
474 | |
475 | i++; |
476 | } |
477 | } |
478 | } |
479 | |
480 | if (cdev->first_packet > 0) |
481 | cdev->first_packet--; |
482 | } |
483 | |
484 | static void read_in_urb(struct snd_usb_caiaqdev *cdev, |
485 | const struct urb *urb, |
486 | const struct usb_iso_packet_descriptor *iso) |
487 | { |
488 | struct device *dev = caiaqdev_to_dev(cdev); |
489 | |
490 | if (!cdev->streaming) |
491 | return; |
492 | |
493 | if (iso->actual_length < cdev->bpp) |
494 | return; |
495 | |
496 | switch (cdev->spec.data_alignment) { |
497 | case 0: |
498 | read_in_urb_mode0(cdev, urb, iso); |
499 | break; |
500 | case 2: |
501 | read_in_urb_mode2(cdev, urb, iso); |
502 | break; |
503 | case 3: |
504 | read_in_urb_mode3(cdev, urb, iso); |
505 | break; |
506 | } |
507 | |
508 | if ((cdev->input_panic || cdev->output_panic) && !cdev->warned) { |
509 | dev_warn(dev, "streaming error detected %s %s\n" , |
510 | cdev->input_panic ? "(input)" : "" , |
511 | cdev->output_panic ? "(output)" : "" ); |
512 | cdev->warned = 1; |
513 | } |
514 | } |
515 | |
516 | static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *cdev, |
517 | struct urb *urb, |
518 | const struct usb_iso_packet_descriptor *iso) |
519 | { |
520 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
521 | struct snd_pcm_substream *sub; |
522 | int stream, i; |
523 | |
524 | for (i = 0; i < iso->length;) { |
525 | for (stream = 0; stream < cdev->n_streams; stream++, i++) { |
526 | sub = cdev->sub_playback[stream]; |
527 | if (sub) { |
528 | struct snd_pcm_runtime *rt = sub->runtime; |
529 | char *audio_buf = rt->dma_area; |
530 | int sz = frames_to_bytes(runtime: rt, size: rt->buffer_size); |
531 | usb_buf[i] = |
532 | audio_buf[cdev->audio_out_buf_pos[stream]]; |
533 | cdev->period_out_count[stream]++; |
534 | cdev->audio_out_buf_pos[stream]++; |
535 | if (cdev->audio_out_buf_pos[stream] == sz) |
536 | cdev->audio_out_buf_pos[stream] = 0; |
537 | } else |
538 | usb_buf[i] = 0; |
539 | } |
540 | |
541 | /* fill in the check bytes */ |
542 | if (cdev->spec.data_alignment == 2 && |
543 | i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == |
544 | (cdev->n_streams * CHANNELS_PER_STREAM)) |
545 | for (stream = 0; stream < cdev->n_streams; stream++, i++) |
546 | usb_buf[i] = MAKE_CHECKBYTE(cdev, stream, i); |
547 | } |
548 | } |
549 | |
550 | static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *cdev, |
551 | struct urb *urb, |
552 | const struct usb_iso_packet_descriptor *iso) |
553 | { |
554 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
555 | int stream, i; |
556 | |
557 | for (i = 0; i < iso->length;) { |
558 | for (stream = 0; stream < cdev->n_streams; stream++) { |
559 | struct snd_pcm_substream *sub = cdev->sub_playback[stream]; |
560 | char *audio_buf = NULL; |
561 | int c, n, sz = 0; |
562 | |
563 | if (sub) { |
564 | struct snd_pcm_runtime *rt = sub->runtime; |
565 | audio_buf = rt->dma_area; |
566 | sz = frames_to_bytes(runtime: rt, size: rt->buffer_size); |
567 | } |
568 | |
569 | for (c = 0; c < CHANNELS_PER_STREAM; c++) { |
570 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { |
571 | if (audio_buf) { |
572 | usb_buf[i+n] = audio_buf[cdev->audio_out_buf_pos[stream]++]; |
573 | |
574 | if (cdev->audio_out_buf_pos[stream] == sz) |
575 | cdev->audio_out_buf_pos[stream] = 0; |
576 | } else { |
577 | usb_buf[i+n] = 0; |
578 | } |
579 | } |
580 | |
581 | if (audio_buf) |
582 | cdev->period_out_count[stream] += BYTES_PER_SAMPLE; |
583 | |
584 | i += BYTES_PER_SAMPLE; |
585 | |
586 | /* fill in the check byte pattern */ |
587 | usb_buf[i++] = (stream << 1) | c; |
588 | } |
589 | } |
590 | } |
591 | } |
592 | |
593 | static inline void fill_out_urb(struct snd_usb_caiaqdev *cdev, |
594 | struct urb *urb, |
595 | const struct usb_iso_packet_descriptor *iso) |
596 | { |
597 | switch (cdev->spec.data_alignment) { |
598 | case 0: |
599 | case 2: |
600 | fill_out_urb_mode_0(cdev, urb, iso); |
601 | break; |
602 | case 3: |
603 | fill_out_urb_mode_3(cdev, urb, iso); |
604 | break; |
605 | } |
606 | } |
607 | |
608 | static void read_completed(struct urb *urb) |
609 | { |
610 | struct snd_usb_caiaq_cb_info *info = urb->context; |
611 | struct snd_usb_caiaqdev *cdev; |
612 | struct device *dev; |
613 | struct urb *out = NULL; |
614 | int i, frame, len, send_it = 0, outframe = 0; |
615 | unsigned long flags; |
616 | size_t offset = 0; |
617 | |
618 | if (urb->status || !info) |
619 | return; |
620 | |
621 | cdev = info->cdev; |
622 | dev = caiaqdev_to_dev(cdev); |
623 | |
624 | if (!cdev->streaming) |
625 | return; |
626 | |
627 | /* find an unused output urb that is unused */ |
628 | for (i = 0; i < N_URBS; i++) |
629 | if (test_and_set_bit(nr: i, addr: &cdev->outurb_active_mask) == 0) { |
630 | out = cdev->data_urbs_out[i]; |
631 | break; |
632 | } |
633 | |
634 | if (!out) { |
635 | dev_err(dev, "Unable to find an output urb to use\n" ); |
636 | goto requeue; |
637 | } |
638 | |
639 | /* read the recently received packet and send back one which has |
640 | * the same layout */ |
641 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
642 | if (urb->iso_frame_desc[frame].status) |
643 | continue; |
644 | |
645 | len = urb->iso_frame_desc[outframe].actual_length; |
646 | out->iso_frame_desc[outframe].length = len; |
647 | out->iso_frame_desc[outframe].actual_length = 0; |
648 | out->iso_frame_desc[outframe].offset = offset; |
649 | offset += len; |
650 | |
651 | if (len > 0) { |
652 | spin_lock_irqsave(&cdev->spinlock, flags); |
653 | fill_out_urb(cdev, urb: out, iso: &out->iso_frame_desc[outframe]); |
654 | read_in_urb(cdev, urb, iso: &urb->iso_frame_desc[frame]); |
655 | spin_unlock_irqrestore(lock: &cdev->spinlock, flags); |
656 | check_for_elapsed_periods(cdev, subs: cdev->sub_playback); |
657 | check_for_elapsed_periods(cdev, subs: cdev->sub_capture); |
658 | send_it = 1; |
659 | } |
660 | |
661 | outframe++; |
662 | } |
663 | |
664 | if (send_it) { |
665 | out->number_of_packets = outframe; |
666 | usb_submit_urb(urb: out, GFP_ATOMIC); |
667 | } else { |
668 | struct snd_usb_caiaq_cb_info *oinfo = out->context; |
669 | clear_bit(nr: oinfo->index, addr: &cdev->outurb_active_mask); |
670 | } |
671 | |
672 | requeue: |
673 | /* re-submit inbound urb */ |
674 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
675 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; |
676 | urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; |
677 | urb->iso_frame_desc[frame].actual_length = 0; |
678 | } |
679 | |
680 | urb->number_of_packets = FRAMES_PER_URB; |
681 | usb_submit_urb(urb, GFP_ATOMIC); |
682 | } |
683 | |
684 | static void write_completed(struct urb *urb) |
685 | { |
686 | struct snd_usb_caiaq_cb_info *info = urb->context; |
687 | struct snd_usb_caiaqdev *cdev = info->cdev; |
688 | |
689 | if (!cdev->output_running) { |
690 | cdev->output_running = 1; |
691 | wake_up(&cdev->prepare_wait_queue); |
692 | } |
693 | |
694 | clear_bit(nr: info->index, addr: &cdev->outurb_active_mask); |
695 | } |
696 | |
697 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) |
698 | { |
699 | int i, frame; |
700 | struct urb **urbs; |
701 | struct usb_device *usb_dev = cdev->chip.dev; |
702 | unsigned int pipe; |
703 | |
704 | pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? |
705 | usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : |
706 | usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); |
707 | |
708 | urbs = kmalloc_array(N_URBS, size: sizeof(*urbs), GFP_KERNEL); |
709 | if (!urbs) { |
710 | *ret = -ENOMEM; |
711 | return NULL; |
712 | } |
713 | |
714 | for (i = 0; i < N_URBS; i++) { |
715 | urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); |
716 | if (!urbs[i]) { |
717 | *ret = -ENOMEM; |
718 | return urbs; |
719 | } |
720 | |
721 | urbs[i]->transfer_buffer = |
722 | kmalloc_array(BYTES_PER_FRAME, FRAMES_PER_URB, |
723 | GFP_KERNEL); |
724 | if (!urbs[i]->transfer_buffer) { |
725 | *ret = -ENOMEM; |
726 | return urbs; |
727 | } |
728 | |
729 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
730 | struct usb_iso_packet_descriptor *iso = |
731 | &urbs[i]->iso_frame_desc[frame]; |
732 | |
733 | iso->offset = BYTES_PER_FRAME * frame; |
734 | iso->length = BYTES_PER_FRAME; |
735 | } |
736 | |
737 | urbs[i]->dev = usb_dev; |
738 | urbs[i]->pipe = pipe; |
739 | urbs[i]->transfer_buffer_length = FRAMES_PER_URB |
740 | * BYTES_PER_FRAME; |
741 | urbs[i]->context = &cdev->data_cb_info[i]; |
742 | urbs[i]->interval = 1; |
743 | urbs[i]->number_of_packets = FRAMES_PER_URB; |
744 | urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? |
745 | read_completed : write_completed; |
746 | } |
747 | |
748 | *ret = 0; |
749 | return urbs; |
750 | } |
751 | |
752 | static void free_urbs(struct urb **urbs) |
753 | { |
754 | int i; |
755 | |
756 | if (!urbs) |
757 | return; |
758 | |
759 | for (i = 0; i < N_URBS; i++) { |
760 | if (!urbs[i]) |
761 | continue; |
762 | |
763 | usb_kill_urb(urb: urbs[i]); |
764 | kfree(objp: urbs[i]->transfer_buffer); |
765 | usb_free_urb(urb: urbs[i]); |
766 | } |
767 | |
768 | kfree(objp: urbs); |
769 | } |
770 | |
771 | int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) |
772 | { |
773 | int i, ret; |
774 | struct device *dev = caiaqdev_to_dev(cdev); |
775 | |
776 | cdev->n_audio_in = max(cdev->spec.num_analog_audio_in, |
777 | cdev->spec.num_digital_audio_in) / |
778 | CHANNELS_PER_STREAM; |
779 | cdev->n_audio_out = max(cdev->spec.num_analog_audio_out, |
780 | cdev->spec.num_digital_audio_out) / |
781 | CHANNELS_PER_STREAM; |
782 | cdev->n_streams = max(cdev->n_audio_in, cdev->n_audio_out); |
783 | |
784 | dev_dbg(dev, "cdev->n_audio_in = %d\n" , cdev->n_audio_in); |
785 | dev_dbg(dev, "cdev->n_audio_out = %d\n" , cdev->n_audio_out); |
786 | dev_dbg(dev, "cdev->n_streams = %d\n" , cdev->n_streams); |
787 | |
788 | if (cdev->n_streams > MAX_STREAMS) { |
789 | dev_err(dev, "unable to initialize device, too many streams.\n" ); |
790 | return -EINVAL; |
791 | } |
792 | |
793 | if (cdev->n_streams < 1) { |
794 | dev_err(dev, "bogus number of streams: %d\n" , cdev->n_streams); |
795 | return -EINVAL; |
796 | } |
797 | |
798 | ret = snd_pcm_new(card: cdev->chip.card, id: cdev->product_name, device: 0, |
799 | playback_count: cdev->n_audio_out, capture_count: cdev->n_audio_in, rpcm: &cdev->pcm); |
800 | |
801 | if (ret < 0) { |
802 | dev_err(dev, "snd_pcm_new() returned %d\n" , ret); |
803 | return ret; |
804 | } |
805 | |
806 | cdev->pcm->private_data = cdev; |
807 | strscpy(cdev->pcm->name, cdev->product_name, sizeof(cdev->pcm->name)); |
808 | |
809 | memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback)); |
810 | memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture)); |
811 | |
812 | memcpy(&cdev->pcm_info, &snd_usb_caiaq_pcm_hardware, |
813 | sizeof(snd_usb_caiaq_pcm_hardware)); |
814 | |
815 | /* setup samplerates */ |
816 | cdev->samplerates = cdev->pcm_info.rates; |
817 | switch (cdev->chip.usb_id) { |
818 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
819 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
820 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): |
821 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE): |
822 | cdev->samplerates |= SNDRV_PCM_RATE_192000; |
823 | fallthrough; |
824 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ): |
825 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): |
826 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
827 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2): |
828 | cdev->samplerates |= SNDRV_PCM_RATE_88200; |
829 | break; |
830 | } |
831 | |
832 | snd_pcm_set_ops(pcm: cdev->pcm, direction: SNDRV_PCM_STREAM_PLAYBACK, |
833 | ops: &snd_usb_caiaq_ops); |
834 | snd_pcm_set_ops(pcm: cdev->pcm, direction: SNDRV_PCM_STREAM_CAPTURE, |
835 | ops: &snd_usb_caiaq_ops); |
836 | snd_pcm_set_managed_buffer_all(pcm: cdev->pcm, SNDRV_DMA_TYPE_VMALLOC, |
837 | NULL, size: 0, max: 0); |
838 | |
839 | cdev->data_cb_info = |
840 | kmalloc_array(N_URBS, size: sizeof(struct snd_usb_caiaq_cb_info), |
841 | GFP_KERNEL); |
842 | |
843 | if (!cdev->data_cb_info) |
844 | return -ENOMEM; |
845 | |
846 | cdev->outurb_active_mask = 0; |
847 | BUILD_BUG_ON(N_URBS > (sizeof(cdev->outurb_active_mask) * 8)); |
848 | |
849 | for (i = 0; i < N_URBS; i++) { |
850 | cdev->data_cb_info[i].cdev = cdev; |
851 | cdev->data_cb_info[i].index = i; |
852 | } |
853 | |
854 | cdev->data_urbs_in = alloc_urbs(cdev, dir: SNDRV_PCM_STREAM_CAPTURE, ret: &ret); |
855 | if (ret < 0) { |
856 | kfree(objp: cdev->data_cb_info); |
857 | free_urbs(urbs: cdev->data_urbs_in); |
858 | return ret; |
859 | } |
860 | |
861 | cdev->data_urbs_out = alloc_urbs(cdev, dir: SNDRV_PCM_STREAM_PLAYBACK, ret: &ret); |
862 | if (ret < 0) { |
863 | kfree(objp: cdev->data_cb_info); |
864 | free_urbs(urbs: cdev->data_urbs_in); |
865 | free_urbs(urbs: cdev->data_urbs_out); |
866 | return ret; |
867 | } |
868 | |
869 | return 0; |
870 | } |
871 | |
872 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev) |
873 | { |
874 | struct device *dev = caiaqdev_to_dev(cdev); |
875 | |
876 | dev_dbg(dev, "%s(%p)\n" , __func__, cdev); |
877 | stream_stop(cdev); |
878 | free_urbs(urbs: cdev->data_urbs_in); |
879 | free_urbs(urbs: cdev->data_urbs_out); |
880 | kfree(objp: cdev->data_cb_info); |
881 | } |
882 | |
883 | |