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