int dwc3_intel_byt_b_idle(struct dwc_otg2 *otg) { u32 gctl, tmp; enable_usb_phy(otg, false); dwc_otg_charger_hwdet(false); /* Disable hibernation mode by default */ gctl = otg_read(otg, GCTL); gctl &= ~GCTL_GBL_HIBERNATION_EN; otg_write(otg, GCTL, gctl); /* Reset ADP related registers */ otg_write(otg, ADPCFG, 0); otg_write(otg, ADPCTL, 0); otg_write(otg, ADPEVTEN, 0); tmp = otg_read(otg, ADPEVT); otg_write(otg, ADPEVT, tmp); otg_write(otg, OCFG, 0); otg_write(otg, OEVTEN, 0); tmp = otg_read(otg, OEVT); otg_write(otg, OEVT, tmp); otg_write(otg, OCTL, OCTL_PERI_MODE); /* Force config to device mode as default */ gctl = otg_read(otg, GCTL); gctl &= ~GCTL_PRT_CAP_DIR; gctl |= GCTL_PRT_CAP_DIR_DEV << GCTL_PRT_CAP_DIR_SHIFT; otg_write(otg, GCTL, gctl); mdelay(100); return 0; }
int dwc3_intel_b_idle(struct dwc_otg2 *otg) { u32 gctl, tmp; /* Disable hibernation mode by default */ gctl = otg_read(otg, GCTL); gctl &= ~GCTL_GBL_HIBERNATION_EN; otg_write(otg, GCTL, gctl); /* Reset ADP related registers */ otg_write(otg, ADPCFG, 0); otg_write(otg, ADPCTL, 0); otg_write(otg, ADPEVTEN, 0); tmp = otg_read(otg, ADPEVT); otg_write(otg, ADPEVT, tmp); otg_write(otg, OCFG, 0); otg_write(otg, OEVTEN, 0); tmp = otg_read(otg, OEVT); otg_write(otg, OEVT, tmp); /* Force config to otg mode as default. */ dwc3_switch_mode(otg, GCTL_PRT_CAP_DIR_OTG); if (!is_hybridvp(otg)) { dwc_otg_charger_hwdet(false); enable_usb_phy(otg, false); } mdelay(100); return 0; }
static enum power_supply_charger_cable_type dwc3_intel_byt_get_charger_type(struct dwc_otg2 *otg) { struct usb_phy *phy; u8 val, vdat_det, chgd_serx_dm; unsigned long timeout, interval; enum power_supply_charger_cable_type type = POWER_SUPPLY_CHARGER_TYPE_NONE; /* No need to do charger detection if not enabled */ if (!charger_detect_enable(otg)) return POWER_SUPPLY_CHARGER_TYPE_USB_SDP; phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!phy) { otg_err(otg, "Get USB2 PHY failed\n"); return POWER_SUPPLY_CHARGER_TYPE_NONE; } /* PHY Enable: * Power on PHY */ enable_usb_phy(otg, true); /* Wait 10ms (~5ms before PHY de-asserts DIR, * XXus for initial Link reg sync-up).*/ msleep(20); /* DCD Enable: Change OPMODE to 01 (Non-driving), * TermSel to 0, & * XcvrSel to 01 (enable FS xcvr) */ usb_phy_io_write(phy, FUNCCTRL_OPMODE(1) | FUNCCTRL_XCVRSELECT(1), TUSB1211_FUNC_CTRL_SET); usb_phy_io_write(phy, FUNCCTRL_OPMODE(2) | FUNCCTRL_XCVRSELECT(2) | FUNCCTRL_TERMSELECT, TUSB1211_FUNC_CTRL_CLR); /*Enable SW control*/ usb_phy_io_write(phy, PWCTRL_SW_CONTROL, TUSB1211_POWER_CONTROL_SET); /* Enable IDPSRC */ usb_phy_io_write(phy, VS3_CHGD_IDP_SRC_EN, TUSB1211_VENDOR_SPECIFIC3_SET); /* Check DCD result, use same polling parameter */ timeout = jiffies + msecs_to_jiffies(DATACON_TIMEOUT); interval = DATACON_INTERVAL * 1000; /* us */ /* DCD Check: * Delay 66.5 ms. (Note: * TIDP_SRC_ON + TCHGD_SERX_DEB = * 347.8us + 66.1ms). */ usleep_range(66500, 67000); while (!time_after(jiffies, timeout)) { /* Read DP logic level. */ val = usb_phy_io_read(phy, TUSB1211_VENDOR_SPECIFIC4); if (val < 0) { otg_err(otg, "ULPI read error! try again\n"); continue; } if (!(val & VS4_CHGD_SERX_DP)) { otg_info(otg, "Data contact detected!\n"); break; } /* Polling interval */ usleep_range(interval, interval + 2000); } /* Disable DP pullup (Idp_src) */ usb_phy_io_write(phy, VS3_CHGD_IDP_SRC_EN, TUSB1211_VENDOR_SPECIFIC3_CLR); /* SE1 Det Enable: * Read DP/DM logic level. Note: use DEBUG * because VS4 isn’t enabled in this situation. */ val = usb_phy_io_read(phy, TUSB1211_DEBUG); if (val < 0) otg_err(otg, "ULPI read error!\n"); val &= DEBUG_LINESTATE; /* If '11': SE1 detected; goto 'Cleanup'. * Else: goto 'Pri Det Enable'. */ if (val == 3) { type = POWER_SUPPLY_CHARGER_TYPE_SE1; goto cleanup; } /* Pri Det Enable: * Enable VDPSRC. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_SET); /* Wait >106.1ms (40ms for BC * Tvdpsrc_on, 66.1ms for TI CHGD_SERX_DEB). */ msleep(107); /* Pri Det Check: * Check if DM > VDATREF. */ vdat_det = usb_phy_io_read(phy, TUSB1211_POWER_CONTROL); if (vdat_det < 0) otg_err(otg, "ULPI read error!\n"); vdat_det &= PWCTRL_VDAT_DET; /* Check if DM<VLGC */ chgd_serx_dm = usb_phy_io_read(phy, TUSB1211_VENDOR_SPECIFIC4); if (chgd_serx_dm < 0) otg_err(otg, "ULPI read error!\n"); chgd_serx_dm &= VS4_CHGD_SERX_DM; /* If VDAT_DET==0 || CHGD_SERX_DM==1: SDP detected * If VDAT_DET==1 && CHGD_SERX_DM==0: CDP/DCP */ if (vdat_det == 0 || chgd_serx_dm == 1) type = POWER_SUPPLY_CHARGER_TYPE_USB_SDP; /* Disable VDPSRC. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_CLR); /* If SDP, goto “Cleanup”. * Else, goto “Sec Det Enable” */ if (type == POWER_SUPPLY_CHARGER_TYPE_USB_SDP) goto cleanup; /* Sec Det Enable: * delay 1ms. */ usleep_range(1000, 1500); /* Swap DP & DM */ usb_phy_io_write(phy, VS1_DATAPOLARITY, TUSB1211_VENDOR_SPECIFIC1_CLR); /* Enable 'VDMSRC'. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_SET); /* Wait >73ms (40ms for BC Tvdmsrc_on, 33ms for TI TVDPSRC_DEB) */ msleep(80); /* Sec Det Check: * Check if DP>VDATREF. */ val = usb_phy_io_read(phy, TUSB1211_POWER_CONTROL); if (val < 0) otg_err(otg, "ULPI read error!\n"); val &= PWCTRL_VDAT_DET; /* If VDAT_DET==0: CDP detected. * If VDAT_DET==1: DCP detected. */ if (!val) type = POWER_SUPPLY_CHARGER_TYPE_USB_CDP; else type = POWER_SUPPLY_CHARGER_TYPE_USB_DCP; /* Disable VDMSRC. */ usb_phy_io_write(phy, PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_CLR); /* Swap DP & DM. */ usb_phy_io_write(phy, VS1_DATAPOLARITY, TUSB1211_VENDOR_SPECIFIC1_SET); cleanup: /* If DCP detected, assert VDPSRC. */ if (type == POWER_SUPPLY_CHARGER_TYPE_USB_DCP) usb_phy_io_write(phy, PWCTRL_SW_CONTROL | PWCTRL_DP_VSRC_EN, TUSB1211_POWER_CONTROL_SET); usb_put_phy(phy); switch (type) { case POWER_SUPPLY_CHARGER_TYPE_ACA_DOCK: case POWER_SUPPLY_CHARGER_TYPE_ACA_A: case POWER_SUPPLY_CHARGER_TYPE_ACA_B: case POWER_SUPPLY_CHARGER_TYPE_ACA_C: case POWER_SUPPLY_CHARGER_TYPE_USB_DCP: case POWER_SUPPLY_CHARGER_TYPE_USB_CDP: case POWER_SUPPLY_CHARGER_TYPE_SE1: dwc_otg_charger_hwdet(true); break; default: break; }; return type; }