power supply and reset changes for the 6.13 series

* power-supply core
   - replace power_supply_register_no_ws() with power_supply_register() and a
     new "no_wakeup_source" field in struct power_supply_config
   - constify battery info tables in the core and all drivers
   - switch back to remove callback for all platform drivers
   - allow power_supply_put() to be called from atomic context
   - mark attribute arrays read-only after init
 
  * power-supply drivers
   - new driver for TWL6030 and TWL6032
   - rk817: improve battery capacity calibration
   - misc. small cleanups and fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmdFLjIACgkQ2O7X88g7
 +pqEKA//YiR8OHLOg+wAysQZmwpoOSKGA/P1PNYrlGE64DarHKGXGRgVs0Z+RjnC
 FC4UKAYPz6h+dIWxuFjcoFmgiB8ewkFEB7Kgys6d9E2pL/Z7k5pteoAT7aiKnF+A
 OcNPsXt18Nj4wUF1va45zc4wUEtbwNoFUpiofCNv2f3SO79ZxHmm0fRScBCHLgAt
 lfiV6Yp1bx8aJ6Z/lgpzz6ofmBVLKNTrzbrJ8c9gYFSNxeQxGPk9nWawhy8bJaHR
 olIcO+XVacRZ8P0D1XtJNgJCzPvl4Qo2fPej5PXKzzQTM1a56b9bFCR0/TSqzYAw
 PLceJQIxttvBZfUVUmS/+ur8R/cc4OoXGs5xILIW3CfXTljdPVxOvx+Y4ztiEQLx
 72uPyT+cmlFEO4NvKK1JkypKfuS589vc4byrIrWquuPU3FPwgEbbYoFLpuBcKBq8
 EKu7LuF5gIR1WxwhNYWivJRQUjGlcRuF8bglaB0o8S4+eB93Hq7Uhchqew/n3ofp
 Qm/YFtCpAjyHoDhTOWH8KvuSEmO/QVz74ffQQw/NuxT7/ul7cEsksN+uolGLt/z/
 fGFj8W+ki1rdQWpFG1epzINSHv6spf9qu2JLAFoHMJlyxjXTLC7s6BVNe41rLNwD
 lGjUlsxIQ9b86tlh4qX1qpDqyKhbJzN6WGGWGmFLubFsjr39O30=
 =vpkz
 -----END PGP SIGNATURE-----

Merge tag 'for-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply

Pull power supply and reset updates from Sebastian Reichel:
 "Power-supply core:

   - replace power_supply_register_no_ws() with power_supply_register()
     and a new "no_wakeup_source" field in struct power_supply_config

   - constify battery info tables in the core and all drivers

   - switch back to remove callback for all platform drivers

   - allow power_supply_put() to be called from atomic context

   - mark attribute arrays read-only after init

  Power-supply drivers:

   - new driver for TWL6030 and TWL6032

   - rk817: improve battery capacity calibration

   - misc small cleanups and fixes"

* tag 'for-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (42 commits)
  power: reset: ep93xx: add AUXILIARY_BUS dependency
  dt-bindings: power: reset: Convert mode-.* properties to array
  power: supply: sc27xx: Fix battery detect GPIO probe
  dt-bindings: power: supply: sc27xx-fg: document deprecated bat-detect-gpio
  reset: keystone-reset: remove unused macros
  power: supply: axp20x_battery: Use scaled iio_read_channel
  power: supply: axp20x_usb_power: Use scaled iio_read_channel
  power: supply: generic-adc-battery: change my gmail
  power: supply: pmu_battery: Set power supply type to BATTERY
  power: Switch back to struct platform_driver::remove()
  power: supply: hwmon: move interface to private header
  power: supply: rk817: Update battery capacity calibration
  power: supply: rk817: stop updating info in suspend
  power: supply: rt9471: Use IC status regfield to report real charger status
  power: supply: rt9471: Fix wrong WDT function regfield declaration
  dt-bindings: power/supply: qcom,pmi8998-charger: Drop incorrect "#interrupt-cells" from example
  power: supply: core: mark attribute arrays as ro_after_init
  power: supply: core: unexport power_supply_property_is_writeable()
  power: supply: core: use device mutex wrappers
  power: supply: bq27xxx: Fix registers of bq27426
  ...
This commit is contained in:
Linus Torvalds 2024-11-28 09:28:09 -08:00
commit 448ecd5771
70 changed files with 971 additions and 292 deletions

View File

@ -31,6 +31,10 @@ properties:
allOf:
- $ref: reboot-mode.yaml#
patternProperties:
"^mode-.*$":
maxItems: 1
required:
- compatible
- nvmem-cells

View File

@ -54,6 +54,10 @@ required:
- compatible
- reg
patternProperties:
"^mode-.*$":
maxItems: 1
unevaluatedProperties: false
allOf:
@ -75,6 +79,9 @@ allOf:
reg-names:
items:
- const: pon
else:
patternProperties:
"^mode-.*$": false
# Special case for pm8941, which doesn't store reset mode
- if:

View File

@ -28,13 +28,13 @@ description: |
properties:
mode-normal:
$ref: /schemas/types.yaml#/definitions/uint32
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
Default value to set on a reboot if no command was provided.
patternProperties:
"^mode-.*$":
$ref: /schemas/types.yaml#/definitions/uint32
$ref: /schemas/types.yaml#/definitions/uint32-array
additionalProperties: true

View File

@ -32,6 +32,10 @@ properties:
allOf:
- $ref: reboot-mode.yaml#
patternProperties:
"^mode-.*$":
maxItems: 1
unevaluatedProperties: false
required:

View File

@ -31,6 +31,10 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32
description: Offset in the register map for the reboot register (in bytes).
reg:
maxItems: 1
description: Base address and size for the reboot register.
regmap:
$ref: /schemas/types.yaml#/definitions/phandle
deprecated: true
@ -45,9 +49,14 @@ properties:
priority:
default: 192
oneOf:
- required:
- offset
- required:
- reg
required:
- compatible
- offset
additionalProperties: false

View File

@ -60,7 +60,6 @@ examples:
pmic {
#address-cells = <1>;
#size-cells = <0>;
#interrupt-cells = <4>;
charger@1000 {
compatible = "qcom,pmi8998-charger";

View File

@ -27,6 +27,11 @@ properties:
battery-detect-gpios:
maxItems: 1
bat-detect-gpio:
maxItems: 1
deprecated: true
description: use battery-detect-gpios instead
interrupts:
maxItems: 1

View File

@ -0,0 +1,48 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/power/supply/ti,twl6030-charger.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TWL6030/32 BCI (Battery Charger Interface)
description:
The battery charger needs to be configured to do any charging besides of
precharging. The GPADC in the PMIC has to be used to get the related
voltages.
maintainers:
- Andreas Kemnade <andreas@kemnade.info>
allOf:
- $ref: power-supply.yaml#
properties:
compatible:
oneOf:
- const: ti,twl6030-charger
- items:
- const: ti,twl6032-charger
- const: ti,twl6030-charger
interrupts:
items:
- description: Charger Control Interrupt
- description: Charger Fault Interrupt
io-channels:
items:
- description: VBUS Voltage Channel
io-channel-names:
items:
- const: vusb
monitored-battery: true
required:
- compatible
- interrupts
- monitored-battery
additionalProperties: false

View File

@ -853,6 +853,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
struct power_supply_config psy_cfg = {
.drv_data = battery,
.attr_grp = acpi_battery_groups,
.no_wakeup_source = true,
};
bool full_cap_broken = false;
@ -888,7 +889,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
battery->bat_desc.get_property = acpi_battery_get_property;
battery->bat = power_supply_register_no_ws(&battery->device->dev,
battery->bat = power_supply_register(&battery->device->dev,
&battery->bat_desc, &psy_cfg);
if (IS_ERR(battery->bat)) {

View File

@ -79,6 +79,7 @@ config POWER_RESET_EP93XX
bool "Cirrus EP93XX reset driver" if COMPILE_TEST
depends on MFD_SYSCON
default ARCH_EP93XX
select AUXILIARY_BUS
help
This driver provides restart support for Cirrus EP93XX SoC.

View File

@ -223,7 +223,7 @@ MODULE_DEVICE_TABLE(of, at91_poweroff_of_match);
static struct platform_driver at91_poweroff_driver = {
.probe = at91_poweroff_probe,
.remove_new = at91_poweroff_remove,
.remove = at91_poweroff_remove,
.driver = {
.name = "at91-poweroff",
.of_match_table = at91_poweroff_of_match,

View File

@ -427,7 +427,7 @@ static void at91_reset_remove(struct platform_device *pdev)
static struct platform_driver at91_reset_driver = {
.probe = at91_reset_probe,
.remove_new = at91_reset_remove,
.remove = at91_reset_remove,
.driver = {
.name = "at91-reset",
.of_match_table = at91_reset_of_match,

View File

@ -441,7 +441,7 @@ static void at91_shdwc_remove(struct platform_device *pdev)
static struct platform_driver at91_shdwc_driver = {
.probe = at91_shdwc_probe,
.remove_new = at91_shdwc_remove,
.remove = at91_shdwc_remove,
.driver = {
.name = "at91-shdwc",
.of_match_table = at91_shdwc_of_match,

View File

@ -16,7 +16,6 @@
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#define RSTYPE_RG 0x0
#define RSCTRL_RG 0x4
#define RSCFG_RG 0x8
#define RSISO_RG 0xc
@ -28,7 +27,6 @@
#define RSMUX_OMODE_MASK 0xe
#define RSMUX_OMODE_RESET_ON 0xa
#define RSMUX_OMODE_RESET_OFF 0x0
#define RSMUX_LOCK_MASK 0x1
#define RSMUX_LOCK_SET 0x1
#define RSCFG_RSTYPE_SOFT 0x300f

View File

@ -305,7 +305,7 @@ MODULE_DEVICE_TABLE(of, of_ltc2952_poweroff_match);
static struct platform_driver ltc2952_poweroff_driver = {
.probe = ltc2952_poweroff_probe,
.remove_new = ltc2952_poweroff_remove,
.remove = ltc2952_poweroff_remove,
.driver = {
.name = "ltc2952-poweroff",
.of_match_table = of_ltc2952_poweroff_match,

View File

@ -118,7 +118,7 @@ static void qnap_power_off_remove(struct platform_device *pdev)
static struct platform_driver qnap_power_off_driver = {
.probe = qnap_power_off_probe,
.remove_new = qnap_power_off_remove,
.remove = qnap_power_off_remove,
.driver = {
.name = "qnap_power_off",
.of_match_table = of_match_ptr(qnap_power_off_of_match_table),

View File

@ -61,7 +61,8 @@ static int syscon_reboot_probe(struct platform_device *pdev)
priority = 192;
if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset))
return -EINVAL;
if (of_property_read_u32(pdev->dev.of_node, "reg", &ctx->offset))
return -EINVAL;
value_err = of_property_read_u32(pdev->dev.of_node, "value", &ctx->value);
mask_err = of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask);

View File

@ -422,7 +422,7 @@ static irqreturn_t pm860x_batt_handler(int irq, void *data)
info->temp_type = PM860X_TEMP_TINT;
}
mutex_unlock(&info->lock);
/* clear ccnt since battery is attached or dettached */
/* clear ccnt since battery is attached or detached */
clear_ccnt(info, &ccnt_data);
return IRQ_HANDLED;
}
@ -566,7 +566,7 @@ static int measure_temp(struct pm860x_battery_info *info, int *data)
ret = measure_12bit_voltage(info, PM8607_GPADC1_MEAS1, data);
if (ret)
return ret;
/* meausered Vtbat(mV) / Ibias_current(11uA)*/
/* measured Vtbat(mV) / Ibias_current(11uA)*/
*data = (*data * 1000) / GPBIAS2_GPADC1_UA;
if (*data > TBAT_NEG_25D) {

View File

@ -493,6 +493,16 @@ config CHARGER_TWL4030
help
Say Y here to enable support for TWL4030 Battery Charge Interface.
config CHARGER_TWL6030
tristate "OMAP TWL6030 BCI charger driver"
depends on IIO && TWL4030_CORE
help
Say Y here to enable support for TWL6030/6032 Battery Charge
Interface.
This driver can be build as a module. If so, the module will be
called twl6030_charger.
config CHARGER_LP8727
tristate "TI/National Semiconductor LP8727 charger driver"
depends on I2C

View File

@ -69,6 +69,7 @@ obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_TWL6030) += twl6030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o

View File

@ -16,7 +16,7 @@
/* Default: temperature hysteresis */
#define AB8500_TEMP_HYSTERESIS 3
static struct power_supply_battery_ocv_table ocv_cap_tbl[] = {
static const struct power_supply_battery_ocv_table ocv_cap_tbl[] = {
{ .ocv = 4186000, .capacity = 100},
{ .ocv = 4163000, .capacity = 99},
{ .ocv = 4114000, .capacity = 95},
@ -48,7 +48,7 @@ static struct power_supply_battery_ocv_table ocv_cap_tbl[] = {
* temperature values to work. Factory resistance is 300 mOhm and the
* resistance values to the right are percentages of 300 mOhm.
*/
static struct power_supply_resistance_temp_table temp_to_batres_tbl_thermistor[] = {
static const struct power_supply_resistance_temp_table temp_to_batres_tbl_thermistor[] = {
{ .temp = 40, .resistance = 40 /* 120 mOhm */ },
{ .temp = 30, .resistance = 45 /* 135 mOhm */ },
{ .temp = 20, .resistance = 55 /* 165 mOhm */ },

View File

@ -283,7 +283,7 @@ static void ab8500_btemp_periodic_work(struct work_struct *work)
dev_warn(di->dev, "failed to identify the battery\n");
}
/* Failover if a reading is erroneous, use last meausurement */
/* Failover if a reading is erroneous, use last measurement */
ret = thermal_zone_get_temp(di->tz, &bat_temp);
if (ret) {
dev_err(di->dev, "error reading temperature\n");
@ -818,7 +818,7 @@ MODULE_DEVICE_TABLE(of, ab8500_btemp_match);
struct platform_driver ab8500_btemp_driver = {
.probe = ab8500_btemp_probe,
.remove_new = ab8500_btemp_remove,
.remove = ab8500_btemp_remove,
.driver = {
.name = "ab8500-btemp",
.of_match_table = ab8500_btemp_match,

View File

@ -1837,7 +1837,7 @@ static const struct of_device_id ab8500_chargalg_match[] = {
struct platform_driver ab8500_chargalg_driver = {
.probe = ab8500_chargalg_probe,
.remove_new = ab8500_chargalg_remove,
.remove = ab8500_chargalg_remove,
.driver = {
.name = "ab8500_chargalg",
.of_match_table = ab8500_chargalg_match,

View File

@ -3711,7 +3711,7 @@ MODULE_DEVICE_TABLE(of, ab8500_charger_match);
static struct platform_driver ab8500_charger_driver = {
.probe = ab8500_charger_probe,
.remove_new = ab8500_charger_remove,
.remove = ab8500_charger_remove,
.driver = {
.name = "ab8500-charger",
.of_match_table = ab8500_charger_match,

View File

@ -3242,7 +3242,7 @@ MODULE_DEVICE_TABLE(of, ab8500_fg_match);
struct platform_driver ab8500_fg_driver = {
.probe = ab8500_fg_probe,
.remove_new = ab8500_fg_remove,
.remove = ab8500_fg_remove,
.driver = {
.name = "ab8500-fg",
.of_match_table = ab8500_fg_match,

View File

@ -233,14 +233,15 @@ static int a500_battery_probe(struct platform_device *pdev)
psy_cfg.of_node = pdev->dev.parent->of_node;
psy_cfg.drv_data = bat;
psy_cfg.no_wakeup_source = true;
bat->regmap = dev_get_regmap(pdev->dev.parent, "KB930");
if (!bat->regmap)
return -EINVAL;
bat->psy = devm_power_supply_register_no_ws(&pdev->dev,
&a500_battery_desc,
&psy_cfg);
bat->psy = devm_power_supply_register(&pdev->dev,
&a500_battery_desc,
&psy_cfg);
if (IS_ERR(bat->psy))
return dev_err_probe(&pdev->dev, PTR_ERR(bat->psy),
"failed to register battery\n");
@ -285,7 +286,7 @@ static struct platform_driver a500_battery_driver = {
.pm = &a500_battery_pm_ops,
},
.probe = a500_battery_probe,
.remove_new = a500_battery_remove,
.remove = a500_battery_remove,
};
module_platform_driver(a500_battery_driver);

View File

@ -651,7 +651,7 @@ static struct platform_driver act8945a_charger_driver = {
.name = "act8945a-charger",
},
.probe = act8945a_charger_probe,
.remove_new = act8945a_charger_remove,
.remove = act8945a_charger_remove,
};
module_platform_driver(act8945a_charger_driver);

View File

@ -590,7 +590,7 @@ static int adp5061_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
/*
* This property is used to set the VWEAK threshold
* bellow this value, weak charge mode is entered
* below this value, weak charge mode is entered
* above this value, fast chargerge mode is entered
*/
return adp5061_get_vweak_th(st, val);

View File

@ -354,17 +354,18 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
if (ret)
return ret;
/* IIO framework gives mA but Power Supply framework gives uA */
if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval);
ret = iio_read_channel_processed_scale(axp20x_batt->batt_chrg_i,
&val->intval, 1000);
} else {
ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, &val1);
ret = iio_read_channel_processed_scale(axp20x_batt->batt_dischrg_i,
&val1, 1000);
val->intval = -val1;
}
if (ret)
return ret;
/* IIO framework gives mA but Power Supply framework gives uA */
val->intval *= 1000;
break;
case POWER_SUPPLY_PROP_CAPACITY:
@ -406,13 +407,12 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = iio_read_channel_processed(axp20x_batt->batt_v,
&val->intval);
/* IIO framework gives mV but Power Supply framework gives uV */
ret = iio_read_channel_processed_scale(axp20x_batt->batt_v,
&val->intval, 1000);
if (ret)
return ret;
/* IIO framework gives mV but Power Supply framework gives uV */
val->intval *= 1000;
break;
default:
@ -519,13 +519,15 @@ static int axp717_battery_get_prop(struct power_supply *psy,
* The offset of this value is currently unknown and is
* not documented in the datasheet. Based on
* observation it's assumed to be somewhere around
* 450ma. I will leave the value raw for now.
* 450ma. I will leave the value raw for now. Note that
* IIO framework gives mA but Power Supply framework
* gives uA.
*/
ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval);
ret = iio_read_channel_processed_scale(axp20x_batt->batt_chrg_i,
&val->intval, 1000);
if (ret)
return ret;
/* IIO framework gives mA but Power Supply framework gives uA */
val->intval *= 1000;
return 0;
case POWER_SUPPLY_PROP_CAPACITY:
@ -564,13 +566,12 @@ static int axp717_battery_get_prop(struct power_supply *psy,
return 0;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = iio_read_channel_processed(axp20x_batt->batt_v,
&val->intval);
/* IIO framework gives mV but Power Supply framework gives uV */
ret = iio_read_channel_processed_scale(axp20x_batt->batt_v,
&val->intval, 1000);
if (ret)
return ret;
/* IIO framework gives mV but Power Supply framework gives uV */
val->intval *= 1000;
return 0;
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:

View File

@ -220,16 +220,15 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
return 0;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
ret = iio_read_channel_processed(power->vbus_v,
&val->intval);
if (ret)
return ret;
/*
* IIO framework gives mV but Power Supply framework
* gives uV.
*/
val->intval *= 1000;
ret = iio_read_channel_processed_scale(power->vbus_v,
&val->intval, 1000);
if (ret)
return ret;
return 0;
}
@ -253,16 +252,15 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
return 0;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
ret = iio_read_channel_processed(power->vbus_i,
&val->intval);
if (ret)
return ret;
/*
* IIO framework gives mA but Power Supply framework
* gives uA.
*/
val->intval *= 1000;
ret = iio_read_channel_processed_scale(power->vbus_i,
&val->intval, 1000);
if (ret)
return ret;
return 0;
}
@ -374,16 +372,15 @@ static int axp717_usb_power_get_property(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
ret = iio_read_channel_processed(power->vbus_v,
&val->intval);
if (ret)
return ret;
/*
* IIO framework gives mV but Power Supply framework
* gives uV.
*/
val->intval *= 1000;
ret = iio_read_channel_processed_scale(power->vbus_v,
&val->intval, 1000);
if (ret)
return ret;
return 0;
}

View File

@ -449,9 +449,29 @@ static u8
[BQ27XXX_REG_AP] = 0x18,
BQ27XXX_DM_REG_ROWS,
},
bq27426_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
[BQ27XXX_REG_TEMP] = 0x02,
[BQ27XXX_REG_INT_TEMP] = 0x1e,
[BQ27XXX_REG_VOLT] = 0x04,
[BQ27XXX_REG_AI] = 0x10,
[BQ27XXX_REG_FLAGS] = 0x06,
[BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
[BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
[BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
[BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
[BQ27XXX_REG_NAC] = 0x08,
[BQ27XXX_REG_RC] = 0x0c,
[BQ27XXX_REG_FCC] = 0x0e,
[BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
[BQ27XXX_REG_AE] = INVALID_REG_ADDR,
[BQ27XXX_REG_SOC] = 0x1c,
[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
[BQ27XXX_REG_AP] = 0x18,
BQ27XXX_DM_REG_ROWS,
},
#define bq27411_regs bq27421_regs
#define bq27425_regs bq27421_regs
#define bq27426_regs bq27421_regs
#define bq27441_regs bq27421_regs
#define bq27621_regs bq27421_regs
bq27z561_regs[BQ27XXX_REG_MAX] = {
@ -769,10 +789,23 @@ static enum power_supply_property bq27421_props[] = {
};
#define bq27411_props bq27421_props
#define bq27425_props bq27421_props
#define bq27426_props bq27421_props
#define bq27441_props bq27421_props
#define bq27621_props bq27421_props
static enum power_supply_property bq27426_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_MANUFACTURER,
};
static enum power_supply_property bq27z561_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
@ -2131,6 +2164,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
struct power_supply_config psy_cfg = {
.of_node = di->dev->of_node,
.drv_data = di,
.no_wakeup_source = true,
};
int ret;
@ -2157,7 +2191,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
psy_desc->get_property = bq27xxx_battery_get_property;
psy_desc->external_power_changed = bq27xxx_external_power_changed;
di->bat = devm_power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
di->bat = devm_power_supply_register(di->dev, psy_desc, &psy_cfg);
if (IS_ERR(di->bat))
return dev_err_probe(di->dev, PTR_ERR(di->bat),
"failed to register battery\n");

View File

@ -221,7 +221,7 @@ static bool is_charging(struct charger_manager *cm)
/* If at least one of the charger is charging, return yes */
for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
/* 1. The charger sholuld not be DISABLED */
/* 1. The charger should not be DISABLED */
if (cm->emergency_stop)
continue;
if (!cm->charger_enabled)
@ -1739,7 +1739,7 @@ static struct platform_driver charger_manager_driver = {
.of_match_table = charger_manager_match,
},
.probe = charger_manager_probe,
.remove_new = charger_manager_remove,
.remove = charger_manager_remove,
.id_table = charger_manager_id,
};

View File

@ -1169,7 +1169,7 @@ static struct platform_driver cpcap_battery_driver = {
.of_match_table = of_match_ptr(cpcap_battery_id_table),
},
.probe = cpcap_battery_probe,
.remove_new = cpcap_battery_remove,
.remove = cpcap_battery_remove,
};
module_platform_driver(cpcap_battery_driver);

View File

@ -969,7 +969,7 @@ static struct platform_driver cpcap_charger_driver = {
.of_match_table = cpcap_charger_id_table,
},
.shutdown = cpcap_charger_shutdown,
.remove_new = cpcap_charger_remove,
.remove = cpcap_charger_remove,
};
module_platform_driver(cpcap_charger_driver);

View File

@ -618,6 +618,7 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
psy_desc->external_power_changed =
cros_usbpd_charger_power_changed;
psy_cfg.drv_data = port;
psy_cfg.no_wakeup_source = true;
if (cros_usbpd_charger_port_is_dedicated(port)) {
sprintf(port->name, CHARGER_DEDICATED_DIR_NAME);
@ -644,8 +645,7 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
psy_desc->name = port->name;
psy = devm_power_supply_register_no_ws(dev, psy_desc,
&psy_cfg);
psy = devm_power_supply_register(dev, psy_desc, &psy_cfg);
if (IS_ERR(psy)) {
dev_err(dev, "Failed to register power supply\n");
continue;

View File

@ -269,7 +269,7 @@ static void da9030_charger_check_state(struct da9030_charger *charger)
}
if (charger->adc.vchmax_res > charger->thresholds.vcharge_max ||
charger->adc.vchmin_res < charger->thresholds.vcharge_min ||
/* Tempreture readings are negative */
/* Temperature readings are negative */
charger->adc.tbat_res < charger->thresholds.tbat_high ||
charger->adc.tbat_res > charger->thresholds.tbat_low) {
/* disable charger */
@ -470,7 +470,7 @@ static int da9030_battery_charger_init(struct da9030_charger *charger)
if (ret)
return ret;
/* enable auto ADC measuremnts */
/* enable auto ADC measurements */
return da903x_write(charger->master, DA9030_ADC_AUTO_CONTROL,
DA9030_ADC_TBAT_ENABLE | DA9030_ADC_VBAT_IN_TXON |
DA9030_ADC_VCH_ENABLE | DA9030_ADC_ICH_ENABLE |
@ -571,7 +571,7 @@ static struct platform_driver da903x_battery_driver = {
.name = "da903x-battery",
},
.probe = da9030_battery_probe,
.remove_new = da9030_battery_remove,
.remove = da9030_battery_remove,
};
module_platform_driver(da903x_battery_driver);

View File

@ -648,7 +648,7 @@ static void da9052_bat_remove(struct platform_device *pdev)
static struct platform_driver da9052_bat_driver = {
.probe = da9052_bat_probe,
.remove_new = da9052_bat_remove,
.remove = da9052_bat_remove,
.driver = {
.name = "da9052-bat",
},

View File

@ -636,7 +636,7 @@ static struct platform_driver da9150_charger_driver = {
.name = "da9150-charger",
},
.probe = da9150_charger_probe,
.remove_new = da9150_charger_remove,
.remove = da9150_charger_remove,
};
module_platform_driver(da9150_charger_driver);

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Generic battery driver using IIO
* Copyright (C) 2012, Anish Kumar <anish198519851985@gmail.com>
* Copyright (C) 2012, Anish Kumar <yesanishhere@gmail.com>
* Copyright (c) 2023, Sebastian Reichel <sre@kernel.org>
*/
#include <linux/interrupt.h>
@ -295,6 +295,6 @@ static struct platform_driver gab_driver = {
};
module_platform_driver(gab_driver);
MODULE_AUTHOR("anish kumar <anish198519851985@gmail.com>");
MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>");
MODULE_DESCRIPTION("generic battery driver using IIO");
MODULE_LICENSE("GPL");

View File

@ -302,7 +302,7 @@ static struct platform_driver micro_batt_device_driver = {
.pm = &micro_batt_dev_pm_ops,
},
.probe = micro_batt_probe,
.remove_new = micro_batt_remove,
.remove = micro_batt_remove,
};
module_platform_driver(micro_batt_device_driver);

View File

@ -501,7 +501,7 @@ static struct platform_driver isp1704_charger_driver = {
.of_match_table = of_match_ptr(omap_isp1704_of_match),
},
.probe = isp1704_charger_probe,
.remove_new = isp1704_charger_remove,
.remove = isp1704_charger_remove,
};
module_platform_driver(isp1704_charger_driver);

View File

@ -368,11 +368,12 @@ static int yoga_c630_psy_register_bat_psy(struct yoga_c630_psy *ecbat)
bat_cfg.drv_data = ecbat;
bat_cfg.fwnode = ecbat->fwnode;
ecbat->bat_psy = power_supply_register_no_ws(ecbat->dev,
ecbat->unit_mA ?
&yoga_c630_psy_bat_psy_desc_mA :
&yoga_c630_psy_bat_psy_desc_mWh,
&bat_cfg);
bat_cfg.no_wakeup_source = true;
ecbat->bat_psy = power_supply_register(ecbat->dev,
ecbat->unit_mA ?
&yoga_c630_psy_bat_psy_desc_mA :
&yoga_c630_psy_bat_psy_desc_mWh,
&bat_cfg);
if (IS_ERR(ecbat->bat_psy)) {
dev_err(ecbat->dev, "failed to register battery supply\n");
return PTR_ERR(ecbat->bat_psy);
@ -442,7 +443,8 @@ static int yoga_c630_psy_probe(struct auxiliary_device *adev,
adp_cfg.fwnode = ecbat->fwnode;
adp_cfg.supplied_to = (char **)&yoga_c630_psy_bat_psy_desc_mA.name;
adp_cfg.num_supplicants = 1;
ecbat->adp_psy = devm_power_supply_register_no_ws(dev, &yoga_c630_psy_adpt_psy_desc, &adp_cfg);
adp_cfg.no_wakeup_source = true;
ecbat->adp_psy = devm_power_supply_register(dev, &yoga_c630_psy_adpt_psy_desc, &adp_cfg);
if (IS_ERR(ecbat->adp_psy)) {
dev_err(dev, "failed to register AC adapter supply\n");
return PTR_ERR(ecbat->adp_psy);

View File

@ -716,7 +716,7 @@ static void lp8788_charger_remove(struct platform_device *pdev)
static struct platform_driver lp8788_charger_driver = {
.probe = lp8788_charger_probe,
.remove_new = lp8788_charger_remove,
.remove = lp8788_charger_remove,
.driver = {
.name = LP8788_DEV_CHARGER,
},

View File

@ -634,7 +634,7 @@ static struct platform_driver max14577_charger_driver = {
.of_match_table = of_max14577_charger_dt_match,
},
.probe = max14577_charger_probe,
.remove_new = max14577_charger_remove,
.remove = max14577_charger_remove,
.id_table = max14577_charger_id,
};
module_platform_driver(max14577_charger_driver);

View File

@ -364,7 +364,7 @@ static struct platform_driver max77650_charger_driver = {
.of_match_table = max77650_charger_of_match,
},
.probe = max77650_charger_probe,
.remove_new = max77650_charger_remove,
.remove = max77650_charger_remove,
};
module_platform_driver(max77650_charger_driver);

View File

@ -798,7 +798,7 @@ static struct platform_driver max77693_charger_driver = {
.name = "max77693-charger",
},
.probe = max77693_charger_probe,
.remove_new = max77693_charger_remove,
.remove = max77693_charger_remove,
.id_table = max77693_charger_id,
};
module_platform_driver(max77693_charger_driver);

View File

@ -452,6 +452,7 @@ static int max77976_probe(struct i2c_client *client)
i2c_set_clientdata(client, chg);
psy_cfg.drv_data = chg;
psy_cfg.no_wakeup_source = true;
chg->client = client;
chg->regmap = devm_regmap_init_i2c(client, &max77976_regmap_config);
@ -475,7 +476,7 @@ static int max77976_probe(struct i2c_client *client)
if (err)
return err;
psy = devm_power_supply_register_no_ws(dev, &max77976_psy_desc, &psy_cfg);
psy = devm_power_supply_register(dev, &max77976_psy_desc, &psy_cfg);
if (IS_ERR(psy))
return dev_err_probe(dev, PTR_ERR(psy), "cannot register\n");

View File

@ -73,7 +73,7 @@ struct max8925_power_info {
unsigned usb_online:1;
unsigned bat_online:1;
unsigned chg_mode:2;
unsigned batt_detect:1; /* detecing MB by ID pin */
unsigned batt_detect:1; /* detecting MB by ID pin */
unsigned topoff_threshold:2;
unsigned fast_charge:3;
unsigned no_temp_support:1;
@ -563,7 +563,7 @@ static void max8925_power_remove(struct platform_device *pdev)
static struct platform_driver max8925_power_driver = {
.probe = max8925_power_probe,
.remove_new = max8925_power_remove,
.remove = max8925_power_remove,
.driver = {
.name = "max8925-power",
},

View File

@ -455,7 +455,7 @@ static struct platform_driver pcf50633_mbc_driver = {
.name = "pcf50633-mbc",
},
.probe = pcf50633_mbc_probe,
.remove_new = pcf50633_mbc_remove,
.remove = pcf50633_mbc_remove,
};
module_platform_driver(pcf50633_mbc_driver);

View File

@ -170,6 +170,7 @@ static int __init pmu_bat_init(void)
pbat->bat_desc.properties = pmu_bat_props;
pbat->bat_desc.num_properties = ARRAY_SIZE(pmu_bat_props);
pbat->bat_desc.get_property = pmu_bat_get_property;
pbat->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
pbat->pbi = &pmu_batteries[i];
psy_cfg.drv_data = pbat;

View File

@ -13,9 +13,12 @@ struct device;
struct device_type;
struct power_supply;
extern int power_supply_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp);
#ifdef CONFIG_SYSFS
extern void power_supply_init_attrs(void);
extern void __init power_supply_init_attrs(void);
extern int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env);
extern const struct attribute_group *power_supply_attr_groups[];
@ -41,3 +44,20 @@ static inline int power_supply_create_triggers(struct power_supply *psy)
static inline void power_supply_remove_triggers(struct power_supply *psy) {}
#endif /* CONFIG_LEDS_TRIGGERS */
#ifdef CONFIG_POWER_SUPPLY_HWMON
int power_supply_add_hwmon_sysfs(struct power_supply *psy);
void power_supply_remove_hwmon_sysfs(struct power_supply *psy);
#else
static inline int power_supply_add_hwmon_sysfs(struct power_supply *psy)
{
return 0;
}
static inline
void power_supply_remove_hwmon_sysfs(struct power_supply *psy) {}
#endif /* CONFIG_POWER_SUPPLY_HWMON */

View File

@ -152,7 +152,7 @@ static void power_supply_deferred_register_work(struct work_struct *work)
deferred_register_work.work);
if (psy->dev.parent) {
while (!mutex_trylock(&psy->dev.parent->mutex)) {
while (!device_trylock(psy->dev.parent)) {
if (psy->removing)
return;
msleep(10);
@ -162,7 +162,7 @@ static void power_supply_deferred_register_work(struct work_struct *work)
power_supply_changed(psy);
if (psy->dev.parent)
mutex_unlock(&psy->dev.parent->mutex);
device_unlock(psy->dev.parent);
}
#ifdef CONFIG_OF
@ -484,8 +484,6 @@ EXPORT_SYMBOL_GPL(power_supply_get_by_name);
*/
void power_supply_put(struct power_supply *psy)
{
might_sleep();
atomic_dec(&psy->use_cnt);
put_device(&psy->dev);
}
@ -777,7 +775,7 @@ int power_supply_get_battery_info(struct power_supply *psy,
tab_len = size / (2 * sizeof(__be32));
info->ocv_table_size[index] = tab_len;
table = info->ocv_table[index] =
info->ocv_table[index] = table =
devm_kcalloc(&psy->dev, tab_len, sizeof(*table), GFP_KERNEL);
if (!info->ocv_table[index]) {
power_supply_put_battery_info(psy, info);
@ -798,7 +796,7 @@ int power_supply_get_battery_info(struct power_supply *psy,
goto out_ret_pointer;
info->resist_table_size = len / (2 * sizeof(__be32));
resist_table = info->resist_table = devm_kcalloc(&psy->dev,
info->resist_table = resist_table = devm_kcalloc(&psy->dev,
info->resist_table_size,
sizeof(*resist_table),
GFP_KERNEL);
@ -982,7 +980,7 @@ EXPORT_SYMBOL_GPL(power_supply_battery_info_get_prop);
*
* Return: the battery internal resistance percent
*/
int power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *table,
int power_supply_temp2resist_simple(const struct power_supply_resistance_temp_table *table,
int table_len, int temp)
{
int i, high, low;
@ -1093,7 +1091,7 @@ EXPORT_SYMBOL_GPL(power_supply_get_maintenance_charging_setting);
*
* Return: the battery capacity.
*/
int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_table *table,
int power_supply_ocv2cap_simple(const struct power_supply_battery_ocv_table *table,
int table_len, int ocv)
{
int i, high, low;
@ -1118,7 +1116,7 @@ int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_table *table,
}
EXPORT_SYMBOL_GPL(power_supply_ocv2cap_simple);
struct power_supply_battery_ocv_table *
const struct power_supply_battery_ocv_table *
power_supply_find_ocv2cap_table(struct power_supply_battery_info *info,
int temp, int *table_len)
{
@ -1149,7 +1147,7 @@ EXPORT_SYMBOL_GPL(power_supply_find_ocv2cap_table);
int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info,
int ocv, int temp)
{
struct power_supply_battery_ocv_table *table;
const struct power_supply_battery_ocv_table *table;
int table_len;
table = power_supply_find_ocv2cap_table(info, temp, &table_len);
@ -1233,7 +1231,6 @@ int power_supply_property_is_writeable(struct power_supply *psy,
{
return psy->desc->property_is_writeable && psy->desc->property_is_writeable(psy, psp);
}
EXPORT_SYMBOL_GPL(power_supply_property_is_writeable);
void power_supply_external_power_changed(struct power_supply *psy)
{
@ -1342,8 +1339,7 @@ static void psy_unregister_thermal(struct power_supply *psy)
static struct power_supply *__must_check
__power_supply_register(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg,
bool ws)
const struct power_supply_config *cfg)
{
struct device *dev;
struct power_supply *psy;
@ -1410,7 +1406,7 @@ __power_supply_register(struct device *parent,
if (rc)
goto device_add_failed;
rc = device_init_wakeup(dev, ws);
rc = device_init_wakeup(dev, cfg ? !cfg->no_wakeup_source : true);
if (rc)
goto wakeup_init_failed;
@ -1476,33 +1472,10 @@ struct power_supply *__must_check power_supply_register(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg)
{
return __power_supply_register(parent, desc, cfg, true);
return __power_supply_register(parent, desc, cfg);
}
EXPORT_SYMBOL_GPL(power_supply_register);
/**
* power_supply_register_no_ws() - Register new non-waking-source power supply
* @parent: Device to be a parent of power supply's device, usually
* the device which probe function calls this
* @desc: Description of power supply, must be valid through whole
* lifetime of this power supply
* @cfg: Run-time specific configuration accessed during registering,
* may be NULL
*
* Return: A pointer to newly allocated power_supply on success
* or ERR_PTR otherwise.
* Use power_supply_unregister() on returned power_supply pointer to release
* resources.
*/
struct power_supply *__must_check
power_supply_register_no_ws(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg)
{
return __power_supply_register(parent, desc, cfg, false);
}
EXPORT_SYMBOL_GPL(power_supply_register_no_ws);
static void devm_power_supply_release(struct device *dev, void *res)
{
struct power_supply **psy = res;
@ -1535,7 +1508,7 @@ devm_power_supply_register(struct device *parent,
if (!ptr)
return ERR_PTR(-ENOMEM);
psy = __power_supply_register(parent, desc, cfg, true);
psy = __power_supply_register(parent, desc, cfg);
if (IS_ERR(psy)) {
devres_free(ptr);
} else {
@ -1546,42 +1519,6 @@ devm_power_supply_register(struct device *parent,
}
EXPORT_SYMBOL_GPL(devm_power_supply_register);
/**
* devm_power_supply_register_no_ws() - Register managed non-waking-source power supply
* @parent: Device to be a parent of power supply's device, usually
* the device which probe function calls this
* @desc: Description of power supply, must be valid through whole
* lifetime of this power supply
* @cfg: Run-time specific configuration accessed during registering,
* may be NULL
*
* Return: A pointer to newly allocated power_supply on success
* or ERR_PTR otherwise.
* The returned power_supply pointer will be automatically unregistered
* on driver detach.
*/
struct power_supply *__must_check
devm_power_supply_register_no_ws(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg)
{
struct power_supply **ptr, *psy;
ptr = devres_alloc(devm_power_supply_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
psy = __power_supply_register(parent, desc, cfg, false);
if (IS_ERR(psy)) {
devres_free(ptr);
} else {
*ptr = psy;
devres_add(parent, ptr);
}
return psy;
}
EXPORT_SYMBOL_GPL(devm_power_supply_register_no_ws);
/**
* power_supply_unregister() - Remove this power supply from system
* @psy: Pointer to power supply to unregister

View File

@ -7,6 +7,7 @@
#include <linux/hwmon.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include "power_supply.h"
struct power_supply_hwmon {
struct power_supply *psy;

View File

@ -142,7 +142,7 @@ static const char * const POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[] = {
[POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge",
};
static struct power_supply_attr power_supply_attrs[] = {
static struct power_supply_attr power_supply_attrs[] __ro_after_init = {
/* Properties of type `int' */
POWER_SUPPLY_ENUM_ATTR(STATUS),
POWER_SUPPLY_ENUM_ATTR(CHARGE_TYPE),
@ -225,9 +225,9 @@ static struct power_supply_attr power_supply_attrs[] = {
#define POWER_SUPPLY_ATTR_CNT ARRAY_SIZE(power_supply_attrs)
static struct attribute *
__power_supply_attrs[POWER_SUPPLY_ATTR_CNT + 1];
__power_supply_attrs[POWER_SUPPLY_ATTR_CNT + 1] __ro_after_init;
static struct power_supply_attr *to_ps_attr(struct device_attribute *attr)
static const struct power_supply_attr *to_ps_attr(struct device_attribute *attr)
{
return container_of(attr, struct power_supply_attr, dev_attr);
}
@ -273,7 +273,7 @@ static ssize_t power_supply_show_property(struct device *dev,
char *buf) {
ssize_t ret;
struct power_supply *psy = dev_get_drvdata(dev);
struct power_supply_attr *ps_attr = to_ps_attr(attr);
const struct power_supply_attr *ps_attr = to_ps_attr(attr);
enum power_supply_property psp = dev_attr_psp(attr);
union power_supply_propval value;
@ -326,7 +326,7 @@ static ssize_t power_supply_store_property(struct device *dev,
const char *buf, size_t count) {
ssize_t ret;
struct power_supply *psy = dev_get_drvdata(dev);
struct power_supply_attr *ps_attr = to_ps_attr(attr);
const struct power_supply_attr *ps_attr = to_ps_attr(attr);
enum power_supply_property psp = dev_attr_psp(attr);
union power_supply_propval value;
@ -401,7 +401,7 @@ const struct attribute_group *power_supply_attr_groups[] = {
NULL
};
void power_supply_init_attrs(void)
void __init power_supply_init_attrs(void)
{
int i;

View File

@ -151,7 +151,7 @@ struct qcom_battmgr_message {
__le32 capacity_low;
__le32 capacity_warning;
__le32 cycle_count;
/* thousandth of persent */
/* thousandth of percent */
__le32 accuracy;
__le32 max_sample_time_ms;
__le32 min_sample_time_ms;

View File

@ -832,7 +832,7 @@ static const struct smb2_register smb2_init_seq[] = {
AUTO_RECHG_BIT | EN_ANALOG_DROP_IN_VBATT_BIT |
CHARGER_INHIBIT_BIT,
.val = CHARGER_INHIBIT_BIT },
/* STAT pin software override, match downstream. Parallell charging? */
/* STAT pin software override, match downstream. Parallel charging? */
{ .addr = STAT_CFG,
.mask = STAT_SW_OVERRIDE_CFG_BIT,
.val = STAT_SW_OVERRIDE_CFG_BIT },

View File

@ -1017,10 +1017,10 @@ static const struct of_device_id smbb_charger_id_table[] = {
MODULE_DEVICE_TABLE(of, smbb_charger_id_table);
static struct platform_driver smbb_charger_driver = {
.probe = smbb_charger_probe,
.remove_new = smbb_charger_remove,
.driver = {
.name = "qcom-smbb",
.probe = smbb_charger_probe,
.remove = smbb_charger_remove,
.driver = {
.name = "qcom-smbb",
.of_match_table = smbb_charger_id_table,
},
};

View File

@ -240,9 +240,32 @@ static int rk817_record_battery_nvram_values(struct rk817_charger *charger)
static int rk817_bat_calib_cap(struct rk817_charger *charger)
{
struct rk808 *rk808 = charger->rk808;
int tmp, charge_now, charge_now_adc, volt_avg;
int charge_now, charge_now_adc;
u8 bulk_reg[4];
/* Don't do anything if there's no battery. */
if (!charger->battery_present)
return 0;
/*
* When resuming from suspend, sometimes the voltage value would be
* incorrect. BSP would simply wait two seconds and try reading the
* values again. Do not do any sort of calibration activity when the
* reported value is incorrect. The next scheduled update of battery
* vaules should then return valid data and the driver can continue.
* Use 2.7v as the sanity value because per the datasheet the PMIC
* can in no way support a battery voltage lower than this. BSP only
* checked for values too low, but I'm adding in a check for values
* too high just in case; again the PMIC can in no way support
* voltages above 4.45v, so this seems like a good value.
*/
if ((charger->volt_avg_uv < 2700000) || (charger->volt_avg_uv > 4450000)) {
dev_dbg(charger->dev,
"Battery voltage of %d is invalid, ignoring.\n",
charger->volt_avg_uv);
return -EINVAL;
}
/* Calibrate the soc and fcc on a fully charged battery */
if (charger->charge_status == CHARGE_FINISH && (!charger->soc_cal)) {
@ -304,51 +327,6 @@ static int rk817_bat_calib_cap(struct rk817_charger *charger)
}
}
/*
* Calibrate the fully charged capacity when we previously had a full
* battery (soc_cal = 1) and are now empty (at or below minimum design
* voltage). If our columb counter is still positive, subtract that
* from our fcc value to get a calibrated fcc, and if our columb
* counter is negative add that to our fcc (but not to exceed our
* design capacity).
*/
regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H,
bulk_reg, 2);
tmp = get_unaligned_be16(bulk_reg);
volt_avg = (charger->voltage_k * tmp) + 1000 * charger->voltage_b;
if (volt_avg <= charger->bat_voltage_min_design_uv &&
charger->soc_cal) {
regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
bulk_reg, 4);
charge_now_adc = get_unaligned_be32(bulk_reg);
charge_now = ADC_TO_CHARGE_UAH(charge_now_adc,
charger->res_div);
/*
* Note, if charge_now is negative this will add it (what we
* want) and if it's positive this will subtract (also what
* we want).
*/
charger->fcc_mah = charger->fcc_mah - (charge_now / 1000);
dev_dbg(charger->dev,
"Recalibrating full charge capacity to %d uah\n",
charger->fcc_mah * 1000);
}
/*
* Set the SOC to 0 if we are below the minimum system voltage.
*/
if (volt_avg <= charger->bat_voltage_min_design_uv) {
charger->soc = 0;
charge_now_adc = CHARGE_TO_ADC(0, charger->res_div);
put_unaligned_be32(charge_now_adc, bulk_reg);
regmap_bulk_write(rk808->regmap,
RK817_GAS_GAUGE_Q_INIT_H3, bulk_reg, 4);
dev_warn(charger->dev,
"Battery voltage %d below minimum voltage %d\n",
volt_avg, charger->bat_voltage_min_design_uv);
}
rk817_record_battery_nvram_values(charger);
return 0;
@ -648,6 +626,24 @@ static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
return IRQ_HANDLED;
}
static int rk817_bat_set_prop(struct power_supply *ps,
enum power_supply_property prop,
const union power_supply_propval *val)
{
struct rk817_charger *charger = power_supply_get_drvdata(ps);
switch (prop) {
case POWER_SUPPLY_PROP_CHARGE_FULL:
if ((val->intval < 500000) ||
(val->intval > charger->bat_charge_full_design_uah))
return -EINVAL;
charger->fcc_mah = val->intval / 1000;
return rk817_bat_calib_cap(charger);
default:
return -EINVAL;
}
}
static enum power_supply_property rk817_bat_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_STATUS,
@ -673,12 +669,25 @@ static enum power_supply_property rk817_chg_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_AVG,
};
static int rk817_bat_prop_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
switch (psp) {
case POWER_SUPPLY_PROP_CHARGE_FULL:
return 1;
default:
return 0;
}
}
static const struct power_supply_desc rk817_bat_desc = {
.name = "rk817-battery",
.type = POWER_SUPPLY_TYPE_BATTERY,
.properties = rk817_bat_props,
.property_is_writeable = rk817_bat_prop_writeable,
.num_properties = ARRAY_SIZE(rk817_bat_props),
.get_property = rk817_bat_get_prop,
.set_property = rk817_bat_set_prop,
};
static const struct power_supply_desc rk817_chg_desc = {
@ -1202,6 +1211,15 @@ static int rk817_charger_probe(struct platform_device *pdev)
return 0;
}
static int __maybe_unused rk817_suspend(struct device *dev)
{
struct rk817_charger *charger = dev_get_drvdata(dev);
cancel_delayed_work_sync(&charger->work);
return 0;
}
static int __maybe_unused rk817_resume(struct device *dev)
{
@ -1213,7 +1231,7 @@ static int __maybe_unused rk817_resume(struct device *dev)
return 0;
}
static SIMPLE_DEV_PM_OPS(rk817_charger_pm, NULL, rk817_resume);
static SIMPLE_DEV_PM_OPS(rk817_charger_pm, rk817_suspend, rk817_resume);
static struct platform_driver rk817_charger_driver = {
.probe = rk817_charger_probe,

View File

@ -139,6 +139,19 @@ enum {
RT9471_PORTSTAT_DCP,
};
enum {
RT9471_ICSTAT_SLEEP = 0,
RT9471_ICSTAT_VBUSRDY,
RT9471_ICSTAT_TRICKLECHG,
RT9471_ICSTAT_PRECHG,
RT9471_ICSTAT_FASTCHG,
RT9471_ICSTAT_IEOC,
RT9471_ICSTAT_BGCHG,
RT9471_ICSTAT_CHGDONE,
RT9471_ICSTAT_CHGFAULT,
RT9471_ICSTAT_OTG = 15,
};
struct rt9471_chip {
struct device *dev;
struct regmap *regmap;
@ -153,8 +166,8 @@ struct rt9471_chip {
};
static const struct reg_field rt9471_reg_fields[F_MAX_FIELDS] = {
[F_WDT] = REG_FIELD(RT9471_REG_TOP, 0, 0),
[F_WDT_RST] = REG_FIELD(RT9471_REG_TOP, 1, 1),
[F_WDT] = REG_FIELD(RT9471_REG_TOP, 0, 1),
[F_WDT_RST] = REG_FIELD(RT9471_REG_TOP, 2, 2),
[F_CHG_EN] = REG_FIELD(RT9471_REG_FUNC, 0, 0),
[F_HZ] = REG_FIELD(RT9471_REG_FUNC, 5, 5),
[F_BATFET_DIS] = REG_FIELD(RT9471_REG_FUNC, 7, 7),
@ -255,31 +268,32 @@ static int rt9471_get_ieoc(struct rt9471_chip *chip, int *microamp)
static int rt9471_get_status(struct rt9471_chip *chip, int *status)
{
unsigned int chg_ready, chg_done, fault_stat;
unsigned int ic_stat;
int ret;
ret = regmap_field_read(chip->rm_fields[F_ST_CHG_RDY], &chg_ready);
ret = regmap_field_read(chip->rm_fields[F_IC_STAT], &ic_stat);
if (ret)
return ret;
ret = regmap_field_read(chip->rm_fields[F_ST_CHG_DONE], &chg_done);
if (ret)
return ret;
ret = regmap_read(chip->regmap, RT9471_REG_STAT1, &fault_stat);
if (ret)
return ret;
fault_stat &= RT9471_CHGFAULT_MASK;
if (chg_ready && chg_done)
*status = POWER_SUPPLY_STATUS_FULL;
else if (chg_ready && fault_stat)
switch (ic_stat) {
case RT9471_ICSTAT_VBUSRDY:
case RT9471_ICSTAT_CHGFAULT:
*status = POWER_SUPPLY_STATUS_NOT_CHARGING;
else if (chg_ready && !fault_stat)
break;
case RT9471_ICSTAT_TRICKLECHG ... RT9471_ICSTAT_BGCHG:
*status = POWER_SUPPLY_STATUS_CHARGING;
else
break;
case RT9471_ICSTAT_CHGDONE:
*status = POWER_SUPPLY_STATUS_FULL;
break;
case RT9471_ICSTAT_SLEEP:
case RT9471_ICSTAT_OTG:
*status = POWER_SUPPLY_STATUS_DISCHARGING;
break;
default:
*status = POWER_SUPPLY_STATUS_UNKNOWN;
break;
}
return 0;
}

View File

@ -431,7 +431,7 @@ static const struct power_supply_vbat_ri_table samsung_vbat2res_charging_eb58515
* temperature compensation tables so we just state 100% for every temperature.
* If you have the datasheets, please provide these tables.
*/
static struct power_supply_resistance_temp_table samsung_temp2res[] = {
static const struct power_supply_resistance_temp_table samsung_temp2res[] = {
{ .temp = 50, .resistance = 100 },
{ .temp = 40, .resistance = 100 },
{ .temp = 30, .resistance = 100 },
@ -447,7 +447,7 @@ static struct power_supply_resistance_temp_table samsung_temp2res[] = {
* These must be sorted by falling OCV value.
*/
static struct power_supply_battery_ocv_table samsung_ocv_cap_eb485159lu[] = {
static const struct power_supply_battery_ocv_table samsung_ocv_cap_eb485159lu[] = {
{ .ocv = 4330000, .capacity = 100},
{ .ocv = 4320000, .capacity = 99},
{ .ocv = 4283000, .capacity = 95},
@ -499,7 +499,7 @@ static struct power_supply_battery_ocv_table samsung_ocv_cap_eb485159lu[] = {
};
/* Same capacity table is used by eb-l1m7flu, eb425161la, eb425161lu */
static struct power_supply_battery_ocv_table samsung_ocv_cap_1500mah[] = {
static const struct power_supply_battery_ocv_table samsung_ocv_cap_1500mah[] = {
{ .ocv = 4328000, .capacity = 100},
{ .ocv = 4299000, .capacity = 99},
{ .ocv = 4281000, .capacity = 98},
@ -540,7 +540,7 @@ static struct power_supply_battery_ocv_table samsung_ocv_cap_1500mah[] = {
{ .ocv = 3300000, .capacity = 0},
};
static struct power_supply_battery_ocv_table samsung_ocv_cap_eb535151vu[] = {
static const struct power_supply_battery_ocv_table samsung_ocv_cap_eb535151vu[] = {
{ .ocv = 4178000, .capacity = 100},
{ .ocv = 4148000, .capacity = 99},
{ .ocv = 4105000, .capacity = 95},
@ -572,7 +572,7 @@ static struct power_supply_battery_ocv_table samsung_ocv_cap_eb535151vu[] = {
{ .ocv = 3300000, .capacity = 0},
};
static struct power_supply_battery_ocv_table samsung_ocv_cap_eb585157lu[] = {
static const struct power_supply_battery_ocv_table samsung_ocv_cap_eb585157lu[] = {
{ .ocv = 4320000, .capacity = 100},
{ .ocv = 4296000, .capacity = 99},
{ .ocv = 4283000, .capacity = 98},

View File

@ -530,7 +530,7 @@ static struct platform_driver sc2731_charger_driver = {
.of_match_table = sc2731_charger_of_match,
},
.probe = sc2731_charger_probe,
.remove_new = sc2731_charger_remove,
.remove = sc2731_charger_remove,
};
module_platform_driver(sc2731_charger_driver);

View File

@ -992,7 +992,7 @@ static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data)
static int sc27xx_fgu_hw_init(struct sc27xx_fgu_data *data)
{
struct power_supply_battery_info *info;
struct power_supply_battery_ocv_table *table;
const struct power_supply_battery_ocv_table *table;
int ret, delta_clbcnt, alarm_adc;
ret = power_supply_get_battery_info(data->battery, &info);
@ -1183,10 +1183,14 @@ static int sc27xx_fgu_probe(struct platform_device *pdev)
return PTR_ERR(data->charge_chan);
}
data->gpiod = devm_gpiod_get(dev, "bat-detect", GPIOD_IN);
data->gpiod = devm_gpiod_get(dev, "battery-detect", GPIOD_IN);
if (IS_ERR(data->gpiod)) {
dev_err(dev, "failed to get battery detection GPIO\n");
return PTR_ERR(data->gpiod);
data->gpiod = devm_gpiod_get(dev, "bat-detect", GPIOD_IN);
if (IS_ERR(data->gpiod)) {
dev_err(dev, "failed to get battery detection GPIO\n");
return PTR_ERR(data->gpiod);
}
dev_warn(dev, "bat-detect is deprecated, please use battery-detect\n");
}
ret = gpiod_get_value_cansleep(data->gpiod);

View File

@ -343,7 +343,7 @@ static struct platform_driver tps65090_charger_driver = {
.of_match_table = of_tps65090_charger_match,
},
.probe = tps65090_charger_probe,
.remove_new = tps65090_charger_remove,
.remove = tps65090_charger_remove,
};
module_platform_driver(tps65090_charger_driver);

View File

@ -269,7 +269,7 @@ MODULE_DEVICE_TABLE(of, tps65217_charger_match_table);
static struct platform_driver tps65217_charger_driver = {
.probe = tps65217_charger_probe,
.remove_new = tps65217_charger_remove,
.remove = tps65217_charger_remove,
.driver = {
.name = "tps65217-charger",
.of_match_table = of_match_ptr(tps65217_charger_match_table),

View File

@ -1133,7 +1133,7 @@ MODULE_DEVICE_TABLE(of, twl_bci_of_match);
static struct platform_driver twl4030_bci_driver = {
.probe = twl4030_bci_probe,
.remove_new = twl4030_bci_remove,
.remove = twl4030_bci_remove,
.driver = {
.name = "twl4030_bci",
.of_match_table = of_match_ptr(twl_bci_of_match),

View File

@ -0,0 +1,581 @@
// SPDX-License-Identifier: GPL-2.0
/*
* TWL6030 charger
*
* Copyright (C) 2024 Andreas Kemnade <andreas@kemnade.info>
*
* based on older 6030 driver found in a v3.0 vendor kernel
*
* based on twl4030_bci_battery.c by TI
* Copyright (C) 2008 Texas Instruments, Inc.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/bits.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/mfd/twl.h>
#include <linux/power_supply.h>
#include <linux/notifier.h>
#include <linux/usb/otg.h>
#include <linux/iio/consumer.h>
#include <linux/devm-helpers.h>
#define CONTROLLER_INT_MASK 0x00
#define CONTROLLER_CTRL1 0x01
#define CONTROLLER_WDG 0x02
#define CONTROLLER_STAT1 0x03
#define CHARGERUSB_INT_STATUS 0x04
#define CHARGERUSB_INT_MASK 0x05
#define CHARGERUSB_STATUS_INT1 0x06
#define CHARGERUSB_STATUS_INT2 0x07
#define CHARGERUSB_CTRL1 0x08
#define CHARGERUSB_CTRL2 0x09
#define CHARGERUSB_CTRL3 0x0A
#define CHARGERUSB_STAT1 0x0B
#define CHARGERUSB_VOREG 0x0C
#define CHARGERUSB_VICHRG 0x0D
#define CHARGERUSB_CINLIMIT 0x0E
#define CHARGERUSB_CTRLLIMIT1 0x0F
#define CHARGERUSB_CTRLLIMIT2 0x10
#define ANTICOLLAPSE_CTRL1 0x11
#define ANTICOLLAPSE_CTRL2 0x12
/* TWL6032 registers 0xDA to 0xDE - TWL6032_MODULE_CHARGER */
#define CONTROLLER_CTRL2 0x00
#define CONTROLLER_VSEL_COMP 0x01
#define CHARGERUSB_VSYSREG 0x02
#define CHARGERUSB_VICHRG_PC 0x03
#define LINEAR_CHRG_STS 0x04
#define LINEAR_CHRG_STS_CRYSTL_OSC_OK 0x40
#define LINEAR_CHRG_STS_END_OF_CHARGE 0x20
#define LINEAR_CHRG_STS_VBATOV 0x10
#define LINEAR_CHRG_STS_VSYSOV 0x08
#define LINEAR_CHRG_STS_DPPM_STS 0x04
#define LINEAR_CHRG_STS_CV_STS 0x02
#define LINEAR_CHRG_STS_CC_STS 0x01
#define FG_REG_00 0x00
#define FG_REG_01 0x01
#define FG_REG_02 0x02
#define FG_REG_03 0x03
#define FG_REG_04 0x04
#define FG_REG_05 0x05
#define FG_REG_06 0x06
#define FG_REG_07 0x07
#define FG_REG_08 0x08
#define FG_REG_09 0x09
#define FG_REG_10 0x0A
#define FG_REG_11 0x0B
/* CONTROLLER_INT_MASK */
#define MVAC_FAULT BIT(7)
#define MAC_EOC BIT(6)
#define LINCH_GATED BIT(5)
#define MBAT_REMOVED BIT(4)
#define MFAULT_WDG BIT(3)
#define MBAT_TEMP BIT(2)
#define MVBUS_DET BIT(1)
#define MVAC_DET BIT(0)
/* CONTROLLER_CTRL1 */
#define CONTROLLER_CTRL1_EN_LINCH BIT(5)
#define CONTROLLER_CTRL1_EN_CHARGER BIT(4)
#define CONTROLLER_CTRL1_SEL_CHARGER BIT(3)
/* CONTROLLER_STAT1 */
#define CONTROLLER_STAT1_EXTCHRG_STATZ BIT(7)
#define CONTROLLER_STAT1_LINCH_GATED BIT(6)
#define CONTROLLER_STAT1_CHRG_DET_N BIT(5)
#define CONTROLLER_STAT1_FAULT_WDG BIT(4)
#define CONTROLLER_STAT1_VAC_DET BIT(3)
#define VAC_DET BIT(3)
#define CONTROLLER_STAT1_VBUS_DET BIT(2)
#define VBUS_DET BIT(2)
#define CONTROLLER_STAT1_BAT_REMOVED BIT(1)
#define CONTROLLER_STAT1_BAT_TEMP_OVRANGE BIT(0)
/* CHARGERUSB_INT_STATUS */
#define EN_LINCH BIT(4)
#define CURRENT_TERM_INT BIT(3)
#define CHARGERUSB_STAT BIT(2)
#define CHARGERUSB_THMREG BIT(1)
#define CHARGERUSB_FAULT BIT(0)
/* CHARGERUSB_INT_MASK */
#define MASK_MCURRENT_TERM BIT(3)
#define MASK_MCHARGERUSB_STAT BIT(2)
#define MASK_MCHARGERUSB_THMREG BIT(1)
#define MASK_MCHARGERUSB_FAULT BIT(0)
/* CHARGERUSB_STATUS_INT1 */
#define CHARGERUSB_STATUS_INT1_TMREG BIT(7)
#define CHARGERUSB_STATUS_INT1_NO_BAT BIT(6)
#define CHARGERUSB_STATUS_INT1_BST_OCP BIT(5)
#define CHARGERUSB_STATUS_INT1_TH_SHUTD BIT(4)
#define CHARGERUSB_STATUS_INT1_BAT_OVP BIT(3)
#define CHARGERUSB_STATUS_INT1_POOR_SRC BIT(2)
#define CHARGERUSB_STATUS_INT1_SLP_MODE BIT(1)
#define CHARGERUSB_STATUS_INT1_VBUS_OVP BIT(0)
/* CHARGERUSB_STATUS_INT2 */
#define ICCLOOP BIT(3)
#define CURRENT_TERM BIT(2)
#define CHARGE_DONE BIT(1)
#define ANTICOLLAPSE BIT(0)
/* CHARGERUSB_CTRL1 */
#define SUSPEND_BOOT BIT(7)
#define OPA_MODE BIT(6)
#define HZ_MODE BIT(5)
#define TERM BIT(4)
/* CHARGERUSB_CTRL2 */
#define UA_TO_VITERM(x) (((x) / 50000 - 1) << 5)
/* CHARGERUSB_CTRL3 */
#define VBUSCHRG_LDO_OVRD BIT(7)
#define CHARGE_ONCE BIT(6)
#define BST_HW_PR_DIS BIT(5)
#define AUTOSUPPLY BIT(3)
#define BUCK_HSILIM BIT(0)
/* CHARGERUSB_VOREG */
#define UV_TO_VOREG(x) (((x) - 3500000) / 20000)
#define VOREG_TO_UV(x) (((x) & 0x3F) * 20000 + 3500000)
#define CHARGERUSB_VOREG_3P52 0x01
#define CHARGERUSB_VOREG_4P0 0x19
#define CHARGERUSB_VOREG_4P2 0x23
#define CHARGERUSB_VOREG_4P76 0x3F
/* CHARGERUSB_VICHRG */
/*
* might be inaccurate for < 500 mA, diffent scale might apply,
* either starting from 100 mA or 300 mA
*/
#define UA_TO_VICHRG(x) (((x) / 100000) - 1)
#define VICHRG_TO_UA(x) (((x) & 0xf) * 100000 + 100000)
/* CHARGERUSB_CINLIMIT */
#define CHARGERUSB_CIN_LIMIT_100 0x1
#define CHARGERUSB_CIN_LIMIT_300 0x5
#define CHARGERUSB_CIN_LIMIT_500 0x9
#define CHARGERUSB_CIN_LIMIT_NONE 0xF
/* CHARGERUSB_CTRLLIMIT2 */
#define CHARGERUSB_CTRLLIMIT2_1500 0x0E
#define LOCK_LIMIT BIT(4)
/* ANTICOLLAPSE_CTRL2 */
#define BUCK_VTH_SHIFT 5
/* FG_REG_00 */
#define CC_ACTIVE_MODE_SHIFT 6
#define CC_AUTOCLEAR BIT(2)
#define CC_CAL_EN BIT(1)
#define CC_PAUSE BIT(0)
#define REG_TOGGLE1 0x90
#define REG_PWDNSTATUS1 0x93
#define FGDITHS BIT(7)
#define FGDITHR BIT(6)
#define FGS BIT(5)
#define FGR BIT(4)
#define BBSPOR_CFG 0xE6
#define BB_CHG_EN BIT(3)
struct twl6030_charger_info {
struct device *dev;
struct power_supply *usb;
struct power_supply_battery_info *binfo;
struct work_struct work;
int irq_chg;
int input_current_limit;
struct iio_channel *channel_vusb;
struct delayed_work charger_monitor;
bool extended_current_range;
};
struct twl6030_charger_chip_data {
bool extended_current_range;
};
static int twl6030_charger_read(u8 reg, u8 *val)
{
return twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, val, reg);
}
static int twl6030_charger_write(u8 reg, u8 val)
{
return twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, val, reg);
}
static int twl6030_config_cinlimit_reg(struct twl6030_charger_info *charger,
unsigned int ua)
{
if (ua >= 50000 && ua <= 750000) {
ua = (ua - 50000) / 50000;
} else if ((ua > 750000) && (ua <= 1500000) && charger->extended_current_range) {
ua = ((ua % 100000) ? 0x30 : 0x20) + ((ua - 100000) / 100000);
} else {
if (ua < 50000) {
dev_err(charger->dev, "invalid input current limit\n");
return -EINVAL;
}
/* This is no current limit */
ua = 0x0F;
}
return twl6030_charger_write(CHARGERUSB_CINLIMIT, ua);
}
/*
* rewriting all stuff here, resets to extremely conservative defaults were
* seen under some circumstances, like charge voltage to 3.5V
*/
static int twl6030_enable_usb(struct twl6030_charger_info *charger)
{
int ret;
ret = twl6030_charger_write(CHARGERUSB_VICHRG,
UA_TO_VICHRG(charger->binfo->constant_charge_current_max_ua));
if (ret < 0)
return ret;
ret = twl6030_charger_write(CONTROLLER_WDG, 0xff);
if (ret < 0)
return ret;
charger->input_current_limit = 500000;
ret = twl6030_config_cinlimit_reg(charger, charger->input_current_limit);
if (ret < 0)
return ret;
ret = twl6030_charger_write(CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_500);
if (ret < 0)
return ret;
ret = twl6030_charger_write(CHARGERUSB_VOREG,
UV_TO_VOREG(charger->binfo->constant_charge_voltage_max_uv));
if (ret < 0)
return ret;
ret = twl6030_charger_write(CHARGERUSB_CTRL1, TERM);
if (ret < 0)
return ret;
if (charger->binfo->charge_term_current_ua != -EINVAL) {
ret = twl6030_charger_write(CHARGERUSB_CTRL2,
UA_TO_VITERM(charger->binfo->charge_term_current_ua));
if (ret < 0)
return ret;
}
return twl6030_charger_write(CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER);
}
static void twl6030_charger_wdg(struct work_struct *data)
{
struct twl6030_charger_info *charger =
container_of(data, struct twl6030_charger_info,
charger_monitor.work);
u8 val;
u8 int_stat;
u8 stat_int1;
u8 stat_int2;
twl6030_charger_read(CONTROLLER_STAT1, &val);
twl6030_charger_read(CHARGERUSB_INT_STATUS, &int_stat);
twl6030_charger_read(CHARGERUSB_STATUS_INT1, &stat_int1);
twl6030_charger_read(CHARGERUSB_STATUS_INT2, &stat_int2);
dev_dbg(charger->dev,
"wdg: stat1: %02x %s INT_STATUS %02x STATUS_INT1 %02x STATUS_INT2 %02x\n",
val, (val & VBUS_DET) ? "usb online" : "usb offline",
int_stat, stat_int1, stat_int2);
twl6030_charger_write(CONTROLLER_WDG, 0xff);
schedule_delayed_work(&charger->charger_monitor,
msecs_to_jiffies(10000));
}
static irqreturn_t twl6030_charger_interrupt(int irq, void *arg)
{
struct twl6030_charger_info *charger = arg;
u8 val;
u8 int_stat;
u8 stat_int1;
u8 stat_int2;
if (twl6030_charger_read(CONTROLLER_STAT1, &val) < 0)
return IRQ_HANDLED;
if (twl6030_charger_read(CHARGERUSB_INT_STATUS, &int_stat) < 0)
return IRQ_HANDLED;
if (twl6030_charger_read(CHARGERUSB_STATUS_INT1, &stat_int1) < 0)
return IRQ_HANDLED;
if (twl6030_charger_read(CHARGERUSB_STATUS_INT2, &stat_int2) < 0)
return IRQ_HANDLED;
dev_dbg(charger->dev,
"charger irq: stat1: %02x %s INT_STATUS %02x STATUS_INT1 %02x STATUS_INT2 %02x\n",
val, (val & VBUS_DET) ? "usb online" : "usb offline",
int_stat, stat_int1, stat_int2);
power_supply_changed(charger->usb);
if (val & VBUS_DET) {
if (twl6030_charger_read(CONTROLLER_CTRL1, &val) < 0)
return IRQ_HANDLED;
if (!(val & CONTROLLER_CTRL1_EN_CHARGER)) {
if (twl6030_enable_usb(charger) < 0)
return IRQ_HANDLED;
schedule_delayed_work(&charger->charger_monitor,
msecs_to_jiffies(10000));
}
} else {
cancel_delayed_work(&charger->charger_monitor);
}
return IRQ_HANDLED;
}
static int twl6030_charger_usb_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct twl6030_charger_info *charger = power_supply_get_drvdata(psy);
int ret;
u8 stat1;
u8 intstat;
ret = twl6030_charger_read(CONTROLLER_STAT1, &stat1);
if (ret)
return ret;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (!(stat1 & VBUS_DET)) {
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
break;
}
ret = twl6030_charger_read(CHARGERUSB_STATUS_INT2, &intstat);
if (ret)
return ret;
if (intstat & CHARGE_DONE)
val->intval = POWER_SUPPLY_STATUS_FULL;
else if (intstat & CURRENT_TERM)
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
else
val->intval = POWER_SUPPLY_STATUS_CHARGING;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
if (!charger->channel_vusb)
return -ENODATA;
ret = iio_read_channel_processed_scale(charger->channel_vusb, &val->intval, 1000);
if (ret < 0)
return ret;
break;
case POWER_SUPPLY_PROP_ONLINE:
val->intval = !!(stat1 & VBUS_DET);
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
val->intval = charger->input_current_limit;
break;
default:
return -EINVAL;
}
return 0;
}
static int twl6030_charger_usb_set_property(struct power_supply *psy,
enum power_supply_property psp,
const union power_supply_propval *val)
{
struct twl6030_charger_info *charger = power_supply_get_drvdata(psy);
switch (psp) {
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
charger->input_current_limit = val->intval;
return twl6030_config_cinlimit_reg(charger, charger->input_current_limit);
default:
return -EINVAL;
}
return 0;
}
static int twl6030_charger_usb_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
dev_info(&psy->dev, "is %d writeable?\n", (int)psp);
switch (psp) {
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
return true;
default:
return false;
}
}
static enum power_supply_property twl6030_charger_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
};
static const struct power_supply_desc twl6030_charger_usb_desc = {
.name = "twl6030_usb",
.type = POWER_SUPPLY_TYPE_USB,
.properties = twl6030_charger_props,
.num_properties = ARRAY_SIZE(twl6030_charger_props),
.get_property = twl6030_charger_usb_get_property,
.set_property = twl6030_charger_usb_set_property,
.property_is_writeable = twl6030_charger_usb_property_is_writeable,
};
static int twl6030_charger_probe(struct platform_device *pdev)
{
struct twl6030_charger_info *charger;
const struct twl6030_charger_chip_data *chip_data;
struct power_supply_config psy_cfg = {};
int ret;
u8 val;
charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
if (!charger)
return -ENOMEM;
charger->dev = &pdev->dev;
charger->irq_chg = platform_get_irq(pdev, 0);
chip_data = device_get_match_data(&pdev->dev);
if (!chip_data)
return dev_err_probe(&pdev->dev, -EINVAL, "missing chip data\n");
charger->extended_current_range = chip_data->extended_current_range;
platform_set_drvdata(pdev, charger);
psy_cfg.drv_data = charger;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
charger->channel_vusb = devm_iio_channel_get(&pdev->dev, "vusb");
if (IS_ERR(charger->channel_vusb)) {
ret = PTR_ERR(charger->channel_vusb);
if (ret == -EPROBE_DEFER)
return ret; /* iio not ready */
dev_warn(&pdev->dev, "could not request vusb iio channel (%d)",
ret);
charger->channel_vusb = NULL;
}
charger->usb = devm_power_supply_register(&pdev->dev,
&twl6030_charger_usb_desc,
&psy_cfg);
if (IS_ERR(charger->usb))
return dev_err_probe(&pdev->dev, PTR_ERR(charger->usb),
"Failed to register usb\n");
ret = power_supply_get_battery_info(charger->usb, &charger->binfo);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"Failed to get battery info\n");
dev_info(&pdev->dev, "battery with vmax %d imax: %d\n",
charger->binfo->constant_charge_voltage_max_uv,
charger->binfo->constant_charge_current_max_ua);
if (charger->binfo->constant_charge_voltage_max_uv == -EINVAL) {
ret = twl6030_charger_read(CHARGERUSB_CTRLLIMIT1, &val);
if (ret < 0)
return ret;
charger->binfo->constant_charge_voltage_max_uv =
VOREG_TO_UV(val);
}
if (charger->binfo->constant_charge_voltage_max_uv > 4760000 ||
charger->binfo->constant_charge_voltage_max_uv < 350000)
return dev_err_probe(&pdev->dev, -EINVAL,
"Invalid charge voltage\n");
if (charger->binfo->constant_charge_current_max_ua == -EINVAL) {
ret = twl6030_charger_read(CHARGERUSB_CTRLLIMIT2, &val);
if (ret < 0)
return ret;
charger->binfo->constant_charge_current_max_ua = VICHRG_TO_UA(val);
}
if (charger->binfo->constant_charge_current_max_ua < 100000 ||
charger->binfo->constant_charge_current_max_ua > 1500000) {
return dev_err_probe(&pdev->dev, -EINVAL,
"Invalid charge current\n");
}
if ((charger->binfo->charge_term_current_ua != -EINVAL) &&
(charger->binfo->charge_term_current_ua > 400000 ||
charger->binfo->charge_term_current_ua < 50000)) {
return dev_err_probe(&pdev->dev, -EINVAL,
"Invalid charge termination current\n");
}
ret = devm_delayed_work_autocancel(&pdev->dev,
&charger->charger_monitor,
twl6030_charger_wdg);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"Failed to register delayed work\n");
ret = devm_request_threaded_irq(&pdev->dev, charger->irq_chg, NULL,
twl6030_charger_interrupt,
IRQF_ONESHOT, pdev->name,
charger);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"could not request irq %d\n",
charger->irq_chg);
/* turing to charging to configure things */
twl6030_charger_write(CONTROLLER_CTRL1, 0);
twl6030_charger_interrupt(0, charger);
return 0;
}
static const struct twl6030_charger_chip_data twl6030_data = {
.extended_current_range = false,
};
static const struct twl6030_charger_chip_data twl6032_data = {
.extended_current_range = true,
};
static const struct of_device_id twl_charger_of_match[] = {
{.compatible = "ti,twl6030-charger", .data = &twl6030_data},
{.compatible = "ti,twl6032-charger", .data = &twl6032_data},
{ }
};
MODULE_DEVICE_TABLE(of, twl_charger_of_match);
static struct platform_driver twl6030_charger_driver = {
.probe = twl6030_charger_probe,
.driver = {
.name = "twl6030_charger",
.of_match_table = twl_charger_of_match,
},
};
module_platform_driver(twl6030_charger_driver);
MODULE_DESCRIPTION("TWL6030 Battery Charger Interface driver");
MODULE_LICENSE("GPL");

View File

@ -720,7 +720,7 @@ static void wm831x_power_remove(struct platform_device *pdev)
static struct platform_driver wm831x_power_driver = {
.probe = wm831x_power_probe,
.remove_new = wm831x_power_remove,
.remove = wm831x_power_remove,
.driver = {
.name = "wm831x-power",
},

View File

@ -577,7 +577,7 @@ static void wm8350_power_remove(struct platform_device *pdev)
static struct platform_driver wm8350_power_driver = {
.probe = wm8350_power_probe,
.remove_new = wm8350_power_remove,
.remove = wm8350_power_remove,
.driver = {
.name = "wm8350-power",
},

View File

@ -265,7 +265,7 @@ static struct platform_driver wm97xx_bat_driver = {
#endif
},
.probe = wm97xx_bat_probe,
.remove_new = wm97xx_bat_remove,
.remove = wm97xx_bat_remove,
};
module_platform_driver(wm97xx_bat_driver);

View File

@ -236,6 +236,8 @@ struct power_supply_config {
char **supplied_to;
size_t num_supplicants;
bool no_wakeup_source;
};
/* Description of power supply */
@ -750,9 +752,9 @@ struct power_supply_battery_info {
int temp_alert_max;
int temp_min;
int temp_max;
struct power_supply_battery_ocv_table *ocv_table[POWER_SUPPLY_OCV_TEMP_MAX];
const struct power_supply_battery_ocv_table *ocv_table[POWER_SUPPLY_OCV_TEMP_MAX];
int ocv_table_size[POWER_SUPPLY_OCV_TEMP_MAX];
struct power_supply_resistance_temp_table *resist_table;
const struct power_supply_resistance_temp_table *resist_table;
int resist_table_size;
const struct power_supply_vbat_ri_table *vbat2ri_discharging;
int vbat2ri_discharging_size;
@ -797,15 +799,15 @@ extern bool power_supply_battery_info_has_prop(struct power_supply_battery_info
extern int power_supply_battery_info_get_prop(struct power_supply_battery_info *info,
enum power_supply_property psp,
union power_supply_propval *val);
extern int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_table *table,
extern int power_supply_ocv2cap_simple(const struct power_supply_battery_ocv_table *table,
int table_len, int ocv);
extern struct power_supply_battery_ocv_table *
extern const struct power_supply_battery_ocv_table *
power_supply_find_ocv2cap_table(struct power_supply_battery_info *info,
int temp, int *table_len);
extern int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info,
int ocv, int temp);
extern int
power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *table,
power_supply_temp2resist_simple(const struct power_supply_resistance_temp_table *table,
int table_len, int temp);
extern int power_supply_vbat2ri(struct power_supply_battery_info *info,
int vbat_uv, bool charging);
@ -863,8 +865,6 @@ static inline int power_supply_set_property(struct power_supply *psy,
const union power_supply_propval *val)
{ return 0; }
#endif
extern int power_supply_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp);
extern void power_supply_external_power_changed(struct power_supply *psy);
extern struct power_supply *__must_check
@ -872,17 +872,9 @@ power_supply_register(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg);
extern struct power_supply *__must_check
power_supply_register_no_ws(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg);
extern struct power_supply *__must_check
devm_power_supply_register(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg);
extern struct power_supply *__must_check
devm_power_supply_register_no_ws(struct device *parent,
const struct power_supply_desc *desc,
const struct power_supply_config *cfg);
extern void power_supply_unregister(struct power_supply *psy);
extern int power_supply_powers(struct power_supply *psy, struct device *dev);
@ -945,19 +937,6 @@ static inline bool power_supply_is_watt_property(enum power_supply_property psp)
return false;
}
#ifdef CONFIG_POWER_SUPPLY_HWMON
int power_supply_add_hwmon_sysfs(struct power_supply *psy);
void power_supply_remove_hwmon_sysfs(struct power_supply *psy);
#else
static inline int power_supply_add_hwmon_sysfs(struct power_supply *psy)
{
return 0;
}
static inline
void power_supply_remove_hwmon_sysfs(struct power_supply *psy) {}
#endif
#ifdef CONFIG_SYSFS
ssize_t power_supply_charge_behaviour_show(struct device *dev,
unsigned int available_behaviours,