USB: dwc3: msm: add charger detection for floated D+ and D-

Floated charger means "D+/D- floated charger". According batt
charging spec 1.2, during primary detection, the DP voltage
is VDP_SRC, DM voltage may not exceed VDAT_REF, it's same to
standard downstream port(SDP). Introducing data contact
detection(DCD) here to distinguish between SDP and floated
charger. If DCD detected, it's SDP, otherwise floated charger
is detected. Also rename UNSUPPORTED charger as FLOATED charger
as data lines D+/D- are floating.

Change-Id: I0fd307c512f46331e6e1d80759c1585fc1db8a39
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 2600001..38c2630 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1557,7 +1557,7 @@
 	case DWC3_DCP_CHARGER:		return "USB_DCP_CHARGER";
 	case DWC3_CDP_CHARGER:		return "USB_CDP_CHARGER";
 	case DWC3_PROPRIETARY_CHARGER:	return "USB_PROPRIETARY_CHARGER";
-	case DWC3_UNSUPPORTED_CHARGER:	return "INVALID_CHARGER";
+	case DWC3_FLOATED_CHARGER:	return "USB_FLOATED_CHARGER";
 	default:			return "UNKNOWN_CHARGER";
 	}
 }
@@ -1571,6 +1571,7 @@
 {
 	struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm, chg_work.work);
 	bool is_dcd = false, tmout, vout;
+	static bool dcd;
 	unsigned long delay;
 
 	dev_dbg(mdwc->dev, "chg detection work\n");
@@ -1586,19 +1587,15 @@
 		is_dcd = dwc3_chg_check_dcd(mdwc);
 		tmout = ++mdwc->dcd_retries == DWC3_CHG_DCD_MAX_RETRIES;
 		if (is_dcd || tmout) {
+			if (is_dcd)
+				dcd = true;
+			else
+				dcd = false;
 			dwc3_chg_disable_dcd(mdwc);
+			usleep_range(1000, 1200);
 			if (dwc3_chg_det_check_linestate(mdwc)) {
-				dwc3_chg_enable_primary_det(mdwc);
-				usleep_range(1000, 1200);
-				vout = dwc3_chg_det_check_output(mdwc);
-				if (!vout)
-					mdwc->charger.chg_type =
-						DWC3_UNSUPPORTED_CHARGER;
-				else
-					mdwc->charger.chg_type =
+				mdwc->charger.chg_type =
 						DWC3_PROPRIETARY_CHARGER;
-				dwc3_msm_write_reg(mdwc->base,
-						CHARGING_DET_CTRL_REG, 0x0);
 				mdwc->chg_state = USB_CHG_STATE_DETECTED;
 				delay = 0;
 				break;
@@ -1617,7 +1614,15 @@
 			delay = DWC3_CHG_SECONDARY_DET_TIME;
 			mdwc->chg_state = USB_CHG_STATE_PRIMARY_DONE;
 		} else {
-			mdwc->charger.chg_type = DWC3_SDP_CHARGER;
+			/*
+			 * Detect floating charger only if propreitary
+			 * charger detection is enabled.
+			 */
+			if (!dcd && prop_chg_detect)
+				mdwc->charger.chg_type =
+						DWC3_FLOATED_CHARGER;
+			else
+				mdwc->charger.chg_type = DWC3_SDP_CHARGER;
 			mdwc->chg_state = USB_CHG_STATE_DETECTED;
 			delay = 0;
 		}
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 98c9b4c..1bc7757 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -726,8 +726,17 @@
 					phy->state = OTG_STATE_B_PERIPHERAL;
 					work = 1;
 					break;
-				case DWC3_UNSUPPORTED_CHARGER:
+				case DWC3_FLOATED_CHARGER:
 					dotg->charger_retry_count++;
+					/*
+					 * In case of floating charger, if
+					 * retry count equal to max retry count
+					 * notify PMIC about floating charger
+					 * and put Hw in low power mode. Else
+					 * perform charger detection again by
+					 * calling start_detection() with false
+					 * and then with true argument.
+					 */
 					if (dotg->charger_retry_count ==
 						max_chgr_retry_count) {
 						dwc3_otg_set_power(phy, 0);
diff --git a/drivers/usb/dwc3/dwc3_otg.h b/drivers/usb/dwc3/dwc3_otg.h
index b00468e..28573a1 100644
--- a/drivers/usb/dwc3/dwc3_otg.h
+++ b/drivers/usb/dwc3/dwc3_otg.h
@@ -64,6 +64,7 @@
  *                      IDEV_CHG_MAX can be drawn irrespective of USB state.
  * DWC3_PROPRIETARY_CHARGER A proprietary charger pull DP and DM to specific
  *                     voltages between 2.0-3.3v for identification.
+ * DWC3_FLOATED_CHARGER Non standard charger whose data lines are floating.
  */
 enum dwc3_chg_type {
 	DWC3_INVALID_CHARGER = 0,
@@ -71,7 +72,7 @@
 	DWC3_DCP_CHARGER,
 	DWC3_CDP_CHARGER,
 	DWC3_PROPRIETARY_CHARGER,
-	DWC3_UNSUPPORTED_CHARGER,
+	DWC3_FLOATED_CHARGER,
 };
 
 struct dwc3_charger {