M4521_BSP V3.02.000
The Board Support Package for M4521
uac_driver.c
Go to the documentation of this file.
1/**************************************************************************/
13#include <stdio.h>
14#include <string.h>
15
16#include "M4521.h"
17#include "usbh_core.h"
18
19#include "usbh_uac.h"
20#include "uac.h"
21
22
40
41static UAC_DEV_T g_au_dev[CONFIG_AU_MAX_DEV];
42static UAC_INFO_T g_uac_info[CONFIG_AU_MAX_DEV];
43
44static UAC_DEV_T *g_audev_list = NULL;
45
46int au_parsing_descriptors(UAC_DEV_T *audev);
47
48static UAC_DEV_T *alloc_as_device(void)
49{
50 int i;
51
52 for(i = 0; i < CONFIG_AU_MAX_DEV; i++)
53 {
54 if(g_au_dev[i].udev == NULL)
55 {
56 memset((char *)&g_au_dev[i], 0, sizeof(UAC_DEV_T));
57 g_au_dev[i].ctrl_ifnum = -1;
58 g_au_dev[i].au_in_ifnum = -1;
59 g_au_dev[i].au_out_ifnum = -1;
60 memset((char *)&g_uac_info[i], 0, sizeof(UAC_INFO_T));
61 g_au_dev[i].priv = (void *)&g_uac_info[i];
62 return &g_au_dev[i];
63 }
64 }
65 return NULL;
66}
67
68static void free_au_device(UAC_DEV_T *audev)
69{
70 audev->udev = NULL;
71}
72
73UAC_DEV_T *find_as_deivce_by_udev(USB_DEV_T *udev)
74{
75 int i;
76
77 if(udev == NULL)
78 return NULL;
79
80 for(i = 0; i < CONFIG_AU_MAX_DEV; i++)
81 {
82 if(g_au_dev[i].udev == udev)
83 {
84 return &g_au_dev[i];
85 }
86 }
87 return NULL;
88}
89
90int find_as_device(UAC_DEV_T *hdev)
91{
92 int i;
93
94 for(i = 0; i < CONFIG_AU_MAX_DEV; i++)
95 {
96 if(&g_au_dev[i] == hdev)
97 {
98 return TRUE;
99 }
100 }
101 return FALSE;
102}
103
104
105static int au_probe(USB_DEV_T *dev, USB_IF_DESC_T *ifd, const USB_DEV_ID_T *id)
106{
107 EP_INFO_T *ep_info;
108 int ifnum;
109 UAC_DEV_T *audev, *p;
110 int i;
111
112 if((ifd->bInterfaceSubClass != SUBCLS_AUDIOCONTROL) &&
113 (ifd->bInterfaceSubClass != SUBCLS_AUDIOSTREAMING))
114 {
115 printf("Does not support audio sub-class %x\n", ifd->bInterfaceSubClass);
117 }
118
119
120 ifnum = ifd->bInterfaceNumber;
121
122 audev = find_as_deivce_by_udev(dev);
123 if(audev == NULL)
124 {
125 audev = alloc_as_device();
126 if(audev == NULL)
127 return USB_ERR_NODEV;
128 }
129
130 audev->udev = dev;
131 audev->next = NULL;
132
133 USBAS_DBGMSG("au_probe called for ifnum %d\n", ifnum);
134
135 if(ifd->bInterfaceSubClass == SUBCLS_AUDIOSTREAMING)
136 {
137 ep_info = NULL;
138 for(i = 0; i < dev->ep_list_cnt; i++)
139 {
140 if((dev->ep_list[i].ifnum == ifnum) &&
141 ((dev->ep_list[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC))
142 {
143 ep_info = &dev->ep_list[i];
144 USBAS_DBGMSG("Isochronous Endpoint 0x%x found.\n", ep_info->bEndpointAddress);
145 }
146 }
147 if(ep_info == NULL)
148 {
149 USBAS_DBGMSG("couldn't find isochronous endpoints\n");
150 return USB_ERR_NODEV;
151 }
152
153 if((ep_info->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
154 {
155 audev->ep_au_in = ep_info;
156 audev->au_in_ifnum = ifnum;
157 USBAS_DBGMSG("Audio in stream interface is %d\n", ifnum);
158 }
159 else
160 {
161 audev->ep_au_out = ep_info;
162 audev->au_out_ifnum = ifnum;
163 USBAS_DBGMSG("Audio out stream interface is %d\n", ifnum);
164 }
165 }
166 else
167 {
168 audev->ctrl_ifnum = ifnum;
169 USBAS_DBGMSG("Audio control interface is %d\n", ifnum);
170 }
171
172 /*
173 * Chaining newly found Audio Class device to end of Audio Class device list.
174 */
175 if(g_audev_list == NULL)
176 g_audev_list = audev;
177 else
178 {
179 for(p = g_audev_list; p->next != NULL; p = p->next)
180 ;
181 p->next = audev;
182 }
183
184 return uac_config_parser(audev);
185}
186
187
188static void au_disconnect(USB_DEV_T *dev)
189{
190 UAC_DEV_T *audev, *p;
191 int i;
192
193 USBAS_DBGMSG("Audio Class device disconnected!\n");
194
195 audev = find_as_deivce_by_udev(dev);
196 if(audev == NULL)
197 return;
198
199 for(i = 0; i < ISO_IN_URB_CNT; i++)
200 {
201 if(audev->urbin[i])
202 {
203 USBH_UnlinkUrb(audev->urbin[i]);
204 USBH_FreeUrb(audev->urbin[i]);
205 }
206 }
207
208 for(i = 0; i < ISO_OUT_URB_CNT; i++)
209 {
210 if(audev->urbout[i])
211 {
212 USBH_UnlinkUrb(audev->urbout[i]);
213 USBH_FreeUrb(audev->urbout[i]);
214 }
215 }
216
217 /*
218 * Remove this Audio Class device from device list.
219 */
220 if(audev == g_audev_list)
221 g_audev_list = g_audev_list->next;
222 else
223 {
224 for(p = g_audev_list; p != NULL; p = p->next)
225 {
226 if(p->next == audev)
227 {
228 p->next = audev->next;
229 break;
230 }
231 }
232 }
233 free_au_device(audev);
234}
235
236
237static USB_DEV_ID_T au_id_table[] =
238{
239 USB_DEVICE_ID_MATCH_INT_CLASS, /* match_flags */
240 0, 0, 0, 0, 0, 0, 0,
241 UAC_IFACE_CODE, /* Audio Interface Class Code */
242 0, /* Audio Interface Subclass Codes, support streaming only */
243 0, 0
244};
245
246
247static USB_DRIVER_T au_driver =
248{
249 "audio class driver",
250 au_probe,
251 au_disconnect,
252 au_id_table,
253 NULL, /* suspend */
254 NULL, /* resume */
255 {NULL, NULL} /* driver_list */
256};
257
258
260
265void UAC_Init(void)
266{
267 memset((char *)&g_au_dev[0], 0, sizeof(g_au_dev));
268 g_audev_list = NULL;
269 USBH_RegisterDriver(&au_driver);
270}
271
272
282{
283 return g_audev_list;
284}
285
286 /* end of group USBH_AS_EXPORTED_FUNCTIONS */
288 /* end of group USBH_AS_Driver */
290 /* end of group USB_Host_Driver */
292 /* end of group Component_Library */
294
295
296
297
298
#define NULL
Definition: M4521.h:13912
#define TRUE
Definition: M4521.h:13905
#define FALSE
Definition: M4521.h:13908
#define CONFIG_AU_MAX_DEV
Definition: usbh_uac.h:24
#define ISO_OUT_URB_CNT
Definition: usbh_uac.h:28
#define UAC_RET_DRV_NOT_SUPPORTED
Definition: usbh_uac.h:45
#define ISO_IN_URB_CNT
Definition: usbh_uac.h:27
int ctrl_ifnum
Definition: usbh_uac.h:107
EP_INFO_T * ep_au_out
Definition: usbh_uac.h:117
EP_INFO_T * ep_au_in
Definition: usbh_uac.h:116
void * priv
Definition: usbh_uac.h:110
int au_out_ifnum
Definition: usbh_uac.h:109
USB_DEV_T * udev
Definition: usbh_uac.h:106
struct uac_dev_t * next
Definition: usbh_uac.h:111
void UAC_Init(void)
Initialize this USB Audio Class driver.
Definition: uac_driver.c:265
URB_T * urbout[ISO_OUT_URB_CNT]
Definition: usbh_uac.h:119
int au_in_ifnum
Definition: usbh_uac.h:108
UAC_DEV_T * UAC_GetDeviceList(void)
Get a list of currently connected USB Audio Class devices.
Definition: uac_driver.c:281
URB_T * urbin[ISO_IN_URB_CNT]
Definition: usbh_uac.h:118
int32_t USBH_RegisterDriver(USB_DRIVER_T *new_driver)
Register a device driver to USB Host Core driver.
Definition: usbh_core.c:78
int32_t USBH_UnlinkUrb(URB_T *urb)
Cancel an URB which has been submit to USB core.
Definition: usbh_core.c:237
void USBH_FreeUrb(URB_T *)
Free the URB allocated from USBH_AllocUrb()
Definition: usbh_support.c:99
USB Host core driver header file.
USB_IF_DESC_T
Definition: usbh_core.h:315
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
#define USB_ERR_NODEV
Definition: usbh_err_code.h:11