mpfs_usb: Add mpfs_vbus_detect

External function to query vbus status. Reading from the block requires
the clock, but if no devices are open -> vbus detect does not work.

This creates a chicken / egg problem, if vbus detect is used to start
the usb device.
This commit is contained in:
Ville Juven 2023-05-30 15:08:33 +03:00 committed by Xiang Xiao
parent 3fea2923d7
commit d566b7e2c7
2 changed files with 67 additions and 2 deletions

View File

@ -228,6 +228,7 @@ static void mpfs_epset_reset(struct mpfs_usbdev_s *priv, uint16_t epset);
****************************************************************************/
static struct mpfs_usbdev_s g_usbd;
static uint8_t g_clkrefs;
static const struct usbdev_epops_s g_epops =
{
@ -433,7 +434,18 @@ static inline void mpfs_putreg8(uint8_t regval, uintptr_t regaddr)
static void mpfs_enableclk(void)
{
modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, 0, SYSREG_SUBBLK_CLOCK_CR_USB);
/* Handle the counter atomically */
irqstate_t flags = enter_critical_section();
if (g_clkrefs == 0)
{
modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, 0,
SYSREG_SUBBLK_CLOCK_CR_USB);
}
g_clkrefs++;
leave_critical_section(flags);
}
/****************************************************************************
@ -452,7 +464,18 @@ static void mpfs_enableclk(void)
static void mpfs_disableclk(void)
{
modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, SYSREG_SUBBLK_CLOCK_CR_USB, 0);
/* Handle the counter atomically */
irqstate_t flags = enter_critical_section();
g_clkrefs--;
if (g_clkrefs == 0)
{
modifyreg32(MPFS_SYSREG_SUBBLK_CLOCK_CR, SYSREG_SUBBLK_CLOCK_CR_USB,
0);
}
leave_critical_section(flags);
}
/****************************************************************************
@ -4001,3 +4024,29 @@ errout:
mpfs_usbuninitialize();
}
/****************************************************************************
* Name: mpfs_vbus_detect
*
* Description:
* Read the VBUS state from the USB OTG controller.
*
* Input Parameters:
* None
*
* Returned Value:
* true if VBUS is valid; false otherwise
*
****************************************************************************/
bool mpfs_vbus_detect(void)
{
uint8_t vbus;
/* Accessing the peripheral needs the clock */
mpfs_enableclk();
vbus = getreg8(MPFS_USB_DEV_CTRL) & DEV_CTRL_VBUS_MASK;
mpfs_disableclk();
return vbus == VBUS_ABOVE_VBUS_VALID;
}

View File

@ -63,6 +63,22 @@ extern "C"
void mpfs_usbinitialize(void);
/****************************************************************************
* Name: mpfs_vbus_detect
*
* Description:
* Read the VBUS state from the USB OTG controller.
*
* Input Parameters:
* None
*
* Returned Value:
* true if VBUS is valid; false otherwise
*
****************************************************************************/
bool mpfs_vbus_detect(void);
#undef EXTERN
#if defined(__cplusplus)
}