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