return role;
}
-#define CI_VBUS_CONNECT_TIMEOUT_MS 500
+/*
+ * 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_TIMEOUT_MS 300
static int ci_is_vbus_glitch(struct ci_hdrc *ci)
{
- /*
- * 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 higher than AVV in timeout value, we think
- * it is a vbus glitch
- */
- if (hw_wait_reg(ci, OP_OTGSC, OTGSC_AVV, OTGSC_AVV,
- CI_VBUS_CONNECT_TIMEOUT_MS)) {
- dev_warn(ci->dev, "there is a vbus glitch\n");
- return 1;
+ int i;
+
+ for (i = 0; i < CI_VBUS_CONNECT_TIMEOUT_MS/20; i++) {
+ if (hw_read_otgsc(ci, OTGSC_AVV)) {
+ return 0;
+ } else if (!hw_read_otgsc(ci, OTGSC_BSV)) {
+ dev_warn(ci->dev, "there is a vbus glitch\n");
+ return 1;
+ }
+ msleep(20);
}
return 0;
valid_vbus_change = true;
}
} else {
- if (ci->vbus_active || (ci_otg_is_fsm_mode(ci) &&
- ci->fsm.b_sess_vld))
+ if (ci->vbus_active && !ci_otg_is_fsm_mode(ci))
valid_vbus_change = true;
}
}
} else if (otg_int_src & OTGSC_BSVIS) {
hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
- ci->vbus_glitch_check_event = true;
if (!(otgsc & OTGSC_BSV) && fsm->b_sess_vld) {
+ ci->b_sess_valid_event = true;
fsm->b_sess_vld = 0;
if (fsm->id)
ci_otg_add_timer(ci, B_SSEND_SRP);
if (fsm->b_bus_req)
fsm->b_bus_req = 0;
+ } else {
+ ci->vbus_glitch_check_event = true;
}
} else if (otg_int_src & OTGSC_AVVIS) {
hw_write_otgsc(ci, OTGSC_AVVIS, OTGSC_AVVIS);