1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_USB_DEVICE_USB_DC_DW_STM32_H
8 #define ZEPHYR_DRIVERS_USB_DEVICE_USB_DC_DW_STM32_H
9 
10 #include <stdint.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
13 
14 #include <usb_dwc2_hw.h>
15 
16 struct usb_dw_stm32_clk {
17 	const struct device *const dev;
18 	const struct stm32_pclken *const pclken;
19 	size_t pclken_len;
20 };
21 
clk_enable_st_stm32f4_fsotg(const struct usb_dw_stm32_clk * const clk)22 static inline int clk_enable_st_stm32f4_fsotg(const struct usb_dw_stm32_clk *const clk)
23 {
24 	int ret;
25 
26 	if (!device_is_ready(clk->dev)) {
27 		return -ENODEV;
28 	}
29 
30 	if (clk->pclken_len > 1) {
31 		uint32_t clk_rate;
32 
33 		ret = clock_control_configure(clk->dev,
34 					      (void *)&clk->pclken[1],
35 					      NULL);
36 		if (ret) {
37 			return ret;
38 		}
39 
40 		ret = clock_control_get_rate(clk->dev,
41 					     (void *)&clk->pclken[1],
42 					     &clk_rate);
43 		if (ret) {
44 			return ret;
45 		}
46 
47 		if (clk_rate != MHZ(48)) {
48 			return -ENOTSUP;
49 		}
50 	}
51 
52 	return clock_control_on(clk->dev, (void *)&clk->pclken[0]);
53 }
54 
pwr_on_st_stm32f4_fsotg(struct usb_dwc2_reg * const base)55 static inline int pwr_on_st_stm32f4_fsotg(struct usb_dwc2_reg *const base)
56 {
57 	base->ggpio |= USB_DWC2_GGPIO_STM32_PWRDWN | USB_DWC2_GGPIO_STM32_VBDEN;
58 
59 	return 0;
60 }
61 
62 #define QUIRK_ST_STM32F4_FSOTG_DEFINE(n)					\
63 	static const struct stm32_pclken pclken_##n[] = STM32_DT_INST_CLOCKS(n);\
64 										\
65 	static const struct usb_dw_stm32_clk stm32f4_clk_##n = {		\
66 		.dev = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),			\
67 		.pclken = pclken_##n,						\
68 		.pclken_len = DT_INST_NUM_CLOCKS(n),				\
69 	};									\
70 										\
71 	static int clk_enable_st_stm32f4_fsotg_##n(void)			\
72 	{									\
73 		return clk_enable_st_stm32f4_fsotg(&stm32f4_clk_##n);		\
74 	}
75 
76 #define USB_DW_QUIRK_ST_STM32F4_FSOTG_DEFINE(n)					\
77 	COND_CODE_1(DT_NODE_HAS_COMPAT(DT_DRV_INST(n), st_stm32f4_fsotg),	\
78 		    (QUIRK_ST_STM32F4_FSOTG_DEFINE(n)), ())
79 
80 #endif /* ZEPHYR_DRIVERS_USB_DEVICE_USB_DC_DW_STM32_H */
81