Loading Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +6 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,12 @@ Charger specific properties: Definition: Boolean flag which when present enables stepwise change in FCC. The default stepping rate is 100mA/sec. - qcom,disable-suspend-on-collapse Usage: optional Value type: bool Definition: Boolean flag which when present disables suspend on collapse feature of charger hardware. ============================================= Second Level Nodes - SMB5 Charger Peripherals ============================================= Loading drivers/power/supply/qcom/qpnp-smb5.c +11 −5 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ struct smb_dt_props { int term_current_src; int term_current_thresh_hi_ma; int term_current_thresh_lo_ma; int disable_suspend_on_collapse; }; struct smb5 { Loading Loading @@ -531,6 +532,8 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) return rc; chip->dt.disable_suspend_on_collapse = of_property_read_bool(node, "qcom,disable-suspend-on-collapse"); return 0; } Loading Loading @@ -1767,7 +1770,7 @@ static int smb5_init_hw(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; int rc, type = 0; u8 val = 0; u8 val = 0, mask = 0; union power_supply_propval pval; if (chip->dt.no_battery) Loading Loading @@ -1935,11 +1938,14 @@ static int smb5_init_hw(struct smb5 *chip) * start from min and AICL ADC disable, and enable aicl rerun */ if (chg->smb_version != PMI632_SUBTYPE) { mask = USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_ADC_EN_BIT | USBIN_AICL_EN_BIT | SUSPEND_ON_COLLAPSE_USBIN_BIT; val = USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_EN_BIT; if (!chip->dt.disable_suspend_on_collapse) val |= SUSPEND_ON_COLLAPSE_USBIN_BIT; rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG, USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_ADC_EN_BIT | USBIN_AICL_EN_BIT, USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_EN_BIT); mask, val); if (rc < 0) { dev_err(chg->dev, "Couldn't config AICL rc=%d\n", rc); return rc; Loading drivers/power/supply/qcom/smb5-lib.c +59 −43 Original line number Diff line number Diff line Loading @@ -213,7 +213,7 @@ int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode) static int smblib_select_sec_charger_locked(struct smb_charger *chg, int sec_chg) { int rc; int rc = 0; switch (sec_chg) { case POWER_SUPPLY_CHARGER_SEC_CP: Loading @@ -228,12 +228,14 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, return rc; } /* Enable Charge Pump, under HW control */ rc = smblib_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT); rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, EN_CP_CMD_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't enable SMB charger rc=%d\n", rc); return rc; } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, false, 0); break; case POWER_SUPPLY_CHARGER_SEC_PL: /* select slave charger instead of Charge Pump */ Loading @@ -245,12 +247,14 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, return rc; } /* Enable slave charger, under HW control */ rc = smblib_write(chg, MISC_SMB_EN_CMD_REG, EN_STAT_CMD_BIT); rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_STAT_CMD_BIT, EN_STAT_CMD_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't enable SMB charger rc=%d\n", rc); return rc; } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, false, 0); vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, false, 0); Loading @@ -260,13 +264,7 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, true, 0); /* SW override, disabling secondary charger(s) */ rc = smblib_write(chg, MISC_SMB_EN_CMD_REG, SMB_EN_OVERRIDE_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't disable charging rc=%d\n", rc); return rc; } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, true, 0); break; } Loading Loading @@ -1320,6 +1318,21 @@ int smblib_toggle_smb_en(struct smb_charger *chg, int toggle) /********************* * VOTABLE CALLBACKS * *********************/ static int smblib_smb_disable_override_vote_callback(struct votable *votable, void *data, int disable_smb, const char *client) { struct smb_charger *chg = data; int rc = 0; /* Enable/disable SMB_EN pin */ rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, SMB_EN_OVERRIDE_BIT | SMB_EN_OVERRIDE_VALUE_BIT, disable_smb ? SMB_EN_OVERRIDE_BIT : 0); if (rc < 0) smblib_err(chg, "Couldn't configure SMB_EN, rc=%d\n", rc); return rc; } static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, int suspend, const char *client) Loading Loading @@ -2471,13 +2484,8 @@ static int smblib_process_thermal_readings(struct smb_charger *chg) if (chg->thermal_status == TEMP_ALERT_LEVEL) goto exit; /* Enable/disable SMB_EN pin */ rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, SMB_EN_OVERRIDE_BIT | SMB_EN_OVERRIDE_VALUE_BIT, (disable_smb ? SMB_EN_OVERRIDE_BIT : (SMB_EN_OVERRIDE_BIT | SMB_EN_OVERRIDE_VALUE_BIT))); if (rc < 0) smblib_err(chg, "Couldn't set SMB_EN, rc=%d\n", rc); vote(chg->smb_override_votable, SW_THERM_REGULATION_VOTER, disable_smb, 0); /* * Enable/disable secondary charger through votables to ensure Loading Loading @@ -2718,36 +2726,14 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, return 0; } static int smblib_estimate_hvdcp_voltage(struct smb_charger *chg, union power_supply_propval *val) { int rc; u8 stat; rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read QC_CHANGE_STATUS_REG rc=%d\n", rc); return rc; } if (stat & QC_5V_BIT) val->intval = MICRO_5V; else if (stat & QC_9V_BIT) val->intval = MICRO_9V; else if (stat & QC_12V_BIT) val->intval = MICRO_12V; return 0; } #define HVDCP3_STEP_UV 200000 static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, union power_supply_propval *val) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_HVDCP: return smblib_estimate_hvdcp_voltage(chg, val); val->intval = MICRO_12V; break; case POWER_SUPPLY_TYPE_USB_HVDCP_3: val->intval = MICRO_5V + (HVDCP3_STEP_UV * chg->pulse_cnt); break; Loading Loading @@ -4447,7 +4433,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc); return IRQ_HANDLED; } smblib_dbg(chg, PR_REGISTER, "APSD_STATUS = 0x%02x\n", stat); smblib_dbg(chg, PR_INTERRUPT, "APSD_STATUS = 0x%02x\n", stat); if ((chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) && (stat & APSD_DTC_STATUS_DONE_BIT) Loading Loading @@ -4489,7 +4475,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc); return IRQ_HANDLED; } smblib_dbg(chg, PR_REGISTER, "APSD_STATUS = 0x%02x\n", stat); smblib_dbg(chg, PR_INTERRUPT, "APSD_STATUS = 0x%02x\n", stat); return IRQ_HANDLED; } Loading Loading @@ -4574,7 +4560,13 @@ static bool smblib_src_lpd(struct smb_charger *chg) static void typec_sink_insertion(struct smb_charger *chg) { int rc; vote(chg->usb_icl_votable, OTG_VOTER, true, 0); rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, chg->chg_freq.freq_above_otg_threshold); if (rc < 0) dev_err(chg->dev, "Error in setting freq_boost rc=%d\n", rc); if (chg->use_extcon) { smblib_notify_usb_host(chg, true); Loading Loading @@ -4612,7 +4604,13 @@ static void typec_src_insertion(struct smb_charger *chg) static void typec_sink_removal(struct smb_charger *chg) { int rc; vote(chg->usb_icl_votable, OTG_VOTER, false, 0); rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, chg->chg_freq.freq_removal); if (rc < 0) dev_err(chg->dev, "Error in setting freq_removal rc=%d\n", rc); if (chg->use_extcon) { if (chg->otg_present) Loading Loading @@ -5595,6 +5593,15 @@ static int smblib_create_votables(struct smb_charger *chg) vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); chg->smb_override_votable = create_votable("SMB_EN_OVERRIDE", VOTE_SET_ANY, smblib_smb_disable_override_vote_callback, chg); if (IS_ERR(chg->smb_override_votable)) { rc = PTR_ERR(chg->smb_override_votable); chg->smb_override_votable = NULL; return rc; } chg->dc_suspend_votable = create_votable("DC_SUSPEND", VOTE_SET_ANY, smblib_dc_suspend_vote_callback, chg); Loading Loading @@ -5669,6 +5676,14 @@ static void smblib_iio_deinit(struct smb_charger *chg) iio_channel_release(chg->iio.sbux_chan); if (!IS_ERR_OR_NULL(chg->iio.vph_v_chan)) iio_channel_release(chg->iio.vph_v_chan); if (!IS_ERR_OR_NULL(chg->iio.die_temp_chan)) iio_channel_release(chg->iio.die_temp_chan); if (!IS_ERR_OR_NULL(chg->iio.connector_temp_chan)) iio_channel_release(chg->iio.connector_temp_chan); if (!IS_ERR_OR_NULL(chg->iio.skin_temp_chan)) iio_channel_release(chg->iio.skin_temp_chan); if (!IS_ERR_OR_NULL(chg->iio.smb_temp_chan)) iio_channel_release(chg->iio.smb_temp_chan); } int smblib_init(struct smb_charger *chg) Loading Loading @@ -5696,6 +5711,7 @@ int smblib_init(struct smb_charger *chg) chg->jeita_configured = false; chg->sec_chg_selected = POWER_SUPPLY_CHARGER_SEC_NONE; chg->cp_reason = POWER_SUPPLY_CP_NONE; chg->thermal_status = TEMP_BELOW_RANGE; switch (chg->mode) { case PARALLEL_MASTER: Loading drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,7 @@ struct smb_charger { struct votable *usb_irq_enable_votable; struct votable *cp_disable_votable; struct votable *wdog_snarl_irq_en_votable; struct votable *smb_override_votable; /* work */ struct work_struct bms_update_work; Loading Loading
Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +6 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,12 @@ Charger specific properties: Definition: Boolean flag which when present enables stepwise change in FCC. The default stepping rate is 100mA/sec. - qcom,disable-suspend-on-collapse Usage: optional Value type: bool Definition: Boolean flag which when present disables suspend on collapse feature of charger hardware. ============================================= Second Level Nodes - SMB5 Charger Peripherals ============================================= Loading
drivers/power/supply/qcom/qpnp-smb5.c +11 −5 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ struct smb_dt_props { int term_current_src; int term_current_thresh_hi_ma; int term_current_thresh_lo_ma; int disable_suspend_on_collapse; }; struct smb5 { Loading Loading @@ -531,6 +532,8 @@ static int smb5_parse_dt(struct smb5 *chip) if (rc < 0) return rc; chip->dt.disable_suspend_on_collapse = of_property_read_bool(node, "qcom,disable-suspend-on-collapse"); return 0; } Loading Loading @@ -1767,7 +1770,7 @@ static int smb5_init_hw(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; int rc, type = 0; u8 val = 0; u8 val = 0, mask = 0; union power_supply_propval pval; if (chip->dt.no_battery) Loading Loading @@ -1935,11 +1938,14 @@ static int smb5_init_hw(struct smb5 *chip) * start from min and AICL ADC disable, and enable aicl rerun */ if (chg->smb_version != PMI632_SUBTYPE) { mask = USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_ADC_EN_BIT | USBIN_AICL_EN_BIT | SUSPEND_ON_COLLAPSE_USBIN_BIT; val = USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_EN_BIT; if (!chip->dt.disable_suspend_on_collapse) val |= SUSPEND_ON_COLLAPSE_USBIN_BIT; rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG, USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_ADC_EN_BIT | USBIN_AICL_EN_BIT, USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_EN_BIT); mask, val); if (rc < 0) { dev_err(chg->dev, "Couldn't config AICL rc=%d\n", rc); return rc; Loading
drivers/power/supply/qcom/smb5-lib.c +59 −43 Original line number Diff line number Diff line Loading @@ -213,7 +213,7 @@ int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode) static int smblib_select_sec_charger_locked(struct smb_charger *chg, int sec_chg) { int rc; int rc = 0; switch (sec_chg) { case POWER_SUPPLY_CHARGER_SEC_CP: Loading @@ -228,12 +228,14 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, return rc; } /* Enable Charge Pump, under HW control */ rc = smblib_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT); rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, EN_CP_CMD_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't enable SMB charger rc=%d\n", rc); return rc; } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, false, 0); break; case POWER_SUPPLY_CHARGER_SEC_PL: /* select slave charger instead of Charge Pump */ Loading @@ -245,12 +247,14 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, return rc; } /* Enable slave charger, under HW control */ rc = smblib_write(chg, MISC_SMB_EN_CMD_REG, EN_STAT_CMD_BIT); rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_STAT_CMD_BIT, EN_STAT_CMD_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't enable SMB charger rc=%d\n", rc); return rc; } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, false, 0); vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, false, 0); Loading @@ -260,13 +264,7 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, true, 0); /* SW override, disabling secondary charger(s) */ rc = smblib_write(chg, MISC_SMB_EN_CMD_REG, SMB_EN_OVERRIDE_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't disable charging rc=%d\n", rc); return rc; } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, true, 0); break; } Loading Loading @@ -1320,6 +1318,21 @@ int smblib_toggle_smb_en(struct smb_charger *chg, int toggle) /********************* * VOTABLE CALLBACKS * *********************/ static int smblib_smb_disable_override_vote_callback(struct votable *votable, void *data, int disable_smb, const char *client) { struct smb_charger *chg = data; int rc = 0; /* Enable/disable SMB_EN pin */ rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, SMB_EN_OVERRIDE_BIT | SMB_EN_OVERRIDE_VALUE_BIT, disable_smb ? SMB_EN_OVERRIDE_BIT : 0); if (rc < 0) smblib_err(chg, "Couldn't configure SMB_EN, rc=%d\n", rc); return rc; } static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, int suspend, const char *client) Loading Loading @@ -2471,13 +2484,8 @@ static int smblib_process_thermal_readings(struct smb_charger *chg) if (chg->thermal_status == TEMP_ALERT_LEVEL) goto exit; /* Enable/disable SMB_EN pin */ rc = smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, SMB_EN_OVERRIDE_BIT | SMB_EN_OVERRIDE_VALUE_BIT, (disable_smb ? SMB_EN_OVERRIDE_BIT : (SMB_EN_OVERRIDE_BIT | SMB_EN_OVERRIDE_VALUE_BIT))); if (rc < 0) smblib_err(chg, "Couldn't set SMB_EN, rc=%d\n", rc); vote(chg->smb_override_votable, SW_THERM_REGULATION_VOTER, disable_smb, 0); /* * Enable/disable secondary charger through votables to ensure Loading Loading @@ -2718,36 +2726,14 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, return 0; } static int smblib_estimate_hvdcp_voltage(struct smb_charger *chg, union power_supply_propval *val) { int rc; u8 stat; rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read QC_CHANGE_STATUS_REG rc=%d\n", rc); return rc; } if (stat & QC_5V_BIT) val->intval = MICRO_5V; else if (stat & QC_9V_BIT) val->intval = MICRO_9V; else if (stat & QC_12V_BIT) val->intval = MICRO_12V; return 0; } #define HVDCP3_STEP_UV 200000 static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, union power_supply_propval *val) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_HVDCP: return smblib_estimate_hvdcp_voltage(chg, val); val->intval = MICRO_12V; break; case POWER_SUPPLY_TYPE_USB_HVDCP_3: val->intval = MICRO_5V + (HVDCP3_STEP_UV * chg->pulse_cnt); break; Loading Loading @@ -4447,7 +4433,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc); return IRQ_HANDLED; } smblib_dbg(chg, PR_REGISTER, "APSD_STATUS = 0x%02x\n", stat); smblib_dbg(chg, PR_INTERRUPT, "APSD_STATUS = 0x%02x\n", stat); if ((chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) && (stat & APSD_DTC_STATUS_DONE_BIT) Loading Loading @@ -4489,7 +4475,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc); return IRQ_HANDLED; } smblib_dbg(chg, PR_REGISTER, "APSD_STATUS = 0x%02x\n", stat); smblib_dbg(chg, PR_INTERRUPT, "APSD_STATUS = 0x%02x\n", stat); return IRQ_HANDLED; } Loading Loading @@ -4574,7 +4560,13 @@ static bool smblib_src_lpd(struct smb_charger *chg) static void typec_sink_insertion(struct smb_charger *chg) { int rc; vote(chg->usb_icl_votable, OTG_VOTER, true, 0); rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, chg->chg_freq.freq_above_otg_threshold); if (rc < 0) dev_err(chg->dev, "Error in setting freq_boost rc=%d\n", rc); if (chg->use_extcon) { smblib_notify_usb_host(chg, true); Loading Loading @@ -4612,7 +4604,13 @@ static void typec_src_insertion(struct smb_charger *chg) static void typec_sink_removal(struct smb_charger *chg) { int rc; vote(chg->usb_icl_votable, OTG_VOTER, false, 0); rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, chg->chg_freq.freq_removal); if (rc < 0) dev_err(chg->dev, "Error in setting freq_removal rc=%d\n", rc); if (chg->use_extcon) { if (chg->otg_present) Loading Loading @@ -5595,6 +5593,15 @@ static int smblib_create_votables(struct smb_charger *chg) vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); chg->smb_override_votable = create_votable("SMB_EN_OVERRIDE", VOTE_SET_ANY, smblib_smb_disable_override_vote_callback, chg); if (IS_ERR(chg->smb_override_votable)) { rc = PTR_ERR(chg->smb_override_votable); chg->smb_override_votable = NULL; return rc; } chg->dc_suspend_votable = create_votable("DC_SUSPEND", VOTE_SET_ANY, smblib_dc_suspend_vote_callback, chg); Loading Loading @@ -5669,6 +5676,14 @@ static void smblib_iio_deinit(struct smb_charger *chg) iio_channel_release(chg->iio.sbux_chan); if (!IS_ERR_OR_NULL(chg->iio.vph_v_chan)) iio_channel_release(chg->iio.vph_v_chan); if (!IS_ERR_OR_NULL(chg->iio.die_temp_chan)) iio_channel_release(chg->iio.die_temp_chan); if (!IS_ERR_OR_NULL(chg->iio.connector_temp_chan)) iio_channel_release(chg->iio.connector_temp_chan); if (!IS_ERR_OR_NULL(chg->iio.skin_temp_chan)) iio_channel_release(chg->iio.skin_temp_chan); if (!IS_ERR_OR_NULL(chg->iio.smb_temp_chan)) iio_channel_release(chg->iio.smb_temp_chan); } int smblib_init(struct smb_charger *chg) Loading Loading @@ -5696,6 +5711,7 @@ int smblib_init(struct smb_charger *chg) chg->jeita_configured = false; chg->sec_chg_selected = POWER_SUPPLY_CHARGER_SEC_NONE; chg->cp_reason = POWER_SUPPLY_CP_NONE; chg->thermal_status = TEMP_BELOW_RANGE; switch (chg->mode) { case PARALLEL_MASTER: Loading
drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,7 @@ struct smb_charger { struct votable *usb_irq_enable_votable; struct votable *cp_disable_votable; struct votable *wdog_snarl_irq_en_votable; struct votable *smb_override_votable; /* work */ struct work_struct bms_update_work; Loading