diff --git a/drivers/power/supply/qcom/Makefile b/drivers/power/supply/qcom/Makefile index c1db89816d37..cf8308643a5e 100644 --- a/drivers/power/supply/qcom/Makefile +++ b/drivers/power/supply/qcom/Makefile @@ -6,7 +6,8 @@ obj-$(CONFIG_QPNP_QG) += qcom-qpnp-qg.o qcom-qpnp-qg-y += qpnp-qg.o battery-profile-loader.o pmic-voter.o qg-util.o qg-soc.o qg-sdam.o qg-battery-profile.o qg-profile-lib.o fg-alg.o obj-$(CONFIG_SMB1398_CHARGER) += qcom-smb1398-charger.o qcom-smb1398-charger-y += smb1398-charger.o pmic-voter.o -obj-$(CONFIG_QPNP_SMBLITE) += step-chg-jeita.o battery.o qpnp-smblite.o smblite-lib.o pmic-voter.o storm-watch.o schgm-falshlite.o +obj-$(CONFIG_QPNP_SMBLITE) += qpnp-smblite-main.o +qpnp-smblite-main-y += step-chg-jeita.o battery.o qpnp-smblite.o smblite-lib.o pmic-voter.o storm-watch.o battery-profile-loader.o schgm-flashlite.o smblite-iio.o obj-$(CONFIG_SMB1355_SLAVE_CHARGER) += qcom-smb1355-charger.o qcom-smb1355-charger-y += smb1355-charger.o pmic-voter.o obj-$(CONFIG_SMB1390_CHARGE_PUMP_PSY) += smb1390-charger-psy.o pmic-voter.o diff --git a/drivers/power/supply/qcom/qpnp-smblite.c b/drivers/power/supply/qcom/qpnp-smblite.c index 682f47836021..a20e61b9970d 100644 --- a/drivers/power/supply/qcom/qpnp-smblite.c +++ b/drivers/power/supply/qcom/qpnp-smblite.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. */ #include @@ -11,15 +11,16 @@ #include #include #include +#include #include #include #include -#include #include #include #include #include "smblite-reg.h" #include "smblite-lib.h" +#include "smb5-iio.h" #include "schgm-flashlite.h" static struct power_supply_desc usb_psy_desc; @@ -71,7 +72,6 @@ static struct smb_params smblite_params = { struct smb_dt_props { int usb_icl_ua; - struct device_node *revid_dev_node; int chg_inhibit_thr_mv; bool no_battery; int auto_recharge_soc; @@ -89,6 +89,9 @@ struct smblite { struct smb_charger chg; struct dentry *dfs_root; struct smb_dt_props dt; + unsigned int nchannels; + struct iio_channel *iio_chans; + struct iio_chan_spec *iio_chan_ids; }; static int __debug_mask; @@ -127,38 +130,17 @@ ATTRIBUTE_GROUPS(smblite); static int smblite_chg_config_init(struct smblite *chip) { struct smb_charger *chg = &chip->chg; - struct pmic_revid_data *pmic_rev_id; - struct device_node *revid_dev_node, *node = chg->dev->of_node; + int subtype = (u8)of_device_get_match_data(chg->dev); u8 val; int rc = 0; - revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0); - if (!revid_dev_node) { - pr_err("Missing qcom,pmic-revid property\n"); - return -EINVAL; - } - - pmic_rev_id = get_revid_data(revid_dev_node); - if (IS_ERR_OR_NULL(pmic_rev_id)) { - /* - * the revid peripheral must be registered, any failure - * here only indicates that the rev-id module has not - * probed yet. - */ - rc = -EPROBE_DEFER; - goto out; - } - - switch (pmic_rev_id->pmic_subtype) { - case PM2250_SUBTYPE: + switch (subtype) { + case PM2250: chg->wa_flags |= WEAK_ADAPTER_WA; - if (pmic_rev_id->rev4 < 2) - chg->wa_flags |= FLASH_DIE_TEMP_DERATE_WA; break; default: - pr_err("Unsupported PMIC subtype=%d\n", - pmic_rev_id->pmic_subtype); - break; + pr_err("Unsupported PMIC subtype=%d\n", subtype); + return -EINVAL; } rc = smblite_lib_read(chg, DCDC_LDO_CFG_REG, &val); @@ -172,8 +154,6 @@ static int smblite_chg_config_init(struct smblite *chip) chg->param = smblite_params; chg->name = "PM2250_charger"; -out: - of_node_put(revid_dev_node); return rc; } @@ -374,18 +354,18 @@ static enum power_supply_property smblite_usb_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_TYPE, - POWER_SUPPLY_PROP_TYPEC_MODE, - POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, - POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, - POWER_SUPPLY_PROP_HW_CURRENT_MAX, - POWER_SUPPLY_PROP_REAL_TYPE, - POWER_SUPPLY_PROP_CONNECTOR_TYPE, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, +}; + +static enum power_supply_usb_type smblite_usb_psy_supported_types[] = { + POWER_SUPPLY_USB_TYPE_UNKNOWN, + POWER_SUPPLY_USB_TYPE_SDP, + POWER_SUPPLY_USB_TYPE_DCP, + POWER_SUPPLY_USB_TYPE_CDP, }; static int smblite_usb_get_prop(struct power_supply *psy, @@ -395,8 +375,8 @@ static int smblite_usb_get_prop(struct power_supply *psy, struct smblite *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; - val->intval = 0; + switch (psp) { case POWER_SUPPLY_PROP_PRESENT: rc = smblite_lib_get_prop_usb_present(chg, val); @@ -407,33 +387,9 @@ static int smblite_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblite_lib_get_prop_usb_voltage_now(chg, val); break; - case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: - rc = smblite_lib_get_charge_current(chg, &val->intval); - break; case POWER_SUPPLY_PROP_TYPE: val->intval = POWER_SUPPLY_TYPE_USB; break; - case POWER_SUPPLY_PROP_REAL_TYPE: - val->intval = chg->real_charger_type; - break; - case POWER_SUPPLY_PROP_TYPEC_MODE: - rc = smblite_lib_get_usb_prop_typec_mode(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: - rc = smblite_lib_get_prop_typec_power_role(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION: - rc = smblite_lib_get_prop_typec_cc_orientation(chg, val); - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: - rc = smblite_lib_get_prop_input_current_settled(chg, val); - break; - case POWER_SUPPLY_PROP_HW_CURRENT_MAX: - rc = smblite_lib_get_hw_current_max(chg, &val->intval); - break; - case POWER_SUPPLY_PROP_CONNECTOR_TYPE: - val->intval = chg->connector_type; - break; case POWER_SUPPLY_PROP_SCOPE: rc = smblite_lib_get_prop_scope(chg, val); break; @@ -443,6 +399,10 @@ static int smblite_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX: val->intval = 5000000; break; + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + /* USB uses this to set SDP current */ + rc = smblite_lib_get_charge_current(chg, &val->intval); + break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; @@ -450,7 +410,7 @@ static int smblite_usb_get_prop(struct power_supply *psy, } if (rc < 0) { - pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); + pr_debug("Couldn't get usb prop %d rc = %d\n", psp, rc); return -ENODATA; } @@ -481,14 +441,11 @@ static int smblite_usb_set_prop(struct power_supply *psy, int rc = 0; switch (psp) { - case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: rc = smblite_lib_set_prop_current_max(chg, val); break; - case POWER_SUPPLY_PROP_REAL_TYPE: - rc = smblite_lib_set_prop_usb_type(chg, val); - break; default: - pr_err("set prop %d is not supported\n", psp); + pr_err("usb set prop %d is not supported\n", psp); rc = -EINVAL; break; } @@ -499,15 +456,14 @@ static int smblite_usb_set_prop(struct power_supply *psy, static int smblite_usb_prop_is_writeable(struct power_supply *psy, enum power_supply_property psp) { - int rc = 0; - switch (psp) { + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + return 1; default: - rc = 0; break; } - return rc; + return 0; } static struct power_supply_desc usb_psy_desc = { @@ -517,7 +473,9 @@ static struct power_supply_desc usb_psy_desc = { .num_properties = ARRAY_SIZE(smblite_usb_props), .get_property = smblite_usb_get_prop, .set_property = smblite_usb_set_prop, + .usb_types = smblite_usb_psy_supported_types, .property_is_writeable = smblite_usb_prop_is_writeable, + .num_usb_types = ARRAY_SIZE(smblite_usb_psy_supported_types), }; static int smblite_init_usb_psy(struct smblite *chip) @@ -538,185 +496,15 @@ static int smblite_init_usb_psy(struct smblite *chip) return 0; } -/***************************** - * USB MAIN PSY REGISTRATION * - *****************************/ - -static enum power_supply_property smblite_usb_main_props[] = { - POWER_SUPPLY_PROP_VOLTAGE_MAX, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - POWER_SUPPLY_PROP_TYPE, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, - POWER_SUPPLY_PROP_FCC_DELTA, - POWER_SUPPLY_PROP_CURRENT_MAX, - POWER_SUPPLY_PROP_FLASH_TRIGGER, - POWER_SUPPLY_PROP_FLASH_ACTIVE, -}; - -static int smblite_usb_main_get_prop(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct smblite *chip = power_supply_get_drvdata(psy); - struct smb_charger *chg = &chip->chg; - int rc = 0; - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - rc = smblite_lib_get_charge_param(chg, &chg->param.fv, - &val->intval); - break; - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - rc = smblite_lib_get_charge_param(chg, &chg->param.fcc, - &val->intval); - break; - case POWER_SUPPLY_PROP_TYPE: - val->intval = POWER_SUPPLY_TYPE_MAIN; - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: - rc = smblite_lib_get_prop_input_current_settled(chg, val); - break; - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED: - rc = smblite_lib_get_prop_input_voltage_settled(chg, val); - break; - case POWER_SUPPLY_PROP_FCC_DELTA: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblite_lib_get_icl_current(chg, &val->intval); - break; - case POWER_SUPPLY_PROP_FLASH_TRIGGER: - rc = schgm_flashlite_get_vreg_ok(chg, &val->intval); - break; - case POWER_SUPPLY_PROP_FLASH_ACTIVE: - val->intval = chg->flash_active; - break; - default: - pr_debug("get prop %d is not supported in usb-main\n", psp); - rc = -EINVAL; - break; - } - if (rc < 0) - pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); - - return rc; -} - -static int smblite_usb_main_set_prop(struct power_supply *psy, - enum power_supply_property psp, - const union power_supply_propval *val) -{ - struct smblite *chip = power_supply_get_drvdata(psy); - struct smb_charger *chg = &chip->chg; - int rc = 0, icl_ua; - union power_supply_propval pval = {0, }; - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - rc = smblite_lib_set_charge_param(chg, &chg->param.fv, - val->intval); - break; - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - rc = smblite_lib_set_charge_param(chg, &chg->param.fcc, - val->intval); - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblite_lib_set_icl_current(chg, val->intval); - break; - case POWER_SUPPLY_PROP_FLASH_ACTIVE: - if (chg->flash_active != val->intval) { - chg->flash_active = val->intval; - - rc = smblite_lib_get_prop_usb_present(chg, &pval); - if (rc < 0) - pr_err("Failed to get USB present status rc=%d\n", - rc); - if (!pval.intval) { - /* vote 100ma when usb is not present*/ - vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, - true, USBIN_100UA); - } else if (chg->flash_active) { - icl_ua = get_effective_result_locked( - chg->usb_icl_votable); - if (icl_ua >= USBIN_400UA) { - vote(chg->usb_icl_votable, - FLASH_ACTIVE_VOTER, - true, icl_ua - USBIN_300UA); - } - } else { - vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, - false, 0); - } - pr_debug("flash_active=%d usb_present=%d icl=%d\n", - chg->flash_active, pval.intval, - get_effective_result_locked( - chg->usb_icl_votable)); - - } - break; - default: - pr_err("set prop %d is not supported\n", psp); - rc = -EINVAL; - break; - } - - return rc; -} - -static int smblite_usb_main_prop_is_writeable(struct power_supply *psy, - enum power_supply_property psp) -{ - int rc = 0; - - switch (psp) { - default: - rc = 0; - break; - } - - return rc; -} - -static const struct power_supply_desc usb_main_psy_desc = { - .name = "main", - .type = POWER_SUPPLY_TYPE_MAIN, - .properties = smblite_usb_main_props, - .num_properties = ARRAY_SIZE(smblite_usb_main_props), - .get_property = smblite_usb_main_get_prop, - .set_property = smblite_usb_main_set_prop, - .property_is_writeable = smblite_usb_main_prop_is_writeable, -}; - -static int smblite_init_usb_main_psy(struct smblite *chip) -{ - struct power_supply_config usb_main_cfg = {}; - struct smb_charger *chg = &chip->chg; - - usb_main_cfg.drv_data = chip; - usb_main_cfg.of_node = chg->dev->of_node; - chg->usb_main_psy = devm_power_supply_register(chg->dev, - &usb_main_psy_desc, - &usb_main_cfg); - if (IS_ERR(chg->usb_main_psy)) { - pr_err("Couldn't register USB main power supply\n"); - return PTR_ERR(chg->usb_main_psy); - } - - return 0; -} - /************************* * BATT PSY REGISTRATION * *************************/ static enum power_supply_property smblite_batt_props[] = { - POWER_SUPPLY_PROP_INPUT_SUSPEND, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_CHARGER_TEMP, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_CURRENT_NOW, @@ -725,22 +513,14 @@ static enum power_supply_property smblite_batt_props[] = { POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED, - POWER_SUPPLY_PROP_SW_JEITA_ENABLED, - POWER_SUPPLY_PROP_CHARGE_DONE, - POWER_SUPPLY_PROP_SET_SHIP_MODE, - POWER_SUPPLY_PROP_DIE_HEALTH, POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_CYCLE_COUNT, - POWER_SUPPLY_PROP_RECHARGE_SOC, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, - POWER_SUPPLY_PROP_FORCE_RECHARGE, - POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, - POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, }; #define DEBUG_ACCESSORY_TEMP_DECIDEGC 250 @@ -761,9 +541,6 @@ static int smblite_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PRESENT: rc = smblite_lib_get_prop_batt_present(chg, val); break; - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - rc = smblite_lib_get_prop_input_suspend(chg, val); - break; case POWER_SUPPLY_PROP_CHARGE_TYPE: rc = smblite_lib_get_prop_batt_charge_type(chg, val); break; @@ -776,25 +553,16 @@ static int smblite_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: rc = smblite_lib_get_prop_system_temp_level_max(chg, val); break; - case POWER_SUPPLY_PROP_CHARGER_TEMP: - rc = smblite_lib_get_prop_charger_temp(chg, val); - break; - case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: - val->intval = chg->step_chg_enabled; - break; - case POWER_SUPPLY_PROP_SW_JEITA_ENABLED: - val->intval = 1; - break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_VOLTAGE_NOW, val); + SMB5_QG_VOLTAGE_NOW, &val->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: val->intval = get_client_vote(chg->fv_votable, BATT_PROFILE_VOTER); break; case POWER_SUPPLY_PROP_CURRENT_NOW: - rc = smblite_lib_get_batt_current_now(chg, val); + rc = smblite_lib_get_batt_current_now(chg, &val->intval); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: val->intval = get_client_vote(chg->fcc_votable, @@ -807,56 +575,37 @@ static int smblite_batt_get_prop(struct power_supply *psy, rc = smblite_lib_get_prop_batt_iterm(chg, val); break; case POWER_SUPPLY_PROP_TEMP: - if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) + if (chg->typec_mode == QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) val->intval = DEBUG_ACCESSORY_TEMP_DECIDEGC; else rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_TEMP, val); + SMB5_QG_TEMP, &val->intval); break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = POWER_SUPPLY_TECHNOLOGY_LION; break; - case POWER_SUPPLY_PROP_CHARGE_DONE: - rc = smblite_lib_get_prop_batt_charge_done(chg, val); - break; - case POWER_SUPPLY_PROP_SET_SHIP_MODE: - /* Not in ship mode as long as device is active */ - val->intval = 0; - break; - case POWER_SUPPLY_PROP_DIE_HEALTH: - rc = smblite_lib_get_die_health(chg, val); - break; case POWER_SUPPLY_PROP_CHARGE_COUNTER: rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CHARGE_COUNTER, val); + SMB5_QG_CHARGE_COUNTER, &val->intval); break; case POWER_SUPPLY_PROP_CYCLE_COUNT: rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CYCLE_COUNT, val); - break; - case POWER_SUPPLY_PROP_RECHARGE_SOC: - val->intval = chg->auto_recharge_soc; + SMB5_QG_CYCLE_COUNT, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_FULL: rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CHARGE_FULL, val); + SMB5_QG_CHARGE_FULL, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, val); + SMB5_QG_CHARGE_FULL_DESIGN, &val->intval); break; case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, val); - break; - case POWER_SUPPLY_PROP_FORCE_RECHARGE: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE: - val->intval = chg->fcc_stepper_enable; - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: - rc = smblite_lib_get_prop_input_current_limited(chg, val); + SMB5_QG_TIME_TO_FULL_NOW, &val->intval); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + /* For battery, INPUT_CURRENT_LIMIT equates to INPUT_SUSPEND */ + rc = smblite_lib_get_prop_input_suspend(chg, &val->intval); break; default: pr_err("batt power supply prop %d not supported\n", psp); @@ -864,7 +613,7 @@ static int smblite_batt_get_prop(struct power_supply *psy, } if (rc < 0) { - pr_debug("Couldn't get prop %d rc = %d\n", psp, rc); + pr_debug("Couldn't get batt prop %d rc = %d\n", psp, rc); return -ENODATA; } @@ -882,9 +631,6 @@ static int smblite_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_STATUS: rc = smblite_lib_set_prop_batt_status(chg, val); break; - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - rc = smblite_lib_set_prop_input_suspend(chg, val); - break; case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: rc = smblite_lib_set_prop_system_temp_level(chg, val); break; @@ -895,39 +641,12 @@ static int smblite_batt_set_prop(struct power_supply *psy, chg->batt_profile_fv_uv = val->intval; vote(chg->fv_votable, BATT_PROFILE_VOTER, true, val->intval); break; - case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: - chg->step_chg_enabled = !!val->intval; - break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: chg->batt_profile_fcc_ua = val->intval; vote(chg->fcc_votable, BATT_PROFILE_VOTER, true, val->intval); break; - case POWER_SUPPLY_PROP_SET_SHIP_MODE: - /* Not in ship mode as long as the device is active */ - if (!val->intval) - break; - if (chg->pl.psy) - power_supply_set_property(chg->pl.psy, - POWER_SUPPLY_PROP_SET_SHIP_MODE, val); - rc = smblite_lib_set_prop_ship_mode(chg, val); - break; - case POWER_SUPPLY_PROP_DIE_HEALTH: - power_supply_changed(chg->batt_psy); - break; - case POWER_SUPPLY_PROP_RECHARGE_SOC: - rc = smblite_lib_set_prop_rechg_soc_thresh(chg, val); - break; - case POWER_SUPPLY_PROP_FORCE_RECHARGE: - /* toggle charging to force recharge */ - vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER, - true, 0); - /* charge disable delay */ - msleep(50); - vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER, - false, 0); - break; - case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE: - chg->fcc_stepper_enable = val->intval; + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + rc = smblite_lib_set_prop_input_suspend(chg, val->intval); break; default: rc = -EINVAL; @@ -943,11 +662,11 @@ static int smblite_batt_prop_is_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_STATUS: - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL: case POWER_SUPPLY_PROP_CAPACITY: - case POWER_SUPPLY_PROP_DIE_HEALTH: - case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: rc = 1; break; default: @@ -992,7 +711,6 @@ static int smblite_init_batt_psy(struct smblite *chip) ***************************/ static int smblite_configure_typec(struct smb_charger *chg) { - union power_supply_propval pval = {0, }; int rc; u8 val = 0; @@ -1008,8 +726,8 @@ static int smblite_configure_typec(struct smb_charger *chg) * detection by disabling/enabling typeC mode. */ if (val & TYPEC_LEGACY_CABLE_STATUS_BIT) { - pval.intval = POWER_SUPPLY_TYPEC_PR_NONE; - smblite_lib_set_prop_typec_power_role(chg, &pval); + rc = smblite_lib_set_prop_typec_power_role(chg, + QTI_POWER_SUPPLY_TYPEC_PR_NONE); if (rc < 0) { dev_err(chg->dev, "Couldn't disable TYPEC rc=%d\n", rc); return rc; @@ -1018,8 +736,8 @@ static int smblite_configure_typec(struct smb_charger *chg) /* delay before enabling typeC */ msleep(50); - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - smblite_lib_set_prop_typec_power_role(chg, &pval); + rc = smblite_lib_set_prop_typec_power_role(chg, + QTI_POWER_SUPPLY_TYPEC_PR_DUAL); if (rc < 0) { dev_err(chg->dev, "Couldn't enable TYPEC rc=%d\n", rc); return rc; @@ -1139,7 +857,6 @@ static int smblite_configure_recharging(struct smblite *chip) { int rc = 0; struct smb_charger *chg = &chip->chg; - union power_supply_propval pval; /* Configure VBATT-based or automatic recharging */ rc = smblite_lib_masked_write(chg, CHGR_RECHG_CFG_REG, RECHG_MASK, @@ -1184,8 +901,8 @@ static int smblite_configure_recharging(struct smblite *chip) /* program the auto-recharge threshold */ if (chip->dt.auto_recharge_soc != -EINVAL) { - pval.intval = chip->dt.auto_recharge_soc; - rc = smblite_lib_set_prop_rechg_soc_thresh(chg, &pval); + rc = smblite_lib_set_prop_rechg_soc_thresh(chg, + chip->dt.auto_recharge_soc); if (rc < 0) { dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n", rc); @@ -1213,9 +930,9 @@ static int smblite_init_connector_type(struct smb_charger *chg) pr_debug("Connector type=%s\n", type ? "Micro USB" : "TypeC"); if (type) { - chg->connector_type = POWER_SUPPLY_CONNECTOR_MICRO_USB; + chg->connector_type = QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB; } else { - chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC; + chg->connector_type = QTI_POWER_SUPPLY_CONNECTOR_TYPEC; rc = smblite_configure_typec(chg); if (rc < 0) { dev_err(chg->dev, @@ -1234,7 +951,7 @@ static int smblite_init_otg(struct smblite *chip) chg->usb_id_gpio = chg->usb_id_irq = -EINVAL; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) return 0; if (of_find_property(chg->dev->of_node, "qcom,usb-id-gpio", NULL)) @@ -1442,7 +1159,6 @@ static int smblite_init_hw(struct smblite *chip) static int smblite_post_init(struct smblite *chip) { struct smb_charger *chg = &chip->chg; - union power_supply_propval pval; int rc; /* @@ -1452,10 +1168,10 @@ static int smblite_post_init(struct smblite *chip) */ rerun_election(chg->usb_icl_votable); - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) { + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) { /* configure power role for dual-role */ - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - rc = smblite_lib_set_prop_typec_power_role(chg, &pval); + rc = smblite_lib_set_prop_typec_power_role(chg, + QTI_POWER_SUPPLY_TYPEC_PR_DUAL); if (rc < 0) { dev_err(chg->dev, "Couldn't configure DRP role rc=%d\n", rc); @@ -1485,9 +1201,7 @@ static int smblite_determine_initial_status(struct smblite *chip) return rc; } - if (chg->bms_psy) - smblite_lib_suspend_on_debug_battery(chg); - + smblite_lib_suspend_on_debug_battery(chg); smblite_usb_plugin_irq_handler(0, &irq_data); smblite_typec_attach_detach_irq_handler(0, &irq_data); smblite_typec_state_change_irq_handler(0, &irq_data); @@ -1498,7 +1212,7 @@ static int smblite_determine_initial_status(struct smblite *chip) smblite_typec_or_rid_detection_change_irq_handler(0, &irq_data); if (chg->usb_id_gpio > 0 && - chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) smblite_usb_id_irq_handler(0, chg); return 0; @@ -1884,7 +1598,7 @@ static int smblite_show_charger_status(struct smblite *chip) pr_info("SMBLITE: Mode=%s Conn=%s USB Present=%d Battery present=%d health=%d charge=%d\n", chg->ldo_mode ? "LDO" : "SMBC", - (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) ? + (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) ? "TYPEC" : "uUSB", usb_present, batt_present, batt_health, batt_charge_type); return rc; @@ -1904,7 +1618,6 @@ static int smblite_init_typec_class(struct smblite *chip) chg->typec_caps.data = TYPEC_PORT_DRD; chg->typec_partner_desc.usb_pd = false; chg->typec_partner_desc.accessory = TYPEC_ACCESSORY_NONE; - chg->typec_caps.port_type_set = smblite_lib_typec_port_type_set; chg->typec_caps.revision = 0x0130; chg->typec_port = typec_register_port(chg->dev, &chg->typec_caps); @@ -1917,17 +1630,162 @@ static int smblite_init_typec_class(struct smblite *chip) return rc; } +static int smblite_of_xlate(struct iio_dev *indio_dev, + const struct of_phandle_args *iiospec) +{ + struct smblite *iio_chip = iio_priv(indio_dev); + struct iio_chan_spec *iio_chan = iio_chip->iio_chan_ids; + int i; + + for (i = 0; i < iio_chip->nchannels; i++, iio_chan++) + if (iio_chan->channel == iiospec->args[0]) + return i; + + return -EINVAL; +} + +static int smblite_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, + long mask) +{ + struct smblite *iio_chip = iio_priv(indio_dev); + struct smb_charger *chg = &iio_chip->chg; + + return smblite_iio_get_prop(chg, chan->channel, val); +} + +static int smblite_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long mask) +{ + struct smblite *iio_chip = iio_priv(indio_dev); + struct smb_charger *chg = &iio_chip->chg; + + return smblite_iio_set_prop(chg, chan->channel, val); +} + +static const struct iio_info smblite_iio_info = { + .read_raw = smblite_read_raw, + .write_raw = smblite_write_raw, + .of_xlate = smblite_of_xlate, +}; + +static int smblite_direct_iio_read(struct device *dev, int iio_chan_no, int *val) +{ + struct smblite *chip = dev_get_drvdata(dev); + struct smb_charger *chg = &chip->chg; + int rc; + + rc = smblite_iio_get_prop(chg, iio_chan_no, val); + + return (rc < 0) ? rc : 0; +} + +static int smblite_direct_iio_write(struct device *dev, int iio_chan_no, int val) +{ + struct smblite *chip = dev_get_drvdata(dev); + struct smb_charger *chg = &chip->chg; + + return smblite_iio_set_prop(chg, iio_chan_no, val); +} + +static int smblite_iio_init(struct smblite *chip, struct platform_device *pdev, + struct iio_dev *indio_dev) +{ + struct iio_chan_spec *iio_chan; + int i, rc; + + for (i = 0; i < chip->nchannels; i++) { + chip->iio_chans[i].indio_dev = indio_dev; + iio_chan = &chip->iio_chan_ids[i]; + chip->iio_chans[i].channel = iio_chan; + + iio_chan->channel = smb5_chans_pmic[i].channel_num; + iio_chan->datasheet_name = smb5_chans_pmic[i].datasheet_name; + iio_chan->extend_name = smb5_chans_pmic[i].datasheet_name; + iio_chan->info_mask_separate = smb5_chans_pmic[i].info_mask; + iio_chan->type = smb5_chans_pmic[i].type; + iio_chan->address = i; + } + + indio_dev->dev.parent = &pdev->dev; + indio_dev->dev.of_node = pdev->dev.of_node; + indio_dev->name = "qpnp-smblite"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = chip->iio_chan_ids; + indio_dev->num_channels = chip->nchannels; + + rc = devm_iio_device_register(&pdev->dev, indio_dev); + if (rc < 0) + pr_err("iio device register failed rc=%d\n", rc); + + return rc; +} + +static int smblite_extcon_init(struct smb_charger *chg) +{ + int rc; + + /* extcon registration */ + chg->extcon = devm_extcon_dev_allocate(chg->dev, smblite_lib_extcon_cable); + if (IS_ERR(chg->extcon)) { + rc = PTR_ERR(chg->extcon); + dev_err(chg->dev, "failed to allocate extcon device rc=%d\n", + rc); + return rc; + } + + rc = devm_extcon_dev_register(chg->dev, chg->extcon); + if (rc < 0) { + dev_err(chg->dev, "failed to register extcon device rc=%d\n", + rc); + return rc; + } + + /* Support reporting polarity and speed via properties */ + rc = extcon_set_property_capability(chg->extcon, + EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY); + rc |= extcon_set_property_capability(chg->extcon, + EXTCON_USB, EXTCON_PROP_USB_SS); + rc |= extcon_set_property_capability(chg->extcon, + EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY); + rc |= extcon_set_property_capability(chg->extcon, + EXTCON_USB_HOST, EXTCON_PROP_USB_SS); + if (rc < 0) + dev_err(chg->dev, + "failed to configure extcon capabilities\n"); + + return rc; +} + static int smblite_probe(struct platform_device *pdev) { struct smblite *chip; + struct iio_dev *indio_dev; struct smb_charger *chg; int rc = 0; - chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); - if (!chip) + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*chip)); + if (!indio_dev) + return -ENOMEM; + + indio_dev->info = &smblite_iio_info; + chip = iio_priv(indio_dev); + chip->nchannels = ARRAY_SIZE(smb5_chans_pmic); + + chip->iio_chans = devm_kcalloc(&pdev->dev, chip->nchannels, + sizeof(*chip->iio_chans), GFP_KERNEL); + if (!chip->iio_chans) + return -ENOMEM; + + chip->iio_chan_ids = devm_kcalloc(&pdev->dev, chip->nchannels, + sizeof(*chip->iio_chan_ids), GFP_KERNEL); + if (!chip->iio_chan_ids) return -ENOMEM; chg = &chip->chg; + chg->iio_chans = chip->iio_chans; + chg->iio_chan_list_qg = NULL; chg->dev = &pdev->dev; chg->debug_mask = &__debug_mask; chg->weak_chg_icl_ua = 500000; @@ -1942,6 +1800,10 @@ static int smblite_probe(struct platform_device *pdev) return -EINVAL; } + rc = smblite_iio_init(chip, pdev, indio_dev); + if (rc < 0) + return rc; + rc = smblite_chg_config_init(chip); if (rc < 0) { if (rc != -EPROBE_DEFER) @@ -1954,6 +1816,11 @@ static int smblite_probe(struct platform_device *pdev) pr_err("Couldn't parse device tree rc=%d\n", rc); return rc; } + /* set driver data before resources request it */ + platform_set_drvdata(pdev, chip); + + chg->chg_param.iio_read = smblite_direct_iio_read; + chg->chg_param.iio_write = smblite_direct_iio_write; rc = smblite_lib_init(chg); if (rc < 0) { @@ -1961,40 +1828,9 @@ static int smblite_probe(struct platform_device *pdev) return rc; } - /* set driver data before resources request it */ - platform_set_drvdata(pdev, chip); - - /* extcon registration */ - chg->extcon = devm_extcon_dev_allocate(chg->dev, - smblite_lib_extcon_cable); - if (IS_ERR(chg->extcon)) { - rc = PTR_ERR(chg->extcon); - dev_err(chg->dev, "Couldn't to allocate extcon device rc=%d\n", - rc); + rc = smblite_extcon_init(chg); + if (rc < 0) goto cleanup; - } - - rc = devm_extcon_dev_register(chg->dev, chg->extcon); - if (rc < 0) { - dev_err(chg->dev, "Couldn't to register extcon device rc=%d\n", - rc); - goto cleanup; - } - - /* Support reporting polarity and speed via properties */ - rc = extcon_set_property_capability(chg->extcon, - EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY); - rc |= extcon_set_property_capability(chg->extcon, - EXTCON_USB, EXTCON_PROP_USB_SS); - rc |= extcon_set_property_capability(chg->extcon, - EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY); - rc |= extcon_set_property_capability(chg->extcon, - EXTCON_USB_HOST, EXTCON_PROP_USB_SS); - if (rc < 0) { - dev_err(chg->dev, - "Couldn't to configure extcon capabilities\n"); - goto cleanup; - } rc = smblite_init_hw(chip); if (rc < 0) { @@ -2008,12 +1844,6 @@ static int smblite_probe(struct platform_device *pdev) goto cleanup; } - rc = smblite_init_usb_main_psy(chip); - if (rc < 0) { - pr_err("Couldn't initialize usb main psy rc=%d\n", rc); - goto cleanup; - } - rc = smblite_init_batt_psy(chip); if (rc < 0) { pr_err("Couldn't initialize batt psy rc=%d\n", rc); @@ -2094,13 +1924,16 @@ static void smblite_shutdown(struct platform_device *pdev) smblite_disable_interrupts(chg); /* configure power role for UFP */ - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) smblite_lib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_POWER_ROLE_CMD_MASK, EN_SNK_ONLY_BIT); } static const struct of_device_id match_table[] = { - { .compatible = "qcom,qpnp-smblite", }, + { + .compatible = "qcom,qpnp-smblite", + .data = (void *)PM2250, + }, { }, }; diff --git a/drivers/power/supply/qcom/smblite-iio.c b/drivers/power/supply/qcom/smblite-iio.c new file mode 100644 index 000000000000..3fa16f660972 --- /dev/null +++ b/drivers/power/supply/qcom/smblite-iio.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include "smblite-lib.h" +#include "smb5-iio.h" +#include "smblite-reg.h" +#include "schgm-flashlite.h" + +int smblite_iio_get_prop(struct smb_charger *chg, int channel, int *val) +{ + union power_supply_propval pval = {0, }; + int rc = 0; + + pval.intval = 0; + *val = 0; + + switch (channel) { + /* USB */ + case PSY_IIO_USB_REAL_TYPE: + *val = chg->real_charger_type; + break; + case PSY_IIO_TYPEC_MODE: + rc = smblite_lib_get_usb_prop_typec_mode(chg, val); + break; + case PSY_IIO_TYPEC_POWER_ROLE: + rc = smblite_lib_get_prop_typec_power_role(chg, val); + break; + case PSY_IIO_TYPEC_CC_ORIENTATION: + rc = smblite_lib_get_prop_typec_cc_orientation(chg, val); + break; + case PSY_IIO_USB_INPUT_CURRENT_SETTLED: + rc = smblite_lib_get_prop_input_current_settled(chg, val); + break; + case PSY_IIO_CONNECTOR_TYPE: + *val = chg->connector_type; + break; + case PSY_IIO_HW_CURRENT_MAX: + rc = smblite_lib_get_hw_current_max(chg, val); + break; + /* MAIN */ + case PSY_IIO_MAIN_INPUT_CURRENT_SETTLED: + rc = smblite_lib_get_prop_input_current_settled(chg, val); + if (!rc) + *val = pval.intval; + break; + case PSY_IIO_MAIN_INPUT_VOLTAGE_SETTLED: + rc = smblite_lib_get_prop_input_voltage_settled(chg, val); + break; + case PSY_IIO_FCC_DELTA: + val = 0; + break; + case PSY_IIO_FLASH_ACTIVE: + *val = chg->flash_active; + break; + case PSY_IIO_FLASH_TRIGGER: + *val = 0; + rc = schgm_flashlite_get_vreg_ok(chg, val); + break; + case PSY_IIO_CURRENT_MAX: + rc = smblite_lib_get_icl_current(chg, val); + break; + case PSY_IIO_VOLTAGE_MAX: + rc = smblite_lib_get_charge_param(chg, &chg->param.fv, val); + break; + case PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX: + rc = smblite_lib_get_charge_param(chg, &chg->param.fcc, val); + break; + case PSY_IIO_MAIN_FCC_MAX: + *val = chg->main_fcc_max; + break; + /* BATTERY */ + case PSY_IIO_CHARGER_TEMP: + rc = smblite_lib_get_prop_charger_temp(chg, val); + break; + case PSY_IIO_SW_JEITA_ENABLED: + *val = 1; + break; + case PSY_IIO_PARALLEL_DISABLE: + *val = get_client_vote(chg->pl_disable_votable, + USER_VOTER); + break; + case PSY_IIO_CHARGE_DONE: + rc = smblite_lib_get_prop_batt_charge_done(chg, val); + break; + case PSY_IIO_SET_SHIP_MODE: + /* Not in ship mode as long as device is active */ + *val = 0; + break; + case PSY_IIO_INPUT_CURRENT_LIMITED: + rc = smblite_lib_get_prop_input_current_limited(chg, val); + break; + case PSY_IIO_RECHARGE_SOC: + *val = chg->auto_recharge_soc; + break; + case PSY_IIO_FORCE_RECHARGE: + *val = 0; + break; + case PSY_IIO_FCC_STEPPER_ENABLE: + *val = chg->fcc_stepper_enable; + break; + case PSY_IIO_DIE_HEALTH: + rc = smblite_lib_get_die_health(chg, val); + break; + default: + pr_err("get prop %x is not supported\n", channel); + rc = -EINVAL; + break; + } + + if (rc < 0) { + pr_err("Couldn't get prop %x rc = %d\n", channel, rc); + return rc; + } + + return IIO_VAL_INT; +} + +int smblite_iio_set_prop(struct smb_charger *chg, int channel, int val) +{ + union power_supply_propval pval = {0, }; + int icl_ua, rc = 0; + + switch (channel) { + /* USB */ + case PSY_IIO_USB_REAL_TYPE: + rc = smblite_lib_set_prop_usb_type(chg, val); + break; + case PSY_IIO_TYPEC_POWER_ROLE: + rc = smblite_lib_set_prop_typec_power_role(chg, val); + break; + /* MAIN */ + case PSY_IIO_FLASH_ACTIVE: + if (chg->flash_active != val) { + chg->flash_active = val; + + rc = smblite_lib_get_prop_usb_present(chg, &pval); + if (rc < 0) + pr_err("Failed to get USB present status rc=%d\n", + rc); + if (!pval.intval) { + /* vote 100ma when usb is not present*/ + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, + true, USBIN_100UA); + } else if (chg->flash_active) { + icl_ua = get_effective_result_locked( + chg->usb_icl_votable); + if (icl_ua >= USBIN_400UA) { + vote(chg->usb_icl_votable, + FLASH_ACTIVE_VOTER, + true, icl_ua - USBIN_300UA); + } + } else { + vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER, + false, 0); + } + pr_debug("flash_active=%d usb_present=%d icl=%d\n", + chg->flash_active, pval.intval, + get_effective_result_locked( + chg->usb_icl_votable)); + } + break; + case PSY_IIO_VOLTAGE_MAX: + rc = smblite_lib_set_charge_param(chg, &chg->param.fv, val); + break; + case PSY_IIO_CURRENT_MAX: + rc = smblite_lib_set_icl_current(chg, val); + break; + case PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX: + rc = smblite_lib_set_charge_param(chg, &chg->param.fcc, val); + break; + case PSY_IIO_MAIN_FCC_MAX: + chg->main_fcc_max = val; + rerun_election(chg->fcc_votable); + break; + /* BATTERY */ + case PSY_IIO_SET_SHIP_MODE: + /* Not in ship mode as long as the device is active */ + if (!val) + break; + if (chg->iio_chan_list_smb_parallel) + rc = iio_write_channel_raw( + chg->iio_chan_list_smb_parallel[SMB_SET_SHIP_MODE], + val); + rc = smblite_lib_set_prop_ship_mode(chg, val); + break; + case PSY_IIO_RECHARGE_SOC: + rc = smblite_lib_set_prop_rechg_soc_thresh(chg, val); + break; + case PSY_IIO_FORCE_RECHARGE: + /* toggle charging to force recharge */ + vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER, + true, 0); + /* charge disable delay */ + msleep(50); + vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER, + false, 0); + break; + case PSY_IIO_FCC_STEPPER_ENABLE: + chg->fcc_stepper_enable = val; + break; + case PSY_IIO_DIE_HEALTH: + power_supply_changed(chg->batt_psy); + break; + default: + pr_err("get prop %d is not supported\n", channel); + rc = -EINVAL; + break; + } + + if (rc < 0) { + pr_err("Couldn't set prop %d rc = %d\n", channel, rc); + return rc; + } + + return 0; +} + +struct iio_channel **get_ext_channels(struct device *dev, + const char *const *channel_map, int size) +{ + int i, rc = 0; + struct iio_channel **iio_ch_ext; + + iio_ch_ext = devm_kcalloc(dev, size, sizeof(*iio_ch_ext), GFP_KERNEL); + if (!iio_ch_ext) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < size; i++) { + iio_ch_ext[i] = devm_iio_channel_get(dev, channel_map[i]); + + if (IS_ERR(iio_ch_ext[i])) { + rc = PTR_ERR(iio_ch_ext[i]); + if (rc != -EPROBE_DEFER) + dev_err(dev, "%s channel unavailable, %d\n", + channel_map[i], rc); + return ERR_PTR(rc); + } + } + + return iio_ch_ext; +} diff --git a/drivers/power/supply/qcom/smblite-lib.c b/drivers/power/supply/qcom/smblite-lib.c index 6740cc9350a9..885d445ccc59 100644 --- a/drivers/power/supply/qcom/smblite-lib.c +++ b/drivers/power/supply/qcom/smblite-lib.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. */ #include @@ -11,14 +11,17 @@ #include #include #include +#include #include -#include #include +#include +#include "battery-profile-loader.h" #include "smblite-lib.h" #include "smblite-reg.h" #include "step-chg-jeita.h" #include "storm-watch.h" #include "schgm-flashlite.h" +#include "smb5-iio.h" #define smblite_lib_err(chg, fmt, ...) \ pr_err("%s: %s: " fmt, chg->name, \ @@ -35,12 +38,12 @@ } while (0) #define typec_rp_med_high(chg, typec_mode) \ - ((typec_mode == POWER_SUPPLY_TYPEC_SOURCE_MEDIUM \ - || typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH) \ + ((typec_mode == QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM \ + || typec_mode == QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH) \ && (!chg->typec_legacy || chg->typec_legacy_use_rp_icl)) static void update_sw_icl_max(struct smb_charger *chg, - enum power_supply_type type); + int type); static int smblite_lib_get_prop_typec_mode(struct smb_charger *chg); int smblite_lib_read(struct smb_charger *chg, u16 addr, u8 *val) @@ -102,26 +105,6 @@ int smblite_lib_get_iio_channel(struct smb_charger *chg, const char *propname, #define DIV_FACTOR_MICRO_V_I 1 #define DIV_FACTOR_MILI_V_I 1000 #define DIV_FACTOR_DECIDEGC 100 -int smblite_lib_read_iio_channel(struct smb_charger *chg, - struct iio_channel *chan, int div, int *data) -{ - int rc = 0; - *data = -ENODATA; - - if (chan) { - rc = iio_read_channel_processed(chan, data); - if (rc < 0) { - smblite_lib_err(chg, "Error in reading IIO channel data, rc=%d\n", - rc); - return rc; - } - - if (div != 0) - *data /= div; - } - - return rc; -} int smblite_lib_icl_override(struct smb_charger *chg, enum icl_override_mode mode) @@ -166,17 +149,17 @@ int smblite_lib_icl_override(struct smb_charger *chg, static void smblite_lib_notify_extcon_props(struct smb_charger *chg, int id) { union extcon_property_value val; - union power_supply_propval prop_val; + int prop_val; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) { + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) { smblite_lib_get_prop_typec_cc_orientation(chg, &prop_val); - val.intval = ((prop_val.intval == 2) ? 1 : 0); + val.intval = ((prop_val == 2) ? 1 : 0); extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_TYPEC_POLARITY, val); val.intval = true; extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_SS, val); - } else if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { + } else if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) { val.intval = false; extcon_set_property(chg->extcon, id, EXTCON_PROP_USB_SS, val); @@ -260,21 +243,6 @@ int smblite_lib_get_charge_param(struct smb_charger *chg, return rc; } -int smblite_lib_get_usb_suspend(struct smb_charger *chg, int *suspend) -{ - int rc = 0; - u8 temp; - - rc = smblite_lib_read(chg, USBIN_INPUT_SUSPEND_REG, &temp); - if (rc < 0) { - smblite_lib_err(chg, "Couldn't read USBIN_CMD_IL rc=%d\n", rc); - return rc; - } - *suspend = temp & USBIN_SUSPEND_BIT; - - return rc; -} - #define INPUT_NOT_PRESENT 0 #define INPUT_PRESENT_USB BIT(1) static int smblite_lib_is_input_present(struct smb_charger *chg, @@ -360,18 +328,81 @@ int smblite_lib_set_usb_suspend(struct smb_charger *chg, bool suspend) /******************** * HELPER FUNCTIONS * ********************/ -int smblite_lib_get_prop_from_bms(struct smb_charger *chg, - enum power_supply_property psp, - union power_supply_propval *val) + +/* QG/FG channels */ +static const char * const smblite_lib_qg_ext_iio_chan[] = { + [SMB5_QG_DEBUG_BATTERY] = "debug_battery", + [SMB5_QG_CAPACITY] = "capacity", + [SMB5_QG_REAL_CAPACITY] = "real_capacity", + [SMB5_QG_CC_SOC] = "cc_soc", + [SMB5_QG_CURRENT_NOW] = "current_now", + [SMB5_QG_VOLTAGE_NOW] = "voltage_now", + [SMB5_QG_VOLTAGE_MAX] = "voltage_max", + [SMB5_QG_CHARGE_FULL] = "charge_full", + [SMB5_QG_RESISTANCE_ID] = "resistance_id", + [SMB5_QG_TEMP] = "temp", + [SMB5_QG_CHARGE_COUNTER] = "charge_counter", + [SMB5_QG_CYCLE_COUNT] = "cycle_count", + [SMB5_QG_CHARGE_FULL_DESIGN] = "charge_full_design", + [SMB5_QG_TIME_TO_FULL_NOW] = "time_to_full_now", +}; + +int smblite_lib_read_iio_prop(struct smb_charger *chg, + enum iio_type type, int iio_chan, int *val) +{ + struct iio_channel *iio_chan_list; + int rc; + + switch (type) { + case QG: + if (IS_ERR_OR_NULL(chg->iio_chan_list_qg)) + return -ENODEV; + iio_chan_list = chg->iio_chan_list_qg[iio_chan]; + break; + case SMB_PARALLEL: + if (IS_ERR_OR_NULL(chg->iio_chan_list_smb_parallel)) + return -ENODEV; + iio_chan_list = chg->iio_chan_list_smb_parallel[iio_chan]; + break; + default: + pr_err_ratelimited("iio_type %d is not supported\n", type); + return -EINVAL; + } + + rc = iio_read_channel_processed(iio_chan_list, val); + return rc < 0 ? rc : 0; +} + +int smblite_lib_write_iio_prop(struct smb_charger *chg, + enum iio_type type, int iio_chan, int val) +{ + struct iio_channel *iio_chan_list; + + switch (type) { + case QG: + if (IS_ERR_OR_NULL(chg->iio_chan_list_qg)) + return -ENODEV; + iio_chan_list = chg->iio_chan_list_qg[iio_chan]; + break; + default: + pr_err_ratelimited("iio_type %d is not supported\n", type); + return -EINVAL; + } + + return iio_write_channel_raw(iio_chan_list, val); +} + +int smblite_lib_get_prop_from_bms(struct smb_charger *chg, int channel, int *val) { int rc; - if (!chg->bms_psy) - return -EINVAL; + if (IS_ERR_OR_NULL(chg->iio_chan_list_qg)) + return -ENODEV; - rc = power_supply_get_property(chg->bms_psy, psp, val); + rc = iio_read_channel_processed(chg->iio_chan_list_qg[channel], + val); - return rc; + return rc < 0 ? rc : 0; } static void smblite_lib_update_usb_type(struct smb_charger *chg, @@ -388,8 +419,6 @@ static int smblite_lib_notifier_call(struct notifier_block *nb, struct smb_charger *chg = container_of(nb, struct smb_charger, nb); if (!strcmp(psy->desc->name, "bms")) { - if (!chg->bms_psy) - chg->bms_psy = psy; if (ev == PSY_EVENT_PROP_CHANGED) schedule_work(&chg->bms_update_work); } @@ -456,25 +485,27 @@ static void smblite_lib_uusb_removal(struct smb_charger *chg) void smblite_lib_suspend_on_debug_battery(struct smb_charger *chg) { - int rc; - union power_supply_propval val; + int rc, val; - rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_DEBUG_BATTERY, &val); + if (!chg->iio_chan_list_qg) + return; + + rc = smblite_lib_get_prop_from_bms(chg, SMB5_QG_DEBUG_BATTERY, + &val); if (rc < 0) { smblite_lib_err(chg, "Couldn't get debug battery prop rc=%d\n", rc); return; } if (chg->suspend_input_on_debug_batt) { - vote(chg->usb_icl_votable, DEBUG_BOARD_VOTER, val.intval, 0); - if (val.intval) { + vote(chg->usb_icl_votable, DEBUG_BOARD_VOTER, val, 0); + if (val) { pr_info("Input suspended: Fake battery\n"); schgm_flashlite_config_usbin_collapse(chg, false); } } else { vote(chg->chg_disable_votable, DEBUG_BOARD_VOTER, - val.intval, 0); + val, 0); } } @@ -524,7 +555,7 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) return rc; } -int smblite_lib_set_icl_current(struct smb_charger *chg, int icl_ua) +int smblite_lib_set_icl_current(struct smb_charger *chg, const int icl_ua) { int rc = 0; enum icl_override_mode icl_override = HW_AUTO_MODE; @@ -535,7 +566,7 @@ int smblite_lib_set_icl_current(struct smb_charger *chg, int icl_ua) TORCH_BUCK_MODE); /* Do not configure ICL from SW for DAM */ if (smblite_lib_get_prop_typec_mode(chg) == - POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) + QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) return 0; if (suspend) @@ -548,8 +579,9 @@ int smblite_lib_set_icl_current(struct smb_charger *chg, int icl_ua) /* configure current */ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB && (chg->typec_legacy - || chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT - || chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) { + || chg->typec_mode == QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT + || chg->connector_type == + QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB)) { rc = set_sdp_current(chg, icl_ua); if (rc < 0) { smblite_lib_err(chg, "Couldn't set SDP ICL rc=%d\n", @@ -698,10 +730,9 @@ static int smblite_lib_temp_change_irq_disable_vote_callback( ********************/ int smblite_lib_get_prop_input_suspend(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { - val->intval - = (get_client_vote(chg->usb_icl_votable, USER_VOTER) == 0); + *val = (get_client_vote(chg->usb_icl_votable, USER_VOTER) == 0); return 0; } @@ -733,8 +764,10 @@ int smblite_lib_get_prop_batt_capacity(struct smb_charger *chg, return 0; } - rc = smblite_lib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CAPACITY, - val); + rc = smblite_lib_get_prop_from_bms(chg, SMB5_QG_CAPACITY, + &val->intval); + if (rc < 0) + smblite_lib_err(chg, "Couldn't get capacity prop rc=%d\n", rc); return rc; } @@ -765,7 +798,7 @@ int smblite_lib_get_prop_batt_status(struct smb_charger *chg, if (chg->fake_chg_status_on_debug_batt) { rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_DEBUG_BATTERY, &pval); + SMB5_QG_DEBUG_BATTERY, &pval.intval); if (rc < 0) { pr_err_ratelimited("Couldn't get debug battery prop rc=%d\n", rc); @@ -781,10 +814,10 @@ int smblite_lib_get_prop_batt_status(struct smb_charger *chg, */ smblite_lib_is_input_present(chg, &input_present); rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CAPACITY, &pval); + SMB5_QG_CAPACITY, &pval.intval); if (!rc && pval.intval == 0 && input_present) { rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CURRENT_NOW, &pval); + SMB5_QG_CURRENT_NOW, &pval.intval); if (!rc && pval.intval > 0) { if (chg->cutoff_count > CUTOFF_COUNT) { val->intval = POWER_SUPPLY_STATUS_DISCHARGING; @@ -886,7 +919,7 @@ int smblite_lib_get_prop_batt_charge_type(struct smb_charger *chg, val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; break; case TAPER_CHARGE: - val->intval = POWER_SUPPLY_CHARGE_TYPE_TAPER; + val->intval = POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE; break; default: val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; @@ -913,8 +946,8 @@ int smblite_lib_get_prop_batt_health(struct smb_charger *chg, stat); if (stat & BAT_OV_BIT) { - rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + rc = smblite_lib_get_prop_from_bms(chg, SMB5_QG_VOLTAGE_NOW, + &pval.intval); if (!rc) { /* * If Vbatt is within 40mV above Vfloat, then don't @@ -966,18 +999,23 @@ int smblite_lib_get_prop_system_temp_level_max(struct smb_charger *chg, } int smblite_lib_get_prop_input_current_limited(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { u8 stat; int rc; + if (chg->input_current_limited >= 0) { + *val = chg->input_current_limited; + return 0; + } + rc = smblite_lib_read(chg, AICL_STATUS_REG, &stat); if (rc < 0) { smblite_lib_err(chg, "Couldn't read AICL_STATUS rc=%d\n", rc); return rc; } - val->intval = (stat & SOFT_ILIMIT_BIT); + *val = (stat & SOFT_ILIMIT_BIT); return 0; } @@ -1024,7 +1062,7 @@ int smblite_lib_get_prop_batt_iterm(struct smb_charger *chg, } int smblite_lib_get_prop_batt_charge_done(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc; u8 stat; @@ -1037,19 +1075,23 @@ int smblite_lib_get_prop_batt_charge_done(struct smb_charger *chg, } stat = stat & BATTERY_CHARGER_STATUS_MASK; - val->intval = (stat == TERMINATE_CHARGE); + *val = (stat == TERMINATE_CHARGE); + return 0; } int smblite_lib_get_batt_current_now(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc; rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CURRENT_NOW, val); + SMB5_QG_CURRENT_NOW, val); if (!rc) - val->intval *= (-1); + *val *= (-1); + else + smblite_lib_err(chg, "Couldn't get current_now prop rc=%d\n", + rc); return rc; } @@ -1057,17 +1099,16 @@ int smblite_lib_get_batt_current_now(struct smb_charger *chg, /*********************** * BATTERY PSY SETTERS * ***********************/ - int smblite_lib_set_prop_input_suspend(struct smb_charger *chg, - const union power_supply_propval *val) + const int val) { int rc; /* vote 0mA when suspended */ - rc = vote(chg->usb_icl_votable, USER_VOTER, (bool)val->intval, 0); + rc = vote(chg->usb_icl_votable, USER_VOTER, (bool)val, 0); if (rc < 0) { smblite_lib_err(chg, "Couldn't vote to %s USB rc=%d\n", - (bool)val->intval ? "suspend" : "resume", rc); + (bool)val ? "suspend" : "resume", rc); return rc; } @@ -1127,10 +1168,10 @@ int smblite_lib_set_prop_system_temp_level(struct smb_charger *chg, } int smblite_lib_set_prop_rechg_soc_thresh(struct smb_charger *chg, - const union power_supply_propval *val) + const int val) { int rc; - u8 new_thr = DIV_ROUND_CLOSEST(val->intval * 255, 100); + u8 new_thr = DIV_ROUND_CLOSEST(val * 255, 100); rc = smblite_lib_write(chg, CHARGE_RCHG_SOC_THRESHOLD_CFG_REG, new_thr); @@ -1140,7 +1181,7 @@ int smblite_lib_set_prop_rechg_soc_thresh(struct smb_charger *chg, return rc; } - chg->auto_recharge_soc = val->intval; + chg->auto_recharge_soc = val; return rc; } @@ -1290,7 +1331,7 @@ out: } int smblite_lib_get_prop_charger_temp(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int temp, rc; int input_present; @@ -1309,7 +1350,7 @@ int smblite_lib_get_prop_charger_temp(struct smb_charger *chg, pr_err("Error in reading temp channel, rc=%d\n", rc); return rc; } - val->intval = temp / 100; + *val = temp / 100; } else { return -ENODATA; } @@ -1318,14 +1359,14 @@ int smblite_lib_get_prop_charger_temp(struct smb_charger *chg, } int smblite_lib_get_prop_typec_cc_orientation(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc = 0; u8 stat; - val->intval = 0; + *val = 0; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; rc = smblite_lib_read(chg, TYPE_C_MISC_STATUS_REG, &stat); @@ -1337,22 +1378,22 @@ int smblite_lib_get_prop_typec_cc_orientation(struct smb_charger *chg, smblite_lib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n", stat); if (stat & CC_ATTACHED_BIT) - val->intval = (bool)(stat & CC_ORIENTATION_BIT) + 1; + *val = (bool)(stat & CC_ORIENTATION_BIT) + 1; return rc; } static const char * const smblite_lib_typec_mode_name[] = { - [POWER_SUPPLY_TYPEC_NONE] = "NONE", - [POWER_SUPPLY_TYPEC_SOURCE_DEFAULT] = "SOURCE_DEFAULT", - [POWER_SUPPLY_TYPEC_SOURCE_MEDIUM] = "SOURCE_MEDIUM", - [POWER_SUPPLY_TYPEC_SOURCE_HIGH] = "SOURCE_HIGH", - [POWER_SUPPLY_TYPEC_NON_COMPLIANT] = "NON_COMPLIANT", - [POWER_SUPPLY_TYPEC_SINK] = "SINK", - [POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE] = "SINK_POWERED_CABLE", - [POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY] = "SINK_DEBUG_ACCESSORY", - [POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER] = "SINK_AUDIO_ADAPTER", - [POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY] = "POWERED_CABLE_ONLY", + [QTI_POWER_SUPPLY_TYPEC_NONE] = "NONE", + [QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT] = "SOURCE_DEFAULT", + [QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM] = "SOURCE_MEDIUM", + [QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH] = "SOURCE_HIGH", + [QTI_POWER_SUPPLY_TYPEC_NON_COMPLIANT] = "NON_COMPLIANT", + [QTI_POWER_SUPPLY_TYPEC_SINK] = "SINK", + [QTI_POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE] = "SINK_POWERED_CABLE", + [QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY] = "SINK_DEBUG_ACCESSORY", + [QTI_POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER] = "SINK_AUDIO_ADAPTER", + [QTI_POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY] = "POWERED_CABLE_ONLY", }; static int smblite_lib_get_prop_ufp_mode(struct smb_charger *chg) @@ -1364,28 +1405,28 @@ static int smblite_lib_get_prop_ufp_mode(struct smb_charger *chg) if (rc < 0) { smblite_lib_err(chg, "Couldn't read TYPE_C_STATUS_1 rc=%d\n", rc); - return POWER_SUPPLY_TYPEC_NONE; + return QTI_POWER_SUPPLY_TYPEC_NONE; } smblite_lib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_1 = 0x%02x\n", stat); switch (stat & DETECTED_SRC_TYPE_MASK) { case SNK_RP_STD_BIT: - return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; + return QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; case SNK_RP_1P5_BIT: - return POWER_SUPPLY_TYPEC_SOURCE_MEDIUM; + return QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM; case SNK_RP_3P0_BIT: - return POWER_SUPPLY_TYPEC_SOURCE_HIGH; + return QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH; case SNK_RP_SHORT_BIT: - return POWER_SUPPLY_TYPEC_NON_COMPLIANT; + return QTI_POWER_SUPPLY_TYPEC_NON_COMPLIANT; case SNK_DAM_500MA_BIT: case SNK_DAM_1500MA_BIT: case SNK_DAM_3000MA_BIT: - return POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY; + return QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY; default: break; } - return POWER_SUPPLY_TYPEC_NONE; + return QTI_POWER_SUPPLY_TYPEC_NONE; } static int smblite_lib_get_prop_dfp_mode(struct smb_charger *chg) @@ -1397,23 +1438,23 @@ static int smblite_lib_get_prop_dfp_mode(struct smb_charger *chg) if (rc < 0) { smblite_lib_err(chg, "Couldn't read TYPE_C_SRC_STATUS_REG rc=%d\n", rc); - return POWER_SUPPLY_TYPEC_NONE; + return QTI_POWER_SUPPLY_TYPEC_NONE; } smblite_lib_dbg(chg, PR_REGISTER, "TYPE_C_SRC_STATUS_REG = 0x%02x\n", stat); switch (stat & DETECTED_SNK_TYPE_MASK) { case AUDIO_ACCESS_RA_RA_BIT: - return POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER; + return QTI_POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER; case SRC_DEBUG_ACCESS_BIT: - return POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY; + return QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY; case SRC_RD_OPEN_BIT: - return POWER_SUPPLY_TYPEC_SINK; + return QTI_POWER_SUPPLY_TYPEC_SINK; default: break; } - return POWER_SUPPLY_TYPEC_NONE; + return QTI_POWER_SUPPLY_TYPEC_NONE; } static int smblite_lib_get_prop_typec_mode(struct smb_charger *chg) @@ -1421,8 +1462,8 @@ static int smblite_lib_get_prop_typec_mode(struct smb_charger *chg) int rc; u8 stat; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) - return POWER_SUPPLY_TYPEC_NONE; + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) + return QTI_POWER_SUPPLY_TYPEC_NONE; rc = smblite_lib_read(chg, TYPE_C_MISC_STATUS_REG, &stat); if (rc < 0) { @@ -1440,24 +1481,24 @@ static int smblite_lib_get_prop_typec_mode(struct smb_charger *chg) } inline int smblite_lib_get_usb_prop_typec_mode(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) - val->intval = POWER_SUPPLY_TYPEC_NONE; + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) + *val = QTI_POWER_SUPPLY_TYPEC_NONE; else - val->intval = chg->typec_mode; + *val = chg->typec_mode; return 0; } int smblite_lib_get_prop_typec_power_role(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc = 0; u8 ctrl; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { - val->intval = POWER_SUPPLY_TYPEC_PR_NONE; + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) { + *val = QTI_POWER_SUPPLY_TYPEC_PR_NONE; return 0; } @@ -1471,49 +1512,43 @@ int smblite_lib_get_prop_typec_power_role(struct smb_charger *chg, ctrl); if (ctrl & TYPEC_DISABLE_CMD_BIT) { - val->intval = POWER_SUPPLY_TYPEC_PR_NONE; + *val = QTI_POWER_SUPPLY_TYPEC_PR_NONE; return rc; } switch (ctrl & (EN_SRC_ONLY_BIT | EN_SNK_ONLY_BIT)) { case 0: - val->intval = POWER_SUPPLY_TYPEC_PR_DUAL; + *val = QTI_POWER_SUPPLY_TYPEC_PR_DUAL; break; case EN_SRC_ONLY_BIT: - val->intval = POWER_SUPPLY_TYPEC_PR_SOURCE; + *val = QTI_POWER_SUPPLY_TYPEC_PR_SOURCE; break; case EN_SNK_ONLY_BIT: - val->intval = POWER_SUPPLY_TYPEC_PR_SINK; + *val = QTI_POWER_SUPPLY_TYPEC_PR_SINK; break; default: - val->intval = POWER_SUPPLY_TYPEC_PR_NONE; + *val = QTI_POWER_SUPPLY_TYPEC_PR_NONE; smblite_lib_err(chg, "unsupported power role 0x%02lx\n", ctrl & (EN_SRC_ONLY_BIT | EN_SNK_ONLY_BIT)); return -EINVAL; } - chg->power_role = val->intval; + chg->power_role = *val; return rc; } -static inline bool typec_in_src_mode(struct smb_charger *chg) -{ - return (chg->typec_mode > POWER_SUPPLY_TYPEC_NONE && - chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEFAULT); -} - int smblite_lib_get_prop_input_current_settled(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { return smblite_lib_get_charge_param(chg, &chg->param.icl_stat, - &val->intval); + val); } int smblite_lib_get_prop_input_voltage_settled(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { /* TODO: do we need to read the real VBUS */ - val->intval = 5000000; + *val = 5000000; return 0; } @@ -1550,9 +1585,9 @@ int smblite_lib_get_prop_die_health(struct smb_charger *chg) } int smblite_lib_get_die_health(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { - val->intval = smblite_lib_get_prop_die_health(chg); + *val = smblite_lib_get_prop_die_health(chg); return 0; } @@ -1579,12 +1614,11 @@ static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode) int rp_ua; switch (typec_mode) { - case POWER_SUPPLY_TYPEC_SOURCE_HIGH: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH: rp_ua = TYPEC_HIGH_CURRENT_UA; break; - case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: - case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: - 'fallthrough;' + case QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: default : rp_ua = DCP_CURRENT_UA; } @@ -1597,12 +1631,12 @@ static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode) * *****************/ int smblite_lib_set_prop_usb_type(struct smb_charger *chg, - const union power_supply_propval *val) + const int val) { smblite_lib_dbg(chg, PR_MISC, - "Charger type request form USB driver type=%d\n", val->intval); + "Charger type request form USB driver type=%d\n", val); /* update real charger type */ - smblite_lib_update_usb_type(chg, val->intval); + smblite_lib_update_usb_type(chg, val); /* For SDP rely on USB enumeration based reported the current */ if ((chg->real_charger_type == POWER_SUPPLY_TYPE_USB) @@ -1640,7 +1674,7 @@ int smblite_lib_set_prop_current_max(struct smb_charger *chg, } /* Update TypeC Rp based current */ - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) { + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) { update_sw_icl_max(chg, chg->real_charger_type); } else if (is_flashlite_active(chg) && (val->intval >= USBIN_400UA)) { /* For Uusb based SDP port */ @@ -1654,39 +1688,39 @@ int smblite_lib_set_prop_current_max(struct smb_charger *chg, } int smblite_lib_set_prop_typec_power_role(struct smb_charger *chg, - const union power_supply_propval *val) + const int val) { int rc = 0; u8 power_role; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return -EINVAL; smblite_lib_dbg(chg, PR_MISC, "power role change: %d --> %d!", - chg->power_role, val->intval); + chg->power_role, val); - if (chg->power_role == val->intval) { + if (chg->power_role == val) { smblite_lib_dbg(chg, PR_MISC, "power role already in %d, ignore!", chg->power_role); return 0; } - switch (val->intval) { - case POWER_SUPPLY_TYPEC_PR_NONE: + switch (val) { + case QTI_POWER_SUPPLY_TYPEC_PR_NONE: power_role = TYPEC_DISABLE_CMD_BIT; break; - case POWER_SUPPLY_TYPEC_PR_DUAL: + case QTI_POWER_SUPPLY_TYPEC_PR_DUAL: power_role = 0; break; - case POWER_SUPPLY_TYPEC_PR_SINK: + case QTI_POWER_SUPPLY_TYPEC_PR_SINK: power_role = EN_SNK_ONLY_BIT; break; - case POWER_SUPPLY_TYPEC_PR_SOURCE: + case QTI_POWER_SUPPLY_TYPEC_PR_SOURCE: power_role = EN_SRC_ONLY_BIT; break; default: smblite_lib_err(chg, "power role %d not supported\n", - val->intval); + val); return -EINVAL; } @@ -1700,22 +1734,22 @@ int smblite_lib_set_prop_typec_power_role(struct smb_charger *chg, return rc; } - chg->power_role = val->intval; + chg->power_role = val; return rc; } int smblite_lib_set_prop_ship_mode(struct smb_charger *chg, - const union power_supply_propval *val) + const int val) { int rc; - smblite_lib_dbg(chg, PR_MISC, "Set ship mode: %d!!\n", !!val->intval); + smblite_lib_dbg(chg, PR_MISC, "Set ship mode: %d!!\n", !!val); rc = smblite_lib_masked_write(chg, SHIP_MODE_REG, SHIP_MODE_EN_BIT, - !!val->intval ? SHIP_MODE_EN_BIT : 0); + !!val ? SHIP_MODE_EN_BIT : 0); if (rc < 0) dev_err(chg->dev, "Couldn't %s ship mode, rc=%d\n", - !!val->intval ? "enable" : "disable", rc); + !!val ? "enable" : "disable", rc); return rc; } @@ -1878,7 +1912,7 @@ int smblite_lib_get_hw_current_max(struct smb_charger *chg, non_compliant = stat & TYPEC_NONCOMP_LEGACY_CABLE_STATUS_BIT; /* get settled ICL */ - rc = smblite_lib_get_prop_input_current_settled(chg, &val); + rc = smblite_lib_get_prop_input_current_settled(chg, &val.intval); if (rc < 0) { smblite_lib_err(chg, "Couldn't get settled ICL rc=%d\n", rc); return rc; @@ -1886,7 +1920,7 @@ int smblite_lib_get_hw_current_max(struct smb_charger *chg, typec_source_rd = smblite_lib_get_prop_ufp_mode(chg); - if ((chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if ((chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) || (non_compliant && !chg->typec_legacy_use_rp_icl)) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_CDP: @@ -1905,7 +1939,7 @@ int smblite_lib_get_hw_current_max(struct smb_charger *chg, } switch (typec_source_rd) { - case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_CDP: current_ua = CDP_CURRENT_UA; @@ -1918,14 +1952,14 @@ int smblite_lib_get_hw_current_max(struct smb_charger *chg, break; } break; - case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: current_ua = TYPEC_MEDIUM_CURRENT_UA; break; - case POWER_SUPPLY_TYPEC_SOURCE_HIGH: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH: current_ua = TYPEC_HIGH_CURRENT_UA; break; - case POWER_SUPPLY_TYPEC_NON_COMPLIANT: - case POWER_SUPPLY_TYPEC_NONE: + case QTI_POWER_SUPPLY_TYPEC_NON_COMPLIANT: + case QTI_POWER_SUPPLY_TYPEC_NONE: default: current_ua = 0; break; @@ -2164,13 +2198,13 @@ static int typec_partner_register(struct smb_charger *chg) } } - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) goto unlock; typec_mode = smblite_lib_get_prop_typec_mode(chg); - if (typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT - || typec_mode == POWER_SUPPLY_TYPEC_NONE) { + if (typec_mode >= QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT + || typec_mode == QTI_POWER_SUPPLY_TYPEC_NONE) { if (chg->typec_role_swap_failed) { rc = smblite_lib_role_switch_failure(chg); if (rc < 0) @@ -2227,7 +2261,7 @@ static void smblite_lib_micro_usb_plugin(struct smb_charger *chg, } #define PL_DELAY_MS 30000 -void smblite_lib_usb_plugin_locked(struct smb_charger *chg) +static void smblite_lib_usb_plugin_locked(struct smb_charger *chg) { int rc; u8 stat; @@ -2297,7 +2331,7 @@ void smblite_lib_usb_plugin_locked(struct smb_charger *chg) } } - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) smblite_lib_micro_usb_plugin(chg, vbus_rising); vote(chg->temp_change_irq_disable_votable, DEFAULT_VOTER, @@ -2318,12 +2352,12 @@ irqreturn_t smblite_usb_plugin_irq_handler(int irq, void *data) } static void update_sw_icl_max(struct smb_charger *chg, - enum power_supply_type type) + int type) { int typec_mode; int rp_ua, icl_ua; - if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + if (chg->typec_mode == QTI_POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000); return; } @@ -2471,7 +2505,7 @@ int smblite_lib_typec_port_type_set(const struct typec_capability *cap, struct smb_charger, typec_caps); int rc = 0; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; mutex_lock(&chg->typec_lock); @@ -2516,7 +2550,7 @@ static void smblite_lib_typec_role_check_work(struct work_struct *work) role_reversal_check.work); int rc = 0; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) { chg->pr_swap_in_progress = false; vote(chg->awake_votable, TYPEC_SWAP_VOTER, false, 0); return; @@ -2526,7 +2560,7 @@ static void smblite_lib_typec_role_check_work(struct work_struct *work) switch (chg->dr_mode) { case TYPEC_PORT_SNK: - if (chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { + if (chg->typec_mode < QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { smblite_lib_dbg(chg, PR_MISC, "Role reversal not latched to UFP in %d msecs. Resetting to DRP mode\n", ROLE_REVERSAL_DELAY_MS); rc = smblite_lib_force_dr_mode(chg, TYPEC_PORT_DRP); @@ -2534,15 +2568,15 @@ static void smblite_lib_typec_role_check_work(struct work_struct *work) smblite_lib_err(chg, "Couldn't to set DRP mode, rc=%d\n", rc); } else { - chg->power_role = POWER_SUPPLY_TYPEC_PR_SINK; + chg->power_role = QTI_POWER_SUPPLY_TYPEC_PR_SINK; typec_set_pwr_role(chg->typec_port, TYPEC_SINK); typec_set_data_role(chg->typec_port, TYPEC_DEVICE); smblite_lib_dbg(chg, PR_MISC, "Role changed successfully to SINK"); } break; case TYPEC_PORT_SRC: - if (chg->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT - || chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) { + if (chg->typec_mode >= QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT + || chg->typec_mode == QTI_POWER_SUPPLY_TYPEC_NONE) { smblite_lib_dbg(chg, PR_MISC, "Role reversal not latched to DFP in %d msecs. Resetting to DRP mode\n", ROLE_REVERSAL_DELAY_MS); chg->pr_swap_in_progress = false; @@ -2553,7 +2587,7 @@ static void smblite_lib_typec_role_check_work(struct work_struct *work) smblite_lib_err(chg, "Couldn't to set DRP mode, rc=%d\n", rc); } else { - chg->power_role = POWER_SUPPLY_TYPEC_PR_SOURCE; + chg->power_role = QTI_POWER_SUPPLY_TYPEC_PR_SOURCE; typec_set_pwr_role(chg->typec_port, TYPEC_SOURCE); typec_set_data_role(chg->typec_port, TYPEC_HOST); smblite_lib_dbg(chg, PR_MISC, "Role changed successfully to SOURCE"); @@ -2656,7 +2690,7 @@ irqreturn_t smblite_typec_state_change_irq_handler(int irq, void *data) struct smb_charger *chg = irq_data->parent_data; int typec_mode; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) { smblite_lib_dbg(chg, PR_INTERRUPT, "Ignoring for micro USB\n"); return IRQ_HANDLED; @@ -2686,7 +2720,7 @@ irqreturn_t smblite_typec_attach_detach_irq_handler(int irq, void *data) int rc; /* IRQ not expected to be executed for uUSB, return */ - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return IRQ_HANDLED; smblite_lib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); @@ -2709,7 +2743,7 @@ irqreturn_t smblite_typec_attach_detach_irq_handler(int irq, void *data) } if (smblite_lib_get_prop_dfp_mode(chg) == - POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + QTI_POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { chg->sink_src_mode = AUDIO_ACCESS_MODE; typec_ra_ra_insertion(chg); } else if (stat & SNK_SRC_MODE_BIT) { @@ -2958,6 +2992,27 @@ static void bms_update_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, bms_update_work); + struct iio_channel **qg_list; + int rc; + + if (IS_ERR(chg->iio_chan_list_qg)) + return; + + if (!chg->iio_chan_list_qg) { + qg_list = get_ext_channels(chg->dev, + smblite_lib_qg_ext_iio_chan, + ARRAY_SIZE(smblite_lib_qg_ext_iio_chan)); + if (IS_ERR(qg_list)) { + rc = PTR_ERR(qg_list); + if (rc != -EPROBE_DEFER) { + dev_err(chg->dev, "Failed to get channels, %d\n", + rc); + chg->iio_chan_list_qg = ERR_PTR(-EINVAL); + } + return; + } + chg->iio_chan_list_qg = qg_list; + } smblite_lib_suspend_on_debug_battery(chg); @@ -2978,7 +3033,7 @@ static void smblite_lib_icl_change_work(struct work_struct *work) return; } - power_supply_changed(chg->usb_main_psy); + power_supply_changed(chg->batt_psy); smblite_lib_dbg(chg, PR_INTERRUPT, "icl_settled=%d\n", settled_ua); } @@ -3097,11 +3152,11 @@ static void jeita_update_work(struct work_struct *work) } /* if BMS is not ready, defer the work */ - if (!chg->bms_psy) + if (IS_ERR_OR_NULL(chg->iio_chan_list_qg)) return; rc = smblite_lib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_RESISTANCE_ID, &val); + SMB5_QG_RESISTANCE_ID, &val.intval); if (rc < 0) { smblite_lib_err(chg, "Couldn't to get batt-id rc=%d\n", rc); goto out; @@ -3352,6 +3407,7 @@ static void smblite_lib_iio_deinit(struct smb_charger *chg) int smblite_lib_init(struct smb_charger *chg) { int rc = 0; + struct iio_channel **iio_list; INIT_WORK(&chg->bms_update_work, bms_update_work); INIT_WORK(&chg->jeita_update_work, jeita_update_work); @@ -3369,17 +3425,20 @@ int smblite_lib_init(struct smb_charger *chg) chg->sink_src_mode = UNATTACHED_MODE; chg->jeita_configured = false; chg->dr_mode = TYPEC_PORT_DRP; + chg->flash_active = false; + chg->input_current_limited = -EINVAL; switch (chg->mode) { case PARALLEL_MASTER: - rc = qcom_batt_init(&chg->chg_param); + rc = qcom_batt_init(chg->dev, &chg->chg_param); if (rc < 0) { smblite_lib_err(chg, "Couldn't init qcom_batt_init rc=%d\n", rc); return rc; } - rc = qcom_step_chg_init(chg->dev, true, true, false); + rc = qcom_step_chg_init(chg->dev, true, true, false, + chg->iio_chans); if (rc < 0) { smblite_lib_err(chg, "Couldn't init qcom_step_chg_init rc=%d\n", rc); @@ -3393,7 +3452,11 @@ int smblite_lib_init(struct smb_charger *chg) return rc; } - chg->bms_psy = power_supply_get_by_name("bms"); + iio_list = get_ext_channels(chg->dev, smblite_lib_qg_ext_iio_chan, + ARRAY_SIZE(smblite_lib_qg_ext_iio_chan)); + if (!IS_ERR(iio_list)) + chg->iio_chan_list_qg = iio_list; + rc = smblite_lib_register_notifier(chg); if (rc < 0) { smblite_lib_err(chg, diff --git a/drivers/power/supply/qcom/smblite-lib.h b/drivers/power/supply/qcom/smblite-lib.h index 9bfb9c97eb8a..735b2a73d54a 100644 --- a/drivers/power/supply/qcom/smblite-lib.h +++ b/drivers/power/supply/qcom/smblite-lib.h @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. */ #ifndef __SMBLITE_LIB_H #define __SMBLITE_LIB_H + #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include "storm-watch.h" #include "battery.h" @@ -225,6 +227,10 @@ struct smb_iio { struct iio_channel *usbin_v_chan; }; +enum pmic_type { + PM2250, +}; + struct smb_charger { struct device *dev; char *name; @@ -232,6 +238,9 @@ struct smb_charger { struct smb_irq_info *irq_info; struct smb_params param; struct smb_iio iio; + struct iio_channel *iio_chans; + struct iio_channel **iio_chan_list_qg; + struct iio_channel **iio_chan_list_smb_parallel; int *debug_mask; enum smb_mode mode; int weak_chg_icl_ua; @@ -242,8 +251,6 @@ struct smb_charger { /* power supplies */ struct power_supply *batt_psy; struct power_supply *usb_psy; - struct power_supply *bms_psy; - struct power_supply *usb_main_psy; enum power_supply_type real_charger_type; /* notifiers */ @@ -297,6 +304,8 @@ struct smb_charger { int typec_mode; int dr_mode; int term_vbat_uv; + int input_current_limited; + int main_fcc_max; u32 jeita_status; bool jeita_arb_flag; bool typec_legacy; @@ -350,11 +359,9 @@ int smblite_lib_batch_read(struct smb_charger *chg, u16 addr, u8 *val, int count); int smblite_lib_get_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int *val_u); -int smblite_lib_get_usb_suspend(struct smb_charger *chg, int *suspend); int smblite_lib_enable_charging(struct smb_charger *chg, bool enable); int smblite_lib_set_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int val_u); -int smblite_lib_set_usb_suspend(struct smb_charger *chg, bool suspend); irqreturn_t smblite_default_irq_handler(int irq, void *data); irqreturn_t smblite_chg_state_change_irq_handler(int irq, void *data); @@ -373,8 +380,6 @@ irqreturn_t smblite_temp_change_irq_handler(int irq, void *data); irqreturn_t smblite_usbin_ov_irq_handler(int irq, void *data); irqreturn_t smblite_usb_id_irq_handler(int irq, void *data); -int smblite_lib_get_prop_input_suspend(struct smb_charger *chg, - union power_supply_propval *val); int smblite_lib_get_prop_batt_present(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_prop_batt_capacity(struct smb_charger *chg, @@ -384,21 +389,21 @@ int smblite_lib_get_prop_batt_status(struct smb_charger *chg, int smblite_lib_get_prop_batt_charge_type(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_prop_batt_charge_done(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_batt_current_now(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_batt_health(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_prop_system_temp_level(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_prop_system_temp_level_max(struct smb_charger *chg, union power_supply_propval *val); -int smblite_lib_get_prop_input_current_limited(struct smb_charger *chg, - union power_supply_propval *val); int smblite_lib_get_prop_batt_iterm(struct smb_charger *chg, union power_supply_propval *val); +int smblite_lib_get_prop_input_suspend(struct smb_charger *chg, + int *val); int smblite_lib_set_prop_input_suspend(struct smb_charger *chg, - const union power_supply_propval *val); + const int val); int smblite_lib_set_prop_batt_capacity(struct smb_charger *chg, const union power_supply_propval *val); int smblite_lib_set_prop_batt_status(struct smb_charger *chg, @@ -411,67 +416,57 @@ int smblite_lib_get_prop_usb_online(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_usb_online(struct smb_charger *chg, union power_supply_propval *val); -int smblite_lib_get_prop_usb_suspend(struct smb_charger *chg, - union power_supply_propval *val); +int smblite_lib_get_prop_input_current_limited(struct smb_charger *chg, + int *val); int smblite_lib_get_prop_usb_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_usb_prop_typec_mode(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_typec_cc_orientation(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_scope(struct smb_charger *chg, union power_supply_propval *val); int smblite_lib_get_prop_typec_power_role(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_input_current_settled(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_input_voltage_settled(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_charger_temp(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_get_prop_die_health(struct smb_charger *chg); int smblite_lib_get_die_health(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblite_lib_set_prop_current_max(struct smb_charger *chg, const union power_supply_propval *val); int smblite_lib_set_prop_typec_power_role(struct smb_charger *chg, - const union power_supply_propval *val); + const int val); int smblite_lib_set_prop_ship_mode(struct smb_charger *chg, - const union power_supply_propval *val); + const int val); int smblite_lib_set_prop_rechg_soc_thresh(struct smb_charger *chg, - const union power_supply_propval *val); + const int val); void smblite_lib_suspend_on_debug_battery(struct smb_charger *chg); -int smblite_lib_get_prop_fcc_delta(struct smb_charger *chg, - union power_supply_propval *val); -int smblite_lib_get_thermal_threshold(struct smb_charger *chg, u16 addr, - int *val); int smblite_lib_run_aicl(struct smb_charger *chg, int type); -int smblite_lib_set_icl_current(struct smb_charger *chg, int icl_ua); +int smblite_lib_set_icl_current(struct smb_charger *chg, const int icl_ua); int smblite_lib_get_icl_current(struct smb_charger *chg, int *icl_ua); int smblite_lib_get_charge_current(struct smb_charger *chg, int *total_current_ua); int smblite_lib_get_hw_current_max(struct smb_charger *chg, int *total_current_ua); -int smblite_lib_get_prop_pr_swap_in_progress(struct smb_charger *chg, - union power_supply_propval *val); -int smblite_lib_set_prop_pr_swap_in_progress(struct smb_charger *chg, - const union power_supply_propval *val); int smblite_lib_typec_port_type_set(const struct typec_capability *cap, enum typec_port_type type); -int smblite_lib_get_prop_from_bms(struct smb_charger *chg, - enum power_supply_property psp, - union power_supply_propval *val); +int smblite_lib_get_prop_from_bms(struct smb_charger *chg, int channel, + int *val); int smblite_lib_get_iio_channel(struct smb_charger *chg, const char *propname, struct iio_channel **chan); -int smblite_lib_read_iio_channel(struct smb_charger *chg, - struct iio_channel *chan, int div, int *data); int smblite_lib_icl_override(struct smb_charger *chg, enum icl_override_mode mode); -int smblite_lib_get_irq_status(struct smb_charger *chg, - union power_supply_propval *val); int smblite_lib_set_prop_usb_type(struct smb_charger *chg, - const union power_supply_propval *val); + const int val); void smblite_update_usb_desc(struct smb_charger *chg); int smblite_lib_init(struct smb_charger *chg); int smblite_lib_deinit(struct smb_charger *chg); +int smblite_iio_get_prop(struct smb_charger *chg, int channel, int *val); +int smblite_iio_set_prop(struct smb_charger *chg, int channel, int val); + #endif /* __SMBLITE_LIB_H */