1 // SPDX-License-Identifier: GPL-2.0+
3 * f_uac2.c -- USB Audio Class 2.0 Function
6 * Yadwinder Singh (yadi.brar01@gmail.com)
7 * Jaswinder Singh (jaswinder.singh@linaro.org)
10 #include <linux/usb/audio.h>
11 #include <linux/usb/audio-v2.h>
12 #include <linux/module.h>
18 * The driver implements a simple UAC_2 topology.
19 * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
20 * ALSA_Playback -> IT_2 -> OT_4 -> USB-IN
21 * Capture and Playback sampling rates are independently
22 * controlled by two clock sources :
23 * CLK_5 := c_srate, and CLK_6 := p_srate
25 #define USB_OUT_IT_ID 1
27 #define IO_OUT_OT_ID 3
28 #define USB_IN_OT_ID 4
29 #define USB_OUT_CLK_ID 5
30 #define USB_IN_CLK_ID 6
32 #define CONTROL_ABSENT 0
33 #define CONTROL_RDONLY 1
34 #define CONTROL_RDWR 3
36 #define CLK_FREQ_CTRL 0
37 #define CLK_VLD_CTRL 2
47 struct g_audio g_audio
;
48 u8 ac_intf
, as_in_intf
, as_out_intf
;
49 u8 ac_alt
, as_in_alt
, as_out_alt
; /* needed for get_alt() */
52 static inline struct f_uac2
*func_to_uac2(struct usb_function
*f
)
54 return container_of(f
, struct f_uac2
, g_audio
.func
);
58 struct f_uac2_opts
*g_audio_to_uac2_opts(struct g_audio
*agdev
)
60 return container_of(agdev
->func
.fi
, struct f_uac2_opts
, func_inst
);
63 /* --------- USB Function Interface ------------- */
80 static char clksrc_in
[8];
81 static char clksrc_out
[8];
83 static struct usb_string strings_fn
[] = {
84 [STR_ASSOC
].s
= "Source/Sink",
85 [STR_IF_CTRL
].s
= "Topology Control",
86 [STR_CLKSRC_IN
].s
= clksrc_in
,
87 [STR_CLKSRC_OUT
].s
= clksrc_out
,
88 [STR_USB_IT
].s
= "USBH Out",
89 [STR_IO_IT
].s
= "USBD Out",
90 [STR_USB_OT
].s
= "USBH In",
91 [STR_IO_OT
].s
= "USBD In",
92 [STR_AS_OUT_ALT0
].s
= "Playback Inactive",
93 [STR_AS_OUT_ALT1
].s
= "Playback Active",
94 [STR_AS_IN_ALT0
].s
= "Capture Inactive",
95 [STR_AS_IN_ALT1
].s
= "Capture Active",
99 static struct usb_gadget_strings str_fn
= {
100 .language
= 0x0409, /* en-us */
101 .strings
= strings_fn
,
104 static struct usb_gadget_strings
*fn_strings
[] = {
109 static struct usb_interface_assoc_descriptor iad_desc
= {
110 .bLength
= sizeof iad_desc
,
111 .bDescriptorType
= USB_DT_INTERFACE_ASSOCIATION
,
113 .bFirstInterface
= 0,
114 .bInterfaceCount
= 3,
115 .bFunctionClass
= USB_CLASS_AUDIO
,
116 .bFunctionSubClass
= UAC2_FUNCTION_SUBCLASS_UNDEFINED
,
117 .bFunctionProtocol
= UAC_VERSION_2
,
120 /* Audio Control Interface */
121 static struct usb_interface_descriptor std_ac_if_desc
= {
122 .bLength
= sizeof std_ac_if_desc
,
123 .bDescriptorType
= USB_DT_INTERFACE
,
125 .bAlternateSetting
= 0,
127 .bInterfaceClass
= USB_CLASS_AUDIO
,
128 .bInterfaceSubClass
= USB_SUBCLASS_AUDIOCONTROL
,
129 .bInterfaceProtocol
= UAC_VERSION_2
,
132 /* Clock source for IN traffic */
133 static struct uac_clock_source_descriptor in_clk_src_desc
= {
134 .bLength
= sizeof in_clk_src_desc
,
135 .bDescriptorType
= USB_DT_CS_INTERFACE
,
137 .bDescriptorSubtype
= UAC2_CLOCK_SOURCE
,
138 .bClockID
= USB_IN_CLK_ID
,
139 .bmAttributes
= UAC_CLOCK_SOURCE_TYPE_INT_FIXED
,
140 .bmControls
= (CONTROL_RDONLY
<< CLK_FREQ_CTRL
),
144 /* Clock source for OUT traffic */
145 static struct uac_clock_source_descriptor out_clk_src_desc
= {
146 .bLength
= sizeof out_clk_src_desc
,
147 .bDescriptorType
= USB_DT_CS_INTERFACE
,
149 .bDescriptorSubtype
= UAC2_CLOCK_SOURCE
,
150 .bClockID
= USB_OUT_CLK_ID
,
151 .bmAttributes
= UAC_CLOCK_SOURCE_TYPE_INT_FIXED
,
152 .bmControls
= (CONTROL_RDONLY
<< CLK_FREQ_CTRL
),
156 /* Input Terminal for USB_OUT */
157 static struct uac2_input_terminal_descriptor usb_out_it_desc
= {
158 .bLength
= sizeof usb_out_it_desc
,
159 .bDescriptorType
= USB_DT_CS_INTERFACE
,
161 .bDescriptorSubtype
= UAC_INPUT_TERMINAL
,
162 .bTerminalID
= USB_OUT_IT_ID
,
163 .wTerminalType
= cpu_to_le16(UAC_TERMINAL_STREAMING
),
165 .bCSourceID
= USB_OUT_CLK_ID
,
167 .bmControls
= cpu_to_le16(CONTROL_RDWR
<< COPY_CTRL
),
170 /* Input Terminal for I/O-In */
171 static struct uac2_input_terminal_descriptor io_in_it_desc
= {
172 .bLength
= sizeof io_in_it_desc
,
173 .bDescriptorType
= USB_DT_CS_INTERFACE
,
175 .bDescriptorSubtype
= UAC_INPUT_TERMINAL
,
176 .bTerminalID
= IO_IN_IT_ID
,
177 .wTerminalType
= cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED
),
179 .bCSourceID
= USB_IN_CLK_ID
,
181 .bmControls
= cpu_to_le16(CONTROL_RDWR
<< COPY_CTRL
),
184 /* Ouput Terminal for USB_IN */
185 static struct uac2_output_terminal_descriptor usb_in_ot_desc
= {
186 .bLength
= sizeof usb_in_ot_desc
,
187 .bDescriptorType
= USB_DT_CS_INTERFACE
,
189 .bDescriptorSubtype
= UAC_OUTPUT_TERMINAL
,
190 .bTerminalID
= USB_IN_OT_ID
,
191 .wTerminalType
= cpu_to_le16(UAC_TERMINAL_STREAMING
),
193 .bSourceID
= IO_IN_IT_ID
,
194 .bCSourceID
= USB_IN_CLK_ID
,
195 .bmControls
= cpu_to_le16(CONTROL_RDWR
<< COPY_CTRL
),
198 /* Ouput Terminal for I/O-Out */
199 static struct uac2_output_terminal_descriptor io_out_ot_desc
= {
200 .bLength
= sizeof io_out_ot_desc
,
201 .bDescriptorType
= USB_DT_CS_INTERFACE
,
203 .bDescriptorSubtype
= UAC_OUTPUT_TERMINAL
,
204 .bTerminalID
= IO_OUT_OT_ID
,
205 .wTerminalType
= cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED
),
207 .bSourceID
= USB_OUT_IT_ID
,
208 .bCSourceID
= USB_OUT_CLK_ID
,
209 .bmControls
= cpu_to_le16(CONTROL_RDWR
<< COPY_CTRL
),
212 static struct uac2_ac_header_descriptor ac_hdr_desc
= {
213 .bLength
= sizeof ac_hdr_desc
,
214 .bDescriptorType
= USB_DT_CS_INTERFACE
,
216 .bDescriptorSubtype
= UAC_MS_HEADER
,
217 .bcdADC
= cpu_to_le16(0x200),
218 .bCategory
= UAC2_FUNCTION_IO_BOX
,
219 .wTotalLength
= cpu_to_le16(sizeof in_clk_src_desc
220 + sizeof out_clk_src_desc
+ sizeof usb_out_it_desc
221 + sizeof io_in_it_desc
+ sizeof usb_in_ot_desc
222 + sizeof io_out_ot_desc
),
226 /* Audio Streaming OUT Interface - Alt0 */
227 static struct usb_interface_descriptor std_as_out_if0_desc
= {
228 .bLength
= sizeof std_as_out_if0_desc
,
229 .bDescriptorType
= USB_DT_INTERFACE
,
231 .bAlternateSetting
= 0,
233 .bInterfaceClass
= USB_CLASS_AUDIO
,
234 .bInterfaceSubClass
= USB_SUBCLASS_AUDIOSTREAMING
,
235 .bInterfaceProtocol
= UAC_VERSION_2
,
238 /* Audio Streaming OUT Interface - Alt1 */
239 static struct usb_interface_descriptor std_as_out_if1_desc
= {
240 .bLength
= sizeof std_as_out_if1_desc
,
241 .bDescriptorType
= USB_DT_INTERFACE
,
243 .bAlternateSetting
= 1,
245 .bInterfaceClass
= USB_CLASS_AUDIO
,
246 .bInterfaceSubClass
= USB_SUBCLASS_AUDIOSTREAMING
,
247 .bInterfaceProtocol
= UAC_VERSION_2
,
250 /* Audio Stream OUT Intface Desc */
251 static struct uac2_as_header_descriptor as_out_hdr_desc
= {
252 .bLength
= sizeof as_out_hdr_desc
,
253 .bDescriptorType
= USB_DT_CS_INTERFACE
,
255 .bDescriptorSubtype
= UAC_AS_GENERAL
,
256 .bTerminalLink
= USB_OUT_IT_ID
,
258 .bFormatType
= UAC_FORMAT_TYPE_I
,
259 .bmFormats
= cpu_to_le32(UAC_FORMAT_TYPE_I_PCM
),
263 /* Audio USB_OUT Format */
264 static struct uac2_format_type_i_descriptor as_out_fmt1_desc
= {
265 .bLength
= sizeof as_out_fmt1_desc
,
266 .bDescriptorType
= USB_DT_CS_INTERFACE
,
267 .bDescriptorSubtype
= UAC_FORMAT_TYPE
,
268 .bFormatType
= UAC_FORMAT_TYPE_I
,
271 /* STD AS ISO OUT Endpoint */
272 static struct usb_endpoint_descriptor fs_epout_desc
= {
273 .bLength
= USB_DT_ENDPOINT_SIZE
,
274 .bDescriptorType
= USB_DT_ENDPOINT
,
276 .bEndpointAddress
= USB_DIR_OUT
,
277 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
| USB_ENDPOINT_SYNC_ASYNC
,
278 .wMaxPacketSize
= cpu_to_le16(1023),
282 static struct usb_endpoint_descriptor hs_epout_desc
= {
283 .bLength
= USB_DT_ENDPOINT_SIZE
,
284 .bDescriptorType
= USB_DT_ENDPOINT
,
286 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
| USB_ENDPOINT_SYNC_ASYNC
,
287 .wMaxPacketSize
= cpu_to_le16(1024),
291 /* CS AS ISO OUT Endpoint */
292 static struct uac2_iso_endpoint_descriptor as_iso_out_desc
= {
293 .bLength
= sizeof as_iso_out_desc
,
294 .bDescriptorType
= USB_DT_CS_ENDPOINT
,
296 .bDescriptorSubtype
= UAC_EP_GENERAL
,
299 .bLockDelayUnits
= 0,
303 /* Audio Streaming IN Interface - Alt0 */
304 static struct usb_interface_descriptor std_as_in_if0_desc
= {
305 .bLength
= sizeof std_as_in_if0_desc
,
306 .bDescriptorType
= USB_DT_INTERFACE
,
308 .bAlternateSetting
= 0,
310 .bInterfaceClass
= USB_CLASS_AUDIO
,
311 .bInterfaceSubClass
= USB_SUBCLASS_AUDIOSTREAMING
,
312 .bInterfaceProtocol
= UAC_VERSION_2
,
315 /* Audio Streaming IN Interface - Alt1 */
316 static struct usb_interface_descriptor std_as_in_if1_desc
= {
317 .bLength
= sizeof std_as_in_if1_desc
,
318 .bDescriptorType
= USB_DT_INTERFACE
,
320 .bAlternateSetting
= 1,
322 .bInterfaceClass
= USB_CLASS_AUDIO
,
323 .bInterfaceSubClass
= USB_SUBCLASS_AUDIOSTREAMING
,
324 .bInterfaceProtocol
= UAC_VERSION_2
,
327 /* Audio Stream IN Intface Desc */
328 static struct uac2_as_header_descriptor as_in_hdr_desc
= {
329 .bLength
= sizeof as_in_hdr_desc
,
330 .bDescriptorType
= USB_DT_CS_INTERFACE
,
332 .bDescriptorSubtype
= UAC_AS_GENERAL
,
333 .bTerminalLink
= USB_IN_OT_ID
,
335 .bFormatType
= UAC_FORMAT_TYPE_I
,
336 .bmFormats
= cpu_to_le32(UAC_FORMAT_TYPE_I_PCM
),
340 /* Audio USB_IN Format */
341 static struct uac2_format_type_i_descriptor as_in_fmt1_desc
= {
342 .bLength
= sizeof as_in_fmt1_desc
,
343 .bDescriptorType
= USB_DT_CS_INTERFACE
,
344 .bDescriptorSubtype
= UAC_FORMAT_TYPE
,
345 .bFormatType
= UAC_FORMAT_TYPE_I
,
348 /* STD AS ISO IN Endpoint */
349 static struct usb_endpoint_descriptor fs_epin_desc
= {
350 .bLength
= USB_DT_ENDPOINT_SIZE
,
351 .bDescriptorType
= USB_DT_ENDPOINT
,
353 .bEndpointAddress
= USB_DIR_IN
,
354 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
| USB_ENDPOINT_SYNC_ASYNC
,
355 .wMaxPacketSize
= cpu_to_le16(1023),
359 static struct usb_endpoint_descriptor hs_epin_desc
= {
360 .bLength
= USB_DT_ENDPOINT_SIZE
,
361 .bDescriptorType
= USB_DT_ENDPOINT
,
363 .bmAttributes
= USB_ENDPOINT_XFER_ISOC
| USB_ENDPOINT_SYNC_ASYNC
,
364 .wMaxPacketSize
= cpu_to_le16(1024),
368 /* CS AS ISO IN Endpoint */
369 static struct uac2_iso_endpoint_descriptor as_iso_in_desc
= {
370 .bLength
= sizeof as_iso_in_desc
,
371 .bDescriptorType
= USB_DT_CS_ENDPOINT
,
373 .bDescriptorSubtype
= UAC_EP_GENERAL
,
376 .bLockDelayUnits
= 0,
380 static struct usb_descriptor_header
*fs_audio_desc
[] = {
381 (struct usb_descriptor_header
*)&iad_desc
,
382 (struct usb_descriptor_header
*)&std_ac_if_desc
,
384 (struct usb_descriptor_header
*)&ac_hdr_desc
,
385 (struct usb_descriptor_header
*)&in_clk_src_desc
,
386 (struct usb_descriptor_header
*)&out_clk_src_desc
,
387 (struct usb_descriptor_header
*)&usb_out_it_desc
,
388 (struct usb_descriptor_header
*)&io_in_it_desc
,
389 (struct usb_descriptor_header
*)&usb_in_ot_desc
,
390 (struct usb_descriptor_header
*)&io_out_ot_desc
,
392 (struct usb_descriptor_header
*)&std_as_out_if0_desc
,
393 (struct usb_descriptor_header
*)&std_as_out_if1_desc
,
395 (struct usb_descriptor_header
*)&as_out_hdr_desc
,
396 (struct usb_descriptor_header
*)&as_out_fmt1_desc
,
397 (struct usb_descriptor_header
*)&fs_epout_desc
,
398 (struct usb_descriptor_header
*)&as_iso_out_desc
,
400 (struct usb_descriptor_header
*)&std_as_in_if0_desc
,
401 (struct usb_descriptor_header
*)&std_as_in_if1_desc
,
403 (struct usb_descriptor_header
*)&as_in_hdr_desc
,
404 (struct usb_descriptor_header
*)&as_in_fmt1_desc
,
405 (struct usb_descriptor_header
*)&fs_epin_desc
,
406 (struct usb_descriptor_header
*)&as_iso_in_desc
,
410 static struct usb_descriptor_header
*hs_audio_desc
[] = {
411 (struct usb_descriptor_header
*)&iad_desc
,
412 (struct usb_descriptor_header
*)&std_ac_if_desc
,
414 (struct usb_descriptor_header
*)&ac_hdr_desc
,
415 (struct usb_descriptor_header
*)&in_clk_src_desc
,
416 (struct usb_descriptor_header
*)&out_clk_src_desc
,
417 (struct usb_descriptor_header
*)&usb_out_it_desc
,
418 (struct usb_descriptor_header
*)&io_in_it_desc
,
419 (struct usb_descriptor_header
*)&usb_in_ot_desc
,
420 (struct usb_descriptor_header
*)&io_out_ot_desc
,
422 (struct usb_descriptor_header
*)&std_as_out_if0_desc
,
423 (struct usb_descriptor_header
*)&std_as_out_if1_desc
,
425 (struct usb_descriptor_header
*)&as_out_hdr_desc
,
426 (struct usb_descriptor_header
*)&as_out_fmt1_desc
,
427 (struct usb_descriptor_header
*)&hs_epout_desc
,
428 (struct usb_descriptor_header
*)&as_iso_out_desc
,
430 (struct usb_descriptor_header
*)&std_as_in_if0_desc
,
431 (struct usb_descriptor_header
*)&std_as_in_if1_desc
,
433 (struct usb_descriptor_header
*)&as_in_hdr_desc
,
434 (struct usb_descriptor_header
*)&as_in_fmt1_desc
,
435 (struct usb_descriptor_header
*)&hs_epin_desc
,
436 (struct usb_descriptor_header
*)&as_iso_in_desc
,
440 struct cntrl_cur_lay3
{
444 struct cntrl_range_lay3
{
451 static void set_ep_max_packet_size(const struct f_uac2_opts
*uac2_opts
,
452 struct usb_endpoint_descriptor
*ep_desc
,
453 unsigned int factor
, bool is_playback
)
455 int chmask
, srate
, ssize
;
459 chmask
= uac2_opts
->p_chmask
;
460 srate
= uac2_opts
->p_srate
;
461 ssize
= uac2_opts
->p_ssize
;
463 chmask
= uac2_opts
->c_chmask
;
464 srate
= uac2_opts
->c_srate
;
465 ssize
= uac2_opts
->c_ssize
;
468 max_packet_size
= num_channels(chmask
) * ssize
*
469 DIV_ROUND_UP(srate
, factor
/ (1 << (ep_desc
->bInterval
- 1)));
470 ep_desc
->wMaxPacketSize
= cpu_to_le16(min_t(u16
, max_packet_size
,
471 le16_to_cpu(ep_desc
->wMaxPacketSize
)));
475 afunc_bind(struct usb_configuration
*cfg
, struct usb_function
*fn
)
477 struct f_uac2
*uac2
= func_to_uac2(fn
);
478 struct g_audio
*agdev
= func_to_g_audio(fn
);
479 struct usb_composite_dev
*cdev
= cfg
->cdev
;
480 struct usb_gadget
*gadget
= cdev
->gadget
;
481 struct device
*dev
= &gadget
->dev
;
482 struct f_uac2_opts
*uac2_opts
;
483 struct usb_string
*us
;
486 uac2_opts
= container_of(fn
->fi
, struct f_uac2_opts
, func_inst
);
488 us
= usb_gstrings_attach(cdev
, fn_strings
, ARRAY_SIZE(strings_fn
));
491 iad_desc
.iFunction
= us
[STR_ASSOC
].id
;
492 std_ac_if_desc
.iInterface
= us
[STR_IF_CTRL
].id
;
493 in_clk_src_desc
.iClockSource
= us
[STR_CLKSRC_IN
].id
;
494 out_clk_src_desc
.iClockSource
= us
[STR_CLKSRC_OUT
].id
;
495 usb_out_it_desc
.iTerminal
= us
[STR_USB_IT
].id
;
496 io_in_it_desc
.iTerminal
= us
[STR_IO_IT
].id
;
497 usb_in_ot_desc
.iTerminal
= us
[STR_USB_OT
].id
;
498 io_out_ot_desc
.iTerminal
= us
[STR_IO_OT
].id
;
499 std_as_out_if0_desc
.iInterface
= us
[STR_AS_OUT_ALT0
].id
;
500 std_as_out_if1_desc
.iInterface
= us
[STR_AS_OUT_ALT1
].id
;
501 std_as_in_if0_desc
.iInterface
= us
[STR_AS_IN_ALT0
].id
;
502 std_as_in_if1_desc
.iInterface
= us
[STR_AS_IN_ALT1
].id
;
505 /* Initialize the configurable parameters */
506 usb_out_it_desc
.bNrChannels
= num_channels(uac2_opts
->c_chmask
);
507 usb_out_it_desc
.bmChannelConfig
= cpu_to_le32(uac2_opts
->c_chmask
);
508 io_in_it_desc
.bNrChannels
= num_channels(uac2_opts
->p_chmask
);
509 io_in_it_desc
.bmChannelConfig
= cpu_to_le32(uac2_opts
->p_chmask
);
510 as_out_hdr_desc
.bNrChannels
= num_channels(uac2_opts
->c_chmask
);
511 as_out_hdr_desc
.bmChannelConfig
= cpu_to_le32(uac2_opts
->c_chmask
);
512 as_in_hdr_desc
.bNrChannels
= num_channels(uac2_opts
->p_chmask
);
513 as_in_hdr_desc
.bmChannelConfig
= cpu_to_le32(uac2_opts
->p_chmask
);
514 as_out_fmt1_desc
.bSubslotSize
= uac2_opts
->c_ssize
;
515 as_out_fmt1_desc
.bBitResolution
= uac2_opts
->c_ssize
* 8;
516 as_in_fmt1_desc
.bSubslotSize
= uac2_opts
->p_ssize
;
517 as_in_fmt1_desc
.bBitResolution
= uac2_opts
->p_ssize
* 8;
519 snprintf(clksrc_in
, sizeof(clksrc_in
), "%uHz", uac2_opts
->p_srate
);
520 snprintf(clksrc_out
, sizeof(clksrc_out
), "%uHz", uac2_opts
->c_srate
);
522 ret
= usb_interface_id(cfg
, fn
);
524 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
527 iad_desc
.bFirstInterface
= ret
;
529 std_ac_if_desc
.bInterfaceNumber
= ret
;
533 ret
= usb_interface_id(cfg
, fn
);
535 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
538 std_as_out_if0_desc
.bInterfaceNumber
= ret
;
539 std_as_out_if1_desc
.bInterfaceNumber
= ret
;
540 uac2
->as_out_intf
= ret
;
541 uac2
->as_out_alt
= 0;
543 ret
= usb_interface_id(cfg
, fn
);
545 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
548 std_as_in_if0_desc
.bInterfaceNumber
= ret
;
549 std_as_in_if1_desc
.bInterfaceNumber
= ret
;
550 uac2
->as_in_intf
= ret
;
553 /* Calculate wMaxPacketSize according to audio bandwidth */
554 set_ep_max_packet_size(uac2_opts
, &fs_epin_desc
, 1000, true);
555 set_ep_max_packet_size(uac2_opts
, &fs_epout_desc
, 1000, false);
556 set_ep_max_packet_size(uac2_opts
, &hs_epin_desc
, 8000, true);
557 set_ep_max_packet_size(uac2_opts
, &hs_epout_desc
, 8000, false);
559 agdev
->out_ep
= usb_ep_autoconfig(gadget
, &fs_epout_desc
);
560 if (!agdev
->out_ep
) {
561 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
565 agdev
->in_ep
= usb_ep_autoconfig(gadget
, &fs_epin_desc
);
567 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
571 agdev
->in_ep_maxpsize
= max_t(u16
,
572 le16_to_cpu(fs_epin_desc
.wMaxPacketSize
),
573 le16_to_cpu(hs_epin_desc
.wMaxPacketSize
));
574 agdev
->out_ep_maxpsize
= max_t(u16
,
575 le16_to_cpu(fs_epout_desc
.wMaxPacketSize
),
576 le16_to_cpu(hs_epout_desc
.wMaxPacketSize
));
578 hs_epout_desc
.bEndpointAddress
= fs_epout_desc
.bEndpointAddress
;
579 hs_epin_desc
.bEndpointAddress
= fs_epin_desc
.bEndpointAddress
;
581 ret
= usb_assign_descriptors(fn
, fs_audio_desc
, hs_audio_desc
, NULL
,
586 agdev
->gadget
= gadget
;
588 agdev
->params
.p_chmask
= uac2_opts
->p_chmask
;
589 agdev
->params
.p_srate
= uac2_opts
->p_srate
;
590 agdev
->params
.p_ssize
= uac2_opts
->p_ssize
;
591 agdev
->params
.c_chmask
= uac2_opts
->c_chmask
;
592 agdev
->params
.c_srate
= uac2_opts
->c_srate
;
593 agdev
->params
.c_ssize
= uac2_opts
->c_ssize
;
594 agdev
->params
.req_number
= uac2_opts
->req_number
;
595 ret
= g_audio_setup(agdev
, "UAC2 PCM", "UAC2_Gadget");
601 usb_free_all_descriptors(fn
);
602 agdev
->gadget
= NULL
;
607 afunc_set_alt(struct usb_function
*fn
, unsigned intf
, unsigned alt
)
609 struct usb_composite_dev
*cdev
= fn
->config
->cdev
;
610 struct f_uac2
*uac2
= func_to_uac2(fn
);
611 struct usb_gadget
*gadget
= cdev
->gadget
;
612 struct device
*dev
= &gadget
->dev
;
615 /* No i/f has more than 2 alt settings */
617 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
621 if (intf
== uac2
->ac_intf
) {
622 /* Control I/f has only 1 AltSetting - 0 */
624 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
630 if (intf
== uac2
->as_out_intf
) {
631 uac2
->as_out_alt
= alt
;
634 ret
= u_audio_start_capture(&uac2
->g_audio
);
636 u_audio_stop_capture(&uac2
->g_audio
);
637 } else if (intf
== uac2
->as_in_intf
) {
638 uac2
->as_in_alt
= alt
;
641 ret
= u_audio_start_playback(&uac2
->g_audio
);
643 u_audio_stop_playback(&uac2
->g_audio
);
645 dev_err(dev
, "%s:%d Error!\n", __func__
, __LINE__
);
653 afunc_get_alt(struct usb_function
*fn
, unsigned intf
)
655 struct f_uac2
*uac2
= func_to_uac2(fn
);
656 struct g_audio
*agdev
= func_to_g_audio(fn
);
658 if (intf
== uac2
->ac_intf
)
660 else if (intf
== uac2
->as_out_intf
)
661 return uac2
->as_out_alt
;
662 else if (intf
== uac2
->as_in_intf
)
663 return uac2
->as_in_alt
;
665 dev_err(&agdev
->gadget
->dev
,
666 "%s:%d Invalid Interface %d!\n",
667 __func__
, __LINE__
, intf
);
673 afunc_disable(struct usb_function
*fn
)
675 struct f_uac2
*uac2
= func_to_uac2(fn
);
678 uac2
->as_out_alt
= 0;
679 u_audio_stop_capture(&uac2
->g_audio
);
680 u_audio_stop_playback(&uac2
->g_audio
);
684 in_rq_cur(struct usb_function
*fn
, const struct usb_ctrlrequest
*cr
)
686 struct usb_request
*req
= fn
->config
->cdev
->req
;
687 struct g_audio
*agdev
= func_to_g_audio(fn
);
688 struct f_uac2_opts
*opts
;
689 u16 w_length
= le16_to_cpu(cr
->wLength
);
690 u16 w_index
= le16_to_cpu(cr
->wIndex
);
691 u16 w_value
= le16_to_cpu(cr
->wValue
);
692 u8 entity_id
= (w_index
>> 8) & 0xff;
693 u8 control_selector
= w_value
>> 8;
694 int value
= -EOPNOTSUPP
;
695 int p_srate
, c_srate
;
697 opts
= g_audio_to_uac2_opts(agdev
);
698 p_srate
= opts
->p_srate
;
699 c_srate
= opts
->c_srate
;
701 if (control_selector
== UAC2_CS_CONTROL_SAM_FREQ
) {
702 struct cntrl_cur_lay3 c
;
703 memset(&c
, 0, sizeof(struct cntrl_cur_lay3
));
705 if (entity_id
== USB_IN_CLK_ID
)
707 else if (entity_id
== USB_OUT_CLK_ID
)
710 value
= min_t(unsigned, w_length
, sizeof c
);
711 memcpy(req
->buf
, &c
, value
);
712 } else if (control_selector
== UAC2_CS_CONTROL_CLOCK_VALID
) {
714 value
= min_t(unsigned, w_length
, 1);
716 dev_err(&agdev
->gadget
->dev
,
717 "%s:%d control_selector=%d TODO!\n",
718 __func__
, __LINE__
, control_selector
);
725 in_rq_range(struct usb_function
*fn
, const struct usb_ctrlrequest
*cr
)
727 struct usb_request
*req
= fn
->config
->cdev
->req
;
728 struct g_audio
*agdev
= func_to_g_audio(fn
);
729 struct f_uac2_opts
*opts
;
730 u16 w_length
= le16_to_cpu(cr
->wLength
);
731 u16 w_index
= le16_to_cpu(cr
->wIndex
);
732 u16 w_value
= le16_to_cpu(cr
->wValue
);
733 u8 entity_id
= (w_index
>> 8) & 0xff;
734 u8 control_selector
= w_value
>> 8;
735 struct cntrl_range_lay3 r
;
736 int value
= -EOPNOTSUPP
;
737 int p_srate
, c_srate
;
739 opts
= g_audio_to_uac2_opts(agdev
);
740 p_srate
= opts
->p_srate
;
741 c_srate
= opts
->c_srate
;
743 if (control_selector
== UAC2_CS_CONTROL_SAM_FREQ
) {
744 if (entity_id
== USB_IN_CLK_ID
)
746 else if (entity_id
== USB_OUT_CLK_ID
)
755 value
= min_t(unsigned, w_length
, sizeof r
);
756 memcpy(req
->buf
, &r
, value
);
758 dev_err(&agdev
->gadget
->dev
,
759 "%s:%d control_selector=%d TODO!\n",
760 __func__
, __LINE__
, control_selector
);
767 ac_rq_in(struct usb_function
*fn
, const struct usb_ctrlrequest
*cr
)
769 if (cr
->bRequest
== UAC2_CS_CUR
)
770 return in_rq_cur(fn
, cr
);
771 else if (cr
->bRequest
== UAC2_CS_RANGE
)
772 return in_rq_range(fn
, cr
);
778 out_rq_cur(struct usb_function
*fn
, const struct usb_ctrlrequest
*cr
)
780 u16 w_length
= le16_to_cpu(cr
->wLength
);
781 u16 w_value
= le16_to_cpu(cr
->wValue
);
782 u8 control_selector
= w_value
>> 8;
784 if (control_selector
== UAC2_CS_CONTROL_SAM_FREQ
)
791 setup_rq_inf(struct usb_function
*fn
, const struct usb_ctrlrequest
*cr
)
793 struct f_uac2
*uac2
= func_to_uac2(fn
);
794 struct g_audio
*agdev
= func_to_g_audio(fn
);
795 u16 w_index
= le16_to_cpu(cr
->wIndex
);
796 u8 intf
= w_index
& 0xff;
798 if (intf
!= uac2
->ac_intf
) {
799 dev_err(&agdev
->gadget
->dev
,
800 "%s:%d Error!\n", __func__
, __LINE__
);
804 if (cr
->bRequestType
& USB_DIR_IN
)
805 return ac_rq_in(fn
, cr
);
806 else if (cr
->bRequest
== UAC2_CS_CUR
)
807 return out_rq_cur(fn
, cr
);
813 afunc_setup(struct usb_function
*fn
, const struct usb_ctrlrequest
*cr
)
815 struct usb_composite_dev
*cdev
= fn
->config
->cdev
;
816 struct g_audio
*agdev
= func_to_g_audio(fn
);
817 struct usb_request
*req
= cdev
->req
;
818 u16 w_length
= le16_to_cpu(cr
->wLength
);
819 int value
= -EOPNOTSUPP
;
821 /* Only Class specific requests are supposed to reach here */
822 if ((cr
->bRequestType
& USB_TYPE_MASK
) != USB_TYPE_CLASS
)
825 if ((cr
->bRequestType
& USB_RECIP_MASK
) == USB_RECIP_INTERFACE
)
826 value
= setup_rq_inf(fn
, cr
);
828 dev_err(&agdev
->gadget
->dev
, "%s:%d Error!\n",
833 req
->zero
= value
< w_length
;
834 value
= usb_ep_queue(cdev
->gadget
->ep0
, req
, GFP_ATOMIC
);
836 dev_err(&agdev
->gadget
->dev
,
837 "%s:%d Error!\n", __func__
, __LINE__
);
845 static inline struct f_uac2_opts
*to_f_uac2_opts(struct config_item
*item
)
847 return container_of(to_config_group(item
), struct f_uac2_opts
,
851 static void f_uac2_attr_release(struct config_item
*item
)
853 struct f_uac2_opts
*opts
= to_f_uac2_opts(item
);
855 usb_put_function_instance(&opts
->func_inst
);
858 static struct configfs_item_operations f_uac2_item_ops
= {
859 .release
= f_uac2_attr_release
,
862 #define UAC2_ATTRIBUTE(name) \
863 static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \
866 struct f_uac2_opts *opts = to_f_uac2_opts(item); \
869 mutex_lock(&opts->lock); \
870 result = sprintf(page, "%u\n", opts->name); \
871 mutex_unlock(&opts->lock); \
876 static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \
877 const char *page, size_t len) \
879 struct f_uac2_opts *opts = to_f_uac2_opts(item); \
883 mutex_lock(&opts->lock); \
884 if (opts->refcnt) { \
889 ret = kstrtou32(page, 0, &num); \
897 mutex_unlock(&opts->lock); \
901 CONFIGFS_ATTR(f_uac2_opts_, name)
903 UAC2_ATTRIBUTE(p_chmask
);
904 UAC2_ATTRIBUTE(p_srate
);
905 UAC2_ATTRIBUTE(p_ssize
);
906 UAC2_ATTRIBUTE(c_chmask
);
907 UAC2_ATTRIBUTE(c_srate
);
908 UAC2_ATTRIBUTE(c_ssize
);
909 UAC2_ATTRIBUTE(req_number
);
911 static struct configfs_attribute
*f_uac2_attrs
[] = {
912 &f_uac2_opts_attr_p_chmask
,
913 &f_uac2_opts_attr_p_srate
,
914 &f_uac2_opts_attr_p_ssize
,
915 &f_uac2_opts_attr_c_chmask
,
916 &f_uac2_opts_attr_c_srate
,
917 &f_uac2_opts_attr_c_ssize
,
918 &f_uac2_opts_attr_req_number
,
922 static const struct config_item_type f_uac2_func_type
= {
923 .ct_item_ops
= &f_uac2_item_ops
,
924 .ct_attrs
= f_uac2_attrs
,
925 .ct_owner
= THIS_MODULE
,
928 static void afunc_free_inst(struct usb_function_instance
*f
)
930 struct f_uac2_opts
*opts
;
932 opts
= container_of(f
, struct f_uac2_opts
, func_inst
);
936 static struct usb_function_instance
*afunc_alloc_inst(void)
938 struct f_uac2_opts
*opts
;
940 opts
= kzalloc(sizeof(*opts
), GFP_KERNEL
);
942 return ERR_PTR(-ENOMEM
);
944 mutex_init(&opts
->lock
);
945 opts
->func_inst
.free_func_inst
= afunc_free_inst
;
947 config_group_init_type_name(&opts
->func_inst
.group
, "",
950 opts
->p_chmask
= UAC2_DEF_PCHMASK
;
951 opts
->p_srate
= UAC2_DEF_PSRATE
;
952 opts
->p_ssize
= UAC2_DEF_PSSIZE
;
953 opts
->c_chmask
= UAC2_DEF_CCHMASK
;
954 opts
->c_srate
= UAC2_DEF_CSRATE
;
955 opts
->c_ssize
= UAC2_DEF_CSSIZE
;
956 opts
->req_number
= UAC2_DEF_REQ_NUM
;
957 return &opts
->func_inst
;
960 static void afunc_free(struct usb_function
*f
)
962 struct g_audio
*agdev
;
963 struct f_uac2_opts
*opts
;
965 agdev
= func_to_g_audio(f
);
966 opts
= container_of(f
->fi
, struct f_uac2_opts
, func_inst
);
968 mutex_lock(&opts
->lock
);
970 mutex_unlock(&opts
->lock
);
973 static void afunc_unbind(struct usb_configuration
*c
, struct usb_function
*f
)
975 struct g_audio
*agdev
= func_to_g_audio(f
);
977 g_audio_cleanup(agdev
);
978 usb_free_all_descriptors(f
);
980 agdev
->gadget
= NULL
;
983 static struct usb_function
*afunc_alloc(struct usb_function_instance
*fi
)
986 struct f_uac2_opts
*opts
;
988 uac2
= kzalloc(sizeof(*uac2
), GFP_KERNEL
);
990 return ERR_PTR(-ENOMEM
);
992 opts
= container_of(fi
, struct f_uac2_opts
, func_inst
);
993 mutex_lock(&opts
->lock
);
995 mutex_unlock(&opts
->lock
);
997 uac2
->g_audio
.func
.name
= "uac2_func";
998 uac2
->g_audio
.func
.bind
= afunc_bind
;
999 uac2
->g_audio
.func
.unbind
= afunc_unbind
;
1000 uac2
->g_audio
.func
.set_alt
= afunc_set_alt
;
1001 uac2
->g_audio
.func
.get_alt
= afunc_get_alt
;
1002 uac2
->g_audio
.func
.disable
= afunc_disable
;
1003 uac2
->g_audio
.func
.setup
= afunc_setup
;
1004 uac2
->g_audio
.func
.free_func
= afunc_free
;
1006 return &uac2
->g_audio
.func
;
1009 DECLARE_USB_FUNCTION_INIT(uac2
, afunc_alloc_inst
, afunc_alloc
);
1010 MODULE_LICENSE("GPL");
1011 MODULE_AUTHOR("Yadwinder Singh");
1012 MODULE_AUTHOR("Jaswinder Singh");