Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * u_audio.c -- interface to USB gadget "ALSA sound card" utilities
4 *
5 * Copyright (C) 2016
6 * Author: Ruslan Bilovol <ruslan.bilovol@gmail.com>
7 *
8 * Sound card implementation was cut-and-pasted with changes
9 * from f_uac2.c and has:
10 * Copyright (C) 2011
11 * Yadwinder Singh (yadi.brar01@gmail.com)
12 * Jaswinder Singh (jaswinder.singh@linaro.org)
13 */
14
15#include <linux/module.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19
20#include "u_audio.h"
21
22#define BUFF_SIZE_MAX (PAGE_SIZE * 16)
23#define PRD_SIZE_MAX PAGE_SIZE
24#define MIN_PERIODS 4
25
26/* Runtime data params for one stream */
27struct uac_rtd_params {
28 struct snd_uac_chip *uac; /* parent chip */
29 bool ep_enabled; /* if the ep is enabled */
30
31 struct snd_pcm_substream *ss;
32
33 /* Ring buffer */
34 ssize_t hw_ptr;
35
36 void *rbuf;
37
38 unsigned int max_psize; /* MaxPacketSize of endpoint */
39
40 struct usb_request **reqs;
41};
42
43struct snd_uac_chip {
44 struct g_audio *audio_dev;
45
46 struct uac_rtd_params p_prm;
47 struct uac_rtd_params c_prm;
48
49 struct snd_card *card;
50 struct snd_pcm *pcm;
51
52 /* timekeeping for the playback endpoint */
53 unsigned int p_interval;
54 unsigned int p_residue;
55
56 /* pre-calculated values for playback iso completion */
57 unsigned int p_pktsize;
58 unsigned int p_pktsize_residue;
59 unsigned int p_framesize;
60};
61
62static const struct snd_pcm_hardware uac_pcm_hardware = {
63 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
64 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
65 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
66 .rates = SNDRV_PCM_RATE_CONTINUOUS,
67 .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
68 .buffer_bytes_max = BUFF_SIZE_MAX,
69 .period_bytes_max = PRD_SIZE_MAX,
70 .periods_min = MIN_PERIODS,
71};
72
73static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
74{
75 unsigned int pending;
76 unsigned int hw_ptr;
77 int status = req->status;
78 struct snd_pcm_substream *substream;
79 struct snd_pcm_runtime *runtime;
80 struct uac_rtd_params *prm = req->context;
81 struct snd_uac_chip *uac = prm->uac;
82
83 /* i/f shutting down */
84 if (!prm->ep_enabled) {
85 usb_ep_free_request(ep, req);
86 return;
87 }
88
89 if (req->status == -ESHUTDOWN)
90 return;
91
92 /*
93 * We can't really do much about bad xfers.
94 * Afterall, the ISOCH xfers could fail legitimately.
95 */
96 if (status)
97 pr_debug("%s: iso_complete status(%d) %d/%d\n",
98 __func__, status, req->actual, req->length);
99
100 substream = prm->ss;
101
102 /* Do nothing if ALSA isn't active */
103 if (!substream)
104 goto exit;
105
106 snd_pcm_stream_lock(substream);
107
108 runtime = substream->runtime;
109 if (!runtime || !snd_pcm_running(substream)) {
110 snd_pcm_stream_unlock(substream);
111 goto exit;
112 }
113
114 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
115 /*
116 * For each IN packet, take the quotient of the current data
117 * rate and the endpoint's interval as the base packet size.
118 * If there is a residue from this division, add it to the
119 * residue accumulator.
120 */
121 req->length = uac->p_pktsize;
122 uac->p_residue += uac->p_pktsize_residue;
123
124 /*
125 * Whenever there are more bytes in the accumulator than we
126 * need to add one more sample frame, increase this packet's
127 * size and decrease the accumulator.
128 */
129 if (uac->p_residue / uac->p_interval >= uac->p_framesize) {
130 req->length += uac->p_framesize;
131 uac->p_residue -= uac->p_framesize *
132 uac->p_interval;
133 }
134
135 req->actual = req->length;
136 }
137
138 hw_ptr = prm->hw_ptr;
139
140 /* Pack USB load in ALSA ring buffer */
141 pending = runtime->dma_bytes - hw_ptr;
142
143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
144 if (unlikely(pending < req->actual)) {
145 memcpy(req->buf, runtime->dma_area + hw_ptr, pending);
146 memcpy(req->buf + pending, runtime->dma_area,
147 req->actual - pending);
148 } else {
149 memcpy(req->buf, runtime->dma_area + hw_ptr,
150 req->actual);
151 }
152 } else {
153 if (unlikely(pending < req->actual)) {
154 memcpy(runtime->dma_area + hw_ptr, req->buf, pending);
155 memcpy(runtime->dma_area, req->buf + pending,
156 req->actual - pending);
157 } else {
158 memcpy(runtime->dma_area + hw_ptr, req->buf,
159 req->actual);
160 }
161 }
162
163 /* update hw_ptr after data is copied to memory */
164 prm->hw_ptr = (hw_ptr + req->actual) % runtime->dma_bytes;
165 hw_ptr = prm->hw_ptr;
166 snd_pcm_stream_unlock(substream);
167
168 if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual)
169 snd_pcm_period_elapsed(substream);
170
171exit:
172 if (usb_ep_queue(ep, req, GFP_ATOMIC))
173 dev_err(uac->card->dev, "%d Error!\n", __LINE__);
174}
175
176static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
177{
178 struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
179 struct uac_rtd_params *prm;
180 struct g_audio *audio_dev;
181 struct uac_params *params;
182 int err = 0;
183
184 audio_dev = uac->audio_dev;
185 params = &audio_dev->params;
186
187 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
188 prm = &uac->p_prm;
189 else
190 prm = &uac->c_prm;
191
192 /* Reset */
193 prm->hw_ptr = 0;
194
195 switch (cmd) {
196 case SNDRV_PCM_TRIGGER_START:
197 case SNDRV_PCM_TRIGGER_RESUME:
198 prm->ss = substream;
199 break;
200 case SNDRV_PCM_TRIGGER_STOP:
201 case SNDRV_PCM_TRIGGER_SUSPEND:
202 prm->ss = NULL;
203 break;
204 default:
205 err = -EINVAL;
206 }
207
208 /* Clear buffer after Play stops */
209 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss)
210 memset(prm->rbuf, 0, prm->max_psize * params->req_number);
211
212 return err;
213}
214
215static snd_pcm_uframes_t uac_pcm_pointer(struct snd_pcm_substream *substream)
216{
217 struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
218 struct uac_rtd_params *prm;
219
220 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
221 prm = &uac->p_prm;
222 else
223 prm = &uac->c_prm;
224
225 return bytes_to_frames(substream->runtime, prm->hw_ptr);
226}
227
228static u64 uac_ssize_to_fmt(int ssize)
229{
230 u64 ret;
231
232 switch (ssize) {
233 case 3:
234 ret = SNDRV_PCM_FMTBIT_S24_3LE;
235 break;
236 case 4:
237 ret = SNDRV_PCM_FMTBIT_S32_LE;
238 break;
239 default:
240 ret = SNDRV_PCM_FMTBIT_S16_LE;
241 break;
242 }
243
244 return ret;
245}
246
247static int uac_pcm_open(struct snd_pcm_substream *substream)
248{
249 struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
250 struct snd_pcm_runtime *runtime = substream->runtime;
251 struct g_audio *audio_dev;
252 struct uac_params *params;
253 int p_ssize, c_ssize;
254 int p_srate, c_srate;
255 int p_chmask, c_chmask;
256
257 audio_dev = uac->audio_dev;
258 params = &audio_dev->params;
259 p_ssize = params->p_ssize;
260 c_ssize = params->c_ssize;
261 p_srate = params->p_srate;
262 c_srate = params->c_srate;
263 p_chmask = params->p_chmask;
264 c_chmask = params->c_chmask;
265 uac->p_residue = 0;
266
267 runtime->hw = uac_pcm_hardware;
268
269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
270 runtime->hw.rate_min = p_srate;
271 runtime->hw.formats = uac_ssize_to_fmt(p_ssize);
272 runtime->hw.channels_min = num_channels(p_chmask);
273 runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize
274 / runtime->hw.periods_min;
275 } else {
276 runtime->hw.rate_min = c_srate;
277 runtime->hw.formats = uac_ssize_to_fmt(c_ssize);
278 runtime->hw.channels_min = num_channels(c_chmask);
279 runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize
280 / runtime->hw.periods_min;
281 }
282
283 runtime->hw.rate_max = runtime->hw.rate_min;
284 runtime->hw.channels_max = runtime->hw.channels_min;
285
286 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
287
288 return 0;
289}
290
291/* ALSA cries without these function pointers */
292static int uac_pcm_null(struct snd_pcm_substream *substream)
293{
294 return 0;
295}
296
297static const struct snd_pcm_ops uac_pcm_ops = {
298 .open = uac_pcm_open,
299 .close = uac_pcm_null,
300 .trigger = uac_pcm_trigger,
301 .pointer = uac_pcm_pointer,
302 .prepare = uac_pcm_null,
303};
304
305static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep)
306{
307 struct snd_uac_chip *uac = prm->uac;
308 struct g_audio *audio_dev;
309 struct uac_params *params;
310 int i;
311
312 if (!prm->ep_enabled)
313 return;
314
315 prm->ep_enabled = false;
316
317 audio_dev = uac->audio_dev;
318 params = &audio_dev->params;
319
320 for (i = 0; i < params->req_number; i++) {
321 if (prm->reqs[i]) {
322 if (usb_ep_dequeue(ep, prm->reqs[i]))
323 usb_ep_free_request(ep, prm->reqs[i]);
324 /*
325 * If usb_ep_dequeue() cannot successfully dequeue the
326 * request, the request will be freed by the completion
327 * callback.
328 */
329
330 prm->reqs[i] = NULL;
331 }
332 }
333
334 if (usb_ep_disable(ep))
335 dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
336}
337
338
339int u_audio_start_capture(struct g_audio *audio_dev)
340{
341 struct snd_uac_chip *uac = audio_dev->uac;
342 struct usb_gadget *gadget = audio_dev->gadget;
343 struct device *dev = &gadget->dev;
344 struct usb_request *req;
345 struct usb_ep *ep;
346 struct uac_rtd_params *prm;
347 struct uac_params *params = &audio_dev->params;
348 int req_len, i;
349
350 ep = audio_dev->out_ep;
351 prm = &uac->c_prm;
352 config_ep_by_speed(gadget, &audio_dev->func, ep);
353 req_len = ep->maxpacket;
354
355 prm->ep_enabled = true;
356 usb_ep_enable(ep);
357
358 for (i = 0; i < params->req_number; i++) {
359 if (!prm->reqs[i]) {
360 req = usb_ep_alloc_request(ep, GFP_ATOMIC);
361 if (req == NULL)
362 return -ENOMEM;
363
364 prm->reqs[i] = req;
365
366 req->zero = 0;
367 req->context = prm;
368 req->length = req_len;
369 req->complete = u_audio_iso_complete;
370 req->buf = prm->rbuf + i * ep->maxpacket;
371 }
372
373 if (usb_ep_queue(ep, prm->reqs[i], GFP_ATOMIC))
374 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
375 }
376
377 return 0;
378}
379EXPORT_SYMBOL_GPL(u_audio_start_capture);
380
381void u_audio_stop_capture(struct g_audio *audio_dev)
382{
383 struct snd_uac_chip *uac = audio_dev->uac;
384
385 free_ep(&uac->c_prm, audio_dev->out_ep);
386}
387EXPORT_SYMBOL_GPL(u_audio_stop_capture);
388
389int u_audio_start_playback(struct g_audio *audio_dev)
390{
391 struct snd_uac_chip *uac = audio_dev->uac;
392 struct usb_gadget *gadget = audio_dev->gadget;
393 struct device *dev = &gadget->dev;
394 struct usb_request *req;
395 struct usb_ep *ep;
396 struct uac_rtd_params *prm;
397 struct uac_params *params = &audio_dev->params;
398 unsigned int factor;
399 const struct usb_endpoint_descriptor *ep_desc;
400 int req_len, i;
401
402 ep = audio_dev->in_ep;
403 prm = &uac->p_prm;
404 config_ep_by_speed(gadget, &audio_dev->func, ep);
405
406 ep_desc = ep->desc;
407
408 /* pre-calculate the playback endpoint's interval */
409 if (gadget->speed == USB_SPEED_FULL)
410 factor = 1000;
411 else
412 factor = 8000;
413
414 /* pre-compute some values for iso_complete() */
415 uac->p_framesize = params->p_ssize *
416 num_channels(params->p_chmask);
417 uac->p_interval = factor / (1 << (ep_desc->bInterval - 1));
418 uac->p_pktsize = min_t(unsigned int,
419 uac->p_framesize *
420 (params->p_srate / uac->p_interval),
421 ep->maxpacket);
422
423 if (uac->p_pktsize < ep->maxpacket)
424 uac->p_pktsize_residue = uac->p_framesize *
425 (params->p_srate % uac->p_interval);
426 else
427 uac->p_pktsize_residue = 0;
428
429 req_len = uac->p_pktsize;
430 uac->p_residue = 0;
431
432 prm->ep_enabled = true;
433 usb_ep_enable(ep);
434
435 for (i = 0; i < params->req_number; i++) {
436 if (!prm->reqs[i]) {
437 req = usb_ep_alloc_request(ep, GFP_ATOMIC);
438 if (req == NULL)
439 return -ENOMEM;
440
441 prm->reqs[i] = req;
442
443 req->zero = 0;
444 req->context = prm;
445 req->length = req_len;
446 req->complete = u_audio_iso_complete;
447 req->buf = prm->rbuf + i * ep->maxpacket;
448 }
449
450 if (usb_ep_queue(ep, prm->reqs[i], GFP_ATOMIC))
451 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
452 }
453
454 return 0;
455}
456EXPORT_SYMBOL_GPL(u_audio_start_playback);
457
458void u_audio_stop_playback(struct g_audio *audio_dev)
459{
460 struct snd_uac_chip *uac = audio_dev->uac;
461
462 free_ep(&uac->p_prm, audio_dev->in_ep);
463}
464EXPORT_SYMBOL_GPL(u_audio_stop_playback);
465
466int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
467 const char *card_name)
468{
469 struct snd_uac_chip *uac;
470 struct snd_card *card;
471 struct snd_pcm *pcm;
472 struct uac_params *params;
473 int p_chmask, c_chmask;
474 int err;
475
476 if (!g_audio)
477 return -EINVAL;
478
479 uac = kzalloc(sizeof(*uac), GFP_KERNEL);
480 if (!uac)
481 return -ENOMEM;
482 g_audio->uac = uac;
483 uac->audio_dev = g_audio;
484
485 params = &g_audio->params;
486 p_chmask = params->p_chmask;
487 c_chmask = params->c_chmask;
488
489 if (c_chmask) {
490 struct uac_rtd_params *prm = &uac->c_prm;
491
492 uac->c_prm.uac = uac;
493 prm->max_psize = g_audio->out_ep_maxpsize;
494
495 prm->reqs = kcalloc(params->req_number,
496 sizeof(struct usb_request *),
497 GFP_KERNEL);
498 if (!prm->reqs) {
499 err = -ENOMEM;
500 goto fail;
501 }
502
503 prm->rbuf = kcalloc(params->req_number, prm->max_psize,
504 GFP_KERNEL);
505 if (!prm->rbuf) {
506 prm->max_psize = 0;
507 err = -ENOMEM;
508 goto fail;
509 }
510 }
511
512 if (p_chmask) {
513 struct uac_rtd_params *prm = &uac->p_prm;
514
515 uac->p_prm.uac = uac;
516 prm->max_psize = g_audio->in_ep_maxpsize;
517
518 prm->reqs = kcalloc(params->req_number,
519 sizeof(struct usb_request *),
520 GFP_KERNEL);
521 if (!prm->reqs) {
522 err = -ENOMEM;
523 goto fail;
524 }
525
526 prm->rbuf = kcalloc(params->req_number, prm->max_psize,
527 GFP_KERNEL);
528 if (!prm->rbuf) {
529 prm->max_psize = 0;
530 err = -ENOMEM;
531 goto fail;
532 }
533 }
534
535 /* Choose any slot, with no id */
536 err = snd_card_new(&g_audio->gadget->dev,
537 -1, NULL, THIS_MODULE, 0, &card);
538 if (err < 0)
539 goto fail;
540
541 uac->card = card;
542
543 /*
544 * Create first PCM device
545 * Create a substream only for non-zero channel streams
546 */
547 err = snd_pcm_new(uac->card, pcm_name, 0,
548 p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm);
549 if (err < 0)
550 goto snd_fail;
551
552 strscpy(pcm->name, pcm_name, sizeof(pcm->name));
553 pcm->private_data = uac;
554 uac->pcm = pcm;
555
556 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops);
557 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops);
558
559 strscpy(card->driver, card_name, sizeof(card->driver));
560 strscpy(card->shortname, card_name, sizeof(card->shortname));
561 sprintf(card->longname, "%s %i", card_name, card->dev->id);
562
563 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
564 NULL, 0, BUFF_SIZE_MAX);
565
566 err = snd_card_register(card);
567
568 if (!err)
569 return 0;
570
571snd_fail:
572 snd_card_free(card);
573fail:
574 kfree(uac->p_prm.reqs);
575 kfree(uac->c_prm.reqs);
576 kfree(uac->p_prm.rbuf);
577 kfree(uac->c_prm.rbuf);
578 kfree(uac);
579
580 return err;
581}
582EXPORT_SYMBOL_GPL(g_audio_setup);
583
584void g_audio_cleanup(struct g_audio *g_audio)
585{
586 struct snd_uac_chip *uac;
587 struct snd_card *card;
588
589 if (!g_audio || !g_audio->uac)
590 return;
591
592 uac = g_audio->uac;
593 card = uac->card;
594 if (card)
595 snd_card_free(card);
596
597 kfree(uac->p_prm.reqs);
598 kfree(uac->c_prm.reqs);
599 kfree(uac->p_prm.rbuf);
600 kfree(uac->c_prm.rbuf);
601 kfree(uac);
602}
603EXPORT_SYMBOL_GPL(g_audio_cleanup);
604
605MODULE_LICENSE("GPL");
606MODULE_DESCRIPTION("USB gadget \"ALSA sound card\" utilities");
607MODULE_AUTHOR("Ruslan Bilovol");