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

Commit 7bfcd4bd authored by Shyam Kumar Thella's avatar Shyam Kumar Thella Committed by Gerrit - the friendly Code Review server
Browse files

power: supply: qg: Add support to make QG driver GKI compliant



Add support for "bms" power supply which is not present in kernel 5.4
through IIO device and properties under it through individual IIO
channels under the IIO device.

Change-Id: I55c44e5db2dc4549021cb429444c7c5afa679c3a
Signed-off-by: default avatarShyam Kumar Thella <sthella@codeaurora.org>
parent 1074012e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -723,4 +723,6 @@ config CHARGER_WILCO
	  information can be found in
	  Documentation/ABI/testing/sysfs-class-power-wilco

source "drivers/power/supply/qcom/Kconfig"

endif # POWER_SUPPLY
+5 −2
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only

menuconfig QCOM_POWER_SUPPLY
	bool "Support for Qualcomm Technologies, Inc. power supply"
	depends on ARCH_QCOM
@@ -7,14 +6,18 @@ menuconfig QCOM_POWER_SUPPLY
if QCOM_POWER_SUPPLY

config QPNP_QG
	bool "QPNP Qgauge driver"
	tristate "QPNP Qgauge driver"
	depends on MFD_SPMI_PMIC
	depends on IIO
	help
	  Say Y here to enable the Qualcomm Technologies, Inc. QGauge driver
	  which uses the periodic sampling of the battery voltage and current
	  to determine the battery state-of-charge (SOC) and supports other
	  battery management features.

	  To compile this driver as a module, choose M here: the
	  module will be called qcom-qpnp-qg.

config QPNP_SMB5
	tristate "SMB5 Battery Charger"
	depends on MFD_SPMI_PMIC && IIO
+2 −1
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

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_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)		+= smb1398-charger.o pmic-voter.o
obj-$(CONFIG_SMB1355_SLAVE_CHARGER)	+= smb1355-charger.o pmic-voter.o
+23 −9
Original line number Diff line number Diff line
@@ -6,11 +6,14 @@
#define pr_fmt(fmt)	"ALG: %s: " fmt, __func__

#include <linux/err.h>
#include <linux/iio/iio.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/power_supply.h>
#include <linux/qti_power_supply.h>
#include <linux/slab.h>
#include <linux/sort.h>
#include <dt-bindings/iio/qti_power_supply_iio.h>
#include "fg-alg.h"

#define FULL_SOC_RAW		255
@@ -801,6 +804,18 @@ int cap_learning_init(struct cap_learning *cl)

/* SOH based profile loading */

static int write_int_iio_chan(struct iio_channel *iio_chan_list,
						int chan_id, int val)
{
	do {
		if (iio_chan_list->channel->channel == chan_id)
			return iio_write_channel_raw(iio_chan_list,
							val);
	} while (iio_chan_list++);

	return -ENOENT;
}

/**
 * soh_get_batt_age_level -
 * @sp: SOH profile object
@@ -834,10 +849,9 @@ static int soh_get_batt_age_level(struct soh_profile *sp, int soh,
 */
int soh_profile_update(struct soh_profile *sp, int new_soh)
{
	union power_supply_propval pval = {0, };
	int rc, batt_age_level = 0;

	if (!sp || !sp->bms_psy)
	if (!sp || !sp->bms_psy || !sp->iio_chan_list)
		return -ENODEV;

	if (new_soh <= 0)
@@ -855,9 +869,8 @@ int soh_profile_update(struct soh_profile *sp, int new_soh)
		return rc;

	if (batt_age_level != sp->last_batt_age_level) {
		pval.intval = batt_age_level;
		rc = power_supply_set_property(sp->bms_psy,
			POWER_SUPPLY_PROP_BATT_AGE_LEVEL, &pval);
		rc = write_int_iio_chan(sp->iio_chan_list,
				PSY_IIO_BATT_AGE_LEVEL, batt_age_level);
		if (rc < 0) {
			pr_err("Couldn't set batt_age_level rc=%d\n", rc);
			return rc;
@@ -886,7 +899,8 @@ int soh_profile_init(struct device *dev, struct soh_profile *sp)
{
	int rc, profile_count = 0;

	if (!dev || !sp || !sp->bp_node || !sp->bms_psy)
	if (!dev || !sp || !sp->bp_node || !sp->bms_psy ||
		!sp->iio_chan_list)
		return -ENODEV;

	rc = of_batterydata_get_aged_profile_count(sp->bp_node,
@@ -1199,7 +1213,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val)
	pr_debug("TTF: i_cc2cv=%d\n", i_cc2cv);

	/* if we are already in CV state then we can skip estimating CC */
	if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
	if (charge_type == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER)
		goto cv_estimate;

	/* estimated SOC at the CC to CV transition */
@@ -1329,14 +1343,14 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val)
cv_estimate:
	pr_debug("TTF: t_predicted_cc=%d\n", t_predicted);

	if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
	if (charge_type == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER)
		iterm = max(100, abs(iterm));
	else
		iterm = max(100, abs(iterm) + ttf->iterm_delta);

	pr_debug("TTF: iterm=%d\n", iterm);

	if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
	if (charge_type == QTI_POWER_SUPPLY_CHARGE_TYPE_TAPER)
		tau = max(MILLI_UNIT, ibatt_avg * MILLI_UNIT / iterm);
	else
		tau = max(MILLI_UNIT, i_cc2cv * MILLI_UNIT / iterm);
+1 −1
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct ttf {
struct soh_profile {
	struct device_node *bp_node;
	struct power_supply *bms_psy;
	struct iio_channel *iio_chan_list;
	struct soh_range *soh_data;
	int batt_id_kohms;
	int profile_count;
@@ -166,5 +167,4 @@ int ttf_get_time_to_full(struct ttf *ttf, int *val);
int ttf_tte_init(struct ttf *ttf);
int soh_profile_init(struct device *dev, struct soh_profile *sp);
int soh_profile_update(struct soh_profile *sp, int soh);

#endif
Loading