Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/usb/usbd.c
1476 views
1
/*
2
* Enhanced USB Device (EDCI) driver for Tegra X1
3
*
4
* Copyright (c) 2019-2024 CTCaer
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms and conditions of the GNU General Public License,
8
* version 2, as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <string.h>
20
#include <stdlib.h>
21
22
#include <usb/usbd.h>
23
#include <usb/usb_descriptor_types.h>
24
#include <usb/usb_t210.h>
25
26
#include <gfx_utils.h>
27
#include <soc/bpmp.h>
28
#include <soc/clock.h>
29
#include <soc/fuse.h>
30
#include <soc/gpio.h>
31
#include <soc/pinmux.h>
32
#include <soc/pmc.h>
33
#include <soc/timer.h>
34
#include <soc/t210.h>
35
#include <utils/btn.h>
36
37
#include <memory_map.h>
38
39
typedef enum
40
{
41
USB_HW_EP0 = 0,
42
USB_HW_EP1 = 1
43
} usb_hw_ep_t;
44
45
typedef enum
46
{
47
USB_EP_STATUS_IDLE = 0,
48
USB_EP_STATUS_ACTIVE = 1,
49
USB_EP_STATUS_ERROR = 2,
50
USB_EP_STATUS_NO_CONFIG = 3,
51
USB_EP_STATUS_STALLED = 4,
52
USB_EP_STATUS_DISABLED = 5
53
} usb_ep_status_t;
54
55
typedef enum {
56
USB_LOW_SPEED = 0,
57
USB_FULL_SPEED = 1,
58
USB_HIGH_SPEED = 2,
59
USB_SUPER_SPEED = 3,
60
} usb_speed_t;
61
62
typedef struct _dTD_t
63
{
64
vu32 next_dTD;
65
vu32 info;
66
vu32 pages[5];
67
vu32 reserved;
68
} dTD_t;
69
70
typedef struct _dQH_t
71
{
72
vu32 ep_capabilities;
73
vu32 curr_dTD_ptr;
74
vu32 next_dTD_ptr;
75
vu32 token;
76
vu32 buffers[5]; // hmmm.
77
vu32 reserved;
78
vu32 setup[2];
79
vu32 gap[4];
80
} dQH_t;
81
82
typedef struct _usbd_t
83
{
84
volatile dTD_t dtds[4 * 4]; // 4 dTD per endpoint.
85
volatile dQH_t *qhs;
86
int ep_configured[4];
87
int ep_bytes_requested[4];
88
} usbd_t;
89
90
typedef struct _usbd_controller_t
91
{
92
u32 port_speed;
93
t210_usb2d_t *regs;
94
usb_ctrl_setup_t control_setup;
95
usb_desc_t *desc;
96
usb_gadget_type gadget;
97
u8 config_num;
98
u8 interface_num;
99
u8 max_lun;
100
bool usb_phy_ready;
101
bool configuration_set;
102
bool max_lun_set;
103
bool bulk_reset_req;
104
bool hid_report_sent;
105
u32 charger_detect;
106
} usbd_controller_t;
107
108
extern u8 hid_report_descriptor_jc[];
109
extern u8 hid_report_descriptor_touch[];
110
extern u32 hid_report_descriptor_jc_size;
111
extern u32 hid_report_descriptor_touch_size;
112
113
extern usb_desc_t usb_gadget_hid_jc_descriptors;
114
extern usb_desc_t usb_gadget_hid_touch_descriptors;
115
extern usb_desc_t usb_gadget_ums_descriptors;
116
117
usbd_t *usbdaemon;
118
119
usbd_controller_t *usbd_otg;
120
usbd_controller_t usbd_usb_otg_controller_ctxt;
121
122
bool usb_init_done = false;
123
124
u8 *usb_ep0_ctrl_buf = (u8 *)USB_EP_CONTROL_BUF_ADDR;
125
126
static int _usbd_reset_usb_otg_phy_device_mode()
127
{
128
usbd_otg->usb_phy_ready = false;
129
130
// Clear UTMIP reset.
131
USB(USB1_IF_USB_SUSP_CTRL) &= ~SUSP_CTRL_UTMIP_RESET;
132
133
// Wait for PHY clock to get validated.
134
u32 retries = 100000; // 200ms timeout.
135
while (!(USB(USB1_IF_USB_SUSP_CTRL) & SUSP_CTRL_USB_PHY_CLK_VALID))
136
{
137
retries--;
138
if (!retries)
139
return USB_ERROR_INIT;
140
usleep(1);
141
}
142
usbd_otg->usb_phy_ready = true;
143
144
// Clear all device addresses, enabled setup requests and transmit events.
145
usbd_otg->regs->periodiclistbase = 0;
146
usbd_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat;
147
usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete;
148
149
// Stop device controller.
150
usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN;
151
152
// Set controller mode to idle.
153
usbd_otg->regs->usbmode &= ~USB2D_USBMODE_CM_MASK;
154
155
// Reset the controller.
156
usbd_otg->regs->usbcmd |= USB2D_USBCMD_RESET;
157
158
// Wait for the reset to complete.
159
retries = 100000; // 200ms timeout.
160
while (usbd_otg->regs->usbcmd & USB2D_USBCMD_RESET)
161
{
162
retries--;
163
if (!retries)
164
return USB_ERROR_INIT;
165
usleep(1);
166
}
167
168
// Wait for PHY clock to get validated after reset.
169
retries = 100000; // 200ms timeout.
170
while (!(USB(USB1_IF_USB_SUSP_CTRL) & SUSP_CTRL_USB_PHY_CLK_VALID))
171
{
172
retries--;
173
if (!retries)
174
return USB_ERROR_INIT;
175
usleep(1);
176
}
177
178
// Set controller to Device mode.
179
usbd_otg->regs->usbmode = (usbd_otg->regs->usbmode & ~USB2D_USBMODE_CM_MASK) | USB2D_USBMODE_CM_DEVICE;
180
181
// Wait for the selected mode to be enabled.
182
retries = 100000; // 200ms timeout.
183
while ((usbd_otg->regs->usbmode & USB2D_USBMODE_CM_MASK) != USB2D_USBMODE_CM_DEVICE)
184
{
185
retries--;
186
if (!retries)
187
return USB_ERROR_INIT;
188
usleep(1);
189
}
190
191
// Disable all interrupts.
192
usbd_otg->regs->usbintr = 0;
193
194
// Set the ID pullup and disable all OTGSC interrupts.
195
usbd_otg->regs->otgsc = USB2D_OTGSC_USB_ID_PULLUP;
196
197
// Clear all relevant interrupt statuses.
198
usbd_otg->regs->usbsts = USB2D_USBSTS_UI | USB2D_USBSTS_UEI | USB2D_USBSTS_PCI |
199
USB2D_USBSTS_FRI | USB2D_USBSTS_SEI | USB2D_USBSTS_AAI |
200
USB2D_USBSTS_URI | USB2D_USBSTS_SRI | USB2D_USBSTS_SLI;
201
202
// Disable and clear all OTGSC interrupts.
203
usbd_otg->regs->otgsc = USB2D_OTGSC_USB_IRQ_STS_MASK;
204
205
// Clear EP0, EP1, EP2 setup requests.
206
usbd_otg->regs->endptsetupstat = 7; //TODO: Shouldn't this be endptsetupstat = endptsetupstat?
207
208
// Set all interrupts to immediate.
209
usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_ITC_MASK;
210
211
return USB_RES_OK;
212
}
213
214
static void _usb_charger_detect()
215
{
216
// Charger detect init.
217
usbd_otg->charger_detect = 0;
218
bool charger_detect_enable = FUSE(FUSE_RESERVED_SW) & 0x10; // Disabled on Switch production.
219
if (charger_detect_enable)
220
{
221
usbd_otg->charger_detect |= 1;
222
// Configure detect pin.
223
PINMUX_AUX(PINMUX_AUX_LCD_GPIO1) &= ~(PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK);
224
gpio_direction_input(GPIO_PORT_V, GPIO_PIN_3);
225
226
// Configure charger pin.
227
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) &= ~(PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK);
228
gpio_config(GPIO_PORT_CC, GPIO_PIN_5, GPIO_MODE_GPIO);
229
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
230
231
// Enable charger.
232
if (gpio_read(GPIO_PORT_V, GPIO_PIN_3))
233
{
234
usbd_otg->charger_detect |= 2;
235
gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_HIGH);
236
usbd_otg->charger_detect |= 0x100;
237
USB(USB1_UTMIP_BAT_CHRG_CFG0) = BAT_CHRG_CFG0_OP_SRC_EN; // Clears UTMIP_PD_CHRG and enables charger detect.
238
usleep(5000);
239
}
240
}
241
}
242
243
static void _usb_init_phy()
244
{
245
// Configure and enable PLLU.
246
clock_enable_pllu();
247
248
// Enable USBD clock.
249
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
250
usleep(2);
251
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
252
usleep(2);
253
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_USBD);
254
usleep(2);
255
256
// Clear XUSB_PADCTL reset
257
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB_PADCTL);
258
259
// Enable USB PHY and reset for programming.
260
u32 usb_susp_ctrl = USB(USB1_IF_USB_SUSP_CTRL);
261
USB(USB1_IF_USB_SUSP_CTRL) = usb_susp_ctrl | SUSP_CTRL_UTMIP_RESET;
262
USB(USB1_IF_USB_SUSP_CTRL) = usb_susp_ctrl | SUSP_CTRL_UTMIP_PHY_ENB | SUSP_CTRL_UTMIP_RESET;
263
264
// Enable IDDQ control by software and disable UTMIPLL IDDQ.
265
CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) = (CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) & 0xFFFFFFFC) | 1;
266
usleep(10);
267
268
// Disable crystal clock.
269
USB(USB1_UTMIP_MISC_CFG1) &= 0xBFFFFFFF;
270
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) &= 0xBFFFFFFF;
271
272
// Set B_SESS_VLD.
273
USB(USB1_IF_USB_PHY_VBUS_SENSORS) |= 0x1000;
274
USB(USB1_IF_USB_PHY_VBUS_SENSORS) |= 0x800;
275
276
// Set UTMIPLL dividers and config based on OSC and enable it to 960 MHz.
277
clock_enable_utmipll();
278
279
// Configure UTMIP Transceiver Cells.
280
u32 fuse_usb_calib = FUSE(FUSE_USB_CALIB);
281
USB(USB1_UTMIP_XCVR_CFG0) = (((USB(USB1_UTMIP_XCVR_CFG0) & 0xFFFFFFF0) | (fuse_usb_calib & 0xF)) & 0xFE3FFFFF) | ((fuse_usb_calib & 0x3F) << 25 >> 29 << 22);
282
USB(USB1_UTMIP_XCVR_CFG1) = (USB(USB1_UTMIP_XCVR_CFG1) & 0xFFC3FFFF) | ((fuse_usb_calib << 21) >> 28 << 18);
283
USB(USB1_UTMIP_XCVR_CFG3) = (USB(USB1_UTMIP_XCVR_CFG3) & 0xFFFFC1FF) | ((FUSE(FUSE_USB_CALIB_EXT) & 0x1F) << 9);
284
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFDFFFFF;
285
USB(USB1_UTMIP_XCVR_CFG2) = (USB(USB1_UTMIP_XCVR_CFG2) & 0xFFFFF1FF) | 0x400;
286
usleep(1);
287
288
// Configure misc UTMIP.
289
USB(USB1_UTMIP_DEBOUNCE_CFG0) = (USB(USB1_UTMIP_DEBOUNCE_CFG0) & 0xFFFF0000) | 0xBB80;
290
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFC0FF) | 0x100; // when osc is 38.4KHz
291
292
//USB(USB1_UTMIP_SPARE_CFG0) &= 0xFFFFFEE7; unpatched0
293
USB(USB1_UTMIP_BIAS_CFG2) |= 2; //patched0 - UTMIP_HSSQUELCH_LEVEL_NEW: 2.
294
USB(USB1_UTMIP_SPARE_CFG0) &= 0xFFFFFE67; //patched0 - FUSE_HS_IREF_CAP_CFG
295
USB(USB1_UTMIP_TX_CFG0) |= 0x80000;
296
297
//USB(USB1_UTMIP_HSRX_CFG0) = (USB(USB1_UTMIP_HSRX_CFG0) & 0xFFF003FF) | 0x88000 | 0x4000; unpatched1
298
USB(USB1_UTMIP_HSRX_CFG0) = (USB(USB1_UTMIP_HSRX_CFG0) & 0xF0F003FF) | 0x88000 | 0x4000; //patched1 - reset UTMIP_PCOUNT_UPDN_DIV: From 1 to 0.
299
USB(USB1_UTMIP_BIAS_CFG2) &= 0xFFFFFFF8; //patched1 - UTMIP_HSSQUELCH_LEVEL_NEW: 0
300
301
USB(USB1_UTMIP_HSRX_CFG1) = (USB(USB1_UTMIP_HSRX_CFG1) & 0xFFFFFFC1) | 0x12;
302
USB(USB1_UTMIP_MISC_CFG1) |= 0x40000000;
303
304
// Enable crystal clock.
305
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= 0x40000000;
306
307
// Enable USB2 tracking clock.
308
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_USB2_TRK);
309
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) & 0xFFFFFF00) | 6; // Set trank divisor to 4.
310
311
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFC03F07) | 0x78000 | 0x50; // Set delays.
312
USB(USB1_UTMIP_BIAS_CFG0) &= 0xFFFFFBFF; // Disable Power down bias circuit.
313
usleep(1);
314
315
// Force PDTRK input into power up.
316
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFFFFE) | 2;
317
usleep(100);
318
319
// TRK cycle done. Force PDTRK input into power down.
320
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1;
321
usleep(3);
322
323
// Force PDTRK input into power up.
324
USB(USB1_UTMIP_BIAS_CFG1) = USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFFFFE;
325
usleep(100);
326
327
// TRK cycle done. Force PDTRK input into power down.
328
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1;
329
330
// Disable USB2 tracking clock and configure UTMIP misc.
331
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_CLR) = BIT(CLK_Y_USB2_TRK);
332
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) & 0xFEFFFFEA) | 0x2000000 | 0x28 | 2;
333
usleep(1);
334
335
USB(USB1_UTMIP_BIAS_CFG0) &= 0xFF3FF7FF;
336
usleep(1);
337
338
// Clear power downs on UTMIP ID and VBUS wake up, PD, PD2, PDZI, PDCHRP, PDDR.
339
PMC(APBDEV_PMC_USB_AO) &= 0xFFFFFFF3; // UTMIP ID and VBUS wake up.
340
usleep(1);
341
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFFBFFF; // UTMIP_FORCE_PD_POWERDOWN.
342
usleep(1);
343
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFEFFFF; // UTMIP_FORCE_PD2_POWERDOWN.
344
usleep(1);
345
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFBFFFF; // UTMIP_FORCE_PDZI_POWERDOWN.
346
usleep(1);
347
USB(USB1_UTMIP_XCVR_CFG1) &= 0xFFFFFFFB; // UTMIP_FORCE_PDCHRP_POWERDOWN.
348
usleep(1);
349
USB(USB1_UTMIP_XCVR_CFG1) &= 0xFFFFFFEF; // UTMIP_FORCE_PDDR_POWERDOWN.
350
usleep(1);
351
}
352
353
int usb_device_init()
354
{
355
if (usb_init_done)
356
return USB_RES_OK;
357
358
// Ease the stress to APB.
359
bpmp_clk_rate_relaxed(true);
360
361
// Initialize USB2 controller PHY.
362
_usb_init_phy();
363
364
// Restore OC.
365
bpmp_clk_rate_relaxed(false);
366
367
// AHB USB performance cfg.
368
AHB_GIZMO(AHB_GIZMO_AHB_MEM) |= AHB_MEM_DONT_SPLIT_AHB_WR | AHB_MEM_ENB_FAST_REARBITRATE;
369
AHB_GIZMO(AHB_GIZMO_USB) |= AHB_GIZMO_IMMEDIATE;
370
AHB_GIZMO(AHB_ARBITRATION_PRIORITY_CTRL) = PRIORITY_CTRL_WEIGHT(7) | PRIORITY_SELECT_USB;
371
AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) = MEM_PREFETCH_ENABLE | MEM_PREFETCH_USB_MST_ID |
372
MEM_PREFETCH_ADDR_BNDRY(12) | 0x1000; // Addr boundary 64KB, Inactivity 4096 cycles.
373
374
// Set software and hardware context storage and clear it.
375
usbdaemon = (usbd_t *)USBD_ADDR; // Depends on USB_TD_BUFFER_PAGE_SIZE aligned address.
376
usbd_otg = &usbd_usb_otg_controller_ctxt;
377
memset(usbd_otg, 0, sizeof(usbd_controller_t));
378
memset(usbdaemon, 0, sizeof(usbd_t));
379
380
usbd_otg->regs = (t210_usb2d_t *)USB_OTG_BASE;
381
usbd_otg->usb_phy_ready = false;
382
383
// Initialize USB PHY on the USB_OTG Controller (#1) in Device mode.
384
int res = _usbd_reset_usb_otg_phy_device_mode();
385
usbd_otg->configuration_set = false;
386
387
_usb_charger_detect();
388
389
if (!res)
390
usb_init_done = true;
391
392
return res;
393
}
394
395
static void _usb_device_power_down()
396
{
397
// Enable PHY low power suspend.
398
usbd_otg->regs->hostpc1_devlc |= USB2D_HOSTPC1_DEVLC_PHCD;
399
// Do not use any controller regs after the above!
400
// A reset or clear of the PHCD suspend bit must happen.
401
402
// Power down OTG and Bias circuits.
403
USB(USB1_UTMIP_BIAS_CFG0) |= BIT(11) | BIT(10); // UTMIP_OTGPD, UTMIP_BIASPD.
404
405
// Power down ID detectors.
406
USB(USB1_UTMIP_BIAS_CFG0) |= BIT(23) | BIT(22); // UTMIP_IDPD_SEL, UTMIP_IDPD_VAL.
407
408
if (usbd_otg->charger_detect)
409
{
410
USB(USB1_UTMIP_BAT_CHRG_CFG0) = 1; //UTMIP_PD_CHRG
411
usbd_otg->charger_detect = 0;
412
}
413
414
// Power down the UTMIP transceivers.
415
// UTMIP_FORCE_PDZI_POWERDOWN, UTMIP_FORCE_PD2_POWERDOWN, UTMIP_FORCE_PD_POWERDOWN.
416
USB(USB1_UTMIP_XCVR_CFG0) |= BIT(18) | BIT(16) |BIT(14);
417
// UTMIP_FORCE_PDDR_POWERDOWN, UTMIP_FORCE_PDCHRP_POWERDOWN, UTMIP_FORCE_PDDISC_POWERDOWN.
418
USB(USB1_UTMIP_XCVR_CFG1) |= BIT(4) | BIT(2) | BIT(0);
419
420
// Keep UTMIP in reset.
421
USB(USB1_IF_USB_SUSP_CTRL) |= SUSP_CTRL_UTMIP_RESET;
422
423
// Power down PD trunk.
424
USB(USB1_UTMIP_BIAS_CFG1) |= BIT(0); //UTMIP_FORCE_PDTRK_POWERDOWN.
425
426
// Force UTMIP_PLL power down.
427
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(14); // UTMIP_FORCE_PLL_ENABLE_POWERDOWN.
428
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(12); // UTMIP_FORCE_PLL_ACTIVE_POWERDOWN.
429
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= BIT(4) | BIT(0); // UTMIP_FORCE_PD_SAMP_A/C_POWERDOWN.
430
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(16); // UTMIP_FORCE_PLLU_POWERDOWN.
431
432
// Disable crystal clock.
433
USB(USB1_UTMIP_MISC_CFG1) &= 0xBFFFFFFF;
434
435
// Force enable UTMIPLL IDDQ.
436
CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) |= 3;
437
438
// Set XUSB_PADCTL reset
439
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL);
440
441
// Disable USBD clock.
442
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_USBD);
443
444
// Disable PLLU.
445
clock_disable_pllu();
446
447
usb_init_done = false;
448
}
449
450
static void _usbd_disable_ep1()
451
{
452
usbd_otg->regs->endptctrl[1] = 0;
453
}
454
455
static void _usbd_stall_reset_ep1(usb_dir_t direction, usb_ep_cfg_t stall)
456
{
457
stall &= 1;
458
if (direction == USB_DIR_IN)
459
{
460
usbd_otg->regs->endptctrl[1] = (usbd_otg->regs->endptctrl[1] & ~USB2D_ENDPTCTRL_TX_EP_STALL) | ((u32)stall << 16);
461
if (!stall)
462
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_TX_EP_RESET;
463
}
464
else
465
{
466
usbd_otg->regs->endptctrl[1] = (usbd_otg->regs->endptctrl[1] & ~USB2D_ENDPTCTRL_RX_EP_STALL) | stall;
467
if (!stall)
468
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_RX_EP_RESET;
469
}
470
}
471
472
void usb_device_stall_ep1_bulk_out()
473
{
474
_usbd_stall_reset_ep1(USB_DIR_OUT, USB_EP_CFG_STALL);
475
}
476
477
void usb_device_stall_ep1_bulk_in()
478
{
479
_usbd_stall_reset_ep1(USB_DIR_IN, USB_EP_CFG_STALL);
480
}
481
482
static int _usbd_get_max_pkt_length(int endpoint)
483
{
484
switch (endpoint)
485
{
486
case USB_EP_CTRL_OUT:
487
case USB_EP_CTRL_IN:
488
return 64;
489
case USB_EP_BULK_OUT:
490
case USB_EP_BULK_IN:
491
if (usbd_otg->port_speed == USB_HIGH_SPEED)
492
return 512;
493
else
494
return 64;
495
default:
496
return 64;
497
}
498
}
499
500
static void _usbd_initialize_ep_ctrl(u32 endpoint)
501
{
502
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
503
usb_dir_t direction = endpoint & 1;
504
505
memset((void *)&usbdaemon->qhs[endpoint], 0, sizeof(dQH_t));
506
507
if (!endpoint)
508
usbdaemon->qhs[endpoint].ep_capabilities = USB_QHD_EP_CAP_IOS_ENABLE;
509
510
usbdaemon->qhs[endpoint].next_dTD_ptr = 1; // TERMINATE_SET
511
512
u32 max_packet_len = _usbd_get_max_pkt_length(endpoint) & USB_QHD_EP_CAP_MAX_PKT_LEN_MASK;
513
usbdaemon->qhs[endpoint].ep_capabilities |= max_packet_len << 16;
514
515
if (direction == USB_DIR_IN)
516
{
517
u32 endpoint_type = usbd_otg->regs->endptctrl[actual_ep] & ~USB2D_ENDPTCTRL_TX_EP_TYPE_MASK;
518
if (actual_ep)
519
endpoint_type |= usbd_otg->gadget ? USB2D_ENDPTCTRL_TX_EP_TYPE_INTR : USB2D_ENDPTCTRL_TX_EP_TYPE_BULK;
520
else
521
endpoint_type |= USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL;
522
523
usbd_otg->regs->endptctrl[actual_ep] = endpoint_type;
524
525
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_TX_EP_STALL;
526
527
if (actual_ep == USB_HW_EP1)
528
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_TX_EP_RESET;
529
530
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_TX_EP_ENABLE;
531
}
532
else // EP Bulk OUT.
533
{
534
u32 endpoint_type = usbd_otg->regs->endptctrl[actual_ep] & ~USB2D_ENDPTCTRL_RX_EP_TYPE_MASK;
535
if (actual_ep)
536
endpoint_type |= usbd_otg->gadget ? USB2D_ENDPTCTRL_RX_EP_TYPE_INTR : USB2D_ENDPTCTRL_RX_EP_TYPE_BULK;
537
else
538
endpoint_type |= USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL;
539
540
usbd_otg->regs->endptctrl[actual_ep] = endpoint_type;
541
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL;
542
543
if (actual_ep == USB_HW_EP1)
544
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_RX_EP_RESET;
545
546
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_RX_EP_ENABLE;
547
}
548
}
549
550
static int _usbd_initialize_ep0()
551
{
552
memset((void *)usbdaemon->qhs, 0, sizeof(dQH_t) * 4); // Clear all used EP queue heads.
553
memset((void *)usbdaemon->dtds, 0, sizeof(dTD_t) * 4); // Clear all used EP0 token heads.
554
555
usbd_otg->regs->asynclistaddr = (u32)usbdaemon->qhs;
556
557
_usbd_initialize_ep_ctrl(USB_EP_CTRL_OUT);
558
_usbd_initialize_ep_ctrl(USB_EP_CTRL_IN);
559
560
// Disable Auto Low Power.
561
usbd_otg->regs->hostpc1_devlc &= ~USB2D_HOSTPC1_DEVLC_ASUS;
562
563
// Initiate an attach event.
564
usbd_otg->regs->usbcmd |= USB2D_USBCMD_RUN;
565
566
u32 retries = 100000; // 200ms timeout.
567
while (!(usbd_otg->regs->usbcmd & USB2D_USBCMD_RUN))
568
{
569
retries--;
570
if (!retries)
571
return USB_ERROR_TIMEOUT;
572
usleep(1);
573
}
574
575
return USB_RES_OK;
576
}
577
578
// static void _disable_usb_wdt4()
579
// {
580
// if (TIMER_WDT4_STATUS & 1)// active
581
// {
582
// TIMER_TMR0_TMR_PTV &= 0x7FFFFFFF; // Disable timer
583
// TIMER_WDT4_UNLOCK_PATTERN = 0xC45A; // Alow writes to disable counter bit.
584
// TIMER_WDT4_COMMAND |= 2; // Disable counter
585
// TIMER_TMR0_TMR_PCR |= 0x40000000;// INTR_CLR
586
// }
587
// }
588
589
int usbd_flush_endpoint(u32 endpoint)
590
{
591
592
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
593
usb_dir_t direction = endpoint & 1;
594
u32 reg_mask = endpoint;
595
596
// Flash all endpoints or 1.
597
if (endpoint != USB_EP_ALL)
598
{
599
if (direction == USB_DIR_IN)
600
reg_mask = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
601
else
602
reg_mask = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
603
}
604
usbd_otg->regs->endptflush = reg_mask;
605
606
u32 retries = 100000; // 200ms timeout.
607
while (usbd_otg->regs->endptflush & reg_mask)
608
{
609
retries--;
610
if (!retries)
611
return USB_ERROR_TIMEOUT;
612
usleep(1);
613
}
614
615
// Wait for the endpoint to finish all transactions (buffer not ready).
616
retries = 100000; // 200ms timeout.
617
while (usbd_otg->regs->endptstatus & reg_mask)
618
{
619
retries--;
620
if (!retries)
621
return USB_ERROR_TIMEOUT;
622
usleep(1);
623
}
624
625
// Wait for the endpoint to clear the primed status.
626
retries = 100000; // 200ms timeout.
627
while (usbd_otg->regs->endptprime & reg_mask)
628
{
629
retries--;
630
if (!retries)
631
return USB_ERROR_TIMEOUT;
632
usleep(1);
633
}
634
635
return USB_RES_OK;
636
}
637
638
static void _usb_reset_disable_ep1()
639
{
640
usbd_flush_endpoint(USB_EP_ALL);
641
_usbd_stall_reset_ep1(USB_DIR_OUT, USB_EP_CFG_RESET); // EP1 Bulk OUT.
642
_usbd_stall_reset_ep1(USB_DIR_IN, USB_EP_CFG_RESET); // EP1 Bulk IN.
643
_usbd_disable_ep1();
644
645
usbd_otg->config_num = 0;
646
usbd_otg->interface_num = 0;
647
usbd_otg->configuration_set = false;
648
usbd_otg->max_lun_set = false;
649
}
650
651
void usbd_end(bool reset_ep, bool only_controller)
652
{
653
if (reset_ep)
654
_usb_reset_disable_ep1();
655
656
// Stop device controller.
657
usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN;
658
659
// Enable PHY auto low power suspend.
660
usbd_otg->regs->hostpc1_devlc |= USB2D_HOSTPC1_DEVLC_ASUS;
661
662
if (!only_controller)
663
_usb_device_power_down();
664
}
665
666
static void _usbd_mark_ep_complete(u32 endpoint)
667
{
668
u32 complete_bit;
669
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
670
usb_dir_t direction = endpoint & 1;
671
672
usbd_flush_endpoint(endpoint);
673
674
memset((void *)&usbdaemon->dtds[endpoint * 4], 0, sizeof(dTD_t) * 4);
675
memset((void *)&usbdaemon->qhs[endpoint], 0, sizeof(dQH_t));
676
677
usbdaemon->ep_configured[endpoint] = 0;
678
usbdaemon->ep_bytes_requested[endpoint] = 0;
679
680
if (direction == USB_DIR_IN)
681
complete_bit = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
682
else
683
complete_bit = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
684
685
usbd_otg->regs->endptcomplete |= complete_bit;
686
}
687
688
static usb_ep_status_t _usbd_get_ep_status(usb_ep_t endpoint)
689
{
690
bool status;
691
u32 reg_val;
692
u32 reg_mask;
693
u32 actual_ep = (endpoint & 2) >> 1;
694
usb_dir_t direction = endpoint & 1;
695
696
if (direction == USB_DIR_IN)
697
reg_mask = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
698
else
699
reg_mask = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
700
701
if (actual_ep == USB_HW_EP1)
702
reg_val = usbd_otg->regs->endptctrl[1];
703
else
704
reg_val = usbd_otg->regs->endptctrl[0];
705
706
// Check stalled status.
707
if (direction == USB_DIR_IN)
708
status = reg_val & USB2D_ENDPTCTRL_TX_EP_STALL;
709
else
710
status = reg_val & USB2D_ENDPTCTRL_RX_EP_STALL;
711
712
if (status)
713
return USB_EP_STATUS_STALLED;
714
715
// Check enabled status.
716
if (direction == USB_DIR_IN)
717
status = reg_val & USB2D_ENDPTCTRL_TX_EP_ENABLE;
718
else
719
status = reg_val & USB2D_ENDPTCTRL_RX_EP_ENABLE;
720
721
if (!status)
722
return USB_EP_STATUS_DISABLED;
723
724
// CHeck qHD error status.
725
u32 token_error_mask = USB_QHD_TOKEN_HALTED | USB_QHD_TOKEN_BUFFER_ERROR | USB_QHD_TOKEN_XFER_ERROR;
726
if (usbdaemon->qhs[endpoint].token & token_error_mask)
727
return USB_EP_STATUS_ERROR;
728
729
// Check if endpoint has a request or a ready buffer.
730
if ((usbd_otg->regs->endptprime & reg_mask) || (usbd_otg->regs->endptstatus & reg_mask))
731
return USB_EP_STATUS_ACTIVE; // RX/TX active.
732
733
// Return idle or not configured status.
734
if (!usbdaemon->ep_configured[endpoint])
735
return USB_EP_STATUS_NO_CONFIG;
736
737
return USB_EP_STATUS_IDLE;
738
}
739
740
static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_timeout)
741
{
742
if (!buf)
743
len = 0;
744
745
u32 prime_bit;
746
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
747
usb_dir_t direction = endpoint & 1;
748
u32 length_left = len;
749
u32 dtd_ep_idx = endpoint * 4;
750
751
_usbd_mark_ep_complete(endpoint);
752
753
if (endpoint == USB_EP_CTRL_OUT)
754
usbdaemon->qhs[endpoint].ep_capabilities = USB_QHD_EP_CAP_IOS_ENABLE;
755
756
u32 max_packet_len = _usbd_get_max_pkt_length(endpoint) & USB_QHD_EP_CAP_MAX_PKT_LEN_MASK;
757
usbdaemon->qhs[endpoint].ep_capabilities |= (max_packet_len << 16) | USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS;
758
usbdaemon->qhs[endpoint].next_dTD_ptr = 0; // Clear terminate bit.
759
//usbdaemon->qhs[endpoint].ep_capabilities |= USB_QHD_TOKEN_IRQ_ON_COMPLETE;
760
761
usbdaemon->ep_configured[endpoint] = 1;
762
usbdaemon->ep_bytes_requested[endpoint] = len;
763
764
// Configure dTD.
765
u32 dtd_idx = 0;
766
do
767
{
768
if (dtd_idx)
769
usbdaemon->dtds[dtd_ep_idx + dtd_idx - 1].next_dTD = (u32)&usbdaemon->dtds[dtd_ep_idx + dtd_idx];
770
771
u32 dtd_size = MIN(length_left, USB_TD_BUFFER_MAX_SIZE); // 16KB max per dTD.
772
usbdaemon->dtds[dtd_ep_idx + dtd_idx].info = (dtd_size << 16) | USB_QHD_TOKEN_ACTIVE;
773
// usbdaemon->dtds[dtd_ep_idx + dtd_idx].info |= USB_QHD_TOKEN_IRQ_ON_COMPLETE;
774
775
// Set buffers addresses to all page pointers.
776
u32 dt_buffer_offset = dtd_idx * USB_TD_BUFFER_MAX_SIZE;
777
for (u32 i = 0; i < 4; i++)
778
usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[i] = !buf ? 0 :
779
(u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * i)];
780
781
//usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[5] =
782
// (u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * 4)]; // Last buffer. Unused.
783
784
length_left -= dtd_size;
785
if (length_left)
786
dtd_idx++;
787
}
788
while (length_left);
789
790
// Last dTD, terminate it.
791
usbdaemon->dtds[dtd_ep_idx + dtd_idx].next_dTD = 1;
792
793
// Set first dTD address to queue head next dTD.
794
usbdaemon->qhs[endpoint].next_dTD_ptr |= (u32)&usbdaemon->dtds[dtd_ep_idx] & 0xFFFFFFE0;
795
796
// Flush AHB prefetcher.
797
AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) &= ~MEM_PREFETCH_ENABLE;
798
AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) |= MEM_PREFETCH_ENABLE;
799
800
if (direction == USB_DIR_IN)
801
prime_bit = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
802
else
803
prime_bit = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
804
805
// Flush data before priming EP.
806
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
807
808
// Prime endpoint.
809
usbd_otg->regs->endptprime |= prime_bit; // USB2_CONTROLLER_USB2D_ENDPTPRIME.
810
811
int res = USB_RES_OK;
812
usb_ep_status_t ep_status;
813
if (sync_timeout)
814
{
815
ep_status = _usbd_get_ep_status(endpoint);
816
if (ep_status == USB_EP_STATUS_ACTIVE)
817
{
818
u32 retries = sync_timeout;
819
while (retries)
820
{
821
ep_status = _usbd_get_ep_status(endpoint);
822
if (ep_status != USB_EP_STATUS_ACTIVE)
823
{
824
if (ep_status == USB_EP_STATUS_DISABLED)
825
res = USB2_ERROR_XFER_EP_DISABLED;
826
goto out;
827
}
828
retries--;
829
usleep(1);
830
}
831
res = USB_ERROR_TIMEOUT;
832
}
833
else if (ep_status == USB_EP_STATUS_DISABLED)
834
res = USB2_ERROR_XFER_EP_DISABLED;
835
out:
836
if (res)
837
_usbd_mark_ep_complete(endpoint);
838
else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE)
839
res = USB_ERROR_XFER_ERROR;
840
841
// Invalidate data after OP is done.
842
if (direction == USB_DIR_OUT)
843
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
844
}
845
846
return res;
847
}
848
849
static int _usbd_ep_ack(usb_ep_t ep)
850
{
851
return _usbd_ep_operation(ep, NULL, 0, USB_XFER_SYNCED_ENUM);
852
}
853
854
static void _usbd_set_ep0_stall()
855
{
856
// EP Control endpoints must be always stalled together.
857
usbd_otg->regs->endptctrl[0] = USB2D_ENDPTCTRL_TX_EP_ENABLE | USB2D_ENDPTCTRL_TX_EP_STALL |
858
USB2D_ENDPTCTRL_RX_EP_ENABLE | USB2D_ENDPTCTRL_RX_EP_STALL;
859
}
860
861
int usbd_set_ep_stall(u32 endpoint, int ep_stall)
862
{
863
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
864
usb_dir_t direction = endpoint & 1;
865
866
if (ep_stall)
867
{
868
if (direction == USB_DIR_IN)
869
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_TX_EP_STALL; // Stall EP Bulk IN.
870
else
871
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_RX_EP_STALL; // Stall EP Bulk OUT.
872
}
873
else
874
{
875
if (direction == USB_DIR_IN)
876
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_TX_EP_STALL; // Clear stall EP Bulk IN.
877
else
878
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL; // Clear stall EP Bulk OUT.
879
}
880
881
return USB_RES_OK;
882
}
883
884
static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor, int *size, bool *ep_stall)
885
{
886
u8 _bRequest = usbd_otg->control_setup.bRequest;
887
u16 _wIndex = usbd_otg->control_setup.wIndex;
888
u16 _wValue = usbd_otg->control_setup.wValue;
889
u16 _wLength = usbd_otg->control_setup.wLength;
890
891
bool valid_interface = _wIndex == usbd_otg->interface_num;
892
bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0;
893
894
if (!valid_interface || _wValue != 0 || _wLength != valid_len)
895
{
896
*ep_stall = true;
897
return;
898
}
899
900
switch (_bRequest)
901
{
902
case USB_REQUEST_BULK_RESET:
903
_usbd_ep_ack(USB_EP_CTRL_IN);
904
usbd_otg->bulk_reset_req = true;
905
break; // DELAYED_STATUS;
906
case USB_REQUEST_BULK_GET_MAX_LUN:
907
*transmit_data = true;
908
*size = 1;
909
descriptor[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported.
910
usbd_otg->max_lun_set = true;
911
break;
912
default:
913
*ep_stall = true;
914
break;
915
}
916
}
917
918
static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor, int *size, bool *ep_stall)
919
{
920
u8 descriptor_type = usbd_otg->control_setup.wValue >> 8;
921
u8 descriptor_subtype = usbd_otg->control_setup.wValue & 0xFF;
922
923
switch (descriptor_type)
924
{
925
case USB_DESCRIPTOR_DEVICE:
926
{
927
/*
928
u32 soc_rev = APB_MISC(APB_MISC_GP_HIDREV);
929
usb_device_descriptor.idProduct = (soc_rev >> 8) & 0xFF; // chip_id.
930
usb_device_descriptor.idProduct |= ((soc_rev << 4) | (FUSE(FUSE_SKU_INFO) & 0xF)) << 8; // HIDFAM.
931
usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV.
932
usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV.
933
*/
934
*descriptor = usbd_otg->desc->dev;
935
*size = usbd_otg->desc->dev->bLength;
936
*transmit_data = true;
937
return;
938
}
939
case USB_DESCRIPTOR_CONFIGURATION:
940
if (usbd_otg->gadget == USB_GADGET_UMS)
941
{
942
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
943
{
944
usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200;
945
usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200;
946
}
947
else // Full speed. 64 bytes.
948
{
949
usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40;
950
usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40;
951
}
952
}
953
else
954
{
955
usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_otg->desc->cfg;
956
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
957
{
958
tmp->endpoint[0].wMaxPacketSize = 0x200;
959
tmp->endpoint[1].wMaxPacketSize = 0x200;
960
tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
961
tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
962
}
963
else // Full speed. 64 bytes.
964
{
965
tmp->endpoint[0].wMaxPacketSize = 0x40;
966
tmp->endpoint[1].wMaxPacketSize = 0x40;
967
tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
968
tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
969
}
970
}
971
*descriptor = usbd_otg->desc->cfg;
972
*size = usbd_otg->desc->cfg->config.wTotalLength;
973
*transmit_data = true;
974
return;
975
case USB_DESCRIPTOR_STRING:
976
switch (descriptor_subtype)
977
{
978
case 1:
979
*descriptor = usbd_otg->desc->vendor;
980
*size = usbd_otg->desc->vendor[0];
981
break;
982
case 2:
983
*descriptor = usbd_otg->desc->product;
984
*size = usbd_otg->desc->product[0];
985
break;
986
case 3:
987
*descriptor = usbd_otg->desc->serial;
988
*size = usbd_otg->desc->serial[0];
989
break;
990
case 0xEE:
991
*descriptor = usbd_otg->desc->ms_os;
992
*size = usbd_otg->desc->ms_os->bLength;
993
break;
994
default:
995
*descriptor = usbd_otg->desc->lang_id;
996
*size = 4;
997
break;
998
}
999
*transmit_data = true;
1000
return;
1001
case USB_DESCRIPTOR_DEVICE_QUALIFIER:
1002
if (!usbd_otg->desc->dev_qual)
1003
goto exit;
1004
usbd_otg->desc->dev_qual->bNumOtherConfigs = 1;
1005
*descriptor = usbd_otg->desc->dev_qual;
1006
*size = usbd_otg->desc->dev_qual->bLength;
1007
*transmit_data = true;
1008
return;
1009
case USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION:
1010
if (!usbd_otg->desc->cfg_other)
1011
goto exit;
1012
if (usbd_otg->port_speed == USB_HIGH_SPEED)
1013
{
1014
usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40;
1015
usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40;
1016
}
1017
else
1018
{
1019
usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200;
1020
usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200;
1021
}
1022
if ((usbd_otg->charger_detect & 1) && (usbd_otg->charger_detect & 2))
1023
usbd_otg->desc->cfg_other->config.bMaxPower = 500 / 2;
1024
*descriptor = usbd_otg->desc->cfg_other;
1025
*size = usbd_otg->desc->cfg_other->config.wTotalLength;
1026
*transmit_data = true;
1027
return;
1028
case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT:
1029
*descriptor = usbd_otg->desc->dev_bot;
1030
*size = usbd_otg->desc->dev_bot->wTotalLength;
1031
*transmit_data = true;
1032
return;
1033
default:
1034
*transmit_data = false;
1035
*ep_stall = true;
1036
return;
1037
}
1038
exit:
1039
*transmit_data = false;
1040
*ep_stall = true;
1041
return;
1042
}
1043
1044
static int _usbd_handle_set_request(bool *ep_stall)
1045
{
1046
int res = USB_RES_OK;
1047
u8 bRequest = usbd_otg->control_setup.bRequest;
1048
if (bRequest == USB_REQUEST_SET_ADDRESS)
1049
{
1050
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1051
1052
// Set USB address for device mode.
1053
if (!res)
1054
usbd_otg->regs->periodiclistbase = (usbd_otg->regs->periodiclistbase & 0x1FFFFFF) | ((usbd_otg->control_setup.wValue & 0xFF) << 25);
1055
}
1056
else if (bRequest == USB_REQUEST_SET_CONFIGURATION)
1057
{
1058
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1059
if (!res)
1060
{
1061
usbd_otg->config_num = usbd_otg->control_setup.wValue;
1062
1063
// Remove configuration.
1064
if (!usbd_otg->config_num)
1065
{
1066
//! TODO: Signal that to userspace.
1067
_usb_reset_disable_ep1();
1068
return res;
1069
}
1070
1071
// Initialize configuration.
1072
_usbd_initialize_ep_ctrl(USB_EP_BULK_OUT);
1073
_usbd_initialize_ep_ctrl(USB_EP_BULK_IN);
1074
usbd_otg->configuration_set = true;
1075
}
1076
}
1077
else
1078
*ep_stall = true;
1079
1080
return res;
1081
}
1082
1083
static int _usbd_handle_ep0_control_transfer()
1084
{
1085
int res = USB_RES_OK;
1086
bool ep_stall = false;
1087
bool transmit_data = false;
1088
1089
u8 *descriptor = (u8 *)USB_DESCRIPTOR_ADDR;
1090
int size = 0;
1091
1092
u8 _bmRequestType = usbd_otg->control_setup.bmRequestType;
1093
u8 _bRequest = usbd_otg->control_setup.bRequest;
1094
u16 _wValue = usbd_otg->control_setup.wValue;
1095
u16 _wIndex = usbd_otg->control_setup.wIndex;
1096
u16 _wLength = usbd_otg->control_setup.wLength;
1097
1098
//gfx_printf("%02X %02X %04X %04X %04X\n", _bmRequestType, _bRequest, _wValue, _wIndex, _wLength);
1099
1100
switch (_bmRequestType)
1101
{
1102
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
1103
res = _usbd_handle_set_request(&ep_stall);
1104
break;
1105
1106
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
1107
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1108
if (!res)
1109
usbd_otg->interface_num = _wValue;
1110
break;
1111
1112
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
1113
switch (_bRequest)
1114
{
1115
case USB_REQUEST_CLEAR_FEATURE:
1116
case USB_REQUEST_SET_FEATURE:
1117
if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT)
1118
{
1119
int direction;
1120
switch (_wIndex) // endpoint
1121
{
1122
case USB_EP_ADDR_CTRL_OUT:
1123
direction = 2;
1124
break;
1125
case USB_EP_ADDR_CTRL_IN:
1126
direction = 3;
1127
break;
1128
case USB_EP_ADDR_BULK_OUT:
1129
direction = 0;
1130
break;
1131
case USB_EP_ADDR_BULK_IN:
1132
direction = 1;
1133
break;
1134
default:
1135
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1136
goto out;
1137
}
1138
1139
if (_bRequest == USB_REQUEST_CLEAR_FEATURE)
1140
_usbd_stall_reset_ep1(direction, USB_EP_CFG_RESET);
1141
else
1142
_usbd_stall_reset_ep1(direction, USB_EP_CFG_STALL);
1143
1144
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1145
}
1146
else
1147
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1148
1149
break;
1150
default:
1151
ep_stall = true;
1152
break;
1153
}
1154
break;
1155
1156
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
1157
memset(descriptor, 0, _wLength);
1158
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
1159
break;
1160
1161
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
1162
switch (_bRequest)
1163
{
1164
case USB_REQUEST_GET_STATUS:
1165
descriptor[0] = USB_STATUS_DEV_SELF_POWERED;
1166
descriptor[1] = 0; // No support for remove wake up.
1167
transmit_data = true;
1168
size = 2;
1169
break;
1170
case USB_REQUEST_GET_DESCRIPTOR:
1171
_usbd_handle_get_descriptor(&transmit_data, (void **)&descriptor, &size, &ep_stall);
1172
break;
1173
case USB_REQUEST_GET_CONFIGURATION:
1174
descriptor = (u8 *)&usbd_otg->config_num;
1175
size = _wLength;
1176
transmit_data = true;
1177
break;
1178
default:
1179
ep_stall = true;
1180
break;
1181
}
1182
break;
1183
1184
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
1185
if (_bRequest == USB_REQUEST_GET_INTERFACE)
1186
{
1187
memset(descriptor, 0, _wLength);
1188
descriptor[0] = usbd_otg->interface_num;
1189
size = _wLength;
1190
}
1191
else if (_bRequest == USB_REQUEST_GET_STATUS)
1192
{
1193
memset(descriptor, 0, _wLength);
1194
size = _wLength;
1195
}
1196
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget > USB_GADGET_UMS)
1197
{
1198
if (usbd_otg->gadget == USB_GADGET_HID_GAMEPAD)
1199
{
1200
descriptor = (u8 *)&hid_report_descriptor_jc;
1201
size = hid_report_descriptor_jc_size;
1202
}
1203
else // USB_GADGET_HID_TOUCHPAD
1204
{
1205
descriptor = (u8 *)&hid_report_descriptor_touch;
1206
size = hid_report_descriptor_touch_size;
1207
}
1208
1209
usbd_otg->hid_report_sent = true;
1210
}
1211
else
1212
{
1213
ep_stall = true;
1214
break;
1215
}
1216
1217
if (_wLength < size)
1218
size = _wLength;
1219
transmit_data = true;
1220
break;
1221
1222
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
1223
if (_bRequest == USB_REQUEST_GET_STATUS)
1224
{
1225
int ep_req;
1226
switch (_wIndex)
1227
{
1228
case USB_EP_ADDR_CTRL_OUT:
1229
ep_req = USB_EP_CTRL_OUT;
1230
break;
1231
case USB_EP_ADDR_BULK_OUT:
1232
ep_req = USB_EP_BULK_OUT;
1233
break;
1234
case USB_EP_ADDR_CTRL_IN:
1235
ep_req = USB_EP_CTRL_IN;
1236
break;
1237
case USB_EP_ADDR_BULK_IN:
1238
ep_req = USB_EP_BULK_IN;
1239
break;
1240
default:
1241
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1242
goto out;
1243
}
1244
1245
size = _wLength;
1246
memset(descriptor, 0, size);
1247
1248
if (_usbd_get_ep_status(ep_req) == USB_EP_STATUS_STALLED)
1249
descriptor[0] = USB_STATUS_EP_HALTED;
1250
else
1251
descriptor[0] = USB_STATUS_EP_OK;
1252
1253
transmit_data = true;
1254
}
1255
else
1256
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1257
break;
1258
1259
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
1260
memset(descriptor, 0, _wLength);
1261
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
1262
break;
1263
1264
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
1265
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
1266
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
1267
{
1268
switch (_wIndex)
1269
{
1270
case USB_DESCRIPTOR_MS_COMPAT_ID:
1271
descriptor = (u8 *)usbd_otg->desc->ms_cid;
1272
size = usbd_otg->desc->ms_cid->dLength;
1273
transmit_data = true;
1274
break;
1275
case USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES:
1276
descriptor = (u8 *)usbd_otg->desc->mx_ext;
1277
size = usbd_otg->desc->mx_ext->dLength;
1278
transmit_data = true;
1279
break;
1280
default:
1281
ep_stall = true;
1282
break;
1283
}
1284
}
1285
else
1286
ep_stall = true;
1287
break;
1288
1289
default:
1290
ep_stall = true;
1291
break;
1292
}
1293
1294
// Transmit data to HOST if any.
1295
if (transmit_data)
1296
{
1297
memcpy(usb_ep0_ctrl_buf, descriptor, size);
1298
1299
if (_wLength < size)
1300
size = _wLength;
1301
res = _usbd_ep_operation(USB_EP_CTRL_IN, usb_ep0_ctrl_buf, size, USB_XFER_SYNCED_ENUM);
1302
if (!res)
1303
res = _usbd_ep_ack(USB_EP_CTRL_OUT);
1304
}
1305
1306
out:
1307
if (ep_stall)
1308
_usbd_set_ep0_stall();
1309
1310
return res;
1311
}
1312
1313
static int _usbd_ep0_initialize()
1314
{
1315
bool enter = false;
1316
if (usbd_otg->configuration_set)
1317
enter = true;
1318
else
1319
{
1320
usbdaemon->qhs = (volatile dQH_t *)USB2_QH_USB2D_QH_EP_BASE;
1321
1322
if (!_usbd_initialize_ep0())
1323
enter = true;
1324
}
1325
1326
if (enter)
1327
{
1328
usbd_otg->configuration_set = false;
1329
usbd_otg->max_lun_set = false;
1330
1331
// Timeout if cable or communication isn't started in 1.5 minutes.
1332
u32 timer = get_tmr_ms() + 90000;
1333
while (true)
1334
{
1335
u32 usb_status_irqs = usbd_otg->regs->usbsts;
1336
1337
// Clear all interrupt statuses.
1338
usbd_otg->regs->usbsts = usb_status_irqs;
1339
1340
// Check if a reset was received.
1341
if (usb_status_irqs & USB2D_USBSTS_URI)
1342
{
1343
//_disable_usb_wdt4();
1344
1345
// Clear all device addresses, enabled setup requests, transmit events and flush all endpoints.
1346
usbd_otg->regs->periodiclistbase = 0;
1347
usbd_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat;
1348
usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete;
1349
usbd_flush_endpoint(USB_EP_ALL);
1350
}
1351
1352
// Check if port change happened.
1353
if (usb_status_irqs & USB2D_USBSTS_PCI)
1354
usbd_otg->port_speed = (usbd_otg->regs->hostpc1_devlc & USB2D_HOSTPC1_DEVLC_PSPD_MASK) >> 25;
1355
1356
// Acknowledge setup request for EP0 and copy its configuration.
1357
u32 ep0_setup_req = usbd_otg->regs->endptsetupstat;
1358
if (ep0_setup_req & 1)
1359
{
1360
usbd_otg->regs->endptsetupstat = ep0_setup_req;
1361
memcpy(&usbd_otg->control_setup, (void *)usbdaemon->qhs->setup, 8);
1362
if (_usbd_handle_ep0_control_transfer())
1363
break;
1364
}
1365
if (usbd_otg->configuration_set)
1366
return USB_RES_OK;
1367
1368
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
1369
return USB_ERROR_USER_ABORT;
1370
}
1371
}
1372
1373
return USB_ERROR_TIMEOUT;
1374
}
1375
1376
int usb_device_enumerate(usb_gadget_type gadget)
1377
{
1378
switch (gadget)
1379
{
1380
case USB_GADGET_UMS:
1381
usbd_otg->desc = &usb_gadget_ums_descriptors;
1382
break;
1383
case USB_GADGET_HID_GAMEPAD:
1384
usbd_otg->desc = &usb_gadget_hid_jc_descriptors;
1385
break;
1386
case USB_GADGET_HID_TOUCHPAD:
1387
usbd_otg->desc = &usb_gadget_hid_touch_descriptors;
1388
break;
1389
}
1390
1391
usbd_otg->gadget = gadget;
1392
1393
return _usbd_ep0_initialize();
1394
}
1395
1396
int usbd_handle_ep0_ctrl_setup()
1397
{
1398
// Acknowledge setup request for EP0 and copy its configuration.
1399
u32 ep0_setup_req = usbd_otg->regs->endptsetupstat;
1400
if (ep0_setup_req & 1)
1401
{
1402
usbd_otg->regs->endptsetupstat = ep0_setup_req;
1403
memcpy(&usbd_otg->control_setup, (void *)usbdaemon->qhs->setup, 8);
1404
_usbd_handle_ep0_control_transfer();
1405
memset(usb_ep0_ctrl_buf, 0, USB_TD_BUFFER_PAGE_SIZE);
1406
}
1407
1408
// Only return error if bulk reset was requested.
1409
if (usbd_otg->bulk_reset_req)
1410
{
1411
usbd_otg->bulk_reset_req = false;
1412
return USB_RES_BULK_RESET;
1413
}
1414
1415
return USB_RES_OK;
1416
}
1417
1418
static usb_ep_status_t _usbd_get_ep1_status(usb_dir_t dir)
1419
{
1420
usb_ep_t ep;
1421
if (dir == USB_DIR_OUT)
1422
ep = USB_EP_BULK_OUT;
1423
else
1424
ep = USB_EP_BULK_IN;
1425
return _usbd_get_ep_status(ep);
1426
}
1427
1428
int usb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_timeout)
1429
{
1430
if ((u32)buf % USB_EP_BUFFER_ALIGN)
1431
return USB2_ERROR_XFER_NOT_ALIGNED;
1432
1433
if (len > USB_EP_BUFFER_MAX_SIZE)
1434
len = USB_EP_BUFFER_MAX_SIZE;
1435
1436
int res = _usbd_ep_operation(USB_EP_BULK_OUT, buf, len, sync_timeout);
1437
1438
if (sync_timeout && bytes_read)
1439
*bytes_read = res ? 0 : len;
1440
1441
return res;
1442
}
1443
1444
int usb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read)
1445
{
1446
if ((u32)buf % USB_EP_BUFFER_ALIGN)
1447
return USB2_ERROR_XFER_NOT_ALIGNED;
1448
1449
if (len > USB_EP_BULK_OUT_MAX_XFER)
1450
len = USB_EP_BULK_OUT_MAX_XFER;
1451
1452
int res;
1453
u32 bytes = 0;
1454
*bytes_read = 0;
1455
u8 *buf_curr = buf;
1456
1457
while (len)
1458
{
1459
u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE);
1460
1461
res = usb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED_DATA);
1462
if (res)
1463
return res;
1464
1465
len -= len_ep;
1466
buf_curr += len_ep;
1467
*bytes_read = *bytes_read + bytes;
1468
}
1469
1470
return USB_RES_OK;
1471
}
1472
1473
static int _usbd_get_ep1_out_bytes_read()
1474
{
1475
if (_usbd_get_ep_status(USB_EP_BULK_OUT) != USB_EP_STATUS_IDLE)
1476
return 0;
1477
else
1478
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_OUT] - (usbdaemon->qhs[USB_EP_BULK_OUT].token >> 16));
1479
}
1480
1481
int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout)
1482
{
1483
usb_ep_status_t ep_status;
1484
do
1485
{
1486
ep_status = _usbd_get_ep1_status(USB_DIR_OUT);
1487
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
1488
break;
1489
1490
usbd_handle_ep0_ctrl_setup();
1491
}
1492
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
1493
1494
*pending_bytes = _usbd_get_ep1_out_bytes_read();
1495
1496
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
1497
1498
if (ep_status == USB_EP_STATUS_IDLE)
1499
return USB_RES_OK;
1500
else if (ep_status == USB_EP_STATUS_DISABLED)
1501
return USB2_ERROR_XFER_EP_DISABLED;
1502
else
1503
return USB_ERROR_XFER_ERROR;
1504
}
1505
1506
int usb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_timeout)
1507
{
1508
if ((u32)buf % USB_EP_BUFFER_ALIGN)
1509
return USB2_ERROR_XFER_NOT_ALIGNED;
1510
1511
if (len > USB_EP_BUFFER_MAX_SIZE)
1512
len = USB_EP_BUFFER_MAX_SIZE;
1513
1514
int res = _usbd_ep_operation(USB_EP_BULK_IN, buf, len, sync_timeout);
1515
1516
if (sync_timeout && bytes_written)
1517
*bytes_written = res ? 0 : len;
1518
1519
return res;
1520
}
1521
1522
static int _usbd_get_ep1_in_bytes_written()
1523
{
1524
if (_usbd_get_ep_status(USB_EP_BULK_IN) != USB_EP_STATUS_IDLE)
1525
return 0;
1526
else
1527
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_IN] - (usbdaemon->qhs[USB_EP_BULK_IN].token >> 16));
1528
}
1529
1530
int usb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_timeout)
1531
{
1532
usb_ep_status_t ep_status;
1533
do
1534
{
1535
ep_status = _usbd_get_ep1_status(USB_DIR_IN);
1536
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
1537
break;
1538
1539
usbd_handle_ep0_ctrl_setup();
1540
}
1541
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
1542
1543
*pending_bytes = _usbd_get_ep1_in_bytes_written();
1544
1545
if (ep_status == USB_EP_STATUS_IDLE)
1546
return USB_RES_OK;
1547
else if (ep_status == USB_EP_STATUS_DISABLED)
1548
return USB2_ERROR_XFER_EP_DISABLED;
1549
1550
usb_device_stall_ep1_bulk_out();
1551
return USB_ERROR_XFER_ERROR;
1552
}
1553
1554
bool usb_device_get_suspended()
1555
{
1556
bool suspended = (usbd_otg->regs->portsc1 & USB2D_PORTSC1_SUSP) == USB2D_PORTSC1_SUSP;
1557
return suspended;
1558
}
1559
1560
bool usb_device_get_port_in_sleep()
1561
{
1562
// Windows heuristic: Forces port into suspend, sleep and J-State.
1563
return (usbd_otg->regs->portsc1) == 0x885;
1564
}
1565
1566
int usb_device_class_send_max_lun(u8 max_lun)
1567
{
1568
// Timeout if get MAX_LUN request doesn't happen in 10s.
1569
u32 timer = get_tmr_ms() + 10000;
1570
1571
usbd_otg->max_lun = max_lun;
1572
1573
while (!usbd_otg->max_lun_set)
1574
{
1575
usbd_handle_ep0_ctrl_setup();
1576
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
1577
return USB_ERROR_USER_ABORT;
1578
}
1579
1580
return USB_RES_OK;
1581
}
1582
1583
int usb_device_class_send_hid_report()
1584
{
1585
// Timeout if get GET_HID_REPORT request doesn't happen in 10s.
1586
u32 timer = get_tmr_ms() + 10000;
1587
1588
// Wait for request and transfer start.
1589
while (!usbd_otg->hid_report_sent)
1590
{
1591
usbd_handle_ep0_ctrl_setup();
1592
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
1593
return USB_ERROR_USER_ABORT;
1594
}
1595
1596
return USB_RES_OK;
1597
}
1598
1599
void usb_device_get_ops(usb_ops_t *ops)
1600
{
1601
ops->usbd_flush_endpoint = usbd_flush_endpoint;
1602
ops->usbd_set_ep_stall = usbd_set_ep_stall;
1603
ops->usbd_handle_ep0_ctrl_setup = usbd_handle_ep0_ctrl_setup;
1604
ops->usbd_end = usbd_end;
1605
ops->usb_device_init = usb_device_init;
1606
ops->usb_device_enumerate = usb_device_enumerate;
1607
ops->usb_device_class_send_max_lun = usb_device_class_send_max_lun;
1608
ops->usb_device_class_send_hid_report = usb_device_class_send_hid_report;
1609
ops->usb_device_get_suspended = usb_device_get_suspended;
1610
ops->usb_device_get_port_in_sleep = usb_device_get_port_in_sleep;
1611
1612
ops->usb_device_ep1_out_read = usb_device_ep1_out_read;
1613
ops->usb_device_ep1_out_read_big = usb_device_ep1_out_read_big;
1614
ops->usb_device_ep1_out_reading_finish = usb_device_ep1_out_reading_finish;
1615
ops->usb_device_ep1_in_write = usb_device_ep1_in_write;
1616
ops->usb_device_ep1_in_writing_finish = usb_device_ep1_in_writing_finish;
1617
}
1618
1619
1620