mirror of
https://github.com/LineageOS/android_kernel_samsung_msm8226.git
synced 2026-09-28 00:00:22 +02:00
usb: dwc3-msm: Add support for proprietary charger detection
Proprietary chargers pull D+/- to specific voltages between 2.0-3.3V (VLGC) for identification. The DM voltage may not exceed VLGC due to pull-down resistor. Hence a proprietary charger is detected as a Standard downstream port (SDP). Read line state to distinguish between SDP and proprietary charger. The DP voltage would exceed VLGC for proprietary chargers. CRs-fixed: 383075 Change-Id: Ic9afbdd0996a4c1c7a2af76cd99182d8ae5f3b68 Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
This commit is contained in:
@@ -1326,6 +1326,17 @@ static void dwc3_chg_enable_secondary_det(struct dwc3_msm *mdwc)
|
||||
dwc3_msm_write_readback(mdwc->base, CHARGING_DET_CTRL_REG, 0x3F, 0x34);
|
||||
}
|
||||
|
||||
static bool dwc3_chg_det_check_linestate(struct dwc3_msm *mdwc)
|
||||
{
|
||||
u32 chg_det;
|
||||
bool ret = false;
|
||||
|
||||
chg_det = dwc3_msm_read_reg(mdwc->base, CHARGING_DET_OUTPUT_REG);
|
||||
ret = chg_det & (3 << 8);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool dwc3_chg_det_check_output(struct dwc3_msm *mdwc)
|
||||
{
|
||||
u32 chg_det;
|
||||
@@ -1391,9 +1402,10 @@ static void dwc3_chg_block_reset(struct dwc3_msm *mdwc)
|
||||
static const char *chg_to_string(enum dwc3_chg_type chg_type)
|
||||
{
|
||||
switch (chg_type) {
|
||||
case USB_SDP_CHARGER: return "USB_SDP_CHARGER";
|
||||
case USB_DCP_CHARGER: return "USB_DCP_CHARGER";
|
||||
case USB_CDP_CHARGER: return "USB_CDP_CHARGER";
|
||||
case DWC3_SDP_CHARGER: return "USB_SDP_CHARGER";
|
||||
case DWC3_DCP_CHARGER: return "USB_DCP_CHARGER";
|
||||
case DWC3_CDP_CHARGER: return "USB_CDP_CHARGER";
|
||||
case DWC3_PROPRIETARY_CHARGER: return "USB_PROPRIETARY_CHARGER";
|
||||
default: return "INVALID_CHARGER";
|
||||
}
|
||||
}
|
||||
@@ -1423,6 +1435,14 @@ static void dwc3_chg_detect_work(struct work_struct *w)
|
||||
tmout = ++mdwc->dcd_retries == DWC3_CHG_DCD_MAX_RETRIES;
|
||||
if (is_dcd || tmout) {
|
||||
dwc3_chg_disable_dcd(mdwc);
|
||||
if (dwc3_chg_det_check_linestate(mdwc)) {
|
||||
dev_dbg(mdwc->dev, "proprietary charger\n");
|
||||
mdwc->charger.chg_type =
|
||||
DWC3_PROPRIETARY_CHARGER;
|
||||
mdwc->chg_state = USB_CHG_STATE_DETECTED;
|
||||
delay = 0;
|
||||
break;
|
||||
}
|
||||
dwc3_chg_enable_primary_det(mdwc);
|
||||
delay = DWC3_CHG_PRIMARY_DET_TIME;
|
||||
mdwc->chg_state = USB_CHG_STATE_DCD_DONE;
|
||||
@@ -1437,7 +1457,7 @@ static void dwc3_chg_detect_work(struct work_struct *w)
|
||||
delay = DWC3_CHG_SECONDARY_DET_TIME;
|
||||
mdwc->chg_state = USB_CHG_STATE_PRIMARY_DONE;
|
||||
} else {
|
||||
mdwc->charger.chg_type = USB_SDP_CHARGER;
|
||||
mdwc->charger.chg_type = DWC3_SDP_CHARGER;
|
||||
mdwc->chg_state = USB_CHG_STATE_DETECTED;
|
||||
delay = 0;
|
||||
}
|
||||
@@ -1445,9 +1465,9 @@ static void dwc3_chg_detect_work(struct work_struct *w)
|
||||
case USB_CHG_STATE_PRIMARY_DONE:
|
||||
vout = dwc3_chg_det_check_output(mdwc);
|
||||
if (vout)
|
||||
mdwc->charger.chg_type = USB_DCP_CHARGER;
|
||||
mdwc->charger.chg_type = DWC3_DCP_CHARGER;
|
||||
else
|
||||
mdwc->charger.chg_type = USB_CDP_CHARGER;
|
||||
mdwc->charger.chg_type = DWC3_CDP_CHARGER;
|
||||
mdwc->chg_state = USB_CHG_STATE_SECONDARY_DONE;
|
||||
/* fall through */
|
||||
case USB_CHG_STATE_SECONDARY_DONE:
|
||||
|
||||
@@ -482,7 +482,8 @@ static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
|
||||
power_supply_type = POWER_SUPPLY_TYPE_USB;
|
||||
else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
|
||||
power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
|
||||
else if (dotg->charger->chg_type == DWC3_DCP_CHARGER)
|
||||
else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
|
||||
dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
|
||||
power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
|
||||
else
|
||||
power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
@@ -685,6 +686,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
|
||||
/* Has charger been detected? If no detect it */
|
||||
switch (charger->chg_type) {
|
||||
case DWC3_DCP_CHARGER:
|
||||
case DWC3_PROPRIETARY_CHARGER:
|
||||
dev_dbg(phy->dev, "lpm, DCP charger\n");
|
||||
dwc3_otg_set_power(phy,
|
||||
DWC3_IDEV_CHG_MAX);
|
||||
|
||||
@@ -61,12 +61,15 @@ struct dwc3_otg {
|
||||
* DWC3_DCP_CHARGER Dedicated charger port (AC charger/ Wall charger).
|
||||
* DWC3_CDP_CHARGER Charging downstream port. Enumeration can happen and
|
||||
* 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.
|
||||
*/
|
||||
enum dwc3_chg_type {
|
||||
DWC3_INVALID_CHARGER = 0,
|
||||
DWC3_SDP_CHARGER,
|
||||
DWC3_DCP_CHARGER,
|
||||
DWC3_CDP_CHARGER,
|
||||
DWC3_PROPRIETARY_CHARGER,
|
||||
};
|
||||
|
||||
struct dwc3_charger {
|
||||
|
||||
Reference in New Issue
Block a user