@@ -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 = {
@@ -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,