aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Wu <cooloney@kernel.org>2009-06-03 09:17:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:47 -0400
commitc6994e6f067cf0fc4c6cca3d164018b1150916f8 (patch)
treed971c529cbd4684e5c1c5fcb67f3f09d1cca4295
parentc47d7b09891abb4f8b222317c89c7469bed8db3a (diff)
USB: gadget: add USB Audio Gadget driver
Funtions added: - setup all the USB audio class device descriptors - handle class specific setup request - receive data from USB host by ISO transfer - play audio data by ALSA sound card - open and setup playback PCM interface - set default playback PCM parameters - provide playback functions for USB audio driver - provide PCM parameters set/get functions Test on: - Host: Ubuntu 8.10, kernel 2.6.27 - Gadget: EZKIT-BF548 with ASoC AD1980 codec Todo: - add real Mute control code - add real Volume control code - maybe find another way to replace dynamic buffer handling with static buffer allocation - test on Windows system - provide control interface to handle mute/volume control - provide capture interface in the future - test on BF527, other USB device controler and other audio codec Signed-off-by: Bryan Wu <cooloney@kernel.org> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/gadget/Kconfig14
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/audio.c302
-rw-r--r--drivers/usb/gadget/f_audio.c707
-rw-r--r--drivers/usb/gadget/u_audio.c319
-rw-r--r--drivers/usb/gadget/u_audio.h56
6 files changed, 1400 insertions, 0 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 924bb7a1cecf..ef9d9086cddc 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -580,6 +580,20 @@ config USB_ZERO_HNPTEST
580 the "B-Peripheral" role, that device will use HNP to let this 580 the "B-Peripheral" role, that device will use HNP to let this
581 one serve as the USB host instead (in the "B-Host" role). 581 one serve as the USB host instead (in the "B-Host" role).
582 582
583config USB_AUDIO
584 tristate "Audio Gadget (EXPERIMENTAL)"
585 depends on SND
586 help
587 Gadget Audio is compatible with USB Audio Class specification 1.0.
588 It will include at least one AudioControl interface, zero or more
589 AudioStream interface and zero or more MIDIStream interface.
590
591 Gadget Audio will use on-board ALSA (CONFIG_SND) audio card to
592 playback or capture audio stream.
593
594 Say "y" to link the driver statically, or "m" to build a
595 dynamically linked module called "g_audio".
596
583config USB_ETH 597config USB_ETH
584 tristate "Ethernet Gadget (with CDC Ethernet support)" 598 tristate "Ethernet Gadget (with CDC Ethernet support)"
585 depends on NET 599 depends on NET
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 9be2fbd6f5c2..fc9a7dc01047 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o
31# USB gadget drivers 31# USB gadget drivers
32# 32#
33g_zero-objs := zero.o 33g_zero-objs := zero.o
34g_audio-objs := audio.o
34g_ether-objs := ether.o 35g_ether-objs := ether.o
35g_serial-objs := serial.o 36g_serial-objs := serial.o
36g_midi-objs := gmidi.o 37g_midi-objs := gmidi.o
@@ -40,6 +41,7 @@ g_printer-objs := printer.o
40g_cdc-objs := cdc2.o 41g_cdc-objs := cdc2.o
41 42
42obj-$(CONFIG_USB_ZERO) += g_zero.o 43obj-$(CONFIG_USB_ZERO) += g_zero.o
44obj-$(CONFIG_USB_AUDIO) += g_audio.o
43obj-$(CONFIG_USB_ETH) += g_ether.o 45obj-$(CONFIG_USB_ETH) += g_ether.o
44obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o 46obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
45obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o 47obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
new file mode 100644
index 000000000000..94de7e864614
--- /dev/null
+++ b/drivers/usb/gadget/audio.c
@@ -0,0 +1,302 @@
1/*
2 * audio.c -- Audio gadget driver
3 *
4 * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
5 * Copyright (C) 2008 Analog Devices, Inc
6 *
7 * Enter bugs at http://blackfin.uclinux.org/
8 *
9 * Licensed under the GPL-2 or later.
10 */
11
12/* #define VERBOSE_DEBUG */
13
14#include <linux/kernel.h>
15#include <linux/utsname.h>
16
17#include "u_audio.h"
18
19#define DRIVER_DESC "Linux USB Audio Gadget"
20#define DRIVER_VERSION "Dec 18, 2008"
21
22/*-------------------------------------------------------------------------*/
23
24/*
25 * Kbuild is not very cooperative with respect to linking separately
26 * compiled library objects into one module. So for now we won't use
27 * separate compilation ... ensuring init/exit sections work to shrink
28 * the runtime footprint, and giving us at least some parts of what
29 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
30 */
31#include "composite.c"
32#include "usbstring.c"
33#include "config.c"
34#include "epautoconf.c"
35
36#include "u_audio.c"
37#include "f_audio.c"
38
39/*-------------------------------------------------------------------------*/
40
41/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
42 * Instead: allocate your own, using normal USB-IF procedures.
43 */
44
45/* Thanks to NetChip Technologies for donating this product ID. */
46#define AUDIO_VENDOR_NUM 0x0525 /* NetChip */
47#define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */
48
49/*-------------------------------------------------------------------------*/
50
51static struct usb_device_descriptor device_desc = {
52 .bLength = sizeof device_desc,
53 .bDescriptorType = USB_DT_DEVICE,
54
55 .bcdUSB = __constant_cpu_to_le16(0x200),
56
57 .bDeviceClass = USB_CLASS_PER_INTERFACE,
58 .bDeviceSubClass = 0,
59 .bDeviceProtocol = 0,
60 /* .bMaxPacketSize0 = f(hardware) */
61
62 /* Vendor and product id defaults change according to what configs
63 * we support. (As does bNumConfigurations.) These values can
64 * also be overridden by module parameters.
65 */
66 .idVendor = __constant_cpu_to_le16(AUDIO_VENDOR_NUM),
67 .idProduct = __constant_cpu_to_le16(AUDIO_PRODUCT_NUM),
68 /* .bcdDevice = f(hardware) */
69 /* .iManufacturer = DYNAMIC */
70 /* .iProduct = DYNAMIC */
71 /* NO SERIAL NUMBER */
72 .bNumConfigurations = 1,
73};
74
75static struct usb_otg_descriptor otg_descriptor = {
76 .bLength = sizeof otg_descriptor,
77 .bDescriptorType = USB_DT_OTG,
78
79 /* REVISIT SRP-only hardware is possible, although
80 * it would not be called "OTG" ...
81 */
82 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
83};
84
85static const struct usb_descriptor_header *otg_desc[] = {
86 (struct usb_descriptor_header *) &otg_descriptor,
87 NULL,
88};
89
90/*-------------------------------------------------------------------------*/
91
92/**
93 * Handle USB audio endpoint set/get command in setup class request
94 */
95
96static int audio_set_endpoint_req(struct usb_configuration *c,
97 const struct usb_ctrlrequest *ctrl)
98{
99 struct usb_composite_dev *cdev = c->cdev;
100 int value = -EOPNOTSUPP;
101 u16 ep = le16_to_cpu(ctrl->wIndex);
102 u16 len = le16_to_cpu(ctrl->wLength);
103 u16 w_value = le16_to_cpu(ctrl->wValue);
104
105 DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
106 ctrl->bRequest, w_value, len, ep);
107
108 switch (ctrl->bRequest) {
109 case SET_CUR:
110 value = 0;
111 break;
112
113 case SET_MIN:
114 break;
115
116 case SET_MAX:
117 break;
118
119 case SET_RES:
120 break;
121
122 case SET_MEM:
123 break;
124
125 default:
126 break;
127 }
128
129 return value;
130}
131
132static int audio_get_endpoint_req(struct usb_configuration *c,
133 const struct usb_ctrlrequest *ctrl)
134{
135 struct usb_composite_dev *cdev = c->cdev;
136 int value = -EOPNOTSUPP;
137 u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
138 u16 len = le16_to_cpu(ctrl->wLength);
139 u16 w_value = le16_to_cpu(ctrl->wValue);
140
141 DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
142 ctrl->bRequest, w_value, len, ep);
143
144 switch (ctrl->bRequest) {
145 case GET_CUR:
146 case GET_MIN:
147 case GET_MAX:
148 case GET_RES:
149 value = 3;
150 break;
151 case GET_MEM:
152 break;
153 default:
154 break;
155 }
156
157 return value;
158}
159
160static int
161audio_setup(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl)
162{
163 struct usb_composite_dev *cdev = c->cdev;
164 struct usb_request *req = cdev->req;
165 int value = -EOPNOTSUPP;
166 u16 w_index = le16_to_cpu(ctrl->wIndex);
167 u16 w_value = le16_to_cpu(ctrl->wValue);
168 u16 w_length = le16_to_cpu(ctrl->wLength);
169
170 /* composite driver infrastructure handles everything except
171 * Audio class messages; interface activation uses set_alt().
172 */
173 switch (ctrl->bRequestType) {
174 case USB_AUDIO_SET_ENDPOINT:
175 value = audio_set_endpoint_req(c, ctrl);
176 break;
177
178 case USB_AUDIO_GET_ENDPOINT:
179 value = audio_get_endpoint_req(c, ctrl);
180 break;
181
182 default:
183 ERROR(cdev, "Invalid control req%02x.%02x v%04x i%04x l%d\n",
184 ctrl->bRequestType, ctrl->bRequest,
185 w_value, w_index, w_length);
186 }
187
188 /* respond with data transfer or status phase? */
189 if (value >= 0) {
190 DBG(cdev, "Audio req%02x.%02x v%04x i%04x l%d\n",
191 ctrl->bRequestType, ctrl->bRequest,
192 w_value, w_index, w_length);
193 req->zero = 0;
194 req->length = value;
195 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
196 if (value < 0)
197 ERROR(cdev, "Audio response on err %d\n", value);
198 }
199
200 /* device either stalls (value < 0) or reports success */
201 return value;
202}
203
204/*-------------------------------------------------------------------------*/
205
206static int __init audio_do_config(struct usb_configuration *c)
207{
208 /* FIXME alloc iConfiguration string, set it in c->strings */
209
210 if (gadget_is_otg(c->cdev->gadget)) {
211 c->descriptors = otg_desc;
212 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
213 }
214
215 audio_bind_config(c);
216
217 return 0;
218}
219
220static struct usb_configuration audio_config_driver = {
221 .label = DRIVER_DESC,
222 .bind = audio_do_config,
223 .setup = audio_setup,
224 .bConfigurationValue = 1,
225 /* .iConfiguration = DYNAMIC */
226 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
227};
228
229/*-------------------------------------------------------------------------*/
230
231static int __init audio_bind(struct usb_composite_dev *cdev)
232{
233 int gcnum;
234 int status;
235
236 gcnum = usb_gadget_controller_number(cdev->gadget);
237 if (gcnum >= 0)
238 device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
239 else {
240 ERROR(cdev, "controller '%s' not recognized; trying %s\n",
241 cdev->gadget->name,
242 audio_config_driver.label);
243 device_desc.bcdDevice =
244 __constant_cpu_to_le16(0x0300 | 0x0099);
245 }
246
247 /* device descriptor strings: manufacturer, product */
248 snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
249 init_utsname()->sysname, init_utsname()->release,
250 cdev->gadget->name);
251 status = usb_string_id(cdev);
252 if (status < 0)
253 goto fail;
254 strings_dev[STRING_MANUFACTURER_IDX].id = status;
255 device_desc.iManufacturer = status;
256
257 status = usb_string_id(cdev);
258 if (status < 0)
259 goto fail;
260 strings_dev[STRING_PRODUCT_IDX].id = status;
261 device_desc.iProduct = status;
262
263 status = usb_add_config(cdev, &audio_config_driver);
264 if (status < 0)
265 goto fail;
266
267 INFO(cdev, "%s, version: %s\n", DRIVER_DESC, DRIVER_VERSION);
268 return 0;
269
270fail:
271 return status;
272}
273
274static int __exit audio_unbind(struct usb_composite_dev *cdev)
275{
276 return 0;
277}
278
279static struct usb_composite_driver audio_driver = {
280 .name = "g_audio",
281 .dev = &device_desc,
282 .strings = audio_strings,
283 .bind = audio_bind,
284 .unbind = __exit_p(audio_unbind),
285};
286
287static int __init init(void)
288{
289 return usb_composite_register(&audio_driver);
290}
291module_init(init);
292
293static void __exit cleanup(void)
294{
295 usb_composite_unregister(&audio_driver);
296}
297module_exit(cleanup);
298
299MODULE_DESCRIPTION(DRIVER_DESC);
300MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>");
301MODULE_LICENSE("GPL");
302
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
new file mode 100644
index 000000000000..66527ba2d2ea
--- /dev/null
+++ b/drivers/usb/gadget/f_audio.c
@@ -0,0 +1,707 @@
1/*
2 * f_audio.c -- USB Audio class function driver
3 *
4 * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
5 * Copyright (C) 2008 Analog Devices, Inc
6 *
7 * Enter bugs at http://blackfin.uclinux.org/
8 *
9 * Licensed under the GPL-2 or later.
10 */
11
12#include <linux/kernel.h>
13#include <linux/device.h>
14#include <asm/atomic.h>
15
16#include "u_audio.h"
17
18#define OUT_EP_MAX_PACKET_SIZE 200
19static int req_buf_size = OUT_EP_MAX_PACKET_SIZE;
20module_param(req_buf_size, int, S_IRUGO);
21MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size");
22
23static int req_count = 256;
24module_param(req_count, int, S_IRUGO);
25MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count");
26
27static int audio_buf_size = 48000;
28module_param(audio_buf_size, int, S_IRUGO);
29MODULE_PARM_DESC(audio_buf_size, "Audio buffer size");
30
31/*
32 * DESCRIPTORS ... most are static, but strings and full
33 * configuration descriptors are built on demand.
34 */
35
36/*
37 * We have two interfaces- AudioControl and AudioStreaming
38 * TODO: only supcard playback currently
39 */
40#define F_AUDIO_AC_INTERFACE 0
41#define F_AUDIO_AS_INTERFACE 1
42#define F_AUDIO_NUM_INTERFACES 2
43
44/* B.3.1 Standard AC Interface Descriptor */
45static struct usb_interface_descriptor ac_interface_desc __initdata = {
46 .bLength = USB_DT_INTERFACE_SIZE,
47 .bDescriptorType = USB_DT_INTERFACE,
48 .bNumEndpoints = 0,
49 .bInterfaceClass = USB_CLASS_AUDIO,
50 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
51};
52
53DECLARE_USB_AC_HEADER_DESCRIPTOR(2);
54
55#define USB_DT_AC_HEADER_LENGH USB_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES)
56/* B.3.2 Class-Specific AC Interface Descriptor */
57static struct usb_ac_header_descriptor_2 ac_header_desc = {
58 .bLength = USB_DT_AC_HEADER_LENGH,
59 .bDescriptorType = USB_DT_CS_INTERFACE,
60 .bDescriptorSubtype = HEADER,
61 .bcdADC = __constant_cpu_to_le16(0x0100),
62 .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_LENGH),
63 .bInCollection = F_AUDIO_NUM_INTERFACES,
64 .baInterfaceNr = {
65 [0] = F_AUDIO_AC_INTERFACE,
66 [1] = F_AUDIO_AS_INTERFACE,
67 }
68};
69
70#define INPUT_TERMINAL_ID 1
71static struct usb_input_terminal_descriptor input_terminal_desc = {
72 .bLength = USB_DT_AC_INPUT_TERMINAL_SIZE,
73 .bDescriptorType = USB_DT_CS_INTERFACE,
74 .bDescriptorSubtype = INPUT_TERMINAL,
75 .bTerminalID = INPUT_TERMINAL_ID,
76 .wTerminalType = USB_AC_TERMINAL_STREAMING,
77 .bAssocTerminal = 0,
78 .wChannelConfig = 0x3,
79};
80
81DECLARE_USB_AC_FEATURE_UNIT_DESCRIPTOR(0);
82
83#define FEATURE_UNIT_ID 2
84static struct usb_ac_feature_unit_descriptor_0 feature_unit_desc = {
85 .bLength = USB_DT_AC_FEATURE_UNIT_SIZE(0),
86 .bDescriptorType = USB_DT_CS_INTERFACE,
87 .bDescriptorSubtype = FEATURE_UNIT,
88 .bUnitID = FEATURE_UNIT_ID,
89 .bSourceID = INPUT_TERMINAL_ID,
90 .bControlSize = 2,
91 .bmaControls[0] = (FU_MUTE | FU_VOLUME),
92};
93
94static struct usb_audio_control mute_control = {
95 .list = LIST_HEAD_INIT(mute_control.list),
96 .name = "Mute Control",
97 .type = MUTE_CONTROL,
98 /* Todo: add real Mute control code */
99 .set = generic_set_cmd,
100 .get = generic_get_cmd,
101};
102
103static struct usb_audio_control volume_control = {
104 .list = LIST_HEAD_INIT(volume_control.list),
105 .name = "Volume Control",
106 .type = VOLUME_CONTROL,
107 /* Todo: add real Volume control code */
108 .set = generic_set_cmd,
109 .get = generic_get_cmd,
110};
111
112static struct usb_audio_control_selector feature_unit = {
113 .list = LIST_HEAD_INIT(feature_unit.list),
114 .id = FEATURE_UNIT_ID,
115 .name = "Mute & Volume Control",
116 .type = FEATURE_UNIT,
117 .desc = (struct usb_descriptor_header *)&feature_unit_desc,
118};
119
120#define OUTPUT_TERMINAL_ID 3
121static struct usb_output_terminal_descriptor output_terminal_desc = {
122 .bLength = USB_DT_AC_OUTPUT_TERMINAL_SIZE,
123 .bDescriptorType = USB_DT_CS_INTERFACE,
124 .bDescriptorSubtype = OUTPUT_TERMINAL,
125 .bTerminalID = OUTPUT_TERMINAL_ID,
126 .wTerminalType = USB_AC_OUTPUT_TERMINAL_SPEAKER,
127 .bAssocTerminal = FEATURE_UNIT_ID,
128 .bSourceID = FEATURE_UNIT_ID,
129};
130
131/* B.4.1 Standard AS Interface Descriptor */
132static struct usb_interface_descriptor as_interface_alt_0_desc = {
133 .bLength = USB_DT_INTERFACE_SIZE,
134 .bDescriptorType = USB_DT_INTERFACE,
135 .bAlternateSetting = 0,
136 .bNumEndpoints = 0,
137 .bInterfaceClass = USB_CLASS_AUDIO,
138 .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING,
139};
140
141static struct usb_interface_descriptor as_interface_alt_1_desc = {
142 .bLength = USB_DT_INTERFACE_SIZE,
143 .bDescriptorType = USB_DT_INTERFACE,
144 .bAlternateSetting = 1,
145 .bNumEndpoints = 1,
146 .bInterfaceClass = USB_CLASS_AUDIO,
147 .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING,
148};
149
150/* B.4.2 Class-Specific AS Interface Descriptor */
151static struct usb_as_header_descriptor as_header_desc = {
152 .bLength = USB_DT_AS_HEADER_SIZE,
153 .bDescriptorType = USB_DT_CS_INTERFACE,
154 .bDescriptorSubtype = AS_GENERAL,
155 .bTerminalLink = INPUT_TERMINAL_ID,
156 .bDelay = 1,
157 .wFormatTag = USB_AS_AUDIO_FORMAT_TYPE_I_PCM,
158};
159
160DECLARE_USB_AS_FORMAT_TYPE_I_DISCRETE_DESC(1);
161
162static struct usb_as_formate_type_i_discrete_descriptor_1 as_type_i_desc = {
163 .bLength = USB_AS_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1),
164 .bDescriptorType = USB_DT_CS_INTERFACE,
165 .bDescriptorSubtype = FORMAT_TYPE,
166 .bFormatType = USB_AS_FORMAT_TYPE_I,
167 .bSubframeSize = 2,
168 .bBitResolution = 16,
169 .bSamFreqType = 1,
170};
171
172/* Standard ISO OUT Endpoint Descriptor */
173static struct usb_endpoint_descriptor as_out_ep_desc __initdata = {
174 .bLength = USB_DT_ENDPOINT_AUDIO_SIZE,
175 .bDescriptorType = USB_DT_ENDPOINT,
176 .bEndpointAddress = USB_DIR_OUT,
177 .bmAttributes = USB_AS_ENDPOINT_ADAPTIVE
178 | USB_ENDPOINT_XFER_ISOC,
179 .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE),
180 .bInterval = 4,
181};
182
183/* Class-specific AS ISO OUT Endpoint Descriptor */
184static struct usb_as_iso_endpoint_descriptor as_iso_out_desc __initdata = {
185 .bLength = USB_AS_ISO_ENDPOINT_DESC_SIZE,
186 .bDescriptorType = USB_DT_CS_ENDPOINT,
187 .bDescriptorSubtype = EP_GENERAL,
188 .bmAttributes = 1,
189 .bLockDelayUnits = 1,
190 .wLockDelay = __constant_cpu_to_le16(1),
191};
192
193static struct usb_descriptor_header *f_audio_desc[] __initdata = {
194 (struct usb_descriptor_header *)&ac_interface_desc,
195 (struct usb_descriptor_header *)&ac_header_desc,
196
197 (struct usb_descriptor_header *)&input_terminal_desc,
198 (struct usb_descriptor_header *)&output_terminal_desc,
199 (struct usb_descriptor_header *)&feature_unit_desc,
200
201 (struct usb_descriptor_header *)&as_interface_alt_0_desc,
202 (struct usb_descriptor_header *)&as_interface_alt_1_desc,
203 (struct usb_descriptor_header *)&as_header_desc,
204
205 (struct usb_descriptor_header *)&as_type_i_desc,
206
207 (struct usb_descriptor_header *)&as_out_ep_desc,
208 (struct usb_descriptor_header *)&as_iso_out_desc,
209 NULL,
210};
211
212/* string IDs are assigned dynamically */
213
214#define STRING_MANUFACTURER_IDX 0
215#define STRING_PRODUCT_IDX 1
216
217static char manufacturer[50];
218
219static struct usb_string strings_dev[] = {
220 [STRING_MANUFACTURER_IDX].s = manufacturer,
221 [STRING_PRODUCT_IDX].s = DRIVER_DESC,
222 { } /* end of list */
223};
224
225static struct usb_gadget_strings stringtab_dev = {
226 .language = 0x0409, /* en-us */
227 .strings = strings_dev,
228};
229
230static struct usb_gadget_strings *audio_strings[] = {
231 &stringtab_dev,
232 NULL,
233};
234
235/*
236 * This function is an ALSA sound card following USB Audio Class Spec 1.0.
237 */
238
239/*-------------------------------------------------------------------------*/
240struct f_audio_buf {
241 u8 *buf;
242 int actual;
243 struct list_head list;
244};
245
246static struct f_audio_buf *f_audio_buffer_alloc(int buf_size)
247{
248 struct f_audio_buf *copy_buf;
249
250 copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC);
251 if (!copy_buf)
252 return (struct f_audio_buf *)-ENOMEM;
253
254 copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC);
255 if (!copy_buf->buf) {
256 kfree(copy_buf);
257 return (struct f_audio_buf *)-ENOMEM;
258 }
259
260 return copy_buf;
261}
262
263static void f_audio_buffer_free(struct f_audio_buf *audio_buf)
264{
265 kfree(audio_buf->buf);
266 kfree(audio_buf);
267}
268/*-------------------------------------------------------------------------*/
269
270struct f_audio {
271 struct gaudio card;
272
273 /* endpoints handle full and/or high speeds */
274 struct usb_ep *out_ep;
275 struct usb_endpoint_descriptor *out_desc;
276
277 spinlock_t lock;
278 struct f_audio_buf *copy_buf;
279 struct work_struct playback_work;
280 struct list_head play_queue;
281
282 /* Control Set command */
283 struct list_head cs;
284 u8 set_cmd;
285 struct usb_audio_control *set_con;
286};
287
288static inline struct f_audio *func_to_audio(struct usb_function *f)
289{
290 return container_of(f, struct f_audio, card.func);
291}
292
293/*-------------------------------------------------------------------------*/
294
295static void f_audio_playback_work(struct work_struct *data)
296{
297 struct f_audio *audio = container_of(data, struct f_audio,
298 playback_work);
299 struct f_audio_buf *play_buf;
300
301 spin_lock_irq(&audio->lock);
302 if (list_empty(&audio->play_queue)) {
303 spin_unlock_irq(&audio->lock);
304 return;
305 }
306 play_buf = list_first_entry(&audio->play_queue,
307 struct f_audio_buf, list);
308 list_del(&play_buf->list);
309 spin_unlock_irq(&audio->lock);
310
311 u_audio_playback(&audio->card, play_buf->buf, play_buf->actual);
312 f_audio_buffer_free(play_buf);
313
314 return;
315}
316
317static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req)
318{
319 struct f_audio *audio = req->context;
320 struct usb_composite_dev *cdev = audio->card.func.config->cdev;
321 struct f_audio_buf *copy_buf = audio->copy_buf;
322 int err;
323
324 if (!copy_buf)
325 return -EINVAL;
326
327 /* Copy buffer is full, add it to the play_queue */
328 if (audio_buf_size - copy_buf->actual < req->actual) {
329 list_add_tail(&copy_buf->list, &audio->play_queue);
330 schedule_work(&audio->playback_work);
331 copy_buf = f_audio_buffer_alloc(audio_buf_size);
332 if (copy_buf < 0)
333 return -ENOMEM;
334 }
335
336 memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual);
337 copy_buf->actual += req->actual;
338 audio->copy_buf = copy_buf;
339
340 err = usb_ep_queue(ep, req, GFP_ATOMIC);
341 if (err)
342 ERROR(cdev, "%s queue req: %d\n", ep->name, err);
343
344 return 0;
345
346}
347
348static void f_audio_complete(struct usb_ep *ep, struct usb_request *req)
349{
350 struct f_audio *audio = req->context;
351 int status = req->status;
352 u32 data = 0;
353 struct usb_ep *out_ep = audio->out_ep;
354
355 switch (status) {
356
357 case 0: /* normal completion? */
358 if (ep == out_ep)
359 f_audio_out_ep_complete(ep, req);
360 else if (audio->set_con) {
361 memcpy(&data, req->buf, req->length);
362 audio->set_con->set(audio->set_con, audio->set_cmd,
363 le16_to_cpu(data));
364 audio->set_con = NULL;
365 }
366 break;
367 default:
368 break;
369 }
370}
371
372static int audio_set_intf_req(struct usb_function *f,
373 const struct usb_ctrlrequest *ctrl)
374{
375 struct f_audio *audio = func_to_audio(f);
376 struct usb_composite_dev *cdev = f->config->cdev;
377 struct usb_request *req = cdev->req;
378 u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
379 u16 len = le16_to_cpu(ctrl->wLength);
380 u16 w_value = le16_to_cpu(ctrl->wValue);
381 u8 con_sel = (w_value >> 8) & 0xFF;
382 u8 cmd = (ctrl->bRequest & 0x0F);
383 struct usb_audio_control_selector *cs;
384 struct usb_audio_control *con;
385
386 DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n",
387 ctrl->bRequest, w_value, len, id);
388
389 list_for_each_entry(cs, &audio->cs, list) {
390 if (cs->id == id) {
391 list_for_each_entry(con, &cs->control, list) {
392 if (con->type == con_sel) {
393 audio->set_con = con;
394 break;
395 }
396 }
397 break;
398 }
399 }
400
401 audio->set_cmd = cmd;
402 req->context = audio;
403 req->complete = f_audio_complete;
404
405 return len;
406}
407
408static int audio_get_intf_req(struct usb_function *f,
409 const struct usb_ctrlrequest *ctrl)
410{
411 struct f_audio *audio = func_to_audio(f);
412 struct usb_composite_dev *cdev = f->config->cdev;
413 struct usb_request *req = cdev->req;
414 int value = -EOPNOTSUPP;
415 u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
416 u16 len = le16_to_cpu(ctrl->wLength);
417 u16 w_value = le16_to_cpu(ctrl->wValue);
418 u8 con_sel = (w_value >> 8) & 0xFF;
419 u8 cmd = (ctrl->bRequest & 0x0F);
420 struct usb_audio_control_selector *cs;
421 struct usb_audio_control *con;
422
423 DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n",
424 ctrl->bRequest, w_value, len, id);
425
426 list_for_each_entry(cs, &audio->cs, list) {
427 if (cs->id == id) {
428 list_for_each_entry(con, &cs->control, list) {
429 if (con->type == con_sel && con->get) {
430 value = con->get(con, cmd);
431 break;
432 }
433 }
434 break;
435 }
436 }
437
438 req->context = audio;
439 req->complete = f_audio_complete;
440 memcpy(req->buf, &value, len);
441
442 return len;
443}
444
445static int
446f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
447{
448 struct usb_composite_dev *cdev = f->config->cdev;
449 struct usb_request *req = cdev->req;
450 int value = -EOPNOTSUPP;
451 u16 w_index = le16_to_cpu(ctrl->wIndex);
452 u16 w_value = le16_to_cpu(ctrl->wValue);
453 u16 w_length = le16_to_cpu(ctrl->wLength);
454
455 /* composite driver infrastructure handles everything except
456 * Audio class messages; interface activation uses set_alt().
457 */
458 switch (ctrl->bRequestType) {
459 case USB_AUDIO_SET_INTF:
460 value = audio_set_intf_req(f, ctrl);
461 break;
462
463 case USB_AUDIO_GET_INTF:
464 value = audio_get_intf_req(f, ctrl);
465 break;
466
467 default:
468 ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
469 ctrl->bRequestType, ctrl->bRequest,
470 w_value, w_index, w_length);
471 }
472
473 /* respond with data transfer or status phase? */
474 if (value >= 0) {
475 DBG(cdev, "audio req%02x.%02x v%04x i%04x l%d\n",
476 ctrl->bRequestType, ctrl->bRequest,
477 w_value, w_index, w_length);
478 req->zero = 0;
479 req->length = value;
480 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
481 if (value < 0)
482 ERROR(cdev, "audio response on err %d\n", value);
483 }
484
485 /* device either stalls (value < 0) or reports success */
486 return value;
487}
488
489static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
490{
491 struct f_audio *audio = func_to_audio(f);
492 struct usb_composite_dev *cdev = f->config->cdev;
493 struct usb_ep *out_ep = audio->out_ep;
494 struct usb_request *req;
495 int i = 0, err = 0;
496
497 DBG(cdev, "intf %d, alt %d\n", intf, alt);
498
499 if (intf == 1) {
500 if (alt == 1) {
501 usb_ep_enable(out_ep, audio->out_desc);
502 out_ep->driver_data = audio;
503 audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
504
505 /*
506 * allocate a bunch of read buffers
507 * and queue them all at once.
508 */
509 for (i = 0; i < req_count && err == 0; i++) {
510 req = usb_ep_alloc_request(out_ep, GFP_ATOMIC);
511 if (req) {
512 req->buf = kzalloc(req_buf_size,
513 GFP_ATOMIC);
514 if (req->buf) {
515 req->length = req_buf_size;
516 req->context = audio;
517 req->complete =
518 f_audio_complete;
519 err = usb_ep_queue(out_ep,
520 req, GFP_ATOMIC);
521 if (err)
522 ERROR(cdev,
523 "%s queue req: %d\n",
524 out_ep->name, err);
525 } else
526 err = -ENOMEM;
527 } else
528 err = -ENOMEM;
529 }
530
531 } else {
532 struct f_audio_buf *copy_buf = audio->copy_buf;
533 if (copy_buf) {
534 list_add_tail(&copy_buf->list,
535 &audio->play_queue);
536 schedule_work(&audio->playback_work);
537 }
538 }
539 }
540
541 return err;
542}
543
544static void f_audio_disable(struct usb_function *f)
545{
546 return;
547}
548
549/*-------------------------------------------------------------------------*/
550
551static void f_audio_build_desc(struct f_audio *audio)
552{
553 struct gaudio *card = &audio->card;
554 u8 *sam_freq;
555 int rate;
556
557 /* Set channel numbers */
558 input_terminal_desc.bNrChannels = u_audio_get_playback_channels(card);
559 as_type_i_desc.bNrChannels = u_audio_get_playback_channels(card);
560
561 /* Set sample rates */
562 rate = u_audio_get_playback_rate(card);
563 sam_freq = as_type_i_desc.tSamFreq[0];
564 memcpy(sam_freq, &rate, 3);
565
566 /* Todo: Set Sample bits and other parameters */
567
568 return;
569}
570
571/* audio function driver setup/binding */
572static int __init
573f_audio_bind(struct usb_configuration *c, struct usb_function *f)
574{
575 struct usb_composite_dev *cdev = c->cdev;
576 struct f_audio *audio = func_to_audio(f);
577 int status;
578 struct usb_ep *ep;
579
580 f_audio_build_desc(audio);
581
582 /* allocate instance-specific interface IDs, and patch descriptors */
583 status = usb_interface_id(c, f);
584 if (status < 0)
585 goto fail;
586 ac_interface_desc.bInterfaceNumber = status;
587
588 status = usb_interface_id(c, f);
589 if (status < 0)
590 goto fail;
591 as_interface_alt_0_desc.bInterfaceNumber = status;
592 as_interface_alt_1_desc.bInterfaceNumber = status;
593
594 status = -ENODEV;
595
596 /* allocate instance-specific endpoints */
597 ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc);
598 if (!ep)
599 goto fail;
600 audio->out_ep = ep;
601 ep->driver_data = cdev; /* claim */
602
603 status = -ENOMEM;
604
605 /* supcard all relevant hardware speeds... we expect that when
606 * hardware is dual speed, all bulk-capable endpoints work at
607 * both speeds
608 */
609
610 /* copy descriptors, and track endpoint copies */
611 if (gadget_is_dualspeed(c->cdev->gadget)) {
612 c->highspeed = true;
613 f->hs_descriptors = usb_copy_descriptors(f_audio_desc);
614 } else
615 f->descriptors = usb_copy_descriptors(f_audio_desc);
616
617 return 0;
618
619fail:
620
621 return status;
622}
623
624static void
625f_audio_unbind(struct usb_configuration *c, struct usb_function *f)
626{
627 struct f_audio *audio = func_to_audio(f);
628
629 usb_free_descriptors(f->descriptors);
630 kfree(audio);
631}
632
633/*-------------------------------------------------------------------------*/
634
635/* Todo: add more control selecotor dynamically */
636int __init control_selector_init(struct f_audio *audio)
637{
638 INIT_LIST_HEAD(&audio->cs);
639 list_add(&feature_unit.list, &audio->cs);
640
641 INIT_LIST_HEAD(&feature_unit.control);
642 list_add(&mute_control.list, &feature_unit.control);
643 list_add(&volume_control.list, &feature_unit.control);
644
645 volume_control.data[_CUR] = 0xffc0;
646 volume_control.data[_MIN] = 0xe3a0;
647 volume_control.data[_MAX] = 0xfff0;
648 volume_control.data[_RES] = 0x0030;
649
650 return 0;
651}
652
653/**
654 * audio_bind_config - add USB audio fucntion to a configuration
655 * @c: the configuration to supcard the USB audio function
656 * Context: single threaded during gadget setup
657 *
658 * Returns zero on success, else negative errno.
659 */
660int __init audio_bind_config(struct usb_configuration *c)
661{
662 struct f_audio *audio;
663 int status;
664
665 /* allocate and initialize one new instance */
666 audio = kzalloc(sizeof *audio, GFP_KERNEL);
667 if (!audio)
668 return -ENOMEM;
669
670 audio->card.func.name = "g_audio";
671 audio->card.gadget = c->cdev->gadget;
672
673 INIT_LIST_HEAD(&audio->play_queue);
674 spin_lock_init(&audio->lock);
675
676 /* set up ASLA audio devices */
677 status = gaudio_setup(&audio->card);
678 if (status < 0)
679 goto setup_fail;
680
681 audio->card.func.strings = audio_strings;
682 audio->card.func.bind = f_audio_bind;
683 audio->card.func.unbind = f_audio_unbind;
684 audio->card.func.set_alt = f_audio_set_alt;
685 audio->card.func.setup = f_audio_setup;
686 audio->card.func.disable = f_audio_disable;
687 audio->out_desc = &as_out_ep_desc;
688
689 control_selector_init(audio);
690
691 INIT_WORK(&audio->playback_work, f_audio_playback_work);
692
693 status = usb_add_function(c, &audio->card.func);
694 if (status)
695 goto add_fail;
696
697 INFO(c->cdev, "audio_buf_size %d, req_buf_size %d, req_count %d\n",
698 audio_buf_size, req_buf_size, req_count);
699
700 return status;
701
702add_fail:
703 gaudio_cleanup(&audio->card);
704setup_fail:
705 kfree(audio);
706 return status;
707}
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c
new file mode 100644
index 000000000000..0f3d22fc030e
--- /dev/null
+++ b/drivers/usb/gadget/u_audio.c
@@ -0,0 +1,319 @@
1/*
2 * u_audio.c -- ALSA audio utilities for Gadget stack
3 *
4 * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
5 * Copyright (C) 2008 Analog Devices, Inc
6 *
7 * Enter bugs at http://blackfin.uclinux.org/
8 *
9 * Licensed under the GPL-2 or later.
10 */
11
12#include <linux/kernel.h>
13#include <linux/utsname.h>
14#include <linux/device.h>
15#include <linux/delay.h>
16#include <linux/ctype.h>
17#include <linux/random.h>
18#include <linux/syscalls.h>
19
20#include "u_audio.h"
21
22/*
23 * This component encapsulates the ALSA devices for USB audio gadget
24 */
25
26#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p"
27#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c"
28#define FILE_CONTROL "/dev/snd/controlC0"
29
30static char *fn_play = FILE_PCM_PLAYBACK;
31module_param(fn_play, charp, S_IRUGO);
32MODULE_PARM_DESC(fn_play, "Playback PCM device file name");
33
34static char *fn_cap = FILE_PCM_CAPTURE;
35module_param(fn_cap, charp, S_IRUGO);
36MODULE_PARM_DESC(fn_cap, "Capture PCM device file name");
37
38static char *fn_cntl = FILE_CONTROL;
39module_param(fn_cntl, charp, S_IRUGO);
40MODULE_PARM_DESC(fn_cntl, "Control device file name");
41
42/*-------------------------------------------------------------------------*/
43
44/**
45 * Some ALSA internal helper functions
46 */
47static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
48{
49 struct snd_interval t;
50 t.empty = 0;
51 t.min = t.max = val;
52 t.openmin = t.openmax = 0;
53 t.integer = 1;
54 return snd_interval_refine(i, &t);
55}
56
57static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
58 snd_pcm_hw_param_t var, unsigned int val,
59 int dir)
60{
61 int changed;
62 if (hw_is_mask(var)) {
63 struct snd_mask *m = hw_param_mask(params, var);
64 if (val == 0 && dir < 0) {
65 changed = -EINVAL;
66 snd_mask_none(m);
67 } else {
68 if (dir > 0)
69 val++;
70 else if (dir < 0)
71 val--;
72 changed = snd_mask_refine_set(
73 hw_param_mask(params, var), val);
74 }
75 } else if (hw_is_interval(var)) {
76 struct snd_interval *i = hw_param_interval(params, var);
77 if (val == 0 && dir < 0) {
78 changed = -EINVAL;
79 snd_interval_none(i);
80 } else if (dir == 0)
81 changed = snd_interval_refine_set(i, val);
82 else {
83 struct snd_interval t;
84 t.openmin = 1;
85 t.openmax = 1;
86 t.empty = 0;
87 t.integer = 0;
88 if (dir < 0) {
89 t.min = val - 1;
90 t.max = val;
91 } else {
92 t.min = val;
93 t.max = val+1;
94 }
95 changed = snd_interval_refine(i, &t);
96 }
97 } else
98 return -EINVAL;
99 if (changed) {
100 params->cmask |= 1 << var;
101 params->rmask |= 1 << var;
102 }
103 return changed;
104}
105/*-------------------------------------------------------------------------*/
106
107/**
108 * Set default hardware params
109 */
110static int playback_default_hw_params(struct gaudio_snd_dev *snd)
111{
112 struct snd_pcm_substream *substream = snd->substream;
113 struct snd_pcm_hw_params *params;
114 snd_pcm_sframes_t result;
115
116 /*
117 * SNDRV_PCM_ACCESS_RW_INTERLEAVED,
118 * SNDRV_PCM_FORMAT_S16_LE
119 * CHANNELS: 2
120 * RATE: 48000
121 */
122 snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
123 snd->format = SNDRV_PCM_FORMAT_S16_LE;
124 snd->channels = 2;
125 snd->rate = 48000;
126
127 params = kzalloc(sizeof(*params), GFP_KERNEL);
128 if (!params)
129 return -ENOMEM;
130
131 _snd_pcm_hw_params_any(params);
132 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
133 snd->access, 0);
134 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
135 snd->format, 0);
136 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
137 snd->channels, 0);
138 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
139 snd->rate, 0);
140
141 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
142 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, params);
143
144 result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
145 if (result < 0) {
146 ERROR(snd->card,
147 "Preparing sound card failed: %d\n", (int)result);
148 kfree(params);
149 return result;
150 }
151
152 /* Store the hardware parameters */
153 snd->access = params_access(params);
154 snd->format = params_format(params);
155 snd->channels = params_channels(params);
156 snd->rate = params_rate(params);
157
158 kfree(params);
159
160 INFO(snd->card,
161 "Hardware params: access %x, format %x, channels %d, rate %d\n",
162 snd->access, snd->format, snd->channels, snd->rate);
163
164 return 0;
165}
166
167/**
168 * Playback audio buffer data by ALSA PCM device
169 */
170static size_t u_audio_playback(struct gaudio *card, void *buf, size_t count)
171{
172 struct gaudio_snd_dev *snd = &card->playback;
173 struct snd_pcm_substream *substream = snd->substream;
174 struct snd_pcm_runtime *runtime = substream->runtime;
175 mm_segment_t old_fs;
176 ssize_t result;
177 snd_pcm_sframes_t frames;
178
179try_again:
180 if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
181 runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
182 result = snd_pcm_kernel_ioctl(substream,
183 SNDRV_PCM_IOCTL_PREPARE, NULL);
184 if (result < 0) {
185 ERROR(card, "Preparing sound card failed: %d\n",
186 (int)result);
187 return result;
188 }
189 }
190
191 frames = bytes_to_frames(runtime, count);
192 old_fs = get_fs();
193 set_fs(KERNEL_DS);
194 result = snd_pcm_lib_write(snd->substream, buf, frames);
195 if (result != frames) {
196 ERROR(card, "Playback error: %d\n", (int)result);
197 set_fs(old_fs);
198 goto try_again;
199 }
200 set_fs(old_fs);
201
202 return 0;
203}
204
205static int u_audio_get_playback_channels(struct gaudio *card)
206{
207 return card->playback.channels;
208}
209
210static int u_audio_get_playback_rate(struct gaudio *card)
211{
212 return card->playback.rate;
213}
214
215/**
216 * Open ALSA PCM and control device files
217 * Initial the PCM or control device
218 */
219static int gaudio_open_snd_dev(struct gaudio *card)
220{
221 struct snd_pcm_file *pcm_file;
222 struct gaudio_snd_dev *snd;
223
224 if (!card)
225 return -ENODEV;
226
227 /* Open control device */
228 snd = &card->control;
229 snd->filp = filp_open(fn_cntl, O_RDWR, 0);
230 if (IS_ERR(snd->filp)) {
231 int ret = PTR_ERR(snd->filp);
232 ERROR(card, "unable to open sound control device file: %s\n",
233 fn_cntl);
234 snd->filp = NULL;
235 return ret;
236 }
237 snd->card = card;
238
239 /* Open PCM playback device and setup substream */
240 snd = &card->playback;
241 snd->filp = filp_open(fn_play, O_WRONLY, 0);
242 if (IS_ERR(snd->filp)) {
243 ERROR(card, "No such PCM playback device: %s\n", fn_play);
244 snd->filp = NULL;
245 }
246 pcm_file = snd->filp->private_data;
247 snd->substream = pcm_file->substream;
248 snd->card = card;
249 playback_default_hw_params(snd);
250
251 /* Open PCM capture device and setup substream */
252 snd = &card->capture;
253 snd->filp = filp_open(fn_cap, O_RDONLY, 0);
254 if (IS_ERR(snd->filp)) {
255 ERROR(card, "No such PCM capture device: %s\n", fn_cap);
256 snd->filp = NULL;
257 }
258 pcm_file = snd->filp->private_data;
259 snd->substream = pcm_file->substream;
260 snd->card = card;
261
262 return 0;
263}
264
265/**
266 * Close ALSA PCM and control device files
267 */
268static int gaudio_close_snd_dev(struct gaudio *gau)
269{
270 struct gaudio_snd_dev *snd;
271
272 /* Close control device */
273 snd = &gau->control;
274 if (!IS_ERR(snd->filp))
275 filp_close(snd->filp, current->files);
276
277 /* Close PCM playback device and setup substream */
278 snd = &gau->playback;
279 if (!IS_ERR(snd->filp))
280 filp_close(snd->filp, current->files);
281
282 /* Close PCM capture device and setup substream */
283 snd = &gau->capture;
284 if (!IS_ERR(snd->filp))
285 filp_close(snd->filp, current->files);
286
287 return 0;
288}
289
290/**
291 * gaudio_setup - setup ALSA interface and preparing for USB transfer
292 *
293 * This sets up PCM, mixer or MIDI ALSA devices fore USB gadget using.
294 *
295 * Returns negative errno, or zero on success
296 */
297int __init gaudio_setup(struct gaudio *card)
298{
299 int ret;
300
301 ret = gaudio_open_snd_dev(card);
302 if (ret)
303 ERROR(card, "we need at least one control device\n");
304
305 return ret;
306
307}
308
309/**
310 * gaudio_cleanup - remove ALSA device interface
311 *
312 * This is called to free all resources allocated by @gaudio_setup().
313 */
314void gaudio_cleanup(struct gaudio *card)
315{
316 if (card)
317 gaudio_close_snd_dev(card);
318}
319
diff --git a/drivers/usb/gadget/u_audio.h b/drivers/usb/gadget/u_audio.h
new file mode 100644
index 000000000000..cc8d159c648a
--- /dev/null
+++ b/drivers/usb/gadget/u_audio.h
@@ -0,0 +1,56 @@
1/*
2 * u_audio.h -- interface to USB gadget "ALSA AUDIO" utilities
3 *
4 * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
5 * Copyright (C) 2008 Analog Devices, Inc
6 *
7 * Enter bugs at http://blackfin.uclinux.org/
8 *
9 * Licensed under the GPL-2 or later.
10 */
11
12#ifndef __U_AUDIO_H
13#define __U_AUDIO_H
14
15#include <linux/device.h>
16#include <linux/err.h>
17#include <linux/usb/audio.h>
18#include <linux/usb/composite.h>
19
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23
24#include "gadget_chips.h"
25
26/*
27 * This represents the USB side of an audio card device, managed by a USB
28 * function which provides control and stream interfaces.
29 */
30
31struct gaudio_snd_dev {
32 struct gaudio *card;
33 struct file *filp;
34 struct snd_pcm_substream *substream;
35 int access;
36 int format;
37 int channels;
38 int rate;
39};
40
41struct gaudio {
42 struct usb_function func;
43 struct usb_gadget *gadget;
44
45 /* ALSA sound device interfaces */
46 struct gaudio_snd_dev control;
47 struct gaudio_snd_dev playback;
48 struct gaudio_snd_dev capture;
49
50 /* TODO */
51};
52
53int gaudio_setup(struct gaudio *card);
54void gaudio_cleanup(struct gaudio *card);
55
56#endif /* __U_AUDIO_H */