power supply and reset changes for the 6.15 series

* power-supply core
   - remove unused set_charged infrastructure
   - drop of_node from power_supply struct
  * power-supply drivers
   - axp717: support devices without thermistors
   - bq27xxx: support max design voltage for bq270x0 and bq27x10
   - pcf50633: drop charger driver
   - max1720x: add battery health support
   - switch all power-supply devices from of_node to fwnode
   - convert regmap users to maple tree register cache
   - convert drivers to devm_kmemdup_array
   - misc cleanups and fixes
  * reset drivers
   - at91-sama5d2_shdwc: add sama7d65 support
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmfmAhAACgkQ2O7X88g7
 +pqUVA//QoohKXgC1WOsias7WU0pw+D+zjpGUtiCTyw0EVBjEGcRiK1Fa2mhgn0x
 jQnB84K0WbNZN9uuquMZXBBU7lMQIX/Lltjsy04Y0ZpEdvaO7XpbHXfumy/O5q/3
 xqQzJm+sscE/jBLABauLchSu3Ro3/RlazG9N6XWA8MS9cqUx0wJqsXaITLvrFAsP
 mgV+Ybnusnd1oHjbceccPZzUHqWeBVHE5+fpJlB8HfrmovG3jvfjRtaUabsmhHVM
 afpDXHx7amGJVU3Ild8CRp7UGM0w3RXk7HT3e98o6lzVsULP6JwyCBKq7pUivjF8
 xnGROrpyuYl8yZ8U55cROk0kxEu984o7h1b+SU6ZEXtXwOCUn6Cb+eOSxNUmCKi4
 orl8iEdO/Elxe+L6LnbQUcSgnGg3w6Ugl9rAb+MJ/8R6srrFpghAv7WnnRgJFmKW
 Yt58NtQzCs6yLtgMcnhE98sGgBCD/uBV8xxqtntiKXReTREfVy+dFGlRCJJCSmBN
 TNg49PgOKUyAOYR/7NBBlco9YKMgsKzb3vfOmoO+o3VQy0WYRrC3wOOGkUTQVfTb
 oPXdB3H4hD+eZ5SvGtwSm3E23LWhBlLfb8Zoo45oRpYzqmfQ3vUekKuuzGlScgPY
 Anpua874fJk07SYyz8nE/VMR2BjVyz3Jf98zKdO0Gw35FXDcaTQ=
 =C0aa
 -----END PGP SIGNATURE-----

Merge tag 'for-v6.15' 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:
   - remove unused set_charged infrastructure
   - drop of_node from power_supply struct

  Power-supply drivers:
   - axp717: support devices without thermistors
   - bq27xxx: support max design voltage for bq270x0 and bq27x10
   - pcf50633: drop charger driver
   - max1720x: add battery health support
   - switch all power-supply devices from of_node to fwnode
   - convert regmap users to maple tree register cache
   - convert drivers to devm_kmemdup_array
   - misc cleanups and fixes

  Reset drivers:
   - at91-sama5d2_shdwc: add sama7d65 support

* tag 'for-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (30 commits)
  power: supply: mt6370: Remove redundant 'flush_workqueue()' calls
  Revert "power: supply: bq27xxx: do not report bogus zero values"
  power: supply: max77693: Fix wrong conversion of charge input threshold value
  power: supply: pcf50633: Remove charger
  power: supply: all: switch psy_cfg from of_node to fwnode
  power: supply: core: get rid of of_node
  power: reset: at91-sama5d2_shdwc: Add sama7d65 PMC
  power: supply: smb347: convert to use maple tree register cache
  power: supply: rt9455: convert to use maple tree register cache
  power: supply: max1720x: convert to use maple tree register cache
  power: supply: ltc4162l: convert to use maple tree register cache
  power: supply: bq25980: convert to use maple tree register cache
  power: supply: bq25890: convert to use maple tree register cache
  power: supply: bq2515x: convert to use maple tree register cache
  power: supply: bq24257: convert to use maple tree register cache
  power: supply: bd99954: convert to use maple tree register cache
  power: supply: Remove unused set_charged method
  power: supply: ds2760: Remove unused ds2760_battery_set_charged
  power: supply: core: Remove unused power_supply_set_battery_charged
  power: supply: sc27xx: use devm_kmemdup_array()
  ...
This commit is contained in:
Linus Torvalds 2025-03-29 18:11:12 -07:00
commit 556f1b4874
65 changed files with 212 additions and 627 deletions

View File

@ -16,6 +16,11 @@ description: |
properties:
compatible:
oneOf:
- items:
- enum:
- microchip,sama7d65-shdwc
- const: microchip,sama7g5-shdwc
- const: syscon
- items:
- const: microchip,sama7g5-shdwc
- const: syscon

View File

@ -46,7 +46,6 @@ properties:
required:
- compatible
- interrupts
additionalProperties: false

View File

@ -14,9 +14,6 @@ maintainers:
- Chen-Yu Tsai <wens@csie.org>
- Sebastian Reichel <sre@kernel.org>
allOf:
- $ref: power-supply.yaml#
properties:
compatible:
oneOf:
@ -35,7 +32,24 @@ properties:
this gauge.
$ref: /schemas/types.yaml#/definitions/phandle
x-powers,no-thermistor:
type: boolean
description: Indicates that no thermistor is connected to the TS pin
required:
- compatible
allOf:
- $ref: power-supply.yaml#
- if:
not:
properties:
compatible:
contains:
enum:
- x-powers,axp717-battery-power-supply
then:
properties:
x-powers,no-thermistor: false
additionalProperties: false

View File

@ -327,6 +327,7 @@ static const struct of_device_id at91_pmc_ids[] = {
{ .compatible = "microchip,sam9x60-pmc" },
{ .compatible = "microchip,sama7g5-pmc" },
{ .compatible = "microchip,sam9x7-pmc" },
{ .compatible = "microchip,sama7d65-pmc" },
{ /* Sentinel. */ }
};

View File

@ -449,12 +449,6 @@ config CHARGER_88PM860X
help
Say Y here to enable charger for Marvell 88PM860x chip.
config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
config BATTERY_RX51
tristate "Nokia RX-51 (N900) battery driver"
depends on TWL4030_MADC

View File

@ -62,7 +62,6 @@ obj-$(CONFIG_CHARGER_RT9467) += rt9467-charger.o
obj-$(CONFIG_CHARGER_RT9471) += rt9471.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o ab8500_chargalg.o
obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o

View File

@ -3494,11 +3494,11 @@ static int ab8500_charger_probe(struct platform_device *pdev)
di->invalid_charger_detect_state = 0;
/* AC and USB supply config */
ac_psy_cfg.of_node = np;
ac_psy_cfg.fwnode = dev_fwnode(dev);
ac_psy_cfg.supplied_to = supply_interface;
ac_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
ac_psy_cfg.drv_data = &di->ac_chg;
usb_psy_cfg.of_node = np;
usb_psy_cfg.fwnode = dev_fwnode(dev);
usb_psy_cfg.supplied_to = supply_interface;
usb_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
usb_psy_cfg.drv_data = &di->usb_chg;

View File

@ -17,6 +17,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/property.h>
enum {
REG_CAPACITY,
@ -231,7 +232,7 @@ static int a500_battery_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bat);
psy_cfg.of_node = pdev->dev.parent->of_node;
psy_cfg.fwnode = dev_fwnode(pdev->dev.parent);
psy_cfg.drv_data = bat;
psy_cfg.no_wakeup_source = true;

View File

@ -614,7 +614,7 @@ static int act8945a_charger_probe(struct platform_device *pdev)
if (ret)
return -EINVAL;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = charger;
charger->psy = devm_power_supply_register(&pdev->dev,

View File

@ -364,7 +364,7 @@ static int axp20x_ac_power_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, power);
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = power;
power->supply = devm_power_supply_register(&pdev->dev,

View File

@ -89,6 +89,8 @@
#define AXP717_BAT_CC_MIN_UA 0
#define AXP717_BAT_CC_MAX_UA 3008000
#define AXP717_TS_PIN_DISABLE BIT(4)
struct axp20x_batt_ps;
struct axp_data {
@ -117,6 +119,7 @@ struct axp20x_batt_ps {
/* Maximum constant charge current */
unsigned int max_ccc;
const struct axp_data *data;
bool ts_disable;
};
static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
@ -984,6 +987,24 @@ static void axp717_set_battery_info(struct platform_device *pdev,
int ccc = info->constant_charge_current_max_ua;
int val;
axp_batt->ts_disable = (device_property_read_bool(axp_batt->dev,
"x-powers,no-thermistor"));
/*
* Under rare conditions an incorrectly programmed efuse for
* the temp sensor on the PMIC may trigger a fault condition.
* Allow users to hard-code if the ts pin is not used to work
* around this problem. Note that this requires the battery
* be correctly defined in the device tree with a monitored
* battery node.
*/
if (axp_batt->ts_disable) {
regmap_update_bits(axp_batt->regmap,
AXP717_TS_PIN_CFG,
AXP717_TS_PIN_DISABLE,
AXP717_TS_PIN_DISABLE);
}
if (vmin > 0 && axp717_set_voltage_min_design(axp_batt, vmin))
dev_err(&pdev->dev,
"couldn't set voltage_min_design\n");
@ -1090,7 +1111,7 @@ static int axp20x_power_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, axp20x_batt);
psy_cfg.drv_data = axp20x_batt;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev);

View File

@ -492,7 +492,7 @@ static int axp717_usb_power_set_input_current_limit(struct axp20x_usb_power *pow
if (power->max_input_cur && (intval > power->max_input_cur)) {
dev_warn(power->dev,
"reqested current %d clamped to max current %d\n",
"requested current %d clamped to max current %d\n",
intval, power->max_input_cur);
intval = power->max_input_cur;
}
@ -1011,7 +1011,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
return ret;
}
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = power;
power->supply = devm_power_supply_register(&pdev->dev,

View File

@ -156,7 +156,7 @@ static const struct regmap_config bd9995x_regmap_config = {
.reg_stride = 1,
.max_register = 3 * 0x100,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.ranges = regmap_range_cfg,
.num_ranges = ARRAY_SIZE(regmap_range_cfg),
@ -982,7 +982,7 @@ static int bd9995x_probe(struct i2c_client *client)
bd->client = client;
bd->dev = dev;
psy_cfg.drv_data = bd;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
mutex_init(&bd->lock);

View File

@ -1497,7 +1497,7 @@ static int bq2415x_power_supply_init(struct bq2415x_device *bq)
char revstr[8];
struct power_supply_config psy_cfg = {
.drv_data = bq,
.of_node = bq->dev->of_node,
.fwnode = dev_fwnode(bq->dev),
.attr_grp = bq2415x_sysfs_groups,
};

View File

@ -2117,7 +2117,7 @@ static int bq24190_probe(struct i2c_client *client)
#endif
charger_cfg.drv_data = bdi;
charger_cfg.of_node = dev->of_node;
charger_cfg.fwnode = dev_fwnode(dev);
charger_cfg.supplied_to = bq24190_charger_supplied_to;
charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to);
bdi->charger = power_supply_register(dev, &bq24190_charger_desc,

View File

@ -113,7 +113,7 @@ static const struct regmap_config bq24257_regmap_config = {
.val_bits = 8,
.max_register = BQ24257_REG_7,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = bq24257_is_volatile_reg,
};

View File

@ -402,7 +402,7 @@ static int bq24735_charger_probe(struct i2c_client *client)
psy_cfg.supplied_to = charger->pdata->supplied_to;
psy_cfg.num_supplicants = charger->pdata->num_supplicants;
psy_cfg.of_node = client->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&client->dev);
psy_cfg.drv_data = charger;
i2c_set_clientdata(client, charger);

View File

@ -1060,7 +1060,7 @@ static const struct regmap_config bq25150_regmap_config = {
.max_register = BQ2515X_DEVICE_ID,
.reg_defaults = bq25150_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(bq25150_reg_defaults),
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = bq2515x_volatile_register,
};
@ -1071,7 +1071,7 @@ static const struct regmap_config bq25155_regmap_config = {
.max_register = BQ2515X_DEVICE_ID,
.reg_defaults = bq25155_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(bq25155_reg_defaults),
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = bq2515x_volatile_register,
};
@ -1102,7 +1102,7 @@ static int bq2515x_probe(struct i2c_client *client)
i2c_set_clientdata(client, bq2515x);
charger_cfg.drv_data = bq2515x;
charger_cfg.of_node = dev->of_node;
charger_cfg.fwnode = dev_fwnode(dev);
ret = bq2515x_read_properties(bq2515x);
if (ret) {

View File

@ -1657,7 +1657,7 @@ static int bq256xx_parse_dt(struct bq256xx_device *bq,
int ret = 0;
psy_cfg->drv_data = bq;
psy_cfg->of_node = dev->of_node;
psy_cfg->fwnode = dev_fwnode(dev);
ret = device_property_read_u32(bq->dev, "ti,watchdog-timeout-ms",
&bq->watchdog_timer);

View File

@ -164,7 +164,7 @@ static const struct regmap_config bq25890_regmap_config = {
.val_bits = 8,
.max_register = 0x14,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.wr_table = &bq25890_writeable_regs,
.volatile_table = &bq25890_volatile_regs,

View File

@ -932,7 +932,7 @@ static const struct regmap_config bq25980_regmap_config = {
.max_register = BQ25980_CHRGR_CTRL_6,
.reg_defaults = bq25980_reg_defs,
.num_reg_defaults = ARRAY_SIZE(bq25980_reg_defs),
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = bq25980_is_volatile_reg,
};
@ -943,7 +943,7 @@ static const struct regmap_config bq25975_regmap_config = {
.max_register = BQ25980_CHRGR_CTRL_6,
.reg_defaults = bq25975_reg_defs,
.num_reg_defaults = ARRAY_SIZE(bq25975_reg_defs),
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = bq25980_is_volatile_reg,
};
@ -954,7 +954,7 @@ static const struct regmap_config bq25960_regmap_config = {
.max_register = BQ25980_CHRGR_CTRL_6,
.reg_defaults = bq25960_reg_defs,
.num_reg_defaults = ARRAY_SIZE(bq25960_reg_defs),
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.volatile_reg = bq25980_is_volatile_reg,
};
@ -1057,7 +1057,7 @@ static int bq25980_power_supply_init(struct bq25980_device *bq,
struct device *dev)
{
struct power_supply_config psy_cfg = { .drv_data = bq,
.of_node = dev->of_node, };
.fwnode = dev_fwnode(dev), };
psy_cfg.supplied_to = bq25980_charger_supplied_to;
psy_cfg.num_supplicants = ARRAY_SIZE(bq25980_charger_supplied_to);

View File

@ -124,6 +124,7 @@ enum bq27xxx_reg_index {
BQ27XXX_DM_DATA, /* Block Data */
BQ27XXX_DM_CKSUM, /* Block Data Checksum */
BQ27XXX_REG_SEDVF, /* End-of-discharge Voltage */
BQ27XXX_REG_PKCFG, /* Pack Configuration */
BQ27XXX_REG_MAX, /* sentinel */
};
@ -161,6 +162,7 @@ static u8
[BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
[BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
[BQ27XXX_REG_SEDVF] = 0x77,
[BQ27XXX_REG_PKCFG] = 0x7C,
},
bq27010_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
@ -187,6 +189,7 @@ static u8
[BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
[BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
[BQ27XXX_REG_SEDVF] = 0x77,
[BQ27XXX_REG_PKCFG] = 0x7C,
},
bq2750x_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
@ -583,6 +586,7 @@ static enum power_supply_property bq27000_props[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
};
static enum power_supply_property bq27010_props[] = {
@ -604,6 +608,7 @@ static enum power_supply_property bq27010_props[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
};
#define bq2750x_props bq27510g3_props
@ -1918,7 +1923,6 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
cache.flags = -1; /* read error */
if (cache.flags >= 0) {
cache.capacity = bq27xxx_battery_read_soc(di);
di->cache.flags = cache.flags;
/*
* On gauges with signed current reporting the current must be
@ -2044,6 +2048,35 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
return 0;
}
/*
* Return the design maximum battery Voltage in microvolts, or < 0 if something
* fails. The programmed value of the maximum battery voltage is determined by
* QV0 and QV1 (bits 5 and 6) in the Pack Configuration register.
*/
static int bq27xxx_battery_read_dmax_volt(struct bq27xxx_device_info *di,
union power_supply_propval *val)
{
int reg_val, qv;
if (di->voltage_max_design > 0) {
val->intval = di->voltage_max_design;
return 0;
}
reg_val = bq27xxx_read(di, BQ27XXX_REG_PKCFG, true);
if (reg_val < 0) {
dev_err(di->dev, "error reading design max voltage\n");
return reg_val;
}
qv = (reg_val >> 5) & 0x3;
val->intval = 3968000 + 48000 * qv;
di->voltage_max_design = val->intval;
return 0;
}
/*
* Return the design minimum battery Voltage in microvolts
* Or < 0 if something fails.
@ -2158,6 +2191,9 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
ret = bq27xxx_battery_read_dmin_volt(di, val);
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
ret = bq27xxx_battery_read_dmax_volt(di, val);
break;
case POWER_SUPPLY_PROP_CYCLE_COUNT:
ret = bq27xxx_battery_read_cyct(di, val);
break;
@ -2199,7 +2235,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
{
struct power_supply_desc *psy_desc;
struct power_supply_config psy_cfg = {
.of_node = di->dev->of_node,
.fwnode = dev_fwnode(di->dev),
.drv_data = di,
.no_wakeup_source = true,
};

View File

@ -1130,7 +1130,7 @@ static int cpcap_battery_probe(struct platform_device *pdev)
if (error)
return error;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = ddata;
ddata->psy = devm_power_supply_register(ddata->dev,

View File

@ -902,7 +902,7 @@ static int cpcap_charger_probe(struct platform_device *pdev)
atomic_set(&ddata->active, 1);
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = ddata;
psy_cfg.supplied_to = cpcap_charger_supplied_to;
psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to);

View File

@ -112,7 +112,6 @@ struct ds2760_device_info {
struct power_supply_desc bat_desc;
struct workqueue_struct *monitor_wqueue;
struct delayed_work monitor_work;
struct delayed_work set_charged_work;
struct notifier_block pm_notifier;
};
@ -489,50 +488,6 @@ static void ds2760_battery_external_power_changed(struct power_supply *psy)
}
static void ds2760_battery_set_charged_work(struct work_struct *work)
{
char bias;
struct ds2760_device_info *di = container_of(work,
struct ds2760_device_info, set_charged_work.work);
dev_dbg(di->dev, "%s\n", __func__);
ds2760_battery_read_status(di);
/* When we get notified by external circuitry that the battery is
* considered fully charged now, we know that there is no current
* flow any more. However, the ds2760's internal current meter is
* too inaccurate to rely on - spec say something ~15% failure.
* Hence, we use the current offset bias register to compensate
* that error.
*/
if (!power_supply_am_i_supplied(di->bat))
return;
bias = (signed char) di->current_raw +
(signed char) di->raw[DS2760_CURRENT_OFFSET_BIAS];
dev_dbg(di->dev, "%s: bias = %d\n", __func__, bias);
w1_ds2760_write(di->dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1);
w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
/* Write to the di->raw[] buffer directly - the CURRENT_OFFSET_BIAS
* value won't be read back by ds2760_battery_read_status() */
di->raw[DS2760_CURRENT_OFFSET_BIAS] = bias;
}
static void ds2760_battery_set_charged(struct power_supply *psy)
{
struct ds2760_device_info *di = power_supply_get_drvdata(psy);
/* postpone the actual work by 20 secs. This is for debouncing GPIO
* signals and to let the current value settle. See AN4188. */
mod_delayed_work(di->monitor_wqueue, &di->set_charged_work, HZ * 20);
}
static int ds2760_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@ -692,17 +647,15 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
di->bat_desc.set_property = ds2760_battery_set_property;
di->bat_desc.property_is_writeable =
ds2760_battery_property_is_writeable;
di->bat_desc.set_charged = ds2760_battery_set_charged;
di->bat_desc.external_power_changed =
ds2760_battery_external_power_changed;
psy_cfg.drv_data = di;
psy_cfg.fwnode = dev_fwnode(dev);
if (dev->of_node) {
u32 tmp;
psy_cfg.of_node = dev->of_node;
if (!of_property_read_bool(dev->of_node, "maxim,pmod-enabled"))
pmod_enabled = true;
@ -747,8 +700,6 @@ static int w1_ds2760_add_slave(struct w1_slave *sl)
}
INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
INIT_DELAYED_WORK(&di->set_charged_work,
ds2760_battery_set_charged_work);
di->monitor_wqueue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
if (!di->monitor_wqueue) {
retval = -ESRCH;
@ -774,7 +725,6 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl)
unregister_pm_notifier(&di->pm_notifier);
cancel_delayed_work_sync(&di->monitor_work);
cancel_delayed_work_sync(&di->set_charged_work);
destroy_workqueue(di->monitor_wqueue);
}

View File

@ -166,7 +166,7 @@ static int gab_probe(struct platform_device *pdev)
if (!adc_bat)
return -ENOMEM;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = adc_bat;
psy_desc = &adc_bat->psy_desc;
psy_desc->name = dev_name(&pdev->dev);

View File

@ -333,7 +333,7 @@ static int gpio_charger_probe(struct platform_device *pdev)
charger_desc->property_is_writeable =
gpio_charger_property_is_writeable;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
psy_cfg.drv_data = gpio_charger;
if (pdata) {

View File

@ -146,7 +146,7 @@ static int ingenic_battery_probe(struct platform_device *pdev)
desc->num_properties = ARRAY_SIZE(ingenic_battery_properties);
desc->get_property = ingenic_battery_get_property;
psy_cfg.drv_data = bat;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
bat->battery = devm_power_supply_register(dev, desc, &psy_cfg);
if (IS_ERR(bat->battery))

View File

@ -848,7 +848,7 @@ static int ip5xxx_power_probe(struct i2c_client *client)
fields = (const struct ip5xxx_regfield_config *)of_id->data;
ip5xxx_setup_regs(dev, ip5xxx, fields);
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
psy_cfg.drv_data = ip5xxx;
psy = devm_power_supply_register(dev, &ip5xxx_battery_desc, &psy_cfg);

View File

@ -23,6 +23,7 @@
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/property.h>
struct lego_ev3_battery {
struct iio_channel *iio_v;
@ -198,7 +199,7 @@ static int lego_ev3_battery_probe(struct platform_device *pdev)
batt->v_min = 48000000;
}
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = batt;
batt->psy = devm_power_supply_register(dev, &lego_ev3_battery_desc,

View File

@ -131,7 +131,7 @@ static int lt3651_charger_probe(struct platform_device *pdev)
charger_desc->properties = lt3651_charger_properties;
charger_desc->num_properties = ARRAY_SIZE(lt3651_charger_properties);
charger_desc->get_property = lt3651_charger_get_property;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = lt3651_charger;
lt3651_charger->charger = devm_power_supply_register(&pdev->dev,

View File

@ -1119,7 +1119,7 @@ static const struct regmap_config ltc4162l_regmap_config = {
.writeable_reg = ltc4162l_is_writeable_reg,
.volatile_reg = ltc4162l_is_volatile_reg,
.max_register = LTC4162L_INPUT_UNDERVOLTAGE_DAC,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static void ltc4162l_clear_interrupts(struct ltc4162l_info *info)
@ -1185,7 +1185,7 @@ static int ltc4162l_probe(struct i2c_client *client)
if (!device_property_read_u32(dev, "lltc,cell-count", &value))
info->cell_count = value;
ltc4162l_config.of_node = dev->of_node;
ltc4162l_config.fwnode = dev_fwnode(dev);
ltc4162l_config.drv_data = info;
ltc4162l_config.attr_grp = ltc4162l_attr_groups;

View File

@ -1066,7 +1066,7 @@ static int max17042_probe(struct i2c_client *client, struct device *dev, int irq
dev_set_drvdata(dev, chip);
psy_cfg.drv_data = chip;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
/* When current is not measured,
* CURRENT_NOW and CURRENT_AVG properties should be invisible. */

View File

@ -29,6 +29,11 @@
/* ModelGauge m5 */
#define MAX172XX_STATUS 0x00 /* Status */
#define MAX172XX_STATUS_BAT_ABSENT BIT(3) /* Battery absent */
#define MAX172XX_STATUS_IMX BIT(6) /* Maximum Current Alert Threshold Exceeded */
#define MAX172XX_STATUS_VMN BIT(8) /* Minimum Voltage Alert Threshold Exceeded */
#define MAX172XX_STATUS_TMN BIT(9) /* Minimum Temperature Alert Threshold Exceeded */
#define MAX172XX_STATUS_VMX BIT(12) /* Maximum Voltage Alert Threshold Exceeded */
#define MAX172XX_STATUS_TMX BIT(13) /* Maximum Temperature Alert Threshold Exceeded */
#define MAX172XX_REPCAP 0x05 /* Average capacity */
#define MAX172XX_REPSOC 0x06 /* Percentage of charge */
#define MAX172XX_TEMP 0x08 /* Temperature */
@ -114,7 +119,7 @@ static const struct regmap_config max1720x_regmap_cfg = {
.val_format_endian = REGMAP_ENDIAN_LITTLE,
.rd_table = &max1720x_readable_regs,
.volatile_table = &max1720x_volatile_regs,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_range max1720x_nvmem_allow[] = {
@ -250,6 +255,7 @@ static const struct nvmem_cell_info max1720x_nvmem_cells[] = {
};
static const enum power_supply_property max1720x_battery_props[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
@ -302,7 +308,7 @@ static int max172xx_temperature_to_ps(unsigned int reg)
/*
* Calculating current registers resolution:
*
* RSense stored in 10^-5 Ohm, so mesaurment voltage must be
* RSense stored in 10^-5 Ohm, so measurement voltage must be
* in 10^-11 Volts for get current in uA.
* 16 bit current reg fullscale +/-51.2mV is 102400 uV.
* So: 102400 / 65535 * 10^5 = 156252
@ -314,6 +320,43 @@ static int max172xx_current_to_voltage(unsigned int reg)
return val * 156252;
}
static int max172xx_battery_health(struct max1720x_device_info *info,
unsigned int *health)
{
unsigned int status;
int ret;
ret = regmap_read(info->regmap, MAX172XX_STATUS, &status);
if (ret < 0)
return ret;
if (status & MAX172XX_STATUS_VMN)
*health = POWER_SUPPLY_HEALTH_DEAD;
else if (status & MAX172XX_STATUS_VMX)
*health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
else if (status & MAX172XX_STATUS_TMN)
*health = POWER_SUPPLY_HEALTH_COLD;
else if (status & MAX172XX_STATUS_TMX)
*health = POWER_SUPPLY_HEALTH_OVERHEAT;
else if (status & MAX172XX_STATUS_IMX)
*health = POWER_SUPPLY_HEALTH_OVERCURRENT;
else
*health = POWER_SUPPLY_HEALTH_GOOD;
/* Clear events which are not self-clearing to detect next events */
if (status > 0 && status != MAX172XX_STATUS_IMX) {
ret = regmap_set_bits(info->regmap, MAX172XX_STATUS,
MAX172XX_STATUS_VMN |
MAX172XX_STATUS_VMX |
MAX172XX_STATUS_TMN |
MAX172XX_STATUS_TMX);
if (ret < 0)
return ret;
}
return 0;
}
static int max1720x_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@ -323,6 +366,10 @@ static int max1720x_battery_get_property(struct power_supply *psy,
int ret = 0;
switch (psp) {
case POWER_SUPPLY_PROP_HEALTH:
ret = max172xx_battery_health(info, &reg_val);
val->intval = reg_val;
break;
case POWER_SUPPLY_PROP_PRESENT:
/*
* POWER_SUPPLY_PROP_PRESENT will always readable via

View File

@ -298,7 +298,7 @@ static int max77650_charger_probe(struct platform_device *pdev)
chg->dev = dev;
pscfg.of_node = dev->of_node;
pscfg.fwnode = dev_fwnode(dev);
pscfg.drv_data = chg;
chg_irq = platform_get_irq_byname(pdev, "CHG");

View File

@ -608,7 +608,7 @@ static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg
case 4700000:
case 4800000:
case 4900000:
data = (uvolt - 4700000) / 100000;
data = ((uvolt - 4700000) / 100000) + 1;
break;
default:
dev_err(chg->dev, "Wrong value for charge input voltage regulation threshold\n");

View File

@ -349,7 +349,7 @@ static int max8903_probe(struct platform_device *pdev)
data->psy_desc.properties = max8903_charger_props;
data->psy_desc.num_properties = ARRAY_SIZE(max8903_charger_props);
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
psy_cfg.drv_data = data;
data->psy = devm_power_supply_register(dev, &data->psy_desc, &psy_cfg);

View File

@ -274,7 +274,7 @@ static int mm8013_probe(struct i2c_client *client)
return dev_err_probe(dev, ret, "MM8013 not found\n");
psy_cfg.drv_data = chip;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
psy = devm_power_supply_register(dev, &mm8013_desc, &psy_cfg);
if (IS_ERR(psy))

View File

@ -810,7 +810,7 @@ static int mt6360_charger_probe(struct platform_device *pdev)
memcpy(&mci->psy_desc, &mt6360_charger_desc, sizeof(mci->psy_desc));
mci->psy_desc.name = dev_name(&pdev->dev);
charger_cfg.drv_data = mci;
charger_cfg.of_node = pdev->dev.of_node;
charger_cfg.fwnode = dev_fwnode(&pdev->dev);
mci->psy = devm_power_supply_register(&pdev->dev,
&mci->psy_desc, &charger_cfg);
if (IS_ERR(mci->psy))

View File

@ -752,7 +752,7 @@ static int mt6370_chg_init_psy(struct mt6370_priv *priv)
{
struct power_supply_config cfg = {
.drv_data = priv,
.of_node = dev_of_node(priv->dev),
.fwnode = dev_fwnode(priv->dev),
};
priv->psy = devm_power_supply_register(priv->dev, &mt6370_chg_psy_desc,
@ -772,7 +772,6 @@ static void mt6370_chg_destroy_wq(void *data)
{
struct workqueue_struct *wq = data;
flush_workqueue(wq);
destroy_workqueue(wq);
}

View File

@ -674,7 +674,7 @@ static int olpc_battery_probe(struct platform_device *pdev)
/* Ignore the status. It doesn't actually matter */
ac_psy_cfg.of_node = pdev->dev.of_node;
ac_psy_cfg.fwnode = dev_fwnode(&pdev->dev);
ac_psy_cfg.drv_data = data;
data->olpc_ac = devm_power_supply_register(&pdev->dev, &olpc_ac_desc,
@ -692,7 +692,7 @@ static int olpc_battery_probe(struct platform_device *pdev)
olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props);
}
bat_psy_cfg.of_node = pdev->dev.of_node;
bat_psy_cfg.fwnode = dev_fwnode(&pdev->dev);
bat_psy_cfg.drv_data = data;
bat_psy_cfg.attr_grp = olpc_bat_sysfs_groups;

View File

@ -1,466 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* NXP PCF50633 Main Battery Charger Driver
*
* (C) 2006-2008 by Openmoko, Inc.
* Author: Balaji Rao <balajirrao@openmoko.org>
* All rights reserved.
*
* Broken down from monstrous PCF50633 driver mainly by
* Harald Welte, Andy Green and Werner Almesberger
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/mbc.h>
struct pcf50633_mbc {
struct pcf50633 *pcf;
int adapter_online;
int usb_online;
struct power_supply *usb;
struct power_supply *adapter;
struct power_supply *ac;
};
int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
{
struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
int ret = 0;
u8 bits;
u8 mbcs2, chgmod;
unsigned int mbcc5;
if (ma >= 1000) {
bits = PCF50633_MBCC7_USB_1000mA;
ma = 1000;
} else if (ma >= 500) {
bits = PCF50633_MBCC7_USB_500mA;
ma = 500;
} else if (ma >= 100) {
bits = PCF50633_MBCC7_USB_100mA;
ma = 100;
} else {
bits = PCF50633_MBCC7_USB_SUSPEND;
ma = 0;
}
ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
PCF50633_MBCC7_USB_MASK, bits);
if (ret)
dev_err(pcf->dev, "error setting usb curlim to %d mA\n", ma);
else
dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
/*
* We limit the charging current to be the USB current limit.
* The reason is that on pcf50633, when it enters PMU Standby mode,
* which it does when the device goes "off", the USB current limit
* reverts to the variant default. In at least one common case, that
* default is 500mA. By setting the charging current to be the same
* as the USB limit we set here before PMU standby, we enforce it only
* using the correct amount of current even when the USB current limit
* gets reset to the wrong thing
*/
if (mbc->pcf->pdata->charger_reference_current_ma) {
mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma;
if (mbcc5 > 255)
mbcc5 = 255;
pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
}
mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
/* If chgmod == BATFULL, setting chgena has no effect.
* Datasheet says we need to set resume instead but when autoresume is
* used resume doesn't work. Clear and set chgena instead.
*/
if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
else {
pcf50633_reg_clear_bits(pcf, PCF50633_REG_MBCC1,
PCF50633_MBCC1_CHGENA);
pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
}
power_supply_changed(mbc->usb);
return ret;
}
EXPORT_SYMBOL_GPL(pcf50633_mbc_usb_curlim_set);
int pcf50633_mbc_get_status(struct pcf50633 *pcf)
{
struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
int status = 0;
u8 chgmod;
if (!mbc)
return 0;
chgmod = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2)
& PCF50633_MBCS2_MBC_MASK;
if (mbc->usb_online)
status |= PCF50633_MBC_USB_ONLINE;
if (chgmod == PCF50633_MBCS2_MBC_USB_PRE ||
chgmod == PCF50633_MBCS2_MBC_USB_PRE_WAIT ||
chgmod == PCF50633_MBCS2_MBC_USB_FAST ||
chgmod == PCF50633_MBCS2_MBC_USB_FAST_WAIT)
status |= PCF50633_MBC_USB_ACTIVE;
if (mbc->adapter_online)
status |= PCF50633_MBC_ADAPTER_ONLINE;
if (chgmod == PCF50633_MBCS2_MBC_ADP_PRE ||
chgmod == PCF50633_MBCS2_MBC_ADP_PRE_WAIT ||
chgmod == PCF50633_MBCS2_MBC_ADP_FAST ||
chgmod == PCF50633_MBCS2_MBC_ADP_FAST_WAIT)
status |= PCF50633_MBC_ADAPTER_ACTIVE;
return status;
}
EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status);
int pcf50633_mbc_get_usb_online_status(struct pcf50633 *pcf)
{
struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
if (!mbc)
return 0;
return mbc->usb_online;
}
EXPORT_SYMBOL_GPL(pcf50633_mbc_get_usb_online_status);
static ssize_t
show_chgmode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
u8 mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
u8 chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
return sysfs_emit(buf, "%d\n", chgmod);
}
static DEVICE_ATTR(chgmode, S_IRUGO, show_chgmode, NULL);
static ssize_t
show_usblim(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
PCF50633_MBCC7_USB_MASK;
unsigned int ma;
if (usblim == PCF50633_MBCC7_USB_1000mA)
ma = 1000;
else if (usblim == PCF50633_MBCC7_USB_500mA)
ma = 500;
else if (usblim == PCF50633_MBCC7_USB_100mA)
ma = 100;
else
ma = 0;
return sysfs_emit(buf, "%u\n", ma);
}
static ssize_t set_usblim(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
unsigned long ma;
int ret;
ret = kstrtoul(buf, 10, &ma);
if (ret)
return ret;
pcf50633_mbc_usb_curlim_set(mbc->pcf, ma);
return count;
}
static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim);
static ssize_t
show_chglim(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
u8 mbcc5 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC5);
unsigned int ma;
if (!mbc->pcf->pdata->charger_reference_current_ma)
return -ENODEV;
ma = (mbc->pcf->pdata->charger_reference_current_ma * mbcc5) >> 8;
return sysfs_emit(buf, "%u\n", ma);
}
static ssize_t set_chglim(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
unsigned long ma;
unsigned int mbcc5;
int ret;
if (!mbc->pcf->pdata->charger_reference_current_ma)
return -ENODEV;
ret = kstrtoul(buf, 10, &ma);
if (ret)
return ret;
mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma;
if (mbcc5 > 255)
mbcc5 = 255;
pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
return count;
}
/*
* This attribute allows to change MBC charging limit on the fly
* independently of usb current limit. It also gets set automatically every
* time usb current limit is changed.
*/
static DEVICE_ATTR(chg_curlim, S_IRUGO | S_IWUSR, show_chglim, set_chglim);
static struct attribute *pcf50633_mbc_sysfs_attrs[] = {
&dev_attr_chgmode.attr,
&dev_attr_usb_curlim.attr,
&dev_attr_chg_curlim.attr,
NULL,
};
ATTRIBUTE_GROUPS(pcf50633_mbc_sysfs);
static void
pcf50633_mbc_irq_handler(int irq, void *data)
{
struct pcf50633_mbc *mbc = data;
/* USB */
if (irq == PCF50633_IRQ_USBINS) {
mbc->usb_online = 1;
} else if (irq == PCF50633_IRQ_USBREM) {
mbc->usb_online = 0;
pcf50633_mbc_usb_curlim_set(mbc->pcf, 0);
}
/* Adapter */
if (irq == PCF50633_IRQ_ADPINS)
mbc->adapter_online = 1;
else if (irq == PCF50633_IRQ_ADPREM)
mbc->adapter_online = 0;
power_supply_changed(mbc->ac);
power_supply_changed(mbc->usb);
power_supply_changed(mbc->adapter);
if (mbc->pcf->pdata->mbc_event_callback)
mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq);
}
static int adapter_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy);
int ret = 0;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = mbc->adapter_online;
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int usb_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy);
int ret = 0;
u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
PCF50633_MBCC7_USB_MASK;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = mbc->usb_online &&
(usblim <= PCF50633_MBCC7_USB_500mA);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int ac_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy);
int ret = 0;
u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
PCF50633_MBCC7_USB_MASK;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = mbc->usb_online &&
(usblim == PCF50633_MBCC7_USB_1000mA);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static enum power_supply_property power_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
static const u8 mbc_irq_handlers[] = {
PCF50633_IRQ_ADPINS,
PCF50633_IRQ_ADPREM,
PCF50633_IRQ_USBINS,
PCF50633_IRQ_USBREM,
PCF50633_IRQ_BATFULL,
PCF50633_IRQ_CHGHALT,
PCF50633_IRQ_THLIMON,
PCF50633_IRQ_THLIMOFF,
PCF50633_IRQ_USBLIMON,
PCF50633_IRQ_USBLIMOFF,
PCF50633_IRQ_LOWSYS,
PCF50633_IRQ_LOWBAT,
};
static const struct power_supply_desc pcf50633_mbc_adapter_desc = {
.name = "adapter",
.type = POWER_SUPPLY_TYPE_MAINS,
.properties = power_props,
.num_properties = ARRAY_SIZE(power_props),
.get_property = &adapter_get_property,
};
static const struct power_supply_desc pcf50633_mbc_usb_desc = {
.name = "usb",
.type = POWER_SUPPLY_TYPE_USB,
.properties = power_props,
.num_properties = ARRAY_SIZE(power_props),
.get_property = usb_get_property,
};
static const struct power_supply_desc pcf50633_mbc_ac_desc = {
.name = "ac",
.type = POWER_SUPPLY_TYPE_MAINS,
.properties = power_props,
.num_properties = ARRAY_SIZE(power_props),
.get_property = ac_get_property,
};
static int pcf50633_mbc_probe(struct platform_device *pdev)
{
struct power_supply_config psy_cfg = {};
struct power_supply_config usb_psy_cfg;
struct pcf50633_mbc *mbc;
int i;
u8 mbcs1;
mbc = devm_kzalloc(&pdev->dev, sizeof(*mbc), GFP_KERNEL);
if (!mbc)
return -ENOMEM;
platform_set_drvdata(pdev, mbc);
mbc->pcf = dev_to_pcf50633(pdev->dev.parent);
/* Set up IRQ handlers */
for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
pcf50633_register_irq(mbc->pcf, mbc_irq_handlers[i],
pcf50633_mbc_irq_handler, mbc);
psy_cfg.supplied_to = mbc->pcf->pdata->batteries;
psy_cfg.num_supplicants = mbc->pcf->pdata->num_batteries;
psy_cfg.drv_data = mbc;
/* Create power supplies */
mbc->adapter = devm_power_supply_register(&pdev->dev,
&pcf50633_mbc_adapter_desc,
&psy_cfg);
if (IS_ERR(mbc->adapter)) {
dev_err(mbc->pcf->dev, "failed to register adapter\n");
return PTR_ERR(mbc->adapter);
}
usb_psy_cfg = psy_cfg;
usb_psy_cfg.attr_grp = pcf50633_mbc_sysfs_groups;
mbc->usb = devm_power_supply_register(&pdev->dev,
&pcf50633_mbc_usb_desc,
&usb_psy_cfg);
if (IS_ERR(mbc->usb)) {
dev_err(mbc->pcf->dev, "failed to register usb\n");
return PTR_ERR(mbc->usb);
}
mbc->ac = devm_power_supply_register(&pdev->dev,
&pcf50633_mbc_ac_desc,
&psy_cfg);
if (IS_ERR(mbc->ac)) {
dev_err(mbc->pcf->dev, "failed to register ac\n");
return PTR_ERR(mbc->ac);
}
mbcs1 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS1);
if (mbcs1 & PCF50633_MBCS1_USBPRES)
pcf50633_mbc_irq_handler(PCF50633_IRQ_USBINS, mbc);
if (mbcs1 & PCF50633_MBCS1_ADAPTPRES)
pcf50633_mbc_irq_handler(PCF50633_IRQ_ADPINS, mbc);
return 0;
}
static void pcf50633_mbc_remove(struct platform_device *pdev)
{
struct pcf50633_mbc *mbc = platform_get_drvdata(pdev);
int i;
/* Remove IRQ handlers */
for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
pcf50633_free_irq(mbc->pcf, mbc_irq_handlers[i]);
}
static struct platform_driver pcf50633_mbc_driver = {
.driver = {
.name = "pcf50633-mbc",
},
.probe = pcf50633_mbc_probe,
.remove = pcf50633_mbc_remove,
};
module_platform_driver(pcf50633_mbc_driver);
MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
MODULE_DESCRIPTION("PCF50633 mbc driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pcf50633-mbc");

View File

@ -210,7 +210,7 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
bat->vbat_now = bat->last_ocv;
psy_cfg.drv_data = bat;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
bat->battery = devm_power_supply_register(dev, &pm8916_bms_vm_battery_psy_desc, &psy_cfg);
if (IS_ERR(bat->battery))

View File

@ -322,7 +322,7 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev)
dev_err_probe(dev, ret, "Error while parsing device tree\n");
psy_cfg.drv_data = chg;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
chg->charger = devm_power_supply_register(dev, &pm8916_lbc_charger_psy_desc, &psy_cfg);
if (IS_ERR(chg->charger))

View File

@ -200,11 +200,11 @@ static int __power_supply_populate_supplied_from(struct power_supply *epsy,
int i = 0;
do {
np = of_parse_phandle(psy->of_node, "power-supplies", i++);
np = of_parse_phandle(psy->dev.of_node, "power-supplies", i++);
if (!np)
break;
if (np == epsy->of_node) {
if (np == epsy->dev.of_node) {
dev_dbg(&psy->dev, "%s: Found supply : %s\n",
psy->desc->name, epsy->desc->name);
psy->supplied_from[i-1] = (char *)epsy->desc->name;
@ -235,7 +235,7 @@ static int __power_supply_find_supply_from_node(struct power_supply *epsy,
struct device_node *np = data;
/* returning non-zero breaks out of power_supply_for_each_psy loop */
if (epsy->of_node == np)
if (epsy->dev.of_node == np)
return 1;
return 0;
@ -270,13 +270,13 @@ static int power_supply_check_supplies(struct power_supply *psy)
return 0;
/* No device node found, nothing to do */
if (!psy->of_node)
if (!psy->dev.of_node)
return 0;
do {
int ret;
np = of_parse_phandle(psy->of_node, "power-supplies", cnt++);
np = of_parse_phandle(psy->dev.of_node, "power-supplies", cnt++);
if (!np)
break;
@ -449,19 +449,6 @@ int power_supply_get_property_from_supplier(struct power_supply *psy,
}
EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier);
int power_supply_set_battery_charged(struct power_supply *psy)
{
if (atomic_read(&psy->use_cnt) >= 0 &&
psy->desc->type == POWER_SUPPLY_TYPE_BATTERY &&
psy->desc->set_charged) {
psy->desc->set_charged(psy);
return 0;
}
return -EINVAL;
}
EXPORT_SYMBOL_GPL(power_supply_set_battery_charged);
static int power_supply_match_device_by_name(struct device *dev, const void *data)
{
const char *name = data;
@ -606,8 +593,8 @@ int power_supply_get_battery_info(struct power_supply *psy,
const __be32 *list;
u32 min_max[2];
if (psy->of_node) {
battery_np = of_parse_phandle(psy->of_node, "monitored-battery", 0);
if (psy->dev.of_node) {
battery_np = of_parse_phandle(psy->dev.of_node, "monitored-battery", 0);
if (!battery_np)
return -ENODEV;
@ -1544,9 +1531,8 @@ __power_supply_register(struct device *parent,
if (cfg) {
dev->groups = cfg->attr_grp;
psy->drv_data = cfg->drv_data;
psy->of_node =
dev->of_node =
cfg->fwnode ? to_of_node(cfg->fwnode) : cfg->of_node;
dev->of_node = psy->of_node;
psy->supplied_to = cfg->supplied_to;
psy->num_supplicants = cfg->num_supplicants;
}

View File

@ -8,6 +8,7 @@
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/power_supply.h>
#include <linux/property.h>
#include <linux/soc/qcom/pdr.h>
#include <linux/soc/qcom/pmic_glink.h>
#include <linux/math.h>
@ -1336,10 +1337,10 @@ static int qcom_battmgr_probe(struct auxiliary_device *adev,
battmgr->dev = dev;
psy_cfg.drv_data = battmgr;
psy_cfg.of_node = adev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&adev->dev);
psy_cfg_supply.drv_data = battmgr;
psy_cfg_supply.of_node = adev->dev.of_node;
psy_cfg_supply.fwnode = dev_fwnode(&adev->dev);
psy_cfg_supply.supplied_to = qcom_battmgr_battery;
psy_cfg_supply.num_supplicants = 1;

View File

@ -964,7 +964,7 @@ static int smb2_probe(struct platform_device *pdev)
return rc;
supply_config.drv_data = chip;
supply_config.of_node = pdev->dev.of_node;
supply_config.fwnode = dev_fwnode(&pdev->dev);
desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL);
if (!desc)

View File

@ -880,7 +880,7 @@ static int smbb_charger_probe(struct platform_device *pdev)
}
bat_cfg.drv_data = chg;
bat_cfg.of_node = pdev->dev.of_node;
bat_cfg.fwnode = dev_fwnode(&pdev->dev);
chg->bat_psy = devm_power_supply_register(&pdev->dev,
&bat_psy_desc,
&bat_cfg);

View File

@ -1088,7 +1088,7 @@ static int rk817_charger_probe(struct platform_device *pdev)
rk817_bat_calib_vol(charger);
pscfg.drv_data = charger;
pscfg.of_node = node;
pscfg.fwnode = node ? &node->fwnode : NULL;
/*
* Get sample resistor value. Note only values of 10000 or 20000

View File

@ -160,7 +160,7 @@ static int rt5033_battery_probe(struct i2c_client *client)
}
i2c_set_clientdata(client, battery);
psy_cfg.of_node = client->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&client->dev);
psy_cfg.drv_data = battery;
battery->psy = devm_power_supply_register(&client->dev,

View File

@ -16,6 +16,7 @@
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/mfd/rt5033-private.h>
#include <linux/property.h>
struct rt5033_charger_data {
unsigned int pre_uamp;
@ -675,7 +676,7 @@ static int rt5033_charger_probe(struct platform_device *pdev)
charger->regmap = dev_get_regmap(pdev->dev.parent, NULL);
mutex_init(&charger->lock);
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = charger;
charger->psy = devm_power_supply_register(charger->dev,

View File

@ -1579,7 +1579,7 @@ static const struct regmap_config rt9455_regmap_config = {
.writeable_reg = rt9455_is_writeable_reg,
.volatile_reg = rt9455_is_volatile_reg,
.max_register = RT9455_REG_MASK3,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static int rt9455_probe(struct i2c_client *client)
@ -1658,7 +1658,7 @@ static int rt9455_probe(struct i2c_client *client)
INIT_DEFERRABLE_WORK(&info->batt_presence_work,
rt9455_batt_presence_work_callback);
rt9455_charger_config.of_node = dev->of_node;
rt9455_charger_config.fwnode = dev_fwnode(dev);
rt9455_charger_config.drv_data = info;
rt9455_charger_config.supplied_to = rt9455_charger_supplied_to;
rt9455_charger_config.num_supplicants =

View File

@ -826,7 +826,7 @@ static int rt9467_register_psy(struct rt9467_chg_data *data)
{
struct power_supply_config cfg = {
.drv_data = data,
.of_node = dev_of_node(data->dev),
.fwnode = dev_fwnode(data->dev),
.attr_grp = rt9467_sysfs_groups,
};

View File

@ -723,7 +723,7 @@ static int rt9471_register_psy(struct rt9471_chip *chip)
char *psy_name;
cfg.drv_data = chip;
cfg.of_node = dev->of_node;
cfg.fwnode = dev_fwnode(dev);
cfg.attr_grp = rt9471_sysfs_groups;
psy_name = devm_kasprintf(dev, GFP_KERNEL, "rt9471-%s", dev_name(dev));

View File

@ -1138,7 +1138,7 @@ static int sbs_probe(struct i2c_client *client)
chip->flags = (uintptr_t)i2c_get_match_data(client);
chip->client = client;
psy_cfg.of_node = client->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&client->dev);
psy_cfg.drv_data = chip;
chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
sbs_invalidate_cached_props(chip);

View File

@ -173,7 +173,7 @@ static int sbs_probe(struct i2c_client *client)
return -ENOMEM;
chip->client = client;
psy_cfg.of_node = client->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&client->dev);
psy_cfg.drv_data = chip;
i2c_set_clientdata(client, chip);

View File

@ -379,7 +379,7 @@ static int sbsm_probe(struct i2c_client *client)
return ret;
psy_cfg.drv_data = data;
psy_cfg.of_node = dev->of_node;
psy_cfg.fwnode = dev_fwnode(dev);
data->psy = devm_power_supply_register(dev, psy_desc, &psy_cfg);
if (IS_ERR(data->psy))
return dev_err_probe(dev, PTR_ERR(data->psy),

View File

@ -480,7 +480,7 @@ static int sc2731_charger_probe(struct platform_device *pdev)
}
charger_cfg.drv_data = info;
charger_cfg.of_node = np;
charger_cfg.fwnode = dev_fwnode(&pdev->dev);
info->psy_usb = devm_power_supply_register(&pdev->dev,
&sc2731_charger_desc,
&charger_cfg);

View File

@ -1014,9 +1014,8 @@ static int sc27xx_fgu_hw_init(struct sc27xx_fgu_data *data)
if (!table)
return -EINVAL;
data->cap_table = devm_kmemdup(data->dev, table,
data->table_len * sizeof(*table),
GFP_KERNEL);
data->cap_table = devm_kmemdup_array(data->dev, table, data->table_len,
sizeof(*table), GFP_KERNEL);
if (!data->cap_table) {
power_supply_put_battery_info(data->battery, info);
return -ENOMEM;
@ -1141,7 +1140,6 @@ disable_fgu:
static int sc27xx_fgu_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct power_supply_config fgu_cfg = { };
struct sc27xx_fgu_data *data;
int ret, irq;
@ -1205,7 +1203,7 @@ static int sc27xx_fgu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
fgu_cfg.drv_data = data;
fgu_cfg.of_node = np;
fgu_cfg.fwnode = dev_fwnode(dev);
data->battery = devm_power_supply_register(dev, &sc27xx_fgu_desc,
&fgu_cfg);
if (IS_ERR(data->battery)) {

View File

@ -1488,7 +1488,7 @@ static const struct regmap_config smb347_regmap = {
.max_register = SMB347_MAX_REGISTER,
.volatile_reg = smb347_volatile_reg,
.readable_reg = smb347_readable_reg,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static const struct regulator_ops smb347_usb_vbus_regulator_ops = {
@ -1553,7 +1553,7 @@ static int smb347_probe(struct i2c_client *client)
return PTR_ERR(smb->regmap);
mains_usb_cfg.drv_data = smb;
mains_usb_cfg.of_node = dev->of_node;
mains_usb_cfg.fwnode = dev_fwnode(dev);
if (smb->use_mains) {
smb->mains = devm_power_supply_register(dev, &smb347_mains_desc,
&mains_usb_cfg);

View File

@ -259,7 +259,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
psy_cfg.supplied_to = pdata->supplied_to;
psy_cfg.num_supplicants = pdata->num_supplicants;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.fwnode = dev_fwnode(&pdev->dev);
psy_cfg.drv_data = cdata;
cdata->ac = devm_power_supply_register(&pdev->dev, &tps65090_charger_desc,

View File

@ -198,7 +198,7 @@ static int tps65217_charger_probe(struct platform_device *pdev)
charger->tps = tps;
charger->dev = &pdev->dev;
cfg.of_node = pdev->dev.of_node;
cfg.fwnode = dev_fwnode(&pdev->dev);
cfg.drv_data = charger;
charger->psy = devm_power_supply_register(&pdev->dev,

View File

@ -560,7 +560,7 @@ static int ucs1002_probe(struct i2c_client *client)
irq_a_det = of_irq_get_byname(dev->of_node, "a_det");
irq_alert = of_irq_get_byname(dev->of_node, "alert");
charger_config.of_node = dev->of_node;
charger_config.fwnode = dev_fwnode(dev);
charger_config.drv_data = info;
ret = regmap_read(info->regmap, UCS1002_REG_PRODUCT_ID, &regval);

View File

@ -62,6 +62,7 @@ struct bq27xxx_device_info {
struct bq27xxx_reg_cache cache;
int charge_design_full;
int voltage_min_design;
int voltage_max_design;
bool removed;
unsigned long last_update;
union power_supply_propval last_status;

View File

@ -274,7 +274,6 @@ struct power_supply_desc {
int (*property_is_writeable)(struct power_supply *psy,
enum power_supply_property psp);
void (*external_power_changed)(struct power_supply *psy);
void (*set_charged)(struct power_supply *psy);
/*
* Set if thermal zone should not be created for this power supply.
@ -316,7 +315,6 @@ struct power_supply {
char **supplied_from;
size_t num_supplies;
struct device_node *of_node;
/* Driver private data */
void *drv_data;
@ -852,7 +850,6 @@ extern int power_supply_am_i_supplied(struct power_supply *psy);
int power_supply_get_property_from_supplier(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val);
extern int power_supply_set_battery_charged(struct power_supply *psy);
static inline bool
power_supply_supports_maintenance_charging(struct power_supply_battery_info *info)