blob: d9d18a248690874b31b5a1f7bd06c0d6f41a32b2 [file] [log] [blame]
Channagoud Kadabic14b2a52015-01-06 15:05:12 -08001/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
Amol Jadif3d5a892013-07-23 16:09:44 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/* This file implements the UDC (usb device controller) layer to be used with
30 * the new dwc controller.
31 * It exposes APIs to initialize UDC (and thus usb) and perform data transfer
32 * over usb.
33 */
34
35#include <reg.h>
36#include <debug.h>
37#include <string.h>
38#include <malloc.h>
39#include <stdlib.h>
40#include <arch/defines.h>
41#include <dev/udc.h>
42#include <platform/iomap.h>
43#include <usb30_dwc.h>
44#include <usb30_wrapper.h>
45#include <usb30_udc.h>
Amol Jadi5418da32013-10-11 14:14:47 -070046#include <smem.h>
47#include <board.h>
48#include <platform/timer.h>
Channagoud Kadabi1f24f8a2015-02-11 15:43:10 -080049#include <qmp_phy.h>
Amol Jadif3d5a892013-07-23 16:09:44 -070050
51//#define DEBUG_USB
52
53#ifdef DEBUG_USB
54#define DBG(...) dprintf(ALWAYS, __VA_ARGS__)
55#else
56#define DBG(...)
57#endif
58
59#define ERR(...) dprintf(ALWAYS, __VA_ARGS__)
60
61/* control data transfer is max 512 bytes */
62#define UDC_CONTROL_RX_BUF_SIZE 512
63#define UDC_CONTROL_TX_BUF_SIZE 512
64
65/* Buffer used by dwc driver to process events.
66 * Must be multiple of 4: snps 6.2.7.2.
67 */
68#define UDC_DWC_EVENT_BUF_SIZE 4096
69
70/* macro to parse setup request */
71#define SETUP(type,request) (((type) << 8) | (request))
72
73/* macro to generate bit representation of an EP */
74#define EPT_TX(n) (1 << ((n) + 16))
75#define EPT_RX(n) (1 << (n))
76
Channagoud Kadabi4ec44212014-11-03 14:54:12 -080077/* Macro for bulk SS EP descriptors */
78#define EP_BULK_IN_INDEX 21
79#define EP_BULK_OUT_INDEX 34
80
Amol Jadif3d5a892013-07-23 16:09:44 -070081/* Local functions */
82static struct udc_descriptor *udc_descriptor_alloc(uint32_t type,
83 uint32_t num,
84 uint32_t len,
85 udc_desc_spec_t spec);
86static uint8_t udc_string_desc_alloc(udc_t *udc, const char *str);
87
88static void udc_descriptor_register(udc_t *udc, struct udc_descriptor *desc);
89static void udc_register_language_desc(udc_t *udc);
90static void udc_register_bos_desc(udc_t *udc);
91static void udc_register_device_desc_usb_20(udc_t *udc, struct udc_device *dev_info);
92static void udc_register_device_desc_usb_30(udc_t *udc, struct udc_device *dev_info);
93static void udc_register_config_desc_usb20(udc_t *udc, struct udc_gadget *gadget);
94static void udc_register_config_desc_usb30(udc_t *udc, struct udc_gadget *gadget);
95
96static void udc_ept_desc_fill(struct udc_endpoint *ept, uint8_t *data);
97static void udc_ept_comp_desc_fill(struct udc_endpoint *ept, uint8_t *data);
98
99static void udc_dwc_notify(void *context, dwc_notify_event_t event);
100static int udc_handle_setup(void *context, uint8_t *data);
101
102/* TODO: This must be the only global var in this file, for now.
103 * Ideally, all APIs should be sending
104 * this to us and this ptr should be kept outside of this code.
105 * This needs change in the common udc APIs and thus keeping it here until that
106 * is done.
107 */
108static udc_t *udc_dev = NULL;
109
110
Amol Jadi5418da32013-10-11 14:14:47 -0700111__WEAK int platform_is_8974()
Amol Jadif3d5a892013-07-23 16:09:44 -0700112{
Amol Jadi5418da32013-10-11 14:14:47 -0700113 return 0;
Amol Jadif3d5a892013-07-23 16:09:44 -0700114}
115
Amol Jadi5418da32013-10-11 14:14:47 -0700116__WEAK int platform_is_8974Pro()
Amol Jadif3d5a892013-07-23 16:09:44 -0700117{
Amol Jadi5418da32013-10-11 14:14:47 -0700118 return 0;
119}
120
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800121static void phy_reset(usb_wrapper_dev_t *wrapper, struct udc_device *dev_info)
Amol Jadi5418da32013-10-11 14:14:47 -0700122{
123 /* phy reset is different for some platforms. */
Channagoud Kadabi7bb866c2014-02-18 11:53:06 -0800124 if (platform_is_8974() || platform_is_8974Pro())
Amol Jadi5418da32013-10-11 14:14:47 -0700125 {
126 /* SS PHY */
127 usb_wrapper_ss_phy_reset(wrapper);
128
129 /* For 8974: hs phy is reset as part of soft reset.
130 * No need for explicit reset.
131 */
132 }
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800133 else
Amol Jadi5418da32013-10-11 14:14:47 -0700134 {
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800135 if (dev_info->t_usb_if->phy_reset)
136 dev_info->t_usb_if->phy_reset();
Channagoud Kadabi685337e2013-11-13 13:53:24 -0800137
138 /* On some CDPs PHY_COMMON reset does not set
139 * reset values in the phy_ctrl_common register.
140 * Due to this USB does not get enumerated in fastboot
141 * Force write the reset value
142 */
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800143 if (board_platform_id() == APQ8084)
144 usb_wrapper_hs_phy_ctrl_force_write(wrapper);
Amol Jadi5418da32013-10-11 14:14:47 -0700145 }
146}
147
148/* Initialize HS phy */
149void hs_phy_init(udc_t *dev)
150{
151 /* only for 8974 */
Channagoud Kadabi7bb866c2014-02-18 11:53:06 -0800152 if (platform_is_8974() || platform_is_8974Pro())
Amol Jadi5418da32013-10-11 14:14:47 -0700153 {
154 /* 5.a, 5.b */
155 usb_wrapper_hs_phy_init(dev->wrapper_dev);
156
157 /* 5.d */
158 dwc_usb2_phy_soft_reset(dev->dwc);
159 }
160}
161
162/* vbus override */
163void vbus_override(udc_t *dev)
164{
165 /* when vbus signal is not available directly to the controller,
166 * simulate vbus presense.
167 */
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800168 usb_wrapper_vbus_override(dev->wrapper_dev);
Amol Jadif3d5a892013-07-23 16:09:44 -0700169}
170
171
172/* Initialize usb wrapper and dwc h/w blocks. */
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800173static void usb30_init(struct udc_device *dev_info)
Amol Jadif3d5a892013-07-23 16:09:44 -0700174{
175 usb_wrapper_dev_t* wrapper;
176 usb_wrapper_config_t wrapper_config;
177
178 dwc_dev_t *dwc;
179 dwc_config_t dwc_config;
180
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800181 /* initialize usb clocks */
182 if (dev_info->t_usb_if->clock_init)
183 dev_info->t_usb_if->clock_init();
184
Amol Jadif3d5a892013-07-23 16:09:44 -0700185 /* initialize the usb wrapper h/w block */
186 wrapper_config.qscratch_base = (void*) MSM_USB30_QSCRATCH_BASE;
187
188 wrapper = usb_wrapper_init(&wrapper_config);
189 ASSERT(wrapper);
190
191 /* save the wrapper ptr */
192 udc_dev->wrapper_dev = wrapper;
193
194 /* initialize the dwc device block */
195 dwc_config.base = (void*) MSM_USB30_BASE;
196
197 /* buffer must be aligned to buf size. snps 8.2.2 */
198 dwc_config.event_buf = memalign(lcm(CACHE_LINE, UDC_DWC_EVENT_BUF_SIZE),
199 ROUNDUP(UDC_DWC_EVENT_BUF_SIZE, CACHE_LINE));
200 ASSERT(dwc_config.event_buf);
201
202 dwc_config.event_buf_size = UDC_DWC_EVENT_BUF_SIZE;
203
204 /* notify handler */
205 dwc_config.notify_context = udc_dev;
206 dwc_config.notify = udc_dwc_notify;
207
208 /* setup handler */
209 dwc_config.setup_context = udc_dev;
210 dwc_config.setup_handler = udc_handle_setup;
211
212 dwc = dwc_init(&dwc_config);
213 ASSERT(dwc);
214
215 /* save the dwc dev ptr */
216 udc_dev->dwc = dwc;
217
218
219 /* USB3.0 core and phy initialization as described in HPG */
220
221 /* section 4.4.1 Control sequence */
222 usb_wrapper_dbm_mode(wrapper, DBM_MODE_BYPASS);
223
224 /* section 4.4.1: use config 0 - all of RAM1 */
225 usb_wrapper_ram_configure(wrapper);
226
227 /* section 4.4.2: Initialization and configuration sequences */
228
229 /* 1. UTMI Mux configuration */
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800230 if (dev_info->t_usb_if->mux_config)
231 dev_info->t_usb_if->mux_config();
Amol Jadif3d5a892013-07-23 16:09:44 -0700232
233 /* 2. Put controller in reset */
234 dwc_reset(dwc, 1);
235
Channagoud Kadabic14b2a52015-01-06 15:05:12 -0800236
Amol Jadi5418da32013-10-11 14:14:47 -0700237 /* Steps 3 - 7 must be done while dwc is in reset condition */
Amol Jadif3d5a892013-07-23 16:09:44 -0700238
Amol Jadi5418da32013-10-11 14:14:47 -0700239 /* 3. Reset PHY */
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800240 phy_reset(wrapper, dev_info);
Amol Jadif3d5a892013-07-23 16:09:44 -0700241
242 /* 4. SS phy config */
Channagoud Kadabi1f24f8a2015-02-11 15:43:10 -0800243 if (!use_hsonly_mode())
244 usb_wrapper_ss_phy_configure(wrapper);
Amol Jadif3d5a892013-07-23 16:09:44 -0700245
246 /* 5. HS phy init */
247 usb_wrapper_hs_phy_init(wrapper);
248
Amol Jadif3d5a892013-07-23 16:09:44 -0700249 /* 6. hs phy config */
250 usb_wrapper_hs_phy_configure(wrapper);
251
252 /* 7. Reset PHY digital interface */
253 dwc_phy_digital_reset(dwc);
254
255 /* 8. Bring dwc controller out of reset */
256 dwc_reset(dwc, 0);
257
258 /* 9. */
259 usb_wrapper_ss_phy_electrical_config(wrapper);
260
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800261 /* Perform phy init */
262 if (dev_info->t_usb_if->phy_init)
263 dev_info->t_usb_if->phy_init();
264
Channagoud Kadabi1f24f8a2015-02-11 15:43:10 -0800265 /* HS only mode support */
266 if (use_hsonly_mode())
267 usb_wrapper_hsonly_mode(wrapper);
268
Amol Jadif3d5a892013-07-23 16:09:44 -0700269 /* 10. */
270 usb_wrapper_workaround_10(wrapper);
271
272 /* 11. */
273 usb_wrapper_workaround_11(wrapper);
274
275 /* 12. */
276 dwc_ss_phy_workaround_12(dwc);
277
278 /* 13. */
279 usb_wrapper_workaround_13(wrapper);
280
281 /* 14. needed only for host mode. ignored. */
282
Amol Jadi5418da32013-10-11 14:14:47 -0700283 /* If the target does not support vbus detection in controller,
284 * simulate vbus presence.
285 */
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800286 if (dev_info->t_usb_if->vbus_override)
287 vbus_override(udc_dev);
Amol Jadi5418da32013-10-11 14:14:47 -0700288
Amol Jadif3d5a892013-07-23 16:09:44 -0700289 /* 15 - 20 */
290 dwc_device_init(dwc);
291}
292
293/* udc_init: creates and registers various usb descriptor */
Amol Jadi151f2a52013-10-07 12:39:11 -0700294int usb30_udc_init(struct udc_device *dev_info)
Amol Jadif3d5a892013-07-23 16:09:44 -0700295{
296 /* create and initialize udc instance */
297 udc_dev = (udc_t*) malloc(sizeof(udc_t));
298 ASSERT(udc_dev);
299
300 /* initialize everything to 0 */
301 memset(udc_dev, 0 , sizeof(udc_t));
302
303 /* malloc control data buffers */
304 udc_dev->ctrl_rx_buf = memalign(CACHE_LINE, ROUNDUP(UDC_CONTROL_RX_BUF_SIZE, CACHE_LINE));
305 ASSERT(udc_dev->ctrl_rx_buf);
306
307 udc_dev->ctrl_tx_buf = memalign(CACHE_LINE, ROUNDUP(UDC_CONTROL_TX_BUF_SIZE, CACHE_LINE));
308 ASSERT(udc_dev->ctrl_tx_buf);
309
310 /* initialize string id */
311 udc_dev->next_string_id = 1;
312
313 /* Initialize ept data */
314 /* alloc table to assume EP0 In/OUT are already allocated.*/
315 udc_dev->ept_alloc_table = EPT_TX(0) | EPT_RX(0);
316 udc_dev->ept_list = NULL;
317
Channagoud Kadabi9a8062e2014-02-04 17:09:10 -0800318 usb30_init(dev_info);
Amol Jadif3d5a892013-07-23 16:09:44 -0700319
320 /* register descriptors */
321 udc_register_language_desc(udc_dev);
322 udc_register_device_desc_usb_20(udc_dev, dev_info);
323 udc_register_device_desc_usb_30(udc_dev, dev_info);
324 udc_register_bos_desc(udc_dev);
325
326 return 0;
327}
328
329/* application registers its gadget by calling this func.
330 * gadget == interface descriptor
331 */
Amol Jadi151f2a52013-10-07 12:39:11 -0700332int usb30_udc_register_gadget(struct udc_gadget *gadget)
Amol Jadif3d5a892013-07-23 16:09:44 -0700333{
334 ASSERT(gadget);
335
336 /* check if already registered */
337 if (udc_dev->gadget)
338 {
339 ERR("\nonly one gadget supported\n");
340 return -1;
341 }
342
343 /* create our configuration descriptors based on this gadget data */
344 udc_register_config_desc_usb20(udc_dev, gadget);
345 udc_register_config_desc_usb30(udc_dev, gadget);
346
347 /* save the gadget */
348 udc_dev->gadget = gadget;
349
350 return 0;
351}
352
353/* udc_start: */
Amol Jadi151f2a52013-10-07 12:39:11 -0700354int usb30_udc_start(void)
Amol Jadif3d5a892013-07-23 16:09:44 -0700355{
356 /* 19. run
357 * enable device to receive SOF packets and
358 * respond to control transfers on EP0 and generate events.
359 */
360 dwc_device_run(udc_dev->dwc, 1);
361
362 return 0;
363}
364
365/* Control data rx callback. Called by DWC layer when it receives control
366 * data from host.
367 */
368void udc_control_rx_callback(void *context, unsigned actual, int status)
369{
370 udc_t *udc = (udc_t *) context;
371
372 /* Force reload of buffer update by controller from memory */
373 arch_invalidate_cache_range((addr_t) udc->ctrl_rx_buf, actual);
374
375 /* TODO: for now, there is only one 3-stage write during 3.0 enumeration
376 * (SET_SEL), which causes this callback. Ideally, set_periodic() must
377 * be based on which control rx just happened.
378 * Also, the value of 0x65 should depend on the data received for SET_SEL.
379 * For now, this value works just fine.
380 */
381 dwc_device_set_periodic_param(udc->dwc, 0x65);
382}
383
384/* lookup request name for debug purposes */
385static const char *reqname(uint32_t r)
386{
387 switch (r) {
388 case GET_STATUS:
389 return "GET_STATUS";
390 case CLEAR_FEATURE:
391 return "CLEAR_FEATURE";
392 case SET_FEATURE:
393 return "SET_FEATURE";
394 case SET_ADDRESS:
395 return "SET_ADDRESS";
396 case GET_DESCRIPTOR:
397 return "GET_DESCRIPTOR";
398 case SET_DESCRIPTOR:
399 return "SET_DESCRIPTOR";
400 case GET_CONFIGURATION:
401 return "GET_CONFIGURATION";
402 case SET_CONFIGURATION:
403 return "SET_CONFIGURATION";
404 case GET_INTERFACE:
405 return "GET_INTERFACE";
406 case SET_INTERFACE:
407 return "SET_INTERFACE";
408 case SET_SEL:
409 return "SET_SEL";
410 default:
411 return "*UNKNOWN*";
412 }
413}
414
415/* callback function called by DWC layer when a setup packed is received.
416 * the return value tells dwc layer whether this setup pkt results in
417 * a 2-stage or a 3-stage control transfer or stall.
418 */
419static int udc_handle_setup(void *context, uint8_t *data)
420{
421 udc_t *udc = (udc_t *) context;
422 uint32_t len;
423
424 ASSERT(udc);
425
426 dwc_dev_t *dwc = udc->dwc;
427 ASSERT(dwc);
428
429 struct setup_packet s = *((struct setup_packet*) data);
430
431 DBG("\n SETUP request: \n type = 0x%x \n request = 0x%x \n value = 0x%x"
432 " \n index = 0x%x \n length = 0x%x\n",
433 s.type, s.request, s.value, s.index, s.length);
434
435 switch (SETUP(s.type, s.request))
436 {
437 case SETUP(DEVICE_READ, GET_STATUS):
438 {
439 DBG("\n DEVICE_READ : GET_STATUS: value = %d index = %d"
440 " length = %d", s.value, s.index, s.length);
441
442 if (s.length == 2) {
443
444 uint16_t zero = 0;
445 len = 2;
446
447 /* copy to tx buffer */
448 memcpy(udc->ctrl_tx_buf, &zero, len);
449
450 /* flush buffer to main memory before queueing the request */
451 arch_clean_invalidate_cache_range((addr_t) udc->ctrl_tx_buf, len);
452
453 dwc_transfer_request(udc->dwc,
454 0,
455 DWC_EP_DIRECTION_IN,
456 udc->ctrl_tx_buf,
457 len,
458 NULL,
459 NULL);
460
461 return DWC_SETUP_3_STAGE;
462 }
463 }
464 break;
465 case SETUP(DEVICE_READ, GET_DESCRIPTOR):
466 {
467 DBG("\n DEVICE_READ : GET_DESCRIPTOR: value = %d", s.value);
468
469 /* setup usb ep0-IN to send our device descriptor */
470 struct udc_descriptor *desc;
471
472 for (desc = udc->desc_list; desc; desc = desc->next)
473 {
474 /* tag must match the value AND
475 * if speed is SS, desc must comply with 30 spec OR
476 * if speed is not SS, desc must comply with 20 spec.
477 */
478 if ((desc->tag == s.value) &&
479 (((udc->speed == UDC_SPEED_SS) && (desc->spec & UDC_DESC_SPEC_30)) ||
480 ((udc->speed != UDC_SPEED_SS) && (desc->spec & UDC_DESC_SPEC_20)))
481 )
482 {
483 if (desc->len > s.length)
484 len = s.length;
485 else
486 len = desc->len;
487
488 /* copy to tx buffer */
489 memcpy(udc->ctrl_tx_buf, desc->data, len);
490
491 /* flush buffer to main memory before queueing the request */
492 arch_clean_invalidate_cache_range((addr_t) udc->ctrl_tx_buf, len);
493
494 dwc_transfer_request(udc->dwc,
495 0,
496 DWC_EP_DIRECTION_IN,
497 udc->ctrl_tx_buf,
498 len,
499 NULL,
500 NULL);
501
502 return DWC_SETUP_3_STAGE;
503 }
504 }
505 DBG("\n Did not find matching descriptor: = 0x%x", s.value);
506 }
507 break;
508 case SETUP(DEVICE_READ, GET_CONFIGURATION):
509 {
510 DBG("\n DEVICE_READ : GET_CONFIGURATION");
511
512 if ((s.value == 0) && (s.index == 0) && (s.length == 1)) {
513
514 len = 1;
515
516 /* copy to tx buffer */
517 memcpy(udc->ctrl_tx_buf, &udc->config_selected, len);
518
519 /* flush buffer to main memory before queueing the request */
520 arch_clean_invalidate_cache_range((addr_t) udc->ctrl_tx_buf, len);
521
522 dwc_transfer_request(udc->dwc,
523 0,
524 DWC_EP_DIRECTION_IN,
525 udc->ctrl_tx_buf,
526 len,
527 NULL,
528 NULL);
529
530 return DWC_SETUP_3_STAGE;
531 }
532 else
533 {
534 ASSERT(0);
535 }
536 }
537 break;
538 case SETUP(DEVICE_WRITE, SET_CONFIGURATION):
539 {
540 DBG("\n DEVICE_WRITE : SET_CONFIGURATION");
541
542 /* select configuration 1 */
543 if (s.value == 1) {
544 struct udc_endpoint *ept;
545 /* enable endpoints */
546 for (ept = udc->ept_list; ept; ept = ept->next) {
547 if (ept->num == 0)
548 continue;
549 else
550 {
551 /* add this ep to dwc ep list */
Sundarajan Srinivasan1c421912014-03-31 17:55:31 -0700552 dwc_ep_t *ep = (dwc_ep_t *) malloc(sizeof(dwc_ep_t));
Amol Jadif3d5a892013-07-23 16:09:44 -0700553
Sundarajan Srinivasan1c421912014-03-31 17:55:31 -0700554 if(!ep)
555 {
556 dprintf(CRITICAL, "udc_handle_setup: DEVICE_WRITE : SET_CONFIGURATION malloc failed for ep\n");
557 ASSERT(0);
558 }
559
560 ep->number = ept->num;
561 ep->dir = ept->in;
Channagoud Kadabi5f8f1c42015-03-25 14:35:05 -0700562 ep->type = ept->type;
Sundarajan Srinivasan1c421912014-03-31 17:55:31 -0700563 ep->max_pkt_size = ept->maxpkt;
564 ep->burst_size = ept->maxburst;
565 ep->zlp = 0; /* TODO: zlp could be made part of ept */
566 ep->trb_count = ept->trb_count;
567 ep->trb = ept->trb;
Amol Jadif3d5a892013-07-23 16:09:44 -0700568
569 dwc_device_add_ep(dwc, ep);
Sundarajan Srinivasan1c421912014-03-31 17:55:31 -0700570
571 if(ep)
572 free(ep);
Amol Jadif3d5a892013-07-23 16:09:44 -0700573 }
574 }
575
576 /* now that we have saved the non-control EP details, set config */
577 dwc_device_set_configuration(dwc);
578
579 /* inform client that we are configured. */
580 udc->gadget->notify(udc_dev->gadget, UDC_EVENT_ONLINE);
581
582 udc->config_selected = 1;
583
584 return DWC_SETUP_2_STAGE;
585 }
586 else if (s.value == 0)
587 {
588 /* 0 == de-configure. */
589 udc->config_selected = 0;
590 DBG("\n\n CONFIG = 0 !!!!!!!!!\n\n");
591 return DWC_SETUP_2_STAGE;
592 /* TODO: do proper handling for de-config */
593 }
594 else
595 {
596 ERR("\n CONFIG = %d not supported\n", s.value);
597 ASSERT(0);
598 }
599 }
600 break;
601 case SETUP(DEVICE_WRITE, SET_ADDRESS):
602 {
603 DBG("\n DEVICE_WRITE : SET_ADDRESS");
604
605 dwc_device_set_addr(dwc, s.value);
606 return DWC_SETUP_2_STAGE;
607 }
608 break;
609 case SETUP(INTERFACE_WRITE, SET_INTERFACE):
610 {
611 DBG("\n DEVICE_WRITE : SET_INTERFACE");
612 /* if we ack this everything hangs */
613 /* per spec, STALL is valid if there is not alt func */
614 goto stall;
615 }
616 break;
617 case SETUP(DEVICE_WRITE, SET_FEATURE):
618 {
619 DBG("\n DEVICE_WRITE : SET_FEATURE");
620 goto stall;
621 }
622 break;
623 case SETUP(DEVICE_WRITE, CLEAR_FEATURE):
624 {
625 DBG("\n DEVICE_WRITE : CLEAR_FEATURE");
626 goto stall;
627 }
628 break;
629 case SETUP(ENDPOINT_WRITE, CLEAR_FEATURE):
630 {
Channagoud Kadabide1c1622014-01-13 11:39:06 -0800631 uint8_t usb_epnum;
632 uint8_t dir;
633
634 DBG("\n ENDPOINT_WRITE : CLEAR_FEATURE");
635
636 /*
637 * setup packet received from the host has
638 * index field containing information about the USB
639 * endpoint as below:
640 * __________________________________
641 * | (7) | (6 - 4) | (3 - 0) |
642 * |DIR | Reserved | EP number |
643 * |______|_____________|_____________|
644 */
645 usb_epnum = (s.index & USB_EP_NUM_MASK);
Channagoud Kadabica641d42014-11-21 16:58:51 -0800646 dir = ((s.index & USB_EP_DIR_MASK) == USB_EP_DIR_IN) ? 0x1 : 0x0;
Channagoud Kadabide1c1622014-01-13 11:39:06 -0800647
648 /*
649 * Convert the logical ep number to physical before
650 * sending the clear stall command.
651 * As per the data book we use fixed mapping as
652 * below:
653 * physical ep 0 --> logical ep0 OUT
654 * physical ep 1 --> logical ep0 IN
655 * physical ep 2 --> logical ep 1 OUT
656 * physical ep 3 --> logical ep 1 IN
657 * :
658 * :
659 * physical ep 30 --> logical ep 15 OUT
660 * physical ep 31 --> logical ep 15 IN
661 */
662 dwc_ep_cmd_clear_stall(dwc, DWC_EP_PHY_NUM(usb_epnum, dir));
663
664 return DWC_SETUP_2_STAGE;
Amol Jadif3d5a892013-07-23 16:09:44 -0700665 }
666 break;
667 case SETUP(DEVICE_WRITE, SET_SEL):
668 {
669 DBG("\n DEVICE_WRITE : SET_SEL");
670
671 /* this is 3-stage write. need to receive data of s.length size. */
672 if (s.length > 0) {
673 dwc_transfer_request(udc->dwc,
674 0,
675 DWC_EP_DIRECTION_OUT,
676 udc->ctrl_rx_buf,
677 UDC_CONTROL_RX_BUF_SIZE,
678 udc_control_rx_callback,
679 (void *) udc);
680 return DWC_SETUP_3_STAGE;
681 }
682 else
683 {
684 /* length must be non-zero */
685 ASSERT(0);
686 }
687 }
688 break;
689
690 default:
Channagoud Kadabi4ec44212014-11-03 14:54:12 -0800691 /* some of the requests from host are not handled, add a debug
692 * for the command not being handled, this is not fatal
693 */
694 DBG("\n Unknown setup req.\n type = 0x%x value = %d index = %d"
Amol Jadif3d5a892013-07-23 16:09:44 -0700695 " length = %d\n", s.type, s.value, s.index, s.length);
Amol Jadif3d5a892013-07-23 16:09:44 -0700696 }
697
698stall:
699 ERR("\nSTALL. Unsupported setup req: %s %d %d %d %d %d\n",
700 reqname(s.request), s.type, s.request, s.value, s.index, s.length);
701
702 return DWC_SETUP_ERROR;
703}
704
705/* Callback function called by DWC layer when a request to transfer data
706 * on non-control EP is completed.
707 */
708void udc_request_complete(void *context, uint32_t actual, int status)
709{
710 struct udc_request *req = ((udc_t *) context)->queued_req;
711
712 DBG("\n UDC: udc_request_callback: xferred %d bytes status = %d\n",
713 actual, status);
714
715 /* clear the queued request. */
716 ((udc_t *) context)->queued_req = NULL;
717
718 if (req->complete)
719 {
720 req->complete(req, actual, status);
721 }
722
723 DBG("\n UDC: udc_request_callback: done fastboot callback\n");
724}
725
726/* App interface to queue in data transfer requests for control and data ep */
Amol Jadi151f2a52013-10-07 12:39:11 -0700727int usb30_udc_request_queue(struct udc_endpoint *ept, struct udc_request *req)
Amol Jadif3d5a892013-07-23 16:09:44 -0700728{
729 int ret;
730 dwc_dev_t *dwc_dev = udc_dev->dwc;
731
732 /* ensure device is initialized before queuing request */
733 ASSERT(dwc_dev);
734
735 /* if device is not configured, return error */
736 if(udc_dev->config_selected == 0)
737 {
738 return -1;
739 }
740
741 /* only one request at a time is supported.
742 * check if a request is already queued.
743 */
744 if(udc_dev->queued_req)
745 {
746 return -1;
747 }
748
749 DBG("\n udc_request_queue: entry: ep_usb_num = %d", ept->num);
750
751 /* save the queued request. */
752 udc_dev->queued_req = req;
753
754 ret = dwc_transfer_request(dwc_dev,
755 ept->num,
756 ept->in ? DWC_EP_DIRECTION_IN : DWC_EP_DIRECTION_OUT,
757 req->buf,
758 req->length,
759 udc_request_complete,
760 (void *) udc_dev);
761
762 DBG("\n udc_request_queue: exit: ep_usb_num = %d", ept->num);
763
764 return ret;
765}
766
Channagoud Kadabi4ec44212014-11-03 14:54:12 -0800767static void udc_update_ep_desc(udc_t *udc, uint16_t max_pkt_sz_bulk)
768{
769 struct udc_descriptor *desc= NULL;
770 struct udc_endpoint *ept = NULL;
771
772 /*
773 * By default the bulk EP are registered with 512 Bytes
774 * as the max packet size. As per SS spec the max packet
775 * size for bulk is 1024. Some hosts treat the descriptor
776 * as invalid if the packet size is < 1024. Update the
777 * descriptors once we are notifed with SS connect event
778 */
779 for (desc = udc->desc_list; desc; desc = desc->next)
780 {
781 if (desc->data[EP_BULK_IN_INDEX] == EP_TYPE_BULK)
782 {
783 desc->data[EP_BULK_IN_INDEX + 1] = max_pkt_sz_bulk;
784 desc->data[EP_BULK_IN_INDEX + 2] = max_pkt_sz_bulk >> 8;
785 }
786
787 if (desc->data[EP_BULK_OUT_INDEX] == EP_TYPE_BULK)
788 {
789 desc->data[EP_BULK_OUT_INDEX + 1] = max_pkt_sz_bulk;
790 desc->data[EP_BULK_OUT_INDEX + 2] = max_pkt_sz_bulk >> 8;
791 }
792 }
793
794 for (ept = udc->ept_list; ept; ept = ept->next)
795 {
796 ept->maxpkt = max_pkt_sz_bulk;
797 }
798}
799
Amol Jadif3d5a892013-07-23 16:09:44 -0700800/* callback function called by dwc layer if any dwc event occurs */
801void udc_dwc_notify(void *context, dwc_notify_event_t event)
802{
803 udc_t *udc = (udc_t *) context;
Channagoud Kadabi4ec44212014-11-03 14:54:12 -0800804 uint32_t max_pkt_size = 0;
Amol Jadif3d5a892013-07-23 16:09:44 -0700805
806 switch (event)
807 {
808 case DWC_NOTIFY_EVENT_CONNECTED_LS:
809 udc->speed = UDC_SPEED_LS;
810 break;
811 case DWC_NOTIFY_EVENT_CONNECTED_FS:
812 udc->speed = UDC_SPEED_FS;
Channagoud Kadabi4ec44212014-11-03 14:54:12 -0800813 /* For FS connection update the ep descriptor
814 * with FS max packet size
815 */
816 max_pkt_size = 64;
817 udc_update_ep_desc(udc, max_pkt_size);
Amol Jadif3d5a892013-07-23 16:09:44 -0700818 break;
819 case DWC_NOTIFY_EVENT_CONNECTED_HS:
820 udc->speed = UDC_SPEED_HS;
Channagoud Kadabi4ec44212014-11-03 14:54:12 -0800821 /* For HS connection update the ep descriptor
822 * with HS max packet size
823 */
824 max_pkt_size = 512;
825 udc_update_ep_desc(udc, max_pkt_size);
Amol Jadif3d5a892013-07-23 16:09:44 -0700826 break;
827 case DWC_NOTIFY_EVENT_CONNECTED_SS:
828 udc->speed = UDC_SPEED_SS;
Channagoud Kadabi4ec44212014-11-03 14:54:12 -0800829 /* For SS connection update the ep descriptor
830 * with SS max packet size
831 */
832 max_pkt_size = 1024;
833 udc_update_ep_desc(udc, max_pkt_size);
Amol Jadif3d5a892013-07-23 16:09:44 -0700834 break;
835 case DWC_NOTIFY_EVENT_DISCONNECTED:
836 case DWC_NOTIFY_EVENT_OFFLINE:
837 udc->config_selected = 0;
838 if (udc->gadget && udc->gadget->notify)
839 udc->gadget->notify(udc->gadget, UDC_EVENT_OFFLINE);
840 break;
841 default:
842 ASSERT(0);
843 }
844}
845
846
847/******************* Function related to descriptor allocation etc.************/
848
849static struct udc_endpoint *_udc_endpoint_alloc(uint8_t num,
850 uint8_t in,
Channagoud Kadabi5f8f1c42015-03-25 14:35:05 -0700851 uint8_t type,
Amol Jadif3d5a892013-07-23 16:09:44 -0700852 uint16_t max_pkt)
853{
854 struct udc_endpoint *ept;
855 udc_t *udc = udc_dev;
856
857 ept = malloc(sizeof(*ept));
858 ASSERT(ept);
859
860 ept->maxpkt = max_pkt;
861 ept->num = num;
Channagoud Kadabi5f8f1c42015-03-25 14:35:05 -0700862 ept->type = type;
Amol Jadif3d5a892013-07-23 16:09:44 -0700863 ept->in = !!in;
864 ept->maxburst = 4; /* no performance improvement is seen beyond burst size of 4 */
865 ept->trb_count = 66; /* each trb can transfer (16MB - 1). 65 for 1GB transfer + 1 for roundup/zero length pkt. */
866 ept->trb = memalign(lcm(CACHE_LINE, 16), ROUNDUP(ept->trb_count*sizeof(dwc_trb_t), CACHE_LINE)); /* TRB must be aligned to 16 */
867 ASSERT(ept->trb);
868
869 /* push it on top of ept_list */
870 ept->next = udc->ept_list;
871 udc->ept_list = ept;
872
873 return ept;
874}
875
876/* Called to create non-control in/out End Point structures by the APP */
Amol Jadi151f2a52013-10-07 12:39:11 -0700877struct udc_endpoint *usb30_udc_endpoint_alloc(unsigned type, unsigned maxpkt)
Amol Jadif3d5a892013-07-23 16:09:44 -0700878{
879 struct udc_endpoint *ept;
880 uint8_t in;
881 uint8_t n;
882 udc_t *udc = udc_dev;
883
884 if (type == UDC_TYPE_BULK_IN) {
885 in = 1;
Channagoud Kadabi5f8f1c42015-03-25 14:35:05 -0700886 type = EP_TYPE_BULK;
Amol Jadif3d5a892013-07-23 16:09:44 -0700887 } else if (type == UDC_TYPE_BULK_OUT) {
888 in = 0;
Channagoud Kadabi5f8f1c42015-03-25 14:35:05 -0700889 type = EP_TYPE_BULK;
890 } else if (type == UDC_TYPE_INTR_IN) {
891 in = 1;
892 type = EP_TYPE_INTERRUPT;
893 } else if (type == UDC_TYPE_INTR_OUT){
894 in = 0;
895 type = EP_TYPE_INTERRUPT;
Amol Jadif3d5a892013-07-23 16:09:44 -0700896 } else {
897 return 0;
898 }
899
900 for (n = 1; n < 16; n++) {
901 uint32_t bit = in ? EPT_TX(n) : EPT_RX(n);
902 if (udc->ept_alloc_table & bit)
903 continue;
Channagoud Kadabi5f8f1c42015-03-25 14:35:05 -0700904 ept = _udc_endpoint_alloc(n, in, type, maxpkt);
Amol Jadif3d5a892013-07-23 16:09:44 -0700905 if (ept)
906 udc->ept_alloc_table |= bit;
907 return ept;
908 }
909 return 0;
910}
911
912
913/* create config + interface + ep desc for 2.0 */
914static void udc_register_config_desc_usb20(udc_t *udc,
915 struct udc_gadget *gadget)
916{
917 uint8_t *data;
918 uint16_t size;
919 struct udc_descriptor *desc;
920
921 ASSERT(udc);
922 ASSERT(gadget);
923
924 /* create our configuration descriptor */
925
926 /* size is the total size of (config + interface + all EPs) descriptor */
927 size = UDC_DESC_SIZE_CONFIGURATION +
928 UDC_DESC_SIZE_INTERFACE +
929 (gadget->ifc_endpoints*UDC_DESC_SIZE_ENDPOINT);
930
931 desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size, UDC_DESC_SPEC_20);
932
933 data = desc->data;
934
935 /* Config desc */
936 data[0] = 0x09;
937 data[1] = TYPE_CONFIGURATION;
938 data[2] = size;
939 data[3] = size >> 8;
940 data[4] = 0x01; /* number of interfaces */
941 data[5] = 0x01; /* configuration value */
942 data[6] = 0x00; /* configuration string */
943 data[7] = 0xC0; /* attributes: reserved and self-powered set */
944 data[8] = 0x00; /* max power: 0ma since we are self powered */
945 data += 9;
946
947 /* Interface desc */
948 data[0] = 0x09;
949 data[1] = TYPE_INTERFACE;
950 data[2] = 0x00; /* ifc number */
951 data[3] = 0x00; /* alt number */
952 data[4] = gadget->ifc_endpoints;
953 data[5] = gadget->ifc_class;
954 data[6] = gadget->ifc_subclass;
955 data[7] = gadget->ifc_protocol;
956 data[8] = udc_string_desc_alloc(udc, gadget->ifc_string);
957 data += 9;
958
959 for (uint8_t n = 0; n < gadget->ifc_endpoints; n++) {
960 udc_ept_desc_fill(gadget->ept[n], data);
961 data += UDC_DESC_SIZE_ENDPOINT;
962 }
963
964 udc_descriptor_register(udc, desc);
965}
966
967/* create config + interface + ep desc for 3.0 */
968static void udc_register_config_desc_usb30(udc_t *udc,
969 struct udc_gadget *gadget)
970{
971 uint8_t *data;
972 uint16_t size;
973 struct udc_descriptor *desc;
974
975 ASSERT(udc);
976 ASSERT(gadget);
977
978 /* create our configuration descriptor */
979
980 /* size is the total size of (config + interface + all EPs) descriptor */
981 size = UDC_DESC_SIZE_CONFIGURATION +
982 UDC_DESC_SIZE_INTERFACE +
983 (gadget->ifc_endpoints*(UDC_DESC_SIZE_ENDPOINT + UDC_DESC_SIZE_ENDPOINT_COMP));
984
985 desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size, UDC_DESC_SPEC_30);
986
987 data = desc->data;
988
989 /* Config desc */
990 data[0] = 0x09;
991 data[1] = TYPE_CONFIGURATION;
992 data[2] = size;
993 data[3] = size >> 8;
994 data[4] = 0x01; /* number of interfaces */
995 data[5] = 0x01; /* configuration value */
996 data[6] = 0x00; /* configuration string */
997 data[7] = 0xC0; /* attributes: reserved and self-powered set */
998 data[8] = 0x00; /* max power: 0ma since we are self powered */
999 data += 9;
1000
1001 /* Interface desc */
1002 data[0] = 0x09;
1003 data[1] = TYPE_INTERFACE;
1004 data[2] = 0x00; /* ifc number */
1005 data[3] = 0x00; /* alt number */
1006 data[4] = gadget->ifc_endpoints;
1007 data[5] = gadget->ifc_class;
1008 data[6] = gadget->ifc_subclass;
1009 data[7] = gadget->ifc_protocol;
1010 data[8] = udc_string_desc_alloc(udc, gadget->ifc_string);
1011 data += 9;
1012
1013 for (uint8_t n = 0; n < gadget->ifc_endpoints; n++)
1014 {
1015 /* fill EP desc */
1016 udc_ept_desc_fill(gadget->ept[n], data);
1017 data += UDC_DESC_SIZE_ENDPOINT;
1018
1019 /* fill EP companion desc */
1020 udc_ept_comp_desc_fill(gadget->ept[n], data);
1021 data += UDC_DESC_SIZE_ENDPOINT_COMP;
1022 }
1023
1024 udc_descriptor_register(udc, desc);
1025}
1026
1027
1028static void udc_register_device_desc_usb_20(udc_t *udc,
1029 struct udc_device *dev_info)
1030{
1031 uint8_t *data;
1032 struct udc_descriptor *desc;
1033
1034 /* create our device descriptor */
1035 desc = udc_descriptor_alloc(TYPE_DEVICE, 0, 18, UDC_DESC_SPEC_20);
1036 data = desc->data;
1037
1038 /* data 0 and 1 is filled by descriptor alloc routine.
1039 * fill in the remaining entries.
1040 */
1041 data[2] = 0x00; /* usb spec minor rev */
1042 data[3] = 0x02; /* usb spec major rev */
1043 data[4] = 0x00; /* class */
1044 data[5] = 0x00; /* subclass */
1045 data[6] = 0x00; /* protocol */
1046 data[7] = 0x40; /* max packet size on ept 0 */
1047
1048 memcpy(data + 8, &dev_info->vendor_id, sizeof(short));
1049 memcpy(data + 10, &dev_info->product_id, sizeof(short));
1050 memcpy(data + 12, &dev_info->version_id, sizeof(short));
1051
1052 data[14] = udc_string_desc_alloc(udc, dev_info->manufacturer);
1053 data[15] = udc_string_desc_alloc(udc, dev_info->product);
1054 data[16] = udc_string_desc_alloc(udc, dev_info->serialno);
1055 data[17] = 1; /* number of configurations */
1056
1057 udc_descriptor_register(udc, desc);
1058}
1059
1060static void udc_register_device_desc_usb_30(udc_t *udc, struct udc_device *dev_info)
1061{
1062 uint8_t *data;
1063 struct udc_descriptor *desc;
1064
1065 /* create our device descriptor */
1066 desc = udc_descriptor_alloc(TYPE_DEVICE, 0, 18, UDC_DESC_SPEC_30);
1067 data = desc->data;
1068
1069 /* data 0 and 1 is filled by descriptor alloc routine.
1070 * fill in the remaining entries.
1071 */
1072 data[2] = 0x00; /* usb spec minor rev */
1073 data[3] = 0x03; /* usb spec major rev */
1074 data[4] = 0x00; /* class */
1075 data[5] = 0x00; /* subclass */
1076 data[6] = 0x00; /* protocol */
1077 data[7] = 0x09; /* max packet size on ept 0 */
1078 memcpy(data + 8, &dev_info->vendor_id, sizeof(short));
1079 memcpy(data + 10, &dev_info->product_id, sizeof(short));
1080 memcpy(data + 12, &dev_info->version_id, sizeof(short));
1081 data[14] = udc_string_desc_alloc(udc, dev_info->manufacturer);
1082 data[15] = udc_string_desc_alloc(udc, dev_info->product);
1083 data[16] = udc_string_desc_alloc(udc, dev_info->serialno);
1084 data[17] = 1; /* number of configurations */
1085
1086 udc_descriptor_register(udc, desc);
1087}
1088
1089static void udc_register_bos_desc(udc_t *udc)
1090{
1091 uint8_t *data;
1092 struct udc_descriptor *desc;
1093
1094 /* create our device descriptor */
1095 desc = udc_descriptor_alloc(TYPE_BOS, 0, 15, UDC_DESC_SPEC_30); /* 15 is total length of bos + other descriptors inside it */
1096 data = desc->data;
1097
1098 /* data 0 and 1 is filled by descriptor alloc routine.
1099 * fill in the remaining entries.
1100 */
1101 data[0] = 0x05; /* BOS desc len */
1102 data[1] = TYPE_BOS; /* BOS desc type */
1103 data[2] = 0x0F; /* total len of bos desc and its sub desc */
1104 data[3] = 0x00; /* total len of bos desc and its sub desc */
1105 data[4] = 0x01; /* num of sub desc inside bos */
1106
1107 data[5] = 0x0A; /* desc len */
1108 data[6] = 0x10; /* Device Capability desc */
1109 data[7] = 0x03; /* 3 == SuperSpeed capable */
1110 data[8] = 0x00; /* Attribute: latency tolerance msg: No */
1111 data[9] = 0x0F; /* Supported Speeds (bit mask): LS, FS, HS, SS */
1112 data[10] = 0x00; /* Reserved part of supported wSupportedSpeeds */
1113 data[11] = 0x01; /* lowest supported speed with full functionality: FS */
1114 data[12] = 0x00; /* U1 device exit latency */
1115 data[13] = 0x00; /* U2 device exit latency (lsb) */
1116 data[14] = 0x00; /* U2 device exit latency (msb) */
1117
1118 udc_descriptor_register(udc, desc);
1119}
1120
1121static void udc_register_language_desc(udc_t *udc)
1122{
1123 /* create and register a language table descriptor */
1124 /* language 0x0409 is US English */
1125 struct udc_descriptor *desc = udc_descriptor_alloc(TYPE_STRING,
1126 0,
1127 4,
1128 UDC_DESC_SPEC_20 | UDC_DESC_SPEC_30);
1129 desc->data[2] = 0x09;
1130 desc->data[3] = 0x04;
1131 udc_descriptor_register(udc, desc);
1132}
1133
1134static void udc_ept_desc_fill(struct udc_endpoint *ept, uint8_t *data)
1135{
1136 data[0] = 7;
1137 data[1] = TYPE_ENDPOINT;
1138 data[2] = ept->num | (ept->in ? 0x80 : 0x00);
1139 data[3] = 0x02; /* bulk -- the only kind we support */
1140 data[4] = ept->maxpkt;
1141 data[5] = ept->maxpkt >> 8;
1142 data[6] = 0; /* bInterval: must be 0 for bulk. */
1143}
1144
1145static void udc_ept_comp_desc_fill(struct udc_endpoint *ept, uint8_t *data)
1146{
1147 data[0] = 6; /* bLength */
1148 data[1] = TYPE_SS_EP_COMP; /* ep type */
1149 data[2] = ept->maxburst; /* maxBurst */
1150 data[3] = 0x0; /* maxStreams */
1151 data[4] = 0x0; /* wBytesPerInterval */
1152 data[5] = 0x0; /* wBytesPerInterval */
1153}
1154
1155static uint8_t udc_string_desc_alloc(udc_t *udc, const char *str)
1156{
1157 uint32_t len;
1158 struct udc_descriptor *desc;
1159 uint8_t *data;
1160
1161 if (udc->next_string_id > 255)
1162 return 0;
1163
1164 if (!str)
1165 return 0;
1166
1167 len = strlen(str);
1168 desc = udc_descriptor_alloc(TYPE_STRING,
1169 udc->next_string_id,
1170 len * 2 + 2,
1171 UDC_DESC_SPEC_20 | UDC_DESC_SPEC_30);
1172 if (!desc)
1173 return 0;
1174 udc->next_string_id++;
1175
1176 /* expand ascii string to utf16 */
1177 data = desc->data + 2;
1178 while (len-- > 0) {
1179 *data++ = *str++;
1180 *data++ = 0;
1181 }
1182
1183 udc_descriptor_register(udc, desc);
1184 return desc->tag & 0xff;
1185}
1186
1187
1188static struct udc_descriptor *udc_descriptor_alloc(uint32_t type,
1189 uint32_t num,
1190 uint32_t len,
1191 udc_desc_spec_t spec)
1192{
1193 struct udc_descriptor *desc;
1194 if ((len > 255) || (len < 2) || (num > 255) || (type > 255))
1195 return 0;
1196
1197 if (!(desc = malloc(sizeof(struct udc_descriptor) + len)))
1198 return 0;
1199
1200 desc->next = 0;
1201 desc->tag = (type << 8) | num;
1202 desc->len = len;
1203 desc->spec = spec;
1204
1205 /* descriptor data */
1206 desc->data[0] = len;
1207 desc->data[1] = type;
1208
1209 return desc;
1210}
1211
1212static void udc_descriptor_register(udc_t *udc, struct udc_descriptor *desc)
1213{
1214 desc->next = udc->desc_list;
1215 udc->desc_list = desc;
1216}
1217
1218
Amol Jadi151f2a52013-10-07 12:39:11 -07001219struct udc_request *usb30_udc_request_alloc(void)
Amol Jadif3d5a892013-07-23 16:09:44 -07001220{
1221 struct udc_request *req;
1222
1223 req = malloc(sizeof(*req));
1224 ASSERT(req);
1225
1226 req->buf = 0;
1227 req->length = 0;
1228 req->complete = NULL;
1229 req->context = 0;
1230
1231 return req;
1232}
1233
Amol Jadi151f2a52013-10-07 12:39:11 -07001234void usb30_udc_request_free(struct udc_request *req)
Amol Jadif3d5a892013-07-23 16:09:44 -07001235{
1236 free(req);
1237}
1238
Amol Jadi151f2a52013-10-07 12:39:11 -07001239void usb30_udc_endpoint_free(struct udc_endpoint *ept)
Amol Jadif3d5a892013-07-23 16:09:44 -07001240{
1241 /* TODO */
1242}
1243
Amol Jadi151f2a52013-10-07 12:39:11 -07001244int usb30_udc_stop(void)
Amol Jadif3d5a892013-07-23 16:09:44 -07001245{
1246 dwc_device_run(udc_dev->dwc, 0);
1247
1248 return 0;
1249}