From da167e08a991622b694557befe48d545f474a5ae Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 29 Jul 2020 20:53:29 +0530 Subject: [PATCH] power: supply: qcom: Add support to make SMB5 charger GKI compliant SMB5 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: I7182160258fa2ebd4af36b0531b11d988cffdbd3 Signed-off-by: Jishnu Prakash --- drivers/power/supply/qcom/Kconfig | 11 +- drivers/power/supply/qcom/Makefile | 3 +- drivers/power/supply/qcom/battery.c | 576 +++++---- drivers/power/supply/qcom/battery.h | 4 +- drivers/power/supply/qcom/qpnp-smb5.c | 1130 +++++------------- drivers/power/supply/qcom/smb5-iio.c | 521 +++++++++ drivers/power/supply/qcom/smb5-iio.h | 206 ++++ drivers/power/supply/qcom/smb5-lib.c | 1219 +++++++++++--------- drivers/power/supply/qcom/smb5-lib.h | 114 +- drivers/power/supply/qcom/step-chg-jeita.c | 135 ++- drivers/power/supply/qcom/step-chg-jeita.h | 11 +- include/linux/qti_power_supply.h | 117 ++ 12 files changed, 2309 insertions(+), 1738 deletions(-) create mode 100644 drivers/power/supply/qcom/smb5-iio.c create mode 100644 drivers/power/supply/qcom/smb5-iio.h create mode 100644 include/linux/qti_power_supply.h diff --git a/drivers/power/supply/qcom/Kconfig b/drivers/power/supply/qcom/Kconfig index 03ffae7313b9..4a52ec19c287 100644 --- a/drivers/power/supply/qcom/Kconfig +++ b/drivers/power/supply/qcom/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig QCOM_POWER_SUPPLY - tristate "Support for Qualcomm Technologies, Inc. power supply" + bool "Support for Qualcomm Technologies, Inc. power supply" depends on ARCH_QCOM if QCOM_POWER_SUPPLY @@ -17,17 +17,20 @@ config QPNP_QG config QPNP_SMB5 tristate "SMB5 Battery Charger" - depends on MFD_SPMI_PMIC + depends on MFD_SPMI_PMIC && IIO help Say Y to enables support for the SMB5 charging peripheral. The QPNP SMB5 charger driver supports the charger peripheral present in the chip. - The power supply framework is used to communicate battery and - usb properties to userspace and other driver consumers such + The power supply and iio frameworks are used to communicate battery + and usb properties to userspace and other driver consumers such as fuel gauge, USB, and USB-PD. VBUS and VCONN regulators are registered for supporting OTG, and powered Type-C cables respectively. + To compile this driver as a module, choose M here: the + module will be called qpnp-smb5-main. + config SMB1398_CHARGER tristate "SMB1398 power supply framework based driver" depends on MFD_I2C_PMIC diff --git a/drivers/power/supply/qcom/Makefile b/drivers/power/supply/qcom/Makefile index f5e0eca225f9..f9feade452fd 100644 --- a/drivers/power/supply/qcom/Makefile +++ b/drivers/power/supply/qcom/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_QPNP_SMB5) += qpnp-smb5-main.o +qpnp-smb5-main-y += step-chg-jeita.o battery.o qpnp-smb5.o smb5-lib.o pmic-voter.o storm-watch.o schgm-flash.o battery-profile-loader.o smb5-iio.o obj-$(CONFIG_QPNP_QG) += 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_QPNP_SMB5) += step-chg-jeita.o battery.o qpnp-smb5.o smb5-lib.o pmic-voter.o storm-watch.o schgm-flash.o obj-$(CONFIG_SMB1398_CHARGER) += smb1398-charger.o pmic-voter.o obj-$(CONFIG_SMB1355_SLAVE_CHARGER) += smb1355-charger.o pmic-voter.o diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 4bfa6a3c01ee..66487689937e 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -20,8 +20,12 @@ #include #include #include +#include #include +#include +#include #include "battery.h" +#include "smb5-iio.h" #define DRV_MAJOR_VERSION 1 #define DRV_MINOR_VERSION 0 @@ -45,6 +49,7 @@ #define MAIN_FCC_VOTER "MAIN_FCC_VOTER" struct pl_data { + struct device *dev; int pl_mode; int pl_batfet_mode; int pl_min_icl_ua; @@ -69,13 +74,11 @@ struct pl_data { struct work_struct pl_taper_work; struct delayed_work fcc_stepper_work; bool taper_work_running; - struct power_supply *main_psy; struct power_supply *pl_psy; struct power_supply *batt_psy; struct power_supply *usb_psy; struct power_supply *dc_psy; struct power_supply *cp_master_psy; - struct power_supply *cp_slave_psy; int charge_type; int total_settled_ua; int pl_settled_ua; @@ -99,13 +102,16 @@ struct pl_data { bool cp_disabled; int taper_entry_fv; int main_fcc_max; - enum power_supply_type charger_type; + int charger_type; /* debugfs directory */ struct dentry *dfs_root; u32 float_voltage_uv; + struct iio_channel **iio_chan_list_cp; + struct iio_channel *iio_chan_list_cp_slave; + struct iio_channel **iio_chan_list_smb_parallel; }; -struct pl_data *the_chip; +static struct pl_data *the_chip; enum print_reason { PR_PARALLEL = BIT(0), @@ -126,8 +132,8 @@ static int debug_mask; pr_debug(fmt, ##__VA_ARGS__); \ } while (0) -#define IS_USBIN(mode) ((mode == POWER_SUPPLY_PL_USBIN_USBIN) \ - || (mode == POWER_SUPPLY_PL_USBIN_USBIN_EXT)) +#define IS_USBIN(mode) ((mode == QTI_POWER_SUPPLY_PL_USBIN_USBIN) \ + || (mode == QTI_POWER_SUPPLY_PL_USBIN_USBIN_EXT)) enum { VER = 0, SLAVE_PCT, @@ -140,6 +146,27 @@ enum { PARALLEL_INPUT_MODE, PARALLEL_OUTPUT_MODE, }; + +static const char * const bat_cp_ext_iio_chan[] = { + [BAT_CP_PARALLEL_MODE] = "parallel_mode", + [BAT_CP_PARALLEL_OUTPUT_MODE] = "parallel_output_mode", + [BAT_CP_MIN_ICL] = "min_icl", + [BAT_CP_SWITCHER_EN] = "cp_switcher_en", +}; + +static const char * const bat_smb_parallel_ext_iio_chan[] = { + [BAT_SMB_PARALLEL_INPUT_SUSPEND] = "input_suspend", + [BAT_SMB_PARALLEL_MODE] = "parallel_mode", + [BAT_SMB_PARALLEL_BATFET_MODE] = "parallel_batfet_mode", + [BAT_SMB_PARALLEL_MIN_ICL] = "min_icl", + [BAT_SMB_PARALLEL_FCC_MAX] = "parallel_fcc_max", + [BAT_SMB_PARALLEL_CURRENT_MAX] = "current_max", + [BAT_SMB_PARALLEL_CONSTANT_CHARGE_CURRENT_MAX] = + "constant_charge_current_max", + [BAT_SMB_PARALLEL_VOLTAGE_MAX] = "voltage_max", + [BAT_SMB_PARALLEL_CHARGE_TYPE] = "charge_type", +}; + /********* * HELPER* *********/ @@ -154,29 +181,104 @@ static bool is_usb_available(struct pl_data *chip) static bool is_cp_available(struct pl_data *chip) { - if (!chip->cp_master_psy) + int rc; + struct iio_channel **iio_list; + + if (IS_ERR(chip->iio_chan_list_cp)) + return false; + + if (!chip->iio_chan_list_cp) { + iio_list = get_ext_channels(chip->dev, + bat_cp_ext_iio_chan, + ARRAY_SIZE(bat_cp_ext_iio_chan)); + if (IS_ERR(iio_list)) { + rc = PTR_ERR(iio_list); + if (rc != -EPROBE_DEFER) { + dev_err(chip->dev, "Failed to get channels, %d\n", + rc); + chip->iio_chan_list_cp = ERR_PTR(-EINVAL); + } + return false; + } + chip->iio_chan_list_cp = iio_list; + } + + if (!chip->cp_master_psy) { chip->cp_master_psy = power_supply_get_by_name("charge_pump_master"); + if (!chip->cp_master_psy) + return false; + } - return !!chip->cp_master_psy; + return true; +} + +static int battery_read_iio_prop(struct pl_data *chip, + enum iio_type type, int iio_chan, int *val) +{ + struct iio_channel *iio_chan_list; + int rc; + + switch (type) { + case CP: + if (IS_ERR_OR_NULL(chip->iio_chan_list_cp)) + return -ENODEV; + iio_chan_list = chip->iio_chan_list_cp[iio_chan]; + break; + case SMB_PARALLEL: + if (IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel)) + return -ENODEV; + iio_chan_list = chip->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; +} + +static int battery_write_iio_prop(struct pl_data *chip, + enum iio_type type, int iio_chan, int val) +{ + struct iio_channel *iio_chan_list; + + switch (type) { + case CP: + if (IS_ERR_OR_NULL(chip->iio_chan_list_cp)) + return -ENODEV; + iio_chan_list = chip->iio_chan_list_cp[iio_chan]; + break; + case SMB_PARALLEL: + if (IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel)) + return -ENODEV; + iio_chan_list = chip->iio_chan_list_smb_parallel[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); } static int cp_get_parallel_mode(struct pl_data *chip, int mode) { - union power_supply_propval pval = {-EINVAL, }; - int rc = -EINVAL; + int rc = -EINVAL, val = -EINVAL; if (!is_cp_available(chip)) return -EINVAL; switch (mode) { case PARALLEL_INPUT_MODE: - rc = power_supply_get_property(chip->cp_master_psy, - POWER_SUPPLY_PROP_PARALLEL_MODE, &pval); + rc = battery_read_iio_prop(chip, CP, + BAT_CP_PARALLEL_MODE, &val); break; case PARALLEL_OUTPUT_MODE: - rc = power_supply_get_property(chip->cp_master_psy, - POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); + rc = battery_read_iio_prop(chip, CP, + BAT_CP_PARALLEL_OUTPUT_MODE, + &val); break; default: pr_err("Invalid mode request %d\n", mode); @@ -187,15 +289,15 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode) pr_err("Failed to read CP topology for mode=%d rc=%d\n", mode, rc); - return pval.intval; + return val; } static int get_hvdcp3_icl_limit(struct pl_data *chip) { int main_icl, target_icl = -EINVAL; - if (chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3 && - chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5) + if (chip->charger_type != QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3 && + chip->charger_type != QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5) return target_icl; /* @@ -207,7 +309,7 @@ static int get_hvdcp3_icl_limit(struct pl_data *chip) */ target_icl = chip->chg_param->hvdcp3_max_icl_ua; if (cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE) - == POWER_SUPPLY_PL_USBIN_USBIN) { + == QTI_POWER_SUPPLY_PL_USBIN_USBIN) { main_icl = get_effective_result_locked(chip->usb_icl_votable); if ((main_icl >= 0) && (main_icl < target_icl)) target_icl -= main_icl; @@ -231,8 +333,7 @@ static int get_hvdcp3_icl_limit(struct pl_data *chip) */ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) { - int rc, fcc, target_icl; - union power_supply_propval pval = {0, }; + int rc = 0, fcc, target_icl, val; if (!is_usb_available(chip)) return; @@ -241,16 +342,17 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) return; if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE) - == POWER_SUPPLY_PL_OUTPUT_VPH) + == QTI_POWER_SUPPLY_PL_OUTPUT_VPH) return; target_icl = get_hvdcp3_icl_limit(chip); ilim = (target_icl > 0) ? min(ilim, target_icl) : ilim; - rc = power_supply_get_property(chip->cp_master_psy, - POWER_SUPPLY_PROP_MIN_ICL, &pval); - if (rc < 0) + rc = battery_read_iio_prop(chip, CP, BAT_CP_MIN_ICL, &val); + if (rc < 0) { + pr_err("Failed to read min_icl rc=%d\n", rc); return; + } if (!chip->cp_ilim_votable) chip->cp_ilim_votable = find_votable("CP_ILIM"); @@ -264,8 +366,8 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) * if request_ilim < MIN_ICL cofigure ILIM to MIN_ICL. * otherwise configure ILIM to requested_ilim. */ - if ((fcc >= (pval.intval * 2)) && (ilim < pval.intval)) - vote(chip->cp_ilim_votable, voter, true, pval.intval); + if ((fcc >= (val * 2)) && (ilim < val)) + vote(chip->cp_ilim_votable, voter, true, val); else vote(chip->cp_ilim_votable, voter, true, ilim); @@ -275,13 +377,13 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) */ if (!chip->fcc_main_votable) chip->fcc_main_votable = find_votable("FCC_MAIN"); - if ((chip->charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) + if ((chip->charger_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3) && chip->fcc_main_votable) rerun_election(chip->fcc_main_votable); pl_dbg(chip, PR_PARALLEL, "ILIM: vote: %d voter:%s min_ilim=%d fcc = %d\n", - ilim, voter, pval.intval, fcc); + ilim, voter, val, fcc); } } @@ -293,24 +395,21 @@ static int get_settled_split(struct pl_data *chip, int *main_icl_ua, { int slave_icl_pct, total_current_ua; int slave_ua = 0, main_settled_ua = 0; - union power_supply_propval pval = {0, }; int rc, total_settled_ua = 0; + int val; if (!IS_USBIN(chip->pl_mode)) return -EINVAL; - if (!chip->main_psy) - return -EINVAL; - if (!get_effective_result_locked(chip->pl_disable_votable)) { /* read the aicl settled value */ - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); + rc = chip->chg_param->iio_read(chip->dev, + PSY_IIO_MAIN_INPUT_CURRENT_SETTLED, &val); if (rc < 0) { pr_err("Couldn't get aicl settled value rc=%d\n", rc); return rc; } - main_settled_ua = pval.intval; + main_settled_ua = val; slave_icl_pct = max(0, chip->slave_pct); slave_ua = ((main_settled_ua + chip->pl_settled_ua) * slave_icl_pct) / 100; @@ -326,13 +425,13 @@ static int get_settled_split(struct pl_data *chip, int *main_icl_ua, return -ENOENT; } /* no client is voting, so get the total current from charger */ - rc = power_supply_get_property(chip->usb_psy, - POWER_SUPPLY_PROP_HW_CURRENT_MAX, &pval); + rc = chip->chg_param->iio_read(chip->dev, + PSY_IIO_HW_CURRENT_MAX, &val); if (rc < 0) { pr_err("Couldn't get max current rc=%d\n", rc); return rc; } - total_current_ua = pval.intval; + total_current_ua = val; } *main_icl_ua = total_current_ua - slave_ua; @@ -371,7 +470,6 @@ static int validate_parallel_icl(struct pl_data *chip, bool *disable) static void split_settled(struct pl_data *chip) { - union power_supply_propval pval = {0, }; int rc, main_ua, slave_ua, total_settled_ua; rc = get_settled_split(chip, &main_ua, &slave_ua, &total_settled_ua); @@ -389,10 +487,9 @@ static void split_settled(struct pl_data *chip) * Set slave ICL then main ICL. */ if (slave_ua > chip->pl_settled_ua) { - pval.intval = main_ua; /* Set ICL on main charger */ - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &pval); + rc = chip->chg_param->iio_write(chip->dev, PSY_IIO_CURRENT_MAX, + main_ua); if (rc < 0) { pr_err("Couldn't change slave suspend state rc=%d\n", rc); @@ -400,27 +497,23 @@ static void split_settled(struct pl_data *chip) } /* set parallel's ICL could be 0mA when pl is disabled */ - pval.intval = slave_ua; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CURRENT_MAX, slave_ua); if (rc < 0) { pr_err("Couldn't set parallel icl, rc=%d\n", rc); return; } } else { /* set parallel's ICL could be 0mA when pl is disabled */ - pval.intval = slave_ua; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CURRENT_MAX, slave_ua); if (rc < 0) { pr_err("Couldn't set parallel icl, rc=%d\n", rc); return; } - - pval.intval = main_ua; /* Set ICL on main charger */ - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &pval); + rc = chip->chg_param->iio_write(chip->dev, PSY_IIO_CURRENT_MAX, + main_ua); if (rc < 0) { pr_err("Couldn't change slave suspend state rc=%d\n", rc); @@ -584,33 +677,33 @@ static void get_fcc_split(struct pl_data *chip, int total_ua, int *master_ua, int *slave_ua) { int rc, effective_total_ua, slave_limited_ua, hw_cc_delta_ua = 0, - icl_ua, adapter_uv, bcl_ua; - union power_supply_propval pval = {0, }; + icl_ua, adapter_uv, bcl_ua, val; - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_FCC_DELTA, &pval); - if (rc < 0) + rc = chip->chg_param->iio_read(chip->dev, PSY_IIO_FCC_DELTA, &val); + if (rc < 0) { + pr_err("Couldn't get fcc_delta rc=%d\n", rc); hw_cc_delta_ua = 0; + } else - hw_cc_delta_ua = pval.intval; + hw_cc_delta_ua = val; bcl_ua = INT_MAX; - if (chip->pl_mode == POWER_SUPPLY_PL_USBMID_USBMID) { - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); + if (chip->pl_mode == QTI_POWER_SUPPLY_PL_USBMID_USBMID) { + rc = chip->chg_param->iio_read(chip->dev, + PSY_IIO_MAIN_INPUT_CURRENT_SETTLED, &val); if (rc < 0) { pr_err("Couldn't get aicl settled value rc=%d\n", rc); return; } - icl_ua = pval.intval; + icl_ua = val; - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, &pval); + rc = chip->chg_param->iio_read(chip->dev, + PSY_IIO_MAIN_INPUT_VOLTAGE_SETTLED, &val); if (rc < 0) { pr_err("Couldn't get adaptive voltage rc=%d\n", rc); return; } - adapter_uv = pval.intval; + adapter_uv = val; bcl_ua = div64_s64((s64)icl_ua * adapter_uv * EFFICIENCY_PCT, (s64)get_effective_result(chip->fv_votable) * 100); @@ -626,7 +719,7 @@ static void get_fcc_split(struct pl_data *chip, int total_ua, * through main charger's BATFET, keep the main charger's FCC * to the votable result. */ - if (chip->pl_batfet_mode == POWER_SUPPLY_PL_STACKED_BATFET) { + if (chip->pl_batfet_mode == QTI_POWER_SUPPLY_PL_STACKED_BATFET) { *master_ua = max(0, total_ua); if (chip->main_fcc_max) *master_ua = min(*master_ua, @@ -640,20 +733,18 @@ static void get_fcc_split(struct pl_data *chip, int total_ua, static void get_main_fcc_config(struct pl_data *chip, int *total_fcc) { - union power_supply_propval pval = {0, }; - int rc; + int rc = 0, val; if (!is_cp_available(chip)) goto out; - rc = power_supply_get_property(chip->cp_master_psy, - POWER_SUPPLY_PROP_CP_SWITCHER_EN, &pval); + rc = battery_read_iio_prop(chip, CP, BAT_CP_SWITCHER_EN, &val); if (rc < 0) { pr_err("Couldn't get switcher enable status, rc=%d\n", rc); goto out; } - if (!pval.intval) { + if (!val) { /* * To honor main charger upper FCC limit, on CP switcher * disable, skip fcc slewing as it will cause delay in limiting @@ -854,7 +945,7 @@ static void pl_taper_work(struct work_struct *work) } chip->charge_type = pval.intval; - if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { + if (pval.intval == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER) { fcc_ua = get_client_vote(chip->fcc_votable, TAPER_STEPPER_VOTER); if (fcc_ua < 0) { @@ -884,29 +975,18 @@ done: vote(chip->pl_awake_votable, TAPER_END_VOTER, false, 0); } -static bool is_main_available(struct pl_data *chip) -{ - if (chip->main_psy) - return true; - - chip->main_psy = power_supply_get_by_name("main"); - - return !!chip->main_psy; -} - static int pl_fcc_main_vote_callback(struct votable *votable, void *data, int fcc_main_ua, const char *client) { struct pl_data *chip = data; - union power_supply_propval pval = {0,}; + int rc; - if (!is_main_available(chip)) - return 0; + rc = chip->chg_param->iio_write(chip->dev, + PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX, fcc_main_ua); + if (rc < 0) + pr_err("Couldn't set constant_charge_current_max, rc=%d\n", rc); - pval.intval = fcc_main_ua; - return power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); + return rc; } static int pl_fcc_vote_callback(struct votable *votable, void *data, @@ -914,24 +994,27 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, { struct pl_data *chip = data; int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; - int cp_fcc_ua = 0, rc = 0; - union power_supply_propval pval = {0, }; + int cp_fcc_ua = 0, rc, val = 0; if (total_fcc_ua < 0) return 0; - if (!chip->main_psy) - return 0; - if (!chip->cp_disable_votable) chip->cp_disable_votable = find_votable("CP_DISABLE"); - if (!chip->cp_master_psy) - chip->cp_master_psy = - power_supply_get_by_name("charge_pump_master"); + if (IS_ERR_OR_NULL(chip->iio_chan_list_cp)) + is_cp_available(chip); - if (!chip->cp_slave_psy) - chip->cp_slave_psy = power_supply_get_by_name("cp_slave"); + /* + * Search for a slave charger channel specifically, + * which would be available only if slave got probed. + */ + if (!chip->iio_chan_list_cp_slave) { + chip->iio_chan_list_cp_slave = iio_channel_get(chip->dev, + "current capability"); + if (PTR_ERR(chip->iio_chan_list_cp_slave) == -EPROBE_DEFER) + chip->iio_chan_list_cp_slave = NULL; + } if (!chip->cp_slave_disable_votable) chip->cp_slave_disable_votable = @@ -946,21 +1029,22 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, "cp_fcc_ua=%d total_fcc_ua=%d forced_main_fcc=%d\n", cp_fcc_ua, total_fcc_ua, chip->chg_param->forced_main_fcc); if (cp_fcc_ua > 0) { - if (chip->cp_master_psy) { - rc = power_supply_get_property(chip->cp_master_psy, - POWER_SUPPLY_PROP_MIN_ICL, &pval); + if (!IS_ERR_OR_NULL(chip->iio_chan_list_cp)) { + rc = battery_read_iio_prop(chip, CP, BAT_CP_MIN_ICL, + &val); if (rc < 0) pr_err("Couldn't get MIN ICL threshold rc=%d\n", rc); } - if (chip->cp_slave_psy && chip->cp_slave_disable_votable) { + if (!IS_ERR_OR_NULL(chip->iio_chan_list_cp_slave) && + chip->cp_slave_disable_votable) { /* * Disable Slave CP if FCC share * falls below 3 * min ICL threshold. */ vote(chip->cp_slave_disable_votable, FCC_VOTER, - (cp_fcc_ua < (3 * pval.intval)), 0); + (cp_fcc_ua < (3 * val)), 0); } if (chip->cp_disable_votable) { @@ -969,11 +1053,11 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, * falls below 2 * min ICL threshold. */ vote(chip->cp_disable_votable, FCC_VOTER, - (cp_fcc_ua < (2 * pval.intval)), 0); + (cp_fcc_ua < (2 * val)), 0); } } - if (chip->pl_mode != POWER_SUPPLY_PL_NONE) { + if (chip->pl_mode != QTI_POWER_SUPPLY_PL_NONE) { get_fcc_split(chip, total_fcc_ua, &master_fcc_ua, &slave_fcc_ua); @@ -988,7 +1072,8 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, rerun_election(chip->pl_disable_votable); /* When FCC changes, trigger psy changed event for CC mode */ - if (chip->cp_master_psy) + + if (!IS_ERR_OR_NULL(chip->iio_chan_list_cp)) power_supply_changed(chip->cp_master_psy); return 0; @@ -1031,16 +1116,14 @@ static void fcc_stepper_work(struct work_struct *work) /* Disable parallel */ parallel_fcc = 0; - if (chip->pl_psy) { - pval.intval = 1; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); + if (!IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel)) { + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_INPUT_SUSPEND, 1); if (rc < 0) { pr_err("Couldn't change slave suspend state rc=%d\n", rc); goto out; } - chip->pl_disable = true; power_supply_changed(chip->pl_psy); } @@ -1072,11 +1155,12 @@ static void fcc_stepper_work(struct work_struct *work) if (parallel_fcc < chip->slave_fcc_ua) { /* Set parallel FCC */ - if (chip->pl_psy && !chip->pl_disable) { + if (!IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel) && + !chip->pl_disable) { if (parallel_fcc < MINIMUM_PARALLEL_FCC_UA) { - pval.intval = 1; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_INPUT_SUSPEND, 1); + if (rc < 0) { pr_err("Couldn't change slave suspend state rc=%d\n", rc); @@ -1095,10 +1179,9 @@ static void fcc_stepper_work(struct work_struct *work) power_supply_changed(chip->pl_psy); } else { /* Set Parallel FCC */ - pval.intval = parallel_fcc; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CONSTANT_CHARGE_CURRENT_MAX, + parallel_fcc); if (rc < 0) { pr_err("Couldn't set parallel charger fcc, rc=%d\n", rc); @@ -1114,11 +1197,10 @@ static void fcc_stepper_work(struct work_struct *work) vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc); /* Set parallel FCC */ - if (chip->pl_psy) { - pval.intval = parallel_fcc; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); + if (!IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel)) { + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CONSTANT_CHARGE_CURRENT_MAX, + parallel_fcc); if (rc < 0) { pr_err("Couldn't set parallel charger fcc, rc=%d\n", rc); @@ -1132,9 +1214,9 @@ static void fcc_stepper_work(struct work_struct *work) */ if (chip->pl_disable && parallel_fcc >= MINIMUM_PARALLEL_FCC_UA) { - pval.intval = 0; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_INPUT_SUSPEND, 0); + if (rc < 0) { pr_err("Couldn't change slave suspend state rc=%d\n", rc); @@ -1183,27 +1265,23 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, { struct pl_data *chip = data; union power_supply_propval pval = {0, }; - int rc = 0; + int rc = 0, val; if (fv_uv < 0) return 0; - if (!chip->main_psy) - return 0; + val = fv_uv; - pval.intval = fv_uv; - - rc = power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval); + rc = chip->chg_param->iio_write(chip->dev, PSY_IIO_VOLTAGE_MAX, val); if (rc < 0) { pr_err("Couldn't set main fv, rc=%d\n", rc); return rc; } - if (chip->pl_mode != POWER_SUPPLY_PL_NONE) { - pval.intval += PARALLEL_FLOAT_VOLTAGE_DELTA_UV; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval); + if (chip->pl_mode != QTI_POWER_SUPPLY_PL_NONE) { + val += PARALLEL_FLOAT_VOLTAGE_DELTA_UV; + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_VOLTAGE_MAX, val); if (rc < 0) { pr_err("Couldn't set float on parallel rc=%d\n", rc); return rc; @@ -1222,10 +1300,9 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, } else { if (pval.intval == POWER_SUPPLY_STATUS_FULL) { pr_debug("re-triggering charging\n"); - pval.intval = 1; - rc = power_supply_set_property(chip->batt_psy, - POWER_SUPPLY_PROP_FORCE_RECHARGE, - &pval); + val = 1; + rc = chip->chg_param->iio_write(chip->dev, + PSY_IIO_FORCE_RECHARGE, val); if (rc < 0) pr_err("Couldn't set force recharge rc=%d\n", rc); @@ -1243,14 +1320,11 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, static int usb_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) { - int rc; + int rc, val; struct pl_data *chip = data; union power_supply_propval pval = {0, }; bool rerun_aicl = false, dc_present = false; - if (!chip->main_psy) - return 0; - if (client == NULL) icl_ua = INT_MAX; @@ -1278,37 +1352,37 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, /* rerun AICL */ /* get the settled current */ - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, - &pval); + rc = chip->chg_param->iio_read(chip->dev, + PSY_IIO_MAIN_INPUT_CURRENT_SETTLED, &val); if (rc < 0) { pr_err("Couldn't get aicl settled value rc=%d\n", rc); return rc; } /* rerun AICL if new ICL is above settled ICL */ - if (icl_ua > pval.intval) + if (icl_ua > val) rerun_aicl = true; if (rerun_aicl && (chip->wa_flags & AICL_RERUN_WA_BIT)) { /* set a lower ICL */ - pval.intval = max(pval.intval - ICL_STEP_UA, ICL_STEP_UA); - power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, - &pval); + val = max(val - ICL_STEP_UA, ICL_STEP_UA); + rc = chip->chg_param->iio_write(chip->dev, PSY_IIO_CURRENT_MAX, + val); + if (rc < 0) + pr_err("Couldn't set main current_max, rc=%d\n", rc); } /* set the effective ICL */ - pval.intval = icl_ua; - power_supply_set_property(chip->main_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, - &pval); + val = icl_ua; + rc = chip->chg_param->iio_write(chip->dev, PSY_IIO_CURRENT_MAX, val); + if (rc < 0) + pr_err("Couldn't set main current_max, rc=%d\n", rc); vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0); /* Configure ILIM based on AICL result only if input mode is USBMID */ if (cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE) - == POWER_SUPPLY_PL_USBMID_USBMID) { + == QTI_POWER_SUPPLY_PL_USBMID_USBMID) { if (chip->dc_psy) { rc = power_supply_get_property(chip->dc_psy, POWER_SUPPLY_PROP_PRESENT, &pval); @@ -1349,9 +1423,6 @@ static int pl_disable_vote_callback(struct votable *votable, int rc = 0, cp_ilim; bool disable = false; - if (!is_main_available(chip)) - return -ENODEV; - if (!is_batt_available(chip)) return -ENODEV; @@ -1362,8 +1433,8 @@ static int pl_disable_vote_callback(struct votable *votable, return -ENODEV; } - rc = power_supply_get_property(chip->batt_psy, - POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, &pval); + rc = chip->chg_param->iio_read(chip->dev, PSY_IIO_FCC_STEPPER_ENABLE, + &pval.intval); if (rc < 0) { pr_err("Couldn't read FCC step update status, rc=%d\n", rc); return rc; @@ -1371,8 +1442,8 @@ static int pl_disable_vote_callback(struct votable *votable, chip->fcc_stepper_enable = pval.intval; pr_debug("FCC Stepper %s\n", pval.intval ? "enabled" : "disabled"); - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_MAIN_FCC_MAX, &pval); + rc = chip->chg_param->iio_read(chip->dev, PSY_IIO_MAIN_FCC_MAX, + &pval.intval); if (rc < 0) { pl_dbg(chip, PR_PARALLEL, "Couldn't read primary charger FCC upper limit, rc=%d\n", @@ -1388,7 +1459,7 @@ static int pl_disable_vote_callback(struct votable *votable, total_fcc_ua = get_effective_result_locked(chip->fcc_votable); - if (chip->pl_mode != POWER_SUPPLY_PL_NONE && !pl_disable) { + if (chip->pl_mode != QTI_POWER_SUPPLY_PL_NONE && !pl_disable) { rc = validate_parallel_icl(chip, &disable); if (rc < 0) return rc; @@ -1400,8 +1471,8 @@ static int pl_disable_vote_callback(struct votable *votable, } /* enable parallel charging */ - rc = power_supply_get_property(chip->pl_psy, - POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); + rc = battery_read_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CHARGE_TYPE, &pval.intval); if (rc == -ENODEV) { /* * -ENODEV is returned only if parallel chip @@ -1411,7 +1482,6 @@ static int pl_disable_vote_callback(struct votable *votable, schedule_work(&chip->pl_disable_forever_work); return rc; } - rerun_election(chip->fv_votable); get_fcc_split(chip, total_fcc_ua, &master_fcc_ua, @@ -1439,27 +1509,25 @@ static int pl_disable_vote_callback(struct votable *votable, vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true, master_fcc_ua); pval.intval = slave_fcc_ua; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CONSTANT_CHARGE_CURRENT_MAX, + pval.intval); if (rc < 0) { pr_err("Couldn't set parallel fcc, rc=%d\n", rc); return rc; } - chip->slave_fcc_ua = slave_fcc_ua; } else { pval.intval = slave_fcc_ua; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, - &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CONSTANT_CHARGE_CURRENT_MAX, + pval.intval); if (rc < 0) { pr_err("Couldn't set parallel fcc, rc=%d\n", rc); return rc; } - chip->slave_fcc_ua = slave_fcc_ua; vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true, master_fcc_ua); @@ -1471,12 +1539,12 @@ static int pl_disable_vote_callback(struct votable *votable, * is seen. */ pval.intval = 0; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_INPUT_SUSPEND, + pval.intval); if (rc < 0) pr_err("Couldn't change slave suspend state rc=%d\n", rc); - if (IS_USBIN(chip->pl_mode)) split_settled(chip); } @@ -1490,7 +1558,7 @@ static int pl_disable_vote_callback(struct votable *votable, if (rc < 0) { pr_err("Couldn't get batt charge type rc=%d\n", rc); } else { - if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER + if (pval.intval == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER && !chip->taper_work_running) { pl_dbg(chip, PR_PARALLEL, "pl enabled in Taper scheduing work\n"); @@ -1514,10 +1582,11 @@ static int pl_disable_vote_callback(struct votable *votable, split_settled(chip); /* pl_psy may be NULL while in the disable branch */ - if (chip->pl_psy) { + if (!IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel)) { pval.intval = 1; - rc = power_supply_set_property(chip->pl_psy, - POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval); + rc = battery_write_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_INPUT_SUSPEND, + pval.intval); if (rc < 0) pr_err("Couldn't change slave suspend state rc=%d\n", rc); @@ -1549,7 +1618,8 @@ static int pl_disable_vote_callback(struct votable *votable, } /* notify parallel state change */ - if (chip->pl_psy && (chip->pl_disable != pl_disable) + if (!IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel) && + (chip->pl_disable != pl_disable) && !chip->fcc_stepper_enable) { power_supply_changed(chip->pl_psy); chip->pl_disable = (bool)pl_disable; @@ -1588,24 +1658,45 @@ static int pl_awake_vote_callback(struct votable *votable, static bool is_parallel_available(struct pl_data *chip) { union power_supply_propval pval = {0, }; - int rc; + int rc = 0; + struct iio_channel **iio_list; - if (chip->pl_psy) - return true; - - chip->pl_psy = power_supply_get_by_name("parallel"); - if (!chip->pl_psy) + if (IS_ERR(chip->iio_chan_list_smb_parallel)) return false; + if (!chip->iio_chan_list_smb_parallel) { + iio_list = get_ext_channels(chip->dev, + bat_smb_parallel_ext_iio_chan, + ARRAY_SIZE(bat_smb_parallel_ext_iio_chan)); + if (IS_ERR(iio_list)) { + rc = PTR_ERR(iio_list); + if (rc != -EPROBE_DEFER) { + dev_err(chip->dev, "Failed to get channels, %d\n", + rc); + chip->iio_chan_list_smb_parallel = + ERR_PTR(-EINVAL); + } + return false; + } + chip->iio_chan_list_smb_parallel = iio_list; + } + + if (!chip->pl_psy) { + chip->pl_psy = power_supply_get_by_name("parallel"); + if (!chip->pl_psy) + return false; + } + vote(chip->pl_disable_votable, PARALLEL_PSY_VOTER, false, 0); - rc = power_supply_get_property(chip->pl_psy, - POWER_SUPPLY_PROP_PARALLEL_MODE, &pval); + rc = battery_read_iio_prop(chip, SMB_PARALLEL, BAT_SMB_PARALLEL_MODE, + &pval.intval); if (rc < 0) { pr_err("Couldn't get parallel mode from parallel rc=%d\n", rc); return false; } + /* * Note that pl_mode will be updated to anything other than a _NONE * only after pl_psy is found. IOW pl_mode != _NONE implies that @@ -1627,8 +1718,8 @@ static bool is_parallel_available(struct pl_data *chip) return false; } - rc = power_supply_get_property(chip->pl_psy, - POWER_SUPPLY_PROP_PARALLEL_BATFET_MODE, &pval); + rc = battery_read_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_BATFET_MODE, &pval.intval); if (rc < 0) { pr_err("Couldn't get parallel batfet mode rc=%d\n", rc); @@ -1637,15 +1728,21 @@ static bool is_parallel_available(struct pl_data *chip) chip->pl_batfet_mode = pval.intval; pval.intval = 0; - power_supply_get_property(chip->pl_psy, POWER_SUPPLY_PROP_MIN_ICL, - &pval); - chip->pl_min_icl_ua = pval.intval; + rc = battery_read_iio_prop(chip, SMB_PARALLEL, BAT_SMB_PARALLEL_MIN_ICL, + &pval.intval); + if (rc < 0) + pr_err("Couldn't get min_icl rc=%d\n", rc); + else + chip->pl_min_icl_ua = pval.intval; chip->pl_fcc_max = INT_MAX; - rc = power_supply_get_property(chip->pl_psy, - POWER_SUPPLY_PROP_PARALLEL_FCC_MAX, &pval); + + rc = battery_read_iio_prop(chip, SMB_PARALLEL, BAT_SMB_PARALLEL_FCC_MAX, + &pval.intval); if (!rc) chip->pl_fcc_max = pval.intval; + else + pr_err("Couldn't get fcc_max rc=%d\n", rc); return true; } @@ -1664,7 +1761,7 @@ static void handle_main_charge_type(struct pl_data *chip) /* not fast/not taper state to disables parallel */ if ((pval.intval != POWER_SUPPLY_CHARGE_TYPE_FAST) - && (pval.intval != POWER_SUPPLY_CHARGE_TYPE_TAPER)) { + && (pval.intval != QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER)) { vote(chip->pl_disable_votable, CHG_STATE_VOTER, true, 0); chip->charge_type = pval.intval; return; @@ -1672,7 +1769,7 @@ static void handle_main_charge_type(struct pl_data *chip) /* handle taper charge entry */ if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_FAST - && (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER)) { + && (pval.intval == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER)) { chip->charge_type = pval.intval; if (!chip->taper_work_running) { pl_dbg(chip, PR_PARALLEL, "taper entry scheduling work\n"); @@ -1683,7 +1780,7 @@ static void handle_main_charge_type(struct pl_data *chip) } /* handle fast/taper charge entry */ - if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER + if (pval.intval == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER || pval.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) { /* * Undo parallel charging termination if entered taper in @@ -1710,7 +1807,7 @@ static void handle_settled_icl_change(struct pl_data *chip) { union power_supply_propval pval = {0, }; int new_total_settled_ua; - int rc; + int rc, val; int main_settled_ua; int main_limited; int total_current_ua; @@ -1722,23 +1819,21 @@ static void handle_settled_icl_change(struct pl_data *chip) * call aicl split only when USBIN_USBIN and enabled * and if aicl changed */ - rc = power_supply_get_property(chip->main_psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, - &pval); + rc = chip->chg_param->iio_read(chip->dev, + PSY_IIO_MAIN_INPUT_CURRENT_SETTLED, &val); if (rc < 0) { pr_err("Couldn't get aicl settled value rc=%d\n", rc); return; } - main_settled_ua = pval.intval; + main_settled_ua = val; - rc = power_supply_get_property(chip->batt_psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, - &pval); + rc = chip->chg_param->iio_read(chip->dev, PSY_IIO_INPUT_CURRENT_LIMITED, + &val); if (rc < 0) { pr_err("Couldn't get aicl settled value rc=%d\n", rc); return; } - main_limited = pval.intval; + main_limited = val; if ((main_limited && (main_settled_ua + chip->pl_settled_ua) < 1400000) || (main_settled_ua == 0) @@ -1786,11 +1881,11 @@ static void handle_parallel_in_taper(struct pl_data *chip) if (get_effective_result_locked(chip->pl_disable_votable)) return; - if (!chip->pl_psy) + if (IS_ERR_OR_NULL(chip->iio_chan_list_smb_parallel)) return; - rc = power_supply_get_property(chip->pl_psy, - POWER_SUPPLY_PROP_CHARGE_TYPE, &pval); + rc = battery_read_iio_prop(chip, SMB_PARALLEL, + BAT_SMB_PARALLEL_CHARGE_TYPE, &pval.intval); if (rc < 0) { pr_err("Couldn't get pl charge type rc=%d\n", rc); return; @@ -1800,7 +1895,7 @@ static void handle_parallel_in_taper(struct pl_data *chip) * if parallel is seen in taper mode ever, that is an anomaly and * we disable parallel charger */ - if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { + if (pval.intval == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER) { vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER, true, 0); return; @@ -1809,7 +1904,7 @@ static void handle_parallel_in_taper(struct pl_data *chip) static void handle_usb_change(struct pl_data *chip) { - int rc; + int rc, val; union power_supply_propval pval = {0, }; if (!chip->usb_psy) @@ -1838,10 +1933,12 @@ static void handle_usb_change(struct pl_data *chip) chip->main_fcc_ua = 0; chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN; } else { - rc = power_supply_get_property(chip->usb_psy, - POWER_SUPPLY_PROP_REAL_TYPE, &pval); - if (!rc) - chip->charger_type = pval.intval; + rc = chip->chg_param->iio_read(chip->dev, PSY_IIO_USB_REAL_TYPE, + &val); + if (rc < 0) + pr_err("Couldn't get USB real type rc=%d\n", rc); + else + chip->charger_type = val; } } @@ -1850,19 +1947,13 @@ static void status_change_work(struct work_struct *work) struct pl_data *chip = container_of(work, struct pl_data, status_change_work.work); - if (!chip->main_psy && is_main_available(chip)) { - /* - * re-run election for FCC/FV/ICL once main_psy - * is available to ensure all votes are reflected - * on hardware - */ - rerun_election(chip->usb_icl_votable); - rerun_election(chip->fcc_votable); - rerun_election(chip->fv_votable); - } - - if (!chip->main_psy) - return; + /* + * re-run election for FCC/FV/ICL to ensure all + * votes are reflected on hardware + */ + rerun_election(chip->usb_icl_votable); + rerun_election(chip->fcc_votable); + rerun_election(chip->fv_votable); if (!is_batt_available(chip)) return; @@ -1885,8 +1976,7 @@ static int pl_notifier_call(struct notifier_block *nb, return NOTIFY_OK; if ((strcmp(psy->desc->name, "parallel") == 0) - || (strcmp(psy->desc->name, "battery") == 0) - || (strcmp(psy->desc->name, "main") == 0)) + || (strcmp(psy->desc->name, "battery") == 0)) schedule_delayed_work(&chip->status_change_work, 0); return NOTIFY_OK; @@ -1943,7 +2033,7 @@ static void qcom_batt_create_debugfs(struct pl_data *chip) } #define DEFAULT_RESTRICTED_CURRENT_UA 1000000 -int qcom_batt_init(struct charger_param *chg_param) +int qcom_batt_init(struct device *dev, struct charger_param *chg_param) { struct pl_data *chip; int rc = 0; @@ -1953,6 +2043,11 @@ int qcom_batt_init(struct charger_param *chg_param) return -EINVAL; } + if (!chg_param->iio_read || !chg_param->iio_write) { + pr_err("Invalid iio read/write pointers\n"); + return -EINVAL; + } + /* initialize just once */ if (the_chip) { pr_err("was initialized earlier. Failing now\n"); @@ -1963,6 +2058,7 @@ int qcom_batt_init(struct charger_param *chg_param) if (!chip) return -ENOMEM; + chip->dev = dev; qcom_batt_create_debugfs(chip); chip->slave_pct = 50; @@ -1970,7 +2066,7 @@ int qcom_batt_init(struct charger_param *chg_param) pl_config_init(chip, chg_param->smb_version); chip->restricted_current = DEFAULT_RESTRICTED_CURRENT_UA; - chip->pl_ws = wakeup_source_register("qcom-battery"); + chip->pl_ws = wakeup_source_register(NULL, "qcom-battery"); if (!chip->pl_ws) goto cleanup; diff --git a/drivers/power/supply/qcom/battery.h b/drivers/power/supply/qcom/battery.h index 04163a96bb8a..300a6e86d8dc 100644 --- a/drivers/power/supply/qcom/battery.h +++ b/drivers/power/supply/qcom/battery.h @@ -12,8 +12,10 @@ struct charger_param { u32 hvdcp2_max_icl_ua; u32 hvdcp3_max_icl_ua; u32 forced_main_fcc; + int (*iio_read)(struct device *dev, int iio_chan, int *val); + int (*iio_write)(struct device *dev, int iio_chan, int val); }; -int qcom_batt_init(struct charger_param *param); +int qcom_batt_init(struct device *dev, struct charger_param *param); void qcom_batt_deinit(void); #endif /* __BATTERY_H */ diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index c1985bee4aeb..e21f9234e853 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -11,9 +11,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -22,6 +22,7 @@ #include #include "smb5-reg.h" #include "smb5-lib.h" +#include "smb5-iio.h" #include "schgm-flash.h" static struct smb_params smb5_pmi632_params = { @@ -201,7 +202,6 @@ static struct smb_params smb5_pm8150b_params = { struct smb_dt_props { int usb_icl_ua; - struct device_node *revid_dev_node; enum float_options float_option; int chg_inhibit_thr_mv; bool no_battery; @@ -225,6 +225,9 @@ struct smb5 { 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; @@ -303,52 +306,33 @@ static const struct clamp_config clamp_levels[] = { static int smb5_chg_config_init(struct smb5 *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 rc = 0; + struct device_node *node = chg->dev->of_node; + int subtype = (u8)of_device_get_match_data(chg->dev); - 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 PM8150B_SUBTYPE: - chip->chg.chg_param.smb_version = PM8150B_SUBTYPE; + switch (subtype) { + case PM8150B: + chip->chg.chg_param.smb_version = PM8150B; chg->param = smb5_pm8150b_params; chg->name = "pm8150b_charger"; chg->wa_flags |= CHG_TERMINATION_WA; break; - case PM7250B_SUBTYPE: - chip->chg.chg_param.smb_version = PM7250B_SUBTYPE; + case PM7250B: + chip->chg.chg_param.smb_version = PM7250B; chg->param = smb5_pm8150b_params; chg->name = "pm7250b_charger"; chg->wa_flags |= CHG_TERMINATION_WA; chg->uusb_moisture_protection_capable = true; break; - case PM6150_SUBTYPE: - chip->chg.chg_param.smb_version = PM6150_SUBTYPE; + case PM6150: + chip->chg.chg_param.smb_version = PM6150; chg->param = smb5_pm8150b_params; chg->name = "pm6150_charger"; chg->wa_flags |= SW_THERM_REGULATION_WA | CHG_TERMINATION_WA; - if (pmic_rev_id->rev4 >= 2) - chg->uusb_moisture_protection_capable = true; + chg->uusb_moisture_protection_capable = true; chg->main_fcc_max = PM6150_MAX_FCC_UA; break; - case PMI632_SUBTYPE: - chip->chg.chg_param.smb_version = PMI632_SUBTYPE; + case PMI632: + chip->chg.chg_param.smb_version = PMI632; chg->wa_flags |= WEAK_ADAPTER_WA | USBIN_OV_WA | CHG_TERMINATION_WA | USBIN_ADC_WA | SKIP_MISC_PBS_IRQ_WA; @@ -358,17 +342,14 @@ static int smb5_chg_config_init(struct smb5 *chip) /* PMI632 does not support PD */ chg->pd_not_supported = true; chg->lpd_disabled = true; - if (pmic_rev_id->rev4 >= 2) - chg->uusb_moisture_protection_enabled = true; + chg->uusb_moisture_protection_enabled = true; chg->hw_max_icl_ua = (chip->dt.usb_icl_ua > 0) ? chip->dt.usb_icl_ua : PMI632_MAX_ICL_UA; break; default: - pr_err("PMIC subtype %d not supported\n", - pmic_rev_id->pmic_subtype); - rc = -EINVAL; - goto out; + pr_err("PMIC subtype %d not supported\n", subtype); + return -EINVAL; } chg->chg_freq.freq_5V = 600; @@ -385,9 +366,7 @@ static int smb5_chg_config_init(struct smb5 *chip) if (of_property_read_bool(node, "qcom,disable-fcc-restriction")) chg->main_fcc_max = -EINVAL; -out: - of_node_put(revid_dev_node); - return rc; + return 0; } #define PULL_NO_PULL 0 @@ -446,12 +425,16 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node) of_property_read_u32(node, "qcom,sec-charger-config", &chip->dt.sec_charger_config); chg->sec_cp_present = - chip->dt.sec_charger_config == POWER_SUPPLY_CHARGER_SEC_CP || - chip->dt.sec_charger_config == POWER_SUPPLY_CHARGER_SEC_CP_PL; + chip->dt.sec_charger_config == + QTI_POWER_SUPPLY_CHARGER_SEC_CP || + chip->dt.sec_charger_config == + QTI_POWER_SUPPLY_CHARGER_SEC_CP_PL; chg->sec_pl_present = - chip->dt.sec_charger_config == POWER_SUPPLY_CHARGER_SEC_PL || - chip->dt.sec_charger_config == POWER_SUPPLY_CHARGER_SEC_CP_PL; + chip->dt.sec_charger_config == + QTI_POWER_SUPPLY_CHARGER_SEC_PL || + chip->dt.sec_charger_config == + QTI_POWER_SUPPLY_CHARGER_SEC_CP_PL; chg->step_chg_enabled = of_property_read_bool(node, "qcom,step-charging-enable"); @@ -678,7 +661,7 @@ static int smb5_parse_dt_currents(struct smb5 *chip, struct device_node *node) "qcom,otg-cl-ua", &chg->otg_cl_ua); if (rc < 0) chg->otg_cl_ua = - (chip->chg.chg_param.smb_version == PMI632_SUBTYPE) ? + (chip->chg.chg_param.smb_version == PMI632) ? MICRO_1PA : MICRO_3PA; rc = of_property_read_u32(node, "qcom,chg-term-src", @@ -804,16 +787,16 @@ static int smb5_parse_dt(struct smb5 *chip) return 0; } -static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, - const union power_supply_propval *val) +int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, + int val) { int rc = 0, i; struct clamp_config clamp_config; enum comp_clamp_levels level; - level = val->intval; + level = val; if (level >= MAX_CLAMP_LEVEL) { - pr_err("Invalid comp clamp level=%d\n", val->intval); + pr_err("Invalid comp clamp level=%d\n", val); return -EINVAL; } @@ -826,7 +809,7 @@ static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, clamp_levels[level].reg[i], rc); } - chg->comp_clamp_level = val->intval; + chg->comp_clamp_level = val; return rc; } @@ -838,42 +821,13 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_PD_CURRENT_MAX, + POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_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_LOW_POWER, - POWER_SUPPLY_PROP_PD_ACTIVE, - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, - POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, - POWER_SUPPLY_PROP_BOOST_CURRENT, - POWER_SUPPLY_PROP_PE_START, - POWER_SUPPLY_PROP_CTM_CURRENT_MAX, - POWER_SUPPLY_PROP_HW_CURRENT_MAX, - POWER_SUPPLY_PROP_REAL_TYPE, - POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, - POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, - POWER_SUPPLY_PROP_CONNECTOR_TYPE, - POWER_SUPPLY_PROP_CONNECTOR_HEALTH, POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT, - POWER_SUPPLY_PROP_SMB_EN_MODE, - POWER_SUPPLY_PROP_SMB_EN_REASON, - POWER_SUPPLY_PROP_ADAPTER_CC_MODE, POWER_SUPPLY_PROP_SCOPE, - POWER_SUPPLY_PROP_MOISTURE_DETECTED, - POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, - POWER_SUPPLY_PROP_QC_OPTI_DISABLE, - POWER_SUPPLY_PROP_VOLTAGE_VPH, - POWER_SUPPLY_PROP_THERM_ICL_LIMIT, - POWER_SUPPLY_PROP_SKIN_HEALTH, - POWER_SUPPLY_PROP_APSD_RERUN, - POWER_SUPPLY_PROP_APSD_TIMEOUT, - POWER_SUPPLY_PROP_CHARGER_STATUS, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, }; static int smb5_usb_get_prop(struct power_supply *psy, @@ -883,7 +837,6 @@ static int smb5_usb_get_prop(struct power_supply *psy, struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; - u8 reg = 0, buff[2] = {0}; val->intval = 0; @@ -900,17 +853,11 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smblib_get_prop_usb_voltage_max(chg, val); break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: - if (chg->usbin_forced_max_uv) - val->intval = chg->usbin_forced_max_uv; - else - smblib_get_prop_usb_voltage_max_design(chg, val); - break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblib_get_prop_usb_voltage_now(chg, val); break; - case POWER_SUPPLY_PROP_PD_CURRENT_MAX: - val->intval = get_client_vote(chg->usb_icl_votable, PD_VOTER); + case POWER_SUPPLY_PROP_CURRENT_NOW: + rc = smblib_get_prop_usb_current_now(chg, val); break; case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_get_prop_input_current_settled(chg, val); @@ -918,130 +865,12 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_TYPE: val->intval = POWER_SUPPLY_TYPE_USB_PD; break; - case POWER_SUPPLY_PROP_REAL_TYPE: - val->intval = chg->real_charger_type; - break; - case POWER_SUPPLY_PROP_TYPEC_MODE: - rc = smblib_get_usb_prop_typec_mode(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: - rc = smblib_get_prop_typec_power_role(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION: - rc = smblib_get_prop_typec_cc_orientation(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_SRC_RP: - rc = smblib_get_prop_typec_select_rp(chg, val); - break; - case POWER_SUPPLY_PROP_LOW_POWER: - rc = smblib_get_prop_low_power(chg, val); - break; - case POWER_SUPPLY_PROP_PD_ACTIVE: - val->intval = chg->pd_active; - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED: - rc = smblib_get_prop_input_current_settled(chg, val); - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW: - rc = smblib_get_prop_usb_current_now(chg, val); - break; - case POWER_SUPPLY_PROP_BOOST_CURRENT: - val->intval = chg->boost_current_ua; - break; - case POWER_SUPPLY_PROP_PD_IN_HARD_RESET: - rc = smblib_get_prop_pd_in_hard_reset(chg, val); - break; - case POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED: - val->intval = chg->system_suspend_supported; - break; - case POWER_SUPPLY_PROP_PE_START: - rc = smblib_get_pe_start(chg, val); - break; - case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: - val->intval = get_client_vote(chg->usb_icl_votable, CTM_VOTER); - break; - case POWER_SUPPLY_PROP_HW_CURRENT_MAX: - rc = smblib_get_charge_current(chg, &val->intval); - break; - case POWER_SUPPLY_PROP_PR_SWAP: - rc = smblib_get_prop_pr_swap_in_progress(chg, val); - break; - case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX: - val->intval = chg->voltage_max_uv; - break; - case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN: - val->intval = chg->voltage_min_uv; - break; - case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: - val->intval = get_client_vote(chg->usb_icl_votable, - USB_PSY_VOTER); - break; - case POWER_SUPPLY_PROP_CONNECTOR_TYPE: - val->intval = chg->connector_type; - break; - case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: - val->intval = smblib_get_prop_connector_health(chg); - break; case POWER_SUPPLY_PROP_SCOPE: rc = smblib_get_prop_scope(chg, val); break; - case POWER_SUPPLY_PROP_SMB_EN_MODE: - mutex_lock(&chg->smb_lock); - val->intval = chg->sec_chg_selected; - mutex_unlock(&chg->smb_lock); - break; - case POWER_SUPPLY_PROP_SMB_EN_REASON: - val->intval = chg->cp_reason; - break; - case POWER_SUPPLY_PROP_MOISTURE_DETECTED: - val->intval = chg->moisture_present; - break; - case POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED: - val->intval = !chg->flash_active; - break; - case POWER_SUPPLY_PROP_QC_OPTI_DISABLE: - if (chg->hw_die_temp_mitigation) - val->intval = POWER_SUPPLY_QC_THERMAL_BALANCE_DISABLE - | POWER_SUPPLY_QC_INOV_THERMAL_DISABLE; - if (chg->hw_connector_mitigation) - val->intval |= POWER_SUPPLY_QC_CTM_DISABLE; - break; - case POWER_SUPPLY_PROP_VOLTAGE_VPH: - rc = smblib_get_prop_vph_voltage_now(chg, val); - break; - case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: val->intval = get_client_vote(chg->usb_icl_votable, - THERMAL_THROTTLE_VOTER); - break; - case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: - val->intval = chg->adapter_cc_mode; - break; - case POWER_SUPPLY_PROP_SKIN_HEALTH: - val->intval = smblib_get_skin_temp_status(chg); - break; - case POWER_SUPPLY_PROP_APSD_RERUN: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_APSD_TIMEOUT: - val->intval = chg->apsd_ext_timeout; - break; - case POWER_SUPPLY_PROP_CHARGER_STATUS: - val->intval = 0; - if (chg->sdam_base) { - rc = smblib_read(chg, - chg->sdam_base + SDAM_QC_DET_STATUS_REG, ®); - if (!rc) - val->intval = reg; - } - break; - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED: - val->intval = 0; - if (chg->sdam_base) { - rc = smblib_batch_read(chg, - chg->sdam_base + SDAM_QC_ADC_LSB_REG, buff, 2); - if (!rc) - val->intval = (buff[1] << 8 | buff[0]) * 1038; - } + USB_PSY_VOTER); break; default: pr_err("get prop %d is not supported in usb\n", psp); @@ -1057,88 +886,21 @@ static int smb5_usb_get_prop(struct power_supply *psy, return 0; } -#define MIN_THERMAL_VOTE_UA 500000 static int smb5_usb_set_prop(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) { struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; - int icl, rc = 0; + int rc = 0; switch (psp) { - case POWER_SUPPLY_PROP_PD_CURRENT_MAX: - rc = smblib_set_prop_pd_current_max(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: - rc = smblib_set_prop_typec_power_role(chg, val); - break; - case POWER_SUPPLY_PROP_TYPEC_SRC_RP: - rc = smblib_set_prop_typec_select_rp(chg, val); - break; - case POWER_SUPPLY_PROP_PD_ACTIVE: - rc = smblib_set_prop_pd_active(chg, val); - break; - case POWER_SUPPLY_PROP_PD_IN_HARD_RESET: - rc = smblib_set_prop_pd_in_hard_reset(chg, val); - break; - case POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED: - chg->system_suspend_supported = val->intval; - break; - case POWER_SUPPLY_PROP_BOOST_CURRENT: - rc = smblib_set_prop_boost_current(chg, val); - break; - case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: - rc = vote(chg->usb_icl_votable, CTM_VOTER, - val->intval >= 0, val->intval); - break; - case POWER_SUPPLY_PROP_PR_SWAP: - rc = smblib_set_prop_pr_swap_in_progress(chg, val); - break; - case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX: - rc = smblib_set_prop_pd_voltage_max(chg, val); - break; - case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN: - rc = smblib_set_prop_pd_voltage_min(chg, val); - break; - case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: - rc = smblib_set_prop_sdp_current_max(chg, val); - break; - case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: - chg->connector_health = val->intval; - power_supply_changed(chg->usb_psy); - break; - case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: - if (!is_client_vote_enabled(chg->usb_icl_votable, - THERMAL_THROTTLE_VOTER)) { - chg->init_thermal_ua = get_effective_result( - chg->usb_icl_votable); - icl = chg->init_thermal_ua + val->intval; - } else { - icl = get_client_vote(chg->usb_icl_votable, - THERMAL_THROTTLE_VOTER) + val->intval; - } - - if (icl >= MIN_THERMAL_VOTE_UA) - rc = vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER, - (icl != chg->init_thermal_ua) ? true : false, - icl); - else - rc = -EINVAL; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: - smblib_set_prop_usb_voltage_max_limit(chg, val); - break; - case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: - chg->adapter_cc_mode = val->intval; - break; - case POWER_SUPPLY_PROP_APSD_RERUN: - del_timer_sync(&chg->apsd_timer); - chg->apsd_ext_timeout = false; - smblib_rerun_apsd(chg); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + rc = smblib_set_prop_sdp_current_max(chg, val->intval); break; default: - pr_err("set prop %d is not supported\n", psp); + pr_err("Set prop %d is not supported in usb psy\n", + psp); rc = -EINVAL; break; } @@ -1150,12 +912,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, enum power_supply_property psp) { switch (psp) { - case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: - case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: - case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: - case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: - case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: - case POWER_SUPPLY_PROP_APSD_RERUN: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: return 1; default: break; @@ -1219,8 +976,10 @@ static int smb5_usb_port_get_prop(struct power_supply *psy, if (!val->intval) break; - if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || - (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) + if (((chg->typec_mode == + QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || + (chg->connector_type == + QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) val->intval = 1; else @@ -1290,275 +1049,17 @@ static int smb5_init_usb_port_psy(struct smb5 *chip) return 0; } -/***************************** - * USB MAIN PSY REGISTRATION * - *****************************/ - -static enum power_supply_property smb5_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_ACTIVE, - POWER_SUPPLY_PROP_FLASH_TRIGGER, - POWER_SUPPLY_PROP_TOGGLE_STAT, - POWER_SUPPLY_PROP_MAIN_FCC_MAX, - POWER_SUPPLY_PROP_IRQ_STATUS, - POWER_SUPPLY_PROP_FORCE_MAIN_FCC, - POWER_SUPPLY_PROP_FORCE_MAIN_ICL, - POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_HOT_TEMP, -}; - -static int smb5_usb_main_get_prop(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct smb5 *chip = power_supply_get_drvdata(psy); - struct smb_charger *chg = &chip->chg; - int rc = 0; - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - rc = smblib_get_charge_param(chg, &chg->param.fv, &val->intval); - break; - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - rc = smblib_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 = smblib_get_prop_input_current_settled(chg, val); - break; - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED: - rc = smblib_get_prop_input_voltage_settled(chg, val); - break; - case POWER_SUPPLY_PROP_FCC_DELTA: - rc = smblib_get_prop_fcc_delta(chg, val); - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblib_get_icl_current(chg, &val->intval); - break; - case POWER_SUPPLY_PROP_FLASH_ACTIVE: - val->intval = chg->flash_active; - break; - case POWER_SUPPLY_PROP_FLASH_TRIGGER: - val->intval = 0; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) - rc = schgm_flash_get_vreg_ok(chg, &val->intval); - break; - case POWER_SUPPLY_PROP_TOGGLE_STAT: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_MAIN_FCC_MAX: - val->intval = chg->main_fcc_max; - break; - case POWER_SUPPLY_PROP_IRQ_STATUS: - rc = smblib_get_irq_status(chg, val); - break; - case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: - rc = smblib_get_charge_param(chg, &chg->param.fcc, - &val->intval); - break; - case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: - rc = smblib_get_charge_param(chg, &chg->param.usb_icl, - &val->intval); - break; - case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: - val->intval = chg->comp_clamp_level; - break; - /* Use this property to report SMB health */ - case POWER_SUPPLY_PROP_HEALTH: - rc = val->intval = smblib_get_prop_smb_health(chg); - break; - /* Use this property to report overheat status */ - case POWER_SUPPLY_PROP_HOT_TEMP: - val->intval = chg->thermal_overheat; - 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 smb5_usb_main_set_prop(struct power_supply *psy, - enum power_supply_property psp, - const union power_supply_propval *val) -{ - struct smb5 *chip = power_supply_get_drvdata(psy); - struct smb_charger *chg = &chip->chg; - union power_supply_propval pval = {0, }; - enum power_supply_type real_chg_type = chg->real_charger_type; - int rc = 0, offset_ua = 0; - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval); - break; - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - /* Adjust Main FCC for QC3.0 + SMB1390 */ - rc = smblib_get_qc3_main_icl_offset(chg, &offset_ua); - if (rc < 0) - offset_ua = 0; - - rc = smblib_set_charge_param(chg, &chg->param.fcc, - val->intval + offset_ua); - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblib_set_icl_current(chg, val->intval); - break; - case POWER_SUPPLY_PROP_FLASH_ACTIVE: - if ((chg->chg_param.smb_version == PMI632_SUBTYPE) - && (chg->flash_active != val->intval)) { - chg->flash_active = val->intval; - - rc = smblib_get_prop_usb_present(chg, &pval); - if (rc < 0) - pr_err("Failed to get USB preset status rc=%d\n", - rc); - if (pval.intval) { - rc = smblib_force_vbus_voltage(chg, - chg->flash_active ? FORCE_5V_BIT - : IDLE_BIT); - if (rc < 0) - pr_err("Failed to force 5V\n"); - else - chg->pulse_cnt = 0; - } else { - /* USB absent & flash not-active - vote 100mA */ - vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, - true, SDP_100_MA); - } - - pr_debug("flash active VBUS 5V restriction %s\n", - chg->flash_active ? "applied" : "removed"); - - /* Update userspace */ - if (chg->batt_psy) - power_supply_changed(chg->batt_psy); - } - break; - case POWER_SUPPLY_PROP_TOGGLE_STAT: - rc = smblib_toggle_smb_en(chg, val->intval); - break; - case POWER_SUPPLY_PROP_MAIN_FCC_MAX: - chg->main_fcc_max = val->intval; - rerun_election(chg->fcc_votable); - break; - case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: - vote_override(chg->fcc_main_votable, CC_MODE_VOTER, - (val->intval < 0) ? false : true, val->intval); - if (val->intval >= 0) - chg->chg_param.forced_main_fcc = val->intval; - /* - * Remove low vote on FCC_MAIN, for WLS, to allow FCC_MAIN to - * rise to its full value. - */ - if (val->intval < 0) - vote(chg->fcc_main_votable, WLS_PL_CHARGING_VOTER, - false, 0); - /* Main FCC updated re-calculate FCC */ - rerun_election(chg->fcc_votable); - break; - case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: - vote_override(chg->usb_icl_votable, CC_MODE_VOTER, - (val->intval < 0) ? false : true, val->intval); - /* Main ICL updated re-calculate ILIM */ - if (real_chg_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || - real_chg_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) - rerun_election(chg->fcc_votable); - break; - case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: - rc = smb5_set_prop_comp_clamp_level(chg, val); - break; - case POWER_SUPPLY_PROP_HOT_TEMP: - rc = smblib_set_prop_thermal_overheat(chg, val->intval); - break; - default: - pr_err("set prop %d is not supported\n", psp); - rc = -EINVAL; - break; - } - - return rc; -} - -static int smb5_usb_main_prop_is_writeable(struct power_supply *psy, - enum power_supply_property psp) -{ - int rc; - - switch (psp) { - case POWER_SUPPLY_PROP_TOGGLE_STAT: - case POWER_SUPPLY_PROP_MAIN_FCC_MAX: - case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: - case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: - case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: - case POWER_SUPPLY_PROP_HOT_TEMP: - rc = 1; - break; - default: - rc = 0; - break; - } - - return rc; -} - -static const struct power_supply_desc usb_main_psy_desc = { - .name = "main", - .type = POWER_SUPPLY_TYPE_MAIN, - .properties = smb5_usb_main_props, - .num_properties = ARRAY_SIZE(smb5_usb_main_props), - .get_property = smb5_usb_main_get_prop, - .set_property = smb5_usb_main_set_prop, - .property_is_writeable = smb5_usb_main_prop_is_writeable, -}; - -static int smb5_init_usb_main_psy(struct smb5 *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; -} - /************************* * DC PSY REGISTRATION * *************************/ static enum power_supply_property smb5_dc_props[] = { - POWER_SUPPLY_PROP_INPUT_SUSPEND, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, - POWER_SUPPLY_PROP_REAL_TYPE, - POWER_SUPPLY_PROP_DC_RESET, - POWER_SUPPLY_PROP_AICL_DONE, }; static int smb5_dc_get_prop(struct power_supply *psy, @@ -1570,7 +1071,7 @@ static int smb5_dc_get_prop(struct power_supply *psy, int rc = 0; switch (psp) { - case POWER_SUPPLY_PROP_INPUT_SUSPEND: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: val->intval = get_effective_result(chg->dc_suspend_votable); break; case POWER_SUPPLY_PROP_PRESENT: @@ -1588,18 +1089,6 @@ static int smb5_dc_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smblib_get_prop_dc_voltage_max(chg, val); break; - case POWER_SUPPLY_PROP_REAL_TYPE: - val->intval = POWER_SUPPLY_TYPE_WIRELESS; - break; - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: - rc = smblib_get_prop_voltage_wls_output(chg, val); - break; - case POWER_SUPPLY_PROP_DC_RESET: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_AICL_DONE: - val->intval = chg->dcin_aicl_done; - break; default: return -EINVAL; } @@ -1619,19 +1108,12 @@ static int smb5_dc_set_prop(struct power_supply *psy, int rc = 0; switch (psp) { - case POWER_SUPPLY_PROP_INPUT_SUSPEND: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: rc = vote(chg->dc_suspend_votable, WBC_VOTER, - (bool)val->intval, 0); - break; + (bool)val->intval, 0); case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_set_prop_dc_current_max(chg, val); break; - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: - rc = smblib_set_prop_voltage_wls_output(chg, val); - break; - case POWER_SUPPLY_PROP_DC_RESET: - rc = smblib_set_prop_dc_reset(chg); - break; default: return -EINVAL; } @@ -1643,7 +1125,7 @@ static int smb5_dc_prop_is_writeable(struct power_supply *psy, enum power_supply_property psp) { switch (psp) { - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION: + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: case POWER_SUPPLY_PROP_CURRENT_MAX: return 1; default: @@ -1655,7 +1137,7 @@ static int smb5_dc_prop_is_writeable(struct power_supply *psy, static const struct power_supply_desc dc_psy_desc = { .name = "dc", - .type = POWER_SUPPLY_TYPE_WIRELESS, + .type = POWER_SUPPLY_TYPE_MAINS, .properties = smb5_dc_props, .num_properties = ARRAY_SIZE(smb5_dc_props), .get_property = smb5_dc_get_prop, @@ -1685,184 +1167,116 @@ static int smb5_init_dc_psy(struct smb5 *chip) * BATT PSY REGISTRATION * *************************/ static enum power_supply_property smb5_batt_props[] = { - POWER_SUPPLY_PROP_INPUT_SUSPEND, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 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_CHARGER_TEMP_MAX, - POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_MAX, - POWER_SUPPLY_PROP_VOLTAGE_QNOVO, POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CURRENT_QNOVO, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 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_PARALLEL_DISABLE, - POWER_SUPPLY_PROP_SET_SHIP_MODE, - POWER_SUPPLY_PROP_DIE_HEALTH, - POWER_SUPPLY_PROP_RERUN_AICL, - POWER_SUPPLY_PROP_DP_DM, 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_FORCE_RECHARGE, - POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, }; #define DEBUG_ACCESSORY_TEMP_DECIDEGC 250 static int smb5_batt_get_prop(struct power_supply *psy, enum power_supply_property psp, - union power_supply_propval *val) + union power_supply_propval *pval) { struct smb_charger *chg = power_supply_get_drvdata(psy); int rc = 0; switch (psp) { case POWER_SUPPLY_PROP_STATUS: - rc = smblib_get_prop_batt_status(chg, val); + rc = smblib_get_prop_batt_status(chg, pval); break; case POWER_SUPPLY_PROP_HEALTH: - rc = smblib_get_prop_batt_health(chg, val); + rc = smblib_get_prop_batt_health(chg, pval); break; case POWER_SUPPLY_PROP_PRESENT: - rc = smblib_get_prop_batt_present(chg, val); + rc = smblib_get_prop_batt_present(chg, pval); break; - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - rc = smblib_get_prop_input_suspend(chg, val); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + rc = smblib_get_prop_input_current_limit_usb(chg, pval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE: - rc = smblib_get_prop_batt_charge_type(chg, val); + rc = smblib_get_prop_batt_charge_type(chg, pval); break; case POWER_SUPPLY_PROP_CAPACITY: - rc = smblib_get_prop_batt_capacity(chg, val); + rc = smblib_get_prop_batt_capacity(chg, pval); break; case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: - rc = smblib_get_prop_system_temp_level(chg, val); + rc = smblib_get_prop_system_temp_level(chg, pval); break; case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: - rc = smblib_get_prop_system_temp_level_max(chg, val); - break; - case POWER_SUPPLY_PROP_CHARGER_TEMP: - rc = smblib_get_prop_charger_temp(chg, val); - break; - case POWER_SUPPLY_PROP_CHARGER_TEMP_MAX: - val->intval = chg->charger_temp_max; - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: - rc = smblib_get_prop_input_current_limited(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 = chg->sw_jeita_enabled; + rc = smblib_get_prop_system_temp_level_max(chg, pval); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_VOLTAGE_NOW, val); + SMB5_QG_VOLTAGE_NOW, &pval->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: - val->intval = get_client_vote(chg->fv_votable, + pval->intval = get_client_vote(chg->fv_votable, QNOVO_VOTER); - if (val->intval < 0) - val->intval = get_client_vote(chg->fv_votable, + if (pval->intval < 0) + pval->intval = get_client_vote(chg->fv_votable, BATT_PROFILE_VOTER); break; - case POWER_SUPPLY_PROP_VOLTAGE_QNOVO: - val->intval = get_client_vote_locked(chg->fv_votable, - QNOVO_VOTER); - break; case POWER_SUPPLY_PROP_CURRENT_NOW: - rc = smblib_get_batt_current_now(chg, val); - break; - case POWER_SUPPLY_PROP_CURRENT_QNOVO: - val->intval = get_client_vote_locked(chg->fcc_votable, - QNOVO_VOTER); + rc = smblib_get_batt_current_now(chg, pval); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - val->intval = get_client_vote(chg->fcc_votable, + pval->intval = get_client_vote(chg->fcc_votable, BATT_PROFILE_VOTER); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: - val->intval = get_effective_result(chg->fcc_votable); + pval->intval = get_effective_result(chg->fcc_votable); break; case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: - rc = smblib_get_prop_batt_iterm(chg, val); + rc = smblib_get_prop_batt_iterm(chg, pval); break; case POWER_SUPPLY_PROP_TEMP: - if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) - val->intval = DEBUG_ACCESSORY_TEMP_DECIDEGC; + if (chg->typec_mode == + QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) + pval->intval = DEBUG_ACCESSORY_TEMP_DECIDEGC; else rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_TEMP, val); + SMB5_QG_TEMP, &pval->intval); break; case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; - break; - case POWER_SUPPLY_PROP_CHARGE_DONE: - rc = smblib_get_prop_batt_charge_done(chg, val); - break; - case POWER_SUPPLY_PROP_PARALLEL_DISABLE: - val->intval = get_client_vote(chg->pl_disable_votable, - USER_VOTER); - 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 = smblib_get_die_health(chg, val); - break; - case POWER_SUPPLY_PROP_DP_DM: - val->intval = chg->pulse_cnt; - break; - case POWER_SUPPLY_PROP_RERUN_AICL: - val->intval = 0; + pval->intval = POWER_SUPPLY_TECHNOLOGY_LION; break; case POWER_SUPPLY_PROP_CHARGE_COUNTER: rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CHARGE_COUNTER, val); + SMB5_QG_CHARGE_COUNTER, &pval->intval); break; case POWER_SUPPLY_PROP_CYCLE_COUNT: rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CYCLE_COUNT, val); - break; - case POWER_SUPPLY_PROP_RECHARGE_SOC: - val->intval = chg->auto_recharge_soc; - break; - case POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE: - val->intval = 0; - if (!chg->qnovo_disable_votable) - chg->qnovo_disable_votable = - find_votable("QNOVO_DISABLE"); - - if (chg->qnovo_disable_votable) - val->intval = - !get_effective_result( - chg->qnovo_disable_votable); + SMB5_QG_CYCLE_COUNT, &pval->intval); break; case POWER_SUPPLY_PROP_CHARGE_FULL: rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CHARGE_FULL, val); + SMB5_QG_CHARGE_FULL, &pval->intval); break; - case POWER_SUPPLY_PROP_FORCE_RECHARGE: - val->intval = 0; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + rc = smblib_get_prop_from_bms(chg, + SMB5_QG_CHARGE_FULL_DESIGN, &pval->intval); break; - case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE: - val->intval = chg->fcc_stepper_enable; + case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: + rc = smblib_get_prop_from_bms(chg, + SMB5_QG_TIME_TO_FULL_NOW, &pval->intval); break; default: pr_err("batt power supply prop %d not supported\n", psp); @@ -1888,8 +1302,8 @@ static int smb5_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_STATUS: rc = smblib_set_prop_batt_status(chg, val); break; - case POWER_SUPPLY_PROP_INPUT_SUSPEND: - rc = smblib_set_prop_input_suspend(chg, val); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + rc = smblib_set_prop_input_current_limit_usb(chg, val); break; case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: rc = smblib_set_prop_system_temp_level(chg, val); @@ -1897,80 +1311,14 @@ static int smb5_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: rc = smblib_set_prop_batt_capacity(chg, val); break; - case POWER_SUPPLY_PROP_PARALLEL_DISABLE: - vote(chg->pl_disable_votable, USER_VOTER, (bool)val->intval, 0); - break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: chg->batt_profile_fv_uv = val->intval; vote(chg->fv_votable, BATT_PROFILE_VOTER, true, val->intval); break; - case POWER_SUPPLY_PROP_VOLTAGE_QNOVO: - if (val->intval == -EINVAL) { - vote(chg->fv_votable, BATT_PROFILE_VOTER, true, - chg->batt_profile_fv_uv); - vote(chg->fv_votable, QNOVO_VOTER, false, 0); - } else { - vote(chg->fv_votable, QNOVO_VOTER, true, val->intval); - vote(chg->fv_votable, BATT_PROFILE_VOTER, false, 0); - } - 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_CURRENT_QNOVO: - vote(chg->pl_disable_votable, PL_QNOVO_VOTER, - val->intval != -EINVAL && val->intval < 2000000, 0); - if (val->intval == -EINVAL) { - vote(chg->fcc_votable, BATT_PROFILE_VOTER, - true, chg->batt_profile_fcc_ua); - vote(chg->fcc_votable, QNOVO_VOTER, false, 0); - } else { - vote(chg->fcc_votable, QNOVO_VOTER, true, val->intval); - vote(chg->fcc_votable, BATT_PROFILE_VOTER, false, 0); - } - 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 = smblib_set_prop_ship_mode(chg, val); - break; - case POWER_SUPPLY_PROP_RERUN_AICL: - rc = smblib_run_aicl(chg, RERUN_AICL); - break; - case POWER_SUPPLY_PROP_DP_DM: - if (!chg->flash_active) - rc = smblib_dp_dm(chg, val->intval); - break; - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: - rc = smblib_set_prop_input_current_limited(chg, val); - break; - case POWER_SUPPLY_PROP_DIE_HEALTH: - chg->die_health = val->intval; - power_supply_changed(chg->batt_psy); - break; - case POWER_SUPPLY_PROP_RECHARGE_SOC: - rc = smblib_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; - break; default: rc = -EINVAL; } @@ -1983,15 +1331,8 @@ static int smb5_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_INPUT_CURRENT_LIMIT: case POWER_SUPPLY_PROP_CAPACITY: - case POWER_SUPPLY_PROP_PARALLEL_DISABLE: - case POWER_SUPPLY_PROP_DP_DM: - case POWER_SUPPLY_PROP_RERUN_AICL: - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: - case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: - case POWER_SUPPLY_PROP_DIE_HEALTH: return 1; default: break; @@ -2087,7 +1428,7 @@ static int smb5_init_vconn_regulator(struct smb5 *chip) struct regulator_config cfg = {}; int rc = 0; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; chg->vconn_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vconn_vreg), @@ -2121,11 +1462,10 @@ static int smb5_init_vconn_regulator(struct smb5 *chip) ***************************/ static int smb5_configure_typec(struct smb_charger *chg) { - union power_supply_propval pval = {0, }; - int rc; - u8 val = 0; + int rc, val; + u8 value = 0; - rc = smblib_read(chg, LEGACY_CABLE_STATUS_REG, &val); + rc = smblib_read(chg, LEGACY_CABLE_STATUS_REG, &value); if (rc < 0) { dev_err(chg->dev, "Couldn't read Legacy status rc=%d\n", rc); return rc; @@ -2139,9 +1479,9 @@ static int smb5_configure_typec(struct smb_charger *chg) * is limited to PD capable designs only. Hence, for non-PD type designs * reset legacy cable detection by disabling/enabling typeC mode. */ - if (chg->pd_not_supported && (val & TYPEC_LEGACY_CABLE_STATUS_BIT)) { - pval.intval = POWER_SUPPLY_TYPEC_PR_NONE; - smblib_set_prop_typec_power_role(chg, &pval); + if (chg->pd_not_supported && (value & TYPEC_LEGACY_CABLE_STATUS_BIT)) { + val = QTI_POWER_SUPPLY_TYPEC_PR_NONE; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { dev_err(chg->dev, "Couldn't disable TYPEC rc=%d\n", rc); return rc; @@ -2150,8 +1490,8 @@ static int smb5_configure_typec(struct smb_charger *chg) /* delay before enabling typeC */ msleep(50); - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_DUAL; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { dev_err(chg->dev, "Couldn't enable TYPEC rc=%d\n", rc); return rc; @@ -2177,10 +1517,10 @@ static int smb5_configure_typec(struct smb_charger *chg) return rc; } - val = chg->lpd_disabled ? 0 : TYPEC_WATER_DETECTION_INT_EN_BIT; + value = chg->lpd_disabled ? 0 : TYPEC_WATER_DETECTION_INT_EN_BIT; /* Use simple write to enable only required interrupts */ rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG, - TYPEC_SRC_BATT_HPWR_INT_EN_BIT | val); + TYPEC_SRC_BATT_HPWR_INT_EN_BIT | value); if (rc < 0) { dev_err(chg->dev, "Couldn't configure Type-C interrupts rc=%d\n", rc); @@ -2211,7 +1551,7 @@ static int smb5_configure_typec(struct smb_charger *chg) } } - if (chg->chg_param.smb_version != PMI632_SUBTYPE) { + if (chg->chg_param.smb_version != PMI632) { /* * Enable detection of unoriented debug * accessory in source mode. @@ -2287,7 +1627,7 @@ static int smb5_configure_micro_usb(struct smb_charger *chg) /* Disable periodic monitoring of CC_ID pin */ rc = smblib_write(chg, - ((chg->chg_param.smb_version == PMI632_SUBTYPE) ? + ((chg->chg_param.smb_version == PMI632) ? PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG : TYPEC_U_USB_WATER_PROTECTION_CFG_REG), 0); if (rc < 0) { @@ -2313,7 +1653,7 @@ static int smb5_configure_iterm_thresholds_adc(struct smb5 *chip) s16 raw_hi_thresh, raw_lo_thresh, max_limit_ma; struct smb_charger *chg = &chip->chg; - if (chip->chg.chg_param.smb_version == PMI632_SUBTYPE) + if (chip->chg.chg_param.smb_version == PMI632) max_limit_ma = ITERM_LIMITS_PMI632_MA; else max_limit_ma = ITERM_LIMITS_PM8150B_MA; @@ -2374,7 +1714,7 @@ static int smb5_configure_iterm_thresholds(struct smb5 *chip) switch (chip->dt.term_current_src) { case ITERM_SRC_ADC: - if (chip->chg.chg_param.smb_version == PM8150B_SUBTYPE) { + if (chip->chg.chg_param.smb_version == PM8150B) { rc = smblib_masked_write(chg, CHGR_ADC_TERM_CFG_REG, TERM_BASED_ON_SYNC_CONV_OR_SAMPLE_CNT, TERM_BASED_ON_SAMPLE_CNT); @@ -2446,7 +1786,7 @@ static int smb5_init_dc_peripheral(struct smb_charger *chg) int rc = 0; /* PMI632 does not have DC peripheral */ - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) return 0; /* Set DCIN ICL to 100 mA */ @@ -2472,7 +1812,7 @@ static int smb5_configure_recharging(struct smb5 *chip) { int rc = 0; struct smb_charger *chg = &chip->chg; - union power_supply_propval pval; + int val; /* Configure VBATT-based or automatic recharging */ rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK, @@ -2518,8 +1858,8 @@ static int smb5_configure_recharging(struct smb5 *chip) /* program the auto-recharge threshold */ if (chip->dt.auto_recharge_soc != -EINVAL) { - pval.intval = chip->dt.auto_recharge_soc; - rc = smblib_set_prop_rechg_soc_thresh(chg, &pval); + val = chip->dt.auto_recharge_soc; + rc = smblib_set_prop_rechg_soc_thresh(chg, val); if (rc < 0) { dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n", rc); @@ -2584,7 +1924,7 @@ static int smb5_init_connector_type(struct smb_charger *chg) * PMI632 can have the connector type defined by a dedicated register * PMI632_TYPEC_MICRO_USB_MODE_REG or by a common TYPEC_U_USB_CFG_REG. */ - if (chg->chg_param.smb_version == PMI632_SUBTYPE) { + if (chg->chg_param.smb_version == PMI632) { rc = smblib_read(chg, PMI632_TYPEC_MICRO_USB_MODE_REG, &val); if (rc < 0) { dev_err(chg->dev, "Couldn't read USB mode rc=%d\n", rc); @@ -2611,10 +1951,10 @@ static int smb5_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; rc = smb5_configure_micro_usb(chg); } else { - chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC; + chg->connector_type = QTI_POWER_SUPPLY_CONNECTOR_TYPEC; rc = smb5_configure_typec(chg); } if (rc < 0) { @@ -2629,7 +1969,7 @@ static int smb5_init_connector_type(struct smb_charger *chg) * boots with charger connected. * - Initialize flash module for PMI632 */ - if (chg->chg_param.smb_version == PMI632_SUBTYPE) { + if (chg->chg_param.smb_version == PMI632) { schgm_flash_init(chg); smblib_rerun_apsd_if_required(chg); } @@ -2937,8 +2277,7 @@ static int smb5_init_hw(struct smb5 *chip) static int smb5_post_init(struct smb5 *chip) { struct smb_charger *chg = &chip->chg; - union power_supply_propval pval; - int rc; + int rc, val; /* * In case the usb path is suspended, we would have missed disabling @@ -2948,8 +2287,8 @@ static int smb5_post_init(struct smb5 *chip) rerun_election(chg->usb_icl_votable); /* configure power role for dual-role */ - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - rc = smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_DUAL; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { dev_err(chg->dev, "Couldn't configure DRP role rc=%d\n", rc); @@ -2979,7 +2318,7 @@ static int smb5_determine_initial_status(struct smb5 *chip) } chg->early_usb_attach = val.intval; - if (chg->bms_psy) + if (chg->iio_chan_list_qg) smblib_suspend_on_debug_battery(chg); usb_plugin_irq_handler(0, &irq_data); @@ -3500,7 +2839,6 @@ static int smb5_init_typec_class(struct smb5 *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 = smblib_typec_port_type_set; chg->typec_caps.revision = 0x0130; chg->typec_port = typec_register_port(chg->dev, &chg->typec_caps); @@ -3513,17 +2851,162 @@ static int smb5_init_typec_class(struct smb5 *chip) return rc; } +static int smb5_of_xlate(struct iio_dev *indio_dev, + const struct of_phandle_args *iiospec) +{ + struct smb5 *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 smb5_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, + long mask) +{ + struct smb5 *iio_chip = iio_priv(indio_dev); + struct smb_charger *chg = &iio_chip->chg; + + return smb5_iio_get_prop(chg, chan->channel, val); +} + +static int smb5_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long mask) +{ + struct smb5 *iio_chip = iio_priv(indio_dev); + struct smb_charger *chg = &iio_chip->chg; + + return smb5_iio_set_prop(chg, chan->channel, val); +} + +static const struct iio_info smb5_iio_info = { + .read_raw = smb5_read_raw, + .write_raw = smb5_write_raw, + .of_xlate = smb5_of_xlate, +}; + +static int smb5_direct_iio_read(struct device *dev, int iio_chan_no, int *val) +{ + struct smb5 *chip = dev_get_drvdata(dev); + struct smb_charger *chg = &chip->chg; + int rc; + + rc = smb5_iio_get_prop(chg, iio_chan_no, val); + + return (rc < 0) ? rc : 0; +} + +static int smb5_direct_iio_write(struct device *dev, int iio_chan_no, int val) +{ + struct smb5 *chip = dev_get_drvdata(dev); + struct smb_charger *chg = &chip->chg; + + return smb5_iio_set_prop(chg, iio_chan_no, val); +} + +static int smb5_iio_init(struct smb5 *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 = pdev->name; + 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) + pr_err("iio device register failed rc=%d\n", rc); + + return rc; +} + +int smb5_extcon_init(struct smb_charger *chg) +{ + int rc; + + /* extcon registration */ + chg->extcon = devm_extcon_dev_allocate(chg->dev, smblib_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 smb5_probe(struct platform_device *pdev) { struct smb5 *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 = &smb5_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->pd_disabled = 0; @@ -3542,6 +3025,10 @@ static int smb5_probe(struct platform_device *pdev) return -EINVAL; } + rc = smb5_iio_init(chip, pdev, indio_dev); + if (rc < 0) + return rc; + rc = smb5_chg_config_init(chip); if (rc < 0) { if (rc != -EPROBE_DEFER) @@ -3561,45 +3048,21 @@ static int smb5_probe(struct platform_device *pdev) else return -EPROBE_DEFER; + /* set driver data before resources request it */ + platform_set_drvdata(pdev, chip); + + chg->chg_param.iio_read = smb5_direct_iio_read; + chg->chg_param.iio_write = smb5_direct_iio_write; + rc = smblib_init(chg); if (rc < 0) { pr_err("Smblib_init failed rc=%d\n", rc); return rc; } - /* set driver data before resources request it */ - platform_set_drvdata(pdev, chip); - - /* extcon registration */ - chg->extcon = devm_extcon_dev_allocate(chg->dev, smblib_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); + rc = smb5_extcon_init(chg); + if (rc < 0) goto cleanup; - } - - 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); - 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, - "failed to configure extcon capabilities\n"); - goto cleanup; - } rc = smb5_init_hw(chip); if (rc < 0) { @@ -3632,9 +3095,9 @@ static int smb5_probe(struct platform_device *pdev) } switch (chg->chg_param.smb_version) { - case PM8150B_SUBTYPE: - case PM6150_SUBTYPE: - case PM7250B_SUBTYPE: + case PM8150B: + case PM6150: + case PM7250B: rc = smb5_init_dc_psy(chip); if (rc < 0) { pr_err("Couldn't initialize dc psy rc=%d\n", rc); @@ -3651,12 +3114,6 @@ static int smb5_probe(struct platform_device *pdev) goto cleanup; } - rc = smb5_init_usb_main_psy(chip); - if (rc < 0) { - pr_err("Couldn't initialize usb main psy rc=%d\n", rc); - goto cleanup; - } - rc = smb5_init_usb_port_psy(chip); if (rc < 0) { pr_err("Couldn't initialize usb pc_port psy rc=%d\n", rc); @@ -3752,7 +3209,7 @@ static void smb5_shutdown(struct platform_device *pdev) smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, 0); /* configure power role for UFP */ - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_POWER_ROLE_CMD_MASK, EN_SNK_ONLY_BIT); @@ -3762,7 +3219,22 @@ static void smb5_shutdown(struct platform_device *pdev) } static const struct of_device_id match_table[] = { - { .compatible = "qcom,qpnp-smb5", }, + { + .compatible = "qcom,pm8150-smb5", + .data = (void *)PM8150B, + }, + { + .compatible = "qcom,pm7250b-smb5", + .data = (void *)PM7250B, + }, + { + .compatible = "qcom,pm6150-smb5", + .data = (void *)PM6150, + }, + { + .compatible = "qcom,pmi632-smb5", + .data = (void *)PMI632, + }, { }, }; diff --git a/drivers/power/supply/qcom/smb5-iio.c b/drivers/power/supply/qcom/smb5-iio.c new file mode 100644 index 000000000000..9b432c268aba --- /dev/null +++ b/drivers/power/supply/qcom/smb5-iio.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include "smb5-lib.h" +#include "smb5-iio.h" +#include "smb5-reg.h" +#include "schgm-flash.h" + +#define MIN_THERMAL_VOTE_UA 500000 + +int smb5_iio_get_prop(struct smb_charger *chg, int channel, int *val) +{ + union power_supply_propval pval = {0, }; + int rc = 0; + u8 reg = 0, buff[2] = {0}; + + pval.intval = 0; + *val = 0; + + switch (channel) { + /* USB */ + case PSY_IIO_VOLTAGE_MAX_LIMIT: + if (chg->usbin_forced_max_uv) + *val = chg->usbin_forced_max_uv; + else + rc = smblib_get_prop_usb_voltage_max_design(chg, &pval); + *val = pval.intval; + break; + case PSY_IIO_PD_CURRENT_MAX: + *val = get_client_vote(chg->usb_icl_votable, PD_VOTER); + break; + case PSY_IIO_USB_REAL_TYPE: + *val = chg->real_charger_type; + break; + case PSY_IIO_TYPEC_MODE: + rc = smblib_get_usb_prop_typec_mode(chg, val); + break; + case PSY_IIO_TYPEC_POWER_ROLE: + rc = smblib_get_prop_typec_power_role(chg, val); + break; + case PSY_IIO_TYPEC_CC_ORIENTATION: + rc = smblib_get_prop_typec_cc_orientation(chg, val); + break; + case PSY_IIO_TYPEC_SRC_RP: + rc = smblib_get_prop_typec_select_rp(chg, val); + break; + case PSY_IIO_PD_ACTIVE: + *val = chg->pd_active; + break; + case PSY_IIO_USB_INPUT_CURRENT_SETTLED: + rc = smblib_get_prop_input_current_settled(chg, &pval); + if (!rc) + *val = pval.intval; + break; + case PSY_IIO_PD_IN_HARD_RESET: + rc = smblib_get_prop_pd_in_hard_reset(chg, val); + break; + case PSY_IIO_PD_USB_SUSPEND_SUPPORTED: + *val = chg->system_suspend_supported; + break; + case PSY_IIO_PE_START: + rc = smblib_get_pe_start(chg, val); + break; + case PSY_IIO_CTM_CURRENT_MAX: + *val = get_client_vote(chg->usb_icl_votable, CTM_VOTER); + break; + case PSY_IIO_HW_CURRENT_MAX: + rc = smblib_get_charge_current(chg, val); + break; + case PSY_IIO_PR_SWAP: + rc = smblib_get_prop_pr_swap_in_progress(chg, val); + break; + case PSY_IIO_PD_VOLTAGE_MAX: + *val = chg->voltage_max_uv; + break; + case PSY_IIO_PD_VOLTAGE_MIN: + *val = chg->voltage_min_uv; + break; + case PSY_IIO_CONNECTOR_TYPE: + *val = chg->connector_type; + break; + case PSY_IIO_CONNECTOR_HEALTH: + *val = smblib_get_prop_connector_health(chg); + break; + case PSY_IIO_SMB_EN_MODE: + mutex_lock(&chg->smb_lock); + *val = chg->sec_chg_selected; + mutex_unlock(&chg->smb_lock); + break; + case PSY_IIO_SMB_EN_REASON: + *val = chg->cp_reason; + break; + case PSY_IIO_MOISTURE_DETECTED: + *val = chg->moisture_present; + break; + case PSY_IIO_HVDCP_OPTI_ALLOWED: + *val = !chg->flash_active; + break; + case PSY_IIO_QC_OPTI_DISABLE: + if (chg->hw_die_temp_mitigation) + *val = QC_THERMAL_BALANCE_DISABLE + | QC_INOV_THERMAL_DISABLE; + if (chg->hw_connector_mitigation) + *val |= QC_CTM_DISABLE; + break; + case PSY_IIO_VOLTAGE_VPH: + rc = smblib_get_prop_vph_voltage_now(chg, val); + break; + case PSY_IIO_THERM_ICL_LIMIT: + *val = get_client_vote(chg->usb_icl_votable, + THERMAL_THROTTLE_VOTER); + break; + case PSY_IIO_ADAPTER_CC_MODE: + *val = chg->adapter_cc_mode; + break; + case PSY_IIO_SKIN_HEALTH: + *val = smblib_get_skin_temp_status(chg); + break; + case PSY_IIO_APSD_RERUN: + *val = 0; + break; + case PSY_IIO_APSD_TIMEOUT: + *val = chg->apsd_ext_timeout; + break; + case PSY_IIO_CHARGER_STATUS: + *val = 0; + if (chg->sdam_base) { + rc = smblib_read(chg, + chg->sdam_base + SDAM_QC_DET_STATUS_REG, ®); + if (!rc) + *val = reg; + } + break; + case PSY_IIO_USB_INPUT_VOLTAGE_SETTLED: + *val = 0; + if (chg->sdam_base) { + rc = smblib_batch_read(chg, + chg->sdam_base + SDAM_QC_ADC_LSB_REG, buff, 2); + if (!rc) + *val = (buff[1] << 8 | buff[0]) * 1038; + } + break; + /* MAIN */ + case PSY_IIO_MAIN_INPUT_CURRENT_SETTLED: + rc = smblib_get_prop_input_current_settled(chg, &pval); + if (!rc) + *val = pval.intval; + break; + case PSY_IIO_MAIN_INPUT_VOLTAGE_SETTLED: + rc = smblib_get_prop_input_voltage_settled(chg, val); + break; + case PSY_IIO_FCC_DELTA: + rc = smblib_get_prop_fcc_delta(chg, val); + break; + case PSY_IIO_FLASH_ACTIVE: + *val = chg->flash_active; + break; + case PSY_IIO_FLASH_TRIGGER: + *val = 0; + if (chg->chg_param.smb_version == PMI632) + rc = schgm_flash_get_vreg_ok(chg, val); + break; + case PSY_IIO_TOGGLE_STAT: + *val = 0; + break; + case PSY_IIO_MAIN_FCC_MAX: + *val = chg->main_fcc_max; + break; + case PSY_IIO_IRQ_STATUS: + rc = smblib_get_irq_status(chg, val); + break; + case PSY_IIO_FORCE_MAIN_FCC: + rc = smblib_get_charge_param(chg, &chg->param.fcc, + val); + break; + case PSY_IIO_FORCE_MAIN_ICL: + rc = smblib_get_charge_param(chg, &chg->param.usb_icl, + val); + break; + case PSY_IIO_COMP_CLAMP_LEVEL: + *val = chg->comp_clamp_level; + break; + /* Use this property to report overheat status */ + case PSY_IIO_HOT_TEMP: + *val = chg->thermal_overheat; + break; + case PSY_IIO_VOLTAGE_MAX: + rc = smblib_get_charge_param(chg, &chg->param.fv, val); + break; + case PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX: + rc = smblib_get_charge_param(chg, &chg->param.fcc, + val); + break; + case PSY_IIO_CURRENT_MAX: + rc = smblib_get_icl_current(chg, val); + break; + case PSY_IIO_HEALTH: + rc = *val = smblib_get_prop_smb_health(chg); + break; + /* DC */ + case PSY_IIO_DC_REAL_TYPE: + *val = POWER_SUPPLY_TYPE_MAINS; + break; + case PSY_IIO_INPUT_VOLTAGE_REGULATION: + rc = smblib_get_prop_voltage_wls_output(chg, &pval); + if (!rc) + *val = pval.intval; + break; + case PSY_IIO_DC_RESET: + *val = 0; + break; + case PSY_IIO_AICL_DONE: + *val = chg->dcin_aicl_done; + break; + /* BATTERY */ + case PSY_IIO_CHARGER_TEMP: + rc = smblib_get_prop_charger_temp(chg, val); + break; + case PSY_IIO_CHARGER_TEMP_MAX: + *val = chg->charger_temp_max; + break; + case PSY_IIO_SW_JEITA_ENABLED: + *val = chg->sw_jeita_enabled; + break; + case PSY_IIO_PARALLEL_DISABLE: + *val = get_client_vote(chg->pl_disable_votable, + USER_VOTER); + break; + case PSY_IIO_CHARGE_DONE: + rc = smblib_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_RERUN_AICL: + *val = 0; + break; + case PSY_IIO_DP_DM: + *val = chg->pulse_cnt; + break; + case PSY_IIO_INPUT_CURRENT_LIMITED: + rc = smblib_get_prop_input_current_limited(chg, val); + break; + case PSY_IIO_DIE_HEALTH: + rc = smblib_get_die_health(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; + default: + pr_err("get prop %d is not supported\n", channel); + rc = -EINVAL; + break; + } + + if (rc < 0) { + pr_err("Couldn't get prop %d rc = %d\n", channel, rc); + return rc; + } + + return IIO_VAL_INT; +} + +int smb5_iio_set_prop(struct smb_charger *chg, int channel, int val) +{ + union power_supply_propval pval = {0, }; + int real_chg_type = chg->real_charger_type; + int icl, rc = 0, offset_ua = 0; + + switch (channel) { + /* USB */ + case PSY_IIO_PD_CURRENT_MAX: + rc = smblib_set_prop_pd_current_max(chg, val); + break; + case PSY_IIO_TYPEC_POWER_ROLE: + rc = smblib_set_prop_typec_power_role(chg, val); + break; + case PSY_IIO_TYPEC_SRC_RP: + rc = smblib_set_prop_typec_select_rp(chg, val); + break; + case PSY_IIO_PD_ACTIVE: + rc = smblib_set_prop_pd_active(chg, val); + break; + case PSY_IIO_PD_IN_HARD_RESET: + rc = smblib_set_prop_pd_in_hard_reset(chg, val); + break; + case PSY_IIO_PD_USB_SUSPEND_SUPPORTED: + chg->system_suspend_supported = val; + break; + case PSY_IIO_CTM_CURRENT_MAX: + rc = vote(chg->usb_icl_votable, CTM_VOTER, + val >= 0, val); + break; + case PSY_IIO_PR_SWAP: + rc = smblib_set_prop_pr_swap_in_progress(chg, val); + break; + case PSY_IIO_PD_VOLTAGE_MAX: + rc = smblib_set_prop_pd_voltage_max(chg, val); + break; + case PSY_IIO_PD_VOLTAGE_MIN: + rc = smblib_set_prop_pd_voltage_min(chg, val); + break; + case PSY_IIO_CONNECTOR_HEALTH: + chg->connector_health = val; + if (chg->usb_psy) + power_supply_changed(chg->usb_psy); + break; + case PSY_IIO_THERM_ICL_LIMIT: + if (!is_client_vote_enabled(chg->usb_icl_votable, + THERMAL_THROTTLE_VOTER)) { + chg->init_thermal_ua = get_effective_result( + chg->usb_icl_votable); + icl = chg->init_thermal_ua + val; + } else { + icl = get_client_vote(chg->usb_icl_votable, + THERMAL_THROTTLE_VOTER) + val; + } + + if (icl >= MIN_THERMAL_VOTE_UA) + rc = vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER, + (icl != chg->init_thermal_ua), icl); + else + rc = -EINVAL; + break; + case PSY_IIO_VOLTAGE_MAX_LIMIT: + smblib_set_prop_usb_voltage_max_limit(chg, val); + break; + case PSY_IIO_ADAPTER_CC_MODE: + chg->adapter_cc_mode = val; + break; + case PSY_IIO_APSD_RERUN: + del_timer_sync(&chg->apsd_timer); + chg->apsd_ext_timeout = false; + smblib_rerun_apsd(chg); + break; + /* MAIN */ + case PSY_IIO_FLASH_ACTIVE: + if ((chg->chg_param.smb_version == PMI632) + && (chg->flash_active != val)) { + chg->flash_active = val; + + rc = smblib_get_prop_usb_present(chg, &pval); + if (rc < 0) + pr_err("Failed to get USB preset status rc=%d\n", + rc); + if (pval.intval) { + rc = smblib_force_vbus_voltage(chg, + chg->flash_active ? FORCE_5V_BIT + : IDLE_BIT); + if (rc < 0) + pr_err("Failed to force 5V\n"); + else + chg->pulse_cnt = 0; + } else { + /* USB absent & flash not-active - vote 100mA */ + vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, + true, SDP_100_MA); + } + + pr_debug("flash active VBUS 5V restriction %s\n", + chg->flash_active ? "applied" : "removed"); + + /* Update userspace */ + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); + } + break; + case PSY_IIO_TOGGLE_STAT: + rc = smblib_toggle_smb_en(chg, val); + break; + case PSY_IIO_MAIN_FCC_MAX: + chg->main_fcc_max = val; + rerun_election(chg->fcc_votable); + break; + case PSY_IIO_FORCE_MAIN_FCC: + vote_override(chg->fcc_main_votable, CC_MODE_VOTER, + (val < 0) ? false : true, val); + if (val >= 0) + chg->chg_param.forced_main_fcc = val; + /* + * Remove low vote on FCC_MAIN, for WLS, to allow FCC_MAIN to + * rise to its full value. + */ + if (val < 0) + vote(chg->fcc_main_votable, WLS_PL_CHARGING_VOTER, + false, 0); + /* Main FCC updated re-calculate FCC */ + rerun_election(chg->fcc_votable); + break; + case PSY_IIO_FORCE_MAIN_ICL: + vote_override(chg->usb_icl_votable, CC_MODE_VOTER, + (val < 0) ? false : true, val); + /* Main ICL updated re-calculate ILIM */ + if (real_chg_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3 || + real_chg_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5) + rerun_election(chg->fcc_votable); + break; + case PSY_IIO_COMP_CLAMP_LEVEL: + rc = smb5_set_prop_comp_clamp_level(chg, val); + break; + case PSY_IIO_HOT_TEMP: + rc = smblib_set_prop_thermal_overheat(chg, val); + break; + case PSY_IIO_VOLTAGE_MAX: + rc = smblib_set_charge_param(chg, &chg->param.fv, val); + break; + case PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX: + /* Adjust Main FCC for QC3.0 + SMB1390 */ + rc = smblib_get_qc3_main_icl_offset(chg, &offset_ua); + if (rc < 0) + offset_ua = 0; + + rc = smblib_set_charge_param(chg, &chg->param.fcc, + val + offset_ua); + break; + case PSY_IIO_CURRENT_MAX: + rc = smblib_set_icl_current(chg, val); + break; + /* DC */ + case PSY_IIO_INPUT_VOLTAGE_REGULATION: + pval.intval = val; + rc = smblib_set_prop_voltage_wls_output(chg, &pval); + break; + case PSY_IIO_DC_RESET: + rc = smblib_set_prop_dc_reset(chg); + break; + /* BATTERY */ + case PSY_IIO_PARALLEL_DISABLE: + vote(chg->pl_disable_votable, USER_VOTER, (bool)val, 0); + break; + 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 = smblib_set_prop_ship_mode(chg, val); + break; + case PSY_IIO_RERUN_AICL: + rc = smblib_run_aicl(chg, RERUN_AICL); + break; + case PSY_IIO_DP_DM: + if (!chg->flash_active) + rc = smblib_dp_dm(chg, val); + break; + case PSY_IIO_INPUT_CURRENT_LIMITED: + rc = smblib_set_prop_input_current_limited(chg, val); + break; + case PSY_IIO_DIE_HEALTH: + chg->die_health = val; + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); + break; + case PSY_IIO_RECHARGE_SOC: + rc = smblib_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; + 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/smb5-iio.h b/drivers/power/supply/qcom/smb5-iio.h new file mode 100644 index 000000000000..f90ec67d11fd --- /dev/null +++ b/drivers/power/supply/qcom/smb5-iio.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef __SMB5_IIO_H +#define __SMB5_IIO_H + +#include +#include + +enum iio_type { + MAIN, + QG, + CP, + SMB_PARALLEL, +}; + +/* For qpnp-smb5.c and smb5-lib.c */ +enum qg_chg_iio_channels { + SMB5_QG_DEBUG_BATTERY, + SMB5_QG_CAPACITY, + SMB5_QG_REAL_CAPACITY, + SMB5_QG_CC_SOC, + SMB5_QG_CURRENT_NOW, + SMB5_QG_VOLTAGE_NOW, + SMB5_QG_VOLTAGE_MAX, + SMB5_QG_CHARGE_FULL, + SMB5_QG_RESISTANCE_ID, + SMB5_QG_TEMP, + SMB5_QG_CHARGE_COUNTER, + SMB5_QG_CYCLE_COUNT, + SMB5_QG_CHARGE_FULL_DESIGN, + SMB5_QG_TIME_TO_FULL_NOW, +}; + +enum cp_iio_channels { + CP_PARALLEL_OUTPUT_MODE, + CP_MASTER_ENABLE, + CP_ILIM, + CP_DIE_TEMP, +}; + +/* For smb5-lib.c and smb5-iio.c */ +enum smb_parallel_iio_channels { + SMB_CHARGER_TEMP, + SMB_CHARGER_TEMP_MAX, + SMB_SET_SHIP_MODE, +}; + +/* For step-chg-jeita.c */ +enum step_chg_iio_channels { + STEP_QG_RESISTANCE_ID = 0, + STEP_QG_VOLTAGE_NOW, + STEP_QG_TEMP, + STEP_QG_CAPACITY, + STEP_QG_VOLTAGE_OCV, + STEP_QG_VOLTAGE_AVG, +}; + +/* For battery.c */ +enum bat_cp_iio_channels { + BAT_CP_PARALLEL_MODE, + BAT_CP_PARALLEL_OUTPUT_MODE, + BAT_CP_MIN_ICL, + BAT_CP_SWITCHER_EN, +}; + +enum bat_smb_parallel_iio_channels { + BAT_SMB_PARALLEL_INPUT_SUSPEND, + BAT_SMB_PARALLEL_MODE, + BAT_SMB_PARALLEL_BATFET_MODE, + BAT_SMB_PARALLEL_MIN_ICL, + BAT_SMB_PARALLEL_FCC_MAX, + BAT_SMB_PARALLEL_CURRENT_MAX, + BAT_SMB_PARALLEL_CONSTANT_CHARGE_CURRENT_MAX, + BAT_SMB_PARALLEL_VOLTAGE_MAX, + BAT_SMB_PARALLEL_CHARGE_TYPE, +}; + +struct smb5_iio_prop_channels { + const char *datasheet_name; + int channel_num; + enum iio_chan_type type; + long info_mask; +}; + +#define PARAM(chan) PSY_IIO_##chan + +#define SMB5_CHAN(_dname, _chan, _type, _mask) \ + { \ + .datasheet_name = _dname, \ + .channel_num = _chan, \ + .type = _type, \ + .info_mask = _mask, \ + }, \ + +#define SMB5_CHAN_VOLT(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_VOLTAGE, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_CUR(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_CURRENT, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_RES(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_RESISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_TEMP(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_POWER(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_POWER, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_CAP(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_CAPACITANCE, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_COUNT(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_COUNT, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_INDEX(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_INDEX, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +#define SMB5_CHAN_ACTIVITY(_dname, chan) \ + [PARAM(chan)] = SMB5_CHAN(_dname, PARAM(chan), \ + IIO_ACTIVITY, BIT(IIO_CHAN_INFO_PROCESSED)) \ + +static const struct smb5_iio_prop_channels smb5_chans_pmic[] = { + SMB5_CHAN_CUR("usb_pd_current_max", PD_CURRENT_MAX) + SMB5_CHAN_INDEX("usb_typec_mode", TYPEC_MODE) + SMB5_CHAN_INDEX("usb_typec_power_role", TYPEC_POWER_ROLE) + SMB5_CHAN_INDEX("usb_typec_cc_orientation", TYPEC_CC_ORIENTATION) + SMB5_CHAN_INDEX("usb_pd_active", PD_ACTIVE) + SMB5_CHAN_CUR("usb_input_current_settled", USB_INPUT_CURRENT_SETTLED) + SMB5_CHAN_ACTIVITY("usb_pe_start", PE_START) + SMB5_CHAN_CUR("usb_ctm_current_max", CTM_CURRENT_MAX) + SMB5_CHAN_CUR("usb_hw_current_max", HW_CURRENT_MAX) + SMB5_CHAN_INDEX("usb_real_type", USB_REAL_TYPE) + SMB5_CHAN_VOLT("usb_pd_voltage_max", PD_VOLTAGE_MAX) + SMB5_CHAN_VOLT("usb_pd_voltage_min", PD_VOLTAGE_MIN) + SMB5_CHAN_INDEX("usb_connector_type", CONNECTOR_TYPE) + SMB5_CHAN_INDEX("usb_connector_health", CONNECTOR_HEALTH) + SMB5_CHAN_VOLT("usb_voltage_max_limit", VOLTAGE_MAX_LIMIT) + SMB5_CHAN_INDEX("usb_smb_en_mode", SMB_EN_MODE) + SMB5_CHAN_INDEX("usb_smb_en_reason", SMB_EN_REASON) + SMB5_CHAN_INDEX("usb_adapter_cc_mode", ADAPTER_CC_MODE) + SMB5_CHAN_INDEX("usb_moisture_detected", MOISTURE_DETECTED) + SMB5_CHAN_INDEX("usb_hvdcp_opti_allowed", HVDCP_OPTI_ALLOWED) + SMB5_CHAN_ACTIVITY("usb_qc_opti_disable", QC_OPTI_DISABLE) + SMB5_CHAN_VOLT("usb_voltage_vph", VOLTAGE_VPH) + SMB5_CHAN_CUR("usb_therm_icl_limit", THERM_ICL_LIMIT) + SMB5_CHAN_INDEX("usb_skin_health", SKIN_HEALTH) + SMB5_CHAN_ACTIVITY("usb_apsd_rerun", APSD_RERUN) + SMB5_CHAN_COUNT("usb_apsd_timeout", APSD_TIMEOUT) + SMB5_CHAN_INDEX("usb_charger_status", CHARGER_STATUS) + SMB5_CHAN_VOLT("usb_input_voltage_settled", USB_INPUT_VOLTAGE_SETTLED) + SMB5_CHAN_ACTIVITY("usb_typec_src_rp", TYPEC_SRC_RP) + SMB5_CHAN_ACTIVITY("usb_pd_in_hard_reset", PD_IN_HARD_RESET) + SMB5_CHAN_INDEX("usb_pd_usb_suspend_supported", + PD_USB_SUSPEND_SUPPORTED) + SMB5_CHAN_ACTIVITY("usb_pr_swap", PR_SWAP) + SMB5_CHAN_CUR("main_input_current_settled", MAIN_INPUT_CURRENT_SETTLED) + SMB5_CHAN_VOLT("main_input_voltage_settled", MAIN_INPUT_VOLTAGE_SETTLED) + SMB5_CHAN_CUR("main_fcc_delta", FCC_DELTA) + SMB5_CHAN_ACTIVITY("main_flash_active", FLASH_ACTIVE) + SMB5_CHAN_ACTIVITY("main_flash_trigger", FLASH_TRIGGER) + SMB5_CHAN_ACTIVITY("main_toggle_stat", TOGGLE_STAT) + SMB5_CHAN_CUR("main_fcc_max", MAIN_FCC_MAX) + SMB5_CHAN_INDEX("main_irq_status", IRQ_STATUS) + SMB5_CHAN_ACTIVITY("main_force_main_fcc", FORCE_MAIN_FCC) + SMB5_CHAN_ACTIVITY("main_force_main_icl", FORCE_MAIN_ICL) + SMB5_CHAN_INDEX("main_comp_clamp_level", COMP_CLAMP_LEVEL) + SMB5_CHAN_TEMP("main_temp_hot", HOT_TEMP) + SMB5_CHAN_VOLT("main_voltage_max", VOLTAGE_MAX) + SMB5_CHAN_CUR("main_constant_charge_current_max", + CONSTANT_CHARGE_CURRENT_MAX) + SMB5_CHAN_CUR("main_current_max", CURRENT_MAX) + SMB5_CHAN_INDEX("main_health", HEALTH) + SMB5_CHAN_VOLT("dc_input_voltage_regulation", INPUT_VOLTAGE_REGULATION) + SMB5_CHAN_INDEX("dc_real_type", DC_REAL_TYPE) + SMB5_CHAN_ACTIVITY("dc_reset", DC_RESET) + SMB5_CHAN_ACTIVITY("dc_aicl_done", AICL_DONE) + SMB5_CHAN_TEMP("battery_charger_temp", CHARGER_TEMP) + SMB5_CHAN_TEMP("battery_charger_temp_max", CHARGER_TEMP_MAX) + SMB5_CHAN_CUR("battery_input_current_limited", INPUT_CURRENT_LIMITED) + SMB5_CHAN_ACTIVITY("battery_sw_jeita_enabled", SW_JEITA_ENABLED) + SMB5_CHAN_ACTIVITY("battery_charge_done", CHARGE_DONE) + SMB5_CHAN_ACTIVITY("battery_parallel_disable", PARALLEL_DISABLE) + SMB5_CHAN_ACTIVITY("battery_set_ship_mode", SET_SHIP_MODE) + SMB5_CHAN_INDEX("battery_die_health", DIE_HEALTH) + SMB5_CHAN_ACTIVITY("battery_rerun_aicl", RERUN_AICL) + SMB5_CHAN_COUNT("battery_dp_dm", DP_DM) + SMB5_CHAN_ACTIVITY("battery_recharge_soc", RECHARGE_SOC) + SMB5_CHAN_ACTIVITY("battery_force_recharge", FORCE_RECHARGE) + SMB5_CHAN_ACTIVITY("battery_fcc_stepper_enable", FCC_STEPPER_ENABLE) +}; + +struct iio_channel **get_ext_channels(struct device *dev, + const char *const *channel_map, int size); +#endif diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index ec6f92822020..bfbe04eab916 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -8,9 +8,9 @@ #include #include #include -#include #include #include +#include #include #include #include "smb5-lib.h" @@ -18,6 +18,7 @@ #include "schgm-flash.h" #include "step-chg-jeita.h" #include "storm-watch.h" +#include "smb5-iio.h" #include "battery-profile-loader.h" #define smblib_err(chg, fmt, ...) \ @@ -35,11 +36,11 @@ } 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, int pst); +static void update_sw_icl_max(struct smb_charger *chg, int val); static int smblib_get_prop_typec_mode(struct smb_charger *chg); int smblib_read(struct smb_charger *chg, u16 addr, u8 *val) @@ -101,8 +102,8 @@ int smblib_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 smblib_read_iio_channel(struct smb_charger *chg, struct iio_channel *chan, - int div, int *data) +static int smblib_read_iio_channel(struct smb_charger *chg, + struct iio_channel *chan, int div, int *data) { int rc = 0; *data = -ENODATA; @@ -122,7 +123,7 @@ int smblib_read_iio_channel(struct smb_charger *chg, struct iio_channel *chan, return rc; } -int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) +static int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) { int rc, cc_minus_ua; u8 stat; @@ -218,7 +219,7 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, int rc = 0; switch (sec_chg) { - case POWER_SUPPLY_CHARGER_SEC_CP: + case QTI_POWER_SUPPLY_CHARGER_SEC_CP: vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, true, 0); /* select Charge Pump instead of slave charger */ @@ -239,7 +240,7 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, } vote(chg->smb_override_votable, PL_SMB_EN_VOTER, false, 0); break; - case POWER_SUPPLY_CHARGER_SEC_PL: + case QTI_POWER_SUPPLY_CHARGER_SEC_PL: /* select slave charger instead of Charge Pump */ rc = smblib_masked_write(chg, MISC_SMB_CFG_REG, SMB_EN_SEL_BIT, 0); @@ -261,7 +262,7 @@ static int smblib_select_sec_charger_locked(struct smb_charger *chg, vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, false, 0); break; - case POWER_SUPPLY_CHARGER_SEC_NONE: + case QTI_POWER_SUPPLY_CHARGER_SEC_NONE: default: vote(chg->pl_disable_votable, PL_SMB_EN_VOTER, true, 0); @@ -280,9 +281,9 @@ static int smblib_select_sec_charger(struct smb_charger *chg, int sec_chg, mutex_lock(&chg->smb_lock); - if (toggle && sec_chg == POWER_SUPPLY_CHARGER_SEC_CP) { + if (toggle && sec_chg == QTI_POWER_SUPPLY_CHARGER_SEC_CP) { rc = smblib_select_sec_charger_locked(chg, - POWER_SUPPLY_CHARGER_SEC_NONE); + QTI_POWER_SUPPLY_CHARGER_SEC_NONE); if (rc < 0) { dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", rc); @@ -315,17 +316,18 @@ unlock_out: static void smblib_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) { smblib_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); @@ -397,7 +399,7 @@ int smblib_get_charge_param(struct smb_charger *chg, return rc; } -int smblib_get_usb_suspend(struct smb_charger *chg, int *suspend) +static int smblib_get_usb_suspend(struct smb_charger *chg, int *suspend) { int rc = 0; u8 temp; @@ -468,7 +470,7 @@ int smblib_get_thermal_threshold(struct smb_charger *chg, u16 addr, int *val) struct apsd_result { const char * const name; const u8 bit; - const enum power_supply_type pst; + const int val; }; enum { @@ -487,42 +489,42 @@ static const struct apsd_result smblib_apsd_results[] = { [UNKNOWN] = { .name = "UNKNOWN", .bit = 0, - .pst = POWER_SUPPLY_TYPE_UNKNOWN + .val = POWER_SUPPLY_TYPE_UNKNOWN }, [SDP] = { .name = "SDP", .bit = SDP_CHARGER_BIT, - .pst = POWER_SUPPLY_TYPE_USB + .val = POWER_SUPPLY_TYPE_USB }, [CDP] = { .name = "CDP", .bit = CDP_CHARGER_BIT, - .pst = POWER_SUPPLY_TYPE_USB_CDP + .val = POWER_SUPPLY_TYPE_USB_CDP }, [DCP] = { .name = "DCP", .bit = DCP_CHARGER_BIT, - .pst = POWER_SUPPLY_TYPE_USB_DCP + .val = POWER_SUPPLY_TYPE_USB_DCP }, [OCP] = { .name = "OCP", .bit = OCP_CHARGER_BIT, - .pst = POWER_SUPPLY_TYPE_USB_DCP + .val = POWER_SUPPLY_TYPE_USB_DCP }, [FLOAT] = { .name = "FLOAT", .bit = FLOAT_CHARGER_BIT, - .pst = POWER_SUPPLY_TYPE_USB_FLOAT + .val = QTI_POWER_SUPPLY_TYPE_USB_FLOAT }, [HVDCP2] = { .name = "HVDCP2", .bit = DCP_CHARGER_BIT | QC_2P0_BIT, - .pst = POWER_SUPPLY_TYPE_USB_HVDCP + .val = QTI_POWER_SUPPLY_TYPE_USB_HVDCP }, [HVDCP3] = { .name = "HVDCP3", .bit = DCP_CHARGER_BIT | QC_3P0_BIT, - .pst = POWER_SUPPLY_TYPE_USB_HVDCP_3, + .val = QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3, }, }; @@ -657,26 +659,14 @@ int smblib_set_chg_freq(struct smb_chg_param *param, return 0; } -int smblib_set_opt_switcher_freq(struct smb_charger *chg, int fsw_khz) +static int smblib_set_opt_switcher_freq(struct smb_charger *chg, int fsw_khz) { - union power_supply_propval pval = {0, }; int rc = 0; rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, fsw_khz); if (rc < 0) dev_err(chg->dev, "Error in setting freq_buck rc=%d\n", rc); - if (chg->mode == PARALLEL_MASTER && chg->pl.psy) { - pval.intval = fsw_khz; - /* - * Some parallel charging implementations may not have - * PROP_BUCK_FREQ property - they could be running - * with a fixed frequency - */ - power_supply_set_property(chg->pl.psy, - POWER_SUPPLY_PROP_BUCK_FREQ, &pval); - } - return rc; } @@ -717,7 +707,7 @@ int smblib_set_charge_param(struct smb_charger *chg, return rc; } -int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend) +static int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend) { int rc = 0; @@ -738,7 +728,7 @@ int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend) return rc; } -int smblib_set_dc_suspend(struct smb_charger *chg, bool suspend) +static int smblib_set_dc_suspend(struct smb_charger *chg, bool suspend) { int rc = 0; @@ -756,7 +746,7 @@ static int smblib_usb_pd_adapter_allowance_override(struct smb_charger *chg, { int rc = 0; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) return 0; rc = smblib_write(chg, USBIN_ADAPTER_ALLOW_OVERRIDE_REG, @@ -803,10 +793,10 @@ static int smblib_set_usb_pd_allowed_voltage(struct smb_charger *chg, int rc, aicl_threshold; u8 vbus_allowance; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) return 0; - if (chg->pd_active == POWER_SUPPLY_PD_PPS_ACTIVE) { + if (chg->pd_active == QTI_POWER_SUPPLY_PD_PPS_ACTIVE) { vbus_allowance = CONTINUOUS; } else if (min_allowed_uv == MICRO_5V && max_allowed_uv == MICRO_5V) { vbus_allowance = FORCE_5V; @@ -873,29 +863,139 @@ int smblib_set_aicl_cont_threshold(struct smb_chg_param *param, /******************** * HELPER FUNCTIONS * ********************/ +static const char * const smblib_cp_ext_iio_chan[] = { + [CP_PARALLEL_OUTPUT_MODE] = "parallel_output_mode", + [CP_MASTER_ENABLE] = "cp_enable", + [CP_ILIM] = "cp_ilim", + [CP_DIE_TEMP] = "cp_die_temp", +}; + +static const char * const smblib_parallel_ext_iio_chan[] = { + [SMB_CHARGER_TEMP] = "charger_temp", + [SMB_CHARGER_TEMP_MAX] = "charger_temp_max", + [SMB_SET_SHIP_MODE] = "set_ship_mode", +}; + +static const char * const smblib_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", +}; + +static int smblib_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 CP: + if (IS_ERR_OR_NULL(chg->iio_chan_list_cp)) + return -ENODEV; + iio_chan_list = chg->iio_chan_list_cp[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; +} + +static int smblib_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; + case CP: + if (IS_ERR_OR_NULL(chg->iio_chan_list_cp)) + return -ENODEV; + iio_chan_list = chg->iio_chan_list_cp[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; + } + + return iio_write_channel_raw(iio_chan_list, val); +} + static bool is_cp_available(struct smb_charger *chg) { - if (!chg->cp_psy) - chg->cp_psy = power_supply_get_by_name("charge_pump_master"); + int rc; + struct iio_channel **iio_list; - return !!chg->cp_psy; + if (IS_ERR(chg->iio_chan_list_cp)) + return false; + + if (!chg->iio_chan_list_cp) { + iio_list = get_ext_channels(chg->dev, + smblib_cp_ext_iio_chan, + ARRAY_SIZE(smblib_cp_ext_iio_chan)); + if (IS_ERR(iio_list)) { + rc = PTR_ERR(iio_list); + if (rc != -EPROBE_DEFER) { + dev_err(chg->dev, "Failed to get channels, rc=%d\n", + rc); + chg->iio_chan_list_cp = ERR_PTR(-EINVAL); + } + return false; + } + chg->iio_chan_list_cp = iio_list; + } + + return true; } static bool is_cp_topo_vbatt(struct smb_charger *chg) { - int rc; + int rc = 0, val; bool is_vbatt; - union power_supply_propval pval; if (!is_cp_available(chg)) return false; - rc = power_supply_get_property(chg->cp_psy, - POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); - if (rc < 0) + rc = smblib_read_iio_prop(chg, CP, CP_PARALLEL_OUTPUT_MODE, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get CP PARALLEL_OUTPUT_MODE rc=%d\n", + rc); return false; + } - is_vbatt = (pval.intval == POWER_SUPPLY_PL_OUTPUT_VBAT); + is_vbatt = (val == QTI_POWER_SUPPLY_PL_OUTPUT_VBAT); smblib_dbg(chg, PR_WLS, "%s\n", is_vbatt ? "true" : "false"); @@ -905,8 +1005,7 @@ static bool is_cp_topo_vbatt(struct smb_charger *chg) #define CP_TO_MAIN_ICL_OFFSET_PC 10 int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua) { - union power_supply_propval pval = {0, }; - int rc; + int rc = 0, val; /* * Apply ILIM offset to main charger's FCC if all of the following @@ -914,45 +1013,45 @@ int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua) * - HVDCP3 adapter with CP as parallel charger * - Output connection topology is VBAT */ - if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config - || ((chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) - && chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5)) + if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config || + ((chg->real_charger_type != + QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3) && + chg->real_charger_type != + QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5)) return -EINVAL; - rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ENABLE, - &pval); + rc = smblib_read_iio_prop(chg, CP, CP_MASTER_ENABLE, &val); if (rc < 0) { smblib_err(chg, "Couldn't get CP ENABLE rc=%d\n", rc); return rc; } - if (!pval.intval) + if (!val) return -EINVAL; - rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ILIM, - &pval); + rc = smblib_read_iio_prop(chg, CP, CP_ILIM, &val); if (rc < 0) { smblib_err(chg, "Couldn't get CP ILIM rc=%d\n", rc); return rc; } - *offset_ua = (pval.intval * CP_TO_MAIN_ICL_OFFSET_PC * 2) / 100; + *offset_ua = (val * CP_TO_MAIN_ICL_OFFSET_PC * 2) / 100; return 0; } int smblib_get_prop_from_bms(struct smb_charger *chg, - enum power_supply_property psp, - union power_supply_propval *val) + 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; } void smblib_apsd_enable(struct smb_charger *chg, bool enable) @@ -1089,15 +1188,15 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) if (chg->pd_active) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_PD; } else if (chg->qc3p5_detected) { - chg->real_charger_type = POWER_SUPPLY_TYPE_USB_HVDCP_3P5; + chg->real_charger_type = QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5; } else { /* * Update real charger type only if its not FLOAT * detected as as SDP */ - if (!(apsd_result->pst == POWER_SUPPLY_TYPE_USB_FLOAT && + if (!(apsd_result->val == QTI_POWER_SUPPLY_TYPE_USB_FLOAT && chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) - chg->real_charger_type = apsd_result->pst; + chg->real_charger_type = apsd_result->val; } smblib_dbg(chg, PR_MISC, "APSD=%s PD=%d QC3P5=%d\n", @@ -1112,8 +1211,6 @@ static int smblib_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); } @@ -1121,11 +1218,9 @@ static int smblib_notifier_call(struct notifier_block *nb, if (chg->jeita_configured == JEITA_CFG_NONE) schedule_work(&chg->jeita_update_work); - if (chg->sec_pl_present && !chg->pl.psy - && !strcmp(psy->desc->name, "parallel")) { - chg->pl.psy = psy; + if (chg->sec_pl_present && !chg->iio_chan_list_smb_parallel + && !strcmp(psy->desc->name, "parallel")) schedule_work(&chg->pl_update_work); - } if (!strcmp(psy->desc->name, "charge_pump_master")) { pm_stay_awake(chg->dev); @@ -1149,41 +1244,6 @@ static int smblib_register_notifier(struct smb_charger *chg) return 0; } -int smblib_mapping_soc_from_field_value(struct smb_chg_param *param, - int val_u, u8 *val_raw) -{ - if (val_u > param->max_u || val_u < param->min_u) - return -EINVAL; - - *val_raw = val_u << 1; - - return 0; -} - -int smblib_mapping_cc_delta_to_field_value(struct smb_chg_param *param, - u8 val_raw) -{ - int val_u = val_raw * param->step_u + param->min_u; - - if (val_u > param->max_u) - val_u -= param->max_u * 2; - - return val_u; -} - -int smblib_mapping_cc_delta_from_field_value(struct smb_chg_param *param, - int val_u, u8 *val_raw) -{ - if (val_u > param->max_u || val_u < param->min_u - param->max_u) - return -EINVAL; - - val_u += param->max_u * 2 - param->min_u; - val_u %= param->max_u * 2; - *val_raw = val_u / param->step_u; - - return 0; -} - static void smblib_uusb_removal(struct smb_charger *chg) { int rc; @@ -1191,9 +1251,9 @@ static void smblib_uusb_removal(struct smb_charger *chg) struct storm_watch *wdata; int sec_charger; - sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL : - POWER_SUPPLY_CHARGER_SEC_NONE; - smblib_select_sec_charger(chg, sec_charger, POWER_SUPPLY_CP_NONE, + sec_charger = chg->sec_pl_present ? QTI_POWER_SUPPLY_CHARGER_SEC_PL : + QTI_POWER_SUPPLY_CHARGER_SEC_NONE; + smblib_select_sec_charger(chg, sec_charger, QTI_POWER_SUPPLY_CP_NONE, false); cancel_delayed_work_sync(&chg->pl_enable_work); @@ -1295,23 +1355,22 @@ static void smblib_uusb_removal(struct smb_charger *chg) void smblib_suspend_on_debug_battery(struct smb_charger *chg) { - int rc; - union power_supply_propval val; + int rc = 0, val; - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_DEBUG_BATTERY, &val); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_DEBUG_BATTERY, &val); if (rc < 0) { smblib_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); - vote(chg->dc_suspend_votable, DEBUG_BOARD_VOTER, val.intval, 0); - if (val.intval) + vote(chg->usb_icl_votable, DEBUG_BOARD_VOTER, val, 0); + vote(chg->dc_suspend_votable, DEBUG_BOARD_VOTER, val, 0); + if (val) pr_info("Input suspended: Fake battery\n"); } else { vote(chg->chg_disable_votable, DEBUG_BOARD_VOTER, - val.intval, 0); + val, 0); } } @@ -1379,7 +1438,7 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) } if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB && - apsd_result->pst == POWER_SUPPLY_TYPE_USB_FLOAT) { + apsd_result->val == QTI_POWER_SUPPLY_TYPE_USB_FLOAT) { /* * change the float charger configuration to SDP, if this * is the case of SDP being detected as FLOAT @@ -1416,13 +1475,13 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) /* suspend if 25mA or less is requested */ bool suspend = (icl_ua <= USBIN_25MA); - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) schgm_flash_torch_priority(chg, suspend ? TORCH_BOOST_MODE : TORCH_BUCK_MODE); /* Do not configure ICL from SW for DAM cables */ if (smblib_get_prop_typec_mode(chg) == - POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) + QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY) return 0; if (suspend) @@ -1434,8 +1493,9 @@ int smblib_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) { smblib_err(chg, "Couldn't set SDP ICL rc=%d\n", rc); @@ -1507,20 +1567,19 @@ int smblib_toggle_smb_en(struct smb_charger *chg, int toggle) return rc; } -int smblib_get_irq_status(struct smb_charger *chg, - union power_supply_propval *val) +int smblib_get_irq_status(struct smb_charger *chg, int *val) { int rc; u8 reg; if (chg->wa_flags & SKIP_MISC_PBS_IRQ_WA) { - val->intval = 0; + *val = 0; return 0; } mutex_lock(&chg->irq_status_lock); /* Report and clear cached status */ - val->intval = chg->irq_status; + *val = chg->irq_status; chg->irq_status = 0; /* get real time status of pulse skip irq */ @@ -1529,7 +1588,7 @@ int smblib_get_irq_status(struct smb_charger *chg, smblib_err(chg, "Couldn't read MISC_PBS_RT_STS_REG rc=%d\n", rc); else - val->intval |= (reg & PULSE_SKIP_IRQ_BIT); + *val |= (reg & PULSE_SKIP_IRQ_BIT); mutex_unlock(&chg->irq_status_lock); return rc; @@ -1575,7 +1634,7 @@ static int smblib_set_moisture_protection(struct smb_charger *chg, /* Set 1% duty cycle on ID detection */ rc = smblib_masked_write(chg, - ((chg->chg_param.smb_version == PMI632_SUBTYPE) + ((chg->chg_param.smb_version == PMI632) ? PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG : TYPEC_U_USB_WATER_PROTECTION_CFG_REG), EN_MICRO_USB_WATER_PROTECTION_BIT | @@ -1609,7 +1668,7 @@ static int smblib_set_moisture_protection(struct smb_charger *chg, /* Disable periodic monitoring of CC_ID pin */ rc = smblib_write(chg, - ((chg->chg_param.smb_version == PMI632_SUBTYPE) + ((chg->chg_param.smb_version == PMI632) ? PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG : TYPEC_U_USB_WATER_PROTECTION_CFG_REG), 0); if (rc < 0) { @@ -1658,7 +1717,7 @@ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, { struct smb_charger *chg = data; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) return 0; /* resume input if suspend is invalid */ @@ -1906,13 +1965,10 @@ int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev) /******************** * BATT PSY GETTERS * ********************/ - -int smblib_get_prop_input_suspend(struct smb_charger *chg, - union power_supply_propval *val) +int smblib_get_prop_input_current_limit_usb(struct smb_charger *chg, + union power_supply_propval *val) { - val->intval - = (get_client_vote(chg->usb_icl_votable, USER_VOTER) == 0) - && get_client_vote(chg->dc_suspend_votable, USER_VOTER); + val->intval = get_client_vote(chg->usb_icl_votable, USER_VOTER); return 0; } @@ -1944,7 +2000,9 @@ int smblib_get_prop_batt_capacity(struct smb_charger *chg, return 0; } - rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CAPACITY, val); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CAPACITY, &val->intval); + if (rc < 0) + smblib_err(chg, "Couldn't get capacity prop rc=%d\n", rc); return rc; } @@ -1973,8 +2031,8 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, int rc, suspend = 0, input_present = 0; if (chg->fake_chg_status_on_debug_batt) { - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_DEBUG_BATTERY, &pval); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_DEBUG_BATTERY, + &pval.intval); if (rc < 0) { pr_err_ratelimited("Couldn't get debug battery prop rc=%d\n", rc); @@ -2005,10 +2063,10 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, * the battery status as DISCHARGING. */ smblib_is_input_present(chg, &input_present); - rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CAPACITY, &pval); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CAPACITY, &pval.intval); if (!rc && pval.intval == 0 && input_present) { - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CURRENT_NOW, &pval); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CURRENT_NOW, + &pval.intval); if (!rc && pval.intval > 0) { if (chg->cutoff_count > CUTOFF_COUNT) { val->intval = POWER_SUPPLY_STATUS_DISCHARGING; @@ -2166,7 +2224,7 @@ int smblib_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 = QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER; break; default: val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; @@ -2193,9 +2251,12 @@ int smblib_get_prop_batt_health(struct smb_charger *chg, stat); if (stat & CHARGER_ERROR_STATUS_BAT_OV_BIT) { - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); - if (!rc) { + rc = smblib_get_prop_from_bms(chg, SMB5_QG_VOLTAGE_NOW, + &pval.intval); + if (rc < 0) { + smblib_err(chg, "Couldn't get voltage_now prop rc=%d\n", + rc); + } else { /* * If Vbatt is within 40mV above Vfloat, then don't * treat it as overvoltage. @@ -2246,13 +2307,13 @@ int smblib_get_prop_system_temp_level_max(struct smb_charger *chg, } int smblib_get_prop_input_current_limited(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { u8 stat; int rc; if (chg->fake_input_current_limited >= 0) { - val->intval = chg->fake_input_current_limited; + *val = chg->fake_input_current_limited; return 0; } @@ -2261,7 +2322,7 @@ int smblib_get_prop_input_current_limited(struct smb_charger *chg, smblib_err(chg, "Couldn't read AICL_STATUS rc=%d\n", rc); return rc; } - val->intval = (stat & SOFT_ILIMIT_BIT) || chg->is_hdc; + *val = (stat & SOFT_ILIMIT_BIT) || chg->is_hdc; return 0; } @@ -2299,7 +2360,7 @@ int smblib_get_prop_batt_iterm(struct smb_charger *chg, temp = buf[1] | (buf[0] << 8); temp = sign_extend32(temp, 15); - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) temp = DIV_ROUND_CLOSEST(temp * ITERM_LIMITS_PMI632_MA, ADC_CHG_ITERM_MASK); else @@ -2312,7 +2373,7 @@ int smblib_get_prop_batt_iterm(struct smb_charger *chg, } int smblib_get_prop_batt_charge_done(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc; u8 stat; @@ -2325,7 +2386,7 @@ int smblib_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; } @@ -2334,10 +2395,11 @@ int smblib_get_batt_current_now(struct smb_charger *chg, { int rc; - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_CURRENT_NOW, val); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CURRENT_NOW, &val->intval); if (!rc) val->intval *= (-1); + else + smblib_err(chg, "Couldn't get current_now prop rc=%d\n", rc); return rc; } @@ -2345,28 +2407,22 @@ int smblib_get_batt_current_now(struct smb_charger *chg, /*********************** * BATTERY PSY SETTERS * ***********************/ - -int smblib_set_prop_input_suspend(struct smb_charger *chg, +int smblib_set_prop_input_current_limit_usb(struct smb_charger *chg, const union power_supply_propval *val) { int rc; - /* vote 0mA when suspended */ - rc = vote(chg->usb_icl_votable, USER_VOTER, (bool)val->intval, 0); - if (rc < 0) { - smblib_err(chg, "Couldn't vote to %s USB rc=%d\n", - (bool)val->intval ? "suspend" : "resume", rc); - return rc; - } + if (val->intval == 0) + rc = vote(chg->usb_icl_votable, USER_VOTER, true, 0); + else if (val->intval < 0) + rc = vote(chg->usb_icl_votable, USER_VOTER, false, 0); + else + rc = vote(chg->usb_icl_votable, USER_VOTER, true, val->intval); - rc = vote(chg->dc_suspend_votable, USER_VOTER, (bool)val->intval, 0); - if (rc < 0) { - smblib_err(chg, "Couldn't vote to %s DC rc=%d\n", - (bool)val->intval ? "suspend" : "resume", rc); - return rc; - } + if (rc < 0) + smblib_err(chg, "Couldn't vote to set USB ICL to %d rc=%d\n", + val->intval, rc); - power_supply_changed(chg->batt_psy); return rc; } @@ -2422,17 +2478,17 @@ int smblib_set_prop_system_temp_level(struct smb_charger *chg, } int smblib_set_prop_input_current_limited(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { - chg->fake_input_current_limited = val->intval; + chg->fake_input_current_limited = val; return 0; } int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc; - u8 new_thr = DIV_ROUND_CLOSEST(val->intval * 255, 100); + u8 new_thr = DIV_ROUND_CLOSEST(val * 255, 100); rc = smblib_write(chg, CHARGE_RCHG_SOC_THRESHOLD_CFG_REG, new_thr); @@ -2442,7 +2498,7 @@ int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg, return rc; } - chg->auto_recharge_soc = val->intval; + chg->auto_recharge_soc = val; return rc; } @@ -2569,7 +2625,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) int rc; u8 stat; - if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) { + if (chg->real_charger_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, @@ -2581,24 +2637,24 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0); } - if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 - || chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { + if (chg->real_charger_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3 + || chg->real_charger_type == + QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { rc = smblib_hvdcp3_set_fsw(chg); if (rc < 0) smblib_err(chg, "Couldn't set QC3.0 Fsw rc=%d\n", rc); } - power_supply_changed(chg->usb_main_psy); + power_supply_changed(chg->batt_psy); } int smblib_dp_dm(struct smb_charger *chg, int val) { - int target_icl_ua, rc = 0; - union power_supply_propval pval; + int target_icl_ua, data, rc = 0; u8 stat; switch (val) { - case POWER_SUPPLY_DP_DM_DP_PULSE: + case QTI_POWER_SUPPLY_DP_DM_DP_PULSE: /* * Pre-emptively increment pulse count to enable the setting * of FSW prior to increasing voltage. @@ -2623,26 +2679,24 @@ int smblib_dp_dm(struct smb_charger *chg, int val) smblib_dbg(chg, PR_PARALLEL, "DP_DM_DP_PULSE rc=%d cnt=%d\n", rc, chg->pulse_cnt); break; - case POWER_SUPPLY_DP_DM_DM_PULSE: + case QTI_POWER_SUPPLY_DP_DM_DM_PULSE: rc = smblib_dm_pulse(chg); if (!rc && chg->pulse_cnt) chg->pulse_cnt--; smblib_dbg(chg, PR_PARALLEL, "DP_DM_DM_PULSE rc=%d cnt=%d\n", rc, chg->pulse_cnt); break; - case POWER_SUPPLY_DP_DM_ICL_DOWN: + case QTI_POWER_SUPPLY_DP_DM_ICL_DOWN: target_icl_ua = get_effective_result(chg->usb_icl_votable); if (target_icl_ua < 0) { /* no client vote, get the ICL from charger */ - rc = power_supply_get_property(chg->usb_psy, - POWER_SUPPLY_PROP_HW_CURRENT_MAX, - &pval); + rc = smblib_get_charge_current(chg, &data); if (rc < 0) { smblib_err(chg, "Couldn't get max curr rc=%d\n", rc); return rc; } - target_icl_ua = pval.intval; + target_icl_ua = data; } /* @@ -2660,12 +2714,12 @@ int smblib_dp_dm(struct smb_charger *chg, int val) smblib_dbg(chg, PR_PARALLEL, "ICL DOWN ICL=%d reduction=%d\n", target_icl_ua, chg->usb_icl_delta_ua); break; - case POWER_SUPPLY_DP_DM_FORCE_5V: + case QTI_POWER_SUPPLY_DP_DM_FORCE_5V: rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT); if (rc < 0) pr_err("Failed to force 5V\n"); break; - case POWER_SUPPLY_DP_DM_FORCE_9V: + case QTI_POWER_SUPPLY_DP_DM_FORCE_9V: if (chg->qc2_unsupported_voltage == QC2_NON_COMPLIANT_9V) { smblib_err(chg, "Couldn't set 9V: unsupported\n"); return -EINVAL; @@ -2690,7 +2744,7 @@ int smblib_dp_dm(struct smb_charger *chg, int val) if (rc < 0) pr_err("Failed to force 9V\n"); break; - case POWER_SUPPLY_DP_DM_FORCE_12V: + case QTI_POWER_SUPPLY_DP_DM_FORCE_12V: if (chg->qc2_unsupported_voltage == QC2_NON_COMPLIANT_12V) { smblib_err(chg, "Couldn't set 12V: unsupported\n"); return -EINVAL; @@ -2715,11 +2769,11 @@ int smblib_dp_dm(struct smb_charger *chg, int val) if (rc < 0) pr_err("Failed to force 12V\n"); break; - case POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5: + case QTI_POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5: chg->qc3p5_detected = true; smblib_update_usb_type(chg); break; - case POWER_SUPPLY_DP_DM_ICL_UP: + case QTI_POWER_SUPPLY_DP_DM_ICL_UP: default: break; } @@ -2795,11 +2849,25 @@ static int smblib_set_sw_thermal_regulation(struct smb_charger *chg, static int smblib_update_thermal_readings(struct smb_charger *chg) { - union power_supply_propval pval = {0, }; - int rc = 0; + int rc = 0, data = 0; + struct iio_channel **iio_list; - if (!chg->pl.psy) - chg->pl.psy = power_supply_get_by_name("parallel"); + if (!chg->iio_chan_list_smb_parallel) { + iio_list = get_ext_channels(chg->dev, + smblib_parallel_ext_iio_chan, + ARRAY_SIZE(smblib_parallel_ext_iio_chan)); + if (IS_ERR(iio_list)) { + rc = PTR_ERR(iio_list); + if (rc != -EPROBE_DEFER) { + dev_err(chg->dev, "Failed to get channels, %d\n", + rc); + chg->iio_chan_list_smb_parallel = + ERR_PTR(-EINVAL); + } + } else { + chg->iio_chan_list_smb_parallel = iio_list; + } + } rc = smblib_read_iio_channel(chg, chg->iio.die_temp_chan, DIV_FACTOR_DECIDEGC, &chg->die_temp); @@ -2822,30 +2890,30 @@ static int smblib_update_thermal_readings(struct smb_charger *chg) return rc; } - if (chg->sec_chg_selected == POWER_SUPPLY_CHARGER_SEC_CP) { + if (chg->sec_chg_selected == QTI_POWER_SUPPLY_CHARGER_SEC_CP) { if (is_cp_available(chg)) { - rc = power_supply_get_property(chg->cp_psy, - POWER_SUPPLY_PROP_CP_DIE_TEMP, &pval); + rc = smblib_read_iio_prop(chg, CP, CP_DIE_TEMP, &data); + if (rc < 0) { smblib_err(chg, "Couldn't get smb1390 charger temp, rc=%d\n", rc); return rc; } - chg->smb_temp = pval.intval; + chg->smb_temp = data; } else { smblib_dbg(chg, PR_MISC, "Coudln't find cp_psy\n"); chg->smb_temp = -ENODATA; } - } else if (chg->pl.psy && chg->sec_chg_selected == - POWER_SUPPLY_CHARGER_SEC_PL) { - rc = power_supply_get_property(chg->pl.psy, - POWER_SUPPLY_PROP_CHARGER_TEMP, &pval); + } else if (!IS_ERR_OR_NULL(chg->iio_chan_list_smb_parallel) && + chg->sec_chg_selected == QTI_POWER_SUPPLY_CHARGER_SEC_PL) { + rc = smblib_read_iio_prop(chg, SMB_PARALLEL, SMB_CHARGER_TEMP, + &data); if (rc < 0) { smblib_err(chg, "Couldn't get smb1355 charger temp, rc=%d\n", rc); return rc; } - chg->smb_temp = pval.intval; + chg->smb_temp = data; } else { chg->smb_temp = -ENODATA; } @@ -3012,11 +3080,10 @@ exit: /******************* * DC PSY GETTERS * *******************/ - int smblib_get_prop_voltage_wls_output(struct smb_charger *chg, union power_supply_propval *val) { - int rc; + int rc = 0; if (!chg->wls_psy) { chg->wls_psy = power_supply_get_by_name("wireless"); @@ -3025,11 +3092,8 @@ int smblib_get_prop_voltage_wls_output(struct smb_charger *chg, } rc = power_supply_get_property(chg->wls_psy, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, val); - if (rc < 0) - dev_err(chg->dev, "Couldn't get POWER_SUPPLY_PROP_VOLTAGE_REGULATION, rc=%d\n", - rc); return rc; } @@ -3040,7 +3104,7 @@ int smblib_get_prop_dc_present(struct smb_charger *chg, int rc; u8 stat; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) { + if (chg->chg_param.smb_version == PMI632) { val->intval = 0; return 0; } @@ -3061,7 +3125,7 @@ int smblib_get_prop_dc_online(struct smb_charger *chg, int rc = 0; u8 stat; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) { + if (chg->chg_param.smb_version == PMI632) { val->intval = 0; return 0; } @@ -3125,7 +3189,7 @@ int smblib_get_prop_dc_voltage_max(struct smb_charger *chg, int smblib_get_prop_dc_voltage_now(struct smb_charger *chg, union power_supply_propval *val) { - int rc; + int rc = 0; if (!chg->wls_psy) { chg->wls_psy = power_supply_get_by_name("wireless"); @@ -3134,10 +3198,10 @@ int smblib_get_prop_dc_voltage_now(struct smb_charger *chg, } rc = power_supply_get_property(chg->wls_psy, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, val); if (rc < 0) { - dev_err(chg->dev, "Couldn't get POWER_SUPPLY_PROP_VOLTAGE_REGULATION, rc=%d\n", + dev_err(chg->dev, "Couldn't get POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, rc=%d\n", rc); return rc; } @@ -3158,9 +3222,9 @@ int smblib_set_prop_dc_current_max(struct smb_charger *chg, #define DCIN_AICL_RERUN_DELAY_MS 5000 int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, - const union power_supply_propval *val) + union power_supply_propval *val) { - int rc; + int rc = 0; if (!chg->wls_psy) { chg->wls_psy = power_supply_get_by_name("wireless"); @@ -3169,10 +3233,11 @@ int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, } rc = power_supply_set_property(chg->wls_psy, - POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, val); + if (rc < 0) - dev_err(chg->dev, "Couldn't set POWER_SUPPLY_PROP_VOLTAGE_REGULATION, rc=%d\n", + dev_err(chg->dev, "Couldn't set POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, rc=%d\n", rc); smblib_dbg(chg, PR_WLS, "%d\n", val->intval); @@ -3304,8 +3369,8 @@ int smblib_get_usb_online(struct smb_charger *chg, if (!val->intval) goto exit; - if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || - (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) + if (((chg->typec_mode == QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) || + (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB)) && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) val->intval = 0; else @@ -3322,7 +3387,7 @@ int smblib_get_prop_usb_voltage_max_design(struct smb_charger *chg, union power_supply_propval *val) { switch (chg->real_charger_type) { - case POWER_SUPPLY_TYPE_USB_HVDCP: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP: if (chg->qc2_unsupported_voltage == QC2_NON_COMPLIANT_9V) { val->intval = MICRO_5V; break; @@ -3332,10 +3397,10 @@ int smblib_get_prop_usb_voltage_max_design(struct smb_charger *chg, break; } /* else, fallthrough */ - case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: - case POWER_SUPPLY_TYPE_USB_HVDCP_3: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_PD: - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) val->intval = MICRO_9V; else val->intval = MICRO_12V; @@ -3352,7 +3417,7 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, union power_supply_propval *val) { switch (chg->real_charger_type) { - case POWER_SUPPLY_TYPE_USB_HVDCP: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP: if (chg->qc2_unsupported_voltage == QC2_NON_COMPLIANT_9V) { val->intval = MICRO_5V; break; @@ -3362,9 +3427,9 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, break; } /* else, fallthrough */ - case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: - case POWER_SUPPLY_TYPE_USB_HVDCP_3: - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3: + if (chg->chg_param.smb_version == PMI632) val->intval = MICRO_9V; else val->intval = MICRO_12V; @@ -3388,12 +3453,12 @@ static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, int step_uv = HVDCP3_STEP_UV; switch (chg->real_charger_type) { - case POWER_SUPPLY_TYPE_USB_HVDCP: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP: val->intval = MICRO_12V; break; - case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5: step_uv = HVDCP3P5_STEP_UV; - case POWER_SUPPLY_TYPE_USB_HVDCP_3: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3: val->intval = MICRO_5V + (step_uv * chg->pulse_cnt); break; case POWER_SUPPLY_TYPE_USB_PD: @@ -3506,7 +3571,7 @@ int smblib_get_prop_usb_voltage_now(struct smb_charger *chg, * to occur randomly in the USBIN channel, particularly at high * voltages. */ - if (chg->chg_param.smb_version == PM8150B_SUBTYPE) + if (chg->chg_param.smb_version == PM8150B) rc = smblib_read_mid_voltage_chan(chg, val); else rc = smblib_read_usbin_voltage_chan(chg, val); @@ -3531,14 +3596,14 @@ unlock: } int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc; if (!chg->iio.vph_v_chan) return -ENODATA; - rc = iio_read_channel_processed(chg->iio.vph_v_chan, &val->intval); + rc = iio_read_channel_processed(chg->iio.vph_v_chan, val); if (rc < 0) { smblib_err(chg, "Couldn't read vph channel rc=%d\n", rc); return rc; @@ -3547,7 +3612,7 @@ int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, return 0; } -bool smblib_rsbux_low(struct smb_charger *chg, int r_thr) +static bool smblib_rsbux_low(struct smb_charger *chg, int r_thr) { int r_sbu1, r_sbu2; bool ret = false; @@ -3615,7 +3680,7 @@ cleanup: } int smblib_get_prop_charger_temp(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int temp, rc; int input_present; @@ -3634,7 +3699,7 @@ int smblib_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; } @@ -3643,14 +3708,14 @@ int smblib_get_prop_charger_temp(struct smb_charger *chg, } int smblib_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 = smblib_read(chg, TYPE_C_MISC_STATUS_REG, &stat); @@ -3661,22 +3726,22 @@ int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, smblib_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 smblib_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 smblib_get_prop_ufp_mode(struct smb_charger *chg) @@ -3687,28 +3752,28 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg) rc = smblib_read(chg, TYPE_C_SNK_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_1 rc=%d\n", rc); - return POWER_SUPPLY_TYPEC_NONE; + return QTI_POWER_SUPPLY_TYPEC_NONE; } smblib_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 smblib_get_prop_dfp_mode(struct smb_charger *chg) @@ -3717,30 +3782,30 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg) u8 stat; if (chg->lpd_stage == LPD_STAGE_COMMIT) - return POWER_SUPPLY_TYPEC_NONE; + return QTI_POWER_SUPPLY_TYPEC_NONE; rc = smblib_read(chg, TYPE_C_SRC_STATUS_REG, &stat); if (rc < 0) { smblib_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; } smblib_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_RA_VCONN_BIT: - return POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE; + return QTI_POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE; 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 smblib_get_prop_typec_mode(struct smb_charger *chg) @@ -3763,24 +3828,23 @@ static int smblib_get_prop_typec_mode(struct smb_charger *chg) } inline int smblib_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 smblib_get_prop_typec_power_role(struct smb_charger *chg, - union power_supply_propval *val) +int smblib_get_prop_typec_power_role(struct smb_charger *chg, 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; } @@ -3794,39 +3858,39 @@ int smblib_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; smblib_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); + return (chg->typec_mode > QTI_POWER_SUPPLY_TYPEC_NONE && + chg->typec_mode < QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT); } int smblib_get_prop_typec_select_rp(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc, rp; u8 stat; @@ -3843,20 +3907,20 @@ int smblib_get_prop_typec_select_rp(struct smb_charger *chg, switch (stat & TYPEC_SRC_RP_SEL_MASK) { case TYPEC_SRC_RP_STD: - rp = POWER_SUPPLY_TYPEC_SRC_RP_STD; + rp = QTI_POWER_SUPPLY_TYPEC_SRC_RP_STD; break; case TYPEC_SRC_RP_1P5A: - rp = POWER_SUPPLY_TYPEC_SRC_RP_1P5A; + rp = QTI_POWER_SUPPLY_TYPEC_SRC_RP_1P5A; break; case TYPEC_SRC_RP_3A: case TYPEC_SRC_RP_3A_DUPLICATE: - rp = POWER_SUPPLY_TYPEC_SRC_RP_3A; + rp = QTI_POWER_SUPPLY_TYPEC_SRC_RP_3A; break; default: return -EINVAL; } - val->intval = rp; + *val = rp; return 0; } @@ -3882,7 +3946,7 @@ int smblib_get_prop_usb_current_now(struct smb_charger *chg, * 0.4V/A in Buck mode, 0.8V/A in Boost mode. */ switch (chg->chg_param.smb_version) { - case PMI632_SUBTYPE: + case PMI632: buck_scale = 40; boost_scale = 80; break; @@ -3893,7 +3957,7 @@ int smblib_get_prop_usb_current_now(struct smb_charger *chg, } if (chg->otg_present || smblib_get_prop_dfp_mode(chg) != - POWER_SUPPLY_TYPEC_NONE) { + QTI_POWER_SUPPLY_TYPEC_NONE) { val->intval = DIV_ROUND_CLOSEST(val->intval * 100, boost_scale); return rc; @@ -3948,28 +4012,28 @@ int smblib_get_prop_input_current_settled(struct smb_charger *chg, } int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc, pulses; int step_uv = HVDCP3_STEP_UV; switch (chg->real_charger_type) { - case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5: step_uv = HVDCP3P5_STEP_UV; - case POWER_SUPPLY_TYPE_USB_HVDCP_3: + case QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3: rc = smblib_get_pulse_cnt(chg, &pulses); if (rc < 0) { smblib_err(chg, "Couldn't read QC_PULSE_COUNT rc=%d\n", rc); return 0; } - val->intval = MICRO_5V + step_uv * pulses; + *val = MICRO_5V + step_uv * pulses; break; case POWER_SUPPLY_TYPE_USB_PD: - val->intval = chg->voltage_min_uv; + *val = chg->voltage_min_uv; break; default: - val->intval = MICRO_5V; + *val = MICRO_5V; break; } @@ -3977,24 +4041,23 @@ int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, } int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { - val->intval = chg->pd_hard_reset; + *val = chg->pd_hard_reset; return 0; } int smblib_get_pe_start(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { - val->intval = chg->ok_to_pd; + *val = chg->ok_to_pd; return 0; } int smblib_get_prop_smb_health(struct smb_charger *chg) { - int rc; + int rc, val; int input_present; - union power_supply_propval prop = {0, }; rc = smblib_is_input_present(chg, &input_present); if (rc < 0) @@ -4003,24 +4066,25 @@ int smblib_get_prop_smb_health(struct smb_charger *chg) if ((input_present == INPUT_NOT_PRESENT) || (!is_cp_available(chg))) return POWER_SUPPLY_HEALTH_UNKNOWN; - rc = power_supply_get_property(chg->cp_psy, - POWER_SUPPLY_PROP_CP_DIE_TEMP, &prop); - if (rc < 0) + rc = smblib_read_iio_prop(chg, CP, CP_DIE_TEMP, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get CP DIE_TEMP rc=%d\n", rc); return rc; + } - if (prop.intval > SMB_TEMP_RST_THRESH) + if (val > SMB_TEMP_RST_THRESH) return POWER_SUPPLY_HEALTH_OVERHEAT; - if (prop.intval > SMB_TEMP_REG_H_THRESH) + if (val > SMB_TEMP_REG_H_THRESH) return POWER_SUPPLY_HEALTH_HOT; - if (prop.intval > SMB_TEMP_REG_L_THRESH) + if (val > SMB_TEMP_REG_L_THRESH) return POWER_SUPPLY_HEALTH_WARM; return POWER_SUPPLY_HEALTH_COOL; } -int smblib_get_prop_die_health(struct smb_charger *chg) +static int smblib_get_prop_die_health(struct smb_charger *chg) { int rc; u8 stat; @@ -4069,12 +4133,12 @@ int smblib_get_prop_die_health(struct smb_charger *chg) } int smblib_get_die_health(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { if (chg->die_health == -EINVAL) - val->intval = smblib_get_prop_die_health(chg); + *val = smblib_get_prop_die_health(chg); else - val->intval = chg->die_health; + *val = chg->die_health; return 0; } @@ -4187,7 +4251,7 @@ int smblib_get_prop_connector_health(struct smb_charger *chg) * In PM8150B, SKIN channel measures Wireless charger receiver * temp, used to regulate DC ICL. */ - if (chg->chg_param.smb_version == PM8150B_SUBTYPE && dc_present) + if (chg->chg_param.smb_version == PM8150B && dc_present) return smblib_get_skin_temp_status(chg); return POWER_SUPPLY_HEALTH_COOL; @@ -4198,11 +4262,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: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: /* fall through */ default: rp_ua = DCP_CURRENT_UA; @@ -4216,14 +4280,14 @@ static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode) * *****************/ int smblib_set_prop_pd_current_max(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc, icl; if (chg->pd_active) { icl = get_client_vote(chg->usb_icl_votable, PD_VOTER); - rc = vote(chg->usb_icl_votable, PD_VOTER, true, val->intval); - if (val->intval != icl) + rc = vote(chg->usb_icl_votable, PD_VOTER, true, val); + if (val != icl) power_supply_changed(chg->usb_psy); } else { rc = -EPERM; @@ -4238,7 +4302,7 @@ static int smblib_handle_usb_current(struct smb_charger *chg, int rc = 0, rp_ua, typec_mode; union power_supply_propval val = {0, }; - if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_FLOAT) { + if (chg->real_charger_type == QTI_POWER_SUPPLY_TYPE_USB_FLOAT) { if (usb_current == -ETIMEDOUT) { if ((chg->float_cfg & FLOAT_OPTIONS_MASK) == FORCE_FLOAT_SDP_CFG_BIT) { @@ -4256,7 +4320,7 @@ static int smblib_handle_usb_current(struct smb_charger *chg, } if (chg->connector_type == - POWER_SUPPLY_CONNECTOR_TYPEC) { + QTI_POWER_SUPPLY_CONNECTOR_TYPEC) { /* * Valid FLOAT charger, report the current * based of Rp. @@ -4318,7 +4382,7 @@ static int smblib_handle_usb_current(struct smb_charger *chg, } int smblib_set_prop_sdp_current_max(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { union power_supply_propval pval; int rc = 0; @@ -4333,11 +4397,11 @@ int smblib_set_prop_sdp_current_max(struct smb_charger *chg, /* handle the request only when USB is present */ if (pval.intval) - rc = smblib_handle_usb_current(chg, val->intval); + rc = smblib_handle_usb_current(chg, val); } else if (chg->system_suspend_supported) { - if (val->intval <= USBIN_25MA) + if (val <= USBIN_25MA) rc = vote(chg->usb_icl_votable, - PD_SUSPEND_SUPPORTED_VOTER, true, val->intval); + PD_SUSPEND_SUPPORTED_VOTER, true, val); else rc = vote(chg->usb_icl_votable, PD_SUSPEND_SUPPORTED_VOTER, false, 0); @@ -4345,39 +4409,21 @@ int smblib_set_prop_sdp_current_max(struct smb_charger *chg, return rc; } -int smblib_set_prop_boost_current(struct smb_charger *chg, - const union power_supply_propval *val) -{ - int rc = 0; - - rc = smblib_set_charge_param(chg, &chg->param.freq_switcher, - val->intval <= chg->boost_threshold_ua ? - chg->chg_freq.freq_below_otg_threshold : - chg->chg_freq.freq_above_otg_threshold); - if (rc < 0) { - dev_err(chg->dev, "Error in setting freq_boost rc=%d\n", rc); - return rc; - } - - chg->boost_current_ua = val->intval; - return rc; -} - int smblib_set_prop_usb_voltage_max_limit(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { union power_supply_propval pval = {0, }; /* Exit if same value is re-configured */ - if (val->intval == chg->usbin_forced_max_uv) + if (val == chg->usbin_forced_max_uv) return 0; smblib_get_prop_usb_voltage_max_design(chg, &pval); - if (val->intval >= MICRO_5V && val->intval <= pval.intval) { - chg->usbin_forced_max_uv = val->intval; + if (val >= MICRO_5V && val <= pval.intval) { + chg->usbin_forced_max_uv = val; smblib_dbg(chg, PR_MISC, "Max VBUS limit changed to: %d\n", - val->intval); + val); } else if (chg->usbin_forced_max_uv) { chg->usbin_forced_max_uv = 0; } else { @@ -4389,7 +4435,7 @@ int smblib_set_prop_usb_voltage_max_limit(struct smb_charger *chg, return 0; } -void smblib_typec_irq_config(struct smb_charger *chg, bool en) +static void smblib_typec_irq_config(struct smb_charger *chg, bool en) { if (en == chg->typec_irq_en) return; @@ -4414,32 +4460,31 @@ void smblib_typec_irq_config(struct smb_charger *chg, bool en) } #define PR_LOCK_TIMEOUT_MS 1000 -int smblib_set_prop_typec_power_role(struct smb_charger *chg, - const union power_supply_propval *val) +int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) { int rc = 0; u8 power_role; enum power_supply_typec_mode typec_mode; bool snk_attached = false, src_attached = false, is_pr_lock = false; - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; smblib_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) { smblib_dbg(chg, PR_MISC, "power role already in %d, ignore!", chg->power_role); return 0; } typec_mode = smblib_get_prop_typec_mode(chg); - if (typec_mode >= POWER_SUPPLY_TYPEC_SINK && - typec_mode <= POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) + if (typec_mode >= QTI_POWER_SUPPLY_TYPEC_SINK && + typec_mode <= QTI_POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) snk_attached = true; - else if (typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT && - typec_mode <= POWER_SUPPLY_TYPEC_SOURCE_HIGH) + else if (typec_mode >= QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT && + typec_mode <= QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH) src_attached = true; /* @@ -4449,9 +4494,9 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, * related interrupts for locking power role to avoid the redundant * notifications. */ - if ((chg->power_role == POWER_SUPPLY_TYPEC_PR_DUAL) && - ((src_attached && val->intval == POWER_SUPPLY_TYPEC_PR_SINK) || - (snk_attached && val->intval == POWER_SUPPLY_TYPEC_PR_SOURCE))) + if ((chg->power_role == QTI_POWER_SUPPLY_TYPEC_PR_DUAL) && + ((src_attached && val == QTI_POWER_SUPPLY_TYPEC_PR_SINK) || + (snk_attached && val == QTI_POWER_SUPPLY_TYPEC_PR_SOURCE))) is_pr_lock = true; smblib_dbg(chg, PR_MISC, "snk_attached = %d, src_attached = %d, is_pr_lock = %d\n", @@ -4471,21 +4516,21 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, chg->pr_lock_in_progress = is_pr_lock; spin_unlock(&chg->typec_pr_lock); - 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 = chg->typec_try_mode; 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: - smblib_err(chg, "power role %d not supported\n", val->intval); + smblib_err(chg, "power role %d not supported\n", val); return -EINVAL; } @@ -4498,12 +4543,12 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, return rc; } - chg->power_role = val->intval; + chg->power_role = val; return rc; } int smblib_set_prop_typec_select_rp(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc; @@ -4512,10 +4557,10 @@ int smblib_set_prop_typec_select_rp(struct smb_charger *chg, return -EINVAL; } - if (val->intval < TYPEC_SRC_RP_MAX_ELEMENTS) { + if (val < TYPEC_SRC_RP_MAX_ELEMENTS) { rc = smblib_masked_write(chg, TYPE_C_CURRSRC_CFG_REG, TYPEC_SRC_RP_SEL_MASK, - val->intval); + val); if (rc < 0) smblib_err(chg, "Couldn't write to TYPE_C_CURRSRC_CFG rc=%d\n", rc); @@ -4526,11 +4571,11 @@ int smblib_set_prop_typec_select_rp(struct smb_charger *chg, } int smblib_set_prop_pd_voltage_min(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc, min_uv; - min_uv = min(val->intval, chg->voltage_max_uv); + min_uv = min(val, chg->voltage_max_uv); if (chg->voltage_min_uv == min_uv) return 0; @@ -4538,29 +4583,29 @@ int smblib_set_prop_pd_voltage_min(struct smb_charger *chg, chg->voltage_max_uv); if (rc < 0) { smblib_err(chg, "invalid min voltage %duV rc=%d\n", - val->intval, rc); + val, rc); return rc; } chg->voltage_min_uv = min_uv; - power_supply_changed(chg->usb_main_psy); + power_supply_changed(chg->batt_psy); return rc; } int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc, max_uv; - max_uv = max(val->intval, chg->voltage_min_uv); + max_uv = max(val, chg->voltage_min_uv); if (chg->voltage_max_uv == max_uv) return 0; rc = smblib_set_usb_pd_fsw(chg, max_uv); if (rc < 0) { smblib_err(chg, "Couldn't set FSW for voltage %duV rc=%d\n", - val->intval, rc); + val, rc); return rc; } @@ -4568,18 +4613,17 @@ int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, max_uv); if (rc < 0) { smblib_err(chg, "invalid max voltage %duV rc=%d\n", - val->intval, rc); + val, rc); return rc; } chg->voltage_max_uv = max_uv; - power_supply_changed(chg->usb_main_psy); - + power_supply_changed(chg->batt_psy); return rc; } int smblib_set_prop_pd_active(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { const struct apsd_result *apsd = smblib_get_apsd_result(chg); @@ -4590,14 +4634,14 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, * Ignore repetitive notification while PD is active, which * is caused by hard reset. */ - if (chg->pd_active && chg->pd_active == val->intval) + if (chg->pd_active && chg->pd_active == val) return 0; - chg->pd_active = val->intval; + chg->pd_active = val; smblib_apsd_enable(chg, !chg->pd_active); - update_sw_icl_max(chg, apsd->pst); + update_sw_icl_max(chg, apsd->val); if (chg->pd_active) { vote(chg->limited_irq_disable_votable, CHARGER_TYPE_VOTER, @@ -4618,11 +4662,11 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, * For PPS, Charge Pump is preferred over parallel charger if * present. */ - if (chg->pd_active == POWER_SUPPLY_PD_PPS_ACTIVE + if (chg->pd_active == QTI_POWER_SUPPLY_PD_PPS_ACTIVE && chg->sec_cp_present) { rc = smblib_select_sec_charger(chg, - POWER_SUPPLY_CHARGER_SEC_CP, - POWER_SUPPLY_CP_PPS, false); + QTI_POWER_SUPPLY_CHARGER_SEC_CP, + QTI_POWER_SUPPLY_CP_PPS, false); if (rc < 0) dev_err(chg->dev, "Couldn't enable secondary charger rc=%d\n", rc); @@ -4635,10 +4679,10 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, true, 0); sec_charger = chg->sec_pl_present ? - POWER_SUPPLY_CHARGER_SEC_PL : - POWER_SUPPLY_CHARGER_SEC_NONE; + QTI_POWER_SUPPLY_CHARGER_SEC_PL : + QTI_POWER_SUPPLY_CHARGER_SEC_NONE; rc = smblib_select_sec_charger(chg, sec_charger, - POWER_SUPPLY_CP_NONE, false); + QTI_POWER_SUPPLY_CP_NONE, false); if (rc < 0) dev_err(chg->dev, "Couldn't enable secondary charger rc=%d\n", @@ -4667,30 +4711,30 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, } int smblib_set_prop_ship_mode(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc; - smblib_dbg(chg, PR_MISC, "Set ship mode: %d!!\n", !!val->intval); + smblib_dbg(chg, PR_MISC, "Set ship mode: %d!!\n", !!val); rc = smblib_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; } int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc = 0; - if (chg->pd_hard_reset == val->intval) + if (chg->pd_hard_reset == val) return rc; - chg->pd_hard_reset = val->intval; + chg->pd_hard_reset = val; rc = smblib_masked_write(chg, TYPE_C_EXIT_STATE_CFG_REG, EXIT_SNK_BASED_ON_CC_BIT, (chg->pd_hard_reset) ? EXIT_SNK_BASED_ON_CC_BIT : 0); @@ -4840,12 +4884,12 @@ static int smblib_soft_jeita_arb_wa(struct smb_charger *chg) * USB MAIN PSY GETTERS * ************************/ int smblib_get_prop_fcc_delta(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { int rc, jeita_cc_delta_ua = 0; if (chg->sw_jeita_enabled) { - val->intval = 0; + *val = 0; return 0; } @@ -4855,7 +4899,7 @@ int smblib_get_prop_fcc_delta(struct smb_charger *chg, jeita_cc_delta_ua = 0; } - val->intval = jeita_cc_delta_ua; + *val = jeita_cc_delta_ua; return 0; } @@ -4919,7 +4963,7 @@ int smblib_get_charge_current(struct smb_charger *chg, } switch (typec_source_rd) { - case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: + case QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT: switch (apsd_result->bit) { case CDP_CHARGER_BIT: current_ua = CDP_CURRENT_UA; @@ -4934,14 +4978,14 @@ int smblib_get_charge_current(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; @@ -5037,7 +5081,7 @@ irqreturn_t sdam_sts_change_irq_handler(int irq, void *data) chg->irq_status |= PULSE_SKIP_IRQ_BIT; mutex_unlock(&chg->irq_status_lock); - power_supply_changed(chg->usb_main_psy); + power_supply_changed(chg->batt_psy); return IRQ_HANDLED; } @@ -5049,8 +5093,7 @@ static void smblib_eval_chg_termination(struct smb_charger *chg, u8 batt_status) union power_supply_propval pval = {0, }; int rc = 0; - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_REAL_CAPACITY, &pval); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_REAL_CAPACITY, &pval.intval); if (rc < 0) { smblib_err(chg, "Couldn't read SOC value, rc=%d\n", rc); return; @@ -5193,7 +5236,7 @@ irqreturn_t usbin_uv_irq_handler(int irq, void *data) unsuspend_input: /* Force torch in boost mode to ensure it works with low ICL */ - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) schgm_flash_torch_priority(chg, TORCH_BOOST_MODE); if (chg->aicl_max_reached) { @@ -5220,7 +5263,7 @@ unsuspend_input: /* Workaround for non-QC2.0-compliant chargers follows */ if (!chg->qc2_unsupported_voltage && - apsd->pst == POWER_SUPPLY_TYPE_USB_HVDCP) { + apsd->val == QTI_POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); if (rc < 0) smblib_err(chg, @@ -5333,7 +5376,7 @@ static void smblib_micro_usb_plugin(struct smb_charger *chg, bool vbus_rising) } } -void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) +static void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) { int rc; u8 stat; @@ -5379,7 +5422,7 @@ void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) } #define PL_DELAY_MS 30000 -void smblib_usb_plugin_locked(struct smb_charger *chg) +static void smblib_usb_plugin_locked(struct smb_charger *chg) { int rc; u8 stat; @@ -5457,7 +5500,7 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) chg->aicl_cont_threshold_mv); chg->aicl_max_reached = false; - if (chg->chg_param.smb_version == PMI632_SUBTYPE) + if (chg->chg_param.smb_version == PMI632) schgm_flash_torch_priority(chg, TORCH_BUCK_MODE); @@ -5477,7 +5520,7 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) smblib_update_usb_type(chg); } - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) smblib_micro_usb_plugin(chg, vbus_rising); vote(chg->temp_change_irq_disable_votable, DEFAULT_VOTER, @@ -5536,8 +5579,8 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, /* for QC3, switch to CP if present */ if (chg->sec_cp_present) { rc = smblib_select_sec_charger(chg, - POWER_SUPPLY_CHARGER_SEC_CP, - POWER_SUPPLY_CP_HVDCP3, false); + QTI_POWER_SUPPLY_CHARGER_SEC_CP, + QTI_POWER_SUPPLY_CP_HVDCP3, false); if (rc < 0) dev_err(chg->dev, "Couldn't enable secondary chargers rc=%d\n", @@ -5570,7 +5613,7 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, if (qc_charger) { hvdcp_ua = (chg->real_charger_type == - POWER_SUPPLY_TYPE_USB_HVDCP) ? + QTI_POWER_SUPPLY_TYPE_USB_HVDCP) ? chg->chg_param.hvdcp2_max_icl_ua : HVDCP_CURRENT_UA; @@ -5600,7 +5643,7 @@ static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg, rising ? "rising" : "falling"); } -static void update_sw_icl_max(struct smb_charger *chg, int pst) +static void update_sw_icl_max(struct smb_charger *chg, int val) { int typec_mode; int rp_ua; @@ -5609,7 +5652,7 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) if (chg->pd_active) return; - 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; } @@ -5617,8 +5660,8 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) /* * HVDCP 2/3, handled separately */ - if (pst == POWER_SUPPLY_TYPE_USB_HVDCP - || pst == POWER_SUPPLY_TYPE_USB_HVDCP_3) + if (val == QTI_POWER_SUPPLY_TYPE_USB_HVDCP + || val == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3) return; /* TypeC rp med or high, use rp value */ @@ -5630,7 +5673,7 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) } /* rp-std or legacy, USB BC 1.2 */ - switch (pst) { + switch (val) { case POWER_SUPPLY_TYPE_USB: /* * USB_PSY will vote to increase the current to 500/900mA once @@ -5653,7 +5696,7 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) rp_ua = get_rp_based_dcp_current(chg, typec_mode); vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua); break; - case POWER_SUPPLY_TYPE_USB_FLOAT: + case QTI_POWER_SUPPLY_TYPE_USB_FLOAT: /* * limit ICL to 100mA, the USB driver will enumerate to check * if this is a SDP and appropriately set the current @@ -5678,7 +5721,7 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) apsd_result = smblib_update_usb_type(chg); - update_sw_icl_max(chg, apsd_result->pst); + update_sw_icl_max(chg, apsd_result->val); switch (apsd_result->bit) { case SDP_CHARGER_BIT: @@ -5716,7 +5759,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) } smblib_dbg(chg, PR_INTERRUPT, "APSD_STATUS = 0x%02x\n", stat); - if ((chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + if ((chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) && (stat & APSD_DTC_STATUS_DONE_BIT) && !chg->uusb_apsd_rerun_done) { /* @@ -5764,17 +5807,17 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, ktime_t time) { - union power_supply_propval pval; + int val; struct smb_charger *chg = container_of(alarm, struct smb_charger, lpd_recheck_timer); int rc; if (chg->lpd_reason == LPD_MOISTURE_DETECTED) { - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - rc = smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_DUAL; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", - pval.intval, rc); + val, rc); return ALARMTIMER_NORESTART; } chg->moisture_present = false; @@ -5799,10 +5842,9 @@ enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, #define RSBU_K_300K_UV 3000000 static bool smblib_src_lpd(struct smb_charger *chg) { - union power_supply_propval pval; bool lpd_flag = false; u8 stat; - int rc; + int rc, val; if (chg->lpd_disabled) return false; @@ -5828,11 +5870,11 @@ static bool smblib_src_lpd(struct smb_charger *chg) if (lpd_flag) { chg->lpd_stage = LPD_STAGE_COMMIT; - pval.intval = POWER_SUPPLY_TYPEC_PR_SINK; - rc = smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_SINK; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", - pval.intval, rc); + val, rc); chg->lpd_reason = LPD_MOISTURE_DETECTED; chg->moisture_present = true; vote(chg->usb_icl_votable, LPD_VOTER, true, 0); @@ -5968,8 +6010,8 @@ static int typec_partner_register(struct smb_charger *chg) typec_mode = smblib_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 = smblib_role_switch_failure(chg); @@ -6100,7 +6142,7 @@ static void smblib_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) { smblib_dbg(chg, PR_MISC, "Role reversal not latched to UFP in %d msecs. Resetting to DRP mode\n", ROLE_REVERSAL_DELAY_MS); rc = smblib_force_dr_mode(chg, TYPEC_PORT_DRP); @@ -6108,15 +6150,15 @@ static void smblib_typec_role_check_work(struct work_struct *work) smblib_err(chg, "Failed 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); smblib_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) { smblib_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; @@ -6126,7 +6168,7 @@ static void smblib_typec_role_check_work(struct work_struct *work) smblib_err(chg, "Failed 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); smblib_dbg(chg, PR_MISC, "Role changed successfully to SOURCE"); @@ -6167,11 +6209,11 @@ static void typec_src_removal(struct smb_charger *chg) int sec_charger; u8 val[2] = {0}; - sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL : - POWER_SUPPLY_CHARGER_SEC_NONE; + sec_charger = chg->sec_pl_present ? QTI_POWER_SUPPLY_CHARGER_SEC_PL : + QTI_POWER_SUPPLY_CHARGER_SEC_NONE; - rc = smblib_select_sec_charger(chg, sec_charger, POWER_SUPPLY_CP_NONE, - false); + rc = smblib_select_sec_charger(chg, sec_charger, + QTI_POWER_SUPPLY_CP_NONE, false); if (rc < 0) dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", rc); @@ -6327,7 +6369,7 @@ static void smblib_handle_rp_change(struct smb_charger *chg, int typec_mode) * pre-existing valid vote or FLOAT is configured for * SDP current. */ - if (apsd->pst == POWER_SUPPLY_TYPE_USB_FLOAT) { + if (apsd->val == QTI_POWER_SUPPLY_TYPE_USB_FLOAT) { if (get_client_vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER) <= USBIN_100MA || (chg->float_cfg & FLOAT_OPTIONS_MASK) @@ -6335,7 +6377,7 @@ static void smblib_handle_rp_change(struct smb_charger *chg, int typec_mode) return; } - update_sw_icl_max(chg, apsd->pst); + update_sw_icl_max(chg, apsd->val); smblib_dbg(chg, PR_MISC, "CC change old_mode=%d new_mode=%d\n", chg->typec_mode, typec_mode); @@ -6373,7 +6415,7 @@ irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data) smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); - if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { + if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) { if (chg->uusb_moisture_protection_enabled) { /* * Adding pm_stay_awake as because pm_relax is called @@ -6416,7 +6458,7 @@ irqreturn_t 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) { smblib_dbg(chg, PR_INTERRUPT, "Ignoring for micro USB\n"); return IRQ_HANDLED; @@ -6478,7 +6520,7 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data) } if (smblib_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) { @@ -6730,14 +6772,14 @@ irqreturn_t dc_plugin_irq_handler(int irq, void *data) int input_present; bool dcin_present, vbus_present; int rc, wireless_vout = 0, wls_set = 0; - int sec_charger; + int sec_charger, val; - rc = smblib_get_prop_vph_voltage_now(chg, &pval); + rc = smblib_get_prop_vph_voltage_now(chg, &val); if (rc < 0) return IRQ_HANDLED; /* 2*VPH, with a granularity of 100mV */ - wireless_vout = ((pval.intval * 2) / 100000) * 100000; + wireless_vout = ((val * 2) / 100000) * 100000; rc = smblib_is_input_present(chg, &input_present); if (rc < 0) @@ -6793,8 +6835,8 @@ irqreturn_t dc_plugin_irq_handler(int irq, void *data) rc); rc = smblib_select_sec_charger(chg, - POWER_SUPPLY_CHARGER_SEC_CP, - POWER_SUPPLY_CP_WIRELESS, false); + QTI_POWER_SUPPLY_CHARGER_SEC_CP, + QTI_POWER_SUPPLY_CP_WIRELESS, false); if (rc < 0) dev_err(chg->dev, "Couldn't enable secondary chargers rc=%d\n", rc); @@ -6812,12 +6854,12 @@ irqreturn_t dc_plugin_irq_handler(int irq, void *data) schedule_work(&chg->dcin_aicl_work); } else { - if (chg->cp_reason == POWER_SUPPLY_CP_WIRELESS) { + if (chg->cp_reason == QTI_POWER_SUPPLY_CP_WIRELESS) { sec_charger = chg->sec_pl_present ? - POWER_SUPPLY_CHARGER_SEC_PL : - POWER_SUPPLY_CHARGER_SEC_NONE; + QTI_POWER_SUPPLY_CHARGER_SEC_PL : + QTI_POWER_SUPPLY_CHARGER_SEC_NONE; rc = smblib_select_sec_charger(chg, sec_charger, - POWER_SUPPLY_CP_NONE, false); + QTI_POWER_SUPPLY_CP_NONE, false); if (rc < 0) dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", rc); @@ -7056,21 +7098,21 @@ irqreturn_t usbin_ov_irq_handler(int irq, void *data) ***************/ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, - union power_supply_propval *val) + int *val) { - val->intval = chg->pr_swap_in_progress; + *val = chg->pr_swap_in_progress; return 0; } #define DETACH_DETECT_DELAY_MS 20 int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, - const union power_supply_propval *val) + int val) { int rc; u8 stat = 0, orientation; - smblib_dbg(chg, PR_MISC, "Requested PR_SWAP %d\n", val->intval); - chg->pr_swap_in_progress = val->intval; + smblib_dbg(chg, PR_MISC, "Requested PR_SWAP %d\n", val); + chg->pr_swap_in_progress = val; /* check for cable removal during pr_swap */ if (!chg->pr_swap_in_progress) { @@ -7082,13 +7124,13 @@ int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, rc = smblib_masked_write(chg, TYPE_C_DEBOUNCE_OPTION_REG, REDUCE_TCCDEBOUNCE_TO_2MS_BIT, - val->intval ? REDUCE_TCCDEBOUNCE_TO_2MS_BIT : 0); + val ? REDUCE_TCCDEBOUNCE_TO_2MS_BIT : 0); if (rc < 0) smblib_err(chg, "Couldn't set tCC debounce rc=%d\n", rc); rc = smblib_masked_write(chg, TYPE_C_EXIT_STATE_CFG_REG, BYPASS_VSAFE0V_DURING_ROLE_SWAP_BIT, - val->intval ? BYPASS_VSAFE0V_DURING_ROLE_SWAP_BIT : 0); + val ? BYPASS_VSAFE0V_DURING_ROLE_SWAP_BIT : 0); if (rc < 0) smblib_err(chg, "Couldn't set exit state cfg rc=%d\n", rc); @@ -7126,7 +7168,7 @@ int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, smblib_err(chg, "Couldn't enable DRP rc=%d\n", rc); return rc; } - chg->power_role = POWER_SUPPLY_TYPEC_PR_DUAL; + chg->power_role = QTI_POWER_SUPPLY_TYPEC_PR_DUAL; smblib_dbg(chg, PR_MISC, "restore power role: %d\n", chg->power_role); } @@ -7217,6 +7259,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, + smblib_qg_ext_iio_chan, + ARRAY_SIZE(smblib_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; + } smblib_suspend_on_debug_battery(chg); @@ -7226,10 +7289,25 @@ static void bms_update_work(struct work_struct *work) static void pl_update_work(struct work_struct *work) { - union power_supply_propval prop_val; + int val, rc; struct smb_charger *chg = container_of(work, struct smb_charger, pl_update_work); - int rc; + struct iio_channel **iio_list; + + iio_list = get_ext_channels(chg->dev, + smblib_parallel_ext_iio_chan, + ARRAY_SIZE(smblib_parallel_ext_iio_chan)); + if (IS_ERR(iio_list)) { + rc = PTR_ERR(iio_list); + if (rc != -EPROBE_DEFER) { + dev_err(chg->dev, "Failed to get channels, %d\n", + rc); + chg->iio_chan_list_smb_parallel = ERR_PTR(-EINVAL); + } + return; + } + + chg->iio_chan_list_smb_parallel = iio_list; if (chg->smb_temp_max == -EINVAL) { rc = smblib_get_thermal_threshold(chg, @@ -7242,21 +7320,21 @@ static void pl_update_work(struct work_struct *work) } } - prop_val.intval = chg->smb_temp_max; - rc = power_supply_set_property(chg->pl.psy, - POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, - &prop_val); + val = chg->smb_temp_max; + rc = smblib_write_iio_prop(chg, SMB_PARALLEL, + SMB_CHARGER_TEMP_MAX, val); + if (rc < 0) { dev_err(chg->dev, "Couldn't set POWER_SUPPLY_PROP_CHARGER_TEMP_MAX rc=%d\n", rc); return; } - if (chg->sec_chg_selected == POWER_SUPPLY_CHARGER_SEC_CP) + if (chg->sec_chg_selected == QTI_POWER_SUPPLY_CHARGER_SEC_CP) return; - smblib_select_sec_charger(chg, POWER_SUPPLY_CHARGER_SEC_PL, - POWER_SUPPLY_CP_NONE, false); + smblib_select_sec_charger(chg, QTI_POWER_SUPPLY_CHARGER_SEC_PL, + QTI_POWER_SUPPLY_CP_NONE, false); } static void clear_hdc_work(struct work_struct *work) @@ -7280,7 +7358,7 @@ static void smblib_icl_change_work(struct work_struct *work) return; } - power_supply_changed(chg->usb_main_psy); + power_supply_changed(chg->batt_psy); smblib_dbg(chg, PR_INTERRUPT, "icl_settled=%d\n", settled_ua); } @@ -7331,7 +7409,7 @@ static void smblib_moisture_protection_work(struct work_struct *work) * Disable 1% duty cycle on CC_ID pin and enable uUSB factory mode * detection to track any change on RID, as interrupts are disable. */ - rc = smblib_write(chg, ((chg->chg_param.smb_version == PMI632_SUBTYPE) ? + rc = smblib_write(chg, ((chg->chg_param.smb_version == PMI632) ? PMI632_TYPEC_U_USB_WATER_PROTECTION_CFG_REG : TYPEC_U_USB_WATER_PROTECTION_CFG_REG), 0); if (rc < 0) { @@ -7412,7 +7490,7 @@ static enum alarmtimer_restart moisture_protection_alarm_cb(struct alarm *alarm, static void smblib_chg_termination_work(struct work_struct *work) { - union power_supply_propval pval; + int val; struct smb_charger *chg = container_of(work, struct smb_charger, chg_termination_work); int rc, input_present, delay = CHG_TERM_WA_ENTRY_DELAY_MS; @@ -7428,26 +7506,28 @@ static void smblib_chg_termination_work(struct work_struct *work) if ((rc < 0) || !input_present) goto out; - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_REAL_CAPACITY, &pval); - if ((rc < 0) || (pval.intval < 100)) { + rc = smblib_get_prop_from_bms(chg, SMB5_QG_REAL_CAPACITY, &val); + if ((rc < 0) || (val < 100)) { vote(chg->usb_icl_votable, CHG_TERMINATION_VOTER, false, 0); vote(chg->dc_suspend_votable, CHG_TERMINATION_VOTER, false, 0); + smblib_err(chg, "Couldn't read SOC value, rc=%d\n", rc); goto out; } /* Get the battery float voltage */ - rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_VOLTAGE_MAX, - &pval); - if (rc < 0) + rc = smblib_get_prop_from_bms(chg, SMB5_QG_VOLTAGE_MAX, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read voltage_max prop, rc=%d\n", rc); goto out; + } - max_fv_uv = pval.intval; + max_fv_uv = val; - rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CHARGE_FULL, - &pval); - if (rc < 0) + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CHARGE_FULL, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read charge_full prop, rc=%d\n", rc); goto out; + } /* * On change in the value of learned capacity, re-initialize the @@ -7455,64 +7535,71 @@ static void smblib_chg_termination_work(struct work_struct *work) * at full capacity. Also, in case cc_soc_ref value is reset, * re-initialize it. */ - if (pval.intval != chg->charge_full_cc || !chg->cc_soc_ref) { - chg->charge_full_cc = pval.intval; + if (val != chg->charge_full_cc || !chg->cc_soc_ref) { + chg->charge_full_cc = val; - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); - if (rc < 0) + rc = smblib_get_prop_from_bms(chg, SMB5_QG_VOLTAGE_NOW, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read voltage_now prop, rc=%d\n", + rc); goto out; + } /* * Store the Vbat at the charge termination to compare with * the current voltage to see if the Vbat is increasing after * charge termination in BSM. */ - chg->term_vbat_uv = pval.intval; - vbat_now_uv = pval.intval; + chg->term_vbat_uv = val; + vbat_now_uv = val; - rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CC_SOC, - &pval); - if (rc < 0) + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CC_SOC, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read cc_soc prop, rc=%d\n", + rc); goto out; - - chg->cc_soc_ref = pval.intval; + } + chg->cc_soc_ref = val; } else { - rc = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); - if (rc < 0) + rc = smblib_get_prop_from_bms(chg, SMB5_QG_VOLTAGE_NOW, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read voltage_now prop, rc=%d\n", + rc); goto out; + } - vbat_now_uv = pval.intval; + vbat_now_uv = val; - rc = smblib_get_prop_from_bms(chg, POWER_SUPPLY_PROP_CC_SOC, - &pval); - if (rc < 0) + rc = smblib_get_prop_from_bms(chg, SMB5_QG_CC_SOC, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't read cc_soc prop, rc=%d\n", + rc); goto out; + } } /* * In BSM a sudden jump in CC_SOC is not expected. If seen, its a * good_ocv or updated capacity, reject it. */ - if (chg->last_cc_soc && pval.intval > (chg->last_cc_soc + 100)) { + if (chg->last_cc_soc && val > (chg->last_cc_soc + 100)) { /* CC_SOC has increased by 1% from last time */ - chg->cc_soc_ref = pval.intval; + chg->cc_soc_ref = val; smblib_dbg(chg, PR_MISC, "cc_soc jumped(%d->%d), reset cc_soc_ref\n", - chg->last_cc_soc, pval.intval); + chg->last_cc_soc, val); } - chg->last_cc_soc = pval.intval; + chg->last_cc_soc = val; /* * Suspend/Unsuspend USB input to keep cc_soc within the 0.5% to 0.75% * overshoot range of the cc_soc value at termination and make sure that * vbat is indeed rising above vfloat. */ - if (pval.intval < DIV_ROUND_CLOSEST(chg->cc_soc_ref * 10050, 10000)) { + if (val < DIV_ROUND_CLOSEST(chg->cc_soc_ref * 10050, 10000)) { vote(chg->usb_icl_votable, CHG_TERMINATION_VOTER, false, 0); vote(chg->dc_suspend_votable, CHG_TERMINATION_VOTER, false, 0); delay = CHG_TERM_WA_ENTRY_DELAY_MS; - } else if ((pval.intval > DIV_ROUND_CLOSEST(chg->cc_soc_ref * 10075, + } else if ((val > DIV_ROUND_CLOSEST(chg->cc_soc_ref * 10075, 10000)) && ((vbat_now_uv > chg->term_vbat_uv) && (vbat_now_uv > max_fv_uv))) { @@ -7527,7 +7614,7 @@ static void smblib_chg_termination_work(struct work_struct *work) } smblib_dbg(chg, PR_MISC, "Chg Term WA readings: cc_soc: %d, cc_soc_ref: %d, delay: %d vbat_now %d term_vbat %d\n", - pval.intval, chg->cc_soc_ref, delay, vbat_now_uv, + val, chg->cc_soc_ref, delay, vbat_now_uv, chg->term_vbat_uv); alarm_start_relative(&chg->chg_termination_alarm, ms_to_ktime(delay)); out: @@ -7581,11 +7668,10 @@ 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 = smblib_get_prop_from_bms(chg, - POWER_SUPPLY_PROP_RESISTANCE_ID, &val); + rc = smblib_get_prop_from_bms(chg, SMB5_QG_RESISTANCE_ID, &val.intval); if (rc < 0) { smblib_err(chg, "Failed to get batt-id rc=%d\n", rc); goto out; @@ -7728,9 +7814,8 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, lpd_ra_open_work.work); - union power_supply_propval pval; u8 stat; - int rc; + int rc, val; if (chg->pr_swap_in_progress || chg->pd_hard_reset) { chg->lpd_stage = LPD_STAGE_NONE; @@ -7757,8 +7842,8 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) chg->lpd_stage = LPD_STAGE_COMMIT; /* Enable source only mode */ - pval.intval = POWER_SUPPLY_TYPEC_PR_SOURCE; - rc = smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_SOURCE; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { smblib_err(chg, "Couldn't set typec source only mode rc=%d\n", rc); @@ -7770,8 +7855,8 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) if (smblib_rsbux_low(chg, RSBU_K_300K_UV)) { /* Moisture detected, enable sink only mode */ - pval.intval = POWER_SUPPLY_TYPEC_PR_SINK; - rc = smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_SINK; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { smblib_err(chg, "Couldn't set typec sink only rc=%d\n", rc); @@ -7793,11 +7878,11 @@ static void smblib_lpd_ra_open_work(struct work_struct *work) } /* restore DRP mode */ - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - rc = smblib_set_prop_typec_power_role(chg, &pval); + val = QTI_POWER_SUPPLY_TYPEC_PR_DUAL; + rc = smblib_set_prop_typec_power_role(chg, val); if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", - pval.intval, rc); + val, rc); goto out; } @@ -7821,29 +7906,25 @@ static void smblib_lpd_detach_work(struct work_struct *work) static void smblib_cp_status_change_work(struct work_struct *work) { - int rc; - union power_supply_propval pval; + int rc = 0, val; struct smb_charger *chg = container_of(work, struct smb_charger, cp_status_change_work); - if (!chg->cp_psy) - chg->cp_psy = power_supply_get_by_name("charge_pump_master"); - - if (!chg->cp_psy) + if (!is_cp_available(chg)) goto relax; if (chg->cp_topo == -EINVAL) { - rc = power_supply_get_property(chg->cp_psy, - POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); + rc = smblib_read_iio_prop(chg, CP, CP_PARALLEL_OUTPUT_MODE, + &val); if (rc < 0) { smblib_err(chg, "Couldn't read cp topo rc=%d\n", rc); goto relax; } - chg->cp_topo = pval.intval; + chg->cp_topo = val; - if (chg->cp_topo == POWER_SUPPLY_PL_OUTPUT_VBAT && - chg->cp_reason == POWER_SUPPLY_CP_WIRELESS) + if (chg->cp_topo == QTI_POWER_SUPPLY_PL_OUTPUT_VBAT && + chg->cp_reason == QTI_POWER_SUPPLY_CP_WIRELESS) vote(chg->fcc_main_votable, WLS_PL_CHARGING_VOTER, true, 800000); } @@ -8016,8 +8097,8 @@ static void smblib_iio_deinit(struct smb_charger *chg) int smblib_init(struct smb_charger *chg) { - union power_supply_propval prop_val; - int rc = 0; + int rc = 0, val; + struct iio_channel **iio_list; mutex_init(&chg->smb_lock); mutex_init(&chg->irq_status_lock); @@ -8087,8 +8168,8 @@ int smblib_init(struct smb_charger *chg) chg->fake_batt_status = -EINVAL; chg->sink_src_mode = UNATTACHED_MODE; chg->jeita_configured = false; - chg->sec_chg_selected = POWER_SUPPLY_CHARGER_SEC_NONE; - chg->cp_reason = POWER_SUPPLY_CP_NONE; + chg->sec_chg_selected = QTI_POWER_SUPPLY_CHARGER_SEC_NONE; + chg->cp_reason = QTI_POWER_SUPPLY_CP_NONE; chg->thermal_status = TEMP_BELOW_RANGE; chg->typec_irq_en = true; chg->cp_topo = -EINVAL; @@ -8096,7 +8177,7 @@ int smblib_init(struct smb_charger *chg) 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) { smblib_err(chg, "Couldn't init qcom_batt_init rc=%d\n", rc); @@ -8104,7 +8185,7 @@ int smblib_init(struct smb_charger *chg) } rc = qcom_step_chg_init(chg->dev, chg->step_chg_enabled, - chg->sw_jeita_enabled, false); + chg->sw_jeita_enabled, false, chg->iio_chans); if (rc < 0) { smblib_err(chg, "Couldn't init qcom_step_chg_init rc=%d\n", rc); @@ -8118,16 +8199,26 @@ int smblib_init(struct smb_charger *chg) return rc; } - chg->bms_psy = power_supply_get_by_name("bms"); + iio_list = get_ext_channels(chg->dev, smblib_qg_ext_iio_chan, + ARRAY_SIZE(smblib_qg_ext_iio_chan)); + if (!IS_ERR(iio_list)) + chg->iio_chan_list_qg = iio_list; if (chg->sec_pl_present) { - chg->pl.psy = power_supply_get_by_name("parallel"); - if (chg->pl.psy) { + iio_list = get_ext_channels( + chg->dev, smblib_parallel_ext_iio_chan, + ARRAY_SIZE(smblib_parallel_ext_iio_chan)); + + if (!IS_ERR(iio_list)) + chg->iio_chan_list_smb_parallel = iio_list; + + if (chg->iio_chan_list_smb_parallel) { if (chg->sec_chg_selected - != POWER_SUPPLY_CHARGER_SEC_CP) { + != QTI_POWER_SUPPLY_CHARGER_SEC_CP) { rc = smblib_select_sec_charger(chg, - POWER_SUPPLY_CHARGER_SEC_PL, - POWER_SUPPLY_CP_NONE, false); + QTI_POWER_SUPPLY_CHARGER_SEC_PL, + QTI_POWER_SUPPLY_CP_NONE, + false); if (rc < 0) smblib_err(chg, "Couldn't config pl charger rc=%d\n", rc); @@ -8144,10 +8235,10 @@ int smblib_init(struct smb_charger *chg) } } - prop_val.intval = chg->smb_temp_max; - rc = power_supply_set_property(chg->pl.psy, - POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, - &prop_val); + val = chg->smb_temp_max; + rc = smblib_write_iio_prop(chg, SMB_PARALLEL, + SMB_CHARGER_TEMP_MAX, val); + if (rc < 0) { dev_err(chg->dev, "Couldn't set POWER_SUPPLY_PROP_CHARGER_TEMP_MAX rc=%d\n", rc); diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index 2136155a3b88..fc7965638320 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "storm-watch.h" #include "battery.h" @@ -373,6 +374,13 @@ struct smb_iio { struct iio_channel *smb_temp_chan; }; +enum pmic_type { + PM8150B, + PM7250B, + PM6150, + PMI632, +}; + struct smb_charger { struct device *dev; char *name; @@ -380,6 +388,10 @@ 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_cp; + struct iio_channel **iio_chan_list_smb_parallel; int *debug_mask; int pd_disabled; enum smb_mode mode; @@ -403,12 +415,8 @@ struct smb_charger { struct power_supply *batt_psy; struct power_supply *usb_psy; struct power_supply *dc_psy; - struct power_supply *bms_psy; - struct power_supply *usb_main_psy; struct power_supply *usb_port_psy; struct power_supply *wls_psy; - struct power_supply *cp_psy; - enum power_supply_type real_charger_type; /* notifiers */ struct notifier_block nb; @@ -585,6 +593,7 @@ struct smb_charger { bool qc3p5_detected; /* workaround flag */ + int real_charger_type; u32 wa_flags; int boost_current_ua; int qc2_max_pulses; @@ -626,24 +635,13 @@ int smblib_batch_read(struct smb_charger *chg, u16 addr, u8 *val, int count); int smblib_get_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int *val_u); -int smblib_get_usb_suspend(struct smb_charger *chg, int *suspend); int smblib_get_aicl_cont_threshold(struct smb_chg_param *param, u8 val_raw); int smblib_enable_charging(struct smb_charger *chg, bool enable); int smblib_set_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int val_u); -int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend); -int smblib_set_dc_suspend(struct smb_charger *chg, bool suspend); -int smblib_mapping_soc_from_field_value(struct smb_chg_param *param, - int val_u, u8 *val_raw); -int smblib_mapping_cc_delta_to_field_value(struct smb_chg_param *param, - u8 val_raw); -int smblib_mapping_cc_delta_from_field_value(struct smb_chg_param *param, - int val_u, u8 *val_raw); int smblib_set_chg_freq(struct smb_chg_param *param, int val_u, u8 *val_raw); -int smblib_set_prop_boost_current(struct smb_charger *chg, - const union power_supply_propval *val); int smblib_set_aicl_cont_threshold(struct smb_chg_param *param, int val_u, u8 *val_raw); int smblib_vbus_regulator_enable(struct regulator_dev *rdev); @@ -675,7 +673,7 @@ irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data); irqreturn_t temp_change_irq_handler(int irq, void *data); irqreturn_t usbin_ov_irq_handler(int irq, void *data); irqreturn_t sdam_sts_change_irq_handler(int irq, void *data); -int smblib_get_prop_input_suspend(struct smb_charger *chg, +int smblib_get_prop_input_current_limit_usb(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_batt_present(struct smb_charger *chg, union power_supply_propval *val); @@ -686,7 +684,7 @@ int smblib_get_prop_batt_status(struct smb_charger *chg, int smblib_get_prop_batt_charge_type(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_batt_charge_done(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_batt_current_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_batt_health(struct smb_charger *chg, @@ -696,11 +694,11 @@ int smblib_get_prop_system_temp_level(struct smb_charger *chg, int smblib_get_prop_system_temp_level_max(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_input_current_limited(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_batt_iterm(struct smb_charger *chg, union power_supply_propval *val); -int smblib_set_prop_input_suspend(struct smb_charger *chg, - const union power_supply_propval *val); +int smblib_set_prop_input_current_limit_usb(struct smb_charger *chg, + const union power_supply_propval *val); int smblib_set_prop_batt_capacity(struct smb_charger *chg, const union power_supply_propval *val); int smblib_set_prop_batt_status(struct smb_charger *chg, @@ -708,7 +706,7 @@ int smblib_set_prop_batt_status(struct smb_charger *chg, int smblib_set_prop_system_temp_level(struct smb_charger *chg, const union power_supply_propval *val); int smblib_set_prop_input_current_limited(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_get_prop_dc_present(struct smb_charger *chg, union power_supply_propval *val); @@ -718,14 +716,8 @@ int smblib_get_prop_dc_current_max(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_dc_current_max(struct smb_charger *chg, const union power_supply_propval *val); -int smblib_get_prop_dc_voltage_now(struct smb_charger *chg, - union power_supply_propval *val); int smblib_get_prop_dc_voltage_max(struct smb_charger *chg, union power_supply_propval *val); -int smblib_get_prop_voltage_wls_output(struct smb_charger *chg, - union power_supply_propval *val); -int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, - const union power_supply_propval *val); int smblib_set_prop_dc_reset(struct smb_charger *chg); int smblib_get_prop_usb_present(struct smb_charger *chg, union power_supply_propval *val); @@ -740,7 +732,7 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, int smblib_get_prop_usb_voltage_max_design(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_usb_voltage_max_limit(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_get_prop_usb_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_low_power(struct smb_charger *chg, @@ -748,60 +740,61 @@ int smblib_get_prop_low_power(struct smb_charger *chg, int smblib_get_prop_usb_current_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_usb_prop_typec_mode(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_scope(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_typec_select_rp(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_typec_power_role(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_input_current_settled(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_pe_start(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_charger_temp(struct smb_charger *chg, - union power_supply_propval *val); -int smblib_get_prop_die_health(struct smb_charger *chg); + int *val); int smblib_get_die_health(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_prop_smb_health(struct smb_charger *chg); int smblib_get_prop_connector_health(struct smb_charger *chg); int smblib_set_prop_thermal_overheat(struct smb_charger *chg, int therm_overheat); int smblib_get_skin_temp_status(struct smb_charger *chg); int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, - union power_supply_propval *val); + int *val); +int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, + int val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_sdp_current_max(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_pd_voltage_min(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_typec_power_role(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_typec_select_rp(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_pd_active(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_ship_mode(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg, - const union power_supply_propval *val); + int val); void smblib_suspend_on_debug_battery(struct smb_charger *chg); int smblib_rerun_apsd_if_required(struct smb_charger *chg); void smblib_rerun_apsd(struct smb_charger *chg); int smblib_get_prop_fcc_delta(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_thermal_threshold(struct smb_charger *chg, u16 addr, int *val); int smblib_dp_dm(struct smb_charger *chg, int val); int smblib_disable_hw_jeita(struct smb_charger *chg, bool disable); @@ -810,18 +803,15 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua); int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua); int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, - const union power_supply_propval *val); + int val); int smblib_typec_port_type_set(const struct typec_capability *cap, enum typec_port_type type); int smblib_get_prop_from_bms(struct smb_charger *chg, - enum power_supply_property psp, - union power_supply_propval *val); + int channel, int *val); int smblib_get_iio_channel(struct smb_charger *chg, const char *propname, struct iio_channel **chan); -int smblib_read_iio_channel(struct smb_charger *chg, struct iio_channel *chan, - int div, int *data); int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable); int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode); enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, @@ -833,9 +823,19 @@ void smblib_hvdcp_exit_config(struct smb_charger *chg); void smblib_apsd_enable(struct smb_charger *chg, bool enable); int smblib_force_vbus_voltage(struct smb_charger *chg, u8 val); int smblib_get_irq_status(struct smb_charger *chg, - union power_supply_propval *val); + int *val); int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); +int smb5_iio_get_prop(struct smb_charger *chg, int channel, int *val); +int smb5_iio_set_prop(struct smb_charger *chg, int channel, int val); + +int smblib_set_prop_voltage_wls_output(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_get_prop_voltage_wls_output(struct smb_charger *chg, + union power_supply_propval *val); +int smblib_get_prop_dc_voltage_now(struct smb_charger *chg, + union power_supply_propval *val); + #endif /* __SMB5_CHARGER_H */ diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index e05ab75f459a..665cc61eff86 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "step-chg-jeita.h" #include "battery-profile-loader.h" @@ -67,12 +69,13 @@ struct step_chg_info { struct votable *usb_icl_votable; struct wakeup_source *step_chg_ws; struct power_supply *batt_psy; - struct power_supply *bms_psy; struct power_supply *usb_psy; struct power_supply *dc_psy; struct delayed_work status_change_work; struct delayed_work get_config_work; struct notifier_block nb; + struct iio_channel *iio_chans; + struct iio_channel **iio_chan_list_qg; }; static struct step_chg_info *the_chip; @@ -95,14 +98,38 @@ static bool is_batt_available(struct step_chg_info *chip) return true; } +static const char * const step_chg_ext_iio_chan[] = { + [STEP_QG_RESISTANCE_ID] = "resistance_id", + [STEP_QG_VOLTAGE_NOW] = "voltage_now", + [STEP_QG_TEMP] = "temp", + [STEP_QG_CAPACITY] = "capacity", + [STEP_QG_VOLTAGE_OCV] = "voltage_ocv", + [STEP_QG_VOLTAGE_AVG] = "voltage_avg", +}; + static bool is_bms_available(struct step_chg_info *chip) { - if (!chip->bms_psy) - chip->bms_psy = power_supply_get_by_name("bms"); + int rc = 0; + struct iio_channel **iio_list; - if (!chip->bms_psy) + if (IS_ERR(chip->iio_chan_list_qg)) return false; + if (!chip->iio_chan_list_qg) { + iio_list = get_ext_channels(chip->dev, step_chg_ext_iio_chan, + ARRAY_SIZE(step_chg_ext_iio_chan)); + if (IS_ERR(iio_list)) { + rc = PTR_ERR(iio_list); + if (rc != -EPROBE_DEFER) { + dev_err(chip->dev, "Failed to get channels, %d\n", + rc); + chip->iio_chan_list_qg = ERR_PTR(-EINVAL); + } + return false; + } + chip->iio_chan_list_qg = iio_list; + } + return true; } @@ -150,7 +177,7 @@ static bool is_input_present(struct step_chg_info *chip) return false; } -int read_range_data_from_node(struct device_node *node, +static int read_range_data_from_node(struct device_node *node, const char *prop_str, struct range_data *ranges, int max_threshold, u32 max_value) { @@ -221,7 +248,32 @@ clean: memset(ranges, 0, tuples * sizeof(struct range_data)); return rc; } -EXPORT_SYMBOL(read_range_data_from_node); + +static int step_chg_read_iio_prop(struct step_chg_info *chip, + enum iio_type type, int iio_chan, int *val) +{ + struct iio_channel *iio_chan_list; + int rc; + + switch (type) { + case MAIN: + if (!chip->iio_chans) + return -ENODEV; + iio_chan_list = &chip->iio_chans[iio_chan]; + break; + case QG: + if (IS_ERR_OR_NULL(chip->iio_chan_list_qg)) + return -ENODEV; + iio_chan_list = chip->iio_chan_list_qg[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; +} static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) { @@ -229,8 +281,7 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) u32 max_fv_uv, max_fcc_ma; const char *batt_type_str; const __be32 *handle; - int batt_id_ohms, rc; - union power_supply_propval prop = {0, }; + int batt_id_ohms = 0, rc; handle = of_get_property(chip->dev->of_node, "qcom,battery-data", NULL); @@ -248,9 +299,10 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) if (!is_bms_available(chip)) return -ENODEV; - power_supply_get_property(chip->bms_psy, - POWER_SUPPLY_PROP_RESISTANCE_ID, &prop); - batt_id_ohms = prop.intval; + rc = step_chg_read_iio_prop(chip, QG, STEP_QG_RESISTANCE_ID, + &batt_id_ohms); + if (rc < 0) + pr_err("Failed to read batt_id rc=%d\n", rc); /* bms_psy has not yet read the batt_id */ if (batt_id_ohms < 0) @@ -296,6 +348,7 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) if (chip->soc_based_step_chg) { chip->step_chg_config->param.psy_prop = POWER_SUPPLY_PROP_CAPACITY; + chip->step_chg_config->param.iio_prop = STEP_QG_CAPACITY; chip->step_chg_config->param.prop_name = "SOC"; chip->step_chg_config->param.hysteresis = 0; } @@ -305,6 +358,7 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) if (chip->ocv_based_step_chg) { chip->step_chg_config->param.psy_prop = POWER_SUPPLY_PROP_VOLTAGE_OCV; + chip->step_chg_config->param.iio_prop = STEP_QG_VOLTAGE_OCV; chip->step_chg_config->param.prop_name = "OCV"; chip->step_chg_config->param.hysteresis = 0; chip->step_chg_config->param.use_bms = true; @@ -316,6 +370,7 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip) if (chip->vbat_avg_based_step_chg) { chip->step_chg_config->param.psy_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; + chip->step_chg_config->param.iio_prop = STEP_QG_VOLTAGE_AVG; chip->step_chg_config->param.prop_name = "VBAT_AVG"; chip->step_chg_config->param.hysteresis = 0; chip->step_chg_config->param.use_bms = true; @@ -370,7 +425,7 @@ static void get_config_work(struct work_struct *work) if (rc == -ENODEV || rc == -EBUSY) { if (chip->get_config_retry_count++ < GET_CONFIG_RETRY_COUNT) { - pr_debug("bms_psy is not ready, retry: %d\n", + pr_debug("bms is not ready, retry: %d\n", chip->get_config_retry_count); goto reschedule; } @@ -538,22 +593,19 @@ static int handle_step_chg_config(struct step_chg_info *chip) if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US) return 0; - rc = power_supply_get_property(chip->batt_psy, - POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED, &pval); - if (rc < 0) - chip->step_chg_enable = false; - else - chip->step_chg_enable = pval.intval; - if (!chip->step_chg_enable || !chip->step_chg_cfg_valid) { if (chip->fcc_votable) vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0); goto update_time; } - if (chip->step_chg_config->param.use_bms) - rc = power_supply_get_property(chip->bms_psy, - chip->step_chg_config->param.psy_prop, &pval); + if (chip->step_chg_config->param.use_bms) { + rc = step_chg_read_iio_prop(chip, QG, + chip->step_chg_config->param.iio_prop, &pval.intval); + if (rc < 0) + pr_err("Failed to read IIO prop %d rc=%d\n", + chip->step_chg_config->param.iio_prop, rc); + } else rc = power_supply_get_property(chip->batt_psy, chip->step_chg_config->param.psy_prop, &pval); @@ -612,15 +664,17 @@ update_time: static int handle_jeita(struct step_chg_info *chip) { union power_supply_propval pval = {0, }; - int rc = 0, fcc_ua = 0, fv_uv = 0; + int rc = 0, fcc_ua = 0, fv_uv = 0, data; u64 elapsed_us; - rc = power_supply_get_property(chip->batt_psy, - POWER_SUPPLY_PROP_SW_JEITA_ENABLED, &pval); - if (rc < 0) + rc = step_chg_read_iio_prop(chip, MAIN, PSY_IIO_SW_JEITA_ENABLED, + &data); + if (rc < 0) { chip->sw_jeita_enable = false; - else - chip->sw_jeita_enable = pval.intval; + pr_err("Failed to read jeita_enabled rc=%d\n", rc); + } else { + chip->sw_jeita_enable = data; + } if (!chip->sw_jeita_enable || !chip->sw_jeita_cfg_valid) { if (chip->fcc_votable) @@ -637,12 +691,16 @@ static int handle_jeita(struct step_chg_info *chip) if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US) return 0; - if (chip->jeita_fcc_config->param.use_bms) - rc = power_supply_get_property(chip->bms_psy, - chip->jeita_fcc_config->param.psy_prop, &pval); - else + if (chip->jeita_fcc_config->param.use_bms) { + rc = step_chg_read_iio_prop(chip, QG, + chip->jeita_fcc_config->param.iio_prop, &pval.intval); + if (rc < 0) + pr_err("Failed to read IIO prop %d rc=%d\n", + chip->jeita_fcc_config->param.iio_prop, rc); + } else { rc = power_supply_get_property(chip->batt_psy, chip->jeita_fcc_config->param.psy_prop, &pval); + } if (rc < 0) { pr_err("Couldn't read %s property rc=%d\n", @@ -805,8 +863,6 @@ static int step_chg_notifier_call(struct notifier_block *nb, } if ((strcmp(psy->desc->name, "bms") == 0)) { - if (chip->bms_psy == NULL) - chip->bms_psy = psy; if (!chip->config_is_read) schedule_delayed_work(&chip->get_config_work, 0); } @@ -828,8 +884,8 @@ static int step_chg_register_notifier(struct step_chg_info *chip) return 0; } -int qcom_step_chg_init(struct device *dev, - bool step_chg_enable, bool sw_jeita_enable, bool jeita_arb_en) +int qcom_step_chg_init(struct device *dev, bool step_chg_enable, + bool sw_jeita_enable, bool jeita_arb_en, struct iio_channel *iio_chans) { int rc; struct step_chg_info *chip; @@ -843,7 +899,7 @@ int qcom_step_chg_init(struct device *dev, if (!chip) return -ENOMEM; - chip->step_chg_ws = wakeup_source_register("qcom-step-chg"); + chip->step_chg_ws = wakeup_source_register(dev, "qcom-step-chg"); if (!chip->step_chg_ws) return -EINVAL; @@ -854,6 +910,8 @@ int qcom_step_chg_init(struct device *dev, chip->step_index = -EINVAL; chip->jeita_fcc_index = -EINVAL; chip->jeita_fv_index = -EINVAL; + chip->iio_chans = iio_chans; + chip->iio_chan_list_qg = NULL; chip->step_chg_config = devm_kzalloc(dev, sizeof(struct step_chg_cfg), GFP_KERNEL); @@ -861,6 +919,7 @@ int qcom_step_chg_init(struct device *dev, return -ENOMEM; chip->step_chg_config->param.psy_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; + chip->step_chg_config->param.iio_prop = STEP_QG_VOLTAGE_NOW; chip->step_chg_config->param.prop_name = "VBATT"; chip->step_chg_config->param.hysteresis = 100000; @@ -872,9 +931,11 @@ int qcom_step_chg_init(struct device *dev, return -ENOMEM; chip->jeita_fcc_config->param.psy_prop = POWER_SUPPLY_PROP_TEMP; + chip->jeita_fcc_config->param.iio_prop = STEP_QG_TEMP; chip->jeita_fcc_config->param.prop_name = "BATT_TEMP"; chip->jeita_fcc_config->param.hysteresis = 10; chip->jeita_fv_config->param.psy_prop = POWER_SUPPLY_PROP_TEMP; + chip->jeita_fv_config->param.iio_prop = STEP_QG_TEMP; chip->jeita_fv_config->param.prop_name = "BATT_TEMP"; chip->jeita_fv_config->param.hysteresis = 10; diff --git a/drivers/power/supply/qcom/step-chg-jeita.h b/drivers/power/supply/qcom/step-chg-jeita.h index 5c9c128e5f72..d33a13f71523 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.h +++ b/drivers/power/supply/qcom/step-chg-jeita.h @@ -6,10 +6,14 @@ #ifndef __STEP_CHG_H__ #define __STEP_CHG_H__ +#include +#include "smb5-iio.h" + #define MAX_STEP_CHG_ENTRIES 8 struct step_chg_jeita_param { u32 psy_prop; + u32 iio_prop; char *prop_name; int hysteresis; bool use_bms; @@ -21,10 +25,7 @@ struct range_data { u32 value; }; -int qcom_step_chg_init(struct device *dev, - bool step_chg_enable, bool sw_jeita_enable, bool jeita_arb_en); +int qcom_step_chg_init(struct device *dev, bool step_chg_enable, + bool sw_jeita_enable, bool jeita_arb_en, struct iio_channel *iio_chans); void qcom_step_chg_deinit(void); -int read_range_data_from_node(struct device_node *node, - const char *prop_str, struct range_data *ranges, - int max_threshold, u32 max_value); #endif /* __STEP_CHG_H__ */ diff --git a/include/linux/qti_power_supply.h b/include/linux/qti_power_supply.h new file mode 100644 index 000000000000..a64d756a7b83 --- /dev/null +++ b/include/linux/qti_power_supply.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef __QTI_POWER_SUPPLY_H_ +#define __QTI_POWER_SUPPLY_H_ + +#define QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER 7 +#define QTI_POWER_SUPPLY_TYPE_USB_HVDCP 20 +#define QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3 21 +#define QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5 22 +#define QTI_POWER_SUPPLY_TYPE_USB_FLOAT 23 + +enum { + QTI_POWER_SUPPLY_CHARGER_SEC_NONE = 0, + QTI_POWER_SUPPLY_CHARGER_SEC_CP, + QTI_POWER_SUPPLY_CHARGER_SEC_PL, + QTI_POWER_SUPPLY_CHARGER_SEC_CP_PL, +}; + +enum { + QTI_POWER_SUPPLY_CP_NONE = 0, + QTI_POWER_SUPPLY_CP_HVDCP3, + QTI_POWER_SUPPLY_CP_HVDCP3P5, + QTI_POWER_SUPPLY_CP_PPS, + QTI_POWER_SUPPLY_CP_WIRELESS, +}; + +enum { + QTI_POWER_SUPPLY_CONNECTOR_TYPEC, + QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB, +}; + +enum { + QC_CTM_DISABLE = BIT(0), + QC_THERMAL_BALANCE_DISABLE = BIT(1), + QC_INOV_THERMAL_DISABLE = BIT(2), +}; + +enum { + QTI_POWER_SUPPLY_PD_INACTIVE = 0, + QTI_POWER_SUPPLY_PD_ACTIVE, + QTI_POWER_SUPPLY_PD_PPS_ACTIVE, +}; + +enum { + QTI_POWER_SUPPLY_DP_DM_UNKNOWN = 0, + QTI_POWER_SUPPLY_DP_DM_PREPARE = 1, + QTI_POWER_SUPPLY_DP_DM_UNPREPARE = 2, + QTI_POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3 = 3, + QTI_POWER_SUPPLY_DP_DM_DP_PULSE = 4, + QTI_POWER_SUPPLY_DP_DM_DM_PULSE = 5, + QTI_POWER_SUPPLY_DP_DM_DP0P6_DMF = 6, + QTI_POWER_SUPPLY_DP_DM_DP0P6_DM3P3 = 7, + QTI_POWER_SUPPLY_DP_DM_DPF_DMF = 8, + QTI_POWER_SUPPLY_DP_DM_DPR_DMR = 9, + QTI_POWER_SUPPLY_DP_DM_HVDCP3_SUPPORTED = 10, + QTI_POWER_SUPPLY_DP_DM_ICL_DOWN = 11, + QTI_POWER_SUPPLY_DP_DM_ICL_UP = 12, + QTI_POWER_SUPPLY_DP_DM_FORCE_5V = 13, + QTI_POWER_SUPPLY_DP_DM_FORCE_9V = 14, + QTI_POWER_SUPPLY_DP_DM_FORCE_12V = 15, + QTI_POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5 = 16, +}; + +/* Indicates USB Type-C CC connection status */ +enum power_supply_typec_mode { + QTI_POWER_SUPPLY_TYPEC_NONE, + + /* Acting as source */ + QTI_POWER_SUPPLY_TYPEC_SINK, /* Rd only */ + QTI_POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE, /* Rd/Ra */ + QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY,/* Rd/Rd */ + QTI_POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER, /* Ra/Ra */ + QTI_POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY, /* Ra only */ + + /* Acting as sink */ + QTI_POWER_SUPPLY_TYPEC_SOURCE_DEFAULT, /* Rp default */ + QTI_POWER_SUPPLY_TYPEC_SOURCE_MEDIUM, /* Rp 1.5A */ + QTI_POWER_SUPPLY_TYPEC_SOURCE_HIGH, /* Rp 3A */ + QTI_POWER_SUPPLY_TYPEC_NON_COMPLIANT, +}; + +enum power_supply_typec_src_rp { + QTI_POWER_SUPPLY_TYPEC_SRC_RP_STD, + QTI_POWER_SUPPLY_TYPEC_SRC_RP_1P5A, + QTI_POWER_SUPPLY_TYPEC_SRC_RP_3A +}; + +/* Parallel output connection topology */ +enum { + QTI_POWER_SUPPLY_PL_OUTPUT_NONE, + QTI_POWER_SUPPLY_PL_OUTPUT_VPH, + QTI_POWER_SUPPLY_PL_OUTPUT_VBAT, +}; + +enum { + QTI_POWER_SUPPLY_PL_NONE, + QTI_POWER_SUPPLY_PL_USBIN_USBIN, + QTI_POWER_SUPPLY_PL_USBIN_USBIN_EXT, + QTI_POWER_SUPPLY_PL_USBMID_USBMID, +}; + +enum { + QTI_POWER_SUPPLY_PL_STACKED_BATFET, + QTI_POWER_SUPPLY_PL_NON_STACKED_BATFET, +}; + +enum power_supply_typec_power_role { + QTI_POWER_SUPPLY_TYPEC_PR_NONE, /* CC lines in high-Z */ + QTI_POWER_SUPPLY_TYPEC_PR_DUAL, + QTI_POWER_SUPPLY_TYPEC_PR_SINK, + QTI_POWER_SUPPLY_TYPEC_PR_SOURCE, +}; + +#endif /* __QTI_POWER_SUPPLY_H_ */