drivers/usbmisc/fusb303.c: Toggle enable bit off/on after detaching
This commit is contained in:
parent
d3cedfb823
commit
ddcc6dd501
@ -92,7 +92,7 @@
|
||||
int ret = fusb303_getreg((priv), (x)); \
|
||||
if (ret < 0) \
|
||||
{ \
|
||||
fusb303_err("ERROR: Failed to read %s(0x%02X)\n", #x, (x)); \
|
||||
fusb303_err("ERROR: Failed to read %s(0x%02X)\n", #x, (x)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@ -121,7 +121,8 @@ struct fusb303_dev_s
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FUSB303
|
||||
static int fusb303_dumpregs(FAR struct fusb303_dev_s *priv);
|
||||
static int fusb303_dumpregs(FAR const char *funcname,
|
||||
FAR struct fusb303_dev_s *priv);
|
||||
#endif
|
||||
static int fusb303_open(FAR struct file *filep);
|
||||
static int fusb303_close(FAR struct file *filep);
|
||||
@ -313,8 +314,10 @@ static int fusb303_putreg(FAR struct fusb303_dev_s *priv, uint8_t regaddr,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FUSB303
|
||||
static int noinline_function fusb303_dumpregs(FAR struct fusb303_dev_s *priv)
|
||||
static int noinline_function fusb303_dumpregs(FAR const char *funcname,
|
||||
FAR struct fusb303_dev_s *priv)
|
||||
{
|
||||
fusb303_info("'%s':\n", funcname);
|
||||
DUMPREG(priv, FUSB303_DEV_ID_REG);
|
||||
DUMPREG(priv, FUSB303_DEV_TYPE_REG);
|
||||
DUMPREG(priv, FUSB303_PORTROLE_REG);
|
||||
@ -495,11 +498,56 @@ static int fusb303_setup(FAR struct fusb303_dev_s *priv,
|
||||
|
||||
err_out:
|
||||
#ifdef CONFIG_DEBUG_FUSB303
|
||||
fusb303_dumpregs(priv);
|
||||
fusb303_dumpregs("fusb303_setup", priv);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fusb303_toggle_control1_enable
|
||||
*
|
||||
* Description:
|
||||
* Switch enable flag off and then on.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fusb303_toggle_control1_enable(FAR struct fusb303_dev_s *priv)
|
||||
{
|
||||
int regval;
|
||||
int ret;
|
||||
|
||||
regval = fusb303_getreg(priv, FUSB303_CONTROL1_REG);
|
||||
if (regval < 0)
|
||||
{
|
||||
fusb303_err("ERROR: Failed to read CONTROL1 register\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(regval & CONTROL1_ENABLE))
|
||||
{
|
||||
/* Not enabled, skip toggling. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = fusb303_putreg(priv, FUSB303_CONTROL1_REG,
|
||||
regval & ~CONTROL1_ENABLE);
|
||||
if (ret < 0)
|
||||
{
|
||||
fusb303_err("ERROR: Failed to write CONTROL1 register\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fusb303_putreg(priv, FUSB303_CONTROL1_REG, regval);
|
||||
if (ret < 0)
|
||||
{
|
||||
fusb303_err("ERROR: Failed to write CONTROL1 register\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fusb303_set_mode
|
||||
*
|
||||
@ -728,18 +776,30 @@ static ssize_t fusb303_read(FAR struct file *filep, FAR char *buffer,
|
||||
return ret;
|
||||
}
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->int_pending = false;
|
||||
leave_critical_section(flags);
|
||||
|
||||
ptr->status = fusb303_getreg(priv, FUSB303_STATUS_REG);
|
||||
ptr->status1 = fusb303_getreg(priv, FUSB303_STATUS1_REG);
|
||||
ptr->dev_type = fusb303_getreg(priv, FUSB303_TYPE_REG);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FUSB303
|
||||
fusb303_dumpregs(priv);
|
||||
fusb303_dumpregs("fusb303_read", priv);
|
||||
#endif
|
||||
|
||||
if (!(ptr->status & STATUS_ATTACH) ||
|
||||
(ptr->status & STATUS_BC_LVL_3000) == STATUS_BC_LVL_UNATT)
|
||||
{
|
||||
/* Toggle enable bit when USB is not attached. This is needed to
|
||||
* enable attach interrupt when orientation of USB-C cable changes.
|
||||
*/
|
||||
|
||||
(void)fusb303_toggle_control1_enable(priv);
|
||||
|
||||
up_mdelay(1); /* Wait for initial interrupt. */
|
||||
}
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->int_pending = false;
|
||||
leave_critical_section(flags);
|
||||
|
||||
(void)fusb303_clear_interrupts(priv);
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
|
@ -183,7 +183,7 @@ enum fusb303_reset_e
|
||||
|
||||
enum fusb303_int_mask_e
|
||||
{
|
||||
INT_MASK_ATTACK = (1 << 0),
|
||||
INT_MASK_ATTACH = (1 << 0),
|
||||
INT_MASK_DETACH = (1 << 1),
|
||||
INT_MASK_BC_LVL = (1 << 2),
|
||||
INT_MASK_AUTOSNK = (1 << 3),
|
||||
|
Loading…
Reference in New Issue
Block a user