1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * audio.c -- Audio gadget driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
6*4882a593Smuzhiyun * Copyright (C) 2008 Analog Devices, Inc
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun /* #define VERBOSE_DEBUG */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/usb/composite.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define DRIVER_DESC "Linux USB Audio Gadget"
16*4882a593Smuzhiyun #define DRIVER_VERSION "Feb 2, 2012"
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun USB_GADGET_COMPOSITE_OPTIONS();
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1
21*4882a593Smuzhiyun #include "u_uac2.h"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* Playback(USB-IN) Default Stereo - Fl/Fr */
24*4882a593Smuzhiyun static int p_chmask = UAC2_DEF_PCHMASK;
25*4882a593Smuzhiyun module_param(p_chmask, uint, 0444);
26*4882a593Smuzhiyun MODULE_PARM_DESC(p_chmask, "Playback Channel Mask");
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /* Playback Default 48 KHz */
29*4882a593Smuzhiyun static int p_srates[UAC_MAX_RATES] = {UAC2_DEF_PSRATE};
30*4882a593Smuzhiyun static int p_srates_cnt = 1;
31*4882a593Smuzhiyun module_param_array_named(p_srate, p_srates, uint, &p_srates_cnt, 0444);
32*4882a593Smuzhiyun MODULE_PARM_DESC(p_srate, "Playback Sampling Rates (array)");
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /* Playback Default 16bits/sample */
35*4882a593Smuzhiyun static int p_ssize = UAC2_DEF_PSSIZE;
36*4882a593Smuzhiyun module_param(p_ssize, uint, 0444);
37*4882a593Smuzhiyun MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)");
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /* Capture(USB-OUT) Default Stereo - Fl/Fr */
40*4882a593Smuzhiyun static int c_chmask = UAC2_DEF_CCHMASK;
41*4882a593Smuzhiyun module_param(c_chmask, uint, 0444);
42*4882a593Smuzhiyun MODULE_PARM_DESC(c_chmask, "Capture Channel Mask");
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* Capture Default 64 KHz */
45*4882a593Smuzhiyun static int c_srates[UAC_MAX_RATES] = {UAC2_DEF_CSRATE};
46*4882a593Smuzhiyun static int c_srates_cnt = 1;
47*4882a593Smuzhiyun module_param_array_named(c_srate, c_srates, uint, &c_srates_cnt, 0444);
48*4882a593Smuzhiyun MODULE_PARM_DESC(c_srate, "Capture Sampling Rates (array)");
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun /* Capture Default 16bits/sample */
51*4882a593Smuzhiyun static int c_ssize = UAC2_DEF_CSSIZE;
52*4882a593Smuzhiyun module_param(c_ssize, uint, 0444);
53*4882a593Smuzhiyun MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
54*4882a593Smuzhiyun #else
55*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1_LEGACY
56*4882a593Smuzhiyun #include "u_uac1.h"
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /* Playback(USB-IN) Default Stereo - Fl/Fr */
59*4882a593Smuzhiyun static int p_chmask = UAC1_DEF_PCHMASK;
60*4882a593Smuzhiyun module_param(p_chmask, uint, 0444);
61*4882a593Smuzhiyun MODULE_PARM_DESC(p_chmask, "Playback Channel Mask");
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /* Playback Default 48 KHz */
64*4882a593Smuzhiyun static int p_srates[UAC_MAX_RATES] = {UAC1_DEF_PSRATE};
65*4882a593Smuzhiyun static int p_srates_cnt = 1;
66*4882a593Smuzhiyun module_param_array_named(p_srate, p_srates, uint, &p_srates_cnt, 0444);
67*4882a593Smuzhiyun MODULE_PARM_DESC(p_srate, "Playback Sampling Rates (array)");
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /* Playback Default 16bits/sample */
70*4882a593Smuzhiyun static int p_ssize = UAC1_DEF_PSSIZE;
71*4882a593Smuzhiyun module_param(p_ssize, uint, 0444);
72*4882a593Smuzhiyun MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)");
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /* Capture(USB-OUT) Default Stereo - Fl/Fr */
75*4882a593Smuzhiyun static int c_chmask = UAC1_DEF_CCHMASK;
76*4882a593Smuzhiyun module_param(c_chmask, uint, 0444);
77*4882a593Smuzhiyun MODULE_PARM_DESC(c_chmask, "Capture Channel Mask");
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /* Capture Default 48 KHz */
80*4882a593Smuzhiyun static int c_srates[UAC_MAX_RATES] = {UAC1_DEF_CSRATE};
81*4882a593Smuzhiyun static int c_srates_cnt = 1;
82*4882a593Smuzhiyun module_param_array_named(c_srate, c_srates, uint, &c_srates_cnt, 0444);
83*4882a593Smuzhiyun MODULE_PARM_DESC(c_srate, "Capture Sampling Rates (array)");
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /* Capture Default 16bits/sample */
86*4882a593Smuzhiyun static int c_ssize = UAC1_DEF_CSSIZE;
87*4882a593Smuzhiyun module_param(c_ssize, uint, 0444);
88*4882a593Smuzhiyun MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
89*4882a593Smuzhiyun #else /* CONFIG_GADGET_UAC1_LEGACY */
90*4882a593Smuzhiyun #include "u_uac1_legacy.h"
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun static char *fn_play = FILE_PCM_PLAYBACK;
93*4882a593Smuzhiyun module_param(fn_play, charp, 0444);
94*4882a593Smuzhiyun MODULE_PARM_DESC(fn_play, "Playback PCM device file name");
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun static char *fn_cap = FILE_PCM_CAPTURE;
97*4882a593Smuzhiyun module_param(fn_cap, charp, 0444);
98*4882a593Smuzhiyun MODULE_PARM_DESC(fn_cap, "Capture PCM device file name");
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static char *fn_cntl = FILE_CONTROL;
101*4882a593Smuzhiyun module_param(fn_cntl, charp, 0444);
102*4882a593Smuzhiyun MODULE_PARM_DESC(fn_cntl, "Control device file name");
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun static int req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE;
105*4882a593Smuzhiyun module_param(req_buf_size, int, 0444);
106*4882a593Smuzhiyun MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size");
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun static int req_count = UAC1_REQ_COUNT;
109*4882a593Smuzhiyun module_param(req_count, int, 0444);
110*4882a593Smuzhiyun MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count");
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun static int audio_buf_size = UAC1_AUDIO_BUF_SIZE;
113*4882a593Smuzhiyun module_param(audio_buf_size, int, 0444);
114*4882a593Smuzhiyun MODULE_PARM_DESC(audio_buf_size, "Audio buffer size");
115*4882a593Smuzhiyun #endif /* CONFIG_GADGET_UAC1_LEGACY */
116*4882a593Smuzhiyun #endif
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /* string IDs are assigned dynamically */
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun static struct usb_string strings_dev[] = {
121*4882a593Smuzhiyun [USB_GADGET_MANUFACTURER_IDX].s = "",
122*4882a593Smuzhiyun [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
123*4882a593Smuzhiyun [USB_GADGET_SERIAL_IDX].s = "",
124*4882a593Smuzhiyun { } /* end of list */
125*4882a593Smuzhiyun };
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun static struct usb_gadget_strings stringtab_dev = {
128*4882a593Smuzhiyun .language = 0x0409, /* en-us */
129*4882a593Smuzhiyun .strings = strings_dev,
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun static struct usb_gadget_strings *audio_strings[] = {
133*4882a593Smuzhiyun &stringtab_dev,
134*4882a593Smuzhiyun NULL,
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1
138*4882a593Smuzhiyun static struct usb_function_instance *fi_uac2;
139*4882a593Smuzhiyun static struct usb_function *f_uac2;
140*4882a593Smuzhiyun #else
141*4882a593Smuzhiyun static struct usb_function_instance *fi_uac1;
142*4882a593Smuzhiyun static struct usb_function *f_uac1;
143*4882a593Smuzhiyun #endif
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
148*4882a593Smuzhiyun * Instead: allocate your own, using normal USB-IF procedures.
149*4882a593Smuzhiyun */
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* Thanks to Linux Foundation for donating this product ID. */
152*4882a593Smuzhiyun #define AUDIO_VENDOR_NUM 0x1d6b /* Linux Foundation */
153*4882a593Smuzhiyun #define AUDIO_PRODUCT_NUM 0x0101 /* Linux-USB Audio Gadget */
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun static struct usb_device_descriptor device_desc = {
158*4882a593Smuzhiyun .bLength = sizeof device_desc,
159*4882a593Smuzhiyun .bDescriptorType = USB_DT_DEVICE,
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* .bcdUSB = DYNAMIC */
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun #ifdef CONFIG_GADGET_UAC1_LEGACY
164*4882a593Smuzhiyun .bDeviceClass = USB_CLASS_PER_INTERFACE,
165*4882a593Smuzhiyun .bDeviceSubClass = 0,
166*4882a593Smuzhiyun .bDeviceProtocol = 0,
167*4882a593Smuzhiyun #else
168*4882a593Smuzhiyun .bDeviceClass = USB_CLASS_MISC,
169*4882a593Smuzhiyun .bDeviceSubClass = 0x02,
170*4882a593Smuzhiyun .bDeviceProtocol = 0x01,
171*4882a593Smuzhiyun #endif
172*4882a593Smuzhiyun /* .bMaxPacketSize0 = f(hardware) */
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /* Vendor and product id defaults change according to what configs
175*4882a593Smuzhiyun * we support. (As does bNumConfigurations.) These values can
176*4882a593Smuzhiyun * also be overridden by module parameters.
177*4882a593Smuzhiyun */
178*4882a593Smuzhiyun .idVendor = cpu_to_le16(AUDIO_VENDOR_NUM),
179*4882a593Smuzhiyun .idProduct = cpu_to_le16(AUDIO_PRODUCT_NUM),
180*4882a593Smuzhiyun /* .bcdDevice = f(hardware) */
181*4882a593Smuzhiyun /* .iManufacturer = DYNAMIC */
182*4882a593Smuzhiyun /* .iProduct = DYNAMIC */
183*4882a593Smuzhiyun /* NO SERIAL NUMBER */
184*4882a593Smuzhiyun .bNumConfigurations = 1,
185*4882a593Smuzhiyun };
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun static const struct usb_descriptor_header *otg_desc[2];
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
190*4882a593Smuzhiyun
audio_do_config(struct usb_configuration * c)191*4882a593Smuzhiyun static int audio_do_config(struct usb_configuration *c)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun int status;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun /* FIXME alloc iConfiguration string, set it in c->strings */
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun if (gadget_is_otg(c->cdev->gadget)) {
198*4882a593Smuzhiyun c->descriptors = otg_desc;
199*4882a593Smuzhiyun c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun #ifdef CONFIG_GADGET_UAC1
203*4882a593Smuzhiyun f_uac1 = usb_get_function(fi_uac1);
204*4882a593Smuzhiyun if (IS_ERR(f_uac1)) {
205*4882a593Smuzhiyun status = PTR_ERR(f_uac1);
206*4882a593Smuzhiyun return status;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun status = usb_add_function(c, f_uac1);
210*4882a593Smuzhiyun if (status < 0) {
211*4882a593Smuzhiyun usb_put_function(f_uac1);
212*4882a593Smuzhiyun return status;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun #else
215*4882a593Smuzhiyun f_uac2 = usb_get_function(fi_uac2);
216*4882a593Smuzhiyun if (IS_ERR(f_uac2)) {
217*4882a593Smuzhiyun status = PTR_ERR(f_uac2);
218*4882a593Smuzhiyun return status;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun status = usb_add_function(c, f_uac2);
222*4882a593Smuzhiyun if (status < 0) {
223*4882a593Smuzhiyun usb_put_function(f_uac2);
224*4882a593Smuzhiyun return status;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun #endif
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun return 0;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun static struct usb_configuration audio_config_driver = {
232*4882a593Smuzhiyun .label = DRIVER_DESC,
233*4882a593Smuzhiyun .bConfigurationValue = 1,
234*4882a593Smuzhiyun /* .iConfiguration = DYNAMIC */
235*4882a593Smuzhiyun .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
239*4882a593Smuzhiyun
audio_bind(struct usb_composite_dev * cdev)240*4882a593Smuzhiyun static int audio_bind(struct usb_composite_dev *cdev)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1
243*4882a593Smuzhiyun struct f_uac2_opts *uac2_opts;
244*4882a593Smuzhiyun int i;
245*4882a593Smuzhiyun #else
246*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1_LEGACY
247*4882a593Smuzhiyun struct f_uac1_opts *uac1_opts;
248*4882a593Smuzhiyun int i;
249*4882a593Smuzhiyun #else
250*4882a593Smuzhiyun struct f_uac1_legacy_opts *uac1_opts;
251*4882a593Smuzhiyun #endif
252*4882a593Smuzhiyun #endif
253*4882a593Smuzhiyun int status;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1
256*4882a593Smuzhiyun fi_uac2 = usb_get_function_instance("uac2");
257*4882a593Smuzhiyun if (IS_ERR(fi_uac2))
258*4882a593Smuzhiyun return PTR_ERR(fi_uac2);
259*4882a593Smuzhiyun #else
260*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1_LEGACY
261*4882a593Smuzhiyun fi_uac1 = usb_get_function_instance("uac1");
262*4882a593Smuzhiyun #else
263*4882a593Smuzhiyun fi_uac1 = usb_get_function_instance("uac1_legacy");
264*4882a593Smuzhiyun #endif
265*4882a593Smuzhiyun if (IS_ERR(fi_uac1))
266*4882a593Smuzhiyun return PTR_ERR(fi_uac1);
267*4882a593Smuzhiyun #endif
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1
270*4882a593Smuzhiyun uac2_opts = container_of(fi_uac2, struct f_uac2_opts, func_inst);
271*4882a593Smuzhiyun uac2_opts->p_chmask = p_chmask;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun for (i = 0; i < p_srates_cnt; ++i)
274*4882a593Smuzhiyun uac2_opts->p_srates[i] = p_srates[i];
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun uac2_opts->p_ssize = p_ssize;
277*4882a593Smuzhiyun uac2_opts->c_chmask = c_chmask;
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun for (i = 0; i < c_srates_cnt; ++i)
280*4882a593Smuzhiyun uac2_opts->c_srates[i] = c_srates[i];
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun uac2_opts->c_ssize = c_ssize;
283*4882a593Smuzhiyun uac2_opts->req_number = UAC2_DEF_REQ_NUM;
284*4882a593Smuzhiyun #else
285*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1_LEGACY
286*4882a593Smuzhiyun uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst);
287*4882a593Smuzhiyun uac1_opts->p_chmask = p_chmask;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun for (i = 0; i < p_srates_cnt; ++i)
290*4882a593Smuzhiyun uac1_opts->p_srates[i] = p_srates[i];
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun uac1_opts->p_ssize = p_ssize;
293*4882a593Smuzhiyun uac1_opts->c_chmask = c_chmask;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun for (i = 0; i < c_srates_cnt; ++i)
296*4882a593Smuzhiyun uac1_opts->c_srates[i] = c_srates[i];
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun uac1_opts->c_ssize = c_ssize;
299*4882a593Smuzhiyun uac1_opts->req_number = UAC1_DEF_REQ_NUM;
300*4882a593Smuzhiyun #else /* CONFIG_GADGET_UAC1_LEGACY */
301*4882a593Smuzhiyun uac1_opts = container_of(fi_uac1, struct f_uac1_legacy_opts, func_inst);
302*4882a593Smuzhiyun uac1_opts->fn_play = fn_play;
303*4882a593Smuzhiyun uac1_opts->fn_cap = fn_cap;
304*4882a593Smuzhiyun uac1_opts->fn_cntl = fn_cntl;
305*4882a593Smuzhiyun uac1_opts->req_buf_size = req_buf_size;
306*4882a593Smuzhiyun uac1_opts->req_count = req_count;
307*4882a593Smuzhiyun uac1_opts->audio_buf_size = audio_buf_size;
308*4882a593Smuzhiyun #endif /* CONFIG_GADGET_UAC1_LEGACY */
309*4882a593Smuzhiyun #endif
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun status = usb_string_ids_tab(cdev, strings_dev);
312*4882a593Smuzhiyun if (status < 0)
313*4882a593Smuzhiyun goto fail;
314*4882a593Smuzhiyun device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
315*4882a593Smuzhiyun device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun if (gadget_is_otg(cdev->gadget) && !otg_desc[0]) {
318*4882a593Smuzhiyun struct usb_descriptor_header *usb_desc;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun usb_desc = usb_otg_descriptor_alloc(cdev->gadget);
321*4882a593Smuzhiyun if (!usb_desc) {
322*4882a593Smuzhiyun status = -ENOMEM;
323*4882a593Smuzhiyun goto fail;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun usb_otg_descriptor_init(cdev->gadget, usb_desc);
326*4882a593Smuzhiyun otg_desc[0] = usb_desc;
327*4882a593Smuzhiyun otg_desc[1] = NULL;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun status = usb_add_config(cdev, &audio_config_driver, audio_do_config);
331*4882a593Smuzhiyun if (status < 0)
332*4882a593Smuzhiyun goto fail_otg_desc;
333*4882a593Smuzhiyun usb_composite_overwrite_options(cdev, &coverwrite);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun INFO(cdev, "%s, version: %s\n", DRIVER_DESC, DRIVER_VERSION);
336*4882a593Smuzhiyun return 0;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun fail_otg_desc:
339*4882a593Smuzhiyun kfree(otg_desc[0]);
340*4882a593Smuzhiyun otg_desc[0] = NULL;
341*4882a593Smuzhiyun fail:
342*4882a593Smuzhiyun #ifndef CONFIG_GADGET_UAC1
343*4882a593Smuzhiyun usb_put_function_instance(fi_uac2);
344*4882a593Smuzhiyun #else
345*4882a593Smuzhiyun usb_put_function_instance(fi_uac1);
346*4882a593Smuzhiyun #endif
347*4882a593Smuzhiyun return status;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
audio_unbind(struct usb_composite_dev * cdev)350*4882a593Smuzhiyun static int audio_unbind(struct usb_composite_dev *cdev)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun #ifdef CONFIG_GADGET_UAC1
353*4882a593Smuzhiyun if (!IS_ERR_OR_NULL(f_uac1))
354*4882a593Smuzhiyun usb_put_function(f_uac1);
355*4882a593Smuzhiyun if (!IS_ERR_OR_NULL(fi_uac1))
356*4882a593Smuzhiyun usb_put_function_instance(fi_uac1);
357*4882a593Smuzhiyun #else
358*4882a593Smuzhiyun if (!IS_ERR_OR_NULL(f_uac2))
359*4882a593Smuzhiyun usb_put_function(f_uac2);
360*4882a593Smuzhiyun if (!IS_ERR_OR_NULL(fi_uac2))
361*4882a593Smuzhiyun usb_put_function_instance(fi_uac2);
362*4882a593Smuzhiyun #endif
363*4882a593Smuzhiyun kfree(otg_desc[0]);
364*4882a593Smuzhiyun otg_desc[0] = NULL;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun return 0;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun static struct usb_composite_driver audio_driver = {
370*4882a593Smuzhiyun .name = "g_audio",
371*4882a593Smuzhiyun .dev = &device_desc,
372*4882a593Smuzhiyun .strings = audio_strings,
373*4882a593Smuzhiyun .max_speed = USB_SPEED_HIGH,
374*4882a593Smuzhiyun .bind = audio_bind,
375*4882a593Smuzhiyun .unbind = audio_unbind,
376*4882a593Smuzhiyun };
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun module_usb_composite_driver(audio_driver);
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
381*4882a593Smuzhiyun MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>");
382*4882a593Smuzhiyun MODULE_LICENSE("GPL");
383*4882a593Smuzhiyun
384