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