[PATCH] power: supply: Add enable the primary charger interface

Cixi Geng posted 1 patch 4 years ago
There is a newer version of this series
drivers/power/supply/sc2731_charger.c | 50 +++++++++++++++++++++++++--
include/linux/power_supply.h          |  1 +
2 files changed, 49 insertions(+), 2 deletions(-)
[PATCH] power: supply: Add enable the primary charger interface
Posted by Cixi Geng 4 years ago
From: Chen Yongzhi <Yongzhi.Chen@unisoc.com>

   In the case of charging multiple charging ICs,the primary
   charging IC often needs to be turned off in the fast
   charging stage, and only using the charger pump to charge,
   need to add a new power_supply_property attribute.

Signed-off-by: Chen Yongzhi <Yongzhi.Chen@unisoc.com>
---
 drivers/power/supply/sc2731_charger.c | 50 +++++++++++++++++++++++++--
 include/linux/power_supply.h          |  1 +
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/power/supply/sc2731_charger.c b/drivers/power/supply/sc2731_charger.c
index 9ac17cf7a126..64c79d5ea90f 100644
--- a/drivers/power/supply/sc2731_charger.c
+++ b/drivers/power/supply/sc2731_charger.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2018 Spreadtrum Communications Inc.
+// Copyright (C) 2022 Spreadtrum Communications Inc.
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -146,6 +146,24 @@ static int sc2731_charger_get_status(struct sc2731_charger_info *info)
 	return POWER_SUPPLY_STATUS_CHARGING;
 }
 
+static int sc2731_charger_set_status(struct sc2731_charger_info *info, int val)
+{
+	int ret;
+
+	if (!val && info->charging) {
+		sc2731_charger_stop_charge(info);
+		info->charging = false;
+	} else if (val && !info->charging) {
+		ret = sc2731_charger_start_charge(info);
+		if (ret)
+			dev_err(info->dev, "start charge failed\n");
+		else
+			info->charging = true;
+	}
+
+	return ret;
+}
+
 static int sc2731_charger_get_current(struct sc2731_charger_info *info,
 				      u32 *cur)
 {
@@ -214,6 +232,12 @@ sc2731_charger_usb_set_property(struct power_supply *psy,
 	}
 
 	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		ret = sc2731_charger_set_status(info, val->intval);
+		if (ret < 0)
+			dev_err(info->dev, "set charge status failed\n");
+		break;
+
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 		ret = sc2731_charger_set_current(info, val->intval / 1000);
 		if (ret < 0)
@@ -227,6 +251,15 @@ sc2731_charger_usb_set_property(struct power_supply *psy,
 			dev_err(info->dev, "set input current limit failed\n");
 		break;
 
+	case POWER_SUPPLY_PROP_CHARGE_ENABLED:
+		if (val->intval == true) {
+			ret = sc2731_charger_start_charge(info);
+			if (ret)
+				dev_err(info->dev, "start charge failed\n");
+		} else if (val->intval == false) {
+			sc2731_charger_stop_charge(info);
+		}
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -241,7 +274,7 @@ static int sc2731_charger_usb_get_property(struct power_supply *psy,
 {
 	struct sc2731_charger_info *info = power_supply_get_drvdata(psy);
 	int ret = 0;
-	u32 cur;
+	u32 cur, enabled = 0;
 
 	mutex_lock(&info->lock);
 
@@ -277,6 +310,16 @@ static int sc2731_charger_usb_get_property(struct power_supply *psy,
 		}
 		break;
 
+	case POWER_SUPPLY_PROP_CHARGE_ENABLED:
+		ret = regmap_read(info->regmap, info->base + SC2731_CHG_CFG0, &enabled);
+		if (ret) {
+			dev_err(info->dev, "get sc2731 charge enabled failed\n");
+			goto out;
+		}
+
+		val->intval = enabled & SC2731_CHARGER_PD;
+
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -292,8 +335,10 @@ static int sc2731_charger_property_is_writeable(struct power_supply *psy,
 	int ret;
 
 	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+	case POWER_SUPPLY_PROP_CHARGE_ENABLED:
 		ret = 1;
 		break;
 
@@ -308,6 +353,7 @@ static enum power_supply_property sc2731_usb_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
+	POWER_SUPPLY_PROP_CHARGE_ENABLED,
 };
 
 static const struct power_supply_desc sc2731_charger_desc = {
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index cb380c1d9459..1dfe194d8a5e 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -167,6 +167,7 @@ enum power_supply_property {
 	POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
 	POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
 	POWER_SUPPLY_PROP_CALIBRATE,
+	POWER_SUPPLY_PROP_CHARGE_ENABLED,
 	POWER_SUPPLY_PROP_MANUFACTURE_YEAR,
 	POWER_SUPPLY_PROP_MANUFACTURE_MONTH,
 	POWER_SUPPLY_PROP_MANUFACTURE_DAY,
-- 
2.25.1
Re: [PATCH] power: supply: Add enable the primary charger interface
Posted by kernel test robot 4 years ago
Hi Cixi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on sre-power-supply/for-next]
[also build test WARNING on v5.18-rc3 next-20220422]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Cixi-Geng/power-supply-Add-enable-the-primary-charger-interface/20220422-154432
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git for-next
config: riscv-randconfig-r042-20220422 (https://download.01.org/0day-ci/archive/20220423/202204230206.9TgyhSb1-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 5bd87350a5ae429baf8f373cb226a57b62f87280)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/a566cf23ffad8453d1e1f611086b6eda3f14515d
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Cixi-Geng/power-supply-Add-enable-the-primary-charger-interface/20220422-154432
        git checkout a566cf23ffad8453d1e1f611086b6eda3f14515d
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/power/supply/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/power/supply/sc2731_charger.c:156:13: warning: variable 'ret' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
           } else if (val && !info->charging) {
                      ^~~~~~~~~~~~~~~~~~~~~~
   drivers/power/supply/sc2731_charger.c:164:9: note: uninitialized use occurs here
           return ret;
                  ^~~
   drivers/power/supply/sc2731_charger.c:156:9: note: remove the 'if' if its condition is always true
           } else if (val && !info->charging) {
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/power/supply/sc2731_charger.c:156:13: warning: variable 'ret' is used uninitialized whenever '&&' condition is false [-Wsometimes-uninitialized]
           } else if (val && !info->charging) {
                      ^~~
   drivers/power/supply/sc2731_charger.c:164:9: note: uninitialized use occurs here
           return ret;
                  ^~~
   drivers/power/supply/sc2731_charger.c:156:13: note: remove the '&&' if its condition is always true
           } else if (val && !info->charging) {
                      ^~~~~~
>> drivers/power/supply/sc2731_charger.c:153:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
           if (!val && info->charging) {
               ^~~~~~~~~~~~~~~~~~~~~~
   drivers/power/supply/sc2731_charger.c:164:9: note: uninitialized use occurs here
           return ret;
                  ^~~
   drivers/power/supply/sc2731_charger.c:153:2: note: remove the 'if' if its condition is always false
           if (!val && info->charging) {
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/power/supply/sc2731_charger.c:151:9: note: initialize the variable 'ret' to silence this warning
           int ret;
                  ^
                   = 0
   drivers/power/supply/sc2731_charger.c:255:7: warning: variable 'ret' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
                   if (val->intval == true) {
                       ^~~~~~~~~~~~~~~~~~~
   drivers/power/supply/sc2731_charger.c:268:9: note: uninitialized use occurs here
           return ret;
                  ^~~
   drivers/power/supply/sc2731_charger.c:255:3: note: remove the 'if' if its condition is always true
                   if (val->intval == true) {
                   ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/power/supply/sc2731_charger.c:225:9: note: initialize the variable 'ret' to silence this warning
           int ret;
                  ^
                   = 0
   4 warnings generated.


vim +156 drivers/power/supply/sc2731_charger.c

   148	
   149	static int sc2731_charger_set_status(struct sc2731_charger_info *info, int val)
   150	{
   151		int ret;
   152	
 > 153		if (!val && info->charging) {
   154			sc2731_charger_stop_charge(info);
   155			info->charging = false;
 > 156		} else if (val && !info->charging) {
   157			ret = sc2731_charger_start_charge(info);
   158			if (ret)
   159				dev_err(info->dev, "start charge failed\n");
   160			else
   161				info->charging = true;
   162		}
   163	
   164		return ret;
   165	}
   166	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp