Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e76f8318 authored by Ashish Chavan's avatar Ashish Chavan
Browse files

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: default avatarAshish Chavan <ashichav@codeaurora.org>
parent 676add95
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+230 −397

File changed.

Preview size limit exceeded, changes collapsed.

+247 −0
Original line number Diff line number Diff line
// 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;
}
+259 −196

File changed.

Preview size limit exceeded, changes collapsed.

+36 −41
Original line number Diff line number Diff line
/* 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 */