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