rM2: usb: chipidea: rM2 specific changes
Signed-off-by: Alistair Francis <alistair@alistair23.me>5.4-rM2-2.2.x-imx-deep-sleep
parent
d0fd59fb0a
commit
55043fe464
|
@ -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)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue