charge: Handle QC2.0 charger vbus rise 12V

some non-standard QC2.0 charger (e.g. Tronsmart) will rise
vbus to 12V when phone do HVDCP3 detect protocol.
So when vbus reach 12V, we disable HVDCP to workaround it.

refer to (CR)

Change-Id: I1a1fbf1715ac6fbd12a9cd550207b210f16a951d
Signed-off-by: chailu1 <chailu1@lenovo.com>
Reviewed-on: https://gerrit.mot.com/1709435
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Haijian Ma <mahj8@motorola.com>
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
chailu1 authored and Gilberto Gambugge committed 2023-06-01 00:47:13 -03:00
1 parent 4a8fffaf9c
commit fe183ea9c0
3 files changed
+48 -3

No files matched your search

+4
View File
@@ -648,6 +648,9 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node)
if (chg->chg_param.qc4_max_icl_ua <= 0) if (chg->chg_param.qc4_max_icl_ua <= 0)
chg->chg_param.qc4_max_icl_ua = MICRO_4PA; chg->chg_param.qc4_max_icl_ua = MICRO_4PA;
chg->ext_ovp_greater_12v = of_property_read_bool(node,
"mmi,ext-ovp-greater-12v");
return 0; return 0;
} }
@@ -4260,6 +4263,7 @@ static int smb5_probe(struct platform_device *pdev)
chg->connector_health = -EINVAL; chg->connector_health = -EINVAL;
chg->otg_present = false; chg->otg_present = false;
chg->main_fcc_max = -EINVAL; chg->main_fcc_max = -EINVAL;
chg->qc_usbov = false;
mutex_init(&chg->adc_lock); mutex_init(&chg->adc_lock);
chg->regmap = dev_get_regmap(chg->dev->parent, NULL); chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
+40 -2
View File
@@ -574,12 +574,12 @@ static const struct apsd_result smblib_apsd_results[] = {
[HVDCP2] = { [HVDCP2] = {
.name = "HVDCP2", .name = "HVDCP2",
.bit = DCP_CHARGER_BIT | QC_2P0_BIT, .bit = DCP_CHARGER_BIT | QC_2P0_BIT,
.pst = POWER_SUPPLY_TYPE_USB_DCP .pst = POWER_SUPPLY_TYPE_USB_HVDCP
}, },
[HVDCP3] = { [HVDCP3] = {
.name = "HVDCP3", .name = "HVDCP3",
.bit = DCP_CHARGER_BIT | QC_3P0_BIT, .bit = DCP_CHARGER_BIT | QC_3P0_BIT,
.pst = POWER_SUPPLY_TYPE_USB_DCP, .pst = POWER_SUPPLY_TYPE_USB_HVDCP_3,
}, },
}; };
@@ -1156,6 +1156,26 @@ void smblib_hvdcp_hw_inov_enable(struct smb_charger *chg, bool enable)
rc); rc);
} }
void smblib_hvdcp_enable_mmi(struct smb_charger *chg, bool enable)
{
int rc;
u8 mask;
if (chg->hvdcp_disable)
return;
mask = HVDCP_AUTH_ALG_EN_CFG_BIT | HVDCP_EN_BIT;
rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, mask,
enable ? mask : 0);
if (rc < 0)
smblib_err(chg, "MMI failed to write USBIN_OPTIONS_1_CFG rc=%d\n",
rc);
else
chg->hvdcp_is_disable = enable ? false : true;
return;
}
void smblib_hvdcp_exit_config(struct smb_charger *chg) void smblib_hvdcp_exit_config(struct smb_charger *chg)
{ {
u8 stat; u8 stat;
@@ -6875,6 +6895,14 @@ static void typec_src_removal(struct smb_charger *chg)
chg->qc2_unsupported_voltage = QC2_COMPLIANT; chg->qc2_unsupported_voltage = QC2_COMPLIANT;
} }
if (chg->hvdcp_is_disable &&
((!chg->ext_ovp_greater_12v && !chg->qc_usbov) ||
(chg->ext_ovp_greater_12v && chg->qc_usbov))) {
smblib_err(chg, "Re-enable HVDCP as type-c removal\n");
smblib_hvdcp_enable_mmi(chg, true);
}
chg->qc_usbov = false;
if (chg->use_extcon) if (chg->use_extcon)
smblib_notify_device_mode(chg, false); smblib_notify_device_mode(chg, false);
@@ -7684,6 +7712,16 @@ irqreturn_t usbin_ov_irq_handler(int irq, void *data)
smblib_dbg(chg, PR_MISC, "USBOV debounce status %d\n", smblib_dbg(chg, PR_MISC, "USBOV debounce status %d\n",
chg->dbc_usbov); chg->dbc_usbov);
if ((!chg->qc_usbov) &&
(chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP ||
chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3)) {
smblib_err(chg, "QC vbus OV disable HVDCP\n");
chg->qc_usbov = true;
smblib_hvdcp_enable_mmi(chg, false);
smblib_rerun_apsd(chg);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
+4 -1
View File
@@ -738,7 +738,10 @@ struct smb_charger {
int qc2_max_pulses; int qc2_max_pulses;
enum qc2_non_comp_voltage qc2_unsupported_voltage; enum qc2_non_comp_voltage qc2_unsupported_voltage;
bool dbc_usbov; bool dbc_usbov;
bool qc_usbov;
bool hvdcp_is_disable;
/*if external ovp threshold greater than 12V*/
bool ext_ovp_greater_12v;
/* extcon for VBUS / ID notification to USB for uUSB */ /* extcon for VBUS / ID notification to USB for uUSB */
struct extcon_dev *extcon; struct extcon_dev *extcon;