1
0
Fork 0

rM2: usb: chipidea: rM2 specific changes

Signed-off-by: Alistair Francis <alistair@alistair23.me>
5.4-rM2-2.2.x-imx-deep-sleep
Alistair Francis 2021-02-07 10:47:34 -08:00
parent d0fd59fb0a
commit 55043fe464
3 changed files with 63 additions and 2 deletions

View File

@ -128,6 +128,59 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci)
return role;
}
/*
* Handling vbus glitch
* We only need to consider glitch for without usb connection,
* With usb connection, we consider it as real disconnection.
*
* If the vbus can't be kept above B session valid for timeout value,
* we think it is a vbus glitch, otherwise it's a valid vbus.
*/
#define CI_VBUS_CONNECT_GLITCH_TIMEOUT_MS 300
#define CI_VBUS_CONNECT_TOTAL_TIMEOUT_MS 1000
#define CI_VBUS_GLITCH_COUNTER_RESET_VAL (CI_VBUS_CONNECT_GLITCH_TIMEOUT_MS/20)
static int ci_is_vbus_glitch(struct ci_hdrc *ci)
{
int glitch_counter = CI_VBUS_GLITCH_COUNTER_RESET_VAL;
int total_counter = CI_VBUS_CONNECT_TOTAL_TIMEOUT_MS/20;
dev_dbg(ci->dev,
"Running for max %d ms while checking for VBUS glitc\n",
CI_VBUS_CONNECT_TOTAL_TIMEOUT_MS);
dev_dbg(ci->dev,
"(expecting min %d ms with stable VBUS)\n",
CI_VBUS_CONNECT_GLITCH_TIMEOUT_MS);
do {
if (hw_read_otgsc(ci, OTGSC_AVV)) {
dev_dbg(ci->dev, "VBUS is valid, returning\n");
return 0;
} else if (!hw_read_otgsc(ci, OTGSC_BSV)) {
dev_dbg(ci->dev,
"B session glitch, resetting glitch counter\n");
glitch_counter = CI_VBUS_GLITCH_COUNTER_RESET_VAL;
dev_warn(ci->dev, "there is a vbus glitch\n");
} else {
glitch_counter--;
}
msleep(20);
total_counter--;
} while ((total_counter > 0) && (glitch_counter > 0));
if (glitch_counter > 0) {
dev_dbg(ci->dev,
"Unable to measure stable VBUS for %d ms\n",
CI_VBUS_CONNECT_GLITCH_TIMEOUT_MS);
return 1;
}
dev_dbg(ci->dev,
"%d ms with stable VBUS !\n",
CI_VBUS_CONNECT_GLITCH_TIMEOUT_MS);
return 0;
}
void ci_handle_vbus_connected(struct ci_hdrc *ci)
{
/*

View File

@ -1760,7 +1760,7 @@ static const struct usb_gadget_ops usb_gadget_ops = {
.wakeup = ci_udc_wakeup,
.set_selfpowered = ci_udc_selfpowered,
.pullup = ci_udc_pullup,
.vbus_draw = ci_udc_vbus_draw,
/*.vbus_draw = ci_udc_vbus_draw, */
.udc_start = ci_udc_start,
.udc_stop = ci_udc_stop,
.match_ep = ci_udc_match_ep,

View File

@ -820,6 +820,10 @@ static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data)
/* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */
spin_lock_irqsave(&usbmisc->lock, flags);
dev_dbg(data->dev, "Setting up USB PHY to check whether a charger is "
"connected to the USB port\n");
dev_dbg(data->dev, "(NOT checking whether the USB plug has been in "
"contact with each other)\n");
val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL;
writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
@ -827,7 +831,8 @@ static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data)
usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
spin_unlock_irqrestore(&usbmisc->lock, flags);
usleep_range(1000, 2000);
dev_dbg(data->dev, "Waiting 500 ms before reading status\n");
usleep_range(500000, 501000);
/* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */
val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
@ -835,6 +840,9 @@ static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data)
dev_dbg(data->dev, "It is a standard downstream port\n");
usb_phy->chg_type = SDP_TYPE;
}
else {
dev_dbg(data->dev, "It is NOT a standard downstream port\n");
}
return 0;
}