From fdbd3b02dd47f125a0976e6f0c3e892b270022a8 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Wed, 5 Jul 2023 02:39:01 +0200 Subject: [PATCH 324/464] power: supply: rk818-charger: Unify rk818-charger and rk818-battery The BSP driver is still used, but there is now a one device handling the battery/charger properties, which should confuse the userspace less. This also makes writing a power manager for the keyboard easier. Signed-off-by: Ondrej Jirman --- drivers/power/supply/Kconfig | 8 --- drivers/power/supply/Makefile | 3 +- drivers/power/supply/rk818_battery.c | 38 ++++++++++--- drivers/power/supply/rk818_charger.c | 79 ++++++++++++++++++++++------ 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index e0f9c21be031..f57fe3aa495a 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -951,14 +951,6 @@ config CHARGER_QCOM_SMB2 adds support for the SMB2 switch mode battery charger found in PMI8998 and related PMICs. -config BATTERY_RK818 - bool "RK818 Battery driver" - depends on MFD_RK808 - default n - help - If you say yes here you will get support for the battery of RK818 PMIC. - This driver can give support for Rk818 Battery Charge Interface. - config CHARGER_RK818 bool "RK818 Charger driver" depends on MFD_RK8XX diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index ca8204ce1081..adb9969dd16f 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -111,5 +111,4 @@ obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o obj-$(CONFIG_BATTERY_UG3105) += ug3105_battery.o obj-$(CONFIG_CHARGER_QCOM_SMB2) += qcom_pmi8998_charger.o -obj-$(CONFIG_BATTERY_RK818) += rk818_battery.o -obj-$(CONFIG_CHARGER_RK818) += rk818_charger.o +obj-$(CONFIG_CHARGER_RK818) += rk818_charger.o rk818_battery.o diff --git a/drivers/power/supply/rk818_battery.c b/drivers/power/supply/rk818_battery.c index cc409b7aafb5..e0e5ed0e3d2a 100644 --- a/drivers/power/supply/rk818_battery.c +++ b/drivers/power/supply/rk818_battery.c @@ -897,12 +897,10 @@ static int rk818_bat_get_charge_state(struct rk818_battery *di) return di->current_avg > 0; } -static int rk818_battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) +int rk818_battery_get_property(struct rk818_battery *di, + enum power_supply_property psp, + union power_supply_propval *val) { - struct rk818_battery *di = power_supply_get_drvdata(psy); - switch (psp) { case POWER_SUPPLY_PROP_CURRENT_NOW: val->intval = di->current_avg * 1000;/*uA*/ @@ -961,16 +959,26 @@ static int rk818_battery_get_property(struct power_supply *psy, return 0; } +EXPORT_SYMBOL_GPL(rk818_battery_get_property); + +static int rk818_battery_get_property_psy(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct rk818_battery *di = power_supply_get_drvdata(psy); + + return rk818_battery_get_property(di, psp, val); +} static const struct power_supply_desc rk818_bat_desc = { .name = "battery", .type = POWER_SUPPLY_TYPE_BATTERY, .properties = rk818_bat_props, .num_properties = ARRAY_SIZE(rk818_bat_props), - .get_property = rk818_battery_get_property, + .get_property = rk818_battery_get_property_psy, }; -static int rk818_bat_init_power_supply(struct rk818_battery *di) +static __maybe_unused int rk818_bat_init_power_supply(struct rk818_battery *di) { struct power_supply_config psy_cfg = { .drv_data = di, }; @@ -2422,7 +2430,10 @@ static void rk818_bat_power_supply_changed(struct rk818_battery *di) status = (status & CHRG_STATUS_MSK) >> 4; old_soc = di->dsoc; di->last_dsoc = di->dsoc; - power_supply_changed(di->bat); + + if (di->bat) + power_supply_changed(di->bat); + BAT_INFO("changed: dsoc=%d, rsoc=%d, v=%d, ov=%d c=%d, " "cap=%d, f=%d, st=%s, hotdie=%d\n", di->dsoc, di->rsoc, di->voltage_avg, di->voltage_ocv, @@ -3251,6 +3262,14 @@ static const struct of_device_id rk818_battery_of_match[] = { { }, }; +static struct rk818_battery* bat; + +struct rk818_battery* rk818_battery_get(void) +{ + return bat; +} +EXPORT_SYMBOL_GPL(rk818_battery_get); + static int rk818_battery_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -3291,11 +3310,13 @@ static int rk818_battery_probe(struct platform_device *pdev) return ret; } + /* ret = rk818_bat_init_power_supply(di); if (ret) { dev_err(di->dev, "rk818 power supply register failed!\n"); return ret; } + */ rk818_bat_init_info(di); rk818_bat_init_fg(di); @@ -3309,6 +3330,7 @@ static int rk818_battery_probe(struct platform_device *pdev) BAT_INFO("driver version %s\n", DRIVER_VERSION); + bat = di; return ret; } diff --git a/drivers/power/supply/rk818_charger.c b/drivers/power/supply/rk818_charger.c index 6a9f2d1a7086..16bc4686b547 100644 --- a/drivers/power/supply/rk818_charger.c +++ b/drivers/power/supply/rk818_charger.c @@ -355,14 +355,36 @@ static int rk818_charger_get_voltage_max(struct rk818_charger *cg, int *val) return 0; } +struct rk818_battery; +struct rk818_battery* rk818_battery_get(void); +int rk818_battery_get_property(struct rk818_battery *di, + enum power_supply_property psp, + union power_supply_propval *val); + static int rk818_charger_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { struct rk818_charger *cg = power_supply_get_drvdata(psy); + struct rk818_battery* di = rk818_battery_get(); unsigned reg; int ret; + switch (psp) { + case POWER_SUPPLY_PROP_CURRENT_NOW: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_CAPACITY: + case POWER_SUPPLY_PROP_TEMP: + case POWER_SUPPLY_PROP_STATUS: + case POWER_SUPPLY_PROP_CHARGE_COUNTER: + case POWER_SUPPLY_PROP_CHARGE_FULL: + if (!di) + return -ENODEV; + return rk818_battery_get_property(di, psp, val); + default:; + } + switch (psp) { case POWER_SUPPLY_PROP_ONLINE: ret = regmap_read(cg->regmap, RK818_CHRG_CTRL_REG1, ®); @@ -374,6 +396,20 @@ static int rk818_charger_get_property(struct power_supply *psy, val->intval = !!(reg & RK818_CHRG_CTRL_REG1_CHRG_EN); break; + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + ret = regmap_read(cg->regmap, RK818_CHRG_CTRL_REG1, ®); + if (ret) { + dev_err(cg->dev, "failed to read the charger state (%d)\n", ret); + return ret; + } + + if (reg & RK818_CHRG_CTRL_REG1_CHRG_EN) + val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; + else + val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE; + + return 0; + case POWER_SUPPLY_PROP_STATUS: ret = regmap_read(cg->regmap, RK818_SUP_STS_REG, ®); if (ret) @@ -480,14 +516,18 @@ static int rk818_charger_set_property(struct power_supply *psy, int ret; switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - ret = regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG1, - RK818_CHRG_CTRL_REG1_CHRG_EN, - val->intval ? RK818_CHRG_CTRL_REG1_CHRG_EN : 0); - if (ret) - dev_err(cg->dev, "failed to setup the charger (%d)\n", ret); - - return ret; + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + switch (val->intval) { + case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO: + return regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG1, + RK818_CHRG_CTRL_REG1_CHRG_EN, + RK818_CHRG_CTRL_REG1_CHRG_EN); + case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE: + return regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG1, + RK818_CHRG_CTRL_REG1_CHRG_EN, 0); + default: + return -EINVAL; + } case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: return rk818_charger_set_voltage_max(cg, val->intval); @@ -506,7 +546,7 @@ static int rk818_charger_prop_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: - case POWER_SUPPLY_PROP_ONLINE: + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: return 1; default: @@ -518,6 +558,7 @@ static enum power_supply_property rk818_charger_props[] = { POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, @@ -525,17 +566,25 @@ static enum power_supply_property rk818_charger_props[] = { POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, POWER_SUPPLY_PROP_PRECHARGE_CURRENT, + + // inherited from BSP battery driver + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CHARGE_COUNTER, + POWER_SUPPLY_PROP_CHARGE_FULL, }; /* - * TODO: This functionality should be in a battery driver/supply, but that one - * is such a mess, I don't want to touch it now. Let's have a separate supply - * for controlling the charger for now, and a prayer for the poor soul that - * will have to understand and clean up the battery driver. + * We import some capacity tracking functionality from the BSP battery driver. + * Some poor soul will have to understand and clean up the BSP battery driver, + * but not me, not now. :) */ static const struct power_supply_desc rk818_charger_desc = { - .name = "rk818-charger", - .type = POWER_SUPPLY_TYPE_MAINS, + .name = "rk818-battery", + .type = POWER_SUPPLY_TYPE_BATTERY, .properties = rk818_charger_props, .num_properties = ARRAY_SIZE(rk818_charger_props), .property_is_writeable = rk818_charger_prop_writeable, -- 2.34.1