drivers/usbmisc/fusb303.c: Toggle enable bit off/on after detaching

This commit is contained in:
Jussi Kivilinna 2019-05-31 07:40:06 -06:00 committed by Gregory Nutt
parent d3cedfb823
commit ddcc6dd501
2 changed files with 70 additions and 10 deletions

View File

@ -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);

View File

@ -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),