From e76f8318ec3b1058fa3ee578ceb09b5b47548bf9 Mon Sep 17 00:00:00 2001 From: Ashish Chavan Date: Wed, 16 Dec 2020 11:06:16 +0530 Subject: [PATCH] power: supply: qcom: Add support to make SMBLITE charger GKI compliant SMBLITE charger drivers and their helper files use several power supply properties on msm-4.19 which cannot be supported on msm-5.4 due to the need for GKI compliance. Add support for main charger to register as an IIO device with individual channels under it corresponding to missing power supply properties from msm-4.19. Change-Id: I397ed52d2fa822c7f93616090e15b109435d9657 Signed-off-by: Ashish Chavan --- drivers/power/supply/qcom/Makefile | 3 +- drivers/power/supply/qcom/qpnp-smblite.c | 627 +++++++++-------------- drivers/power/supply/qcom/smblite-iio.c | 247 +++++++++ drivers/power/supply/qcom/smblite-lib.c | 457 ++++++++++------- drivers/power/supply/qcom/smblite-lib.h | 77 ++- 5 files changed, 775 insertions(+), 636 deletions(-) create mode 100644 drivers/power/supply/qcom/smblite-iio.c 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 */