1 /*
2 * Copyright (c) 2023 ITE Technology Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT ite_it82xx2_usb
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/usb/usb_device.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <soc.h>
13 #include <soc_dt.h>
14 #include <string.h>
15 #include <zephyr/irq.h>
16 #include <zephyr/pm/policy.h>
17 #include <zephyr/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
18 #include <zephyr/dt-bindings/interrupt-controller/it8xxx2-wuc.h>
19
20 #include <zephyr/logging/log.h>
21 LOG_MODULE_REGISTER(usb_dc_it82xx2, CONFIG_USB_DRIVER_LOG_LEVEL);
22
23 /* USB Device Controller Registers Bits & Constants */
24 #define IT8XXX2_USB_IRQ DT_INST_IRQ_BY_IDX(0, 0, irq)
25 #define IT8XXX2_WU90_IRQ DT_INST_IRQ_BY_IDX(0, 1, irq)
26
27 #define MAX_NUM_ENDPOINTS 16
28 #define FIFO_NUM 3
29 #define SETUP_DATA_CNT 8
30 #define DC_ADDR_NULL 0x00
31 #define DC_ADDR_MASK 0x7F
32
33 /* The related definitions of the register EP STATUS:
34 * 0x41/0x45/0x49/0x4D
35 */
36 #define EP_STATUS_ERROR 0x0F
37
38 /* The related definitions of the register dc_line_status: 0x51 */
39 #define RX_LINE_STATE_MASK (RX_LINE_FULL_SPD | RX_LINE_LOW_SPD)
40 #define RX_LINE_LOW_SPD 0x02
41 #define RX_LINE_FULL_SPD 0x01
42 #define RX_LINE_RESET 0x00
43
44 /* EPN Extend Control 2 Register Mask Definition */
45 #define READY_BITS 0x0F
46 #define COMPLETED_TRANS 0xF0
47
48 /* EP Definitions */
49 #define EP_VALID_MASK 0x0F
50 #define EP_INVALID_MASK ~(USB_EP_DIR_MASK | EP_VALID_MASK)
51
52 /* Bit [1:0] represents the TRANSACTION_TYPE as follows: */
53 enum it82xx2_transaction_types {
54 DC_SETUP_TRANS,
55 DC_IN_TRANS,
56 DC_OUTDATA_TRANS,
57 DC_ALL_TRANS
58 };
59
60 /* The bit definitions of the register EP RX/TX FIFO Control:
61 * EP_RX_FIFO_CONTROL: 0X64/0x84/0xA4/0xC4
62 * EP_TX_FIFO_CONTROL: 0X74/0x94/0xB4/0xD4
63 */
64 #define FIFO_FORCE_EMPTY BIT(0)
65
66 /* The bit definitions of the register Host/Device Control: 0XE0 */
67 #define RESET_CORE BIT(1)
68
69 /* Bit definitions of the register Port0/Port1 MISC Control: 0XE4/0xE8 */
70 #define PULL_DOWN_EN BIT(4)
71
72 /* Bit definitions of the register EPN0N1_EXTEND_CONTROL_REG: 0X98 ~ 0X9D */
73 #define EPN1_OUTDATA_SEQ BIT(4)
74 #define EPN0_ISO_ENABLE BIT(2)
75 #define EPN0_SEND_STALL BIT(1)
76 #define EPN0_OUTDATA_SEQ BIT(0)
77
78 /* ENDPOINT[3..0]_STATUS_REG */
79 #define DC_STALL_SENT BIT(5)
80
81 /* DC_INTERRUPT_STATUS_REG */
82 #define DC_TRANS_DONE BIT(0)
83 #define DC_RESUME_INT BIT(1)
84 #define DC_RESET_EVENT BIT(2)
85 #define DC_SOF_RECEIVED BIT(3)
86 #define DC_NAK_SENT_INT BIT(4)
87
88 /* DC_CONTROL_REG */
89 #define DC_GLOBAL_ENABLE BIT(0)
90 #define DC_TX_LINE_STATE_DM BIT(1)
91 #define DC_DIRECT_CONTROL BIT(3)
92 #define DC_FULL_SPEED_LINE_POLARITY BIT(4)
93 #define DC_FULL_SPEED_LINE_RATE BIT(5)
94 #define DC_CONNECT_TO_HOST BIT(6) /* internal pull-up */
95
96 /* ENDPOINT[3..0]_CONTROL_REG */
97 #define ENDPOINT_EN BIT(0)
98 #define ENDPOINT_RDY BIT(1)
99 #define EP_OUTDATA_SEQ BIT(2)
100 #define EP_SEND_STALL BIT(3)
101 #define EP_ISO_ENABLE BIT(4)
102 #define EP_DIRECTION BIT(5)
103
104 enum it82xx2_ep_status {
105 EP_INIT,
106 EP_CHECK,
107 EP_CONFIG,
108 EP_CONFIG_IN,
109 EP_CONFIG_OUT,
110 };
111
112 enum it82xx2_trans_type {
113 SETUP_TOKEN,
114 IN_TOKEN,
115 OUT_TOKEN,
116 };
117
118 enum it82xx2_setup_stage {
119 INIT_ST,
120 SETUP_ST,
121 DIN_ST,
122 DOUT_ST,
123 STATUS_ST,
124 STALL_SEND,
125 };
126
127 enum it82xx2_extend_ep_ctrl {
128 /* EPN0N1_EXTEND_CONTROL_REG */
129 EXT_EP_ISO_DISABLE,
130 EXT_EP_ISO_ENABLE,
131 EXT_EP_SEND_STALL,
132 EXT_EP_CLEAR_STALL,
133 EXT_EP_CHECK_STALL,
134 EXT_EP_DATA_SEQ_1,
135 EXT_EP_DATA_SEQ_0,
136 EXT_EP_DATA_SEQ_INV,
137 /* EPN_EXTEND_CONTROL1_REG */
138 EXT_EP_DIR_IN,
139 EXT_EP_DIR_OUT,
140 EXT_EP_ENABLE,
141 EXT_EP_DISABLE,
142 /* EPN_EXTEND_CONTROL2_REG */
143 EXT_EP_READY,
144 };
145
146 struct usb_it8xxx2_wuc {
147 /* WUC control device structure */
148 const struct device *wucs;
149 /* WUC pin mask */
150 uint8_t mask;
151 };
152
153 struct usb_it82xx2_config {
154 struct usb_it82xx2_regs *const base;
155 const struct pinctrl_dev_config *pcfg;
156 const struct usb_it8xxx2_wuc *wuc_list;
157 };
158
159 static const struct usb_it8xxx2_wuc usb_wuc0[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] =
160 IT8XXX2_DT_WUC_ITEMS_LIST(0);
161
162 PINCTRL_DT_INST_DEFINE(0);
163
164 static const struct usb_it82xx2_config ucfg0 = {
165 .base = (struct usb_it82xx2_regs *)DT_INST_REG_ADDR(0),
166 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
167 .wuc_list = usb_wuc0
168 };
169
170 struct it82xx2_endpoint_data {
171 usb_dc_ep_callback cb_in;
172 usb_dc_ep_callback cb_out;
173 enum it82xx2_ep_status ep_status;
174 enum usb_dc_ep_transfer_type ep_type;
175 uint16_t remaining; /* remaining bytes */
176 uint16_t mps;
177 };
178
179 struct usb_it82xx2_data {
180 const struct device *dev;
181 struct it82xx2_endpoint_data ep_data[MAX_NUM_ENDPOINTS];
182 enum it82xx2_setup_stage st_state; /* Setup State */
183
184 /* EP0 status */
185 enum it82xx2_trans_type last_token;
186
187 /* EP0 status */
188 enum it82xx2_trans_type now_token;
189
190 uint8_t attached;
191 uint8_t addr;
192 bool no_data_ctrl;
193 bool suspended;
194 usb_dc_status_callback usb_status_cb;
195
196 /* Check the EP interrupt status for (ep > 0) */
197 bool ep_ready[3];
198
199 struct k_sem ep_sem[3];
200 struct k_sem suspended_sem;
201 struct k_work_delayable check_suspended_work;
202 };
203
204 /* Mapped to the bit definitions in the EPN_EXTEND_CONTROL1 Register
205 * (D6h to DDh) for configuring the FIFO direction and for enabling/disabling
206 * the endpoints.
207 */
208 static uint8_t ext_ep_bit_shift[12] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3};
209
210 /* The ep_fifo_res[ep_idx % FIFO_NUM] where the FIFO_NUM is 3 represents the
211 * EP mapping because when (ep_idx % FIFO_NUM) is 3, it actually means the EP0.
212 */
213 static const uint8_t ep_fifo_res[3] = {3, 1, 2};
214
215 /* Mapping the enum it82xx2_extend_ep_ctrl code to their corresponding bit in
216 * the EP45/67/89/1011/1213/1415 Extended Control Registers.
217 */
218 static const uint8_t ext_ctrl_tbl[7] = {
219 EPN0_ISO_ENABLE,
220 EPN0_ISO_ENABLE,
221 EPN0_SEND_STALL,
222 EPN0_SEND_STALL,
223 EPN0_SEND_STALL,
224 EPN0_OUTDATA_SEQ,
225 EPN0_OUTDATA_SEQ,
226 };
227
228 /* Indexing of the following control codes:
229 * EXT_EP_DIR_IN, EXT_EP_DIR_OUT, EXT_EP_ENABLE, EXT_EP_DISABLE
230 */
231 static const uint8_t epn_ext_ctrl_tbl[4] = {1, 0, 1, 0};
232
233 static struct usb_it82xx2_data udata0;
234
it82xx2_get_usb_regs(void)235 static struct usb_it82xx2_regs *it82xx2_get_usb_regs(void)
236 {
237 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(usb0));
238 const struct usb_it82xx2_config *cfg = dev->config;
239 struct usb_it82xx2_regs *const usb_regs = cfg->base;
240
241 return usb_regs;
242 }
243
it82xx2_enable_sof_int(bool enable)244 static void it82xx2_enable_sof_int(bool enable)
245 {
246 struct usb_it82xx2_regs *const usb_regs =
247 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
248
249 usb_regs->dc_interrupt_status = DC_SOF_RECEIVED;
250 if (enable) {
251 usb_regs->dc_interrupt_mask |= DC_SOF_RECEIVED;
252 } else {
253 usb_regs->dc_interrupt_mask &= ~DC_SOF_RECEIVED;
254 }
255 }
256
257 /* Standby(deep doze) mode enable/disable */
it82xx2_enable_standby_state(bool enable)258 static void it82xx2_enable_standby_state(bool enable)
259 {
260 if (enable) {
261 pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
262 } else {
263 pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
264 }
265 }
266
267 /* WU90 (USB D+) Enable/Disable */
it82xx2_enable_wu90_irq(const struct device * dev,bool enable)268 static void it82xx2_enable_wu90_irq(const struct device *dev, bool enable)
269 {
270 const struct usb_it82xx2_config *cfg = dev->config;
271
272 /* Clear pending interrupt */
273 it8xxx2_wuc_clear_status(cfg->wuc_list[0].wucs, cfg->wuc_list[0].mask);
274
275 if (enable) {
276 irq_enable(IT8XXX2_WU90_IRQ);
277 } else {
278 irq_disable(IT8XXX2_WU90_IRQ);
279 }
280 }
281
it82xx2_wu90_isr(const struct device * dev)282 static void it82xx2_wu90_isr(const struct device *dev)
283 {
284 it82xx2_enable_wu90_irq(dev, false);
285 it82xx2_enable_standby_state(false);
286 LOG_DBG("USB D+ (WU90) Triggered");
287 }
288
289 /* WU90 (USB D+) Initializations */
it8xxx2_usb_dc_wuc_init(const struct device * dev)290 static void it8xxx2_usb_dc_wuc_init(const struct device *dev)
291 {
292 const struct usb_it82xx2_config *cfg = dev->config;
293
294 /* Initializing the WUI */
295 it8xxx2_wuc_set_polarity(cfg->wuc_list[0].wucs,
296 cfg->wuc_list[0].mask,
297 WUC_TYPE_EDGE_FALLING);
298 it8xxx2_wuc_clear_status(cfg->wuc_list[0].wucs,
299 cfg->wuc_list[0].mask);
300
301 /* Enabling the WUI */
302 it8xxx2_wuc_enable(cfg->wuc_list[0].wucs, cfg->wuc_list[0].mask);
303
304 /* Connect WU90 (USB D+) interrupt but make it disabled initially */
305 IRQ_CONNECT(IT8XXX2_WU90_IRQ, 0, it82xx2_wu90_isr, 0, 0);
306 }
307
308 /* Function it82xx2_get_ep_fifo_ctrl_reg_idx(uint8_t ep_idx):
309 *
310 * Calculate the register offset index which determines the corresponding
311 * EP FIFO Ctrl Registers which is defined as ep_fifo_ctrl[reg_idx] here
312 *
313 * The ep_fifo_res[ep_idx % FIFO_NUM] represents the EP mapping because when
314 * (ep_idx % FIFO_NUM) is 3, it actually means the EP0.
315 */
it82xx2_get_ep_fifo_ctrl_reg_idx(uint8_t ep_idx)316 static uint8_t it82xx2_get_ep_fifo_ctrl_reg_idx(uint8_t ep_idx)
317 {
318
319 uint8_t reg_idx = (ep_idx < EP8) ?
320 ((ep_fifo_res[ep_idx % FIFO_NUM] - 1) * 2) :
321 ((ep_fifo_res[ep_idx % FIFO_NUM] - 1) * 2 + 1);
322
323 return reg_idx;
324 }
325
326 /* Function it82xx2_get_ep_fifo_ctrl_reg_val(uint8_t ep_idx):
327 *
328 * Calculate the register value written to the ep_fifo_ctrl which is defined as
329 * ep_fifo_ctrl[reg_idx] here for selecting the corresponding control bit.
330 */
it82xx2_get_ep_fifo_ctrl_reg_val(uint8_t ep_idx)331 static uint8_t it82xx2_get_ep_fifo_ctrl_reg_val(uint8_t ep_idx)
332 {
333 uint8_t reg_val = (ep_idx < EP8) ?
334 (1 << ep_idx) : (1 << (ep_idx - EP8));
335
336 return reg_val;
337 }
338
339 /*
340 * Functions it82xx2_epn0n1_ext_ctrl_cfg() and epn0n1_ext_ctrl_cfg_seq_inv()
341 * provide the entrance of configuring the EPN0N1 Extended Ctrl Registers.
342 *
343 * The variable set_clr determines if we set/clear the corresponding bit.
344 */
it82xx2_epn0n1_ext_ctrl_cfg(uint8_t reg_idx,uint8_t bit_mask,bool set_clr)345 static void it82xx2_epn0n1_ext_ctrl_cfg(uint8_t reg_idx, uint8_t bit_mask,
346 bool set_clr)
347 {
348 struct usb_it82xx2_regs *const usb_regs =
349 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
350 volatile uint8_t *epn0n1_ext_ctrl =
351 usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;
352
353 (set_clr) ? (epn0n1_ext_ctrl[reg_idx] |= bit_mask) :
354 (epn0n1_ext_ctrl[reg_idx] &= ~(bit_mask));
355 }
356
it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(uint8_t reg_idx,uint8_t bit_mask,bool set_clr)357 static void it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(uint8_t reg_idx,
358 uint8_t bit_mask, bool set_clr)
359 {
360 struct usb_it82xx2_regs *const usb_regs =
361 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
362 volatile uint8_t *epn0n1_ext_ctrl =
363 usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;
364
365 bool check = (set_clr) ?
366 (epn0n1_ext_ctrl[reg_idx] & EPN0_OUTDATA_SEQ) :
367 (epn0n1_ext_ctrl[reg_idx] & EPN1_OUTDATA_SEQ);
368
369 (check) ? (epn0n1_ext_ctrl[reg_idx] &= ~(bit_mask)) :
370 (epn0n1_ext_ctrl[reg_idx] |= bit_mask);
371 }
372
373 /* Return the status of STALL bit in the EPN0N1 Extend Control Registers */
it82xx2_epn01n1_check_stall(uint8_t reg_idx,uint8_t bit_mask)374 static bool it82xx2_epn01n1_check_stall(uint8_t reg_idx, uint8_t bit_mask)
375 {
376 struct usb_it82xx2_regs *const usb_regs =
377 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
378 volatile uint8_t *epn0n1_ext_ctrl =
379 usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;
380
381 return !!(epn0n1_ext_ctrl[reg_idx] & bit_mask);
382 }
383
384 /* Configuring the EPN Extended Ctrl Registers. */
it82xx2_epn_ext_ctrl_cfg1(uint8_t reg_idx,uint8_t bit_mask,bool set_clr)385 static void it82xx2_epn_ext_ctrl_cfg1(uint8_t reg_idx, uint8_t bit_mask,
386 bool set_clr)
387 {
388 struct usb_it82xx2_regs *const usb_regs =
389 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
390 struct epn_ext_ctrl_regs *epn_ext_ctrl =
391 usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;
392
393 (set_clr) ? (epn_ext_ctrl[reg_idx].epn_ext_ctrl1 |= bit_mask) :
394 (epn_ext_ctrl[reg_idx].epn_ext_ctrl1 &= ~(bit_mask));
395 }
396
it82xx2_epn_ext_ctrl_cfg2(uint8_t reg_idx,uint8_t bit_mask,bool set_clr)397 static void it82xx2_epn_ext_ctrl_cfg2(uint8_t reg_idx, uint8_t bit_mask,
398 bool set_clr)
399 {
400 struct usb_it82xx2_regs *const usb_regs =
401 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
402 struct epn_ext_ctrl_regs *epn_ext_ctrl =
403 usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;
404
405 (set_clr) ? (epn_ext_ctrl[reg_idx].epn_ext_ctrl2 |= bit_mask) :
406 (epn_ext_ctrl[reg_idx].epn_ext_ctrl2 &= ~(bit_mask));
407 }
408
409 /* From 98h to 9Dh, the EP45/67/89/1011/1213/1415 Extended Control Registers
410 * are defined, and their bits definitions are as follows:
411 *
412 * Bit Description
413 * 7 Reserved
414 * 6 EPPOINT5_ISO_ENABLE
415 * 5 EPPOINT5_SEND_STALL
416 * 4 EPPOINT5_OUT_DATA_SEQUENCE
417 * 3 Reserved
418 * 2 EPPOINT4_ISO_ENABLE
419 * 1 EPPOINT4_SEND_STALL
420 * 0 EPPOINT4_OUT_DATA_SEQUENCE
421 *
422 * Apparently, we can tell that the EP4 and EP5 share the same register, and
423 * the EP6 and EP7 share the same one, and the other EPs are defined in the
424 * same way.
425 *
426 * In the function it82xx2_usb_extend_ep_ctrl() we will obtain the mask/flag
427 * according to the bits definitions mentioned above. As for the control code,
428 * please refer to the definition of enum it82xx2_extend_ep_ctrl.
429 */
it82xx2_usb_extend_ep_ctrl(uint8_t ep_idx,enum it82xx2_extend_ep_ctrl ctrl)430 static int it82xx2_usb_extend_ep_ctrl(uint8_t ep_idx,
431 enum it82xx2_extend_ep_ctrl ctrl)
432 {
433 uint8_t reg_idx, mask;
434 bool flag;
435
436 if (ep_idx < EP4) {
437 return -EINVAL;
438 }
439
440 if ((ctrl >= EXT_EP_DIR_IN) && (ctrl < EXT_EP_READY)) {
441 /* From EXT_EP_DIR_IN to EXT_EP_DISABLE */
442 reg_idx = ep_fifo_res[ep_idx % FIFO_NUM];
443 mask = 1 << (ext_ep_bit_shift[ep_idx - 4] * 2 + 1);
444 flag = epn_ext_ctrl_tbl[ctrl - EXT_EP_DIR_IN];
445 it82xx2_epn_ext_ctrl_cfg1(reg_idx, mask, flag);
446
447 } else if ((ctrl >= EXT_EP_ISO_DISABLE) && (ctrl < EXT_EP_DIR_IN)) {
448 /* From EXT_EP_ISO_DISABLE to EXT_EP_DATA_SEQ_0 */
449 reg_idx = (ep_idx - 4) >> 1;
450 flag = !!(ep_idx & 1);
451 mask = flag ? (ext_ctrl_tbl[ctrl] << 4) : (ext_ctrl_tbl[ctrl]);
452
453 if (ctrl == EXT_EP_CHECK_STALL) {
454 return it82xx2_epn01n1_check_stall(reg_idx, mask);
455 } else if (ctrl == EXT_EP_DATA_SEQ_INV) {
456 it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(
457 reg_idx, mask, flag);
458 } else {
459 it82xx2_epn0n1_ext_ctrl_cfg(reg_idx, mask, flag);
460 }
461 } else if (ctrl == EXT_EP_READY) {
462 reg_idx = (ep_idx - 4) >> 1;
463 mask = 1 << (ext_ep_bit_shift[ep_idx - 4]);
464 it82xx2_epn_ext_ctrl_cfg2(reg_idx, mask, true);
465 } else {
466 LOG_ERR("Invalid Control Code of Endpoint");
467 return -EINVAL;
468 }
469
470 return 0;
471 }
472
it82xx2_usb_dc_ip_init(uint8_t p_action)473 static int it82xx2_usb_dc_ip_init(uint8_t p_action)
474 {
475 struct usb_it82xx2_regs *const usb_regs =
476 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
477
478 if (p_action == 0) {
479 /* Reset Device Controller */
480 usb_regs->host_device_control = RESET_CORE;
481 k_msleep(1);
482 usb_regs->port0_misc_control &= ~(PULL_DOWN_EN);
483 usb_regs->port1_misc_control &= ~(PULL_DOWN_EN);
484 /* clear reset bit */
485 usb_regs->host_device_control = 0;
486 }
487
488 usb_regs->dc_interrupt_status =
489 DC_TRANS_DONE | DC_RESET_EVENT | DC_SOF_RECEIVED;
490
491 usb_regs->dc_interrupt_mask = 0x00;
492 usb_regs->dc_interrupt_mask =
493 DC_TRANS_DONE | DC_RESET_EVENT | DC_SOF_RECEIVED;
494
495 usb_regs->dc_address = DC_ADDR_NULL;
496
497 return 0;
498 }
499
it82xx2_usb_dc_attach_init(void)500 static int it82xx2_usb_dc_attach_init(void)
501 {
502 struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;
503 /*
504 * Disable USB debug path , prevent CPU enter
505 * JTAG mode and then reset by USB command.
506 */
507 gctrl_regs->GCTRL_MCCR &= ~(IT8XXX2_GCTRL_MCCR_USB_EN);
508 gctrl_regs->gctrl_pmer2 |= IT8XXX2_GCTRL_PMER2_USB_PAD_EN;
509
510 return it82xx2_usb_dc_ip_init(0);
511 }
512
513 /* Check the condition that SETUP_TOKEN following OUT_TOKEN and return it */
it82xx2_check_setup_following_out(void)514 static bool it82xx2_check_setup_following_out(void)
515 {
516 struct usb_it82xx2_regs *const usb_regs =
517 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
518 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
519 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
520
521 return ((ep_regs[EP0].ep_transtype_sts & DC_ALL_TRANS) == 0 ||
522 (udata0.last_token == IN_TOKEN &&
523 ff_regs[EP0].ep_rx_fifo_dcnt_lsb == SETUP_DATA_CNT));
524 }
525
it82xx2_setup_done(uint8_t ep_ctrl,uint8_t idx)526 static int it82xx2_setup_done(uint8_t ep_ctrl, uint8_t idx)
527 {
528 struct usb_it82xx2_regs *const usb_regs =
529 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
530 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
531 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
532
533 LOG_DBG("SETUP(%d)", idx);
534 /* wrong trans*/
535 if (ep_ctrl & EP_SEND_STALL) {
536 ep_regs[idx].ep_ctrl &= ~EP_SEND_STALL;
537 udata0.st_state = STALL_SEND;
538 ff_regs[idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
539 LOG_DBG("Clear Stall Bit & RX FIFO");
540 return -EINVAL;
541 }
542 /* handle status interrupt */
543 /* status out */
544 if (udata0.st_state == DIN_ST) {
545 LOG_DBG("Status OUT");
546 udata0.last_token = udata0.now_token;
547 udata0.now_token = OUT_TOKEN;
548 udata0.st_state = STATUS_ST;
549 udata0.ep_data[idx].cb_out(idx, USB_DC_EP_DATA_OUT);
550
551 } else if (udata0.st_state == DOUT_ST || udata0.st_state == SETUP_ST) {
552 /* Status IN*/
553 LOG_DBG("Status IN");
554 udata0.last_token = udata0.now_token;
555 udata0.now_token = IN_TOKEN;
556 udata0.st_state = STATUS_ST;
557 udata0.ep_data[idx].cb_in(idx | 0x80, USB_DC_EP_DATA_IN);
558 }
559
560 udata0.last_token = udata0.now_token;
561 udata0.now_token = SETUP_TOKEN;
562 udata0.st_state = SETUP_ST;
563
564 ep_regs[idx].ep_ctrl |= EP_OUTDATA_SEQ;
565 udata0.ep_data[idx].cb_out(USB_EP_DIR_OUT, USB_DC_EP_SETUP);
566
567 /* Set ready bit to no-data control in */
568 if (udata0.no_data_ctrl) {
569 ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
570 LOG_DBG("(%d): Set Ready Bit for no-data control", __LINE__);
571
572 udata0.no_data_ctrl = false;
573 }
574
575 return 0;
576 }
577
it82xx2_in_done(uint8_t ep_ctrl,uint8_t idx)578 static int it82xx2_in_done(uint8_t ep_ctrl, uint8_t idx)
579 {
580 struct usb_it82xx2_regs *const usb_regs =
581 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
582 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
583
584 /* stall send check */
585 if (ep_ctrl & EP_SEND_STALL) {
586 ep_regs[EP0].ep_ctrl &= ~EP_SEND_STALL;
587 udata0.st_state = STALL_SEND;
588 LOG_DBG("Clear Stall Bit");
589 return -EINVAL;
590 }
591
592 if (udata0.st_state >= STATUS_ST) {
593 return -EINVAL;
594 }
595
596 LOG_DBG("IN(%d)(%d)", idx, !!(ep_regs[idx].ep_ctrl & EP_OUTDATA_SEQ));
597
598 udata0.last_token = udata0.now_token;
599 udata0.now_token = IN_TOKEN;
600
601 if (udata0.addr != DC_ADDR_NULL &&
602 udata0.addr != usb_regs->dc_address) {
603 usb_regs->dc_address = udata0.addr;
604 LOG_DBG("Address Is Set Successfully");
605 }
606
607 /* set setup stage */
608 if (udata0.st_state == DOUT_ST) {
609 udata0.st_state = STATUS_ST;
610 /* no data status in */
611 } else if (udata0.ep_data[EP0].remaining == 0 &&
612 udata0.st_state == SETUP_ST) {
613 udata0.st_state = STATUS_ST;
614 } else {
615 udata0.st_state = DIN_ST;
616 }
617
618 if (!!(ep_regs[idx].ep_ctrl & EP_OUTDATA_SEQ)) {
619 ep_regs[idx].ep_ctrl &= ~EP_OUTDATA_SEQ;
620 } else {
621 ep_regs[idx].ep_ctrl |= EP_OUTDATA_SEQ;
622 }
623 udata0.ep_data[idx].cb_in(idx | 0x80, USB_DC_EP_DATA_IN);
624
625 /* set ready bit for status out */
626 LOG_DBG("Remaining Bytes: %d, Stage: %d",
627 udata0.ep_data[EP0].remaining, udata0.st_state);
628
629 if (udata0.st_state == DIN_ST && udata0.ep_data[EP0].remaining == 0) {
630 ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
631 LOG_DBG("Set EP%d Ready (%d)", idx, __LINE__);
632 }
633
634 return 0;
635 }
636
it82xx2_out_done(uint8_t idx)637 static int it82xx2_out_done(uint8_t idx)
638 {
639 struct usb_it82xx2_regs *const usb_regs =
640 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
641 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
642
643 /* ep0 wrong enter check */
644 if (udata0.st_state >= STATUS_ST) {
645 return -EINVAL;
646 }
647
648 LOG_DBG("OUT(%d)", idx);
649
650 udata0.last_token = udata0.now_token;
651 udata0.now_token = OUT_TOKEN;
652
653 if (udata0.st_state == SETUP_ST) {
654 udata0.st_state = DOUT_ST;
655 } else {
656 udata0.st_state = STATUS_ST;
657 }
658
659 udata0.ep_data[idx].cb_out(idx, USB_DC_EP_DATA_OUT);
660
661 /* SETUP_TOKEN follow OUT_TOKEN */
662 if (it82xx2_check_setup_following_out()) {
663 LOG_WRN("[%s] OUT => SETUP", __func__);
664 udata0.last_token = udata0.now_token;
665 udata0.now_token = SETUP_TOKEN;
666 udata0.st_state = SETUP_ST;
667 ep_regs[EP0].ep_ctrl |= EP_OUTDATA_SEQ;
668 udata0.ep_data[EP0].cb_out(USB_EP_DIR_OUT, USB_DC_EP_SETUP);
669
670 /* NOTE: set ready bit to no-data control in */
671 if (udata0.no_data_ctrl) {
672 ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
673 LOG_DBG("Set Ready Bit for no-data control");
674 udata0.no_data_ctrl = false;
675 }
676 }
677
678 return 0;
679 }
680
681 /* Functions it82xx2_ep_in_out_config():
682 * Dealing with the ep_ctrl configurations in this subroutine when it's
683 * invoked in the it82xx2_usb_dc_trans_done().
684 */
it82xx2_ep_in_out_config(uint8_t idx)685 static void it82xx2_ep_in_out_config(uint8_t idx)
686 {
687 struct usb_it82xx2_regs *const usb_regs =
688 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
689 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
690 struct epn_ext_ctrl_regs *epn_ext_ctrl =
691 usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;
692
693 uint8_t ep_trans = (epn_ext_ctrl[idx].epn_ext_ctrl2 >> 4) & READY_BITS;
694
695 if (udata0.ep_data[ep_trans].ep_status == EP_CONFIG_IN) {
696 if (ep_trans < 4) {
697 if (!!(ep_regs[idx].ep_ctrl & EP_OUTDATA_SEQ)) {
698 ep_regs[idx].ep_ctrl &= ~EP_OUTDATA_SEQ;
699 } else {
700 ep_regs[idx].ep_ctrl |= EP_OUTDATA_SEQ;
701 }
702 } else {
703 it82xx2_usb_extend_ep_ctrl(ep_trans,
704 EXT_EP_DATA_SEQ_INV);
705 }
706
707 if (udata0.ep_data[ep_trans].cb_in) {
708 udata0.ep_data[ep_trans].cb_in(ep_trans | 0x80,
709 USB_DC_EP_DATA_IN);
710 }
711
712 k_sem_give(&udata0.ep_sem[idx - 1]);
713
714 } else {
715 if (udata0.ep_data[ep_trans].cb_out) {
716 udata0.ep_data[ep_trans].cb_out(ep_trans,
717 USB_DC_EP_DATA_OUT);
718 }
719 }
720 }
721
it82xx2_usb_dc_trans_done(uint8_t ep_ctrl,uint8_t ep_trans_type)722 static void it82xx2_usb_dc_trans_done(uint8_t ep_ctrl, uint8_t ep_trans_type)
723 {
724 struct usb_it82xx2_regs *const usb_regs =
725 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
726 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
727 struct epn_ext_ctrl_regs *epn_ext_ctrl =
728 usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;
729
730 int ret;
731
732 for (uint8_t idx = 0 ; idx < EP4 ; idx++) {
733 ep_ctrl = ep_regs[idx].ep_ctrl;
734
735 /* check ready bit ,will be 0 when trans done */
736 if ((ep_ctrl & ENDPOINT_EN) && !(ep_ctrl & ENDPOINT_RDY)) {
737 if (idx == EP0) {
738 ep_trans_type = ep_regs[idx].ep_transtype_sts &
739 DC_ALL_TRANS;
740
741 /* set up*/
742 if (ep_trans_type == DC_SETUP_TRANS) {
743 ret = it82xx2_setup_done(ep_ctrl, idx);
744
745 if (ret != 0) {
746 continue;
747 }
748 } else if (ep_trans_type == DC_IN_TRANS) {
749 /* in */
750 ret = it82xx2_in_done(ep_ctrl, idx);
751
752 if (ret != 0) {
753 continue;
754 }
755 } else if (ep_trans_type == DC_OUTDATA_TRANS) {
756 /* out */
757 ret = it82xx2_out_done(idx);
758
759 if (ret != 0) {
760 continue;
761 }
762 }
763 } else {
764 /* prevent wrong entry */
765 if (!udata0.ep_ready[idx - 1]) {
766 continue;
767 }
768
769 if ((epn_ext_ctrl[idx].epn_ext_ctrl2 &
770 COMPLETED_TRANS) == 0) {
771 continue;
772 }
773
774 udata0.ep_ready[idx - 1] = false;
775 it82xx2_ep_in_out_config(idx);
776 }
777 }
778 }
779 }
780
it82xx2_usb_dc_isr(void)781 static void it82xx2_usb_dc_isr(void)
782 {
783 struct usb_it82xx2_regs *const usb_regs =
784 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
785
786 uint8_t status = usb_regs->dc_interrupt_status &
787 usb_regs->dc_interrupt_mask; /* mask non enable int */
788 uint8_t ep_ctrl, ep_trans_type;
789
790 /* reset */
791 if (status & DC_RESET_EVENT) {
792 if ((usb_regs->dc_line_status & RX_LINE_STATE_MASK) ==
793 RX_LINE_RESET) {
794 usb_dc_reset();
795 usb_regs->dc_interrupt_status = DC_RESET_EVENT;
796
797 if (udata0.usb_status_cb) {
798 (*(udata0.usb_status_cb))(USB_DC_RESET, NULL);
799 }
800
801 return;
802
803 } else {
804 usb_regs->dc_interrupt_status = DC_RESET_EVENT;
805 }
806 }
807 /* sof received */
808 if (status & DC_SOF_RECEIVED) {
809 it82xx2_enable_sof_int(false);
810 k_work_reschedule(&udata0.check_suspended_work, K_MSEC(5));
811 }
812 /* transaction done */
813 if (status & DC_TRANS_DONE) {
814 /* clear interrupt before new transaction */
815 usb_regs->dc_interrupt_status = DC_TRANS_DONE;
816 it82xx2_usb_dc_trans_done(ep_ctrl, ep_trans_type);
817 return;
818 }
819
820 }
821
suspended_check_handler(struct k_work * item)822 static void suspended_check_handler(struct k_work *item)
823 {
824 struct k_work_delayable *dwork = k_work_delayable_from_work(item);
825 struct usb_it82xx2_data *udata =
826 CONTAINER_OF(dwork, struct usb_it82xx2_data, check_suspended_work);
827
828 struct usb_it82xx2_regs *const usb_regs =
829 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
830
831 if (usb_regs->dc_interrupt_status & DC_SOF_RECEIVED) {
832 usb_regs->dc_interrupt_status = DC_SOF_RECEIVED;
833 if (udata->suspended) {
834 if (udata->usb_status_cb) {
835 (*(udata->usb_status_cb))(USB_DC_RESUME, NULL);
836 }
837 udata->suspended = false;
838 k_sem_give(&udata->suspended_sem);
839 }
840 k_work_reschedule(&udata->check_suspended_work, K_MSEC(5));
841 return;
842 }
843
844 it82xx2_enable_sof_int(true);
845
846 if (!udata->suspended) {
847 if (udata->usb_status_cb) {
848 (*(udata->usb_status_cb))(USB_DC_SUSPEND, NULL);
849 }
850 udata->suspended = true;
851 it82xx2_enable_wu90_irq(udata->dev, true);
852 it82xx2_enable_standby_state(true);
853
854 k_sem_reset(&udata->suspended_sem);
855 }
856 }
857
858 /*
859 * USB Device Controller API
860 */
usb_dc_attach(void)861 int usb_dc_attach(void)
862 {
863 int ret;
864 struct usb_it82xx2_regs *const usb_regs =
865 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
866
867 if (udata0.attached) {
868 LOG_DBG("Already Attached");
869 return 0;
870 }
871
872 LOG_DBG("Attached");
873 ret = it82xx2_usb_dc_attach_init();
874
875 if (ret) {
876 return ret;
877 }
878
879 for (int idx = 0 ; idx < MAX_NUM_ENDPOINTS ; idx++) {
880 udata0.ep_data[idx].ep_status = EP_INIT;
881 }
882
883 udata0.attached = 1U;
884
885 /* init ep ready status */
886 udata0.ep_ready[0] = false;
887 udata0.ep_ready[1] = false;
888 udata0.ep_ready[2] = false;
889
890 k_sem_init(&udata0.ep_sem[0], 1, 1);
891 k_sem_init(&udata0.ep_sem[1], 1, 1);
892 k_sem_init(&udata0.ep_sem[2], 1, 1);
893 k_sem_init(&udata0.suspended_sem, 0, 1);
894
895 k_work_init_delayable(&udata0.check_suspended_work, suspended_check_handler);
896
897 /* Connect USB interrupt */
898 IRQ_CONNECT(IT8XXX2_USB_IRQ, 0, it82xx2_usb_dc_isr, 0, 0);
899
900 usb_regs->dc_control =
901 DC_GLOBAL_ENABLE | DC_FULL_SPEED_LINE_POLARITY |
902 DC_FULL_SPEED_LINE_RATE | DC_CONNECT_TO_HOST;
903
904 /* Enable USB D+ and USB interrupts */
905 it82xx2_enable_wu90_irq(udata0.dev, true);
906 irq_enable(IT8XXX2_USB_IRQ);
907
908 return 0;
909 }
910
usb_dc_detach(void)911 int usb_dc_detach(void)
912 {
913 struct usb_it82xx2_regs *const usb_regs =
914 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
915
916 if (!udata0.attached) {
917 LOG_DBG("Already Detached");
918 return 0;
919 }
920
921 LOG_DBG("Detached");
922 irq_disable(IT8XXX2_USB_IRQ);
923
924 /* stop pull-up D+ D-*/
925 usb_regs->dc_control &= ~DC_CONNECT_TO_HOST;
926 udata0.attached = 0U;
927
928 return 0;
929 }
930
usb_dc_reset(void)931 int usb_dc_reset(void)
932 {
933 struct usb_it82xx2_regs *const usb_regs =
934 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
935 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
936 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
937
938 int idx;
939
940 LOG_DBG("USB Device Reset");
941
942 ff_regs[EP0].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
943 ff_regs[EP0].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;
944
945 for (idx = 1 ; idx < EP4 ; idx++) {
946 if (udata0.ep_data[idx].ep_status > EP_CHECK) {
947 ff_regs[idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
948 ff_regs[idx].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;
949 }
950 }
951
952 ep_regs[EP0].ep_ctrl = ENDPOINT_EN;
953 usb_regs->dc_address = DC_ADDR_NULL;
954 udata0.addr = DC_ADDR_NULL;
955 usb_regs->dc_interrupt_status = DC_NAK_SENT_INT | DC_SOF_RECEIVED;
956
957 if (udata0.usb_status_cb) {
958 (*(udata0.usb_status_cb))(USB_DC_RESET, NULL);
959 }
960
961 return 0;
962 }
963
usb_dc_set_address(const uint8_t addr)964 int usb_dc_set_address(const uint8_t addr)
965 {
966 LOG_DBG("Set Address(0x%02x) to Data", addr);
967 udata0.addr = addr & DC_ADDR_MASK;
968 return 0;
969 }
970
usb_dc_set_status_callback(const usb_dc_status_callback cb)971 void usb_dc_set_status_callback(const usb_dc_status_callback cb)
972 {
973 udata0.usb_status_cb = cb;
974 }
975
usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)976 int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
977 {
978 uint8_t ep_idx = cfg->ep_addr & EP_VALID_MASK;
979 bool in = !!((cfg->ep_addr) & USB_EP_DIR_MASK);
980
981 if ((cfg->ep_addr & EP_INVALID_MASK) != 0) {
982 return -EINVAL;
983 }
984
985 if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx > EP0) {
986 LOG_ERR("Invalid Endpoint Configuration");
987 return -EINVAL;
988 }
989
990 if (ep_idx >= MAX_NUM_ENDPOINTS) {
991 LOG_WRN("Invalid Endpoint Number 0x%02x", cfg->ep_addr);
992 return -EINVAL;
993 }
994
995 if ((ep_idx != 0) && (!in && ep_idx % FIFO_NUM != 2)) {
996 LOG_WRN("Invalid Endpoint Number 0x%02x", cfg->ep_addr);
997 return -EINVAL;
998 }
999
1000 if ((ep_idx != 0) && (in && ep_idx % FIFO_NUM == 2)) {
1001 LOG_WRN("Invalid Endpoint Number 0x%02x", cfg->ep_addr);
1002 return -EINVAL;
1003 }
1004
1005 if (udata0.ep_data[ep_idx].ep_status > 0) {
1006 LOG_WRN("EP%d have been used", ep_idx);
1007 return -EINVAL;
1008 }
1009
1010 if (ep_idx > EP0) {
1011 udata0.ep_data[ep_idx].mps = cfg->ep_mps;
1012 }
1013
1014 udata0.ep_data[ep_idx].ep_status = EP_CHECK;
1015 LOG_DBG("Check cap(%02x)", cfg->ep_addr);
1016
1017 return 0;
1018 }
1019
usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)1020 int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
1021 {
1022 struct usb_it82xx2_regs *const usb_regs =
1023 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1024 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1025 volatile uint8_t *ep_fifo_ctrl =
1026 usb_regs->fifo_regs[EP_EXT_REGS_BX].fifo_ctrl.ep_fifo_ctrl;
1027
1028 uint8_t ep_idx = (cfg->ep_addr) & EP_VALID_MASK;
1029 uint8_t reg_idx = it82xx2_get_ep_fifo_ctrl_reg_idx(ep_idx);
1030 uint8_t reg_val = it82xx2_get_ep_fifo_ctrl_reg_val(ep_idx);
1031 bool in = !!((cfg->ep_addr) & USB_EP_DIR_MASK);
1032
1033 if ((cfg->ep_addr & EP_INVALID_MASK) != 0) {
1034 LOG_DBG("Invalid Address");
1035 return -EINVAL;
1036 }
1037
1038 if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
1039 LOG_DBG("Not attached / Invalid Endpoint: 0x%X", cfg->ep_addr);
1040 return -EINVAL;
1041 }
1042
1043 if (!cfg->ep_mps) {
1044 LOG_DBG("Wrong EP or Descriptor");
1045 return -EINVAL;
1046 }
1047
1048 udata0.ep_data[ep_idx].ep_status = EP_CONFIG;
1049 udata0.ep_data[ep_idx].mps = cfg->ep_mps;
1050
1051 LOG_DBG("ep_status: %d, mps: %d",
1052 udata0.ep_data[ep_idx].ep_status, udata0.ep_data[ep_idx].mps);
1053
1054 if (!(ep_idx > EP0)) {
1055 return 0;
1056 }
1057
1058 if (ep_idx < EP4) {
1059 (in) ? (ep_regs[ep_idx].ep_ctrl |= EP_DIRECTION) :
1060 (ep_regs[ep_idx].ep_ctrl &= ~EP_DIRECTION);
1061
1062 } else {
1063
1064 (in) ? (it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DIR_IN)) :
1065 (it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DIR_OUT));
1066
1067 if (in) {
1068 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DATA_SEQ_0);
1069 }
1070
1071 LOG_DBG("ep_status %d", udata0.ep_data[ep_idx].ep_status);
1072 }
1073
1074 (in) ? (udata0.ep_data[ep_idx].ep_status = EP_CONFIG_IN) :
1075 (udata0.ep_data[ep_idx].ep_status = EP_CONFIG_OUT);
1076
1077 ep_fifo_ctrl[reg_idx] |= reg_val;
1078
1079 switch (cfg->ep_type) {
1080
1081 case USB_DC_EP_CONTROL:
1082 return -EINVAL;
1083
1084 case USB_DC_EP_ISOCHRONOUS:
1085 if (ep_idx < EP4) {
1086 ep_regs[ep_idx].ep_ctrl |= EP_ISO_ENABLE;
1087 } else {
1088 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ISO_ENABLE);
1089 }
1090
1091 break;
1092
1093 case USB_DC_EP_BULK:
1094 case USB_DC_EP_INTERRUPT:
1095 default:
1096 if (ep_idx < EP4) {
1097 ep_regs[ep_idx].ep_ctrl &= ~EP_ISO_ENABLE;
1098 } else {
1099 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ISO_DISABLE);
1100 }
1101
1102 break;
1103
1104 }
1105
1106 udata0.ep_data[ep_idx].ep_type = cfg->ep_type;
1107
1108 LOG_DBG("EP%d Configured: 0x%2X(%d)", ep_idx, !!(in), cfg->ep_type);
1109 return 0;
1110 }
1111
usb_dc_ep_set_callback(const uint8_t ep,const usb_dc_ep_callback cb)1112 int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb)
1113 {
1114 uint8_t ep_idx = ep & EP_VALID_MASK;
1115
1116 if ((ep & EP_INVALID_MASK) != 0) {
1117 return -EINVAL;
1118 }
1119
1120 if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
1121 LOG_ERR("(%d)Not attached / Invalid endpoint: EP 0x%x",
1122 __LINE__, ep);
1123 return -EINVAL;
1124 }
1125
1126 if (cb == NULL) {
1127 LOG_ERR("(%d): NO callback function", __LINE__);
1128 return -EINVAL;
1129 }
1130
1131 LOG_DBG("EP%d set callback: %d", ep_idx, !!(ep & USB_EP_DIR_IN));
1132
1133 (ep & USB_EP_DIR_IN) ?
1134 (udata0.ep_data[ep_idx].cb_in = cb) :
1135 (udata0.ep_data[ep_idx].cb_out = cb);
1136
1137 return 0;
1138 }
1139
usb_dc_ep_enable(const uint8_t ep)1140 int usb_dc_ep_enable(const uint8_t ep)
1141 {
1142 struct usb_it82xx2_regs *const usb_regs =
1143 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1144 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1145
1146 uint8_t ep_idx = ep & EP_VALID_MASK;
1147
1148 if ((ep & EP_INVALID_MASK) != 0) {
1149 LOG_DBG("Bit[6:4] has something invalid");
1150 return -EINVAL;
1151 }
1152
1153 if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
1154 LOG_ERR("Not attached / Invalid endpoint: EP 0x%x", ep_idx);
1155 return -EINVAL;
1156 }
1157
1158 if (ep_idx < EP4) {
1159 LOG_DBG("ep_idx < 4");
1160 ep_regs[ep_idx].ep_ctrl |= ENDPOINT_EN;
1161 LOG_DBG("EP%d Enabled %02x", ep_idx, ep_regs[ep_idx].ep_ctrl);
1162 } else {
1163 LOG_DBG("ep_idx >= 4");
1164 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ENABLE);
1165 }
1166
1167 return 0;
1168 }
1169
usb_dc_ep_disable(uint8_t ep)1170 int usb_dc_ep_disable(uint8_t ep)
1171 {
1172 struct usb_it82xx2_regs *const usb_regs =
1173 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1174 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1175
1176 uint8_t ep_idx = ep & EP_VALID_MASK;
1177
1178 if ((ep & EP_INVALID_MASK) != 0) {
1179 return -EINVAL;
1180 }
1181
1182 if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
1183 LOG_ERR("Not attached / Invalid endpoint: EP 0x%x", ep_idx);
1184 return -EINVAL;
1185 }
1186
1187 if (ep_idx < EP4) {
1188 ep_regs[ep_idx].ep_ctrl &= ~ENDPOINT_EN;
1189 } else {
1190 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DISABLE);
1191 }
1192
1193 return 0;
1194 }
1195
1196
usb_dc_ep_set_stall(const uint8_t ep)1197 int usb_dc_ep_set_stall(const uint8_t ep)
1198 {
1199 struct usb_it82xx2_regs *const usb_regs =
1200 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1201 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1202
1203 uint8_t ep_idx = ep & EP_VALID_MASK;
1204 struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;
1205
1206 if (((ep & EP_INVALID_MASK) != 0) || (ep_idx >= MAX_NUM_ENDPOINTS)) {
1207 return -EINVAL;
1208 }
1209
1210 if (ep_idx < EP4) {
1211 ep_regs[ep_idx].ep_ctrl |= EP_SEND_STALL;
1212 } else {
1213 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_SEND_STALL);
1214 }
1215
1216 if (ep_idx == EP0) {
1217 ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
1218 uint32_t idx = 0;
1219 /* polling if stall send for 3ms */
1220 while (idx < 198 &&
1221 !(ep_regs[EP0].ep_status & DC_STALL_SENT)) {
1222 /* wait 15.15us */
1223 gctrl_regs->GCTRL_WNCKR = 0;
1224 idx++;
1225 }
1226
1227 if (idx < 198) {
1228 ep_regs[EP0].ep_ctrl &= ~EP_SEND_STALL;
1229 }
1230
1231 udata0.no_data_ctrl = false;
1232 udata0.st_state = STALL_SEND;
1233 }
1234
1235 LOG_DBG("EP(%d) ctrl: 0x%02x", ep_idx, ep_regs[ep_idx].ep_ctrl);
1236 LOG_DBG("EP(%d) Set Stall", ep_idx);
1237
1238 return 0;
1239 }
1240
usb_dc_ep_clear_stall(const uint8_t ep)1241 int usb_dc_ep_clear_stall(const uint8_t ep)
1242 {
1243 struct usb_it82xx2_regs *const usb_regs =
1244 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1245 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1246
1247 uint8_t ep_idx = ep & EP_VALID_MASK;
1248
1249 if ((ep & EP_INVALID_MASK) != 0) {
1250 return -EINVAL;
1251 }
1252
1253 if (ep_idx >= MAX_NUM_ENDPOINTS) {
1254 return -EINVAL;
1255 }
1256
1257 ep_regs[ep_idx].ep_ctrl &= ~EP_SEND_STALL;
1258 LOG_DBG("EP(%d) clear stall", ep_idx);
1259
1260 return 0;
1261 }
1262
usb_dc_ep_is_stalled(const uint8_t ep,uint8_t * stalled)1263 int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
1264 {
1265 struct usb_it82xx2_regs *const usb_regs =
1266 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1267 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1268
1269 uint8_t ep_idx = ep & EP_VALID_MASK;
1270
1271 if ((!stalled) || ((ep & EP_INVALID_MASK) != 0) ||
1272 (ep_idx >= MAX_NUM_ENDPOINTS)) {
1273 return -EINVAL;
1274 }
1275
1276 if (ep_idx < EP4) {
1277 *stalled =
1278 (0 != (ep_regs[ep_idx].ep_ctrl & EP_SEND_STALL));
1279 } else {
1280 *stalled = it82xx2_usb_extend_ep_ctrl(ep_idx,
1281 EXT_EP_CHECK_STALL);
1282 }
1283
1284 return 0;
1285 }
1286
usb_dc_ep_halt(uint8_t ep)1287 int usb_dc_ep_halt(uint8_t ep)
1288 {
1289 return usb_dc_ep_set_stall(ep);
1290 }
1291
usb_dc_ep_flush(uint8_t ep)1292 int usb_dc_ep_flush(uint8_t ep)
1293 {
1294 struct usb_it82xx2_regs *const usb_regs =
1295 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1296 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
1297
1298 uint8_t ep_idx = ep & EP_VALID_MASK;
1299 bool in = !!(ep & USB_EP_DIR_MASK);
1300
1301 if (((ep & EP_INVALID_MASK) != 0) || (ep_idx >= MAX_NUM_ENDPOINTS)) {
1302 return -EINVAL;
1303 }
1304
1305 if (ep_idx > FIFO_NUM) {
1306 ep_idx = ep_fifo_res[ep_idx % FIFO_NUM];
1307 }
1308
1309 in ? (ff_regs[ep_idx].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY) :
1310 (ff_regs[ep_idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY);
1311
1312 return 0;
1313 }
1314
usb_dc_ep_write(uint8_t ep,const uint8_t * buf,uint32_t data_len,uint32_t * ret_bytes)1315 int usb_dc_ep_write(uint8_t ep, const uint8_t *buf,
1316 uint32_t data_len, uint32_t *ret_bytes)
1317 {
1318 struct usb_it82xx2_regs *const usb_regs =
1319 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1320 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1321 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
1322 volatile uint8_t *ep_fifo_ctrl =
1323 usb_regs->fifo_regs[EP_EXT_REGS_BX].fifo_ctrl.ep_fifo_ctrl;
1324
1325 uint8_t ep_idx = ep & EP_VALID_MASK;
1326 uint8_t reg_idx = it82xx2_get_ep_fifo_ctrl_reg_idx(ep_idx);
1327 uint8_t reg_val = it82xx2_get_ep_fifo_ctrl_reg_val(ep_idx);
1328 uint8_t ep_fifo = (ep_idx > EP0) ?
1329 (ep_fifo_res[ep_idx % FIFO_NUM]) : 0;
1330 uint32_t idx;
1331
1332 if ((ep & EP_INVALID_MASK) != 0)
1333 return -EINVAL;
1334
1335 /* status IN */
1336 if ((ep_idx == EP0) && (data_len == 0) &&
1337 (udata0.now_token == SETUP_TOKEN)) {
1338 return 0;
1339 }
1340
1341 if (ep_idx >= MAX_NUM_ENDPOINTS) {
1342 return -EINVAL;
1343 }
1344
1345 /* clear fifo before write*/
1346 if (ep_idx == EP0) {
1347 ff_regs[ep_idx].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;
1348 }
1349
1350 if ((ep_idx == EP0) && (udata0.st_state == SETUP_ST)) {
1351 udata0.st_state = DIN_ST;
1352 }
1353
1354 /* select FIFO */
1355 if (ep_idx > EP0) {
1356
1357 k_sem_take(&udata0.ep_sem[ep_fifo-1], K_FOREVER);
1358
1359 /* select FIFO */
1360 ep_fifo_ctrl[reg_idx] |= reg_val;
1361 }
1362
1363 if (data_len > udata0.ep_data[ep_idx].mps) {
1364
1365 for (idx = 0 ; idx < udata0.ep_data[ep_idx].mps ; idx++) {
1366 ff_regs[ep_fifo].ep_tx_fifo_data = buf[idx];
1367 }
1368
1369 *ret_bytes = udata0.ep_data[ep_idx].mps;
1370 udata0.ep_data[ep_idx].remaining =
1371 data_len - udata0.ep_data[ep_idx].mps;
1372
1373 LOG_DBG("data_len: %d, Write Max Packets to TX FIFO(%d)",
1374 data_len, ep_idx);
1375 } else {
1376 for (idx = 0 ; idx < data_len ; idx++) {
1377 ff_regs[ep_fifo].ep_tx_fifo_data = buf[idx];
1378 }
1379
1380 *ret_bytes = data_len;
1381 udata0.ep_data[ep_idx].remaining = 0;
1382 LOG_DBG("Write %d Packets to TX FIFO(%d)", data_len, ep_idx);
1383 }
1384
1385 if (ep_idx > FIFO_NUM) {
1386 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
1387 }
1388
1389 ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
1390
1391 if (ep_fifo > EP0) {
1392 udata0.ep_ready[ep_fifo - 1] = true;
1393 }
1394
1395 LOG_DBG("Set EP%d Ready(%d)", ep_idx, __LINE__);
1396
1397 return 0;
1398 }
1399
1400 /* Read data from an OUT endpoint */
usb_dc_ep_read(uint8_t ep,uint8_t * buf,uint32_t max_data_len,uint32_t * read_bytes)1401 int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
1402 uint32_t *read_bytes)
1403 {
1404 struct usb_it82xx2_regs *const usb_regs =
1405 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1406 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1407 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
1408
1409 uint8_t ep_idx = ep & EP_VALID_MASK;
1410 uint8_t ep_fifo = 0;
1411 uint16_t rx_fifo_len;
1412
1413 if ((ep & EP_INVALID_MASK) != 0) {
1414 return -EINVAL;
1415 }
1416
1417 if (ep_regs[ep_idx].ep_status & EP_STATUS_ERROR) {
1418 LOG_WRN("EP Error Flag: 0x%02x", ep_regs[ep_idx].ep_status);
1419 }
1420
1421 if (max_data_len == 0) {
1422
1423 *read_bytes = 0;
1424
1425 if (ep_idx > EP0) {
1426 ep_regs[ep_idx].ep_ctrl |= ENDPOINT_RDY;
1427 LOG_DBG("Set EP%d Ready(%d)", ep_idx, __LINE__);
1428 }
1429
1430 return 0;
1431 }
1432
1433 if (ep_idx > EP0) {
1434 ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
1435 }
1436
1437 rx_fifo_len = (uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_lsb +
1438 (((uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_msb) << 8);
1439
1440 if (ep_idx == 0) {
1441 /* if ep0 check trans_type in OUT_TOKEN to
1442 * prevent wrong read_bytes cause memory error
1443 */
1444 if (udata0.st_state == STATUS_ST &&
1445 (ep_regs[EP0].ep_transtype_sts & DC_ALL_TRANS) == 0) {
1446
1447 *read_bytes = 0;
1448 return 0;
1449
1450 } else if (udata0.st_state == STATUS_ST) {
1451 /* status out but rx_fifo_len not zero */
1452 if (rx_fifo_len != 0) {
1453 LOG_ERR("Status OUT length not 0 (%d)",
1454 rx_fifo_len);
1455 }
1456 /* rx_fifo_len = 0; */
1457 *read_bytes = 0;
1458
1459 return 0;
1460 } else if (rx_fifo_len == 0 &&
1461 udata0.now_token == SETUP_TOKEN) {
1462 /* RX fifo error workaround */
1463
1464 /* wrong length(like 7),
1465 * may read wrong packet so clear fifo then return -1
1466 */
1467 LOG_ERR("Setup length 0, reset to 8");
1468 rx_fifo_len = 8;
1469 } else if (rx_fifo_len != 8 &&
1470 udata0.now_token == SETUP_TOKEN) {
1471 LOG_ERR("Setup length: %d", rx_fifo_len);
1472 /* clear rx fifo */
1473 ff_regs[EP0].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
1474
1475 return -EIO;
1476 }
1477 }
1478
1479 if (rx_fifo_len > max_data_len) {
1480 *read_bytes = max_data_len;
1481 for (int idx = 0 ; idx < max_data_len ; idx++) {
1482 buf[idx] = ff_regs[ep_fifo].ep_rx_fifo_data;
1483 }
1484
1485 LOG_DBG("Read Max (%d) Packets", max_data_len);
1486 } else {
1487
1488 *read_bytes = rx_fifo_len;
1489
1490 for (int idx = 0 ; idx < rx_fifo_len ; idx++) {
1491 buf[idx] = ff_regs[ep_fifo].ep_rx_fifo_data;
1492 }
1493
1494 if (ep_fifo == 0 &&
1495 udata0.now_token == SETUP_TOKEN) {
1496 LOG_DBG("RX buf: (%x)(%x)(%x)(%x)(%x)(%x)(%x)(%x)",
1497 buf[0], buf[1], buf[2], buf[3],
1498 buf[4], buf[5], buf[6], buf[7]);
1499 }
1500
1501 if (ep_fifo > EP0) {
1502 ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
1503 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
1504 LOG_DBG("(%d): Set EP%d Ready", __LINE__, ep_idx);
1505 udata0.ep_ready[ep_fifo - 1] = true;
1506 } else if (udata0.now_token == SETUP_TOKEN) {
1507
1508 if (!(buf[0] & USB_EP_DIR_MASK)) {
1509 /* Host to device transfer check */
1510 if (buf[6] != 0 || buf[7] != 0) {
1511 /* clear tx fifo */
1512 ff_regs[EP0].ep_tx_fifo_ctrl =
1513 FIFO_FORCE_EMPTY;
1514 /* set status IN after data OUT */
1515 ep_regs[EP0].ep_ctrl |=
1516 ENDPOINT_RDY | EP_OUTDATA_SEQ;
1517 LOG_DBG("Set EP%d Ready(%d)",
1518 ep_idx, __LINE__);
1519 } else {
1520 /* no_data_ctrl status */
1521
1522 /* clear tx fifo */
1523 ff_regs[EP0].ep_tx_fifo_ctrl =
1524 FIFO_FORCE_EMPTY;
1525 udata0.no_data_ctrl = true;
1526 }
1527 }
1528 }
1529
1530 }
1531
1532 return 0;
1533 }
1534
usb_dc_ep_read_wait(uint8_t ep,uint8_t * buf,uint32_t max_data_len,uint32_t * read_bytes)1535 int usb_dc_ep_read_wait(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
1536 uint32_t *read_bytes)
1537 {
1538 struct usb_it82xx2_regs *const usb_regs =
1539 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1540 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1541 struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
1542
1543 uint8_t ep_idx = ep & EP_VALID_MASK;
1544 uint8_t ep_fifo = 0;
1545 uint16_t rx_fifo_len;
1546
1547 if ((ep & EP_INVALID_MASK) != 0) {
1548 return -EINVAL;
1549 }
1550
1551 if (ep_idx >= MAX_NUM_ENDPOINTS) {
1552 LOG_ERR("(%d): Wrong Endpoint Index/Address", __LINE__);
1553 return -EINVAL;
1554 }
1555 /* Check if OUT ep */
1556 if (!!(ep & USB_EP_DIR_MASK)) {
1557 LOG_ERR("Wrong Endpoint Direction");
1558 return -EINVAL;
1559 }
1560
1561 if (ep_idx > EP0) {
1562 ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
1563 }
1564
1565 if (ep_regs[ep_fifo].ep_status & EP_STATUS_ERROR) {
1566 LOG_WRN("EP error flag(%02x)", ep_regs[ep_fifo].ep_status);
1567 }
1568
1569 rx_fifo_len = (uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_lsb +
1570 (((uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_msb) << 8);
1571
1572 LOG_DBG("ep_read_wait (EP: %d), len: %d", ep_idx, rx_fifo_len);
1573
1574 *read_bytes = (rx_fifo_len > max_data_len) ?
1575 max_data_len : rx_fifo_len;
1576
1577 for (int idx = 0 ; idx < *read_bytes ; idx++) {
1578 buf[idx] = ff_regs[ep_fifo].ep_rx_fifo_data;
1579 }
1580
1581 LOG_DBG("Read %d packets", *read_bytes);
1582
1583 if (ep_idx > EP0) {
1584 LOG_DBG("RX buf[0]: 0x%02X", buf[0]);
1585 }
1586
1587 return 0;
1588 }
1589
usb_dc_ep_read_continue(uint8_t ep)1590 int usb_dc_ep_read_continue(uint8_t ep)
1591 {
1592 struct usb_it82xx2_regs *const usb_regs =
1593 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1594 struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
1595
1596 uint8_t ep_idx = ep & EP_VALID_MASK;
1597 uint8_t ep_fifo = 2;
1598
1599 if ((ep & EP_INVALID_MASK) != 0) {
1600 return -EINVAL;
1601 }
1602
1603 if (ep_idx >= MAX_NUM_ENDPOINTS) {
1604 LOG_ERR("(%d): Wrong Endpoint Index/Address", __LINE__);
1605 return -EINVAL;
1606 }
1607
1608 /* Check if OUT ep */
1609 if (!!(ep & USB_EP_DIR_MASK)) {
1610 LOG_ERR("Wrong Endpoint Direction");
1611 return -EINVAL;
1612 }
1613
1614 if (ep_idx > EP0) {
1615 ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
1616 }
1617
1618 it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
1619 ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
1620 udata0.ep_ready[ep_fifo - 1] = true;
1621 LOG_DBG("EP(%d) Read Continue", ep_idx);
1622 return 0;
1623 }
1624
1625
usb_dc_ep_mps(const uint8_t ep)1626 int usb_dc_ep_mps(const uint8_t ep)
1627 {
1628 uint8_t ep_idx = ep & EP_VALID_MASK;
1629
1630 if ((ep & EP_INVALID_MASK) != 0) {
1631 return -EINVAL;
1632 }
1633
1634 if (ep_idx >= MAX_NUM_ENDPOINTS) {
1635 LOG_ERR("(%d): Wrong Endpoint Index/Address", __LINE__);
1636 return -EINVAL;
1637 }
1638 /* Not configured, return length 0 */
1639 if (udata0.ep_data[ep_idx].ep_status < EP_CONFIG) {
1640 LOG_WRN("(%d)EP not set", __LINE__);
1641 return 0;
1642 }
1643
1644 return udata0.ep_data[ep_idx].mps;
1645 }
1646
usb_dc_wakeup_request(void)1647 int usb_dc_wakeup_request(void)
1648 {
1649 int ret;
1650 struct usb_it82xx2_regs *const usb_regs =
1651 (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
1652
1653 if (udata0.suspended) {
1654
1655 usb_regs->dc_control =
1656 DC_GLOBAL_ENABLE | DC_FULL_SPEED_LINE_POLARITY |
1657 DC_FULL_SPEED_LINE_RATE | DC_DIRECT_CONTROL |
1658 DC_TX_LINE_STATE_DM | DC_CONNECT_TO_HOST;
1659
1660 /* The remote wakeup device must hold the resume signal for */
1661 /* at least 1 ms but for no more than 15 ms */
1662 k_msleep(2);
1663
1664 usb_regs->dc_control =
1665 DC_GLOBAL_ENABLE | DC_FULL_SPEED_LINE_POLARITY |
1666 DC_FULL_SPEED_LINE_RATE | DC_CONNECT_TO_HOST;
1667
1668 ret = k_sem_take(&udata0.suspended_sem, K_MSEC(500));
1669 if (ret < 0) {
1670 LOG_ERR("failed to wake up host");
1671 }
1672 }
1673 return 0;
1674 }
1675
it82xx2_usb_dc_init(const struct device * dev)1676 static int it82xx2_usb_dc_init(const struct device *dev)
1677 {
1678 const struct usb_it82xx2_config *cfg = dev->config;
1679
1680 int status = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
1681
1682 if (status < 0) {
1683 LOG_ERR("Failed to configure USB pins");
1684 return status;
1685 }
1686
1687 /* Initializing WU90 (USB D+) */
1688 it8xxx2_usb_dc_wuc_init(dev);
1689
1690 udata0.dev = dev;
1691
1692 return 0;
1693 }
1694
1695 DEVICE_DT_INST_DEFINE(0,
1696 &it82xx2_usb_dc_init,
1697 NULL,
1698 &udata0,
1699 &ucfg0,
1700 POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
1701 NULL);
1702