summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c')
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c1489
1 files changed, 1489 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c
new file mode 100644
index 0000000000..4fdf73cb50
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c
@@ -0,0 +1,1489 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2021 by Tomasz Moń
11 * Ported from Sansa Connect TNETV105 UDC Linux driver
12 * Copyright (c) 2005,2006 Zermatt Systems, Inc.
13 * Written by: Ben Bostwick
14 * Linux driver was modeled strongly after the pxa usb driver.
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26#include "config.h"
27#include "system.h"
28#include "kernel.h"
29#include "panic.h"
30#include "logf.h"
31#include "usb.h"
32#include "usb_drv.h"
33#include "usb_core.h"
34#include <string.h>
35#include "tnetv105_usb_drv.h"
36#include "tnetv105_cppi.h"
37
38#ifdef SANSA_CONNECT
39#define SDRAM_SIZE 0x04000000
40
41static void set_tnetv_reset(bool high)
42{
43 if (high)
44 {
45 IO_GIO_BITSET0 = (1 << 7);
46 }
47 else
48 {
49 IO_GIO_BITCLR0 = (1 << 7);
50 }
51}
52
53static bool is_tnetv_reset_high(void)
54{
55 return (IO_GIO_BITSET0 & (1 << 7)) ? true : false;
56}
57#endif
58
59static bool setup_is_set_address;
60
61static cppi_info cppi;
62
63static struct ep_runtime_t
64{
65 int max_packet_size;
66 bool in_allocated;
67 bool out_allocated;
68 uint8_t *rx_buf; /* OUT */
69 int rx_remaining;
70 int rx_size;
71 uint8_t *tx_buf; /* IN */
72 int tx_remaining;
73 int tx_size;
74 volatile bool block; /* flag indicating that transfer is blocking */
75 struct semaphore complete; /* semaphore for blocking transfers */
76}
77ep_runtime[USB_NUM_ENDPOINTS];
78
79static const struct
80{
81 int type;
82 int hs_max_packet_size;
83 /* Not sure what xyoff[1] is for. Presumably it is double buffer, but how
84 * the double buffering works is not so clear from the Sansa Connect Linux
85 * kernel patch. As TNETV105 datasheet is not available, the values are
86 * simply taken from the Linux patch as potential constraints are unknown.
87 *
88 * Linux kernel has 9 endpoints:
89 * * 0: ep0
90 * * 1: ep1in-bulk
91 * * 2: ep2out-bulk
92 * * 3: ep3in-int
93 * * 4: ep4in-int
94 * * 5: ep1out-bulk
95 * * 6: ep2in-bulk
96 * * 7: ep3out-int
97 * * 8: ep4out-int
98 */
99 uint16_t xyoff_in[2];
100 uint16_t xyoff_out[2];
101}
102ep_const_data[USB_NUM_ENDPOINTS] =
103{
104 {
105 .type = USB_ENDPOINT_XFER_CONTROL,
106 .hs_max_packet_size = EP0_MAX_PACKET_SIZE,
107 /* Do not set xyoff as it likely does not apply here.
108 * Linux simply hardcodes the offsets when needed.
109 */
110 },
111 {
112 .type = USB_ENDPOINT_XFER_BULK,
113 .hs_max_packet_size = EP1_MAX_PACKET_SIZE,
114 .xyoff_in = {EP1_XBUFFER_ADDRESS, EP1_YBUFFER_ADDRESS},
115 .xyoff_out = {EP5_XBUFFER_ADDRESS, EP5_YBUFFER_ADDRESS},
116 },
117 {
118 .type = USB_ENDPOINT_XFER_BULK,
119 .hs_max_packet_size = EP2_MAX_PACKET_SIZE,
120 .xyoff_in = {EP6_XBUFFER_ADDRESS, EP6_YBUFFER_ADDRESS},
121 .xyoff_out = {EP2_XBUFFER_ADDRESS, EP2_YBUFFER_ADDRESS},
122 },
123 {
124 .type = USB_ENDPOINT_XFER_INT,
125 .hs_max_packet_size = EP3_MAX_PACKET_SIZE,
126 .xyoff_in = {EP3_XBUFFER_ADDRESS, EP3_YBUFFER_ADDRESS},
127 .xyoff_out = {EP7_XBUFFER_ADDRESS, EP7_YBUFFER_ADDRESS},
128 },
129 {
130 .type = USB_ENDPOINT_XFER_INT,
131 .hs_max_packet_size = EP4_MAX_PACKET_SIZE,
132 .xyoff_in = {EP4_XBUFFER_ADDRESS, EP4_YBUFFER_ADDRESS},
133 .xyoff_out = {EP8_XBUFFER_ADDRESS, EP8_YBUFFER_ADDRESS},
134 },
135};
136
137#define VLYNQ_CTL_RESET_MASK 0x0001
138#define VLYNQ_CTL_CLKDIR_MASK 0x8000
139#define VLYNQ_STS_LINK_MASK 0x0001
140
141#define DM320_VLYNQ_CTRL_RESET (1 << 0)
142#define DM320_VLYNQ_CTRL_LOOP (1 << 1)
143#define DM320_VLYNQ_CTRL_ADR_OPT (1 << 2)
144#define DM320_VLYNQ_CTRL_INT_CFG (1 << 7)
145#define DM320_VLYNQ_CTRL_INT_VEC_MASK (0x00001F00)
146#define DM320_VLYNQ_CTRL_INT_EN (1 << 13)
147#define DM320_VLYNQ_CTRL_INT_LOC (1 << 14)
148#define DM320_VLYNQ_CTRL_CLKDIR (1 << 15)
149#define DM320_VLYNQ_CTRL_CLKDIV_MASK (0x00070000)
150#define DM320_VLYNQ_CTRL_PWR_MAN (1 << 31)
151
152#define DM320_VLYNQ_STAT_LINK (1 << 0)
153#define DM320_VLYNQ_STAT_MST_PEND (1 << 1)
154#define DM320_VLYNQ_STAT_SLV_PEND (1 << 2)
155#define DM320_VLYNQ_STAT_F0_NE (1 << 3)
156#define DM320_VLYNQ_STAT_F1_NE (1 << 4)
157#define DM320_VLYNQ_STAT_F2_NE (1 << 5)
158#define DM320_VLYNQ_STAT_F3_NE (1 << 6)
159#define DM320_VLYNQ_STAT_LOC_ERR (1 << 7)
160#define DM320_VLYNQ_STAT_REM_ERR (1 << 8)
161#define DM320_VLYNQ_STAT_FC_OUT (1 << 9)
162#define DM320_VLYNQ_STAT_FC_IN (1 << 10)
163
164#define MAX_PACKET(epn, speed) ((((speed) == USB_SPEED_HIGH) && (((epn) == 1) || ((epn) == 2))) ? USB_HIGH_SPEED_MAXPACKET : USB_FULL_SPEED_MAXPACKET)
165
166#define VLYNQ_INTR_USB20 (1 << 0)
167#define VLYNQ_INTR_CPPI (1 << 1)
168
169static inline void set_vlynq_clock(bool enable)
170{
171 if (enable)
172 {
173 IO_CLK_MOD2 |= (1 << 13);
174 }
175 else
176 {
177 IO_CLK_MOD2 &= ~(1 << 13);
178 }
179}
180
181static inline void set_vlynq_irq(bool enabled)
182{
183 if (enabled)
184 {
185 /* Enable VLYNQ interrupt */
186 IO_INTC_EINT1 |= (1 << 0);
187 }
188 else
189 {
190 IO_INTC_EINT1 &= ~(1 << 0);
191 }
192}
193
194static int tnetv_hw_reset(void)
195{
196 int timeout;
197
198 /* hold down the reset pin on the USB chip */
199 set_tnetv_reset(false);
200
201 /* Turn on VLYNQ clock. */
202 set_vlynq_clock(true);
203
204 /* now reset the VLYNQ module */
205 VL_CTRL |= (VLYNQ_CTL_CLKDIR_MASK | DM320_VLYNQ_CTRL_PWR_MAN);
206 VL_CTRL |= VLYNQ_CTL_RESET_MASK;
207
208 mdelay(10);
209
210 /* pull up the reset pin */
211 set_tnetv_reset(true);
212
213 /* take the VLYNQ out of reset */
214 VL_CTRL &= ~VLYNQ_CTL_RESET_MASK;
215
216 timeout = 0;
217 while (!(VL_STAT & VLYNQ_STS_LINK_MASK) && timeout++ < 50);
218 {
219 mdelay(40);
220 }
221
222 if (!(VL_STAT & VLYNQ_STS_LINK_MASK))
223 {
224 logf("ERROR: VLYNQ not initialized!\n");
225 return -1;
226 }
227
228 /* set up vlynq local map */
229 VL_TXMAP = DM320_VLYNQ_PADDR;
230 VL_RXMAPOF1 = CONFIG_SDRAM_START;
231 VL_RXMAPSZ1 = SDRAM_SIZE;
232
233 /* set up vlynq remote map for tnetv105 */
234 VL_TXMAP_R = 0x00000000;
235 VL_RXMAPOF1_R = 0x0C000000;
236 VL_RXMAPSZ1_R = 0x00030000;
237
238 /* clear TNETV gpio state */
239 tnetv_usb_reg_write(TNETV_V2USB_GPIO_FS, 0);
240
241 /* set USB_CHARGE_EN pin (gpio 1) - output, disable pullup */
242 tnetv_usb_reg_write(TNETV_V2USB_GPIO_DOUT, 0);
243 tnetv_usb_reg_write(TNETV_V2USB_GPIO_DIR, 0xffff);
244
245 return 0;
246}
247
248static int tnetv_xcvr_on(void)
249{
250 return tnetv_hw_reset();
251}
252
253static void tnetv_xcvr_off(void)
254{
255 /* turn off vlynq module clock */
256 set_vlynq_clock(false);
257
258 /* hold down the reset pin on the USB chip */
259 set_tnetv_reset(false);
260}
261
262/* Copy data from the usb data memory. The memory reads should be done 32 bits at a time.
263 * We do not assume that the dst data is aligned.
264 */
265static void tnetv_copy_from_data_mem(void *dst, const volatile uint32_t *sp, int size)
266{
267 uint8_t *dp = (uint8_t *) dst;
268 uint32_t value;
269
270 while (size >= 4)
271 {
272 value = *sp++;
273 dp[0] = value;
274 dp[1] = value >> 8;
275 dp[2] = value >> 16;
276 dp[3] = value >> 24;
277 dp += 4;
278 size -= 4;
279 }
280
281 if (size)
282 {
283 value = sp[0];
284 switch (size)
285 {
286 case 3:
287 dp[2] = value >> 16;
288 case 2:
289 dp[1] = value >> 8;
290 case 1:
291 dp[0] = value;
292 break;
293 }
294 }
295}
296
297/* Copy data into the usb data memory. The memory writes must be done 32 bits at a time.
298 * We do not assume that the src data is aligned.
299*/
300static void tnetv_copy_to_data_mem(volatile uint32_t *dp, const void *src, int size)
301{
302 const uint8_t *sp = (const uint8_t *) src;
303 uint32_t value;
304
305 while (size >= 4)
306 {
307 value = sp[0] | (sp[1] << 8) | (sp[2] << 16) | (sp[3] << 24);
308 *dp++ = value;
309 sp += 4;
310 size -= 4;
311 }
312
313 switch (size)
314 {
315 case 3:
316 value = sp[0] | (sp[1] << 8) | (sp[2] << 16);
317 *dp = value;
318 break;
319 case 2:
320 value = sp[0] | (sp[1] << 8);
321 *dp = value;
322 break;
323 case 1:
324 value = sp[0];
325 *dp = value;
326 break;
327 }
328}
329
330static void tnetv_init_endpoints(void)
331{
332 UsbEp0CtrlType ep0Cfg;
333 UsbEp0ByteCntType ep0Cnt;
334 UsbEpCfgCtrlType epCfg;
335 UsbEpStartAddrType epStartAddr;
336 int ch, wd, epn;
337
338 ep0Cnt.val = 0;
339 ep0Cnt.f.out_ybuf_nak = 1;
340 ep0Cnt.f.out_xbuf_nak = 1;
341 ep0Cnt.f.in_ybuf_nak = 1;
342 ep0Cnt.f.in_xbuf_nak = 1;
343 tnetv_usb_reg_write(TNETV_USB_EP0_CNT, ep0Cnt.val);
344
345 /* Setup endpoint zero */
346 ep0Cfg.val = 0;
347 ep0Cfg.f.buf_size = EP0_BUF_SIZE_64; /* must be 64 bytes for USB 2.0 */
348 ep0Cfg.f.dbl_buf = 0;
349 ep0Cfg.f.in_en = 1;
350 ep0Cfg.f.in_int_en = 1;
351 ep0Cfg.f.out_en = 1;
352 ep0Cfg.f.out_int_en = 1;
353 tnetv_usb_reg_write(TNETV_USB_EP0_CFG, ep0Cfg.val);
354
355 /* disable cell dma */
356 tnetv_usb_reg_write(TNETV_USB_CELL_DMA_EN, 0);
357
358 /* turn off dma engines */
359 tnetv_usb_reg_write(TNETV_USB_TX_CTL, 0);
360 tnetv_usb_reg_write(TNETV_USB_RX_CTL, 0);
361
362 /* clear out DMA registers */
363 for (ch = 0; ch < TNETV_DMA_NUM_CHANNELS; ch++)
364 {
365 for (wd = 0; wd < TNETV_DMA_TX_NUM_WORDS; wd++)
366 {
367 tnetv_usb_reg_write(TNETV_DMA_TX_STATE(ch, wd), 0);
368 }
369
370 for (wd = 0; wd < TNETV_DMA_RX_NUM_WORDS; wd++)
371 {
372 tnetv_usb_reg_write(TNETV_DMA_RX_STATE(ch, wd), 0);
373 }
374
375 /* flush the free buf count */
376 while (tnetv_usb_reg_read(TNETV_USB_RX_FREE_BUF_CNT(ch)) != 0)
377 {
378 tnetv_usb_reg_write(TNETV_USB_RX_FREE_BUF_CNT(ch), 0xFFFF);
379 }
380 }
381
382 for (epn = 1; epn < USB_NUM_ENDPOINTS; epn++)
383 {
384 tnetv_usb_reg_write(TNETV_USB_EPx_ADR(epn),0);
385 tnetv_usb_reg_write(TNETV_USB_EPx_CFG(epn), 0);
386 tnetv_usb_reg_write(TNETV_USB_EPx_IN_CNT(epn), 0x80008000);
387 tnetv_usb_reg_write(TNETV_USB_EPx_OUT_CNT(epn), 0x80008000);
388 }
389
390 /* Setup the other endpoints */
391 for (epn = 1; epn < USB_NUM_ENDPOINTS; epn++)
392 {
393 epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn));
394 epStartAddr.val = tnetv_usb_reg_read(TNETV_USB_EPx_ADR(epn));
395
396 epCfg.f.in_dbl_buf = 1;
397 epCfg.f.in_toggle_rst = 1;
398 epCfg.f.in_ack_int = 0;
399 epCfg.f.in_stall = 0;
400 epCfg.f.in_nak_int = 0;
401 epCfg.f.out_dbl_buf = 1;
402 epCfg.f.out_toggle_rst = 1;
403 epCfg.f.out_ack_int = 0;
404 epCfg.f.out_stall = 0;
405 epCfg.f.out_nak_int = 0;
406
407 /* buf_size is specified "in increments of 8 bytes" */
408 epCfg.f.in_buf_size = ep_const_data[epn].hs_max_packet_size >> 3;
409 epCfg.f.out_buf_size = ep_const_data[epn].hs_max_packet_size >> 3;
410
411 epStartAddr.f.xBuffStartAddrIn = ep_const_data[epn].xyoff_in[0] >> 4;
412 epStartAddr.f.yBuffStartAddrIn = ep_const_data[epn].xyoff_in[1] >> 4;
413 epStartAddr.f.xBuffStartAddrOut = ep_const_data[epn].xyoff_out[0] >> 4;
414 epStartAddr.f.yBuffStartAddrOut = ep_const_data[epn].xyoff_out[1] >> 4;
415
416 /* allocate memory for DMA */
417 tnetv_cppi_init_rcb(&cppi, (epn - 1));
418 /* set up DMA queue */
419 tnetv_cppi_init_tcb(&cppi, (epn - 1));
420
421 /* now write out the config to the TNETV (write enable bits last) */
422 tnetv_usb_reg_write(TNETV_USB_EPx_ADR(epn), epStartAddr.val);
423 tnetv_usb_reg_write(TNETV_USB_EPx_CFG(epn), epCfg.val);
424 tnetv_usb_reg_write(TNETV_USB_EPx_IN_CNT(epn), 0x80008000);
425 tnetv_usb_reg_write(TNETV_USB_EPx_OUT_CNT(epn), 0x80008000);
426 }
427
428 /* turn on dma engines */
429 tnetv_usb_reg_write(TNETV_USB_TX_CTL, 1);
430 tnetv_usb_reg_write(TNETV_USB_RX_CTL, 1);
431
432 /* enable cell dma */
433 tnetv_usb_reg_write(TNETV_USB_CELL_DMA_EN, (TNETV_USB_CELL_DMA_EN_RX | TNETV_USB_CELL_DMA_EN_TX));
434}
435
436static void tnetv_udc_enable_interrupts(void)
437{
438 UsbCtrlType usb_ctl;
439 uint8_t tx_int_en, rx_int_en;
440 int ep, chan;
441
442 /* set up the system interrupts */
443 usb_ctl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
444 usb_ctl.f.vbus_int_en = 1;
445 usb_ctl.f.reset_int_en = 1;
446 usb_ctl.f.suspend_int_en = 1;
447 usb_ctl.f.resume_int_en = 1;
448 usb_ctl.f.ep0_in_int_en = 1;
449 usb_ctl.f.ep0_out_int_en = 1;
450 usb_ctl.f.setup_int_en = 1;
451 usb_ctl.f.setupow_int_en = 1;
452 tnetv_usb_reg_write(TNETV_USB_CTRL, usb_ctl.val);
453
454 /* Enable the DMA endpoint interrupts */
455 tx_int_en = 0;
456 rx_int_en = 0;
457
458 for (ep = 1; ep < USB_NUM_ENDPOINTS; ep++)
459 {
460 chan = ep - 1;
461 rx_int_en |= (1 << chan); /* OUT */
462 tx_int_en |= (1 << chan); /* IN */
463 }
464
465 /* enable rx interrupts */
466 tnetv_usb_reg_write(TNETV_USB_RX_INT_EN, rx_int_en);
467 /* enable tx interrupts */
468 tnetv_usb_reg_write(TNETV_USB_TX_INT_EN, tx_int_en);
469
470 set_vlynq_irq(true);
471}
472
473static void tnetv_udc_disable_interrupts(void)
474{
475 UsbCtrlType usb_ctl;
476
477 /* disable interrupts from linux */
478 set_vlynq_irq(false);
479
480 /* Disable Endpoint Interrupts */
481 tnetv_usb_reg_write(TNETV_USB_RX_INT_DIS, 0x3);
482 tnetv_usb_reg_write(TNETV_USB_TX_INT_DIS, 0x3);
483
484 /* Disable USB system interrupts */
485 usb_ctl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
486 usb_ctl.f.vbus_int_en = 0;
487 usb_ctl.f.reset_int_en = 0;
488 usb_ctl.f.suspend_int_en = 0;
489 usb_ctl.f.resume_int_en = 0;
490 usb_ctl.f.ep0_in_int_en = 0;
491 usb_ctl.f.ep0_out_int_en = 0;
492 usb_ctl.f.setup_int_en = 0;
493 usb_ctl.f.setupow_int_en = 0;
494 tnetv_usb_reg_write(TNETV_USB_CTRL, usb_ctl.val);
495}
496
497static void tnetv_ep_halt(int epn, bool in)
498{
499 if (in)
500 {
501 tnetv_usb_reg_write(TNETV_USB_EPx_IN_CNT(epn), 0x80008000);
502 }
503 else
504 {
505 tnetv_usb_reg_write(TNETV_USB_EPx_OUT_CNT(epn), 0x80008000);
506 }
507}
508
509/* Reset the TNETV usb2.0 controller and configure it to run in function mode */
510static void tnetv_usb_reset(void)
511{
512 uint32_t timeout = 0;
513 int wd;
514 int ch;
515
516 /* configure function clock */
517 tnetv_usb_reg_write(TNETV_V2USB_CLK_CFG, 0x80);
518
519 /* Reset the USB 2.0 function module */
520 tnetv_usb_reg_write(TNETV_V2USB_RESET, 0x01);
521
522 /* now poll the module ready register until the 2.0 controller finishes resetting */
523 while (!(tnetv_usb_reg_read(TNETV_USB_RESET_CMPL) & 0x1) && (timeout < 1000000))
524 {
525 timeout++;
526 }
527
528 if (!(tnetv_usb_reg_read(TNETV_USB_RESET_CMPL) & 0x1))
529 {
530 logf("tnetv105_udc: VLYNQ USB module reset failed!\n");
531 return;
532 }
533
534 /* turn off external clock */
535 tnetv_usb_reg_write(TNETV_V2USB_CLK_PERF, 0);
536
537 /* clear out USB data memory */
538 for (wd = 0; wd < TNETV_EP_DATA_SIZE; wd += 4)
539 {
540 tnetv_usb_reg_write(TNETV_EP_DATA_ADDR(wd), 0);
541 }
542
543 /* clear out DMA memory */
544 for (ch = 0; ch < TNETV_DMA_NUM_CHANNELS; ch++)
545 {
546 for (wd = 0; wd < TNETV_DMA_TX_NUM_WORDS; wd++)
547 {
548 tnetv_usb_reg_write(TNETV_DMA_TX_STATE(ch, wd), 0);
549 }
550
551 for (wd = 0; wd < TNETV_DMA_RX_NUM_WORDS; wd++)
552 {
553
554 tnetv_usb_reg_write(TNETV_DMA_RX_STATE(ch, wd), 0);
555 }
556 }
557
558 /* point VLYNQ interrupts at the pending register */
559 VL_INTPTR = DM320_VLYNQ_INTPND_PHY;
560
561 /* point VLYNQ remote interrupts at the pending register */
562 VL_INTPTR_R = 0;
563
564 /* clear out interrupt register */
565 VL_INTST |= 0xFFFFFFFF;
566
567 /* enable interrupts on remote device */
568 VL_CTRL_R |= (DM320_VLYNQ_CTRL_INT_EN);
569 VL_INTVEC30_R = 0x8180;
570
571 /* enable VLYNQ interrupts & set interrupts to trigger VLYNQ int */
572 VL_CTRL |= (DM320_VLYNQ_CTRL_INT_LOC | DM320_VLYNQ_CTRL_INT_CFG);
573}
574
575static int tnetv_ep_start_xmit(int epn, void *buf, int size)
576{
577 UsbEp0ByteCntType ep0Cnt;
578
579 if (epn == 0)
580 {
581 /* Write the Control Data packet to the EP0 IN memory area */
582 tnetv_copy_to_data_mem(TNETV_EP_DATA_ADDR(EP0_INPKT_ADDRESS), buf, size);
583
584 /* start xmitting */
585 ep0Cnt.val = tnetv_usb_reg_read(TNETV_USB_EP0_CNT);
586 ep0Cnt.f.in_xbuf_cnt = size;
587 ep0Cnt.f.in_xbuf_nak = 0;
588 tnetv_usb_reg_write(TNETV_USB_EP0_CNT, ep0Cnt.val);
589 }
590 else
591 {
592 dma_addr_t buffer = (dma_addr_t)buf;
593 commit_discard_dcache_range(buf, size);
594 if ((buffer >= CONFIG_SDRAM_START) && (buffer <= CONFIG_SDRAM_START + SDRAM_SIZE))
595 {
596 if (tnetv_cppi_send(&cppi, (epn - 1), buffer, size, 0))
597 {
598 panicf("tnetv_cppi_send() failed");
599 }
600 }
601 else
602 {
603 panicf("USB xmit buf outside SDRAM %p", buf);
604 }
605 }
606
607 return 0;
608}
609
610static void tnetv_gadget_req_nuke(int epn, bool in)
611{
612 struct ep_runtime_t *ep = &ep_runtime[epn];
613 uint32_t old_rx_int = 0;
614 uint32_t old_tx_int = 0;
615 int ch;
616 int flags;
617
618 /* don't nuke control ep */
619 if (epn == 0)
620 {
621 return;
622 }
623
624 flags = disable_irq_save();
625
626 /* save and disable interrupts before nuking request */
627 old_rx_int = tnetv_usb_reg_read(TNETV_USB_RX_INT_EN);
628 old_tx_int = tnetv_usb_reg_read(TNETV_USB_TX_INT_EN);
629 tnetv_usb_reg_write(TNETV_USB_RX_INT_DIS, 0x3);
630 tnetv_usb_reg_write(TNETV_USB_TX_INT_DIS, 0x3);
631
632 ch = epn - 1;
633
634 if (in)
635 {
636 tnetv_cppi_flush_tx_queue(&cppi, ch);
637
638 tnetv_usb_reg_write(TNETV_USB_EPx_IN_CNT(epn), 0x80008000);
639 if (ep->tx_remaining > 0)
640 {
641 usb_core_transfer_complete(epn, USB_DIR_IN, -1, 0);
642 }
643 ep->tx_buf = NULL;
644 ep->tx_remaining = 0;
645 ep->tx_size = 0;
646
647 if (ep->block)
648 {
649 semaphore_release(&ep->complete);
650 ep->block = false;
651 }
652 }
653 else
654 {
655 tnetv_cppi_flush_rx_queue(&cppi, ch);
656
657 tnetv_usb_reg_write(TNETV_USB_EPx_OUT_CNT(epn), 0x80008000);
658 if (ep->rx_remaining > 0)
659 {
660 usb_core_transfer_complete(epn, USB_DIR_OUT, -1, 0);
661 }
662 ep->rx_buf = NULL;
663 ep->rx_remaining = 0;
664 ep->rx_size = 0;
665 }
666
667 /* reenable any interrupts */
668 tnetv_usb_reg_write(TNETV_USB_RX_INT_EN, old_rx_int);
669 tnetv_usb_reg_write(TNETV_USB_TX_INT_EN, old_tx_int);
670
671 restore_irq(flags);
672}
673
674static int tnetv_gadget_ep_enable(int epn, bool in)
675{
676 UsbEpCfgCtrlType epCfg;
677 int flags;
678
679 if (epn == 0 || epn >= USB_NUM_ENDPOINTS)
680 {
681 return 0;
682 }
683
684 flags = disable_irq_save();
685
686 /* set the maxpacket for this endpoint based on the current speed */
687 ep_runtime[epn].max_packet_size = MAX_PACKET(epn, usb_drv_port_speed());
688
689 /* Enable the endpoint */
690 epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn));
691 if (in)
692 {
693 epCfg.f.in_en = 1;
694 epCfg.f.in_stall = 0;
695 epCfg.f.in_toggle_rst = 1;
696 epCfg.f.in_buf_size = ep_runtime[epn].max_packet_size >> 3;
697 tnetv_usb_reg_write(TNETV_USB_EPx_IN_CNT(epn), 0x80008000);
698 }
699 else
700 {
701 epCfg.f.out_en = 1;
702 epCfg.f.out_stall = 0;
703 epCfg.f.out_toggle_rst = 1;
704 epCfg.f.out_buf_size = ep_runtime[epn].max_packet_size >> 3;
705 tnetv_usb_reg_write(TNETV_USB_EPx_OUT_CNT(epn), 0x80008000);
706 }
707 tnetv_usb_reg_write(TNETV_USB_EPx_CFG(epn), epCfg.val);
708
709 restore_irq(flags);
710
711 return 0;
712}
713
714static int tnetv_gadget_ep_disable(int epn, bool in)
715{
716 UsbEpCfgCtrlType epCfg;
717 int flags;
718
719 if (epn == 0 || epn >= USB_NUM_ENDPOINTS)
720 {
721 return 0;
722 }
723
724 flags = disable_irq_save();
725
726 /* Disable the endpoint */
727 epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn));
728 if (in)
729 {
730 epCfg.f.in_en = 0;
731 }
732 else
733 {
734 epCfg.f.out_en = 0;
735 }
736 tnetv_usb_reg_write(TNETV_USB_EPx_CFG(epn), epCfg.val);
737
738 /* Turn off the endpoint and unready it */
739 tnetv_ep_halt(epn, in);
740
741 restore_irq(flags);
742
743 /* Clear out all the pending requests */
744 tnetv_gadget_req_nuke(epn, in);
745
746 return 0;
747}
748
749/* TNETV udc goo
750 * Power up and enable the udc. This includes resetting the hardware, turn on the appropriate clocks
751 * and initializing things so that the first setup packet can be received.
752 */
753static void tnetv_udc_enable(void)
754{
755 /* Enable M48XI crystal resonator */
756 IO_CLK_LPCTL1 &= ~(0x01);
757
758 /* Set GIO33 as CLKOUT1B */
759 IO_GIO_FSEL3 |= 0x0003;
760
761 if (tnetv_xcvr_on())
762 return;
763
764 tnetv_usb_reset();
765
766 /* BEN - RNDIS mode is assuming zlps after packets that are multiples of buffer endpoints
767 * zlps are not required by the spec and many controllers don't send them.
768 * set DMA to RNDIS mode (packet concatenation, less interrupts)
769 * tnetv_usb_reg_write(TNETV_USB_RNDIS_MODE, 0xFF);
770 */
771 tnetv_usb_reg_write(TNETV_USB_RNDIS_MODE, 0);
772
773 tnetv_init_endpoints();
774
775 tnetv_udc_enable_interrupts();
776}
777
778static void tnetv_udc_disable(void)
779{
780 tnetv_udc_disable_interrupts();
781
782 tnetv_hw_reset();
783
784 tnetv_xcvr_off();
785
786 /* Set GIO33 as normal output, drive it low */
787 IO_GIO_FSEL3 &= ~(0x0003);
788 IO_GIO_BITCLR2 = (1 << 1);
789
790 /* Disable M48XI crystal resonator */
791 IO_CLK_LPCTL1 |= 0x01;
792}
793
794static void tnetv_udc_handle_reset(void)
795{
796 UsbCtrlType usbCtrl;
797
798 /* disable USB interrupts */
799 tnetv_udc_disable_interrupts();
800
801 usbCtrl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
802 usbCtrl.f.func_addr = 0;
803 tnetv_usb_reg_write(TNETV_USB_CTRL, usbCtrl.val);
804
805 /* Reset endpoints */
806 tnetv_init_endpoints();
807
808 /* Re-enable interrupts */
809 tnetv_udc_enable_interrupts();
810}
811
812static void ep_write(int epn)
813{
814 struct ep_runtime_t *ep = &ep_runtime[epn];
815 int tx_size;
816 if (epn == 0)
817 {
818 tx_size = MIN(ep->max_packet_size, ep->tx_remaining);
819 }
820 else
821 {
822 /* DMA takes care of splitting the buffer into packets */
823 tx_size = ep->tx_remaining;
824 }
825 tnetv_ep_start_xmit(epn, ep->tx_buf, tx_size);
826 ep->tx_remaining -= tx_size;
827 ep->tx_buf += tx_size;
828}
829
830static void in_interrupt(int epn)
831{
832 struct ep_runtime_t *ep = &ep_runtime[epn];
833
834 if (ep->tx_remaining <= 0)
835 {
836 usb_core_transfer_complete(epn, USB_DIR_IN, 0, ep->tx_size);
837 /* release semaphore for blocking transfer */
838 if (ep->block)
839 {
840 semaphore_release(&ep->complete);
841 ep->tx_buf = NULL;
842 ep->tx_size = 0;
843 ep->tx_remaining = 0;
844 ep->block = false;
845 }
846 }
847 else if (ep->tx_buf)
848 {
849 ep_write(epn);
850 }
851}
852
853static void ep_read(int epn)
854{
855 if (epn == 0)
856 {
857 UsbEp0ByteCntType ep0Cnt;
858 ep0Cnt.val = tnetv_usb_reg_read(TNETV_USB_EP0_CNT);
859 ep0Cnt.f.out_xbuf_nak = 0;
860 tnetv_usb_reg_write(TNETV_USB_EP0_CNT, ep0Cnt.val);
861 }
862 else
863 {
864 struct ep_runtime_t *ep = &ep_runtime[epn];
865 tnetv_cppi_rx_queue_add(&cppi, (epn - 1), 0, ep->rx_remaining);
866 }
867}
868
869static void out_interrupt(int epn)
870{
871 struct ep_runtime_t *ep = &ep_runtime[epn];
872 int is_short;
873 int rcv_len;
874
875 if (epn == 0)
876 {
877 UsbEp0ByteCntType ep0Cnt;
878
879 /* get the length of the received data */
880 ep0Cnt.val = tnetv_usb_reg_read(TNETV_USB_EP0_CNT);
881 rcv_len = ep0Cnt.f.out_xbuf_cnt;
882
883 if (rcv_len > ep->rx_remaining)
884 {
885 rcv_len = ep->rx_remaining;
886 }
887
888 tnetv_copy_from_data_mem(ep->rx_buf, TNETV_EP_DATA_ADDR(EP0_OUTPKT_ADDRESS), rcv_len);
889 ep->rx_buf += rcv_len;
890 ep->rx_remaining -= rcv_len;
891
892 /* See if we are done */
893 is_short = rcv_len && (rcv_len < ep->max_packet_size);
894 if (is_short || (ep->rx_remaining == 0))
895 {
896 usb_core_transfer_complete(epn, USB_DIR_OUT, 0, ep->rx_size - ep->rx_remaining);
897 ep->rx_remaining = 0;
898 ep->rx_size = 0;
899 ep->rx_buf = 0;
900 return;
901 }
902
903 /* make sure nak is cleared only if we expect more data */
904 ep0Cnt.f.out_xbuf_nak = 0;
905 tnetv_usb_reg_write(TNETV_USB_EP0_CNT, ep0Cnt.val);
906 ep_read(epn);
907 }
908 else if (ep->rx_remaining > 0)
909 {
910 int ret, bytes_rcvd;
911
912 /* copy the data from the DMA buffers */
913 bytes_rcvd = ep->rx_remaining;
914 ret = tnetv_cppi_rx_int_recv(&cppi, (epn - 1), &bytes_rcvd, ep->rx_buf, ep->max_packet_size);
915 if (ret == 0 || ret == -EAGAIN)
916 {
917 ep->rx_buf += bytes_rcvd;
918 ep->rx_remaining -= bytes_rcvd;
919 }
920
921 /* complete the request if we got a short packet or an error
922 * make sure we don't complete a request with zero bytes.
923 */
924 if ((ret == 0) && (ep->rx_remaining != ep->rx_size))
925 {
926 usb_core_transfer_complete(epn, USB_DIR_OUT, 0, ep->rx_size - ep->rx_remaining);
927 ep->rx_remaining = 0;
928 ep->rx_size = 0;
929 ep->rx_buf = 0;
930 }
931 }
932}
933
934static bool tnetv_handle_cppi(void)
935{
936 int ret;
937 int ch;
938 uint32_t tx_intstatus;
939 uint32_t rx_intstatus;
940 uint32_t status;
941 int rcv_sched = 0;
942
943 rx_intstatus = tnetv_usb_reg_read(TNETV_USB_RX_INT_STATUS);
944 tx_intstatus = tnetv_usb_reg_read(TNETV_USB_TX_INT_STATUS);
945
946 /* handle any transmit interrupts */
947 status = tx_intstatus;
948 for (ch = 0; ch < CPPI_NUM_CHANNELS && status; ch++)
949 {
950 if (status & 0x1)
951 {
952 ret = tnetv_cppi_tx_int(&cppi, ch);
953 if (ret >= 0)
954 {
955 in_interrupt(ch + 1);
956 }
957 }
958
959 status = status >> 1;
960 }
961
962 rcv_sched = 0;
963 status = rx_intstatus;
964 for (ch = 0; ch < CPPI_NUM_CHANNELS; ch++)
965 {
966 if (status & 0x1 || tnetv_cppi_rx_int_recv_check(&cppi, ch))
967 {
968 ret = tnetv_cppi_rx_int(&cppi, ch);
969 if (ret < 0)
970 {
971 /* only an error if interrupt bit is set */
972 logf("CPPI Rx: failed to ACK int!\n");
973 }
974 else
975 {
976 if (tnetv_cppi_rx_int_recv_check(&cppi, ch))
977 {
978 out_interrupt(ch + 1);
979 }
980 }
981 }
982
983 if (tnetv_cppi_rx_int_recv_check(&cppi, ch))
984 {
985 rcv_sched = 1;
986 }
987
988 status = status >> 1;
989 }
990
991 rx_intstatus = tnetv_usb_reg_read(TNETV_USB_RX_INT_STATUS);
992 tx_intstatus = tnetv_usb_reg_read(TNETV_USB_TX_INT_STATUS);
993
994 if (rx_intstatus || tx_intstatus || rcv_sched)
995 {
996 /* Request calling again after short delay
997 * Needed when for example when OUT endpoint has pending
998 * data but the USB task did not call usb_drv_recv() yet.
999 */
1000 return true;
1001 }
1002 return false;
1003}
1004
1005static int cppi_timeout_cb(struct timeout *tmo)
1006{
1007 (void)tmo;
1008 int flags = disable_irq_save();
1009 bool requeue = tnetv_handle_cppi();
1010 restore_irq(flags);
1011 return requeue ? HZ/10 : 0;
1012}
1013
1014void VLYNQ(void) __attribute__ ((section(".icode")));
1015void VLYNQ(void)
1016{
1017 UsbStatusType sysIntrStatus;
1018 UsbStatusType sysIntClear;
1019 UsbCtrlType usbCtrl;
1020 volatile uint32_t *reg;
1021 uint32_t vlynq_intr;
1022
1023 /* Clear interrupt */
1024 IO_INTC_IRQ1 = (1 << 0);
1025
1026 /* clear out VLYNQ interrupt register */
1027 vlynq_intr = VL_INTST;
1028
1029 if (vlynq_intr & VLYNQ_INTR_USB20)
1030 {
1031 VL_INTST = VLYNQ_INTR_USB20;
1032
1033 /* Examine system interrupt status */
1034 sysIntrStatus.val = tnetv_usb_reg_read(TNETV_USB_STATUS);
1035
1036 if (sysIntrStatus.f.reset)
1037 {
1038 sysIntClear.val = 0;
1039 sysIntClear.f.reset = 1;
1040 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1041
1042 tnetv_udc_handle_reset();
1043 usb_core_bus_reset();
1044 }
1045
1046 if (sysIntrStatus.f.suspend)
1047 {
1048 sysIntClear.val = 0;
1049 sysIntClear.f.suspend = 1;
1050 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1051 }
1052
1053 if (sysIntrStatus.f.resume)
1054 {
1055 sysIntClear.val = 0;
1056 sysIntClear.f.resume = 1;
1057 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1058 }
1059
1060 if (sysIntrStatus.f.vbus)
1061 {
1062 sysIntClear.val = 0;
1063 sysIntClear.f.vbus = 1;
1064 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1065
1066 if (*((uint32_t *) TNETV_USB_IF_STATUS) & 0x40)
1067 {
1068 /* write out connect bit */
1069 reg = (volatile uint32_t *) TNETV_USB_CTRL;
1070 *reg |= 0x80;
1071
1072 /* write to wakeup bit in clock config */
1073 reg = (volatile uint32_t *) TNETV_V2USB_CLK_WKUP;
1074 *reg |= TNETV_V2USB_CLK_WKUP_VBUS;
1075 }
1076 else
1077 {
1078 /* clear out connect bit */
1079 reg = (volatile uint32_t *) TNETV_USB_CTRL;
1080 *reg &= ~0x80;
1081 }
1082 }
1083
1084 if (sysIntrStatus.f.setup_ow)
1085 {
1086 sysIntrStatus.f.setup_ow = 0;
1087 sysIntClear.val = 0;
1088 sysIntClear.f.setup_ow = 1;
1089 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1090 }
1091 if (sysIntrStatus.f.setup)
1092 {
1093 UsbEp0ByteCntType ep0Cnt;
1094 static struct usb_ctrlrequest setup;
1095
1096 sysIntrStatus.f.setup = 0;
1097
1098 /* Copy setup packet into buffer */
1099 tnetv_copy_from_data_mem(&setup, TNETV_EP_DATA_ADDR(EP0_OUTPKT_ADDRESS), sizeof(setup));
1100
1101 /* Determine next stage of the control message */
1102 if (setup.bRequestType & USB_DIR_IN)
1103 {
1104 /* This is a control-read. Switch directions to send the response.
1105 * set the dir bit before clearing the interrupt
1106 */
1107 usbCtrl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
1108 usbCtrl.f.dir = 1;
1109 tnetv_usb_reg_write(TNETV_USB_CTRL, usbCtrl.val);
1110 }
1111 else
1112 {
1113 /* This is a control-write. Remain using USB_DIR_OUT to receive the rest of the data.
1114 * set the NAK bits according to supplement doc
1115 */
1116 ep0Cnt.val = 0;
1117 ep0Cnt.f.in_xbuf_nak = 1;
1118 ep0Cnt.f.out_xbuf_nak = 1;
1119 tnetv_usb_reg_write(TNETV_USB_EP0_CNT, ep0Cnt.val);
1120
1121 /* clear the dir bit before clearing the interrupt */
1122 usbCtrl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
1123 usbCtrl.f.dir = 0;
1124 tnetv_usb_reg_write(TNETV_USB_CTRL, usbCtrl.val);
1125 }
1126
1127 /* Clear interrupt */
1128 sysIntClear.val = 0;
1129 sysIntClear.f.setup = 1;
1130 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1131
1132 if (((setup.bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) &&
1133 (setup.bRequest == USB_REQ_SET_ADDRESS))
1134 {
1135 /* Rockbox USB core works according to USB specification, i.e.
1136 * it first acknowledges the control transfer and then sets
1137 * the address. However, Linux TNETV105 driver first sets the
1138 * address and then acknowledges the transfer. At first,
1139 * it seemed that Linux driver was wrong, but it seems that
1140 * TNETV105 simply requires such order. It might be documented
1141 * in the datasheet and thus there is no comment in the Linux
1142 * driver about this.
1143 */
1144 setup_is_set_address = true;
1145 }
1146 else
1147 {
1148 setup_is_set_address = false;
1149 }
1150
1151 /* Process control packet */
1152 usb_core_control_request(&setup);
1153 }
1154
1155 if (sysIntrStatus.f.ep0_in_ack)
1156 {
1157 sysIntClear.val = 0;
1158 sysIntClear.f.ep0_in_ack = 1;
1159 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1160
1161 in_interrupt(0);
1162 }
1163
1164 if (sysIntrStatus.f.ep0_out_ack)
1165 {
1166 sysIntClear.val = 0;
1167 sysIntClear.f.ep0_out_ack = 1;
1168 tnetv_usb_reg_write(TNETV_USB_STATUS, sysIntClear.val);
1169
1170 out_interrupt(0);
1171 }
1172 }
1173
1174 if (vlynq_intr & VLYNQ_INTR_CPPI)
1175 {
1176 static struct timeout cppi_timeout;
1177
1178 VL_INTST = VLYNQ_INTR_CPPI;
1179
1180 if (tnetv_handle_cppi())
1181 {
1182 timeout_register(&cppi_timeout, cppi_timeout_cb, HZ/10, 0);
1183 }
1184 }
1185}
1186
1187void usb_charging_maxcurrent_change(int maxcurrent)
1188{
1189 uint32_t wreg;
1190
1191 if (!is_tnetv_reset_high())
1192 {
1193 /* TNETV105 is in reset, it is not getting more than 100 mA */
1194 return;
1195 }
1196
1197 wreg = tnetv_usb_reg_read(TNETV_V2USB_GPIO_DOUT);
1198 if (maxcurrent < 500)
1199 {
1200 /* set tnetv into low power mode */
1201 tnetv_usb_reg_write(TNETV_V2USB_GPIO_DOUT, (wreg & ~0x2));
1202 }
1203 else
1204 {
1205 /* set tnetv into high power mode */
1206 tnetv_usb_reg_write(TNETV_V2USB_GPIO_DOUT, (wreg | 0x2));
1207 }
1208}
1209
1210void usb_drv_init(void)
1211{
1212 int epn;
1213 memset(ep_runtime, 0, sizeof(ep_runtime));
1214 ep_runtime[0].max_packet_size = EP0_MAX_PACKET_SIZE;
1215 ep_runtime[0].in_allocated = true;
1216 ep_runtime[0].out_allocated = true;
1217 for (epn = 0; epn < USB_NUM_ENDPOINTS; epn++)
1218 {
1219 semaphore_init(&ep_runtime[epn].complete, 1, 0);
1220 }
1221 tnetv_cppi_init(&cppi);
1222 tnetv_udc_enable();
1223}
1224
1225void usb_drv_exit(void)
1226{
1227 tnetv_udc_disable();
1228 tnetv_cppi_cleanup(&cppi);
1229}
1230
1231void usb_drv_stall(int endpoint, bool stall, bool in)
1232{
1233 int epn = EP_NUM(endpoint);
1234
1235 if (epn == 0)
1236 {
1237 UsbEp0CtrlType ep0Ctrl;
1238 ep0Ctrl.val = tnetv_usb_reg_read(TNETV_USB_EP0_CFG);
1239 if (in)
1240 {
1241 ep0Ctrl.f.in_stall = stall ? 1 : 0;
1242 }
1243 else
1244 {
1245 ep0Ctrl.f.out_stall = stall ? 1 : 0;
1246 }
1247 tnetv_usb_reg_write(TNETV_USB_EP0_CFG, ep0Ctrl.val);
1248 }
1249 else
1250 {
1251 UsbEpCfgCtrlType epCfg;
1252 epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn));
1253 if (in)
1254 {
1255 epCfg.f.in_stall = stall ? 1 : 0;
1256 }
1257 else
1258 {
1259 epCfg.f.out_stall = stall ? 1 : 0;
1260 }
1261 tnetv_usb_reg_write(TNETV_USB_EPx_CFG(epn), epCfg.val);
1262 }
1263}
1264
1265bool usb_drv_stalled(int endpoint, bool in)
1266{
1267 int epn = EP_NUM(endpoint);
1268 if (epn == 0)
1269 {
1270 UsbEp0CtrlType ep0Ctrl;
1271 ep0Ctrl.val = tnetv_usb_reg_read(TNETV_USB_EP0_CFG);
1272 if (in)
1273 {
1274 return ep0Ctrl.f.in_stall;
1275 }
1276 else
1277 {
1278 return ep0Ctrl.f.out_stall;
1279 }
1280 }
1281 else
1282 {
1283 UsbEpCfgCtrlType epCfg;
1284 epCfg.val = tnetv_usb_reg_read(TNETV_USB_EPx_CFG(epn));
1285 if (in)
1286 {
1287 return epCfg.f.in_stall;
1288 }
1289 else
1290 {
1291 return epCfg.f.out_stall;
1292 }
1293 }
1294}
1295
1296static int _usb_drv_send(int endpoint, void *ptr, int length, bool block)
1297{
1298 int epn = EP_NUM(endpoint);
1299 struct ep_runtime_t *ep;
1300 int flags;
1301
1302 ep = &ep_runtime[epn];
1303
1304 flags = disable_irq_save();
1305 ep->tx_buf = ptr;
1306 ep->tx_remaining = ep->tx_size = length;
1307 ep->block = block;
1308 ep_write(epn);
1309 restore_irq(flags);
1310
1311 /* wait for transfer to end */
1312 if (block)
1313 {
1314 semaphore_wait(&ep->complete, TIMEOUT_BLOCK);
1315 }
1316 return 0;
1317}
1318
1319int usb_drv_send(int endpoint, void* ptr, int length)
1320{
1321 if ((EP_NUM(endpoint) == 0) && (length == 0))
1322 {
1323 if (setup_is_set_address)
1324 {
1325 /* usb_drv_set_address() will call us later */
1326 return 0;
1327 }
1328 /* HACK: Do not wait for status stage ZLP
1329 * This seems to be the only way to get through SET ADDRESS
1330 * and retain ability to receive SETUP packets.
1331 */
1332 return _usb_drv_send(endpoint, ptr, length, false);
1333 }
1334 return _usb_drv_send(endpoint, ptr, length, false);
1335}
1336
1337int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
1338{
1339 return _usb_drv_send(endpoint, ptr, length, false);
1340}
1341
1342int usb_drv_recv(int endpoint, void* ptr, int length)
1343{
1344 int epn = EP_NUM(endpoint);
1345 struct ep_runtime_t *ep;
1346 int flags;
1347
1348 ep = &ep_runtime[epn];
1349
1350 flags = disable_irq_save();
1351 ep->rx_buf = ptr;
1352 ep->rx_remaining = ep->rx_size = length;
1353 ep_read(epn);
1354 restore_irq(flags);
1355
1356 return 0;
1357}
1358
1359void usb_drv_ack(struct usb_ctrlrequest* req);
1360
1361void usb_drv_set_address(int address)
1362{
1363 UsbCtrlType usbCtrl;
1364 usbCtrl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
1365 usbCtrl.f.func_addr = address;
1366 tnetv_usb_reg_write(TNETV_USB_CTRL, usbCtrl.val);
1367
1368 /* This seems to be the only working order */
1369 setup_is_set_address = false;
1370 usb_drv_send(EP_CONTROL, NULL, 0);
1371 usb_drv_cancel_all_transfers();
1372}
1373
1374/* return port speed FS=0, HS=1 */
1375int usb_drv_port_speed(void)
1376{
1377 UsbCtrlType usbCtrl;
1378 usbCtrl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
1379 return usbCtrl.f.speed ? 1 : 0;
1380}
1381
1382void usb_drv_cancel_all_transfers(void)
1383{
1384 int epn;
1385 if (setup_is_set_address)
1386 {
1387 return;
1388 }
1389 for (epn = 1; epn < USB_NUM_ENDPOINTS; epn++)
1390 {
1391 tnetv_gadget_req_nuke(epn, false);
1392 tnetv_gadget_req_nuke(epn, true);
1393 }
1394}
1395
1396static const uint8_t TestPacket[] =
1397{
1398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1399 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
1400 0xAA, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
1401 0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1402 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xDF,
1403 0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF,
1404 0xEF, 0xF7, 0xFB, 0xFD, 0x7E
1405};
1406
1407void usb_drv_set_test_mode(int mode)
1408{
1409 UsbCtrlType usbCtrl;
1410 if (mode == 4)
1411 {
1412 volatile uint32_t *reg;
1413 UsbEp0ByteCntType ep0Cnt;
1414 UsbEp0CtrlType ep0Cfg;
1415 uint8_t *addr;
1416 size_t i;
1417
1418 /* set up the xnak for ep0 */
1419 reg = (volatile uint32_t *) TNETV_USB_EP0_CNT;
1420 *reg &= ~0xFF;
1421
1422 /* Setup endpoint zero */
1423 ep0Cfg.val = 0;
1424 ep0Cfg.f.buf_size = EP0_BUF_SIZE_64; /* must be 64 bytes for USB 2.0 */
1425 ep0Cfg.f.dbl_buf = 0;
1426 ep0Cfg.f.in_en = 1;
1427 ep0Cfg.f.in_int_en = 0;
1428 ep0Cfg.f.out_en = 0;
1429 ep0Cfg.f.out_int_en = 0;
1430 tnetv_usb_reg_write(TNETV_USB_EP0_CFG, ep0Cfg.val);
1431
1432 addr = (uint8_t *) TNETV_EP_DATA_ADDR(EP0_INPKT_ADDRESS);
1433 for (i = 0; i < sizeof(TestPacket); i++)
1434 {
1435 *addr++ = TestPacket[i];
1436 }
1437
1438 /* start xmitting (only 53 bytes are used) */
1439 ep0Cnt.val = 0;
1440 ep0Cnt.f.in_xbuf_cnt = 53;
1441 ep0Cnt.f.in_xbuf_nak = 0;
1442 tnetv_usb_reg_write(TNETV_USB_EP0_CNT, ep0Cnt.val);
1443 }
1444
1445 /* write the config */
1446 usbCtrl.val = tnetv_usb_reg_read(TNETV_USB_CTRL);
1447 usbCtrl.f.hs_test_mode = mode;
1448 usbCtrl.f.dir = 1;
1449 tnetv_usb_reg_write(TNETV_USB_CTRL, usbCtrl.val);
1450}
1451
1452int usb_drv_request_endpoint(int type, int dir)
1453{
1454 int epn;
1455 for (epn = 1; epn < USB_NUM_ENDPOINTS; epn++)
1456 {
1457 if (type == ep_const_data[epn].type)
1458 {
1459 if ((dir == USB_DIR_IN) && (!ep_runtime[epn].in_allocated))
1460 {
1461 ep_runtime[epn].in_allocated = true;
1462 tnetv_gadget_ep_enable(epn, true);
1463 return epn | USB_DIR_IN;
1464 }
1465 if ((dir == USB_DIR_OUT) && (!ep_runtime[epn].out_allocated))
1466 {
1467 ep_runtime[epn].out_allocated = true;
1468 tnetv_gadget_ep_enable(epn, false);
1469 return epn | USB_DIR_OUT;
1470 }
1471 }
1472 }
1473 return -1;
1474}
1475
1476void usb_drv_release_endpoint(int ep)
1477{
1478 int epn = EP_NUM(ep);
1479 if (EP_DIR(ep) == DIR_IN)
1480 {
1481 ep_runtime[epn].in_allocated = false;
1482 tnetv_gadget_ep_disable(epn, true);
1483 }
1484 else
1485 {
1486 ep_runtime[epn].out_allocated = false;
1487 tnetv_gadget_ep_disable(epn, false);
1488 }
1489}