Loading Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt +7 −6 Original line number Diff line number Diff line Loading @@ -35,6 +35,13 @@ Charger specific properties: addition battery properties will be faked such that the device assumes normal operation. - qcom,use-extcon Usage: optional Value type: <empty> Definition: Boolean flag which specify that SMB2 will act as main charger to do extcon USB calls. If not defined, other charger driver can act as main charger to do extcon USB calls. - qcom,fcc-max-ua Usage: optional Value type: <u32> Loading Loading @@ -137,12 +144,6 @@ Charger specific properties: be based off battery voltage. For both SOC and battery voltage, charger receives the signal from FG to resume charging. - qcom,micro-usb Usage: optional Value type: <empty> Definition: Boolean flag which indicates that the platform only support micro usb port. - qcom,suspend-input-on-debug-batt Usage: optional Value type: <empty> Loading drivers/power/supply/qcom/qpnp-smb2.c +54 −23 Original line number Diff line number Diff line /* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -313,7 +313,8 @@ static int smb2_parse_dt(struct smb2 *chip) chip->dt.auto_recharge_soc = of_property_read_bool(node, "qcom,auto-recharge-soc"); chg->micro_usb_mode = of_property_read_bool(node, "qcom,micro-usb"); chg->use_extcon = of_property_read_bool(node, "qcom,use-extcon"); chg->dcp_icl_ua = chip->dt.usb_icl_ua; Loading Loading @@ -356,6 +357,8 @@ static enum power_supply_property smb2_usb_props[] = { POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_CONNECTOR_TYPE, POWER_SUPPLY_PROP_MOISTURE_DETECTED, }; static int smb2_usb_get_prop(struct power_supply *psy, Loading @@ -378,9 +381,9 @@ static int smb2_usb_get_prop(struct power_supply *psy, if (!val->intval) break; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) val->intval = 0; else val->intval = 1; Loading Loading @@ -409,7 +412,7 @@ static int smb2_usb_get_prop(struct power_supply *psy, val->intval = chg->real_charger_type; break; case POWER_SUPPLY_PROP_TYPEC_MODE: if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = POWER_SUPPLY_TYPEC_NONE; else if (chip->bad_part) val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; Loading @@ -417,13 +420,13 @@ static int smb2_usb_get_prop(struct power_supply *psy, val->intval = chg->typec_mode; break; case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = POWER_SUPPLY_TYPEC_PR_NONE; else rc = smblib_get_prop_typec_power_role(chg, val); break; case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION: if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = 0; else rc = smblib_get_prop_typec_cc_orientation(chg, val); Loading Loading @@ -471,6 +474,13 @@ static int smb2_usb_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->usb_icl_votable, USB_PSY_VOTER); break; case POWER_SUPPLY_PROP_CONNECTOR_TYPE: val->intval = chg->connector_type; break; case POWER_SUPPLY_PROP_MOISTURE_DETECTED: val->intval = get_client_vote(chg->disable_power_role_switch, MOISTURE_VOTER); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading @@ -493,7 +503,16 @@ static int smb2_usb_set_prop(struct power_supply *psy, mutex_lock(&chg->lock); if (!chg->typec_present) { switch (psp) { case POWER_SUPPLY_PROP_MOISTURE_DETECTED: vote(chg->disable_power_role_switch, MOISTURE_VOTER, val->intval > 0, 0); break; default: rc = -EINVAL; break; } goto unlock; } Loading Loading @@ -609,9 +628,9 @@ static int smb2_usb_port_get_prop(struct power_supply *psy, if (!val->intval) break; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) val->intval = 1; else val->intval = 0; Loading Loading @@ -1268,7 +1287,7 @@ static int smb2_init_vconn_regulator(struct smb2 *chip) struct regulator_config cfg = {}; int rc = 0; if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; chg->vconn_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vconn_vreg), Loading Loading @@ -1552,20 +1571,12 @@ static int smb2_init_hw(struct smb2 *chip) BATT_PROFILE_VOTER, true, chg->batt_profile_fv_uv); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER, chip->dt.hvdcp_disable, 0); vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, MICRO_USB_VOTER, chg->micro_usb_mode, 0); vote(chg->hvdcp_enable_votable, MICRO_USB_VOTER, chg->micro_usb_mode, 0); /* * AICL configuration: Loading Loading @@ -1595,7 +1606,17 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } if (chg->micro_usb_mode) /* Check USB connector type (typeC/microUSB) */ rc = smblib_read(chg, RID_CC_CONTROL_7_0_REG, &val); if (rc < 0) { dev_err(chg->dev, "Couldn't read RID_CC_CONTROL_7_0 rc=%d\n", rc); return rc; } chg->connector_type = (val & EN_MICRO_USB_MODE_BIT) ? POWER_SUPPLY_CONNECTOR_MICRO_USB : POWER_SUPPLY_CONNECTOR_TYPEC; if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) rc = smb2_disable_typec(chg); else rc = smb2_configure_typec(chg); Loading @@ -1605,6 +1626,16 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } /* Connector types based votes */ vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC), 0); vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC), 0); vote(chg->pd_disallowed_votable_indirect, MICRO_USB_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB), 0); vote(chg->hvdcp_enable_votable, MICRO_USB_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB), 0); /* configure VCONN for software control */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT, Loading Loading @@ -1845,7 +1876,7 @@ static int smb2_chg_config_init(struct smb2 *chip) break; case PM660_SUBTYPE: chip->chg.smb_version = PM660_SUBTYPE; chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA; chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA | OV_IRQ_WA_BIT; chg->param.freq_buck = pm660_params.freq_buck; chg->param.freq_boost = pm660_params.freq_boost; chg->chg_freq.freq_5V = 650; Loading drivers/power/supply/qcom/smb-lib.c +180 −59 Original line number Diff line number Diff line /* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -687,6 +687,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0); vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, false, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); Loading Loading @@ -979,8 +980,8 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) u8 load_cfg; bool override; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); if (rc < 0) { Loading Loading @@ -1008,6 +1009,101 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) return 0; } static int smblib_micro_usb_disable_power_role_switch(struct smb_charger *chg, bool disable) { int rc = 0; u8 power_role; power_role = disable ? TYPEC_DISABLE_CMD_BIT : 0; /* Disable pullup on CC1_ID pin and stop detection on CC pins */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, (uint8_t)TYPEC_POWER_ROLE_CMD_MASK, power_role); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); return rc; } if (disable) { /* configure TypeC mode */ rc = smblib_masked_write(chg, TYPE_C_CFG_REG, TYPE_C_OR_U_USB_BIT, 0); if (rc < 0) { smblib_err(chg, "Couldn't configure typec mode rc=%d\n", rc); return rc; } /* wait for FSM to enter idle state */ usleep_range(5000, 5100); /* configure micro USB mode */ rc = smblib_masked_write(chg, TYPE_C_CFG_REG, TYPE_C_OR_U_USB_BIT, TYPE_C_OR_U_USB_BIT); if (rc < 0) { smblib_err(chg, "Couldn't configure micro USB mode rc=%d\n", rc); return rc; } } return rc; } static int __smblib_set_prop_typec_power_role(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0; u8 power_role; switch (val->intval) { case POWER_SUPPLY_TYPEC_PR_NONE: power_role = TYPEC_DISABLE_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_DUAL: power_role = 0; break; case POWER_SUPPLY_TYPEC_PR_SINK: power_role = UFP_EN_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_SOURCE: power_role = DFP_EN_CMD_BIT; break; default: smblib_err(chg, "power role %d not supported\n", val->intval); return -EINVAL; } if (power_role == UFP_EN_CMD_BIT) { /* disable PBS workaround when forcing sink mode */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0x0); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } else { /* restore it back to 0xA5 */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0xA5); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, power_role); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); return rc; } return rc; } /********************* * VOTABLE CALLBACKS * *********************/ Loading Loading @@ -1248,6 +1344,31 @@ static int smblib_typec_irq_disable_vote_callback(struct votable *votable, return 0; } static int smblib_disable_power_role_switch_callback(struct votable *votable, void *data, int disable, const char *client) { struct smb_charger *chg = data; union power_supply_propval pval; int rc = 0; if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { rc = smblib_micro_usb_disable_power_role_switch(chg, disable); } else { pval.intval = disable ? POWER_SUPPLY_TYPEC_PR_SINK : POWER_SUPPLY_TYPEC_PR_DUAL; rc = __smblib_set_prop_typec_power_role(chg, &pval); } if (rc) smblib_err(chg, "power_role_switch = %s failed, rc=%d\n", disable ? "disabled" : "enabled", rc); else smblib_dbg(chg, PR_MISC, "power_role_switch = %s\n", disable ? "disabled" : "enabled"); return rc; } /******************* * VCONN REGULATOR * * *****************/ Loading Loading @@ -2655,52 +2776,11 @@ int smblib_set_prop_boost_current(struct smb_charger *chg, int smblib_set_prop_typec_power_role(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0; u8 power_role; switch (val->intval) { case POWER_SUPPLY_TYPEC_PR_NONE: power_role = TYPEC_DISABLE_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_DUAL: power_role = 0; break; case POWER_SUPPLY_TYPEC_PR_SINK: power_role = UFP_EN_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_SOURCE: power_role = DFP_EN_CMD_BIT; break; default: smblib_err(chg, "power role %d not supported\n", val->intval); return -EINVAL; } if (power_role == UFP_EN_CMD_BIT) { /* disable PBS workaround when forcing sink mode */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0x0); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } else { /* restore it back to 0xA5 */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0xA5); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } /* Check if power role switch is disabled */ if (!get_effective_result(chg->disable_power_role_switch)) return __smblib_set_prop_typec_power_role(chg, val); rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, power_role); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); return rc; } return rc; return 0; } int smblib_set_prop_pd_voltage_min(struct smb_charger *chg, Loading Loading @@ -3455,7 +3535,7 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); } if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) smblib_micro_usb_plugin(chg, vbus_rising); power_supply_changed(chg->usb_psy); Loading Loading @@ -3528,6 +3608,33 @@ static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg, rising ? "rising" : "falling"); } #define MICRO_10P3V 10300000 static void smblib_check_ov_condition(struct smb_charger *chg) { union power_supply_propval pval = {0, }; int rc; if (chg->wa_flags & OV_IRQ_WA_BIT) { rc = power_supply_get_property(chg->usb_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get current voltage, rc=%d\n", rc); return; } if (pval.intval > MICRO_10P3V) { smblib_err(chg, "USBIN OV detected\n"); vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, true, 0); pval.intval = POWER_SUPPLY_DP_DM_FORCE_5V; rc = power_supply_set_property(chg->batt_psy, POWER_SUPPLY_PROP_DP_DM, &pval); return; } } } #define QC3_PULSES_FOR_6V 5 #define QC3_PULSES_FOR_9V 20 #define QC3_PULSES_FOR_12V 35 Loading @@ -3537,6 +3644,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) u8 stat; int pulses; smblib_check_ov_condition(chg); power_supply_changed(chg->usb_main_psy); if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); Loading Loading @@ -3774,13 +3882,11 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) switch (apsd_result->bit) { case SDP_CHARGER_BIT: case CDP_CHARGER_BIT: if (chg->micro_usb_mode) extcon_set_state_sync(chg->extcon, EXTCON_USB, true); /* if not DCP then no hvdcp timeout happens. Enable pd here */ /* if not DCP, Enable pd here */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); if (chg->use_extcon) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB || chg->use_extcon) smblib_notify_device_mode(chg, true); break; case OCP_CHARGER_BIT: Loading Loading @@ -3816,7 +3922,8 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data) } smblib_dbg(chg, PR_REGISTER, "APSD_STATUS = 0x%02x\n", stat); if (chg->micro_usb_mode && (stat & APSD_DTC_STATUS_DONE_BIT) if ((chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) && (stat & APSD_DTC_STATUS_DONE_BIT) && !chg->uusb_apsd_rerun_done) { /* * Force re-run APSD to handle slow insertion related Loading Loading @@ -4042,6 +4149,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) int rc; struct smb_irq_data *data; struct storm_watch *wdata; union power_supply_propval val; chg->cc2_detach_wa_active = false; Loading Loading @@ -4080,6 +4188,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) /* reset hvdcp voters */ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, true, 0); vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, false, 0); /* reset power delivery voters */ vote(chg->pd_allowed_votable, PD_VOTER, false, 0); Loading Loading @@ -4165,8 +4274,8 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) rc); /* enable DRP */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, 0); val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) smblib_err(chg, "Couldn't enable DRP rc=%d\n", rc); Loading Loading @@ -4335,7 +4444,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; if (chg->micro_usb_mode) { if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { cancel_delayed_work_sync(&chg->uusb_otg_work); vote(chg->awake_votable, OTG_DELAY_VOTER, true, 0); smblib_dbg(chg, PR_INTERRUPT, "Scheduling OTG work\n"); Loading Loading @@ -4747,7 +4856,7 @@ static void smblib_vconn_oc_work(struct work_struct *work) int rc, i; u8 stat; if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) return; smblib_err(chg, "over-current detected on VCONN\n"); Loading Loading @@ -5052,6 +5161,16 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } chg->disable_power_role_switch = create_votable("DISABLE_POWER_ROLE_SWITCH", VOTE_SET_ANY, smblib_disable_power_role_switch_callback, chg); if (IS_ERR(chg->disable_power_role_switch)) { rc = PTR_ERR(chg->disable_power_role_switch); return rc; } return rc; } Loading @@ -5077,6 +5196,8 @@ static void smblib_destroy_votables(struct smb_charger *chg) destroy_votable(chg->hvdcp_hw_inov_dis_votable); if (chg->typec_irq_disable_votable) destroy_votable(chg->typec_irq_disable_votable); if (chg->disable_power_role_switch) destroy_votable(chg->disable_power_role_switch); } static void smblib_iio_deinit(struct smb_charger *chg) Loading drivers/power/supply/qcom/smb-lib.h +6 −2 Original line number Diff line number Diff line /* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -68,6 +68,8 @@ enum print_reason { #define OTG_VOTER "OTG_VOTER" #define PL_FCC_LOW_VOTER "PL_FCC_LOW_VOTER" #define WBC_VOTER "WBC_VOTER" #define OV_VOTER "OV_VOTER" #define MOISTURE_VOTER "MOISTURE_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 Loading @@ -86,6 +88,7 @@ enum { TYPEC_CC2_REMOVAL_WA_BIT = BIT(2), QC_AUTH_INTERRUPT_WA_BIT = BIT(3), OTG_WA = BIT(4), OV_IRQ_WA_BIT = BIT(5), }; enum smb_irq_index { Loading Loading @@ -291,6 +294,7 @@ struct smb_charger { struct votable *hvdcp_hw_inov_dis_votable; struct votable *usb_irq_enable_votable; struct votable *typec_irq_disable_votable; struct votable *disable_power_role_switch; /* work */ struct work_struct bms_update_work; Loading Loading @@ -324,7 +328,7 @@ struct smb_charger { bool sw_jeita_enabled; bool is_hdc; bool chg_done; bool micro_usb_mode; bool connector_type; bool otg_en; bool vconn_en; bool suspend_input_on_debug_batt; Loading Loading
Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt +7 −6 Original line number Diff line number Diff line Loading @@ -35,6 +35,13 @@ Charger specific properties: addition battery properties will be faked such that the device assumes normal operation. - qcom,use-extcon Usage: optional Value type: <empty> Definition: Boolean flag which specify that SMB2 will act as main charger to do extcon USB calls. If not defined, other charger driver can act as main charger to do extcon USB calls. - qcom,fcc-max-ua Usage: optional Value type: <u32> Loading Loading @@ -137,12 +144,6 @@ Charger specific properties: be based off battery voltage. For both SOC and battery voltage, charger receives the signal from FG to resume charging. - qcom,micro-usb Usage: optional Value type: <empty> Definition: Boolean flag which indicates that the platform only support micro usb port. - qcom,suspend-input-on-debug-batt Usage: optional Value type: <empty> Loading
drivers/power/supply/qcom/qpnp-smb2.c +54 −23 Original line number Diff line number Diff line /* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -313,7 +313,8 @@ static int smb2_parse_dt(struct smb2 *chip) chip->dt.auto_recharge_soc = of_property_read_bool(node, "qcom,auto-recharge-soc"); chg->micro_usb_mode = of_property_read_bool(node, "qcom,micro-usb"); chg->use_extcon = of_property_read_bool(node, "qcom,use-extcon"); chg->dcp_icl_ua = chip->dt.usb_icl_ua; Loading Loading @@ -356,6 +357,8 @@ static enum power_supply_property smb2_usb_props[] = { POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_CONNECTOR_TYPE, POWER_SUPPLY_PROP_MOISTURE_DETECTED, }; static int smb2_usb_get_prop(struct power_supply *psy, Loading @@ -378,9 +381,9 @@ static int smb2_usb_get_prop(struct power_supply *psy, if (!val->intval) break; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) val->intval = 0; else val->intval = 1; Loading Loading @@ -409,7 +412,7 @@ static int smb2_usb_get_prop(struct power_supply *psy, val->intval = chg->real_charger_type; break; case POWER_SUPPLY_PROP_TYPEC_MODE: if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = POWER_SUPPLY_TYPEC_NONE; else if (chip->bad_part) val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; Loading @@ -417,13 +420,13 @@ static int smb2_usb_get_prop(struct power_supply *psy, val->intval = chg->typec_mode; break; case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = POWER_SUPPLY_TYPEC_PR_NONE; else rc = smblib_get_prop_typec_power_role(chg, val); break; case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION: if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) val->intval = 0; else rc = smblib_get_prop_typec_cc_orientation(chg, val); Loading Loading @@ -471,6 +474,13 @@ static int smb2_usb_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->usb_icl_votable, USB_PSY_VOTER); break; case POWER_SUPPLY_PROP_CONNECTOR_TYPE: val->intval = chg->connector_type; break; case POWER_SUPPLY_PROP_MOISTURE_DETECTED: val->intval = get_client_vote(chg->disable_power_role_switch, MOISTURE_VOTER); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading @@ -493,7 +503,16 @@ static int smb2_usb_set_prop(struct power_supply *psy, mutex_lock(&chg->lock); if (!chg->typec_present) { switch (psp) { case POWER_SUPPLY_PROP_MOISTURE_DETECTED: vote(chg->disable_power_role_switch, MOISTURE_VOTER, val->intval > 0, 0); break; default: rc = -EINVAL; break; } goto unlock; } Loading Loading @@ -609,9 +628,9 @@ static int smb2_usb_port_get_prop(struct power_supply *psy, if (!val->intval) break; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) val->intval = 1; else val->intval = 0; Loading Loading @@ -1268,7 +1287,7 @@ static int smb2_init_vconn_regulator(struct smb2 *chip) struct regulator_config cfg = {}; int rc = 0; if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; chg->vconn_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vconn_vreg), Loading Loading @@ -1552,20 +1571,12 @@ static int smb2_init_hw(struct smb2 *chip) BATT_PROFILE_VOTER, true, chg->batt_profile_fv_uv); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER, chip->dt.hvdcp_disable, 0); vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, MICRO_USB_VOTER, chg->micro_usb_mode, 0); vote(chg->hvdcp_enable_votable, MICRO_USB_VOTER, chg->micro_usb_mode, 0); /* * AICL configuration: Loading Loading @@ -1595,7 +1606,17 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } if (chg->micro_usb_mode) /* Check USB connector type (typeC/microUSB) */ rc = smblib_read(chg, RID_CC_CONTROL_7_0_REG, &val); if (rc < 0) { dev_err(chg->dev, "Couldn't read RID_CC_CONTROL_7_0 rc=%d\n", rc); return rc; } chg->connector_type = (val & EN_MICRO_USB_MODE_BIT) ? POWER_SUPPLY_CONNECTOR_MICRO_USB : POWER_SUPPLY_CONNECTOR_TYPEC; if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) rc = smb2_disable_typec(chg); else rc = smb2_configure_typec(chg); Loading @@ -1605,6 +1626,16 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } /* Connector types based votes */ vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC), 0); vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC), 0); vote(chg->pd_disallowed_votable_indirect, MICRO_USB_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB), 0); vote(chg->hvdcp_enable_votable, MICRO_USB_VOTER, (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB), 0); /* configure VCONN for software control */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT, Loading Loading @@ -1845,7 +1876,7 @@ static int smb2_chg_config_init(struct smb2 *chip) break; case PM660_SUBTYPE: chip->chg.smb_version = PM660_SUBTYPE; chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA; chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA | OV_IRQ_WA_BIT; chg->param.freq_buck = pm660_params.freq_buck; chg->param.freq_boost = pm660_params.freq_boost; chg->chg_freq.freq_5V = 650; Loading
drivers/power/supply/qcom/smb-lib.c +180 −59 Original line number Diff line number Diff line /* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -687,6 +687,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0); vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, false, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); Loading Loading @@ -979,8 +980,8 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) u8 load_cfg; bool override; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); if (rc < 0) { Loading Loading @@ -1008,6 +1009,101 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) return 0; } static int smblib_micro_usb_disable_power_role_switch(struct smb_charger *chg, bool disable) { int rc = 0; u8 power_role; power_role = disable ? TYPEC_DISABLE_CMD_BIT : 0; /* Disable pullup on CC1_ID pin and stop detection on CC pins */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, (uint8_t)TYPEC_POWER_ROLE_CMD_MASK, power_role); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); return rc; } if (disable) { /* configure TypeC mode */ rc = smblib_masked_write(chg, TYPE_C_CFG_REG, TYPE_C_OR_U_USB_BIT, 0); if (rc < 0) { smblib_err(chg, "Couldn't configure typec mode rc=%d\n", rc); return rc; } /* wait for FSM to enter idle state */ usleep_range(5000, 5100); /* configure micro USB mode */ rc = smblib_masked_write(chg, TYPE_C_CFG_REG, TYPE_C_OR_U_USB_BIT, TYPE_C_OR_U_USB_BIT); if (rc < 0) { smblib_err(chg, "Couldn't configure micro USB mode rc=%d\n", rc); return rc; } } return rc; } static int __smblib_set_prop_typec_power_role(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0; u8 power_role; switch (val->intval) { case POWER_SUPPLY_TYPEC_PR_NONE: power_role = TYPEC_DISABLE_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_DUAL: power_role = 0; break; case POWER_SUPPLY_TYPEC_PR_SINK: power_role = UFP_EN_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_SOURCE: power_role = DFP_EN_CMD_BIT; break; default: smblib_err(chg, "power role %d not supported\n", val->intval); return -EINVAL; } if (power_role == UFP_EN_CMD_BIT) { /* disable PBS workaround when forcing sink mode */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0x0); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } else { /* restore it back to 0xA5 */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0xA5); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, power_role); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); return rc; } return rc; } /********************* * VOTABLE CALLBACKS * *********************/ Loading Loading @@ -1248,6 +1344,31 @@ static int smblib_typec_irq_disable_vote_callback(struct votable *votable, return 0; } static int smblib_disable_power_role_switch_callback(struct votable *votable, void *data, int disable, const char *client) { struct smb_charger *chg = data; union power_supply_propval pval; int rc = 0; if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { rc = smblib_micro_usb_disable_power_role_switch(chg, disable); } else { pval.intval = disable ? POWER_SUPPLY_TYPEC_PR_SINK : POWER_SUPPLY_TYPEC_PR_DUAL; rc = __smblib_set_prop_typec_power_role(chg, &pval); } if (rc) smblib_err(chg, "power_role_switch = %s failed, rc=%d\n", disable ? "disabled" : "enabled", rc); else smblib_dbg(chg, PR_MISC, "power_role_switch = %s\n", disable ? "disabled" : "enabled"); return rc; } /******************* * VCONN REGULATOR * * *****************/ Loading Loading @@ -2655,52 +2776,11 @@ int smblib_set_prop_boost_current(struct smb_charger *chg, int smblib_set_prop_typec_power_role(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0; u8 power_role; switch (val->intval) { case POWER_SUPPLY_TYPEC_PR_NONE: power_role = TYPEC_DISABLE_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_DUAL: power_role = 0; break; case POWER_SUPPLY_TYPEC_PR_SINK: power_role = UFP_EN_CMD_BIT; break; case POWER_SUPPLY_TYPEC_PR_SOURCE: power_role = DFP_EN_CMD_BIT; break; default: smblib_err(chg, "power role %d not supported\n", val->intval); return -EINVAL; } if (power_role == UFP_EN_CMD_BIT) { /* disable PBS workaround when forcing sink mode */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0x0); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } else { /* restore it back to 0xA5 */ rc = smblib_write(chg, TM_IO_DTEST4_SEL, 0xA5); if (rc < 0) { smblib_err(chg, "Couldn't write to TM_IO_DTEST4_SEL rc=%d\n", rc); } } /* Check if power role switch is disabled */ if (!get_effective_result(chg->disable_power_role_switch)) return __smblib_set_prop_typec_power_role(chg, val); rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, power_role); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); return rc; } return rc; return 0; } int smblib_set_prop_pd_voltage_min(struct smb_charger *chg, Loading Loading @@ -3455,7 +3535,7 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); } if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) smblib_micro_usb_plugin(chg, vbus_rising); power_supply_changed(chg->usb_psy); Loading Loading @@ -3528,6 +3608,33 @@ static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg, rising ? "rising" : "falling"); } #define MICRO_10P3V 10300000 static void smblib_check_ov_condition(struct smb_charger *chg) { union power_supply_propval pval = {0, }; int rc; if (chg->wa_flags & OV_IRQ_WA_BIT) { rc = power_supply_get_property(chg->usb_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get current voltage, rc=%d\n", rc); return; } if (pval.intval > MICRO_10P3V) { smblib_err(chg, "USBIN OV detected\n"); vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, true, 0); pval.intval = POWER_SUPPLY_DP_DM_FORCE_5V; rc = power_supply_set_property(chg->batt_psy, POWER_SUPPLY_PROP_DP_DM, &pval); return; } } } #define QC3_PULSES_FOR_6V 5 #define QC3_PULSES_FOR_9V 20 #define QC3_PULSES_FOR_12V 35 Loading @@ -3537,6 +3644,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) u8 stat; int pulses; smblib_check_ov_condition(chg); power_supply_changed(chg->usb_main_psy); if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); Loading Loading @@ -3774,13 +3882,11 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) switch (apsd_result->bit) { case SDP_CHARGER_BIT: case CDP_CHARGER_BIT: if (chg->micro_usb_mode) extcon_set_state_sync(chg->extcon, EXTCON_USB, true); /* if not DCP then no hvdcp timeout happens. Enable pd here */ /* if not DCP, Enable pd here */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); if (chg->use_extcon) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB || chg->use_extcon) smblib_notify_device_mode(chg, true); break; case OCP_CHARGER_BIT: Loading Loading @@ -3816,7 +3922,8 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data) } smblib_dbg(chg, PR_REGISTER, "APSD_STATUS = 0x%02x\n", stat); if (chg->micro_usb_mode && (stat & APSD_DTC_STATUS_DONE_BIT) if ((chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) && (stat & APSD_DTC_STATUS_DONE_BIT) && !chg->uusb_apsd_rerun_done) { /* * Force re-run APSD to handle slow insertion related Loading Loading @@ -4042,6 +4149,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) int rc; struct smb_irq_data *data; struct storm_watch *wdata; union power_supply_propval val; chg->cc2_detach_wa_active = false; Loading Loading @@ -4080,6 +4188,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) /* reset hvdcp voters */ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, true, 0); vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, false, 0); /* reset power delivery voters */ vote(chg->pd_allowed_votable, PD_VOTER, false, 0); Loading Loading @@ -4165,8 +4274,8 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) rc); /* enable DRP */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, 0); val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) smblib_err(chg, "Couldn't enable DRP rc=%d\n", rc); Loading Loading @@ -4335,7 +4444,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; if (chg->micro_usb_mode) { if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { cancel_delayed_work_sync(&chg->uusb_otg_work); vote(chg->awake_votable, OTG_DELAY_VOTER, true, 0); smblib_dbg(chg, PR_INTERRUPT, "Scheduling OTG work\n"); Loading Loading @@ -4747,7 +4856,7 @@ static void smblib_vconn_oc_work(struct work_struct *work) int rc, i; u8 stat; if (chg->micro_usb_mode) if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) return; smblib_err(chg, "over-current detected on VCONN\n"); Loading Loading @@ -5052,6 +5161,16 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } chg->disable_power_role_switch = create_votable("DISABLE_POWER_ROLE_SWITCH", VOTE_SET_ANY, smblib_disable_power_role_switch_callback, chg); if (IS_ERR(chg->disable_power_role_switch)) { rc = PTR_ERR(chg->disable_power_role_switch); return rc; } return rc; } Loading @@ -5077,6 +5196,8 @@ static void smblib_destroy_votables(struct smb_charger *chg) destroy_votable(chg->hvdcp_hw_inov_dis_votable); if (chg->typec_irq_disable_votable) destroy_votable(chg->typec_irq_disable_votable); if (chg->disable_power_role_switch) destroy_votable(chg->disable_power_role_switch); } static void smblib_iio_deinit(struct smb_charger *chg) Loading
drivers/power/supply/qcom/smb-lib.h +6 −2 Original line number Diff line number Diff line /* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -68,6 +68,8 @@ enum print_reason { #define OTG_VOTER "OTG_VOTER" #define PL_FCC_LOW_VOTER "PL_FCC_LOW_VOTER" #define WBC_VOTER "WBC_VOTER" #define OV_VOTER "OV_VOTER" #define MOISTURE_VOTER "MOISTURE_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 Loading @@ -86,6 +88,7 @@ enum { TYPEC_CC2_REMOVAL_WA_BIT = BIT(2), QC_AUTH_INTERRUPT_WA_BIT = BIT(3), OTG_WA = BIT(4), OV_IRQ_WA_BIT = BIT(5), }; enum smb_irq_index { Loading Loading @@ -291,6 +294,7 @@ struct smb_charger { struct votable *hvdcp_hw_inov_dis_votable; struct votable *usb_irq_enable_votable; struct votable *typec_irq_disable_votable; struct votable *disable_power_role_switch; /* work */ struct work_struct bms_update_work; Loading Loading @@ -324,7 +328,7 @@ struct smb_charger { bool sw_jeita_enabled; bool is_hdc; bool chg_done; bool micro_usb_mode; bool connector_type; bool otg_en; bool vconn_en; bool suspend_input_on_debug_batt; Loading