From: lyz Date: Thu, 21 May 2015 02:15:00 +0000 (+0800) Subject: usb: bc: fix usb charger type detect error in rapidly hotplug X-Git-Tag: firefly_0821_release~4051 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ab1ac5a5b9537674546a06611400146a72a60b34;p=firefly-linux-kernel-4.4.55.git 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 --- 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);