power: supply: qcom: Add support to make SMBLITE charger GKI compliant

SMBLITE charger drivers and their helper files use several power supply
properties on msm-4.19 which cannot be supported on msm-5.4 due to the
need for GKI compliance. Add support for main charger to register
as an IIO device with individual channels under it corresponding to
missing power supply properties from msm-4.19.

Change-Id: I397ed52d2fa822c7f93616090e15b109435d9657
Signed-off-by: Ashish Chavan <ashichav@codeaurora.org>
This commit is contained in:
Ashish Chavan 2020-12-16 11:06:16 +05:30
commit e76f8318ec
5 changed files with 774 additions and 635 deletions

View file

@ -6,7 +6,8 @@ obj-$(CONFIG_QPNP_QG) += qcom-qpnp-qg.o
qcom-qpnp-qg-y += qpnp-qg.o battery-profile-loader.o pmic-voter.o qg-util.o qg-soc.o qg-sdam.o qg-battery-profile.o qg-profile-lib.o fg-alg.o
obj-$(CONFIG_SMB1398_CHARGER) += qcom-smb1398-charger.o
qcom-smb1398-charger-y += smb1398-charger.o pmic-voter.o
obj-$(CONFIG_QPNP_SMBLITE) += step-chg-jeita.o battery.o qpnp-smblite.o smblite-lib.o pmic-voter.o storm-watch.o schgm-falshlite.o
obj-$(CONFIG_QPNP_SMBLITE) += qpnp-smblite-main.o
qpnp-smblite-main-y += step-chg-jeita.o battery.o qpnp-smblite.o smblite-lib.o pmic-voter.o storm-watch.o battery-profile-loader.o schgm-flashlite.o smblite-iio.o
obj-$(CONFIG_SMB1355_SLAVE_CHARGER) += qcom-smb1355-charger.o
qcom-smb1355-charger-y += smb1355-charger.o pmic-voter.o
obj-$(CONFIG_SMB1390_CHARGE_PUMP_PSY) += smb1390-charger-psy.o pmic-voter.o

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
*/
#include <linux/debugfs.h>
@ -11,15 +11,16 @@
#include <linux/regmap.h>
#include <linux/power_supply.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/log2.h>
#include <linux/qpnp/qpnp-revid.h>
#include <linux/iio/consumer.h>
#include <linux/pmic-voter.h>
#include <linux/usb/typec.h>
#include "smblite-reg.h"
#include "smblite-lib.h"
#include "smb5-iio.h"
#include "schgm-flashlite.h"
static struct power_supply_desc usb_psy_desc;
@ -71,7 +72,6 @@ static struct smb_params smblite_params = {
struct smb_dt_props {
int usb_icl_ua;
struct device_node *revid_dev_node;
int chg_inhibit_thr_mv;
bool no_battery;
int auto_recharge_soc;
@ -89,6 +89,9 @@ struct smblite {
struct smb_charger chg;
struct dentry *dfs_root;
struct smb_dt_props dt;
unsigned int nchannels;
struct iio_channel *iio_chans;
struct iio_chan_spec *iio_chan_ids;
};
static int __debug_mask;
@ -127,38 +130,17 @@ ATTRIBUTE_GROUPS(smblite);
static int smblite_chg_config_init(struct smblite *chip)
{
struct smb_charger *chg = &chip->chg;
struct pmic_revid_data *pmic_rev_id;
struct device_node *revid_dev_node, *node = chg->dev->of_node;
int subtype = (u8)of_device_get_match_data(chg->dev);
u8 val;
int rc = 0;
revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
if (!revid_dev_node) {
pr_err("Missing qcom,pmic-revid property\n");
return -EINVAL;
}
pmic_rev_id = get_revid_data(revid_dev_node);
if (IS_ERR_OR_NULL(pmic_rev_id)) {
/*
* the revid peripheral must be registered, any failure
* here only indicates that the rev-id module has not
* probed yet.
*/
rc = -EPROBE_DEFER;
goto out;
}
switch (pmic_rev_id->pmic_subtype) {
case PM2250_SUBTYPE:
switch (subtype) {
case PM2250:
chg->wa_flags |= WEAK_ADAPTER_WA;
if (pmic_rev_id->rev4 < 2)
chg->wa_flags |= FLASH_DIE_TEMP_DERATE_WA;
break;
default:
pr_err("Unsupported PMIC subtype=%d\n",
pmic_rev_id->pmic_subtype);
break;
pr_err("Unsupported PMIC subtype=%d\n", subtype);
return -EINVAL;
}
rc = smblite_lib_read(chg, DCDC_LDO_CFG_REG, &val);
@ -172,8 +154,6 @@ static int smblite_chg_config_init(struct smblite *chip)
chg->param = smblite_params;
chg->name = "PM2250_charger";
out:
of_node_put(revid_dev_node);
return rc;
}
@ -374,18 +354,18 @@ static enum power_supply_property smblite_usb_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_SDP_CURRENT_MAX,
POWER_SUPPLY_PROP_TYPE,
POWER_SUPPLY_PROP_TYPEC_MODE,
POWER_SUPPLY_PROP_TYPEC_POWER_ROLE,
POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
POWER_SUPPLY_PROP_HW_CURRENT_MAX,
POWER_SUPPLY_PROP_REAL_TYPE,
POWER_SUPPLY_PROP_CONNECTOR_TYPE,
POWER_SUPPLY_PROP_SCOPE,
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
};
static enum power_supply_usb_type smblite_usb_psy_supported_types[] = {
POWER_SUPPLY_USB_TYPE_UNKNOWN,
POWER_SUPPLY_USB_TYPE_SDP,
POWER_SUPPLY_USB_TYPE_DCP,
POWER_SUPPLY_USB_TYPE_CDP,
};
static int smblite_usb_get_prop(struct power_supply *psy,
@ -395,8 +375,8 @@ static int smblite_usb_get_prop(struct power_supply *psy,
struct smblite *chip = power_supply_get_drvdata(psy);
struct smb_charger *chg = &chip->chg;
int rc = 0;
val->intval = 0;
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
rc = smblite_lib_get_prop_usb_present(chg, val);
@ -407,33 +387,9 @@ static int smblite_usb_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
rc = smblite_lib_get_prop_usb_voltage_now(chg, val);
break;
case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
rc = smblite_lib_get_charge_current(chg, &val->intval);
break;
case POWER_SUPPLY_PROP_TYPE:
val->intval = POWER_SUPPLY_TYPE_USB;
break;
case POWER_SUPPLY_PROP_REAL_TYPE:
val->intval = chg->real_charger_type;
break;
case POWER_SUPPLY_PROP_TYPEC_MODE:
rc = smblite_lib_get_usb_prop_typec_mode(chg, val);
break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
rc = smblite_lib_get_prop_typec_power_role(chg, val);
break;
case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION:
rc = smblite_lib_get_prop_typec_cc_orientation(chg, val);
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
rc = smblite_lib_get_prop_input_current_settled(chg, val);
break;
case POWER_SUPPLY_PROP_HW_CURRENT_MAX:
rc = smblite_lib_get_hw_current_max(chg, &val->intval);
break;
case POWER_SUPPLY_PROP_CONNECTOR_TYPE:
val->intval = chg->connector_type;
break;
case POWER_SUPPLY_PROP_SCOPE:
rc = smblite_lib_get_prop_scope(chg, val);
break;
@ -443,6 +399,10 @@ static int smblite_usb_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = 5000000;
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
/* USB uses this to set SDP current */
rc = smblite_lib_get_charge_current(chg, &val->intval);
break;
default:
pr_err("get prop %d is not supported in usb\n", psp);
rc = -EINVAL;
@ -450,7 +410,7 @@ static int smblite_usb_get_prop(struct power_supply *psy,
}
if (rc < 0) {
pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
pr_debug("Couldn't get usb prop %d rc = %d\n", psp, rc);
return -ENODATA;
}
@ -481,14 +441,11 @@ static int smblite_usb_set_prop(struct power_supply *psy,
int rc = 0;
switch (psp) {
case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
rc = smblite_lib_set_prop_current_max(chg, val);
break;
case POWER_SUPPLY_PROP_REAL_TYPE:
rc = smblite_lib_set_prop_usb_type(chg, val);
break;
default:
pr_err("set prop %d is not supported\n", psp);
pr_err("usb set prop %d is not supported\n", psp);
rc = -EINVAL;
break;
}
@ -499,15 +456,14 @@ static int smblite_usb_set_prop(struct power_supply *psy,
static int smblite_usb_prop_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
int rc = 0;
switch (psp) {
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
return 1;
default:
rc = 0;
break;
}
return rc;
return 0;
}
static struct power_supply_desc usb_psy_desc = {
@ -517,7 +473,9 @@ static struct power_supply_desc usb_psy_desc = {
.num_properties = ARRAY_SIZE(smblite_usb_props),
.get_property = smblite_usb_get_prop,
.set_property = smblite_usb_set_prop,
.usb_types = smblite_usb_psy_supported_types,
.property_is_writeable = smblite_usb_prop_is_writeable,
.num_usb_types = ARRAY_SIZE(smblite_usb_psy_supported_types),
};
static int smblite_init_usb_psy(struct smblite *chip)
@ -538,185 +496,15 @@ static int smblite_init_usb_psy(struct smblite *chip)
return 0;
}
/*****************************
* USB MAIN PSY REGISTRATION *
*****************************/
static enum power_supply_property smblite_usb_main_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_TYPE,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
POWER_SUPPLY_PROP_FCC_DELTA,
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_FLASH_TRIGGER,
POWER_SUPPLY_PROP_FLASH_ACTIVE,
};
static int smblite_usb_main_get_prop(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct smblite *chip = power_supply_get_drvdata(psy);
struct smb_charger *chg = &chip->chg;
int rc = 0;
switch (psp) {
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
rc = smblite_lib_get_charge_param(chg, &chg->param.fv,
&val->intval);
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
rc = smblite_lib_get_charge_param(chg, &chg->param.fcc,
&val->intval);
break;
case POWER_SUPPLY_PROP_TYPE:
val->intval = POWER_SUPPLY_TYPE_MAIN;
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
rc = smblite_lib_get_prop_input_current_settled(chg, val);
break;
case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED:
rc = smblite_lib_get_prop_input_voltage_settled(chg, val);
break;
case POWER_SUPPLY_PROP_FCC_DELTA:
val->intval = 0;
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
rc = smblite_lib_get_icl_current(chg, &val->intval);
break;
case POWER_SUPPLY_PROP_FLASH_TRIGGER:
rc = schgm_flashlite_get_vreg_ok(chg, &val->intval);
break;
case POWER_SUPPLY_PROP_FLASH_ACTIVE:
val->intval = chg->flash_active;
break;
default:
pr_debug("get prop %d is not supported in usb-main\n", psp);
rc = -EINVAL;
break;
}
if (rc < 0)
pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
return rc;
}
static int smblite_usb_main_set_prop(struct power_supply *psy,
enum power_supply_property psp,
const union power_supply_propval *val)
{
struct smblite *chip = power_supply_get_drvdata(psy);
struct smb_charger *chg = &chip->chg;
int rc = 0, icl_ua;
union power_supply_propval pval = {0, };
switch (psp) {
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
rc = smblite_lib_set_charge_param(chg, &chg->param.fv,
val->intval);
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
rc = smblite_lib_set_charge_param(chg, &chg->param.fcc,
val->intval);
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
rc = smblite_lib_set_icl_current(chg, val->intval);
break;
case POWER_SUPPLY_PROP_FLASH_ACTIVE:
if (chg->flash_active != val->intval) {
chg->flash_active = val->intval;
rc = smblite_lib_get_prop_usb_present(chg, &pval);
if (rc < 0)
pr_err("Failed to get USB present status rc=%d\n",
rc);
if (!pval.intval) {
/* vote 100ma when usb is not present*/
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER,
true, USBIN_100UA);
} else if (chg->flash_active) {
icl_ua = get_effective_result_locked(
chg->usb_icl_votable);
if (icl_ua >= USBIN_400UA) {
vote(chg->usb_icl_votable,
FLASH_ACTIVE_VOTER,
true, icl_ua - USBIN_300UA);
}
} else {
vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER,
false, 0);
}
pr_debug("flash_active=%d usb_present=%d icl=%d\n",
chg->flash_active, pval.intval,
get_effective_result_locked(
chg->usb_icl_votable));
}
break;
default:
pr_err("set prop %d is not supported\n", psp);
rc = -EINVAL;
break;
}
return rc;
}
static int smblite_usb_main_prop_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
int rc = 0;
switch (psp) {
default:
rc = 0;
break;
}
return rc;
}
static const struct power_supply_desc usb_main_psy_desc = {
.name = "main",
.type = POWER_SUPPLY_TYPE_MAIN,
.properties = smblite_usb_main_props,
.num_properties = ARRAY_SIZE(smblite_usb_main_props),
.get_property = smblite_usb_main_get_prop,
.set_property = smblite_usb_main_set_prop,
.property_is_writeable = smblite_usb_main_prop_is_writeable,
};
static int smblite_init_usb_main_psy(struct smblite *chip)
{
struct power_supply_config usb_main_cfg = {};
struct smb_charger *chg = &chip->chg;
usb_main_cfg.drv_data = chip;
usb_main_cfg.of_node = chg->dev->of_node;
chg->usb_main_psy = devm_power_supply_register(chg->dev,
&usb_main_psy_desc,
&usb_main_cfg);
if (IS_ERR(chg->usb_main_psy)) {
pr_err("Couldn't register USB main power supply\n");
return PTR_ERR(chg->usb_main_psy);
}
return 0;
}
/*************************
* BATT PSY REGISTRATION *
*************************/
static enum power_supply_property smblite_batt_props[] = {
POWER_SUPPLY_PROP_INPUT_SUSPEND,
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CHARGER_TEMP,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CURRENT_NOW,
@ -725,22 +513,14 @@ static enum power_supply_property smblite_batt_props[] = {
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED,
POWER_SUPPLY_PROP_SW_JEITA_ENABLED,
POWER_SUPPLY_PROP_CHARGE_DONE,
POWER_SUPPLY_PROP_SET_SHIP_MODE,
POWER_SUPPLY_PROP_DIE_HEALTH,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_RECHARGE_SOC,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
POWER_SUPPLY_PROP_FORCE_RECHARGE,
POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
};
#define DEBUG_ACCESSORY_TEMP_DECIDEGC 250
@ -761,9 +541,6 @@ static int smblite_batt_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_PRESENT:
rc = smblite_lib_get_prop_batt_present(chg, val);
break;
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
rc = smblite_lib_get_prop_input_suspend(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGE_TYPE:
rc = smblite_lib_get_prop_batt_charge_type(chg, val);
break;
@ -776,25 +553,16 @@ static int smblite_batt_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
rc = smblite_lib_get_prop_system_temp_level_max(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGER_TEMP:
rc = smblite_lib_get_prop_charger_temp(chg, val);
break;
case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
val->intval = chg->step_chg_enabled;
break;
case POWER_SUPPLY_PROP_SW_JEITA_ENABLED:
val->intval = 1;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_VOLTAGE_NOW, val);
SMB5_QG_VOLTAGE_NOW, &val->intval);
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = get_client_vote(chg->fv_votable,
BATT_PROFILE_VOTER);
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
rc = smblite_lib_get_batt_current_now(chg, val);
rc = smblite_lib_get_batt_current_now(chg, &val->intval);
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
val->intval = get_client_vote(chg->fcc_votable,
@ -807,56 +575,37 @@ static int smblite_batt_get_prop(struct power_supply *psy,
rc = smblite_lib_get_prop_batt_iterm(chg, val);
break;
case POWER_SUPPLY_PROP_TEMP:
if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY)
if (chg->typec_mode == QTI_POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY)
val->intval = DEBUG_ACCESSORY_TEMP_DECIDEGC;
else
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_TEMP, val);
SMB5_QG_TEMP, &val->intval);
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CHARGE_DONE:
rc = smblite_lib_get_prop_batt_charge_done(chg, val);
break;
case POWER_SUPPLY_PROP_SET_SHIP_MODE:
/* Not in ship mode as long as device is active */
val->intval = 0;
break;
case POWER_SUPPLY_PROP_DIE_HEALTH:
rc = smblite_lib_get_die_health(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_CHARGE_COUNTER, val);
SMB5_QG_CHARGE_COUNTER, &val->intval);
break;
case POWER_SUPPLY_PROP_CYCLE_COUNT:
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_CYCLE_COUNT, val);
break;
case POWER_SUPPLY_PROP_RECHARGE_SOC:
val->intval = chg->auto_recharge_soc;
SMB5_QG_CYCLE_COUNT, &val->intval);
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_CHARGE_FULL, val);
SMB5_QG_CHARGE_FULL, &val->intval);
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, val);
SMB5_QG_CHARGE_FULL_DESIGN, &val->intval);
break;
case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
rc = smblite_lib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, val);
break;
case POWER_SUPPLY_PROP_FORCE_RECHARGE:
val->intval = 0;
break;
case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
val->intval = chg->fcc_stepper_enable;
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
rc = smblite_lib_get_prop_input_current_limited(chg, val);
SMB5_QG_TIME_TO_FULL_NOW, &val->intval);
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
/* For battery, INPUT_CURRENT_LIMIT equates to INPUT_SUSPEND */
rc = smblite_lib_get_prop_input_suspend(chg, &val->intval);
break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
@ -864,7 +613,7 @@ static int smblite_batt_get_prop(struct power_supply *psy,
}
if (rc < 0) {
pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
pr_debug("Couldn't get batt prop %d rc = %d\n", psp, rc);
return -ENODATA;
}
@ -882,9 +631,6 @@ static int smblite_batt_set_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_STATUS:
rc = smblite_lib_set_prop_batt_status(chg, val);
break;
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
rc = smblite_lib_set_prop_input_suspend(chg, val);
break;
case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
rc = smblite_lib_set_prop_system_temp_level(chg, val);
break;
@ -895,39 +641,12 @@ static int smblite_batt_set_prop(struct power_supply *psy,
chg->batt_profile_fv_uv = val->intval;
vote(chg->fv_votable, BATT_PROFILE_VOTER, true, val->intval);
break;
case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
chg->step_chg_enabled = !!val->intval;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
chg->batt_profile_fcc_ua = val->intval;
vote(chg->fcc_votable, BATT_PROFILE_VOTER, true, val->intval);
break;
case POWER_SUPPLY_PROP_SET_SHIP_MODE:
/* Not in ship mode as long as the device is active */
if (!val->intval)
break;
if (chg->pl.psy)
power_supply_set_property(chg->pl.psy,
POWER_SUPPLY_PROP_SET_SHIP_MODE, val);
rc = smblite_lib_set_prop_ship_mode(chg, val);
break;
case POWER_SUPPLY_PROP_DIE_HEALTH:
power_supply_changed(chg->batt_psy);
break;
case POWER_SUPPLY_PROP_RECHARGE_SOC:
rc = smblite_lib_set_prop_rechg_soc_thresh(chg, val);
break;
case POWER_SUPPLY_PROP_FORCE_RECHARGE:
/* toggle charging to force recharge */
vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER,
true, 0);
/* charge disable delay */
msleep(50);
vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER,
false, 0);
break;
case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
chg->fcc_stepper_enable = val->intval;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
rc = smblite_lib_set_prop_input_suspend(chg, val->intval);
break;
default:
rc = -EINVAL;
@ -943,11 +662,11 @@ static int smblite_batt_prop_is_writeable(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
case POWER_SUPPLY_PROP_CAPACITY:
case POWER_SUPPLY_PROP_DIE_HEALTH:
case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
rc = 1;
break;
default:
@ -992,7 +711,6 @@ static int smblite_init_batt_psy(struct smblite *chip)
***************************/
static int smblite_configure_typec(struct smb_charger *chg)
{
union power_supply_propval pval = {0, };
int rc;
u8 val = 0;
@ -1008,8 +726,8 @@ static int smblite_configure_typec(struct smb_charger *chg)
* detection by disabling/enabling typeC mode.
*/
if (val & TYPEC_LEGACY_CABLE_STATUS_BIT) {
pval.intval = POWER_SUPPLY_TYPEC_PR_NONE;
smblite_lib_set_prop_typec_power_role(chg, &pval);
rc = smblite_lib_set_prop_typec_power_role(chg,
QTI_POWER_SUPPLY_TYPEC_PR_NONE);
if (rc < 0) {
dev_err(chg->dev, "Couldn't disable TYPEC rc=%d\n", rc);
return rc;
@ -1018,8 +736,8 @@ static int smblite_configure_typec(struct smb_charger *chg)
/* delay before enabling typeC */
msleep(50);
pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
smblite_lib_set_prop_typec_power_role(chg, &pval);
rc = smblite_lib_set_prop_typec_power_role(chg,
QTI_POWER_SUPPLY_TYPEC_PR_DUAL);
if (rc < 0) {
dev_err(chg->dev, "Couldn't enable TYPEC rc=%d\n", rc);
return rc;
@ -1139,7 +857,6 @@ static int smblite_configure_recharging(struct smblite *chip)
{
int rc = 0;
struct smb_charger *chg = &chip->chg;
union power_supply_propval pval;
/* Configure VBATT-based or automatic recharging */
rc = smblite_lib_masked_write(chg, CHGR_RECHG_CFG_REG, RECHG_MASK,
@ -1184,8 +901,8 @@ static int smblite_configure_recharging(struct smblite *chip)
/* program the auto-recharge threshold */
if (chip->dt.auto_recharge_soc != -EINVAL) {
pval.intval = chip->dt.auto_recharge_soc;
rc = smblite_lib_set_prop_rechg_soc_thresh(chg, &pval);
rc = smblite_lib_set_prop_rechg_soc_thresh(chg,
chip->dt.auto_recharge_soc);
if (rc < 0) {
dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n",
rc);
@ -1213,9 +930,9 @@ static int smblite_init_connector_type(struct smb_charger *chg)
pr_debug("Connector type=%s\n", type ? "Micro USB" : "TypeC");
if (type) {
chg->connector_type = POWER_SUPPLY_CONNECTOR_MICRO_USB;
chg->connector_type = QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB;
} else {
chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC;
chg->connector_type = QTI_POWER_SUPPLY_CONNECTOR_TYPEC;
rc = smblite_configure_typec(chg);
if (rc < 0) {
dev_err(chg->dev,
@ -1234,7 +951,7 @@ static int smblite_init_otg(struct smblite *chip)
chg->usb_id_gpio = chg->usb_id_irq = -EINVAL;
if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC)
if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC)
return 0;
if (of_find_property(chg->dev->of_node, "qcom,usb-id-gpio", NULL))
@ -1442,7 +1159,6 @@ static int smblite_init_hw(struct smblite *chip)
static int smblite_post_init(struct smblite *chip)
{
struct smb_charger *chg = &chip->chg;
union power_supply_propval pval;
int rc;
/*
@ -1452,10 +1168,10 @@ static int smblite_post_init(struct smblite *chip)
*/
rerun_election(chg->usb_icl_votable);
if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) {
if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) {
/* configure power role for dual-role */
pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
rc = smblite_lib_set_prop_typec_power_role(chg, &pval);
rc = smblite_lib_set_prop_typec_power_role(chg,
QTI_POWER_SUPPLY_TYPEC_PR_DUAL);
if (rc < 0) {
dev_err(chg->dev, "Couldn't configure DRP role rc=%d\n",
rc);
@ -1485,9 +1201,7 @@ static int smblite_determine_initial_status(struct smblite *chip)
return rc;
}
if (chg->bms_psy)
smblite_lib_suspend_on_debug_battery(chg);
smblite_lib_suspend_on_debug_battery(chg);
smblite_usb_plugin_irq_handler(0, &irq_data);
smblite_typec_attach_detach_irq_handler(0, &irq_data);
smblite_typec_state_change_irq_handler(0, &irq_data);
@ -1498,7 +1212,7 @@ static int smblite_determine_initial_status(struct smblite *chip)
smblite_typec_or_rid_detection_change_irq_handler(0, &irq_data);
if (chg->usb_id_gpio > 0 &&
chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB)
smblite_usb_id_irq_handler(0, chg);
return 0;
@ -1884,7 +1598,7 @@ static int smblite_show_charger_status(struct smblite *chip)
pr_info("SMBLITE: Mode=%s Conn=%s USB Present=%d Battery present=%d health=%d charge=%d\n",
chg->ldo_mode ? "LDO" : "SMBC",
(chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) ?
(chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC) ?
"TYPEC" : "uUSB", usb_present, batt_present,
batt_health, batt_charge_type);
return rc;
@ -1904,7 +1618,6 @@ static int smblite_init_typec_class(struct smblite *chip)
chg->typec_caps.data = TYPEC_PORT_DRD;
chg->typec_partner_desc.usb_pd = false;
chg->typec_partner_desc.accessory = TYPEC_ACCESSORY_NONE;
chg->typec_caps.port_type_set = smblite_lib_typec_port_type_set;
chg->typec_caps.revision = 0x0130;
chg->typec_port = typec_register_port(chg->dev, &chg->typec_caps);
@ -1917,17 +1630,162 @@ static int smblite_init_typec_class(struct smblite *chip)
return rc;
}
static int smblite_of_xlate(struct iio_dev *indio_dev,
const struct of_phandle_args *iiospec)
{
struct smblite *iio_chip = iio_priv(indio_dev);
struct iio_chan_spec *iio_chan = iio_chip->iio_chan_ids;
int i;
for (i = 0; i < iio_chip->nchannels; i++, iio_chan++)
if (iio_chan->channel == iiospec->args[0])
return i;
return -EINVAL;
}
static int smblite_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask)
{
struct smblite *iio_chip = iio_priv(indio_dev);
struct smb_charger *chg = &iio_chip->chg;
return smblite_iio_get_prop(chg, chan->channel, val);
}
static int smblite_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val, int val2,
long mask)
{
struct smblite *iio_chip = iio_priv(indio_dev);
struct smb_charger *chg = &iio_chip->chg;
return smblite_iio_set_prop(chg, chan->channel, val);
}
static const struct iio_info smblite_iio_info = {
.read_raw = smblite_read_raw,
.write_raw = smblite_write_raw,
.of_xlate = smblite_of_xlate,
};
static int smblite_direct_iio_read(struct device *dev, int iio_chan_no, int *val)
{
struct smblite *chip = dev_get_drvdata(dev);
struct smb_charger *chg = &chip->chg;
int rc;
rc = smblite_iio_get_prop(chg, iio_chan_no, val);
return (rc < 0) ? rc : 0;
}
static int smblite_direct_iio_write(struct device *dev, int iio_chan_no, int val)
{
struct smblite *chip = dev_get_drvdata(dev);
struct smb_charger *chg = &chip->chg;
return smblite_iio_set_prop(chg, iio_chan_no, val);
}
static int smblite_iio_init(struct smblite *chip, struct platform_device *pdev,
struct iio_dev *indio_dev)
{
struct iio_chan_spec *iio_chan;
int i, rc;
for (i = 0; i < chip->nchannels; i++) {
chip->iio_chans[i].indio_dev = indio_dev;
iio_chan = &chip->iio_chan_ids[i];
chip->iio_chans[i].channel = iio_chan;
iio_chan->channel = smb5_chans_pmic[i].channel_num;
iio_chan->datasheet_name = smb5_chans_pmic[i].datasheet_name;
iio_chan->extend_name = smb5_chans_pmic[i].datasheet_name;
iio_chan->info_mask_separate = smb5_chans_pmic[i].info_mask;
iio_chan->type = smb5_chans_pmic[i].type;
iio_chan->address = i;
}
indio_dev->dev.parent = &pdev->dev;
indio_dev->dev.of_node = pdev->dev.of_node;
indio_dev->name = "qpnp-smblite";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = chip->iio_chan_ids;
indio_dev->num_channels = chip->nchannels;
rc = devm_iio_device_register(&pdev->dev, indio_dev);
if (rc < 0)
pr_err("iio device register failed rc=%d\n", rc);
return rc;
}
static int smblite_extcon_init(struct smb_charger *chg)
{
int rc;
/* extcon registration */
chg->extcon = devm_extcon_dev_allocate(chg->dev, smblite_lib_extcon_cable);
if (IS_ERR(chg->extcon)) {
rc = PTR_ERR(chg->extcon);
dev_err(chg->dev, "failed to allocate extcon device rc=%d\n",
rc);
return rc;
}
rc = devm_extcon_dev_register(chg->dev, chg->extcon);
if (rc < 0) {
dev_err(chg->dev, "failed to register extcon device rc=%d\n",
rc);
return rc;
}
/* Support reporting polarity and speed via properties */
rc = extcon_set_property_capability(chg->extcon,
EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY);
rc |= extcon_set_property_capability(chg->extcon,
EXTCON_USB, EXTCON_PROP_USB_SS);
rc |= extcon_set_property_capability(chg->extcon,
EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY);
rc |= extcon_set_property_capability(chg->extcon,
EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
if (rc < 0)
dev_err(chg->dev,
"failed to configure extcon capabilities\n");
return rc;
}
static int smblite_probe(struct platform_device *pdev)
{
struct smblite *chip;
struct iio_dev *indio_dev;
struct smb_charger *chg;
int rc = 0;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
indio_dev->info = &smblite_iio_info;
chip = iio_priv(indio_dev);
chip->nchannels = ARRAY_SIZE(smb5_chans_pmic);
chip->iio_chans = devm_kcalloc(&pdev->dev, chip->nchannels,
sizeof(*chip->iio_chans), GFP_KERNEL);
if (!chip->iio_chans)
return -ENOMEM;
chip->iio_chan_ids = devm_kcalloc(&pdev->dev, chip->nchannels,
sizeof(*chip->iio_chan_ids), GFP_KERNEL);
if (!chip->iio_chan_ids)
return -ENOMEM;
chg = &chip->chg;
chg->iio_chans = chip->iio_chans;
chg->iio_chan_list_qg = NULL;
chg->dev = &pdev->dev;
chg->debug_mask = &__debug_mask;
chg->weak_chg_icl_ua = 500000;
@ -1942,6 +1800,10 @@ static int smblite_probe(struct platform_device *pdev)
return -EINVAL;
}
rc = smblite_iio_init(chip, pdev, indio_dev);
if (rc < 0)
return rc;
rc = smblite_chg_config_init(chip);
if (rc < 0) {
if (rc != -EPROBE_DEFER)
@ -1954,6 +1816,11 @@ static int smblite_probe(struct platform_device *pdev)
pr_err("Couldn't parse device tree rc=%d\n", rc);
return rc;
}
/* set driver data before resources request it */
platform_set_drvdata(pdev, chip);
chg->chg_param.iio_read = smblite_direct_iio_read;
chg->chg_param.iio_write = smblite_direct_iio_write;
rc = smblite_lib_init(chg);
if (rc < 0) {
@ -1961,40 +1828,9 @@ static int smblite_probe(struct platform_device *pdev)
return rc;
}
/* set driver data before resources request it */
platform_set_drvdata(pdev, chip);
/* extcon registration */
chg->extcon = devm_extcon_dev_allocate(chg->dev,
smblite_lib_extcon_cable);
if (IS_ERR(chg->extcon)) {
rc = PTR_ERR(chg->extcon);
dev_err(chg->dev, "Couldn't to allocate extcon device rc=%d\n",
rc);
rc = smblite_extcon_init(chg);
if (rc < 0)
goto cleanup;
}
rc = devm_extcon_dev_register(chg->dev, chg->extcon);
if (rc < 0) {
dev_err(chg->dev, "Couldn't to register extcon device rc=%d\n",
rc);
goto cleanup;
}
/* Support reporting polarity and speed via properties */
rc = extcon_set_property_capability(chg->extcon,
EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY);
rc |= extcon_set_property_capability(chg->extcon,
EXTCON_USB, EXTCON_PROP_USB_SS);
rc |= extcon_set_property_capability(chg->extcon,
EXTCON_USB_HOST, EXTCON_PROP_USB_TYPEC_POLARITY);
rc |= extcon_set_property_capability(chg->extcon,
EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
if (rc < 0) {
dev_err(chg->dev,
"Couldn't to configure extcon capabilities\n");
goto cleanup;
}
rc = smblite_init_hw(chip);
if (rc < 0) {
@ -2008,12 +1844,6 @@ static int smblite_probe(struct platform_device *pdev)
goto cleanup;
}
rc = smblite_init_usb_main_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize usb main psy rc=%d\n", rc);
goto cleanup;
}
rc = smblite_init_batt_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize batt psy rc=%d\n", rc);
@ -2094,13 +1924,16 @@ static void smblite_shutdown(struct platform_device *pdev)
smblite_disable_interrupts(chg);
/* configure power role for UFP */
if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC)
if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_TYPEC)
smblite_lib_masked_write(chg, TYPE_C_MODE_CFG_REG,
TYPEC_POWER_ROLE_CMD_MASK, EN_SNK_ONLY_BIT);
}
static const struct of_device_id match_table[] = {
{ .compatible = "qcom,qpnp-smblite", },
{
.compatible = "qcom,qpnp-smblite",
.data = (void *)PM2250,
},
{ },
};

View file

@ -0,0 +1,247 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021 The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/pmic-voter.h>
#include <linux/power_supply.h>
#include <linux/iio/consumer.h>
#include "smblite-lib.h"
#include "smb5-iio.h"
#include "smblite-reg.h"
#include "schgm-flashlite.h"
int smblite_iio_get_prop(struct smb_charger *chg, int channel, int *val)
{
union power_supply_propval pval = {0, };
int rc = 0;
pval.intval = 0;
*val = 0;
switch (channel) {
/* USB */
case PSY_IIO_USB_REAL_TYPE:
*val = chg->real_charger_type;
break;
case PSY_IIO_TYPEC_MODE:
rc = smblite_lib_get_usb_prop_typec_mode(chg, val);
break;
case PSY_IIO_TYPEC_POWER_ROLE:
rc = smblite_lib_get_prop_typec_power_role(chg, val);
break;
case PSY_IIO_TYPEC_CC_ORIENTATION:
rc = smblite_lib_get_prop_typec_cc_orientation(chg, val);
break;
case PSY_IIO_USB_INPUT_CURRENT_SETTLED:
rc = smblite_lib_get_prop_input_current_settled(chg, val);
break;
case PSY_IIO_CONNECTOR_TYPE:
*val = chg->connector_type;
break;
case PSY_IIO_HW_CURRENT_MAX:
rc = smblite_lib_get_hw_current_max(chg, val);
break;
/* MAIN */
case PSY_IIO_MAIN_INPUT_CURRENT_SETTLED:
rc = smblite_lib_get_prop_input_current_settled(chg, val);
if (!rc)
*val = pval.intval;
break;
case PSY_IIO_MAIN_INPUT_VOLTAGE_SETTLED:
rc = smblite_lib_get_prop_input_voltage_settled(chg, val);
break;
case PSY_IIO_FCC_DELTA:
val = 0;
break;
case PSY_IIO_FLASH_ACTIVE:
*val = chg->flash_active;
break;
case PSY_IIO_FLASH_TRIGGER:
*val = 0;
rc = schgm_flashlite_get_vreg_ok(chg, val);
break;
case PSY_IIO_CURRENT_MAX:
rc = smblite_lib_get_icl_current(chg, val);
break;
case PSY_IIO_VOLTAGE_MAX:
rc = smblite_lib_get_charge_param(chg, &chg->param.fv, val);
break;
case PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX:
rc = smblite_lib_get_charge_param(chg, &chg->param.fcc, val);
break;
case PSY_IIO_MAIN_FCC_MAX:
*val = chg->main_fcc_max;
break;
/* BATTERY */
case PSY_IIO_CHARGER_TEMP:
rc = smblite_lib_get_prop_charger_temp(chg, val);
break;
case PSY_IIO_SW_JEITA_ENABLED:
*val = 1;
break;
case PSY_IIO_PARALLEL_DISABLE:
*val = get_client_vote(chg->pl_disable_votable,
USER_VOTER);
break;
case PSY_IIO_CHARGE_DONE:
rc = smblite_lib_get_prop_batt_charge_done(chg, val);
break;
case PSY_IIO_SET_SHIP_MODE:
/* Not in ship mode as long as device is active */
*val = 0;
break;
case PSY_IIO_INPUT_CURRENT_LIMITED:
rc = smblite_lib_get_prop_input_current_limited(chg, val);
break;
case PSY_IIO_RECHARGE_SOC:
*val = chg->auto_recharge_soc;
break;
case PSY_IIO_FORCE_RECHARGE:
*val = 0;
break;
case PSY_IIO_FCC_STEPPER_ENABLE:
*val = chg->fcc_stepper_enable;
break;
case PSY_IIO_DIE_HEALTH:
rc = smblite_lib_get_die_health(chg, val);
break;
default:
pr_err("get prop %x is not supported\n", channel);
rc = -EINVAL;
break;
}
if (rc < 0) {
pr_err("Couldn't get prop %x rc = %d\n", channel, rc);
return rc;
}
return IIO_VAL_INT;
}
int smblite_iio_set_prop(struct smb_charger *chg, int channel, int val)
{
union power_supply_propval pval = {0, };
int icl_ua, rc = 0;
switch (channel) {
/* USB */
case PSY_IIO_USB_REAL_TYPE:
rc = smblite_lib_set_prop_usb_type(chg, val);
break;
case PSY_IIO_TYPEC_POWER_ROLE:
rc = smblite_lib_set_prop_typec_power_role(chg, val);
break;
/* MAIN */
case PSY_IIO_FLASH_ACTIVE:
if (chg->flash_active != val) {
chg->flash_active = val;
rc = smblite_lib_get_prop_usb_present(chg, &pval);
if (rc < 0)
pr_err("Failed to get USB present status rc=%d\n",
rc);
if (!pval.intval) {
/* vote 100ma when usb is not present*/
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER,
true, USBIN_100UA);
} else if (chg->flash_active) {
icl_ua = get_effective_result_locked(
chg->usb_icl_votable);
if (icl_ua >= USBIN_400UA) {
vote(chg->usb_icl_votable,
FLASH_ACTIVE_VOTER,
true, icl_ua - USBIN_300UA);
}
} else {
vote(chg->usb_icl_votable, FLASH_ACTIVE_VOTER,
false, 0);
}
pr_debug("flash_active=%d usb_present=%d icl=%d\n",
chg->flash_active, pval.intval,
get_effective_result_locked(
chg->usb_icl_votable));
}
break;
case PSY_IIO_VOLTAGE_MAX:
rc = smblite_lib_set_charge_param(chg, &chg->param.fv, val);
break;
case PSY_IIO_CURRENT_MAX:
rc = smblite_lib_set_icl_current(chg, val);
break;
case PSY_IIO_CONSTANT_CHARGE_CURRENT_MAX:
rc = smblite_lib_set_charge_param(chg, &chg->param.fcc, val);
break;
case PSY_IIO_MAIN_FCC_MAX:
chg->main_fcc_max = val;
rerun_election(chg->fcc_votable);
break;
/* BATTERY */
case PSY_IIO_SET_SHIP_MODE:
/* Not in ship mode as long as the device is active */
if (!val)
break;
if (chg->iio_chan_list_smb_parallel)
rc = iio_write_channel_raw(
chg->iio_chan_list_smb_parallel[SMB_SET_SHIP_MODE],
val);
rc = smblite_lib_set_prop_ship_mode(chg, val);
break;
case PSY_IIO_RECHARGE_SOC:
rc = smblite_lib_set_prop_rechg_soc_thresh(chg, val);
break;
case PSY_IIO_FORCE_RECHARGE:
/* toggle charging to force recharge */
vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER,
true, 0);
/* charge disable delay */
msleep(50);
vote(chg->chg_disable_votable, FORCE_RECHARGE_VOTER,
false, 0);
break;
case PSY_IIO_FCC_STEPPER_ENABLE:
chg->fcc_stepper_enable = val;
break;
case PSY_IIO_DIE_HEALTH:
power_supply_changed(chg->batt_psy);
break;
default:
pr_err("get prop %d is not supported\n", channel);
rc = -EINVAL;
break;
}
if (rc < 0) {
pr_err("Couldn't set prop %d rc = %d\n", channel, rc);
return rc;
}
return 0;
}
struct iio_channel **get_ext_channels(struct device *dev,
const char *const *channel_map, int size)
{
int i, rc = 0;
struct iio_channel **iio_ch_ext;
iio_ch_ext = devm_kcalloc(dev, size, sizeof(*iio_ch_ext), GFP_KERNEL);
if (!iio_ch_ext)
return ERR_PTR(-ENOMEM);
for (i = 0; i < size; i++) {
iio_ch_ext[i] = devm_iio_channel_get(dev, channel_map[i]);
if (IS_ERR(iio_ch_ext[i])) {
rc = PTR_ERR(iio_ch_ext[i]);
if (rc != -EPROBE_DEFER)
dev_err(dev, "%s channel unavailable, %d\n",
channel_map[i], rc);
return ERR_PTR(rc);
}
}
return iio_ch_ext;
}

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
*/
#ifndef __SMBLITE_LIB_H
#define __SMBLITE_LIB_H
#include <linux/alarmtimer.h>
#include <linux/ktime.h>
#include <linux/types.h>
@ -15,6 +16,7 @@
#include <linux/regulator/consumer.h>
#include <linux/extcon-provider.h>
#include <linux/usb/typec.h>
#include <linux/qti_power_supply.h>
#include "storm-watch.h"
#include "battery.h"
@ -225,6 +227,10 @@ struct smb_iio {
struct iio_channel *usbin_v_chan;
};
enum pmic_type {
PM2250,
};
struct smb_charger {
struct device *dev;
char *name;
@ -232,6 +238,9 @@ struct smb_charger {
struct smb_irq_info *irq_info;
struct smb_params param;
struct smb_iio iio;
struct iio_channel *iio_chans;
struct iio_channel **iio_chan_list_qg;
struct iio_channel **iio_chan_list_smb_parallel;
int *debug_mask;
enum smb_mode mode;
int weak_chg_icl_ua;
@ -242,8 +251,6 @@ struct smb_charger {
/* power supplies */
struct power_supply *batt_psy;
struct power_supply *usb_psy;
struct power_supply *bms_psy;
struct power_supply *usb_main_psy;
enum power_supply_type real_charger_type;
/* notifiers */
@ -297,6 +304,8 @@ struct smb_charger {
int typec_mode;
int dr_mode;
int term_vbat_uv;
int input_current_limited;
int main_fcc_max;
u32 jeita_status;
bool jeita_arb_flag;
bool typec_legacy;
@ -350,11 +359,9 @@ int smblite_lib_batch_read(struct smb_charger *chg, u16 addr, u8 *val,
int count);
int smblite_lib_get_charge_param(struct smb_charger *chg,
struct smb_chg_param *param, int *val_u);
int smblite_lib_get_usb_suspend(struct smb_charger *chg, int *suspend);
int smblite_lib_enable_charging(struct smb_charger *chg, bool enable);
int smblite_lib_set_charge_param(struct smb_charger *chg,
struct smb_chg_param *param, int val_u);
int smblite_lib_set_usb_suspend(struct smb_charger *chg, bool suspend);
irqreturn_t smblite_default_irq_handler(int irq, void *data);
irqreturn_t smblite_chg_state_change_irq_handler(int irq, void *data);
@ -373,8 +380,6 @@ irqreturn_t smblite_temp_change_irq_handler(int irq, void *data);
irqreturn_t smblite_usbin_ov_irq_handler(int irq, void *data);
irqreturn_t smblite_usb_id_irq_handler(int irq, void *data);
int smblite_lib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_batt_present(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_batt_capacity(struct smb_charger *chg,
@ -384,21 +389,21 @@ int smblite_lib_get_prop_batt_status(struct smb_charger *chg,
int smblite_lib_get_prop_batt_charge_type(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_batt_charge_done(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_batt_current_now(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_batt_health(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_system_temp_level(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_system_temp_level_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_input_current_limited(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_batt_iterm(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_input_suspend(struct smb_charger *chg,
int *val);
int smblite_lib_set_prop_input_suspend(struct smb_charger *chg,
const union power_supply_propval *val);
const int val);
int smblite_lib_set_prop_batt_capacity(struct smb_charger *chg,
const union power_supply_propval *val);
int smblite_lib_set_prop_batt_status(struct smb_charger *chg,
@ -411,67 +416,57 @@ int smblite_lib_get_prop_usb_online(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_usb_online(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_usb_suspend(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_input_current_limited(struct smb_charger *chg,
int *val);
int smblite_lib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_usb_prop_typec_mode(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_typec_cc_orientation(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_scope(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_prop_typec_power_role(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_input_current_settled(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_input_voltage_settled(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_charger_temp(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_get_prop_die_health(struct smb_charger *chg);
int smblite_lib_get_die_health(struct smb_charger *chg,
union power_supply_propval *val);
int *val);
int smblite_lib_set_prop_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblite_lib_set_prop_typec_power_role(struct smb_charger *chg,
const union power_supply_propval *val);
const int val);
int smblite_lib_set_prop_ship_mode(struct smb_charger *chg,
const union power_supply_propval *val);
const int val);
int smblite_lib_set_prop_rechg_soc_thresh(struct smb_charger *chg,
const union power_supply_propval *val);
const int val);
void smblite_lib_suspend_on_debug_battery(struct smb_charger *chg);
int smblite_lib_get_prop_fcc_delta(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_get_thermal_threshold(struct smb_charger *chg, u16 addr,
int *val);
int smblite_lib_run_aicl(struct smb_charger *chg, int type);
int smblite_lib_set_icl_current(struct smb_charger *chg, int icl_ua);
int smblite_lib_set_icl_current(struct smb_charger *chg, const int icl_ua);
int smblite_lib_get_icl_current(struct smb_charger *chg, int *icl_ua);
int smblite_lib_get_charge_current(struct smb_charger *chg,
int *total_current_ua);
int smblite_lib_get_hw_current_max(struct smb_charger *chg,
int *total_current_ua);
int smblite_lib_get_prop_pr_swap_in_progress(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
const union power_supply_propval *val);
int smblite_lib_typec_port_type_set(const struct typec_capability *cap,
enum typec_port_type type);
int smblite_lib_get_prop_from_bms(struct smb_charger *chg,
enum power_supply_property psp,
union power_supply_propval *val);
int smblite_lib_get_prop_from_bms(struct smb_charger *chg, int channel,
int *val);
int smblite_lib_get_iio_channel(struct smb_charger *chg, const char *propname,
struct iio_channel **chan);
int smblite_lib_read_iio_channel(struct smb_charger *chg,
struct iio_channel *chan, int div, int *data);
int smblite_lib_icl_override(struct smb_charger *chg,
enum icl_override_mode mode);
int smblite_lib_get_irq_status(struct smb_charger *chg,
union power_supply_propval *val);
int smblite_lib_set_prop_usb_type(struct smb_charger *chg,
const union power_supply_propval *val);
const int val);
void smblite_update_usb_desc(struct smb_charger *chg);
int smblite_lib_init(struct smb_charger *chg);
int smblite_lib_deinit(struct smb_charger *chg);
int smblite_iio_get_prop(struct smb_charger *chg, int channel, int *val);
int smblite_iio_set_prop(struct smb_charger *chg, int channel, int val);
#endif /* __SMBLITE_LIB_H */