drivers: udc_dwc2: rework vendor quirks
Rework and rename vendor quirks to better reflect where they intended to be called. Number of quirks probably not final and will be trimmed later. Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
parent
67cdccc1c2
commit
efb286dfdf
3 changed files with 83 additions and 32 deletions
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "udc_common.h"
|
||||
#include "udc_dwc2.h"
|
||||
#include "udc_dwc2_vendor_quirks.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -22,6 +21,7 @@
|
|||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(udc_dwc2, CONFIG_UDC_DRIVER_LOG_LEVEL);
|
||||
#include "udc_dwc2_vendor_quirks.h"
|
||||
|
||||
enum dwc2_drv_event_type {
|
||||
/* Trigger next transfer, must not be used for control OUT */
|
||||
|
@ -904,9 +904,7 @@ static void udc_dwc2_isr_handler(const struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
if (config->quirks != NULL && config->quirks->irq_clear != NULL) {
|
||||
config->quirks->irq_clear(dev);
|
||||
}
|
||||
(void)dwc2_quirk_irq_clear(dev);
|
||||
}
|
||||
|
||||
static int udc_dwc2_ep_enqueue(const struct device *dev,
|
||||
|
@ -1523,18 +1521,21 @@ static int udc_dwc2_enable(const struct device *dev)
|
|||
struct usb_dwc2_reg *const base = dwc2_get_base(dev);
|
||||
int err;
|
||||
|
||||
err = dwc2_quirk_pre_enable(dev);
|
||||
if (err) {
|
||||
LOG_ERR("Quirk pre enable failed %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = udc_dwc2_init_controller(dev);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call vendor-specific function to enable peripheral */
|
||||
if (config->quirks != NULL && config->quirks->pwr_on != NULL) {
|
||||
LOG_DBG("Enable vendor power");
|
||||
err = config->quirks->pwr_on(dev);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
err = dwc2_quirk_post_enable(dev);
|
||||
if (err) {
|
||||
LOG_ERR("Quirk post enable failed %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable global interrupt */
|
||||
|
@ -1553,6 +1554,7 @@ static int udc_dwc2_disable(const struct device *dev)
|
|||
const struct udc_dwc2_config *const config = dev->config;
|
||||
struct usb_dwc2_reg *const base = dwc2_get_base(dev);
|
||||
mem_addr_t dctl_reg = (mem_addr_t)&base->dctl;
|
||||
int err;
|
||||
|
||||
/* Enable soft disconnect */
|
||||
sys_set_bits(dctl_reg, USB_DWC2_DCTL_SFTDISCON);
|
||||
|
@ -1571,20 +1573,23 @@ static int udc_dwc2_disable(const struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
err = dwc2_quirk_disable(dev);
|
||||
if (err) {
|
||||
LOG_ERR("Quirk disable failed %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int udc_dwc2_init(const struct device *dev)
|
||||
{
|
||||
const struct udc_dwc2_config *const config = dev->config;
|
||||
int ret;
|
||||
|
||||
if (config->quirks != NULL && config->quirks->clk_enable != NULL) {
|
||||
LOG_DBG("Enable vendor clock");
|
||||
ret = config->quirks->clk_enable(dev);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
ret = dwc2_quirk_init(dev);
|
||||
if (ret) {
|
||||
LOG_ERR("Quirk init failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return dwc2_init_pinctrl(dev);
|
||||
|
@ -1592,6 +1597,14 @@ static int udc_dwc2_init(const struct device *dev)
|
|||
|
||||
static int udc_dwc2_shutdown(const struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dwc2_quirk_shutdown(dev);
|
||||
if (ret) {
|
||||
LOG_ERR("Quirk shutdown failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,17 @@
|
|||
|
||||
/* Vendor quirks per driver instance */
|
||||
struct dwc2_vendor_quirks {
|
||||
int (*clk_enable)(const struct device *dev);
|
||||
int (*clk_disable)(const struct device *dev);
|
||||
int (*pwr_on)(const struct device *dev);
|
||||
int (*pwr_off)(const struct device *dev);
|
||||
/* Called at the beginning of udc_dwc2_init() */
|
||||
int (*init)(const struct device *dev);
|
||||
/* Called on udc_dwc2_enable() before the controller is initialized */
|
||||
int (*pre_enable)(const struct device *dev);
|
||||
/* Called on udc_dwc2_enable() after the controller is initialized */
|
||||
int (*post_enable)(const struct device *dev);
|
||||
/* Called at the end of udc_dwc2_disable() */
|
||||
int (*disable)(const struct device *dev);
|
||||
/* Called at the end of udc_dwc2_shutdown() */
|
||||
int (*shutdown)(const struct device *dev);
|
||||
/* Called at the end of IRQ handling */
|
||||
int (*irq_clear)(const struct device *dev);
|
||||
};
|
||||
|
||||
|
@ -37,4 +44,24 @@ struct udc_dwc2_config {
|
|||
void (*irq_disable_func)(const struct device *dev);
|
||||
};
|
||||
|
||||
#define DWC2_QUIRK_FUNC_DEFINE(fname) \
|
||||
static inline int dwc2_quirk_##fname(const struct device *dev) \
|
||||
{ \
|
||||
const struct udc_dwc2_config *const config = dev->config; \
|
||||
struct dwc2_vendor_quirks *quirks = config->quirks; \
|
||||
\
|
||||
if (quirks != NULL && config->quirks->fname != NULL) { \
|
||||
return quirks->fname(dev); \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
DWC2_QUIRK_FUNC_DEFINE(init)
|
||||
DWC2_QUIRK_FUNC_DEFINE(pre_enable)
|
||||
DWC2_QUIRK_FUNC_DEFINE(post_enable)
|
||||
DWC2_QUIRK_FUNC_DEFINE(disable)
|
||||
DWC2_QUIRK_FUNC_DEFINE(shutdown)
|
||||
DWC2_QUIRK_FUNC_DEFINE(irq_clear)
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_USB_UDC_DWC2_H */
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/sys/sys_io.h>
|
||||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
|
||||
#include <usb_dwc2_hw.h>
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_fsotg)
|
||||
|
||||
#include <zephyr/sys/sys_io.h>
|
||||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#include <usb_dwc2_hw.h>
|
||||
|
||||
struct usb_dw_stm32_clk {
|
||||
const struct device *const dev;
|
||||
const struct stm32_pclken *const pclken;
|
||||
|
@ -26,7 +26,7 @@ struct usb_dw_stm32_clk {
|
|||
|
||||
#define DT_DRV_COMPAT snps_dwc2
|
||||
|
||||
static inline int clk_enable_stm32f4_fsotg(const struct usb_dw_stm32_clk *const clk)
|
||||
static inline int stm32f4_fsotg_enable_clk(const struct usb_dw_stm32_clk *const clk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -59,7 +59,7 @@ static inline int clk_enable_stm32f4_fsotg(const struct usb_dw_stm32_clk *const
|
|||
return clock_control_on(clk->dev, (void *)&clk->pclken[0]);
|
||||
}
|
||||
|
||||
static inline int pwr_on_stm32f4_fsotg(const struct device *dev)
|
||||
static inline int stm32f4_fsotg_enable_phy(const struct device *dev)
|
||||
{
|
||||
const struct udc_dwc2_config *const config = dev->config;
|
||||
mem_addr_t ggpio_reg = (mem_addr_t)&config->base->ggpio;
|
||||
|
@ -69,6 +69,16 @@ static inline int pwr_on_stm32f4_fsotg(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int stm32f4_fsotg_disable_phy(const struct device *dev)
|
||||
{
|
||||
const struct udc_dwc2_config *const config = dev->config;
|
||||
mem_addr_t ggpio_reg = (mem_addr_t)&config->base->ggpio;
|
||||
|
||||
sys_clear_bits(ggpio_reg, USB_DWC2_GGPIO_STM32_PWRDWN | USB_DWC2_GGPIO_STM32_VBDEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define QUIRK_STM32F4_FSOTG_DEFINE(n) \
|
||||
static const struct stm32_pclken pclken_##n[] = STM32_DT_INST_CLOCKS(n);\
|
||||
\
|
||||
|
@ -78,14 +88,15 @@ static inline int pwr_on_stm32f4_fsotg(const struct device *dev)
|
|||
.pclken_len = DT_INST_NUM_CLOCKS(n), \
|
||||
}; \
|
||||
\
|
||||
static int clk_enable_stm32f4_fsotg_##n(const struct device *dev) \
|
||||
static int stm32f4_fsotg_enable_clk_##n(const struct device *dev) \
|
||||
{ \
|
||||
return clk_enable_stm32f4_fsotg(&stm32f4_clk_##n); \
|
||||
return stm32f4_fsotg_enable_clk(&stm32f4_clk_##n); \
|
||||
} \
|
||||
\
|
||||
struct dwc2_vendor_quirks dwc2_vendor_quirks_##n = { \
|
||||
.clk_enable = clk_enable_stm32f4_fsotg_##n, \
|
||||
.pwr_on = pwr_on_stm32f4_fsotg, \
|
||||
.pre_enable = stm32f4_fsotg_enable_clk_##n, \
|
||||
.post_enable = stm32f4_fsotg_enable_phy, \
|
||||
.disable = stm32f4_fsotg_disable_phy, \
|
||||
.irq_clear = NULL, \
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue