blob: 5a7ba058d9477417bc64edacf32c0a232bbec306 [file] [log] [blame]
Jassi Brar132fcb42012-02-02 22:01:34 +05301/*
2 * f_uac2.c -- USB Audio Class 2.0 Function
3 *
4 * Copyright (C) 2011
5 * Yadwinder Singh (yadi.brar01@gmail.com)
6 * Jaswinder Singh (jaswinder.singh@linaro.org)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/usb/audio.h>
15#include <linux/usb/audio-v2.h>
16#include <linux/platform_device.h>
17#include <linux/module.h>
18
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +020023#include "u_uac2.h"
24
Jassi Brar132fcb42012-02-02 22:01:34 +053025/*
26 * The driver implements a simple UAC_2 topology.
27 * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
28 * ALSA_Playback -> IT_2 -> OT_4 -> USB-IN
29 * Capture and Playback sampling rates are independently
30 * controlled by two clock sources :
31 * CLK_5 := c_srate, and CLK_6 := p_srate
32 */
33#define USB_OUT_IT_ID 1
34#define IO_IN_IT_ID 2
35#define IO_OUT_OT_ID 3
36#define USB_IN_OT_ID 4
37#define USB_OUT_CLK_ID 5
38#define USB_IN_CLK_ID 6
39
40#define CONTROL_ABSENT 0
41#define CONTROL_RDONLY 1
42#define CONTROL_RDWR 3
43
44#define CLK_FREQ_CTRL 0
45#define CLK_VLD_CTRL 2
46
47#define COPY_CTRL 0
48#define CONN_CTRL 2
49#define OVRLD_CTRL 4
50#define CLSTR_CTRL 6
51#define UNFLW_CTRL 8
52#define OVFLW_CTRL 10
53
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +000054static const char *uac2_name = "snd_uac2";
Jassi Brar132fcb42012-02-02 22:01:34 +053055
56struct uac2_req {
57 struct uac2_rtd_params *pp; /* parent param */
58 struct usb_request *req;
59};
60
61struct uac2_rtd_params {
Jassi Brareb127cb2013-05-30 18:23:33 +053062 struct snd_uac2_chip *uac2; /* parent chip */
Jassi Brar132fcb42012-02-02 22:01:34 +053063 bool ep_enabled; /* if the ep is enabled */
64 /* Size of the ring buffer */
65 size_t dma_bytes;
66 unsigned char *dma_area;
67
68 struct snd_pcm_substream *ss;
69
70 /* Ring buffer */
71 ssize_t hw_ptr;
72
73 void *rbuf;
74
75 size_t period_size;
76
77 unsigned max_psize;
Peter Chene92b9d42017-01-04 10:19:23 +080078 struct uac2_req *ureq;
Jassi Brar132fcb42012-02-02 22:01:34 +053079
80 spinlock_t lock;
81};
82
83struct snd_uac2_chip {
84 struct platform_device pdev;
85 struct platform_driver pdrv;
86
87 struct uac2_rtd_params p_prm;
88 struct uac2_rtd_params c_prm;
89
90 struct snd_card *card;
91 struct snd_pcm *pcm;
Daniel Mack9bb87f12014-08-27 19:09:07 +020092
93 /* timekeeping for the playback endpoint */
94 unsigned int p_interval;
95 unsigned int p_residue;
96
97 /* pre-calculated values for playback iso completion */
98 unsigned int p_pktsize;
99 unsigned int p_pktsize_residue;
100 unsigned int p_framesize;
Jassi Brar132fcb42012-02-02 22:01:34 +0530101};
102
103#define BUFF_SIZE_MAX (PAGE_SIZE * 16)
104#define PRD_SIZE_MAX PAGE_SIZE
105#define MIN_PERIODS 4
106
107static struct snd_pcm_hardware uac2_pcm_hardware = {
108 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
109 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
110 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
111 .rates = SNDRV_PCM_RATE_CONTINUOUS,
112 .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
113 .buffer_bytes_max = BUFF_SIZE_MAX,
114 .period_bytes_max = PRD_SIZE_MAX,
115 .periods_min = MIN_PERIODS,
116};
117
118struct audio_dev {
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +0200119 u8 ac_intf, ac_alt;
120 u8 as_out_intf, as_out_alt;
121 u8 as_in_intf, as_in_alt;
Jassi Brar132fcb42012-02-02 22:01:34 +0530122
123 struct usb_ep *in_ep, *out_ep;
124 struct usb_function func;
125
126 /* The ALSA Sound Card it represents on the USB-Client side */
127 struct snd_uac2_chip uac2;
128};
129
Jassi Brar132fcb42012-02-02 22:01:34 +0530130static inline
131struct audio_dev *func_to_agdev(struct usb_function *f)
132{
133 return container_of(f, struct audio_dev, func);
134}
135
136static inline
137struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u)
138{
139 return container_of(u, struct audio_dev, uac2);
140}
141
142static inline
143struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p)
144{
145 return container_of(p, struct snd_uac2_chip, pdev);
146}
147
148static inline
Daniel Mack254b3bf2014-08-27 19:09:05 +0200149struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev)
150{
151 return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
152}
153
154static inline
Jassi Brar132fcb42012-02-02 22:01:34 +0530155uint num_channels(uint chanmask)
156{
157 uint num = 0;
158
159 while (chanmask) {
160 num += (chanmask & 1);
161 chanmask >>= 1;
162 }
163
164 return num;
165}
166
167static void
168agdev_iso_complete(struct usb_ep *ep, struct usb_request *req)
169{
170 unsigned pending;
171 unsigned long flags;
Daniel Mackec9e4312014-08-27 19:09:06 +0200172 unsigned int hw_ptr;
Jassi Brar132fcb42012-02-02 22:01:34 +0530173 bool update_alsa = false;
Jassi Brar132fcb42012-02-02 22:01:34 +0530174 int status = req->status;
175 struct uac2_req *ur = req->context;
176 struct snd_pcm_substream *substream;
177 struct uac2_rtd_params *prm = ur->pp;
Jassi Brareb127cb2013-05-30 18:23:33 +0530178 struct snd_uac2_chip *uac2 = prm->uac2;
Jassi Brar132fcb42012-02-02 22:01:34 +0530179
180 /* i/f shutting down */
Andrzej Pietrasiewicz1ade5d72014-05-15 13:43:50 +0200181 if (!prm->ep_enabled || req->status == -ESHUTDOWN)
Jassi Brar132fcb42012-02-02 22:01:34 +0530182 return;
183
184 /*
185 * We can't really do much about bad xfers.
186 * Afterall, the ISOCH xfers could fail legitimately.
187 */
188 if (status)
189 pr_debug("%s: iso_complete status(%d) %d/%d\n",
190 __func__, status, req->actual, req->length);
191
192 substream = prm->ss;
193
194 /* Do nothing if ALSA isn't active */
195 if (!substream)
196 goto exit;
197
198 spin_lock_irqsave(&prm->lock, flags);
199
Daniel Mack9bb87f12014-08-27 19:09:07 +0200200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
201 /*
202 * For each IN packet, take the quotient of the current data
203 * rate and the endpoint's interval as the base packet size.
204 * If there is a residue from this division, add it to the
205 * residue accumulator.
206 */
207 req->length = uac2->p_pktsize;
208 uac2->p_residue += uac2->p_pktsize_residue;
209
210 /*
211 * Whenever there are more bytes in the accumulator than we
212 * need to add one more sample frame, increase this packet's
213 * size and decrease the accumulator.
214 */
215 if (uac2->p_residue / uac2->p_interval >= uac2->p_framesize) {
216 req->length += uac2->p_framesize;
217 uac2->p_residue -= uac2->p_framesize *
218 uac2->p_interval;
219 }
220
Jassi Brar132fcb42012-02-02 22:01:34 +0530221 req->actual = req->length;
Daniel Mack9bb87f12014-08-27 19:09:07 +0200222 }
Jassi Brar132fcb42012-02-02 22:01:34 +0530223
224 pending = prm->hw_ptr % prm->period_size;
225 pending += req->actual;
226 if (pending >= prm->period_size)
227 update_alsa = true;
228
Daniel Mackec9e4312014-08-27 19:09:06 +0200229 hw_ptr = prm->hw_ptr;
Jassi Brar132fcb42012-02-02 22:01:34 +0530230 prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes;
231
232 spin_unlock_irqrestore(&prm->lock, flags);
233
234 /* Pack USB load in ALSA ring buffer */
Daniel Mackec9e4312014-08-27 19:09:06 +0200235 pending = prm->dma_bytes - hw_ptr;
236
237 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
238 if (unlikely(pending < req->actual)) {
239 memcpy(req->buf, prm->dma_area + hw_ptr, pending);
240 memcpy(req->buf + pending, prm->dma_area,
241 req->actual - pending);
242 } else {
243 memcpy(req->buf, prm->dma_area + hw_ptr, req->actual);
244 }
245 } else {
246 if (unlikely(pending < req->actual)) {
247 memcpy(prm->dma_area + hw_ptr, req->buf, pending);
248 memcpy(prm->dma_area, req->buf + pending,
249 req->actual - pending);
250 } else {
251 memcpy(prm->dma_area + hw_ptr, req->buf, req->actual);
252 }
253 }
254
Jassi Brar132fcb42012-02-02 22:01:34 +0530255exit:
256 if (usb_ep_queue(ep, req, GFP_ATOMIC))
257 dev_err(&uac2->pdev.dev, "%d Error!\n", __LINE__);
258
259 if (update_alsa)
260 snd_pcm_period_elapsed(substream);
261
262 return;
263}
264
265static int
266uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
267{
268 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
Peter Chene92b9d42017-01-04 10:19:23 +0800269 struct audio_dev *agdev = uac2_to_agdev(uac2);
270 struct f_uac2_opts *uac2_opts = agdev_to_uac2_opts(agdev);
Jassi Brar132fcb42012-02-02 22:01:34 +0530271 struct uac2_rtd_params *prm;
272 unsigned long flags;
Jassi Brar132fcb42012-02-02 22:01:34 +0530273 int err = 0;
274
Wei Yongjunb6424352012-12-02 05:33:08 -0500275 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
Jassi Brar132fcb42012-02-02 22:01:34 +0530276 prm = &uac2->p_prm;
Wei Yongjunb6424352012-12-02 05:33:08 -0500277 else
Jassi Brar132fcb42012-02-02 22:01:34 +0530278 prm = &uac2->c_prm;
Jassi Brar132fcb42012-02-02 22:01:34 +0530279
280 spin_lock_irqsave(&prm->lock, flags);
281
282 /* Reset */
283 prm->hw_ptr = 0;
284
285 switch (cmd) {
286 case SNDRV_PCM_TRIGGER_START:
287 case SNDRV_PCM_TRIGGER_RESUME:
288 prm->ss = substream;
289 break;
290 case SNDRV_PCM_TRIGGER_STOP:
291 case SNDRV_PCM_TRIGGER_SUSPEND:
292 prm->ss = NULL;
293 break;
294 default:
295 err = -EINVAL;
296 }
297
298 spin_unlock_irqrestore(&prm->lock, flags);
299
300 /* Clear buffer after Play stops */
301 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss)
Peter Chene92b9d42017-01-04 10:19:23 +0800302 memset(prm->rbuf, 0, prm->max_psize * uac2_opts->req_number);
Jassi Brar132fcb42012-02-02 22:01:34 +0530303
304 return err;
305}
306
307static snd_pcm_uframes_t uac2_pcm_pointer(struct snd_pcm_substream *substream)
308{
309 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
310 struct uac2_rtd_params *prm;
311
312 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
313 prm = &uac2->p_prm;
314 else
315 prm = &uac2->c_prm;
316
317 return bytes_to_frames(substream->runtime, prm->hw_ptr);
318}
319
320static int uac2_pcm_hw_params(struct snd_pcm_substream *substream,
321 struct snd_pcm_hw_params *hw_params)
322{
323 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
324 struct uac2_rtd_params *prm;
325 int err;
326
327 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
328 prm = &uac2->p_prm;
329 else
330 prm = &uac2->c_prm;
331
332 err = snd_pcm_lib_malloc_pages(substream,
333 params_buffer_bytes(hw_params));
334 if (err >= 0) {
335 prm->dma_bytes = substream->runtime->dma_bytes;
336 prm->dma_area = substream->runtime->dma_area;
337 prm->period_size = params_period_bytes(hw_params);
338 }
339
340 return err;
341}
342
343static int uac2_pcm_hw_free(struct snd_pcm_substream *substream)
344{
345 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
346 struct uac2_rtd_params *prm;
347
348 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
349 prm = &uac2->p_prm;
350 else
351 prm = &uac2->c_prm;
352
353 prm->dma_area = NULL;
354 prm->dma_bytes = 0;
355 prm->period_size = 0;
356
357 return snd_pcm_lib_free_pages(substream);
358}
359
360static int uac2_pcm_open(struct snd_pcm_substream *substream)
361{
362 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
363 struct snd_pcm_runtime *runtime = substream->runtime;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +0200364 struct audio_dev *audio_dev;
365 struct f_uac2_opts *opts;
366 int p_ssize, c_ssize;
367 int p_srate, c_srate;
368 int p_chmask, c_chmask;
369
370 audio_dev = uac2_to_agdev(uac2);
371 opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
372 p_ssize = opts->p_ssize;
373 c_ssize = opts->c_ssize;
374 p_srate = opts->p_srate;
375 c_srate = opts->c_srate;
376 p_chmask = opts->p_chmask;
377 c_chmask = opts->c_chmask;
Daniel Mack9bb87f12014-08-27 19:09:07 +0200378 uac2->p_residue = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +0530379
380 runtime->hw = uac2_pcm_hardware;
381
382 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
383 spin_lock_init(&uac2->p_prm.lock);
384 runtime->hw.rate_min = p_srate;
Sebastian Reimers55f78402014-07-03 20:15:28 +0200385 switch (p_ssize) {
386 case 3:
387 runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE;
388 break;
389 case 4:
390 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
391 break;
392 default:
393 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
394 break;
395 }
Jassi Brar132fcb42012-02-02 22:01:34 +0530396 runtime->hw.channels_min = num_channels(p_chmask);
397 runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize
398 / runtime->hw.periods_min;
399 } else {
400 spin_lock_init(&uac2->c_prm.lock);
401 runtime->hw.rate_min = c_srate;
Sebastian Reimers55f78402014-07-03 20:15:28 +0200402 switch (c_ssize) {
403 case 3:
404 runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE;
405 break;
406 case 4:
407 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
408 break;
409 default:
410 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
411 break;
412 }
Jassi Brar132fcb42012-02-02 22:01:34 +0530413 runtime->hw.channels_min = num_channels(c_chmask);
414 runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize
415 / runtime->hw.periods_min;
416 }
417
418 runtime->hw.rate_max = runtime->hw.rate_min;
419 runtime->hw.channels_max = runtime->hw.channels_min;
420
421 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
422
423 return 0;
424}
425
426/* ALSA cries without these function pointers */
427static int uac2_pcm_null(struct snd_pcm_substream *substream)
428{
429 return 0;
430}
431
432static struct snd_pcm_ops uac2_pcm_ops = {
433 .open = uac2_pcm_open,
434 .close = uac2_pcm_null,
435 .ioctl = snd_pcm_lib_ioctl,
436 .hw_params = uac2_pcm_hw_params,
437 .hw_free = uac2_pcm_hw_free,
438 .trigger = uac2_pcm_trigger,
439 .pointer = uac2_pcm_pointer,
440 .prepare = uac2_pcm_null,
441};
442
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500443static int snd_uac2_probe(struct platform_device *pdev)
Jassi Brar132fcb42012-02-02 22:01:34 +0530444{
445 struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
446 struct snd_card *card;
447 struct snd_pcm *pcm;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +0200448 struct audio_dev *audio_dev;
449 struct f_uac2_opts *opts;
Jassi Brar132fcb42012-02-02 22:01:34 +0530450 int err;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +0200451 int p_chmask, c_chmask;
452
453 audio_dev = uac2_to_agdev(uac2);
454 opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
455 p_chmask = opts->p_chmask;
456 c_chmask = opts->c_chmask;
Jassi Brar132fcb42012-02-02 22:01:34 +0530457
458 /* Choose any slot, with no id */
Takashi Iwai13345092014-01-29 15:04:31 +0100459 err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card);
Jassi Brar132fcb42012-02-02 22:01:34 +0530460 if (err < 0)
461 return err;
462
463 uac2->card = card;
464
465 /*
466 * Create first PCM device
467 * Create a substream only for non-zero channel streams
468 */
469 err = snd_pcm_new(uac2->card, "UAC2 PCM", 0,
470 p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm);
471 if (err < 0)
472 goto snd_fail;
473
474 strcpy(pcm->name, "UAC2 PCM");
475 pcm->private_data = uac2;
476
477 uac2->pcm = pcm;
478
479 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac2_pcm_ops);
480 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac2_pcm_ops);
481
482 strcpy(card->driver, "UAC2_Gadget");
483 strcpy(card->shortname, "UAC2_Gadget");
484 sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
485
Jassi Brar132fcb42012-02-02 22:01:34 +0530486 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
487 snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
488
489 err = snd_card_register(card);
490 if (!err) {
491 platform_set_drvdata(pdev, card);
492 return 0;
493 }
494
495snd_fail:
496 snd_card_free(card);
497
498 uac2->pcm = NULL;
499 uac2->card = NULL;
500
501 return err;
502}
503
Sebastian Andrzej Siewior1e1a27c2012-09-06 20:11:02 +0200504static int snd_uac2_remove(struct platform_device *pdev)
Jassi Brar132fcb42012-02-02 22:01:34 +0530505{
506 struct snd_card *card = platform_get_drvdata(pdev);
507
Jassi Brar132fcb42012-02-02 22:01:34 +0530508 if (card)
509 return snd_card_free(card);
510
511 return 0;
512}
513
Felipe Balbide1e6e72014-09-29 14:24:09 -0500514static void snd_uac2_release(struct device *dev)
515{
516 dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
517}
518
Jassi Brar132fcb42012-02-02 22:01:34 +0530519static int alsa_uac2_init(struct audio_dev *agdev)
520{
521 struct snd_uac2_chip *uac2 = &agdev->uac2;
522 int err;
523
524 uac2->pdrv.probe = snd_uac2_probe;
525 uac2->pdrv.remove = snd_uac2_remove;
526 uac2->pdrv.driver.name = uac2_name;
527
528 uac2->pdev.id = 0;
529 uac2->pdev.name = uac2_name;
Felipe Balbide1e6e72014-09-29 14:24:09 -0500530 uac2->pdev.dev.release = snd_uac2_release;
Jassi Brar132fcb42012-02-02 22:01:34 +0530531
532 /* Register snd_uac2 driver */
533 err = platform_driver_register(&uac2->pdrv);
534 if (err)
535 return err;
536
537 /* Register snd_uac2 device */
538 err = platform_device_register(&uac2->pdev);
539 if (err)
540 platform_driver_unregister(&uac2->pdrv);
541
542 return err;
543}
544
545static void alsa_uac2_exit(struct audio_dev *agdev)
546{
547 struct snd_uac2_chip *uac2 = &agdev->uac2;
548
549 platform_driver_unregister(&uac2->pdrv);
550 platform_device_unregister(&uac2->pdev);
551}
552
553
554/* --------- USB Function Interface ------------- */
555
556enum {
557 STR_ASSOC,
558 STR_IF_CTRL,
559 STR_CLKSRC_IN,
560 STR_CLKSRC_OUT,
561 STR_USB_IT,
562 STR_IO_IT,
563 STR_USB_OT,
564 STR_IO_OT,
565 STR_AS_OUT_ALT0,
566 STR_AS_OUT_ALT1,
567 STR_AS_IN_ALT0,
568 STR_AS_IN_ALT1,
569};
570
Jassi Brar132fcb42012-02-02 22:01:34 +0530571static char clksrc_in[8];
572static char clksrc_out[8];
Jassi Brar132fcb42012-02-02 22:01:34 +0530573
574static struct usb_string strings_fn[] = {
Sebastian Andrzej Siewiorb36c3472012-10-22 22:15:09 +0200575 [STR_ASSOC].s = "Source/Sink",
576 [STR_IF_CTRL].s = "Topology Control",
Jassi Brar132fcb42012-02-02 22:01:34 +0530577 [STR_CLKSRC_IN].s = clksrc_in,
578 [STR_CLKSRC_OUT].s = clksrc_out,
Sebastian Andrzej Siewiorb36c3472012-10-22 22:15:09 +0200579 [STR_USB_IT].s = "USBH Out",
580 [STR_IO_IT].s = "USBD Out",
581 [STR_USB_OT].s = "USBH In",
582 [STR_IO_OT].s = "USBD In",
583 [STR_AS_OUT_ALT0].s = "Playback Inactive",
584 [STR_AS_OUT_ALT1].s = "Playback Active",
585 [STR_AS_IN_ALT0].s = "Capture Inactive",
586 [STR_AS_IN_ALT1].s = "Capture Active",
Jassi Brar132fcb42012-02-02 22:01:34 +0530587 { },
588};
589
590static struct usb_gadget_strings str_fn = {
591 .language = 0x0409, /* en-us */
592 .strings = strings_fn,
593};
594
595static struct usb_gadget_strings *fn_strings[] = {
596 &str_fn,
597 NULL,
598};
599
Jassi Brar132fcb42012-02-02 22:01:34 +0530600static struct usb_interface_assoc_descriptor iad_desc = {
601 .bLength = sizeof iad_desc,
602 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
603
604 .bFirstInterface = 0,
605 .bInterfaceCount = 3,
606 .bFunctionClass = USB_CLASS_AUDIO,
607 .bFunctionSubClass = UAC2_FUNCTION_SUBCLASS_UNDEFINED,
608 .bFunctionProtocol = UAC_VERSION_2,
609};
610
611/* Audio Control Interface */
612static struct usb_interface_descriptor std_ac_if_desc = {
613 .bLength = sizeof std_ac_if_desc,
614 .bDescriptorType = USB_DT_INTERFACE,
615
616 .bAlternateSetting = 0,
617 .bNumEndpoints = 0,
618 .bInterfaceClass = USB_CLASS_AUDIO,
619 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
620 .bInterfaceProtocol = UAC_VERSION_2,
621};
622
623/* Clock source for IN traffic */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000624static struct uac_clock_source_descriptor in_clk_src_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530625 .bLength = sizeof in_clk_src_desc,
626 .bDescriptorType = USB_DT_CS_INTERFACE,
627
628 .bDescriptorSubtype = UAC2_CLOCK_SOURCE,
629 .bClockID = USB_IN_CLK_ID,
630 .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED,
631 .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL),
632 .bAssocTerminal = 0,
633};
634
635/* Clock source for OUT traffic */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000636static struct uac_clock_source_descriptor out_clk_src_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530637 .bLength = sizeof out_clk_src_desc,
638 .bDescriptorType = USB_DT_CS_INTERFACE,
639
640 .bDescriptorSubtype = UAC2_CLOCK_SOURCE,
641 .bClockID = USB_OUT_CLK_ID,
642 .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED,
643 .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL),
644 .bAssocTerminal = 0,
645};
646
647/* Input Terminal for USB_OUT */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000648static struct uac2_input_terminal_descriptor usb_out_it_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530649 .bLength = sizeof usb_out_it_desc,
650 .bDescriptorType = USB_DT_CS_INTERFACE,
651
652 .bDescriptorSubtype = UAC_INPUT_TERMINAL,
653 .bTerminalID = USB_OUT_IT_ID,
654 .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING),
655 .bAssocTerminal = 0,
656 .bCSourceID = USB_OUT_CLK_ID,
657 .iChannelNames = 0,
658 .bmControls = (CONTROL_RDWR << COPY_CTRL),
659};
660
661/* Input Terminal for I/O-In */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000662static struct uac2_input_terminal_descriptor io_in_it_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530663 .bLength = sizeof io_in_it_desc,
664 .bDescriptorType = USB_DT_CS_INTERFACE,
665
666 .bDescriptorSubtype = UAC_INPUT_TERMINAL,
667 .bTerminalID = IO_IN_IT_ID,
668 .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED),
669 .bAssocTerminal = 0,
670 .bCSourceID = USB_IN_CLK_ID,
671 .iChannelNames = 0,
672 .bmControls = (CONTROL_RDWR << COPY_CTRL),
673};
674
675/* Ouput Terminal for USB_IN */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000676static struct uac2_output_terminal_descriptor usb_in_ot_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530677 .bLength = sizeof usb_in_ot_desc,
678 .bDescriptorType = USB_DT_CS_INTERFACE,
679
680 .bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
681 .bTerminalID = USB_IN_OT_ID,
682 .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING),
683 .bAssocTerminal = 0,
684 .bSourceID = IO_IN_IT_ID,
685 .bCSourceID = USB_IN_CLK_ID,
686 .bmControls = (CONTROL_RDWR << COPY_CTRL),
687};
688
689/* Ouput Terminal for I/O-Out */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000690static struct uac2_output_terminal_descriptor io_out_ot_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530691 .bLength = sizeof io_out_ot_desc,
692 .bDescriptorType = USB_DT_CS_INTERFACE,
693
694 .bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
695 .bTerminalID = IO_OUT_OT_ID,
696 .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED),
697 .bAssocTerminal = 0,
698 .bSourceID = USB_OUT_IT_ID,
699 .bCSourceID = USB_OUT_CLK_ID,
700 .bmControls = (CONTROL_RDWR << COPY_CTRL),
701};
702
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000703static struct uac2_ac_header_descriptor ac_hdr_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530704 .bLength = sizeof ac_hdr_desc,
705 .bDescriptorType = USB_DT_CS_INTERFACE,
706
707 .bDescriptorSubtype = UAC_MS_HEADER,
708 .bcdADC = cpu_to_le16(0x200),
709 .bCategory = UAC2_FUNCTION_IO_BOX,
710 .wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc
711 + sizeof usb_out_it_desc + sizeof io_in_it_desc
712 + sizeof usb_in_ot_desc + sizeof io_out_ot_desc,
713 .bmControls = 0,
714};
715
716/* Audio Streaming OUT Interface - Alt0 */
717static struct usb_interface_descriptor std_as_out_if0_desc = {
718 .bLength = sizeof std_as_out_if0_desc,
719 .bDescriptorType = USB_DT_INTERFACE,
720
721 .bAlternateSetting = 0,
722 .bNumEndpoints = 0,
723 .bInterfaceClass = USB_CLASS_AUDIO,
724 .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING,
725 .bInterfaceProtocol = UAC_VERSION_2,
726};
727
728/* Audio Streaming OUT Interface - Alt1 */
729static struct usb_interface_descriptor std_as_out_if1_desc = {
730 .bLength = sizeof std_as_out_if1_desc,
731 .bDescriptorType = USB_DT_INTERFACE,
732
733 .bAlternateSetting = 1,
734 .bNumEndpoints = 1,
735 .bInterfaceClass = USB_CLASS_AUDIO,
736 .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING,
737 .bInterfaceProtocol = UAC_VERSION_2,
738};
739
740/* Audio Stream OUT Intface Desc */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000741static struct uac2_as_header_descriptor as_out_hdr_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530742 .bLength = sizeof as_out_hdr_desc,
743 .bDescriptorType = USB_DT_CS_INTERFACE,
744
745 .bDescriptorSubtype = UAC_AS_GENERAL,
746 .bTerminalLink = USB_OUT_IT_ID,
747 .bmControls = 0,
748 .bFormatType = UAC_FORMAT_TYPE_I,
749 .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM),
750 .iChannelNames = 0,
751};
752
753/* Audio USB_OUT Format */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000754static struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530755 .bLength = sizeof as_out_fmt1_desc,
756 .bDescriptorType = USB_DT_CS_INTERFACE,
757 .bDescriptorSubtype = UAC_FORMAT_TYPE,
758 .bFormatType = UAC_FORMAT_TYPE_I,
759};
760
761/* STD AS ISO OUT Endpoint */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000762static struct usb_endpoint_descriptor fs_epout_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530763 .bLength = USB_DT_ENDPOINT_SIZE,
764 .bDescriptorType = USB_DT_ENDPOINT,
765
766 .bEndpointAddress = USB_DIR_OUT,
767 .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
Felipe Balbi703a3032014-09-29 14:18:14 -0500768 .wMaxPacketSize = cpu_to_le16(1023),
Jassi Brar132fcb42012-02-02 22:01:34 +0530769 .bInterval = 1,
770};
771
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000772static struct usb_endpoint_descriptor hs_epout_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530773 .bLength = USB_DT_ENDPOINT_SIZE,
774 .bDescriptorType = USB_DT_ENDPOINT,
775
776 .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
Felipe Balbi703a3032014-09-29 14:18:14 -0500777 .wMaxPacketSize = cpu_to_le16(1024),
Jassi Brar132fcb42012-02-02 22:01:34 +0530778 .bInterval = 4,
779};
780
781/* CS AS ISO OUT Endpoint */
782static struct uac2_iso_endpoint_descriptor as_iso_out_desc = {
783 .bLength = sizeof as_iso_out_desc,
784 .bDescriptorType = USB_DT_CS_ENDPOINT,
785
786 .bDescriptorSubtype = UAC_EP_GENERAL,
787 .bmAttributes = 0,
788 .bmControls = 0,
789 .bLockDelayUnits = 0,
790 .wLockDelay = 0,
791};
792
793/* Audio Streaming IN Interface - Alt0 */
794static struct usb_interface_descriptor std_as_in_if0_desc = {
795 .bLength = sizeof std_as_in_if0_desc,
796 .bDescriptorType = USB_DT_INTERFACE,
797
798 .bAlternateSetting = 0,
799 .bNumEndpoints = 0,
800 .bInterfaceClass = USB_CLASS_AUDIO,
801 .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING,
802 .bInterfaceProtocol = UAC_VERSION_2,
803};
804
805/* Audio Streaming IN Interface - Alt1 */
806static struct usb_interface_descriptor std_as_in_if1_desc = {
807 .bLength = sizeof std_as_in_if1_desc,
808 .bDescriptorType = USB_DT_INTERFACE,
809
810 .bAlternateSetting = 1,
811 .bNumEndpoints = 1,
812 .bInterfaceClass = USB_CLASS_AUDIO,
813 .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING,
814 .bInterfaceProtocol = UAC_VERSION_2,
815};
816
817/* Audio Stream IN Intface Desc */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000818static struct uac2_as_header_descriptor as_in_hdr_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530819 .bLength = sizeof as_in_hdr_desc,
820 .bDescriptorType = USB_DT_CS_INTERFACE,
821
822 .bDescriptorSubtype = UAC_AS_GENERAL,
823 .bTerminalLink = USB_IN_OT_ID,
824 .bmControls = 0,
825 .bFormatType = UAC_FORMAT_TYPE_I,
826 .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM),
827 .iChannelNames = 0,
828};
829
830/* Audio USB_IN Format */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000831static struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530832 .bLength = sizeof as_in_fmt1_desc,
833 .bDescriptorType = USB_DT_CS_INTERFACE,
834 .bDescriptorSubtype = UAC_FORMAT_TYPE,
835 .bFormatType = UAC_FORMAT_TYPE_I,
836};
837
838/* STD AS ISO IN Endpoint */
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000839static struct usb_endpoint_descriptor fs_epin_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530840 .bLength = USB_DT_ENDPOINT_SIZE,
841 .bDescriptorType = USB_DT_ENDPOINT,
842
843 .bEndpointAddress = USB_DIR_IN,
844 .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
Felipe Balbi703a3032014-09-29 14:18:14 -0500845 .wMaxPacketSize = cpu_to_le16(1023),
Jassi Brar132fcb42012-02-02 22:01:34 +0530846 .bInterval = 1,
847};
848
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +0000849static struct usb_endpoint_descriptor hs_epin_desc = {
Jassi Brar132fcb42012-02-02 22:01:34 +0530850 .bLength = USB_DT_ENDPOINT_SIZE,
851 .bDescriptorType = USB_DT_ENDPOINT,
852
853 .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
Felipe Balbi703a3032014-09-29 14:18:14 -0500854 .wMaxPacketSize = cpu_to_le16(1024),
Jassi Brar132fcb42012-02-02 22:01:34 +0530855 .bInterval = 4,
856};
857
858/* CS AS ISO IN Endpoint */
859static struct uac2_iso_endpoint_descriptor as_iso_in_desc = {
860 .bLength = sizeof as_iso_in_desc,
861 .bDescriptorType = USB_DT_CS_ENDPOINT,
862
863 .bDescriptorSubtype = UAC_EP_GENERAL,
864 .bmAttributes = 0,
865 .bmControls = 0,
866 .bLockDelayUnits = 0,
867 .wLockDelay = 0,
868};
869
870static struct usb_descriptor_header *fs_audio_desc[] = {
871 (struct usb_descriptor_header *)&iad_desc,
872 (struct usb_descriptor_header *)&std_ac_if_desc,
873
874 (struct usb_descriptor_header *)&ac_hdr_desc,
875 (struct usb_descriptor_header *)&in_clk_src_desc,
876 (struct usb_descriptor_header *)&out_clk_src_desc,
877 (struct usb_descriptor_header *)&usb_out_it_desc,
878 (struct usb_descriptor_header *)&io_in_it_desc,
879 (struct usb_descriptor_header *)&usb_in_ot_desc,
880 (struct usb_descriptor_header *)&io_out_ot_desc,
881
882 (struct usb_descriptor_header *)&std_as_out_if0_desc,
883 (struct usb_descriptor_header *)&std_as_out_if1_desc,
884
885 (struct usb_descriptor_header *)&as_out_hdr_desc,
886 (struct usb_descriptor_header *)&as_out_fmt1_desc,
887 (struct usb_descriptor_header *)&fs_epout_desc,
888 (struct usb_descriptor_header *)&as_iso_out_desc,
889
890 (struct usb_descriptor_header *)&std_as_in_if0_desc,
891 (struct usb_descriptor_header *)&std_as_in_if1_desc,
892
893 (struct usb_descriptor_header *)&as_in_hdr_desc,
894 (struct usb_descriptor_header *)&as_in_fmt1_desc,
895 (struct usb_descriptor_header *)&fs_epin_desc,
896 (struct usb_descriptor_header *)&as_iso_in_desc,
897 NULL,
898};
899
900static struct usb_descriptor_header *hs_audio_desc[] = {
901 (struct usb_descriptor_header *)&iad_desc,
902 (struct usb_descriptor_header *)&std_ac_if_desc,
903
904 (struct usb_descriptor_header *)&ac_hdr_desc,
905 (struct usb_descriptor_header *)&in_clk_src_desc,
906 (struct usb_descriptor_header *)&out_clk_src_desc,
907 (struct usb_descriptor_header *)&usb_out_it_desc,
908 (struct usb_descriptor_header *)&io_in_it_desc,
909 (struct usb_descriptor_header *)&usb_in_ot_desc,
910 (struct usb_descriptor_header *)&io_out_ot_desc,
911
912 (struct usb_descriptor_header *)&std_as_out_if0_desc,
913 (struct usb_descriptor_header *)&std_as_out_if1_desc,
914
915 (struct usb_descriptor_header *)&as_out_hdr_desc,
916 (struct usb_descriptor_header *)&as_out_fmt1_desc,
917 (struct usb_descriptor_header *)&hs_epout_desc,
918 (struct usb_descriptor_header *)&as_iso_out_desc,
919
920 (struct usb_descriptor_header *)&std_as_in_if0_desc,
921 (struct usb_descriptor_header *)&std_as_in_if1_desc,
922
923 (struct usb_descriptor_header *)&as_in_hdr_desc,
924 (struct usb_descriptor_header *)&as_in_fmt1_desc,
925 (struct usb_descriptor_header *)&hs_epin_desc,
926 (struct usb_descriptor_header *)&as_iso_in_desc,
927 NULL,
928};
929
930struct cntrl_cur_lay3 {
931 __u32 dCUR;
932};
933
934struct cntrl_range_lay3 {
935 __u16 wNumSubRanges;
936 __u32 dMIN;
937 __u32 dMAX;
938 __u32 dRES;
939} __packed;
940
941static inline void
942free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
943{
Jassi Brareb127cb2013-05-30 18:23:33 +0530944 struct snd_uac2_chip *uac2 = prm->uac2;
Peter Chene92b9d42017-01-04 10:19:23 +0800945 struct audio_dev *agdev = uac2_to_agdev(uac2);
946 struct f_uac2_opts *uac2_opts = agdev_to_uac2_opts(agdev);
Jassi Brar132fcb42012-02-02 22:01:34 +0530947 int i;
948
Felipe Balbif3bb7b22014-09-29 14:23:41 -0500949 if (!prm->ep_enabled)
950 return;
951
Jassi Brar132fcb42012-02-02 22:01:34 +0530952 prm->ep_enabled = false;
953
Peter Chene92b9d42017-01-04 10:19:23 +0800954 for (i = 0; i < uac2_opts->req_number; i++) {
Jassi Brar132fcb42012-02-02 22:01:34 +0530955 if (prm->ureq[i].req) {
956 usb_ep_dequeue(ep, prm->ureq[i].req);
957 usb_ep_free_request(ep, prm->ureq[i].req);
958 prm->ureq[i].req = NULL;
959 }
960 }
961
962 if (usb_ep_disable(ep))
963 dev_err(&uac2->pdev.dev,
964 "%s:%d Error!\n", __func__, __LINE__);
965}
966
Peter Chen913e4a92015-07-30 13:13:03 +0800967static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
968 struct usb_endpoint_descriptor *ep_desc,
969 unsigned int factor, bool is_playback)
970{
971 int chmask, srate, ssize;
972 u16 max_packet_size;
973
974 if (is_playback) {
975 chmask = uac2_opts->p_chmask;
976 srate = uac2_opts->p_srate;
977 ssize = uac2_opts->p_ssize;
978 } else {
979 chmask = uac2_opts->c_chmask;
980 srate = uac2_opts->c_srate;
981 ssize = uac2_opts->c_ssize;
982 }
983
984 max_packet_size = num_channels(chmask) * ssize *
985 DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
Felipe Balbi0f4315a2015-08-04 11:02:45 -0500986 ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
Peter Chen913e4a92015-07-30 13:13:03 +0800987 le16_to_cpu(ep_desc->wMaxPacketSize)));
988}
989
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +0200990static int
Jassi Brar132fcb42012-02-02 22:01:34 +0530991afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
992{
993 struct audio_dev *agdev = func_to_agdev(fn);
994 struct snd_uac2_chip *uac2 = &agdev->uac2;
995 struct usb_composite_dev *cdev = cfg->cdev;
996 struct usb_gadget *gadget = cdev->gadget;
Daniel Macka8147da2014-08-27 19:09:04 +0200997 struct device *dev = &uac2->pdev.dev;
Jassi Brar132fcb42012-02-02 22:01:34 +0530998 struct uac2_rtd_params *prm;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +0200999 struct f_uac2_opts *uac2_opts;
Andrzej Pietrasiewiczf4087572014-07-22 19:58:33 +02001000 struct usb_string *us;
Jassi Brar132fcb42012-02-02 22:01:34 +05301001 int ret;
1002
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001003 uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001004
Andrzej Pietrasiewiczf4087572014-07-22 19:58:33 +02001005 us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
1006 if (IS_ERR(us))
1007 return PTR_ERR(us);
1008 iad_desc.iFunction = us[STR_ASSOC].id;
1009 std_ac_if_desc.iInterface = us[STR_IF_CTRL].id;
1010 in_clk_src_desc.iClockSource = us[STR_CLKSRC_IN].id;
1011 out_clk_src_desc.iClockSource = us[STR_CLKSRC_OUT].id;
1012 usb_out_it_desc.iTerminal = us[STR_USB_IT].id;
1013 io_in_it_desc.iTerminal = us[STR_IO_IT].id;
1014 usb_in_ot_desc.iTerminal = us[STR_USB_OT].id;
1015 io_out_ot_desc.iTerminal = us[STR_IO_OT].id;
1016 std_as_out_if0_desc.iInterface = us[STR_AS_OUT_ALT0].id;
1017 std_as_out_if1_desc.iInterface = us[STR_AS_OUT_ALT1].id;
1018 std_as_in_if0_desc.iInterface = us[STR_AS_IN_ALT0].id;
1019 std_as_in_if1_desc.iInterface = us[STR_AS_IN_ALT1].id;
1020
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001021
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001022 /* Initialize the configurable parameters */
1023 usb_out_it_desc.bNrChannels = num_channels(uac2_opts->c_chmask);
1024 usb_out_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask);
1025 io_in_it_desc.bNrChannels = num_channels(uac2_opts->p_chmask);
1026 io_in_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->p_chmask);
1027 as_out_hdr_desc.bNrChannels = num_channels(uac2_opts->c_chmask);
1028 as_out_hdr_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask);
1029 as_in_hdr_desc.bNrChannels = num_channels(uac2_opts->p_chmask);
1030 as_in_hdr_desc.bmChannelConfig = cpu_to_le32(uac2_opts->p_chmask);
1031 as_out_fmt1_desc.bSubslotSize = uac2_opts->c_ssize;
1032 as_out_fmt1_desc.bBitResolution = uac2_opts->c_ssize * 8;
1033 as_in_fmt1_desc.bSubslotSize = uac2_opts->p_ssize;
1034 as_in_fmt1_desc.bBitResolution = uac2_opts->p_ssize * 8;
1035
1036 snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate);
1037 snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001038
Jassi Brar132fcb42012-02-02 22:01:34 +05301039 ret = usb_interface_id(cfg, fn);
1040 if (ret < 0) {
Daniel Macka8147da2014-08-27 19:09:04 +02001041 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301042 return ret;
1043 }
1044 std_ac_if_desc.bInterfaceNumber = ret;
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001045 agdev->ac_intf = ret;
1046 agdev->ac_alt = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +05301047
1048 ret = usb_interface_id(cfg, fn);
1049 if (ret < 0) {
Daniel Macka8147da2014-08-27 19:09:04 +02001050 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301051 return ret;
1052 }
1053 std_as_out_if0_desc.bInterfaceNumber = ret;
1054 std_as_out_if1_desc.bInterfaceNumber = ret;
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001055 agdev->as_out_intf = ret;
1056 agdev->as_out_alt = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +05301057
1058 ret = usb_interface_id(cfg, fn);
1059 if (ret < 0) {
Daniel Macka8147da2014-08-27 19:09:04 +02001060 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301061 return ret;
1062 }
1063 std_as_in_if0_desc.bInterfaceNumber = ret;
1064 std_as_in_if1_desc.bInterfaceNumber = ret;
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001065 agdev->as_in_intf = ret;
1066 agdev->as_in_alt = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +05301067
Sekhar Nori0db56e42017-05-17 13:45:17 +05301068 /* Calculate wMaxPacketSize according to audio bandwidth */
1069 set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
1070 set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
1071 set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
1072 set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
1073
Jassi Brar132fcb42012-02-02 22:01:34 +05301074 agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001075 if (!agdev->out_ep) {
Daniel Macka8147da2014-08-27 19:09:04 +02001076 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Peter Chenf1d38612016-11-08 10:10:44 +08001077 return ret;
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001078 }
Jassi Brar132fcb42012-02-02 22:01:34 +05301079
1080 agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001081 if (!agdev->in_ep) {
Daniel Macka8147da2014-08-27 19:09:04 +02001082 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Peter Chenf1d38612016-11-08 10:10:44 +08001083 return ret;
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001084 }
Jassi Brar132fcb42012-02-02 22:01:34 +05301085
Jassi Brareb127cb2013-05-30 18:23:33 +05301086 uac2->p_prm.uac2 = uac2;
1087 uac2->c_prm.uac2 = uac2;
1088
Jassi Brar132fcb42012-02-02 22:01:34 +05301089 hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
Jassi Brar132fcb42012-02-02 22:01:34 +05301090 hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
Jassi Brar132fcb42012-02-02 22:01:34 +05301091
John Youneaef50c2016-02-05 17:06:07 -08001092 ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL,
1093 NULL);
Sebastian Andrzej Siewior10287ba2012-10-22 22:15:06 +02001094 if (ret)
Peter Chenf1d38612016-11-08 10:10:44 +08001095 return ret;
Jassi Brar132fcb42012-02-02 22:01:34 +05301096
1097 prm = &agdev->uac2.c_prm;
1098 prm->max_psize = hs_epout_desc.wMaxPacketSize;
Peter Chene92b9d42017-01-04 10:19:23 +08001099 prm->ureq = kcalloc(uac2_opts->req_number, sizeof(struct uac2_req),
1100 GFP_KERNEL);
1101 if (!prm->ureq) {
1102 ret = -ENOMEM;
1103 goto err_free_descs;
1104 }
1105 prm->rbuf = kcalloc(uac2_opts->req_number, prm->max_psize, GFP_KERNEL);
Jassi Brar132fcb42012-02-02 22:01:34 +05301106 if (!prm->rbuf) {
1107 prm->max_psize = 0;
Peter Chen88f950a2017-01-04 10:19:22 +08001108 ret = -ENOMEM;
Pavitrakumar Managutted12a8722014-10-22 19:24:58 +05301109 goto err_free_descs;
Jassi Brar132fcb42012-02-02 22:01:34 +05301110 }
1111
1112 prm = &agdev->uac2.p_prm;
1113 prm->max_psize = hs_epin_desc.wMaxPacketSize;
Peter Chene92b9d42017-01-04 10:19:23 +08001114 prm->ureq = kcalloc(uac2_opts->req_number, sizeof(struct uac2_req),
1115 GFP_KERNEL);
1116 if (!prm->ureq) {
1117 ret = -ENOMEM;
1118 goto err_free_descs;
1119 }
1120 prm->rbuf = kcalloc(uac2_opts->req_number, prm->max_psize, GFP_KERNEL);
Jassi Brar132fcb42012-02-02 22:01:34 +05301121 if (!prm->rbuf) {
1122 prm->max_psize = 0;
Peter Chen88f950a2017-01-04 10:19:22 +08001123 ret = -ENOMEM;
1124 goto err_no_memory;
Jassi Brar132fcb42012-02-02 22:01:34 +05301125 }
1126
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001127 ret = alsa_uac2_init(agdev);
1128 if (ret)
Peter Chen88f950a2017-01-04 10:19:22 +08001129 goto err_no_memory;
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001130 return 0;
Pavitrakumar Managutted12a8722014-10-22 19:24:58 +05301131
Peter Chen88f950a2017-01-04 10:19:22 +08001132err_no_memory:
Peter Chene92b9d42017-01-04 10:19:23 +08001133 kfree(agdev->uac2.p_prm.ureq);
1134 kfree(agdev->uac2.c_prm.ureq);
Sebastian Andrzej Siewior391aa852012-10-22 22:14:59 +02001135 kfree(agdev->uac2.p_prm.rbuf);
1136 kfree(agdev->uac2.c_prm.rbuf);
Peter Chenf1d38612016-11-08 10:10:44 +08001137err_free_descs:
1138 usb_free_all_descriptors(fn);
Peter Chen88f950a2017-01-04 10:19:22 +08001139 return ret;
Jassi Brar132fcb42012-02-02 22:01:34 +05301140}
1141
Jassi Brar132fcb42012-02-02 22:01:34 +05301142static int
1143afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
1144{
1145 struct usb_composite_dev *cdev = fn->config->cdev;
1146 struct audio_dev *agdev = func_to_agdev(fn);
Peter Chene92b9d42017-01-04 10:19:23 +08001147 struct f_uac2_opts *opts = agdev_to_uac2_opts(agdev);
Jassi Brar132fcb42012-02-02 22:01:34 +05301148 struct snd_uac2_chip *uac2 = &agdev->uac2;
1149 struct usb_gadget *gadget = cdev->gadget;
Daniel Macka8147da2014-08-27 19:09:04 +02001150 struct device *dev = &uac2->pdev.dev;
Jassi Brar132fcb42012-02-02 22:01:34 +05301151 struct usb_request *req;
1152 struct usb_ep *ep;
1153 struct uac2_rtd_params *prm;
Daniel Mack9bb87f12014-08-27 19:09:07 +02001154 int req_len, i;
Jassi Brar132fcb42012-02-02 22:01:34 +05301155
1156 /* No i/f has more than 2 alt settings */
1157 if (alt > 1) {
Daniel Macka8147da2014-08-27 19:09:04 +02001158 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301159 return -EINVAL;
1160 }
1161
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001162 if (intf == agdev->ac_intf) {
Jassi Brar132fcb42012-02-02 22:01:34 +05301163 /* Control I/f has only 1 AltSetting - 0 */
1164 if (alt) {
Daniel Macka8147da2014-08-27 19:09:04 +02001165 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301166 return -EINVAL;
1167 }
1168 return 0;
1169 }
1170
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001171 if (intf == agdev->as_out_intf) {
Jassi Brar132fcb42012-02-02 22:01:34 +05301172 ep = agdev->out_ep;
1173 prm = &uac2->c_prm;
1174 config_ep_by_speed(gadget, fn, ep);
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001175 agdev->as_out_alt = alt;
Daniel Mack9bb87f12014-08-27 19:09:07 +02001176 req_len = prm->max_psize;
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001177 } else if (intf == agdev->as_in_intf) {
Daniel Mack9bb87f12014-08-27 19:09:07 +02001178 unsigned int factor, rate;
1179 struct usb_endpoint_descriptor *ep_desc;
1180
Jassi Brar132fcb42012-02-02 22:01:34 +05301181 ep = agdev->in_ep;
1182 prm = &uac2->p_prm;
1183 config_ep_by_speed(gadget, fn, ep);
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001184 agdev->as_in_alt = alt;
Daniel Mack9bb87f12014-08-27 19:09:07 +02001185
1186 /* pre-calculate the playback endpoint's interval */
1187 if (gadget->speed == USB_SPEED_FULL) {
1188 ep_desc = &fs_epin_desc;
1189 factor = 1000;
1190 } else {
1191 ep_desc = &hs_epin_desc;
Peter Chenc41b7762015-07-27 14:51:47 +08001192 factor = 8000;
Daniel Mack9bb87f12014-08-27 19:09:07 +02001193 }
1194
1195 /* pre-compute some values for iso_complete() */
1196 uac2->p_framesize = opts->p_ssize *
1197 num_channels(opts->p_chmask);
1198 rate = opts->p_srate * uac2->p_framesize;
Peter Chenc41b7762015-07-27 14:51:47 +08001199 uac2->p_interval = factor / (1 << (ep_desc->bInterval - 1));
Daniel Mack9bb87f12014-08-27 19:09:07 +02001200 uac2->p_pktsize = min_t(unsigned int, rate / uac2->p_interval,
1201 prm->max_psize);
1202
1203 if (uac2->p_pktsize < prm->max_psize)
1204 uac2->p_pktsize_residue = rate % uac2->p_interval;
1205 else
1206 uac2->p_pktsize_residue = 0;
1207
1208 req_len = uac2->p_pktsize;
1209 uac2->p_residue = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +05301210 } else {
Daniel Macka8147da2014-08-27 19:09:04 +02001211 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301212 return -EINVAL;
1213 }
1214
1215 if (alt == 0) {
1216 free_ep(prm, ep);
1217 return 0;
1218 }
1219
1220 prm->ep_enabled = true;
1221 usb_ep_enable(ep);
1222
Peter Chene92b9d42017-01-04 10:19:23 +08001223 for (i = 0; i < opts->req_number; i++) {
Daniel Mack430fdbd32014-08-27 19:09:03 +02001224 if (!prm->ureq[i].req) {
1225 req = usb_ep_alloc_request(ep, GFP_ATOMIC);
1226 if (req == NULL)
1227 return -ENOMEM;
1228
1229 prm->ureq[i].req = req;
1230 prm->ureq[i].pp = prm;
1231
1232 req->zero = 0;
1233 req->context = &prm->ureq[i];
Daniel Mack9bb87f12014-08-27 19:09:07 +02001234 req->length = req_len;
Daniel Mack430fdbd32014-08-27 19:09:03 +02001235 req->complete = agdev_iso_complete;
Daniel Mack9bb87f12014-08-27 19:09:07 +02001236 req->buf = prm->rbuf + i * prm->max_psize;
Jassi Brar132fcb42012-02-02 22:01:34 +05301237 }
1238
Daniel Mack430fdbd32014-08-27 19:09:03 +02001239 if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
Daniel Macka8147da2014-08-27 19:09:04 +02001240 dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
Jassi Brar132fcb42012-02-02 22:01:34 +05301241 }
1242
1243 return 0;
1244}
1245
1246static int
1247afunc_get_alt(struct usb_function *fn, unsigned intf)
1248{
1249 struct audio_dev *agdev = func_to_agdev(fn);
1250 struct snd_uac2_chip *uac2 = &agdev->uac2;
1251
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001252 if (intf == agdev->ac_intf)
1253 return agdev->ac_alt;
1254 else if (intf == agdev->as_out_intf)
1255 return agdev->as_out_alt;
1256 else if (intf == agdev->as_in_intf)
1257 return agdev->as_in_alt;
Jassi Brar132fcb42012-02-02 22:01:34 +05301258 else
1259 dev_err(&uac2->pdev.dev,
1260 "%s:%d Invalid Interface %d!\n",
1261 __func__, __LINE__, intf);
1262
1263 return -EINVAL;
1264}
1265
1266static void
1267afunc_disable(struct usb_function *fn)
1268{
1269 struct audio_dev *agdev = func_to_agdev(fn);
1270 struct snd_uac2_chip *uac2 = &agdev->uac2;
1271
1272 free_ep(&uac2->p_prm, agdev->in_ep);
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001273 agdev->as_in_alt = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +05301274
1275 free_ep(&uac2->c_prm, agdev->out_ep);
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001276 agdev->as_out_alt = 0;
Jassi Brar132fcb42012-02-02 22:01:34 +05301277}
1278
1279static int
1280in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1281{
1282 struct usb_request *req = fn->config->cdev->req;
1283 struct audio_dev *agdev = func_to_agdev(fn);
1284 struct snd_uac2_chip *uac2 = &agdev->uac2;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001285 struct f_uac2_opts *opts;
Jassi Brar132fcb42012-02-02 22:01:34 +05301286 u16 w_length = le16_to_cpu(cr->wLength);
1287 u16 w_index = le16_to_cpu(cr->wIndex);
1288 u16 w_value = le16_to_cpu(cr->wValue);
1289 u8 entity_id = (w_index >> 8) & 0xff;
1290 u8 control_selector = w_value >> 8;
1291 int value = -EOPNOTSUPP;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001292 int p_srate, c_srate;
1293
Daniel Mack254b3bf2014-08-27 19:09:05 +02001294 opts = agdev_to_uac2_opts(agdev);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001295 p_srate = opts->p_srate;
1296 c_srate = opts->c_srate;
Jassi Brar132fcb42012-02-02 22:01:34 +05301297
1298 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) {
1299 struct cntrl_cur_lay3 c;
Heinrich Schuchardtffeee832016-05-08 23:20:59 +02001300 memset(&c, 0, sizeof(struct cntrl_cur_lay3));
Jassi Brar132fcb42012-02-02 22:01:34 +05301301
1302 if (entity_id == USB_IN_CLK_ID)
1303 c.dCUR = p_srate;
1304 else if (entity_id == USB_OUT_CLK_ID)
1305 c.dCUR = c_srate;
1306
1307 value = min_t(unsigned, w_length, sizeof c);
1308 memcpy(req->buf, &c, value);
1309 } else if (control_selector == UAC2_CS_CONTROL_CLOCK_VALID) {
1310 *(u8 *)req->buf = 1;
1311 value = min_t(unsigned, w_length, 1);
1312 } else {
1313 dev_err(&uac2->pdev.dev,
1314 "%s:%d control_selector=%d TODO!\n",
1315 __func__, __LINE__, control_selector);
1316 }
1317
1318 return value;
1319}
1320
1321static int
1322in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1323{
1324 struct usb_request *req = fn->config->cdev->req;
1325 struct audio_dev *agdev = func_to_agdev(fn);
1326 struct snd_uac2_chip *uac2 = &agdev->uac2;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001327 struct f_uac2_opts *opts;
Jassi Brar132fcb42012-02-02 22:01:34 +05301328 u16 w_length = le16_to_cpu(cr->wLength);
1329 u16 w_index = le16_to_cpu(cr->wIndex);
1330 u16 w_value = le16_to_cpu(cr->wValue);
1331 u8 entity_id = (w_index >> 8) & 0xff;
1332 u8 control_selector = w_value >> 8;
1333 struct cntrl_range_lay3 r;
1334 int value = -EOPNOTSUPP;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001335 int p_srate, c_srate;
1336
Daniel Mack254b3bf2014-08-27 19:09:05 +02001337 opts = agdev_to_uac2_opts(agdev);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001338 p_srate = opts->p_srate;
1339 c_srate = opts->c_srate;
Jassi Brar132fcb42012-02-02 22:01:34 +05301340
1341 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) {
1342 if (entity_id == USB_IN_CLK_ID)
1343 r.dMIN = p_srate;
1344 else if (entity_id == USB_OUT_CLK_ID)
1345 r.dMIN = c_srate;
1346 else
1347 return -EOPNOTSUPP;
1348
1349 r.dMAX = r.dMIN;
1350 r.dRES = 0;
1351 r.wNumSubRanges = 1;
1352
1353 value = min_t(unsigned, w_length, sizeof r);
1354 memcpy(req->buf, &r, value);
1355 } else {
1356 dev_err(&uac2->pdev.dev,
1357 "%s:%d control_selector=%d TODO!\n",
1358 __func__, __LINE__, control_selector);
1359 }
1360
1361 return value;
1362}
1363
1364static int
1365ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1366{
1367 if (cr->bRequest == UAC2_CS_CUR)
1368 return in_rq_cur(fn, cr);
1369 else if (cr->bRequest == UAC2_CS_RANGE)
1370 return in_rq_range(fn, cr);
1371 else
1372 return -EOPNOTSUPP;
1373}
1374
1375static int
1376out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1377{
1378 u16 w_length = le16_to_cpu(cr->wLength);
1379 u16 w_value = le16_to_cpu(cr->wValue);
1380 u8 control_selector = w_value >> 8;
1381
1382 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ)
1383 return w_length;
1384
1385 return -EOPNOTSUPP;
1386}
1387
1388static int
1389setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1390{
1391 struct audio_dev *agdev = func_to_agdev(fn);
1392 struct snd_uac2_chip *uac2 = &agdev->uac2;
1393 u16 w_index = le16_to_cpu(cr->wIndex);
1394 u8 intf = w_index & 0xff;
1395
Sebastian Andrzej Siewior4ce63572012-10-22 22:15:08 +02001396 if (intf != agdev->ac_intf) {
Jassi Brar132fcb42012-02-02 22:01:34 +05301397 dev_err(&uac2->pdev.dev,
1398 "%s:%d Error!\n", __func__, __LINE__);
1399 return -EOPNOTSUPP;
1400 }
1401
1402 if (cr->bRequestType & USB_DIR_IN)
1403 return ac_rq_in(fn, cr);
1404 else if (cr->bRequest == UAC2_CS_CUR)
1405 return out_rq_cur(fn, cr);
1406
1407 return -EOPNOTSUPP;
1408}
1409
1410static int
1411afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1412{
1413 struct usb_composite_dev *cdev = fn->config->cdev;
1414 struct audio_dev *agdev = func_to_agdev(fn);
1415 struct snd_uac2_chip *uac2 = &agdev->uac2;
1416 struct usb_request *req = cdev->req;
1417 u16 w_length = le16_to_cpu(cr->wLength);
1418 int value = -EOPNOTSUPP;
1419
1420 /* Only Class specific requests are supposed to reach here */
1421 if ((cr->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS)
1422 return -EOPNOTSUPP;
1423
1424 if ((cr->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE)
1425 value = setup_rq_inf(fn, cr);
1426 else
1427 dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__);
1428
1429 if (value >= 0) {
1430 req->length = value;
1431 req->zero = value < w_length;
1432 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
1433 if (value < 0) {
1434 dev_err(&uac2->pdev.dev,
1435 "%s:%d Error!\n", __func__, __LINE__);
1436 req->status = 0;
1437 }
1438 }
1439
1440 return value;
1441}
1442
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001443static inline struct f_uac2_opts *to_f_uac2_opts(struct config_item *item)
1444{
1445 return container_of(to_config_group(item), struct f_uac2_opts,
1446 func_inst.group);
1447}
1448
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001449static void f_uac2_attr_release(struct config_item *item)
1450{
1451 struct f_uac2_opts *opts = to_f_uac2_opts(item);
1452
1453 usb_put_function_instance(&opts->func_inst);
1454}
1455
1456static struct configfs_item_operations f_uac2_item_ops = {
1457 .release = f_uac2_attr_release,
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001458};
1459
1460#define UAC2_ATTRIBUTE(name) \
Christoph Hellwig495702b2015-10-03 15:32:49 +02001461static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001462 char *page) \
1463{ \
Christoph Hellwig495702b2015-10-03 15:32:49 +02001464 struct f_uac2_opts *opts = to_f_uac2_opts(item); \
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001465 int result; \
1466 \
1467 mutex_lock(&opts->lock); \
1468 result = sprintf(page, "%u\n", opts->name); \
1469 mutex_unlock(&opts->lock); \
1470 \
1471 return result; \
1472} \
1473 \
Christoph Hellwig495702b2015-10-03 15:32:49 +02001474static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001475 const char *page, size_t len) \
1476{ \
Christoph Hellwig495702b2015-10-03 15:32:49 +02001477 struct f_uac2_opts *opts = to_f_uac2_opts(item); \
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001478 int ret; \
1479 u32 num; \
1480 \
1481 mutex_lock(&opts->lock); \
1482 if (opts->refcnt) { \
1483 ret = -EBUSY; \
1484 goto end; \
1485 } \
1486 \
1487 ret = kstrtou32(page, 0, &num); \
1488 if (ret) \
1489 goto end; \
1490 \
1491 opts->name = num; \
1492 ret = len; \
1493 \
1494end: \
1495 mutex_unlock(&opts->lock); \
1496 return ret; \
1497} \
1498 \
Christoph Hellwig495702b2015-10-03 15:32:49 +02001499CONFIGFS_ATTR(f_uac2_opts_, name)
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001500
1501UAC2_ATTRIBUTE(p_chmask);
1502UAC2_ATTRIBUTE(p_srate);
1503UAC2_ATTRIBUTE(p_ssize);
1504UAC2_ATTRIBUTE(c_chmask);
1505UAC2_ATTRIBUTE(c_srate);
1506UAC2_ATTRIBUTE(c_ssize);
Peter Chene92b9d42017-01-04 10:19:23 +08001507UAC2_ATTRIBUTE(req_number);
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001508
1509static struct configfs_attribute *f_uac2_attrs[] = {
Christoph Hellwig495702b2015-10-03 15:32:49 +02001510 &f_uac2_opts_attr_p_chmask,
1511 &f_uac2_opts_attr_p_srate,
1512 &f_uac2_opts_attr_p_ssize,
1513 &f_uac2_opts_attr_c_chmask,
1514 &f_uac2_opts_attr_c_srate,
1515 &f_uac2_opts_attr_c_ssize,
Peter Chene92b9d42017-01-04 10:19:23 +08001516 &f_uac2_opts_attr_req_number,
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001517 NULL,
1518};
1519
1520static struct config_item_type f_uac2_func_type = {
1521 .ct_item_ops = &f_uac2_item_ops,
1522 .ct_attrs = f_uac2_attrs,
1523 .ct_owner = THIS_MODULE,
1524};
1525
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001526static void afunc_free_inst(struct usb_function_instance *f)
1527{
1528 struct f_uac2_opts *opts;
1529
1530 opts = container_of(f, struct f_uac2_opts, func_inst);
1531 kfree(opts);
1532}
1533
1534static struct usb_function_instance *afunc_alloc_inst(void)
1535{
1536 struct f_uac2_opts *opts;
1537
1538 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
1539 if (!opts)
1540 return ERR_PTR(-ENOMEM);
1541
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001542 mutex_init(&opts->lock);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001543 opts->func_inst.free_func_inst = afunc_free_inst;
1544
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001545 config_group_init_type_name(&opts->func_inst.group, "",
1546 &f_uac2_func_type);
1547
1548 opts->p_chmask = UAC2_DEF_PCHMASK;
1549 opts->p_srate = UAC2_DEF_PSRATE;
1550 opts->p_ssize = UAC2_DEF_PSSIZE;
1551 opts->c_chmask = UAC2_DEF_CCHMASK;
1552 opts->c_srate = UAC2_DEF_CSRATE;
1553 opts->c_ssize = UAC2_DEF_CSSIZE;
Peter Chene92b9d42017-01-04 10:19:23 +08001554 opts->req_number = UAC2_DEF_REQ_NUM;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001555 return &opts->func_inst;
1556}
1557
1558static void afunc_free(struct usb_function *f)
1559{
1560 struct audio_dev *agdev;
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001561 struct f_uac2_opts *opts;
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001562
1563 agdev = func_to_agdev(f);
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001564 opts = container_of(f->fi, struct f_uac2_opts, func_inst);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001565 kfree(agdev);
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001566 mutex_lock(&opts->lock);
1567 --opts->refcnt;
1568 mutex_unlock(&opts->lock);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001569}
1570
1571static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
1572{
1573 struct audio_dev *agdev = func_to_agdev(f);
1574 struct uac2_rtd_params *prm;
1575
1576 alsa_uac2_exit(agdev);
1577
1578 prm = &agdev->uac2.p_prm;
1579 kfree(prm->rbuf);
1580
1581 prm = &agdev->uac2.c_prm;
1582 kfree(prm->rbuf);
Peter Chene92b9d42017-01-04 10:19:23 +08001583 kfree(prm->ureq);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001584 usb_free_all_descriptors(f);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001585}
1586
Lad, Prabhakaref16e7c2015-02-04 18:01:11 +00001587static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001588{
1589 struct audio_dev *agdev;
1590 struct f_uac2_opts *opts;
1591
1592 agdev = kzalloc(sizeof(*agdev), GFP_KERNEL);
1593 if (agdev == NULL)
1594 return ERR_PTR(-ENOMEM);
1595
1596 opts = container_of(fi, struct f_uac2_opts, func_inst);
Andrzej Pietrasiewicz3aeea3c2014-07-22 19:58:35 +02001597 mutex_lock(&opts->lock);
1598 ++opts->refcnt;
1599 mutex_unlock(&opts->lock);
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001600
1601 agdev->func.name = "uac2_func";
Andrzej Pietrasiewiczf8f93d22014-07-22 19:58:30 +02001602 agdev->func.bind = afunc_bind;
1603 agdev->func.unbind = afunc_unbind;
1604 agdev->func.set_alt = afunc_set_alt;
1605 agdev->func.get_alt = afunc_get_alt;
1606 agdev->func.disable = afunc_disable;
1607 agdev->func.setup = afunc_setup;
1608 agdev->func.free_func = afunc_free;
1609
1610 return &agdev->func;
1611}
1612
1613DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc);
1614MODULE_LICENSE("GPL");
1615MODULE_AUTHOR("Yadwinder Singh");
1616MODULE_AUTHOR("Jaswinder Singh");