From ab1ac5a5b9537674546a06611400146a72a60b34 Mon Sep 17 00:00:00 2001 From: lyz Date: Thu, 21 May 2015 10:15:00 +0800 Subject: [PATCH] usb: bc: fix usb charger type detect error in rapidly hotplug case for inno phy In device mode, when doing usb plug and unplug rapidly, there might be some problem with usb battery charger type detect, caused by line bounces and other connect problems, at this case, usb battery charger detect module prefer to report a battery cherger type that draw less current to make it saver for PMIC and downstream port safer. Signed-off-by: lyz --- drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c | 2 +- drivers/usb/dwc_otg_310/usbdev_bc.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c b/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c index 99b3dd7c35ef..e5f1c6d201d4 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c @@ -1637,7 +1637,7 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work) _pcd->conn_status++; if (pldata->bc_detect_cb != NULL) { pldata->bc_detect_cb(_pcd->vbus_status = - USB_BC_TYPE_DCP); + usb_battery_charger_detect(1)); } else { _pcd->vbus_status = USB_BC_TYPE_DCP; } diff --git a/drivers/usb/dwc_otg_310/usbdev_bc.c b/drivers/usb/dwc_otg_310/usbdev_bc.c index 648bd9349a48..3d99f8fbd052 100755 --- a/drivers/usb/dwc_otg_310/usbdev_bc.c +++ b/drivers/usb/dwc_otg_310/usbdev_bc.c @@ -210,7 +210,7 @@ enum bc_port_type usb_battery_charger_detect_inno(bool wait) { enum bc_port_type port_type = USB_BC_TYPE_DISCNT; int dcd_state = DCD_POSITIVE; - int timeout = 0, i = 0; + int timeout = 0, i = 0, filted_cpdet = 0; /* VBUS Valid detect */ if (BC_GET(INNO_BC_BVALID) && @@ -248,8 +248,22 @@ enum bc_port_type usb_battery_charger_detect_inno(bool wait) BC_SET(INNO_BC_IDMSINKEN, 1); udelay(T_BC_CHGDET_VALID); + /* + * Filter for Primary Detection, + * double check CPDET field + */ + timeout = T_BC_CHGDET_VALID; + while(timeout--) { + /* + * In rapidly hotplug case, it's more likely to + * distinguish SDP as DCP/CDP because of line + * bounce + */ + filted_cpdet += (BC_GET(INNO_BC_CPDET) ? 1 : -2); + udelay(1); + } /* SDP and CDP/DCP distinguish */ - if (BC_GET(INNO_BC_CPDET)) { + if (filted_cpdet > 0) { /* Turn off VDPSRC */ BC_SET(INNO_BC_VDPSRCEN, 0); BC_SET(INNO_BC_IDMSINKEN, 0); -- 2.34.1