diff options
Diffstat (limited to 'drivers/power')
65 files changed, 789 insertions, 637 deletions
diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c index c2801bd6384d..e9fe08ee3812 100644 --- a/drivers/power/reset/at91-sama5d2_shdwc.c +++ b/drivers/power/reset/at91-sama5d2_shdwc.c @@ -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. */ } }; diff --git a/drivers/power/reset/ltc2952-poweroff.c b/drivers/power/reset/ltc2952-poweroff.c index 1a6fc8d38e20..90c664d344d0 100644 --- a/drivers/power/reset/ltc2952-poweroff.c +++ b/drivers/power/reset/ltc2952-poweroff.c @@ -162,11 +162,11 @@ static void ltc2952_poweroff_default(struct ltc2952_poweroff *data) data->wde_interval = 300L * NSEC_PER_MSEC; data->trigger_delay = ktime_set(2, 500L * NSEC_PER_MSEC); - hrtimer_init(&data->timer_trigger, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - data->timer_trigger.function = ltc2952_poweroff_timer_trigger; + hrtimer_setup(&data->timer_trigger, ltc2952_poweroff_timer_trigger, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); - hrtimer_init(&data->timer_wde, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - data->timer_wde.function = ltc2952_poweroff_timer_wde; + hrtimer_setup(&data->timer_wde, ltc2952_poweroff_timer_wde, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); } static int ltc2952_poweroff_init(struct platform_device *pdev) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 7b18358f194a..8dbd39afa43c 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -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 @@ -583,6 +577,12 @@ config CHARGER_MAX77693 help Say Y to enable support for the Maxim MAX77693 battery charger. +config CHARGER_MAX77705 + tristate "Maxim MAX77705 battery charger driver" + depends on MFD_MAX77705 + help + Say Y to enable support for the Maxim MAX77705 battery charger. + config CHARGER_MAX77976 tristate "Maxim MAX77976 battery charger driver" depends on I2C diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index b55cc48a4c86..61677be328b0 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -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 @@ -80,6 +79,7 @@ obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o obj-$(CONFIG_CHARGER_DETECTOR_MAX14656) += max14656_charger_detector.o obj-$(CONFIG_CHARGER_MAX77650) += max77650-charger.o obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o +obj-$(CONFIG_CHARGER_MAX77705) += max77705_charger.o obj-$(CONFIG_CHARGER_MAX77976) += max77976_charger.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index 7a8d1feb8e90..dc6c8b0dd1cf 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -1787,13 +1787,12 @@ static int ab8500_chargalg_probe(struct platform_device *pdev) psy_cfg.drv_data = di; /* Initilialize safety timer */ - hrtimer_init(&di->safety_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - di->safety_timer.function = ab8500_chargalg_safety_timer_expired; + hrtimer_setup(&di->safety_timer, ab8500_chargalg_safety_timer_expired, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); /* Initilialize maintenance timer */ - hrtimer_init(&di->maintenance_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - di->maintenance_timer.function = - ab8500_chargalg_maintenance_timer_expired; + hrtimer_setup(&di->maintenance_timer, ab8500_chargalg_maintenance_timer_expired, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); /* Init work for chargalg */ INIT_DEFERRABLE_WORK(&di->chargalg_periodic_work, diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 1042d37424f5..5f4537766e5b 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -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; diff --git a/drivers/power/supply/acer_a500_battery.c b/drivers/power/supply/acer_a500_battery.c index 39d85b11a13c..daf01dc8025b 100644 --- a/drivers/power/supply/acer_a500_battery.c +++ b/drivers/power/supply/acer_a500_battery.c @@ -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; diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c index b2b82f97a471..3901a02f326a 100644 --- a/drivers/power/supply/act8945a_charger.c +++ b/drivers/power/supply/act8945a_charger.c @@ -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, diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c index e5733cb9e19e..5f6ea416fa30 100644 --- a/drivers/power/supply/axp20x_ac_power.c +++ b/drivers/power/supply/axp20x_ac_power.c @@ -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, diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c index 3c3158f31a48..50ca8e110085 100644 --- a/drivers/power/supply/axp20x_battery.c +++ b/drivers/power/supply/axp20x_battery.c @@ -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); diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c index 9722912268fe..e75d1e377ac1 100644 --- a/drivers/power/supply/axp20x_usb_power.c +++ b/drivers/power/supply/axp20x_usb_power.c @@ -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, diff --git a/drivers/power/supply/bd99954-charger.c b/drivers/power/supply/bd99954-charger.c index 54bf88262510..d03a70cf8406 100644 --- a/drivers/power/supply/bd99954-charger.c +++ b/drivers/power/supply/bd99954-charger.c @@ -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); diff --git a/drivers/power/supply/bq2415x_charger.c b/drivers/power/supply/bq2415x_charger.c index 22f6a3b71632..9e3b9181ee76 100644 --- a/drivers/power/supply/bq2415x_charger.c +++ b/drivers/power/supply/bq2415x_charger.c @@ -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, }; diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index b4ba01744368..f0d97ab45bd8 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -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, diff --git a/drivers/power/supply/bq24257_charger.c b/drivers/power/supply/bq24257_charger.c index 1416586f2459..766eecb35694 100644 --- a/drivers/power/supply/bq24257_charger.c +++ b/drivers/power/supply/bq24257_charger.c @@ -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, }; diff --git a/drivers/power/supply/bq24735-charger.c b/drivers/power/supply/bq24735-charger.c index 73a7fc867b03..637e0da65f87 100644 --- a/drivers/power/supply/bq24735-charger.c +++ b/drivers/power/supply/bq24735-charger.c @@ -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); diff --git a/drivers/power/supply/bq2515x_charger.c b/drivers/power/supply/bq2515x_charger.c index a3424f67f2b1..437bff5bc420 100644 --- a/drivers/power/supply/bq2515x_charger.c +++ b/drivers/power/supply/bq2515x_charger.c @@ -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) { diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c index 5514d1896bb8..9f9b6019f8e1 100644 --- a/drivers/power/supply/bq256xx_charger.c +++ b/drivers/power/supply/bq256xx_charger.c @@ -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); diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c index 2f5ceaf00b94..868e86e1749b 100644 --- a/drivers/power/supply/bq25890_charger.c +++ b/drivers/power/supply/bq25890_charger.c @@ -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, diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c index 0c5e2938bb36..4ff76e3dddf6 100644 --- a/drivers/power/supply/bq25980_charger.c +++ b/drivers/power/supply/bq25980_charger.c @@ -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); diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 90a5bccfc6b9..2f31d750a4c1 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -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 @@ -2045,6 +2049,35 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di, } /* + * 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, }; diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c index 813037c00ded..8106d1edcbc2 100644 --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -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, diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c index 6625d539d9ae..13300dc60baf 100644 --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -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); diff --git a/drivers/power/supply/da9030_battery.c b/drivers/power/supply/da9030_battery.c index ac2e319e9517..d25279c26030 100644 --- a/drivers/power/supply/da9030_battery.c +++ b/drivers/power/supply/da9030_battery.c @@ -502,8 +502,7 @@ static int da9030_battery_probe(struct platform_device *pdev) /* 10 seconds between monitor runs unless platform defines other interval */ - charger->interval = msecs_to_jiffies( - (pdata->batmon_interval ? : 10) * 1000); + charger->interval = secs_to_jiffies(pdata->batmon_interval ? : 10); charger->charge_milliamp = pdata->charge_milliamp; charger->charge_millivolt = pdata->charge_millivolt; diff --git a/drivers/power/supply/ds2760_battery.c b/drivers/power/supply/ds2760_battery.c index 83bdec5a2bda..5badf58c6edb 100644 --- a/drivers/power/supply/ds2760_battery.c +++ b/drivers/power/supply/ds2760_battery.c @@ -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); } diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c index d5d215f5ad8b..f5f2566b3a32 100644 --- a/drivers/power/supply/generic-adc-battery.c +++ b/drivers/power/supply/generic-adc-battery.c @@ -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); diff --git a/drivers/power/supply/gpio-charger.c b/drivers/power/supply/gpio-charger.c index 46d18ce6a739..1dfd5b0cb30d 100644 --- a/drivers/power/supply/gpio-charger.c +++ b/drivers/power/supply/gpio-charger.c @@ -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) { diff --git a/drivers/power/supply/ingenic-battery.c b/drivers/power/supply/ingenic-battery.c index 0a40f425c277..b111c7ce2be3 100644 --- a/drivers/power/supply/ingenic-battery.c +++ b/drivers/power/supply/ingenic-battery.c @@ -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)) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index c448e0ac0dfa..24eea7a91b30 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -828,10 +828,9 @@ static void ip5xxx_setup_regs(struct device *dev, struct ip5xxx *ip5xxx, static int ip5xxx_power_probe(struct i2c_client *client) { - const struct ip5xxx_regfield_config *fields = &ip51xx_fields; + const struct ip5xxx_regfield_config *fields; struct power_supply_config psy_cfg = {}; struct device *dev = &client->dev; - const struct of_device_id *of_id; struct power_supply *psy; struct ip5xxx *ip5xxx; @@ -843,12 +842,10 @@ static int ip5xxx_power_probe(struct i2c_client *client) if (IS_ERR(ip5xxx->regmap)) return PTR_ERR(ip5xxx->regmap); - of_id = i2c_of_match_device(dev->driver->of_match_table, client); - if (of_id) - fields = (const struct ip5xxx_regfield_config *)of_id->data; + fields = i2c_get_match_data(client) ?: &ip51xx_fields; 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); diff --git a/drivers/power/supply/lego_ev3_battery.c b/drivers/power/supply/lego_ev3_battery.c index 9085de0ae1b2..28454de05761 100644 --- a/drivers/power/supply/lego_ev3_battery.c +++ b/drivers/power/supply/lego_ev3_battery.c @@ -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, diff --git a/drivers/power/supply/lt3651-charger.c b/drivers/power/supply/lt3651-charger.c index 8de500ffad95..ebfbdbcb7683 100644 --- a/drivers/power/supply/lt3651-charger.c +++ b/drivers/power/supply/lt3651-charger.c @@ -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, diff --git a/drivers/power/supply/ltc4162-l-charger.c b/drivers/power/supply/ltc4162-l-charger.c index 23eb426295db..9dd74fa9552d 100644 --- a/drivers/power/supply/ltc4162-l-charger.c +++ b/drivers/power/supply/ltc4162-l-charger.c @@ -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; diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index 655b3f25dbd7..acea176101fa 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -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. */ diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c index 11580e414713..ea3912fd1de8 100644 --- a/drivers/power/supply/max1720x_battery.c +++ b/drivers/power/supply/max1720x_battery.c @@ -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, ®_val); + val->intval = reg_val; + break; case POWER_SUPPLY_PROP_PRESENT: /* * POWER_SUPPLY_PROP_PRESENT will always readable via diff --git a/drivers/power/supply/max77650-charger.c b/drivers/power/supply/max77650-charger.c index 5f58c0c24b4d..4ae43668992e 100644 --- a/drivers/power/supply/max77650-charger.c +++ b/drivers/power/supply/max77650-charger.c @@ -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"); diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c index cdea35c0d1de..027d6a539b65 100644 --- a/drivers/power/supply/max77693_charger.c +++ b/drivers/power/supply/max77693_charger.c @@ -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"); diff --git a/drivers/power/supply/max77705_charger.c b/drivers/power/supply/max77705_charger.c new file mode 100644 index 000000000000..eec5e9ef795e --- /dev/null +++ b/drivers/power/supply/max77705_charger.c @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Based on max77650-charger.c + * + * Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.org> + * + * Battery charger driver for MAXIM 77705 charger/power-supply. + */ + +#include <linux/devm-helpers.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/mfd/max77693-common.h> +#include <linux/mfd/max77705-private.h> +#include <linux/power/max77705_charger.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/power_supply.h> +#include <linux/regmap.h> + +static const char *max77705_charger_model = "max77705"; +static const char *max77705_charger_manufacturer = "Maxim Integrated"; + +static const struct regmap_config max77705_chg_regmap_config = { + .reg_base = MAX77705_CHG_REG_BASE, + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX77705_CHG_REG_SAFEOUT_CTRL, +}; + +static enum power_supply_property max77705_charger_props[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, +}; + +static int max77705_chgin_irq(void *irq_drv_data) +{ + struct max77705_charger_data *charger = irq_drv_data; + + queue_work(charger->wqueue, &charger->chgin_work); + + return 0; +} + +static const struct regmap_irq max77705_charger_irqs[] = { + { .mask = MAX77705_BYP_IM, }, + { .mask = MAX77705_INP_LIMIT_IM, }, + { .mask = MAX77705_BATP_IM, }, + { .mask = MAX77705_BAT_IM, }, + { .mask = MAX77705_CHG_IM, }, + { .mask = MAX77705_WCIN_IM, }, + { .mask = MAX77705_CHGIN_IM, }, + { .mask = MAX77705_AICL_IM, }, +}; + +static struct regmap_irq_chip max77705_charger_irq_chip = { + .name = "max77705-charger", + .status_base = MAX77705_CHG_REG_INT, + .mask_base = MAX77705_CHG_REG_INT_MASK, + .handle_post_irq = max77705_chgin_irq, + .num_regs = 1, + .irqs = max77705_charger_irqs, + .num_irqs = ARRAY_SIZE(max77705_charger_irqs), +}; + +static int max77705_charger_enable(struct max77705_charger_data *chg) +{ + int rv; + + rv = regmap_update_bits(chg->regmap, MAX77705_CHG_REG_CNFG_09, + MAX77705_CHG_EN_MASK, MAX77705_CHG_EN_MASK); + if (rv) + dev_err(chg->dev, "unable to enable the charger: %d\n", rv); + + return rv; +} + +static void max77705_charger_disable(void *data) +{ + struct max77705_charger_data *chg = data; + int rv; + + rv = regmap_update_bits(chg->regmap, + MAX77705_CHG_REG_CNFG_09, + MAX77705_CHG_EN_MASK, + MAX77705_CHG_DISABLE); + if (rv) + dev_err(chg->dev, "unable to disable the charger: %d\n", rv); +} + +static int max77705_get_online(struct regmap *regmap, int *val) +{ + unsigned int data; + int ret; + + ret = regmap_read(regmap, MAX77705_CHG_REG_INT_OK, &data); + if (ret < 0) + return ret; + + *val = !!(data & MAX77705_CHGIN_OK); + + return 0; +} + +static int max77705_check_battery(struct max77705_charger_data *charger, int *val) +{ + unsigned int reg_data; + unsigned int reg_data2; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_INT_OK, ®_data); + + dev_dbg(charger->dev, "CHG_INT_OK(0x%x)\n", reg_data); + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, ®_data2); + + dev_dbg(charger->dev, "CHG_DETAILS00(0x%x)\n", reg_data2); + + if ((reg_data & MAX77705_BATP_OK) || !(reg_data2 & MAX77705_BATP_DTLS)) + *val = true; + else + *val = false; + + return 0; +} + +static int max77705_get_charge_type(struct max77705_charger_data *charger, int *val) +{ + struct regmap *regmap = charger->regmap; + unsigned int reg_data; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data); + if (!MAX77705_CHARGER_CHG_CHARGING(reg_data)) { + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; + return 0; + } + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, ®_data); + reg_data &= MAX77705_CHG_DTLS; + + switch (reg_data) { + case 0x0: + case MAX77705_CHARGER_CONSTANT_CURRENT: + case MAX77705_CHARGER_CONSTANT_VOLTAGE: + *val = POWER_SUPPLY_CHARGE_TYPE_FAST; + return 0; + default: + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; + return 0; + } + + return 0; +} + +static int max77705_get_status(struct max77705_charger_data *charger, int *val) +{ + struct regmap *regmap = charger->regmap; + unsigned int reg_data; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data); + if (!MAX77705_CHARGER_CHG_CHARGING(reg_data)) { + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; + return 0; + } + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, ®_data); + reg_data &= MAX77705_CHG_DTLS; + + switch (reg_data) { + case 0x0: + case MAX77705_CHARGER_CONSTANT_CURRENT: + case MAX77705_CHARGER_CONSTANT_VOLTAGE: + *val = POWER_SUPPLY_STATUS_CHARGING; + return 0; + case MAX77705_CHARGER_END_OF_CHARGE: + case MAX77705_CHARGER_DONE: + *val = POWER_SUPPLY_STATUS_FULL; + return 0; + /* those values hard coded as in vendor kernel, because of */ + /* failure to determine it's actual meaning. */ + case 0x05: + case 0x06: + case 0x07: + *val = POWER_SUPPLY_STATUS_NOT_CHARGING; + return 0; + case 0x08: + case 0xA: + case 0xB: + *val = POWER_SUPPLY_STATUS_DISCHARGING; + return 0; + default: + *val = POWER_SUPPLY_STATUS_UNKNOWN; + return 0; + } + + return 0; +} + +static int max77705_get_vbus_state(struct regmap *regmap, int *value) +{ + int ret; + unsigned int charge_dtls; + + ret = regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, &charge_dtls); + if (ret) + return ret; + + charge_dtls = ((charge_dtls & MAX77705_CHGIN_DTLS) >> + MAX77705_CHGIN_DTLS_SHIFT); + + switch (charge_dtls) { + case 0x00: + *value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE; + break; + case 0x01: + *value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE; + break; + case 0x02: + *value = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + break; + case 0x03: + *value = POWER_SUPPLY_HEALTH_GOOD; + break; + default: + return 0; + } + return 0; +} + +static int max77705_get_battery_health(struct max77705_charger_data *charger, + int *value) +{ + struct regmap *regmap = charger->regmap; + unsigned int bat_dtls; + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, &bat_dtls); + bat_dtls = ((bat_dtls & MAX77705_BAT_DTLS) >> MAX77705_BAT_DTLS_SHIFT); + + switch (bat_dtls) { + case MAX77705_BATTERY_NOBAT: + dev_dbg(charger->dev, "%s: No battery and the charger is suspended\n", + __func__); + *value = POWER_SUPPLY_HEALTH_NO_BATTERY; + break; + case MAX77705_BATTERY_PREQUALIFICATION: + dev_dbg(charger->dev, "%s: battery is okay but its voltage is low(~VPQLB)\n", + __func__); + break; + case MAX77705_BATTERY_DEAD: + dev_dbg(charger->dev, "%s: battery dead\n", __func__); + *value = POWER_SUPPLY_HEALTH_DEAD; + break; + case MAX77705_BATTERY_GOOD: + case MAX77705_BATTERY_LOWVOLTAGE: + *value = POWER_SUPPLY_HEALTH_GOOD; + break; + case MAX77705_BATTERY_OVERVOLTAGE: + dev_dbg(charger->dev, "%s: battery ovp\n", __func__); + *value = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + break; + default: + dev_dbg(charger->dev, "%s: battery unknown\n", __func__); + *value = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + break; + } + + return 0; +} + +static int max77705_get_health(struct max77705_charger_data *charger, int *val) +{ + struct regmap *regmap = charger->regmap; + int ret, is_online = 0; + + ret = max77705_get_online(regmap, &is_online); + if (ret) + return ret; + if (is_online) { + ret = max77705_get_vbus_state(regmap, val); + if (ret || (*val != POWER_SUPPLY_HEALTH_GOOD)) + return ret; + } + return max77705_get_battery_health(charger, val); +} + +static int max77705_get_input_current(struct max77705_charger_data *charger, + int *val) +{ + unsigned int reg_data; + int get_current = 0; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data); + + reg_data &= MAX77705_CHG_CHGIN_LIM_MASK; + + if (reg_data <= 3) + get_current = MAX77705_CURRENT_CHGIN_MIN; + else if (reg_data >= MAX77705_CHG_CHGIN_LIM_MASK) + get_current = MAX77705_CURRENT_CHGIN_MAX; + else + get_current = (reg_data + 1) * MAX77705_CURRENT_CHGIN_STEP; + + *val = get_current; + + return 0; +} + +static int max77705_get_charge_current(struct max77705_charger_data *charger, + int *val) +{ + unsigned int reg_data; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_02, ®_data); + reg_data &= MAX77705_CHG_CC; + + *val = reg_data <= 0x2 ? MAX77705_CURRENT_CHGIN_MIN : reg_data * MAX77705_CURRENT_CHG_STEP; + + return 0; +} + +static int max77705_set_float_voltage(struct max77705_charger_data *charger, + int float_voltage) +{ + int float_voltage_mv; + unsigned int reg_data = 0; + struct regmap *regmap = charger->regmap; + + float_voltage_mv = float_voltage / 1000; + reg_data = float_voltage_mv <= 4000 ? 0x0 : + float_voltage_mv >= 4500 ? 0x23 : + (float_voltage_mv <= 4200) ? (float_voltage_mv - 4000) / 50 : + (((float_voltage_mv - 4200) / 10) + 0x04); + + return regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_04, + MAX77705_CHG_CV_PRM_MASK, + (reg_data << MAX77705_CHG_CV_PRM_SHIFT)); +} + +static int max77705_get_float_voltage(struct max77705_charger_data *charger, + int *val) +{ + unsigned int reg_data = 0; + int voltage_mv; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_04, ®_data); + reg_data &= MAX77705_CHG_PRM_MASK; + voltage_mv = reg_data <= 0x04 ? reg_data * 50 + 4000 : + (reg_data - 4) * 10 + 4200; + *val = voltage_mv * 1000; + + return 0; +} + +static int max77705_chg_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max77705_charger_data *charger = power_supply_get_drvdata(psy); + struct regmap *regmap = charger->regmap; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + return max77705_get_online(regmap, &val->intval); + case POWER_SUPPLY_PROP_PRESENT: + return max77705_check_battery(charger, &val->intval); + case POWER_SUPPLY_PROP_STATUS: + return max77705_get_status(charger, &val->intval); + case POWER_SUPPLY_PROP_CHARGE_TYPE: + return max77705_get_charge_type(charger, &val->intval); + case POWER_SUPPLY_PROP_HEALTH: + return max77705_get_health(charger, &val->intval); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + return max77705_get_input_current(charger, &val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + return max77705_get_charge_current(charger, &val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + return max77705_get_float_voltage(charger, &val->intval); + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + val->intval = charger->bat_info->voltage_max_design_uv; + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = max77705_charger_model; + break; + case POWER_SUPPLY_PROP_MANUFACTURER: + val->strval = max77705_charger_manufacturer; + break; + default: + return -EINVAL; + } + return 0; +} + +static const struct power_supply_desc max77705_charger_psy_desc = { + .name = "max77705-charger", + .type = POWER_SUPPLY_TYPE_USB, + .properties = max77705_charger_props, + .num_properties = ARRAY_SIZE(max77705_charger_props), + .get_property = max77705_chg_get_property, +}; + +static void max77705_chgin_isr_work(struct work_struct *work) +{ + struct max77705_charger_data *charger = + container_of(work, struct max77705_charger_data, chgin_work); + + power_supply_changed(charger->psy_chg); +} + +static void max77705_charger_initialize(struct max77705_charger_data *chg) +{ + u8 reg_data; + struct power_supply_battery_info *info; + struct regmap *regmap = chg->regmap; + + if (power_supply_get_battery_info(chg->psy_chg, &info) < 0) + return; + + chg->bat_info = info; + + /* unlock charger setting protect */ + /* slowest LX slope */ + reg_data = MAX77705_CHGPROT_MASK | MAX77705_SLOWEST_LX_SLOPE; + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_06, reg_data, + reg_data); + + /* fast charge timer disable */ + /* restart threshold disable */ + /* pre-qual charge disable */ + reg_data = (MAX77705_FCHGTIME_DISABLE << MAX77705_FCHGTIME_SHIFT) | + (MAX77705_CHG_RSTRT_DISABLE << MAX77705_CHG_RSTRT_SHIFT) | + (MAX77705_CHG_PQEN_DISABLE << MAX77705_PQEN_SHIFT); + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_01, + (MAX77705_FCHGTIME_MASK | + MAX77705_CHG_RSTRT_MASK | + MAX77705_PQEN_MASK), + reg_data); + + /* OTG off(UNO on), boost off */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00, + MAX77705_OTG_CTRL, 0); + + /* charge current 450mA(default) */ + /* otg current limit 900mA */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_02, + MAX77705_OTG_ILIM_MASK, + MAX77705_OTG_ILIM_900 << MAX77705_OTG_ILIM_SHIFT); + + /* BAT to SYS OCP 4.80A */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_05, + MAX77705_REG_B2SOVRC_MASK, + MAX77705_B2SOVRC_4_8A << MAX77705_REG_B2SOVRC_SHIFT); + /* top off current 150mA */ + /* top off timer 30min */ + reg_data = (MAX77705_TO_ITH_150MA << MAX77705_TO_ITH_SHIFT) | + (MAX77705_TO_TIME_30M << MAX77705_TO_TIME_SHIFT) | + (MAX77705_SYS_TRACK_DISABLE << MAX77705_SYS_TRACK_DIS_SHIFT); + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_03, + (MAX77705_TO_ITH_MASK | + MAX77705_TO_TIME_MASK | + MAX77705_SYS_TRACK_DIS_MASK), reg_data); + + /* cv voltage 4.2V or 4.35V */ + /* MINVSYS 3.6V(default) */ + if (info->voltage_max_design_uv < 0) { + dev_warn(chg->dev, "missing battery:voltage-max-design-microvolt\n"); + max77705_set_float_voltage(chg, 4200000); + } else { + max77705_set_float_voltage(chg, info->voltage_max_design_uv); + } + + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, + MAX77705_VCHGIN_REG_MASK, MAX77705_VCHGIN_4_5); + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, + MAX77705_WCIN_REG_MASK, MAX77705_WCIN_4_5); + + /* Watchdog timer */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00, + MAX77705_WDTEN_MASK, 0); + + /* Active Discharge Enable */ + regmap_update_bits(regmap, MAX77705_PMIC_REG_MAINCTRL1, 1, 1); + + /* VBYPSET=5.0V */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_11, MAX77705_VBYPSET_MASK, 0); + + /* Switching Frequency : 1.5MHz */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_08, MAX77705_REG_FSW_MASK, + (MAX77705_CHG_FSW_1_5MHz << MAX77705_REG_FSW_SHIFT)); + + /* Auto skip mode */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, MAX77705_REG_DISKIP_MASK, + (MAX77705_AUTO_SKIP << MAX77705_REG_DISKIP_SHIFT)); +} + +static int max77705_charger_probe(struct i2c_client *i2c) +{ + struct power_supply_config pscfg = {}; + struct max77705_charger_data *chg; + struct device *dev; + struct regmap_irq_chip_data *irq_data; + int ret; + + dev = &i2c->dev; + + chg = devm_kzalloc(dev, sizeof(*chg), GFP_KERNEL); + if (!chg) + return -ENOMEM; + + chg->dev = dev; + i2c_set_clientdata(i2c, chg); + + chg->regmap = devm_regmap_init_i2c(i2c, &max77705_chg_regmap_config); + if (IS_ERR(chg->regmap)) + return PTR_ERR(chg->regmap); + + ret = regmap_update_bits(chg->regmap, + MAX77705_CHG_REG_INT_MASK, + MAX77705_CHGIN_IM, 0); + if (ret) + return ret; + + pscfg.fwnode = dev_fwnode(dev); + pscfg.drv_data = chg; + + chg->psy_chg = devm_power_supply_register(dev, &max77705_charger_psy_desc, &pscfg); + if (IS_ERR(chg->psy_chg)) + return PTR_ERR(chg->psy_chg); + + max77705_charger_irq_chip.irq_drv_data = chg; + ret = devm_regmap_add_irq_chip(chg->dev, chg->regmap, i2c->irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77705_charger_irq_chip, + &irq_data); + if (ret) + return dev_err_probe(dev, ret, "failed to add irq chip\n"); + + chg->wqueue = create_singlethread_workqueue(dev_name(dev)); + if (IS_ERR(chg->wqueue)) + return dev_err_probe(dev, PTR_ERR(chg->wqueue), "failed to create workqueue\n"); + + ret = devm_work_autocancel(dev, &chg->chgin_work, max77705_chgin_isr_work); + if (ret) + return dev_err_probe(dev, ret, "failed to initialize interrupt work\n"); + + max77705_charger_initialize(chg); + + ret = max77705_charger_enable(chg); + if (ret) + return dev_err_probe(dev, ret, "failed to enable charge\n"); + + return devm_add_action_or_reset(dev, max77705_charger_disable, chg); +} + +static const struct of_device_id max77705_charger_of_match[] = { + { .compatible = "maxim,max77705-charger" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77705_charger_of_match); + +static struct i2c_driver max77705_charger_driver = { + .driver = { + .name = "max77705-charger", + .of_match_table = max77705_charger_of_match, + }, + .probe = max77705_charger_probe, +}; +module_i2c_driver(max77705_charger_driver); + +MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>"); +MODULE_DESCRIPTION("Maxim MAX77705 charger driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/max8903_charger.c b/drivers/power/supply/max8903_charger.c index e65d0141f260..45fbaad6c647 100644 --- a/drivers/power/supply/max8903_charger.c +++ b/drivers/power/supply/max8903_charger.c @@ -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); diff --git a/drivers/power/supply/mm8013.c b/drivers/power/supply/mm8013.c index 4adf2acc2779..93c50cff31bc 100644 --- a/drivers/power/supply/mm8013.c +++ b/drivers/power/supply/mm8013.c @@ -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)) diff --git a/drivers/power/supply/mt6360_charger.c b/drivers/power/supply/mt6360_charger.c index e99e55148976..77747eb51667 100644 --- a/drivers/power/supply/mt6360_charger.c +++ b/drivers/power/supply/mt6360_charger.c @@ -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)) diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c index ad8793bf997e..98579998b300 100644 --- a/drivers/power/supply/mt6370-charger.c +++ b/drivers/power/supply/mt6370-charger.c @@ -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); } diff --git a/drivers/power/supply/olpc_battery.c b/drivers/power/supply/olpc_battery.c index 849f63e89ba0..b9b607822676 100644 --- a/drivers/power/supply/olpc_battery.c +++ b/drivers/power/supply/olpc_battery.c @@ -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; diff --git a/drivers/power/supply/pcf50633-charger.c b/drivers/power/supply/pcf50633-charger.c deleted file mode 100644 index 0136bc87b105..000000000000 --- a/drivers/power/supply/pcf50633-charger.c +++ /dev/null @@ -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"); diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c index 5d0dd842509c..5120be086e6f 100644 --- a/drivers/power/supply/pm8916_bms_vm.c +++ b/drivers/power/supply/pm8916_bms_vm.c @@ -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)) diff --git a/drivers/power/supply/pm8916_lbc.c b/drivers/power/supply/pm8916_lbc.c index 6d92e98cbecc..c74b75b1b267 100644 --- a/drivers/power/supply/pm8916_lbc.c +++ b/drivers/power/supply/pm8916_lbc.c @@ -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)) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 76c340b38015..33a5bfce4604 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -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; } diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index edb058c19c9c..439dd0bf8644 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -33,7 +33,7 @@ struct power_supply_attr { [POWER_SUPPLY_PROP_ ## _name] = \ { \ .prop_name = #_name, \ - .attr_name = #_name "\0", \ + .attr_name = #_name, \ .text_values = _text, \ .text_values_len = _len, \ } diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c index 47d29271ddf4..fe27676fbc7c 100644 --- a/drivers/power/supply/qcom_battmgr.c +++ b/drivers/power/supply/qcom_battmgr.c @@ -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; diff --git a/drivers/power/supply/qcom_pmi8998_charger.c b/drivers/power/supply/qcom_pmi8998_charger.c index 3b4132376649..74a8d8ed8d9f 100644 --- a/drivers/power/supply/qcom_pmi8998_charger.c +++ b/drivers/power/supply/qcom_pmi8998_charger.c @@ -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) diff --git a/drivers/power/supply/qcom_smbb.c b/drivers/power/supply/qcom_smbb.c index a79563f6ff7a..28afe758a2da 100644 --- a/drivers/power/supply/qcom_smbb.c +++ b/drivers/power/supply/qcom_smbb.c @@ -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); diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c index e5f35d083c23..945c7720c4ae 100644 --- a/drivers/power/supply/rk817_charger.c +++ b/drivers/power/supply/rk817_charger.c @@ -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 diff --git a/drivers/power/supply/rt5033_battery.c b/drivers/power/supply/rt5033_battery.c index 7a27b262fb84..b2674adfa30b 100644 --- a/drivers/power/supply/rt5033_battery.c +++ b/drivers/power/supply/rt5033_battery.c @@ -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, diff --git a/drivers/power/supply/rt5033_charger.c b/drivers/power/supply/rt5033_charger.c index d19c7e80a92a..2fdc58439707 100644 --- a/drivers/power/supply/rt5033_charger.c +++ b/drivers/power/supply/rt5033_charger.c @@ -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, diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c index 64a23e3d7bb0..1ffe7f02932f 100644 --- a/drivers/power/supply/rt9455_charger.c +++ b/drivers/power/supply/rt9455_charger.c @@ -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 = diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c index 235169c85c5d..e9aba9ad393c 100644 --- a/drivers/power/supply/rt9467-charger.c +++ b/drivers/power/supply/rt9467-charger.c @@ -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, }; diff --git a/drivers/power/supply/rt9471.c b/drivers/power/supply/rt9471.c index 67b86ac91a21..bd966abb4df5 100644 --- a/drivers/power/supply/rt9471.c +++ b/drivers/power/supply/rt9471.c @@ -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)); diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index 6f3d0413b1c1..943c82ee978f 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -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); diff --git a/drivers/power/supply/sbs-charger.c b/drivers/power/supply/sbs-charger.c index ab3f095d90ea..27764123b929 100644 --- a/drivers/power/supply/sbs-charger.c +++ b/drivers/power/supply/sbs-charger.c @@ -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); diff --git a/drivers/power/supply/sbs-manager.c b/drivers/power/supply/sbs-manager.c index 7d2f39f19acb..869729dfcd66 100644 --- a/drivers/power/supply/sbs-manager.c +++ b/drivers/power/supply/sbs-manager.c @@ -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), diff --git a/drivers/power/supply/sc2731_charger.c b/drivers/power/supply/sc2731_charger.c index 50d5157af927..58b86fd78771 100644 --- a/drivers/power/supply/sc2731_charger.c +++ b/drivers/power/supply/sc2731_charger.c @@ -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); diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c index f36edc2ba708..a7ed9de8a289 100644 --- a/drivers/power/supply/sc27xx_fuel_gauge.c +++ b/drivers/power/supply/sc27xx_fuel_gauge.c @@ -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)) { diff --git a/drivers/power/supply/smb347-charger.c b/drivers/power/supply/smb347-charger.c index c8392933ee28..8b95f7e8712f 100644 --- a/drivers/power/supply/smb347-charger.c +++ b/drivers/power/supply/smb347-charger.c @@ -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); diff --git a/drivers/power/supply/tps65090-charger.c b/drivers/power/supply/tps65090-charger.c index d65193e410a6..d010f013af8c 100644 --- a/drivers/power/supply/tps65090-charger.c +++ b/drivers/power/supply/tps65090-charger.c @@ -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, diff --git a/drivers/power/supply/tps65217_charger.c b/drivers/power/supply/tps65217_charger.c index 6fff44e1ecac..6af17ce0b204 100644 --- a/drivers/power/supply/tps65217_charger.c +++ b/drivers/power/supply/tps65217_charger.c @@ -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, diff --git a/drivers/power/supply/ucs1002_power.c b/drivers/power/supply/ucs1002_power.c index 7382bec6a43c..d32a7633f9e7 100644 --- a/drivers/power/supply/ucs1002_power.c +++ b/drivers/power/supply/ucs1002_power.c @@ -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, ®val); |