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_ */