From 0188155a234bf77c7588bdedf3b77cc87bfeb7df Mon Sep 17 00:00:00 2001 From: Michael Heinemann Date: Fri, 7 Jul 2017 16:23:54 +0200 Subject: power: supply: sbs-battery: correct capacity mode selection bits The capacity mode bit is bit 15. Currently it is written as default initialized enum and never shifted. This leads to a behaviour where the BATTERY_MODE is not correctly recognized and set again. This commit initializes the enum accordingly. Signed-off-by: Michael Heinemann Tested-by: Phil Reid Signed-off-by: Sebastian Reichel --- drivers/power/supply/sbs-battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index f7059459f0fb..e8065af085bd 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -60,8 +60,8 @@ enum { #define BATTERY_MODE_OFFSET 0x03 #define BATTERY_MODE_MASK 0x8000 enum sbs_battery_mode { - BATTERY_MODE_AMPS, - BATTERY_MODE_WATTS + BATTERY_MODE_AMPS = 0, + BATTERY_MODE_WATTS = 0x8000 }; /* manufacturer access defines */ -- cgit v1.2.3 From 8b35bf5927b1e89e9b2f9ddbd701bd9b27456e78 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 21 Jul 2017 18:14:37 +0200 Subject: power: supply: cpcap-charger: add OMAP_USB2 dependency When CONFIG_OMAP_USB2 is set to 'm' and the charger driver is built-in, we get this link failure: drivers/power/supply/cpcap-charger.o: In function `cpcap_charger_probe': cpcap-charger.c:(.text+0x48c): undefined reference to `omap_usb2_set_comparator' drivers/power/supply/cpcap-charger.o: In function `cpcap_charger_remove': cpcap-charger.c:(.text+0x774): undefined reference to `omap_usb2_set_comparator' This adds a dependency to prevent that problem, while still allowing compile-testing with the OMAP_USB2 driver completely disabled. Fixes: 0c9888e3c192 ("power: supply: cpcap-charger: Add minimal CPCAP PMIC battery charger") Signed-off-by: Arnd Bergmann Signed-off-by: Sebastian Reichel --- drivers/power/supply/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 969f5005669c..765f9ac0a4e7 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -365,6 +365,7 @@ config BATTERY_RX51 config CHARGER_CPCAP tristate "CPCAP PMIC Charger Driver" depends on MFD_CPCAP && IIO + depends on OMAP_USB2 || (!OMAP_USB2 && COMPILE_TEST) default MFD_CPCAP help Say Y to enable support for CPCAP PMIC charger driver for Motorola -- cgit v1.2.3 From 648b8eba20d0bdce9de41df97677e70aa53693ea Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 16 Jul 2017 20:52:20 +0300 Subject: power: supply: act8945a_charger: fix of_irq_get() error check of_irq_get() may return any negative error number as well as 0 on failure, while the driver only checks for -EPROBE_DEFER, blithely continuing with the call to devm_request_irq() -- that function expects *unsigned int*, so would probably fail anyway when a large IRQ number resulting from a conversion of a negative error number is passed to it... This, however, is incorrect behavior -- error number is not IRQ number. Check for 'irq <= 0' instead and return -ENXIO from probe if of_irq_get() returned 0. Fixes: a09209acd6a8 ("power: supply: act8945a_charger: Add status change update support") Signed-off-by: Sergei Shtylyov Signed-off-by: Sebastian Reichel --- drivers/power/supply/act8945a_charger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c index d1eb2e359532..8e117b31ba79 100644 --- a/drivers/power/supply/act8945a_charger.c +++ b/drivers/power/supply/act8945a_charger.c @@ -596,9 +596,9 @@ static int act8945a_charger_probe(struct platform_device *pdev) return ret; irq = of_irq_get(pdev->dev.of_node, 0); - if (irq == -EPROBE_DEFER) { + if (irq <= 0) { dev_err(&pdev->dev, "failed to find IRQ number\n"); - return -EPROBE_DEFER; + return irq ?: -ENXIO; } ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed, -- cgit v1.2.3 From 2f04cd2a9b13f9d8681248f49e907051b1f1426e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:24 -0500 Subject: power: reset: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Cc: Nicolas Ferre Cc: Sebastian Reichel Cc: linux-pm@vger.kernel.org Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-sama5d2_shdwc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c index 55fce8b75245..31080c254124 100644 --- a/drivers/power/reset/at91-sama5d2_shdwc.c +++ b/drivers/power/reset/at91-sama5d2_shdwc.c @@ -171,8 +171,8 @@ static u32 at91_shdwc_get_wakeup_input(struct platform_device *pdev, for_each_child_of_node(np, cnp) { if (of_property_read_u32(cnp, "reg", &wk_input)) { - dev_warn(&pdev->dev, "reg property is missing for %s\n", - cnp->full_name); + dev_warn(&pdev->dev, "reg property is missing for %pOF\n", + cnp); continue; } -- cgit v1.2.3 From 980092efd497dd691438e086dd929c1b04ecc529 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 12 Jul 2017 17:13:22 +0530 Subject: power: supply: constify attribute_group structures. attribute_groups are not supposed to change at runtime. All functions working with attribute_groups provided by work with const attribute_group. So mark the non-const structs as const. File size before: text data bss dec hex filename 2673 400 0 3073 c01 power/supply/pcf50633-charger.o File size After adding 'const': text data bss dec hex filename 2737 336 0 3073 bed power/supply/pcf50633-charger.o Signed-off-by: Arvind Yadav Signed-off-by: Sebastian Reichel --- drivers/power/supply/pcf50633-charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/supply/pcf50633-charger.c b/drivers/power/supply/pcf50633-charger.c index b3c1873ad84d..1ad7ccce6075 100644 --- a/drivers/power/supply/pcf50633-charger.c +++ b/drivers/power/supply/pcf50633-charger.c @@ -254,7 +254,7 @@ static struct attribute *pcf50633_mbc_sysfs_entries[] = { NULL, }; -static struct attribute_group mbc_attr_group = { +static const struct attribute_group mbc_attr_group = { .name = NULL, /* put in device directory */ .attrs = pcf50633_mbc_sysfs_entries, }; -- cgit v1.2.3 From 10e48b7d73487114bdd13bc1ebd10b6ba62de25b Mon Sep 17 00:00:00 2001 From: "Alex A. Mihaylov" Date: Thu, 6 Jul 2017 16:10:16 +0300 Subject: power: supply: Add support for MAX1721x standalone fuel gauge The MAX17211 monitor a single cell pack. The MAX17215 monitor and balance a 2S or 3S pack or monitor a multiple-series cell pack. Both device use 1-Wire interfce. Signed-off-by: Alex A. Mihaylov Signed-off-by: Sebastian Reichel --- drivers/power/supply/Kconfig | 13 + drivers/power/supply/Makefile | 1 + drivers/power/supply/max1721x_battery.c | 448 ++++++++++++++++++++++++++++++++ 3 files changed, 462 insertions(+) create mode 100644 drivers/power/supply/max1721x_battery.c (limited to 'drivers') diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 969f5005669c..15c80c7f8f9e 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -313,6 +313,19 @@ config BATTERY_MAX17042 with MAX17042. This driver also supports max17047/50 chips which are improved version of max17042. +config BATTERY_MAX1721X + tristate "MAX17211/MAX17215 standalone gas-gauge" + depends on W1 + select REGMAP_W1 + help + MAX1721x is fuel-gauge systems for lithium-ion (Li+) batteries + in handheld and portable equipment. MAX17211 used with single cell + battery. MAX17215 designed for muticell battery. Both them have + OneWire (W1) host interface. + + Say Y here to enable support for the MAX17211/MAX17215 standalone + battery gas-gauge. + config BATTERY_Z2 tristate "Z2 battery driver" depends on I2C && MACH_ZIPIT2 diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index a41f40957847..509131673355 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o obj-$(CONFIG_BATTERY_DA9150) += da9150-fg.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o +obj-$(CONFIG_BATTERY_MAX1721X) += max1721x_battery.o obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_BATTERY_RT5033) += rt5033_battery.o obj-$(CONFIG_CHARGER_RT9455) += rt9455_charger.o diff --git a/drivers/power/supply/max1721x_battery.c b/drivers/power/supply/max1721x_battery.c new file mode 100644 index 000000000000..9ee601a03d9b --- /dev/null +++ b/drivers/power/supply/max1721x_battery.c @@ -0,0 +1,448 @@ +/* + * 1-Wire implementation for Maxim Semiconductor + * MAX7211/MAX17215 stanalone fuel gauge chip + * + * Copyright (C) 2017 Radioavionica Corporation + * Author: Alex A. Mihaylov + * + * Use consistent with the GNU GPL is permitted, + * provided that this copyright notice is + * preserved in its entirety in all copies and derived works. + * + */ + +#include +#include +#include +#include +#include + +#define W1_MAX1721X_FAMILY_ID 0x26 +#define DEF_DEV_NAME_MAX17211 "MAX17211" +#define DEF_DEV_NAME_MAX17215 "MAX17215" +#define DEF_DEV_NAME_UNKNOWN "UNKNOWN" +#define DEF_MFG_NAME "MAXIM" + +#define PSY_MAX_NAME_LEN 32 + +/* Number of valid register addresses in W1 mode */ +#define MAX1721X_MAX_REG_NR 0x1EF + +/* Factory settings (nonvilatile registers) (W1 specific) */ +#define MAX1721X_REG_NRSENSE 0x1CF /* RSense in 10^-5 Ohm */ +/* Strings */ +#define MAX1721X_REG_MFG_STR 0x1CC +#define MAX1721X_REG_MFG_NUMB 3 +#define MAX1721X_REG_DEV_STR 0x1DB +#define MAX1721X_REG_DEV_NUMB 5 +/* HEX Strings */ +#define MAX1721X_REG_SER_HEX 0x1D8 + +/* MAX172XX Output Registers for W1 chips */ +#define MAX172XX_REG_STATUS 0x000 /* status reg */ +#define MAX172XX_BAT_PRESENT (1<<4) /* battery connected bit */ +#define MAX172XX_REG_DEVNAME 0x021 /* chip config */ +#define MAX172XX_DEV_MASK 0x000F /* chip type mask */ +#define MAX172X1_DEV 0x0001 +#define MAX172X5_DEV 0x0005 +#define MAX172XX_REG_TEMP 0x008 /* Temperature */ +#define MAX172XX_REG_BATT 0x0DA /* Battery voltage */ +#define MAX172XX_REG_CURRENT 0x00A /* Actual current */ +#define MAX172XX_REG_AVGCURRENT 0x00B /* Average current */ +#define MAX172XX_REG_REPSOC 0x006 /* Percentage of charge */ +#define MAX172XX_REG_DESIGNCAP 0x018 /* Design capacity */ +#define MAX172XX_REG_REPCAP 0x005 /* Average capacity */ +#define MAX172XX_REG_TTE 0x011 /* Time to empty */ +#define MAX172XX_REG_TTF 0x020 /* Time to full */ + +struct max17211_device_info { + char name[PSY_MAX_NAME_LEN]; + struct power_supply *bat; + struct power_supply_desc bat_desc; + struct device *w1_dev; + struct regmap *regmap; + /* battery design format */ + unsigned int rsense; /* in tenths uOhm */ + char DeviceName[2 * MAX1721X_REG_DEV_NUMB + 1]; + char ManufacturerName[2 * MAX1721X_REG_MFG_NUMB + 1]; + char SerialNumber[13]; /* see get_sn_str() later for comment */ +}; + +/* Convert regs value to power_supply units */ + +static inline int max172xx_time_to_ps(unsigned int reg) +{ + return reg * 5625 / 1000; /* in sec. */ +} + +static inline int max172xx_percent_to_ps(unsigned int reg) +{ + return reg / 256; /* in percent from 0 to 100 */ +} + +static inline int max172xx_voltage_to_ps(unsigned int reg) +{ + return reg * 1250; /* in uV */ +} + +static inline int max172xx_capacity_to_ps(unsigned int reg) +{ + return reg * 500; /* in uAh */ +} + +/* + * Current and temperature is signed values, so unsigned regs + * value must be converted to signed type + */ + +static inline int max172xx_temperature_to_ps(unsigned int reg) +{ + int val = (int16_t)(reg); + + return val * 10 / 256; /* in tenths of deg. C */ +} + +/* + * Calculating current registers resolution: + * + * RSense stored in 10^-5 Ohm, so mesaurment 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 + */ +static inline int max172xx_current_to_voltage(unsigned int reg) +{ + int val = (int16_t)(reg); + + return val * 156252; +} + + +static inline struct max17211_device_info * +to_device_info(struct power_supply *psy) +{ + return power_supply_get_drvdata(psy); +} + +static int max1721x_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max17211_device_info *info = to_device_info(psy); + unsigned int reg = 0; + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_PRESENT: + /* + * POWER_SUPPLY_PROP_PRESENT will always readable via + * sysfs interface. Value return 0 if battery not + * present or unaccesable via W1. + */ + val->intval = + regmap_read(info->regmap, MAX172XX_REG_STATUS, + ®) ? 0 : !(reg & MAX172XX_BAT_PRESENT); + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret = regmap_read(info->regmap, MAX172XX_REG_REPSOC, ®); + val->intval = max172xx_percent_to_ps(reg); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = regmap_read(info->regmap, MAX172XX_REG_BATT, ®); + val->intval = max172xx_voltage_to_ps(reg); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + ret = regmap_read(info->regmap, MAX172XX_REG_DESIGNCAP, ®); + val->intval = max172xx_capacity_to_ps(reg); + break; + case POWER_SUPPLY_PROP_CHARGE_AVG: + ret = regmap_read(info->regmap, MAX172XX_REG_REPCAP, ®); + val->intval = max172xx_capacity_to_ps(reg); + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: + ret = regmap_read(info->regmap, MAX172XX_REG_TTE, ®); + val->intval = max172xx_time_to_ps(reg); + break; + case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: + ret = regmap_read(info->regmap, MAX172XX_REG_TTF, ®); + val->intval = max172xx_time_to_ps(reg); + break; + case POWER_SUPPLY_PROP_TEMP: + ret = regmap_read(info->regmap, MAX172XX_REG_TEMP, ®); + val->intval = max172xx_temperature_to_ps(reg); + break; + /* We need signed current, so must cast info->rsense to signed type */ + case POWER_SUPPLY_PROP_CURRENT_NOW: + ret = regmap_read(info->regmap, MAX172XX_REG_CURRENT, ®); + val->intval = + max172xx_current_to_voltage(reg) / (int)info->rsense; + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + ret = regmap_read(info->regmap, MAX172XX_REG_AVGCURRENT, ®); + val->intval = + max172xx_current_to_voltage(reg) / (int)info->rsense; + break; + /* + * Strings already received and inited by probe. + * We do dummy read for check battery still available. + */ + case POWER_SUPPLY_PROP_MODEL_NAME: + ret = regmap_read(info->regmap, MAX1721X_REG_DEV_STR, ®); + val->strval = info->DeviceName; + break; + case POWER_SUPPLY_PROP_MANUFACTURER: + ret = regmap_read(info->regmap, MAX1721X_REG_MFG_STR, ®); + val->strval = info->ManufacturerName; + break; + case POWER_SUPPLY_PROP_SERIAL_NUMBER: + ret = regmap_read(info->regmap, MAX1721X_REG_SER_HEX, ®); + val->strval = info->SerialNumber; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static enum power_supply_property max1721x_battery_props[] = { + /* int */ + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_AVG, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CURRENT_AVG, + /* strings */ + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + +static int get_string(struct max17211_device_info *info, + uint16_t reg, uint8_t nr, char *str) +{ + unsigned int val; + + if (!str || !(reg == MAX1721X_REG_MFG_STR || + reg == MAX1721X_REG_DEV_STR)) + return -EFAULT; + + while (nr--) { + if (regmap_read(info->regmap, reg++, &val)) + return -EFAULT; + *str++ = val>>8 & 0x00FF; + *str++ = val & 0x00FF; + } + return 0; +} + +/* Maxim say: Serial number is a hex string up to 12 hex characters */ +static int get_sn_string(struct max17211_device_info *info, char *str) +{ + unsigned int val[3]; + + if (!str) + return -EFAULT; + + if (regmap_read(info->regmap, MAX1721X_REG_SER_HEX, &val[0])) + return -EFAULT; + if (regmap_read(info->regmap, MAX1721X_REG_SER_HEX + 1, &val[1])) + return -EFAULT; + if (regmap_read(info->regmap, MAX1721X_REG_SER_HEX + 2, &val[2])) + return -EFAULT; + + snprintf(str, 13, "%04X%04X%04X", val[0], val[1], val[2]); + return 0; +} + +/* + * MAX1721x registers description for w1-regmap + */ +static const struct regmap_range max1721x_allow_range[] = { + regmap_reg_range(0, 0xDF), /* volatile data */ + regmap_reg_range(0x180, 0x1DF), /* non-volatile memory */ + regmap_reg_range(0x1E0, 0x1EF), /* non-volatile history (unused) */ +}; + +static const struct regmap_range max1721x_deny_range[] = { + /* volatile data unused registers */ + regmap_reg_range(0x24, 0x26), + regmap_reg_range(0x30, 0x31), + regmap_reg_range(0x33, 0x34), + regmap_reg_range(0x37, 0x37), + regmap_reg_range(0x3B, 0x3C), + regmap_reg_range(0x40, 0x41), + regmap_reg_range(0x43, 0x44), + regmap_reg_range(0x47, 0x49), + regmap_reg_range(0x4B, 0x4C), + regmap_reg_range(0x4E, 0xAF), + regmap_reg_range(0xB1, 0xB3), + regmap_reg_range(0xB5, 0xB7), + regmap_reg_range(0xBF, 0xD0), + regmap_reg_range(0xDB, 0xDB), + /* hole between volatile and non-volatile registers */ + regmap_reg_range(0xE0, 0x17F), +}; + +static const struct regmap_access_table max1721x_regs = { + .yes_ranges = max1721x_allow_range, + .n_yes_ranges = ARRAY_SIZE(max1721x_allow_range), + .no_ranges = max1721x_deny_range, + .n_no_ranges = ARRAY_SIZE(max1721x_deny_range), +}; + +/* + * Model Gauge M5 Algorithm output register + * Volatile data (must not be cached) + */ +static const struct regmap_range max1721x_volatile_allow[] = { + regmap_reg_range(0, 0xDF), +}; + +static const struct regmap_access_table max1721x_volatile_regs = { + .yes_ranges = max1721x_volatile_allow, + .n_yes_ranges = ARRAY_SIZE(max1721x_volatile_allow), +}; + +/* + * W1-regmap config + */ +static const struct regmap_config max1721x_regmap_w1_config = { + .reg_bits = 16, + .val_bits = 16, + .rd_table = &max1721x_regs, + .volatile_table = &max1721x_volatile_regs, + .max_register = MAX1721X_MAX_REG_NR, +}; + +static int devm_w1_max1721x_add_device(struct w1_slave *sl) +{ + struct power_supply_config psy_cfg = {}; + struct max17211_device_info *info; + + info = devm_kzalloc(&sl->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + sl->family_data = (void *)info; + info->w1_dev = &sl->dev; + + /* + * power_supply class battery name translated from W1 slave device + * unical ID (look like 26-0123456789AB) to "max1721x-0123456789AB\0" + * so, 26 (device family) correcpondent to max1721x devices. + * Device name still unical for any numbers connected devices. + */ + snprintf(info->name, sizeof(info->name), + "max1721x-%012X", (unsigned int)sl->reg_num.id); + info->bat_desc.name = info->name; + + /* + * FixMe: battery device name exceed max len for thermal_zone device + * name and translation to thermal_zone must be disabled. + */ + info->bat_desc.no_thermal = true; + info->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; + info->bat_desc.properties = max1721x_battery_props; + info->bat_desc.num_properties = ARRAY_SIZE(max1721x_battery_props); + info->bat_desc.get_property = max1721x_battery_get_property; + psy_cfg.drv_data = info; + + /* regmap init */ + info->regmap = devm_regmap_init_w1(info->w1_dev, + &max1721x_regmap_w1_config); + if (IS_ERR(info->regmap)) { + int err = PTR_ERR(info->regmap); + + dev_err(info->w1_dev, "Failed to allocate register map: %d\n", + err); + return err; + } + + /* rsense init */ + info->rsense = 0; + if (regmap_read(info->regmap, MAX1721X_REG_NRSENSE, &info->rsense)) { + dev_err(info->w1_dev, "Can't read RSense. Hardware error.\n"); + return -ENODEV; + } + + if (!info->rsense) { + dev_warn(info->w1_dev, "RSenese not calibrated, set 10 mOhms!\n"); + info->rsense = 1000; /* in regs in 10^-5 */ + } + dev_info(info->w1_dev, "RSense: %d mOhms.\n", info->rsense / 100); + + if (get_string(info, MAX1721X_REG_MFG_STR, + MAX1721X_REG_MFG_NUMB, info->ManufacturerName)) { + dev_err(info->w1_dev, "Can't read manufacturer. Hardware error.\n"); + return -ENODEV; + } + + if (!info->ManufacturerName[0]) + strncpy(info->ManufacturerName, DEF_MFG_NAME, + 2 * MAX1721X_REG_MFG_NUMB); + + if (get_string(info, MAX1721X_REG_DEV_STR, + MAX1721X_REG_DEV_NUMB, info->DeviceName)) { + dev_err(info->w1_dev, "Can't read device. Hardware error.\n"); + return -ENODEV; + } + if (!info->DeviceName[0]) { + unsigned int dev_name; + + if (regmap_read(info->regmap, + MAX172XX_REG_DEVNAME, &dev_name)) { + dev_err(info->w1_dev, "Can't read device name reg.\n"); + return -ENODEV; + } + + switch (dev_name & MAX172XX_DEV_MASK) { + case MAX172X1_DEV: + strncpy(info->DeviceName, DEF_DEV_NAME_MAX17211, + 2 * MAX1721X_REG_DEV_NUMB); + break; + case MAX172X5_DEV: + strncpy(info->DeviceName, DEF_DEV_NAME_MAX17215, + 2 * MAX1721X_REG_DEV_NUMB); + break; + default: + strncpy(info->DeviceName, DEF_DEV_NAME_UNKNOWN, + 2 * MAX1721X_REG_DEV_NUMB); + } + } + + if (get_sn_string(info, info->SerialNumber)) { + dev_err(info->w1_dev, "Can't read serial. Hardware error.\n"); + return -ENODEV; + } + + info->bat = devm_power_supply_register(&sl->dev, &info->bat_desc, + &psy_cfg); + if (IS_ERR(info->bat)) { + dev_err(info->w1_dev, "failed to register battery\n"); + return PTR_ERR(info->bat); + } + + return 0; +} + +static struct w1_family_ops w1_max1721x_fops = { + .add_slave = devm_w1_max1721x_add_device, +}; + +static struct w1_family w1_max1721x_family = { + .fid = W1_MAX1721X_FAMILY_ID, + .fops = &w1_max1721x_fops, +}; + +module_w1_family(w1_max1721x_family); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alex A. Mihaylov "); +MODULE_DESCRIPTION("Maxim MAX17211/MAX17215 Fuel Gauage IC driver"); +MODULE_ALIAS("w1-family-" __stringify(W1_MAX1721X_FAMILY_ID)); -- cgit v1.2.3 From 6d1eebc99bd5ed17ad6d8554be7b76bde2238e4a Mon Sep 17 00:00:00 2001 From: Phil Reid Date: Tue, 11 Jul 2017 17:43:41 +0800 Subject: power: supply: sbs-battery: Remove FSF mailing address from comments checkpatch issued an error in having the FSF address in the comment. As address may change and Linux already includes a copy. Signed-off-by: Phil Reid Signed-off-by: Sebastian Reichel --- drivers/power/supply/sbs-battery.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index e8065af085bd..f3489856af18 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -12,10 +12,6 @@ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -- cgit v1.2.3 From b70f0a28966082d5392f90c2d4cb1514a2d65ac6 Mon Sep 17 00:00:00 2001 From: Phil Reid Date: Tue, 11 Jul 2017 17:43:42 +0800 Subject: power: supply: sbs-battery: sort includes Sort the header includes prior to adding to the list. Signed-off-by: Phil Reid Signed-off-by: Sebastian Reichel --- drivers/power/supply/sbs-battery.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index f3489856af18..a5eacc4b35e3 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -14,19 +14,18 @@ * more details. */ -#include -#include -#include #include -#include +#include #include -#include +#include #include -#include +#include +#include #include -#include - #include +#include +#include +#include enum { REG_MANUFACTURER_DATA, -- cgit v1.2.3 From adcf04c9f8fce54e65f11bae2fbd37c1282ef128 Mon Sep 17 00:00:00 2001 From: Phil Reid Date: Tue, 11 Jul 2017 17:43:43 +0800 Subject: power: supply: sbs-battery: Add delay when changing capacity mode bit At least with the Inspired Energy compatible batteries a delay is required after setting the capacity mode bit from amp to watts or the reverse. Setting the bit and then immediately pooling the status register results in an unknown error being returned in the register. Add the delay results in and ok status being return. This was also seen when reading the charge and energy registers where the wrong value was returned for the requested mode. Signed-off-by: Phil Reid Tested-by: Michael Heinemann Signed-off-by: Sebastian Reichel --- drivers/power/supply/sbs-battery.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index a5eacc4b35e3..b19a73176910 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -14,6 +14,7 @@ * more details. */ +#include #include #include #include @@ -527,6 +528,8 @@ static enum sbs_battery_mode sbs_set_battery_mode(struct i2c_client *client, if (ret < 0) return ret; + usleep_range(1000, 2000); + return original_val & BATTERY_MODE_MASK; } -- cgit v1.2.3 From 63e67c5769c23e0af729ecc2d28e4326f3a67a08 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Sun, 16 Jul 2017 11:33:06 +0200 Subject: power: supply: ltc2941-battery-gauge: Prepare for LTC2942 and LTC2944 In order to support LTC2942 which has temperature registers at different offsets than LTC2943 use following register naming scheme (prefixes): - LTC294X_ common registers - LTC2942_ chips specific registers - LTC2943_ specific registers LTC2944 is compatible with LTC2943 but uses different constants to compute voltage and current, so replace num_regs misused for device indentification with real device id to discriminate between those two. There are no functional changes. Signed-off-by: Ladislav Michl Acked-by: Dragos Bogdan Tested-by: Dragos Bogdan Signed-off-by: Sebastian Reichel --- drivers/power/supply/ltc2941-battery-gauge.c | 63 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c index 7efb908f4451..b0de448a226b 100644 --- a/drivers/power/supply/ltc2941-battery-gauge.c +++ b/drivers/power/supply/ltc2941-battery-gauge.c @@ -34,16 +34,19 @@ enum ltc294x_reg { LTC294X_REG_CONTROL = 0x01, LTC294X_REG_ACC_CHARGE_MSB = 0x02, LTC294X_REG_ACC_CHARGE_LSB = 0x03, - LTC294X_REG_THRESH_HIGH_MSB = 0x04, - LTC294X_REG_THRESH_HIGH_LSB = 0x05, - LTC294X_REG_THRESH_LOW_MSB = 0x06, - LTC294X_REG_THRESH_LOW_LSB = 0x07, - LTC294X_REG_VOLTAGE_MSB = 0x08, - LTC294X_REG_VOLTAGE_LSB = 0x09, - LTC294X_REG_CURRENT_MSB = 0x0E, - LTC294X_REG_CURRENT_LSB = 0x0F, - LTC294X_REG_TEMPERATURE_MSB = 0x14, - LTC294X_REG_TEMPERATURE_LSB = 0x15, + LTC294X_REG_VOLTAGE_MSB = 0x08, + LTC294X_REG_VOLTAGE_LSB = 0x09, + LTC2942_REG_TEMPERATURE_MSB = 0x0C, + LTC2942_REG_TEMPERATURE_LSB = 0x0D, + LTC2943_REG_CURRENT_MSB = 0x0E, + LTC2943_REG_CURRENT_LSB = 0x0F, + LTC2943_REG_TEMPERATURE_MSB = 0x14, + LTC2943_REG_TEMPERATURE_LSB = 0x15, +}; + +enum ltc294x_id { + LTC2941_ID, + LTC2943_ID, }; #define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6)) @@ -54,15 +57,12 @@ enum ltc294x_reg { ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK) #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0 -#define LTC2941_NUM_REGS 0x08 -#define LTC2943_NUM_REGS 0x18 - struct ltc294x_info { struct i2c_client *client; /* I2C Client pointer */ struct power_supply *supply; /* Supply pointer */ struct power_supply_desc supply_desc; /* Supply description */ struct delayed_work work; /* Work scheduler */ - unsigned long num_regs; /* Number of registers (chip type) */ + enum ltc294x_id id; /* Chip type */ int charge; /* Last charge register content */ int r_sense; /* mOhm */ int Qlsb; /* nAh */ @@ -146,7 +146,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp) control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) | LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED; /* Put the 2943 into "monitor" mode, so it measures every 10 sec */ - if (info->num_regs == LTC2943_NUM_REGS) + if (info->id == LTC2941_ID) control |= LTC2943_REG_CONTROL_MODE_SCAN; if (value != control) { @@ -263,7 +263,7 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val) s32 value; ret = ltc294x_read_regs(info->client, - LTC294X_REG_CURRENT_MSB, &datar[0], 2); + LTC2943_REG_CURRENT_MSB, &datar[0], 2); value = (datar[0] << 8) | datar[1]; value -= 0x7FFF; /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm, @@ -280,7 +280,7 @@ static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val) u32 value; ret = ltc294x_read_regs(info->client, - LTC294X_REG_TEMPERATURE_MSB, &datar[0], 2); + LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2); value = (datar[0] << 8) | datar[1]; /* Full-scale is 510 Kelvin, convert to centidegrees */ *val = (((51000 * value) / 0xFFFF) - 27215); @@ -357,8 +357,8 @@ static enum power_supply_property ltc294x_properties[] = { POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CURRENT_NOW, }; static int ltc294x_i2c_remove(struct i2c_client *client) @@ -388,7 +388,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client, np = of_node_get(client->dev.of_node); - info->num_regs = (unsigned long)of_device_get_match_data(&client->dev); + info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev); info->supply_desc.name = np->name; /* r_sense can be negative, when sense+ is connected to the battery @@ -409,7 +409,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client, prescaler_exp = LTC2941_MAX_PRESCALER_EXP; } - if (info->num_regs == LTC2943_NUM_REGS) { + if (info->id == LTC2943_ID) { if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP) prescaler_exp = LTC2943_MAX_PRESCALER_EXP; info->Qlsb = ((340 * 50000) / r_sense) / @@ -424,18 +424,17 @@ static int ltc294x_i2c_probe(struct i2c_client *client, info->client = client; info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; info->supply_desc.properties = ltc294x_properties; - if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB) + switch (info->id) { + case LTC2943_ID: info->supply_desc.num_properties = ARRAY_SIZE(ltc294x_properties); - else if (info->num_regs >= LTC294X_REG_CURRENT_LSB) - info->supply_desc.num_properties = - ARRAY_SIZE(ltc294x_properties) - 1; - else if (info->num_regs >= LTC294X_REG_VOLTAGE_LSB) - info->supply_desc.num_properties = - ARRAY_SIZE(ltc294x_properties) - 2; - else + break; + case LTC2941_ID: + default: info->supply_desc.num_properties = ARRAY_SIZE(ltc294x_properties) - 3; + break; + } info->supply_desc.get_property = ltc294x_get_property; info->supply_desc.set_property = ltc294x_set_property; info->supply_desc.property_is_writeable = ltc294x_property_is_writeable; @@ -492,8 +491,8 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume); static const struct i2c_device_id ltc294x_i2c_id[] = { - {"ltc2941", LTC2941_NUM_REGS}, - {"ltc2943", LTC2943_NUM_REGS}, + { "ltc2941", LTC2941_ID, }, + { "ltc2943", LTC2943_ID, }, { }, }; MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id); @@ -501,11 +500,11 @@ MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id); static const struct of_device_id ltc294x_i2c_of_match[] = { { .compatible = "lltc,ltc2941", - .data = (void *)LTC2941_NUM_REGS + .data = (void *)LTC2941_ID, }, { .compatible = "lltc,ltc2943", - .data = (void *)LTC2943_NUM_REGS + .data = (void *)LTC2943_ID, }, { }, }; -- cgit v1.2.3 From a65df832f96588debbbdd93d392a4ff77d5d237c Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Sun, 16 Jul 2017 11:34:00 +0200 Subject: power: supply: ltc2941-battery-gauge: Add LTC2942 support LTC2942 is pin compatible with LTC2941 providing additional informations about battery voltage and temperature. It can be runtime detected using bit A7 in the Status register. Signed-off-by: Ladislav Michl Acked-by: Rob Herring Acked-by: Dragos Bogdan Tested-by: Dragos Bogdan Signed-off-by: Sebastian Reichel --- drivers/power/supply/ltc2941-battery-gauge.c | 80 +++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c index b0de448a226b..42ff4e3daf35 100644 --- a/drivers/power/supply/ltc2941-battery-gauge.c +++ b/drivers/power/supply/ltc2941-battery-gauge.c @@ -1,5 +1,5 @@ /* - * I2C client/driver for the Linear Technology LTC2941 and LTC2943 + * I2C client/driver for the Linear Technology LTC2941, LTC2942 and LTC2943 * Battery Gas Gauge IC * * Copyright (C) 2014 Topic Embedded Systems @@ -46,11 +46,14 @@ enum ltc294x_reg { enum ltc294x_id { LTC2941_ID, + LTC2942_ID, LTC2943_ID, }; -#define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6)) -#define LTC2943_REG_CONTROL_MODE_SCAN BIT(7) +#define LTC2941_REG_STATUS_CHIP_ID BIT(7) + +#define LTC2942_REG_CONTROL_MODE_SCAN (BIT(7) | BIT(6)) +#define LTC2943_REG_CONTROL_MODE_SCAN BIT(7) #define LTC294X_REG_CONTROL_PRESCALER_MASK (BIT(5) | BIT(4) | BIT(3)) #define LTC294X_REG_CONTROL_SHUTDOWN_MASK (BIT(0)) #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \ @@ -145,9 +148,17 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp) control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) | LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED; - /* Put the 2943 into "monitor" mode, so it measures every 10 sec */ - if (info->id == LTC2941_ID) + /* Put device into "monitor" mode */ + switch (info->id) { + case LTC2942_ID: /* 2942 measures every 2 sec */ + control |= LTC2942_REG_CONTROL_MODE_SCAN; + break; + case LTC2943_ID: /* 2943 measures every 10 sec */ control |= LTC2943_REG_CONTROL_MODE_SCAN; + break; + default: + break; + } if (value != control) { ret = ltc294x_write_regs(info->client, @@ -252,7 +263,19 @@ static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val) ret = ltc294x_read_regs(info->client, LTC294X_REG_VOLTAGE_MSB, &datar[0], 2); value = (datar[0] << 8) | datar[1]; - *val = ((value * 23600) / 0xFFFF) * 1000; /* in uV */ + switch (info->id) { + case LTC2943_ID: + value *= 23600 * 2; + value /= 0xFFFF; + value *= 1000 / 2; + break; + default: + value *= 6000 * 10; + value /= 0xFFFF; + value *= 1000 / 10; + break; + } + *val = value; return ret; } @@ -275,15 +298,22 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val) static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val) { + enum ltc294x_reg reg; int ret; u8 datar[2]; u32 value; - ret = ltc294x_read_regs(info->client, - LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2); - value = (datar[0] << 8) | datar[1]; - /* Full-scale is 510 Kelvin, convert to centidegrees */ - *val = (((51000 * value) / 0xFFFF) - 27215); + if (info->id == LTC2942_ID) { + reg = LTC2942_REG_TEMPERATURE_MSB; + value = 60000; /* Full-scale is 600 Kelvin */ + } else { + reg = LTC2943_REG_TEMPERATURE_MSB; + value = 51000; /* Full-scale is 510 Kelvin */ + } + ret = ltc294x_read_regs(info->client, reg, &datar[0], 2); + value *= (datar[0] << 8) | datar[1]; + /* Convert to centidegrees */ + *val = value / 0xFFFF - 27215; return ret; } @@ -375,10 +405,11 @@ static int ltc294x_i2c_probe(struct i2c_client *client, { struct power_supply_config psy_cfg = {}; struct ltc294x_info *info; + struct device_node *np; int ret; u32 prescaler_exp; s32 r_sense; - struct device_node *np; + u8 status; info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); if (info == NULL) @@ -421,6 +452,20 @@ static int ltc294x_i2c_probe(struct i2c_client *client, (128 / (1 << prescaler_exp)); } + /* Read status register to check for LTC2942 */ + if (info->id == LTC2941_ID || info->id == LTC2942_ID) { + ret = ltc294x_read_regs(client, LTC294X_REG_STATUS, &status, 1); + if (ret < 0) { + dev_err(&client->dev, + "Could not read status register\n"); + return ret; + } + if (status & LTC2941_REG_STATUS_CHIP_ID) + info->id = LTC2941_ID; + else + info->id = LTC2942_ID; + } + info->client = client; info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; info->supply_desc.properties = ltc294x_properties; @@ -429,6 +474,10 @@ static int ltc294x_i2c_probe(struct i2c_client *client, info->supply_desc.num_properties = ARRAY_SIZE(ltc294x_properties); break; + case LTC2942_ID: + info->supply_desc.num_properties = + ARRAY_SIZE(ltc294x_properties) - 1; + break; case LTC2941_ID: default: info->supply_desc.num_properties = @@ -492,6 +541,7 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume); static const struct i2c_device_id ltc294x_i2c_id[] = { { "ltc2941", LTC2941_ID, }, + { "ltc2942", LTC2942_ID, }, { "ltc2943", LTC2943_ID, }, { }, }; @@ -502,6 +552,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = { .compatible = "lltc,ltc2941", .data = (void *)LTC2941_ID, }, + { + .compatible = "lltc,ltc2942", + .data = (void *)LTC2942_ID, + }, { .compatible = "lltc,ltc2943", .data = (void *)LTC2943_ID, @@ -524,5 +578,5 @@ module_i2c_driver(ltc294x_driver); MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems"); MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products"); -MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver"); +MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943 Battery Gas Gauge IC driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 17825ff6ec6db23892e61a1496abf7d737afe9e7 Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Sun, 16 Jul 2017 11:35:32 +0200 Subject: power: supply: ltc2941-battery-gauge: Add LTC2944 support LTC2944 is compatible with LTC2943, but uses different voltage and current computing constants. Signed-off-by: Dragos Bogdan Signed-off-by: Ladislav Michl Tested-by: Dragos Bogdan Acked-by: Rob Herring Signed-off-by: Sebastian Reichel --- drivers/power/supply/ltc2941-battery-gauge.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c index 42ff4e3daf35..08e4fd9ee607 100644 --- a/drivers/power/supply/ltc2941-battery-gauge.c +++ b/drivers/power/supply/ltc2941-battery-gauge.c @@ -1,6 +1,6 @@ /* - * I2C client/driver for the Linear Technology LTC2941, LTC2942 and LTC2943 - * Battery Gas Gauge IC + * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943 + * and LTC2944 Battery Gas Gauge IC * * Copyright (C) 2014 Topic Embedded Systems * @@ -48,6 +48,7 @@ enum ltc294x_id { LTC2941_ID, LTC2942_ID, LTC2943_ID, + LTC2944_ID, }; #define LTC2941_REG_STATUS_CHIP_ID BIT(7) @@ -153,7 +154,8 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp) case LTC2942_ID: /* 2942 measures every 2 sec */ control |= LTC2942_REG_CONTROL_MODE_SCAN; break; - case LTC2943_ID: /* 2943 measures every 10 sec */ + case LTC2943_ID: + case LTC2944_ID: /* 2943 and 2944 measure every 10 sec */ control |= LTC2943_REG_CONTROL_MODE_SCAN; break; default: @@ -269,6 +271,11 @@ static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val) value /= 0xFFFF; value *= 1000 / 2; break; + case LTC2944_ID: + value *= 70800 / 5*4; + value /= 0xFFFF; + value *= 1000 * 5/4; + break; default: value *= 6000 * 10; value /= 0xFFFF; @@ -289,10 +296,14 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val) LTC2943_REG_CURRENT_MSB, &datar[0], 2); value = (datar[0] << 8) | datar[1]; value -= 0x7FFF; + if (info->id == LTC2944_ID) + value *= 64000; + else + value *= 60000; /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm, * the formula below keeps everything in s32 range while preserving * enough digits */ - *val = 1000 * ((60000 * value) / (info->r_sense * 0x7FFF)); /* in uA */ + *val = 1000 * (value / (info->r_sense * 0x7FFF)); /* in uA */ return ret; } @@ -470,6 +481,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client, info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; info->supply_desc.properties = ltc294x_properties; switch (info->id) { + case LTC2944_ID: case LTC2943_ID: info->supply_desc.num_properties = ARRAY_SIZE(ltc294x_properties); @@ -543,6 +555,7 @@ static const struct i2c_device_id ltc294x_i2c_id[] = { { "ltc2941", LTC2941_ID, }, { "ltc2942", LTC2942_ID, }, { "ltc2943", LTC2943_ID, }, + { "ltc2944", LTC2944_ID, }, { }, }; MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id); @@ -560,6 +573,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = { .compatible = "lltc,ltc2943", .data = (void *)LTC2943_ID, }, + { + .compatible = "lltc,ltc2944", + .data = (void *)LTC2944_ID, + }, { }, }; MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match); @@ -578,5 +595,5 @@ module_i2c_driver(ltc294x_driver); MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems"); MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products"); -MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943 Battery Gas Gauge IC driver"); +MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 55a9db679183bcf85a6e5c44a4f92f158bb6f03d Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Wed, 19 Jul 2017 12:04:06 -0500 Subject: power: supply: move HDQ interface for bq27xxx from w1 to power/supply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HDQ interface driver should be in this folder just like the I2C interface driver. Move this driver out of drivers/w1/slave and into drivers/power/supply. Signed-off-by: Andrew F. Davis Acked-by: Pali Rohár Signed-off-by: Sebastian Reichel --- drivers/power/supply/Kconfig | 9 +++ drivers/power/supply/Makefile | 1 + drivers/power/supply/bq27xxx_battery_hdq.c | 115 ++++++++++++++++++++++++++++ drivers/w1/slaves/Kconfig | 6 -- drivers/w1/slaves/Makefile | 1 - drivers/w1/slaves/w1_bq27000.c | 117 ----------------------------- 6 files changed, 125 insertions(+), 124 deletions(-) create mode 100644 drivers/power/supply/bq27xxx_battery_hdq.c delete mode 100644 drivers/w1/slaves/w1_bq27000.c (limited to 'drivers') diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 969f5005669c..af6397224a82 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -198,6 +198,15 @@ config BATTERY_BQ27XXX_I2C Say Y here to enable support for batteries with BQ27xxx chips connected over an I2C bus. +config BATTERY_BQ27XXX_HDQ + tristate "BQ27xxx HDQ support" + depends on BATTERY_BQ27XXX + depends on W1 + default y + help + Say Y here to enable support for batteries with BQ27xxx chips + connected over an HDQ bus. + config BATTERY_BQ27XXX_DT_UPDATES_NVM bool "BQ27xxx support for update of NVM/flash data memory" depends on BATTERY_BQ27XXX_I2C diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index a41f40957847..946a5e6be860 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o obj-$(CONFIG_CHARGER_SBS) += sbs-charger.o obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o obj-$(CONFIG_BATTERY_BQ27XXX_I2C) += bq27xxx_battery_i2c.o +obj-$(CONFIG_BATTERY_BQ27XXX_HDQ) += bq27xxx_battery_hdq.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o diff --git a/drivers/power/supply/bq27xxx_battery_hdq.c b/drivers/power/supply/bq27xxx_battery_hdq.c new file mode 100644 index 000000000000..f4df67eb9d2c --- /dev/null +++ b/drivers/power/supply/bq27xxx_battery_hdq.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2007 Texas Instruments, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define W1_FAMILY_BQ27000 0x01 + +#define HDQ_CMD_READ (0) +#define HDQ_CMD_WRITE (1<<7) + +static int F_ID; +module_param(F_ID, int, S_IRUSR); +MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); + +static int w1_bq27000_read(struct device *dev, unsigned int reg) +{ + u8 val; + struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); + + mutex_lock(&sl->master->bus_mutex); + w1_write_8(sl->master, HDQ_CMD_READ | reg); + val = w1_read_8(sl->master); + mutex_unlock(&sl->master->bus_mutex); + + return val; +} + +static struct bq27xxx_platform_data bq27000_battery_info = { + .read = w1_bq27000_read, + .name = "bq27000-battery", + .chip = BQ27000, +}; + +static int w1_bq27000_add_slave(struct w1_slave *sl) +{ + int ret; + struct platform_device *pdev; + + pdev = platform_device_alloc("bq27000-battery", -1); + if (!pdev) { + ret = -ENOMEM; + return ret; + } + ret = platform_device_add_data(pdev, + &bq27000_battery_info, + sizeof(bq27000_battery_info)); + if (ret) + goto pdev_add_failed; + pdev->dev.parent = &sl->dev; + + ret = platform_device_add(pdev); + if (ret) + goto pdev_add_failed; + + dev_set_drvdata(&sl->dev, pdev); + + goto success; + +pdev_add_failed: + platform_device_put(pdev); +success: + return ret; +} + +static void w1_bq27000_remove_slave(struct w1_slave *sl) +{ + struct platform_device *pdev = dev_get_drvdata(&sl->dev); + + platform_device_unregister(pdev); +} + +static struct w1_family_ops w1_bq27000_fops = { + .add_slave = w1_bq27000_add_slave, + .remove_slave = w1_bq27000_remove_slave, +}; + +static struct w1_family w1_bq27000_family = { + .fid = W1_FAMILY_BQ27000, + .fops = &w1_bq27000_fops, +}; + +static int __init w1_bq27000_init(void) +{ + if (F_ID) + w1_bq27000_family.fid = F_ID; + + return w1_register_family(&w1_bq27000_family); +} + +static void __exit w1_bq27000_exit(void) +{ + w1_unregister_family(&w1_bq27000_family); +} + +module_init(w1_bq27000_init); +module_exit(w1_bq27000_exit); + +MODULE_AUTHOR("Texas Instruments Ltd"); +MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index fb68465908f2..dc4437683956 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig @@ -140,10 +140,4 @@ config W1_SLAVE_DS28E04 If you are unsure, say N. -config W1_SLAVE_BQ27000 - tristate "BQ27000 slave support" - help - Say Y here if you want to use a hdq - bq27000 slave support. - endmenu diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index 54c63e420302..e59441a5e157 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile @@ -15,5 +15,4 @@ obj-$(CONFIG_W1_SLAVE_DS2438) += w1_ds2438.o obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o -obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c deleted file mode 100644 index 8046ac45381a..000000000000 --- a/drivers/w1/slaves/w1_bq27000.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * drivers/w1/slaves/w1_bq27000.c - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define W1_FAMILY_BQ27000 0x01 - -#define HDQ_CMD_READ (0) -#define HDQ_CMD_WRITE (1<<7) - -static int F_ID; -module_param(F_ID, int, S_IRUSR); -MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); - -static int w1_bq27000_read(struct device *dev, unsigned int reg) -{ - u8 val; - struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); - - mutex_lock(&sl->master->bus_mutex); - w1_write_8(sl->master, HDQ_CMD_READ | reg); - val = w1_read_8(sl->master); - mutex_unlock(&sl->master->bus_mutex); - - return val; -} - -static struct bq27xxx_platform_data bq27000_battery_info = { - .read = w1_bq27000_read, - .name = "bq27000-battery", - .chip = BQ27000, -}; - -static int w1_bq27000_add_slave(struct w1_slave *sl) -{ - int ret; - struct platform_device *pdev; - - pdev = platform_device_alloc("bq27000-battery", -1); - if (!pdev) { - ret = -ENOMEM; - return ret; - } - ret = platform_device_add_data(pdev, - &bq27000_battery_info, - sizeof(bq27000_battery_info)); - if (ret) - goto pdev_add_failed; - pdev->dev.parent = &sl->dev; - - ret = platform_device_add(pdev); - if (ret) - goto pdev_add_failed; - - dev_set_drvdata(&sl->dev, pdev); - - goto success; - -pdev_add_failed: - platform_device_put(pdev); -success: - return ret; -} - -static void w1_bq27000_remove_slave(struct w1_slave *sl) -{ - struct platform_device *pdev = dev_get_drvdata(&sl->dev); - - platform_device_unregister(pdev); -} - -static struct w1_family_ops w1_bq27000_fops = { - .add_slave = w1_bq27000_add_slave, - .remove_slave = w1_bq27000_remove_slave, -}; - -static struct w1_family w1_bq27000_family = { - .fid = W1_FAMILY_BQ27000, - .fops = &w1_bq27000_fops, -}; - -static int __init w1_bq27000_init(void) -{ - if (F_ID) - w1_bq27000_family.fid = F_ID; - - return w1_register_family(&w1_bq27000_family); -} - -static void __exit w1_bq27000_exit(void) -{ - w1_unregister_family(&w1_bq27000_family); -} - -module_init(w1_bq27000_init); -module_exit(w1_bq27000_exit); - -MODULE_AUTHOR("Texas Instruments Ltd"); -MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); -- cgit v1.2.3 From 67bd22c09ac1b54b5f42445783d2dc8e011f7a71 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Wed, 19 Jul 2017 12:04:07 -0500 Subject: power: supply: bq27xxx: move platform driver code into bq27xxx_battery_hdq.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the BQ27xxx driver was originally written the w1 subsystem only allowed device drivers for w1 attached devices to live in the w1 subsystem. Kernel driver subsystems expect that the driver for a device live in the directory of the subsystem for which it implements functionality, not in the directory of the bus that it is attached. To work around this, the BQ27xxx driver was implemented as a platform device driver and the interface driver would instantiate this device from within the w1 directory, then pass a w1 read callback as platform data. As we can now have the w1 interface driver in the power/supply directory (like we do already with the i2c interface driver) we can remove this middle-layer platform driver. Signed-off-by: Andrew F. Davis Acked-by: Pali Rohár Signed-off-by: Sebastian Reichel --- drivers/power/supply/bq27xxx_battery.c | 104 ----------------------- drivers/power/supply/bq27xxx_battery_hdq.c | 130 +++++++++++++++++------------ 2 files changed, 75 insertions(+), 159 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index ed44439d0112..079083b31293 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1938,110 +1938,6 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di) } EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown); -static int bq27xxx_battery_platform_read(struct bq27xxx_device_info *di, u8 reg, - bool single) -{ - struct device *dev = di->dev; - struct bq27xxx_platform_data *pdata = dev->platform_data; - unsigned int timeout = 3; - int upper, lower; - int temp; - - if (!single) { - /* Make sure the value has not changed in between reading the - * lower and the upper part */ - upper = pdata->read(dev, reg + 1); - do { - temp = upper; - if (upper < 0) - return upper; - - lower = pdata->read(dev, reg); - if (lower < 0) - return lower; - - upper = pdata->read(dev, reg + 1); - } while (temp != upper && --timeout); - - if (timeout == 0) - return -EIO; - - return (upper << 8) | lower; - } - - return pdata->read(dev, reg); -} - -static int bq27xxx_battery_platform_probe(struct platform_device *pdev) -{ - struct bq27xxx_device_info *di; - struct bq27xxx_platform_data *pdata = pdev->dev.platform_data; - - if (!pdata) { - dev_err(&pdev->dev, "no platform_data supplied\n"); - return -EINVAL; - } - - if (!pdata->read) { - dev_err(&pdev->dev, "no hdq read callback supplied\n"); - return -EINVAL; - } - - if (!pdata->chip) { - dev_err(&pdev->dev, "no device supplied\n"); - return -EINVAL; - } - - di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); - if (!di) - return -ENOMEM; - - platform_set_drvdata(pdev, di); - - di->dev = &pdev->dev; - di->chip = pdata->chip; - di->name = pdata->name ?: dev_name(&pdev->dev); - di->bus.read = bq27xxx_battery_platform_read; - - return bq27xxx_battery_setup(di); -} - -static int bq27xxx_battery_platform_remove(struct platform_device *pdev) -{ - struct bq27xxx_device_info *di = platform_get_drvdata(pdev); - - bq27xxx_battery_teardown(di); - - return 0; -} - -static const struct platform_device_id bq27xxx_battery_platform_id_table[] = { - { "bq27000-battery", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table); - -#ifdef CONFIG_OF -static const struct of_device_id bq27xxx_battery_platform_of_match_table[] = { - { .compatible = "ti,bq27000" }, - {}, -}; -MODULE_DEVICE_TABLE(of, bq27xxx_battery_platform_of_match_table); -#endif - -static struct platform_driver bq27xxx_battery_platform_driver = { - .probe = bq27xxx_battery_platform_probe, - .remove = bq27xxx_battery_platform_remove, - .driver = { - .name = "bq27000-battery", - .of_match_table = of_match_ptr(bq27xxx_battery_platform_of_match_table), - }, - .id_table = bq27xxx_battery_platform_id_table, -}; -module_platform_driver(bq27xxx_battery_platform_driver); - -MODULE_ALIAS("platform:bq27000-battery"); - MODULE_AUTHOR("Rodolfo Giometti "); MODULE_DESCRIPTION("BQ27xxx battery monitor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/bq27xxx_battery_hdq.c b/drivers/power/supply/bq27xxx_battery_hdq.c index f4df67eb9d2c..9aff896c9802 100644 --- a/drivers/power/supply/bq27xxx_battery_hdq.c +++ b/drivers/power/supply/bq27xxx_battery_hdq.c @@ -1,10 +1,16 @@ /* - * Copyright (C) 2007 Texas Instruments, Inc. + * BQ27xxx battery monitor HDQ/1-wire driver * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. + * Copyright (C) 2007-2017 Texas Instruments Incorporated - http://www.ti.com/ * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include @@ -19,17 +25,16 @@ #define W1_FAMILY_BQ27000 0x01 -#define HDQ_CMD_READ (0) -#define HDQ_CMD_WRITE (1<<7) +#define HDQ_CMD_READ (0 << 7) +#define HDQ_CMD_WRITE (1 << 7) static int F_ID; module_param(F_ID, int, S_IRUSR); -MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); +MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ27xxx device"); -static int w1_bq27000_read(struct device *dev, unsigned int reg) +static int w1_bq27000_read(struct w1_slave *sl, unsigned int reg) { u8 val; - struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); mutex_lock(&sl->master->bus_mutex); w1_write_8(sl->master, HDQ_CMD_READ | reg); @@ -39,77 +44,92 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg) return val; } -static struct bq27xxx_platform_data bq27000_battery_info = { - .read = w1_bq27000_read, - .name = "bq27000-battery", - .chip = BQ27000, -}; - -static int w1_bq27000_add_slave(struct w1_slave *sl) +static int bq27xxx_battery_hdq_read(struct bq27xxx_device_info *di, u8 reg, + bool single) { - int ret; - struct platform_device *pdev; - - pdev = platform_device_alloc("bq27000-battery", -1); - if (!pdev) { - ret = -ENOMEM; - return ret; + struct w1_slave *sl = dev_to_w1_slave(di->dev); + unsigned int timeout = 3; + int upper, lower; + int temp; + + if (!single) { + /* + * Make sure the value has not changed in between reading the + * lower and the upper part + */ + upper = w1_bq27000_read(sl, reg + 1); + do { + temp = upper; + if (upper < 0) + return upper; + + lower = w1_bq27000_read(sl, reg); + if (lower < 0) + return lower; + + upper = w1_bq27000_read(sl, reg + 1); + } while (temp != upper && --timeout); + + if (timeout == 0) + return -EIO; + + return (upper << 8) | lower; } - ret = platform_device_add_data(pdev, - &bq27000_battery_info, - sizeof(bq27000_battery_info)); - if (ret) - goto pdev_add_failed; - pdev->dev.parent = &sl->dev; - ret = platform_device_add(pdev); - if (ret) - goto pdev_add_failed; + return w1_bq27000_read(sl, reg); +} - dev_set_drvdata(&sl->dev, pdev); +static int bq27xxx_battery_hdq_add_slave(struct w1_slave *sl) +{ + struct bq27xxx_device_info *di; + + di = devm_kzalloc(&sl->dev, sizeof(*di), GFP_KERNEL); + if (!di) + return -ENOMEM; - goto success; + dev_set_drvdata(&sl->dev, di); -pdev_add_failed: - platform_device_put(pdev); -success: - return ret; + di->dev = &sl->dev; + di->chip = BQ27000; + di->name = "bq27000-battery"; + di->bus.read = bq27xxx_battery_hdq_read; + + return bq27xxx_battery_setup(di); } -static void w1_bq27000_remove_slave(struct w1_slave *sl) +static void bq27xxx_battery_hdq_remove_slave(struct w1_slave *sl) { - struct platform_device *pdev = dev_get_drvdata(&sl->dev); + struct bq27xxx_device_info *di = dev_get_drvdata(&sl->dev); - platform_device_unregister(pdev); + bq27xxx_battery_teardown(di); } -static struct w1_family_ops w1_bq27000_fops = { - .add_slave = w1_bq27000_add_slave, - .remove_slave = w1_bq27000_remove_slave, +static struct w1_family_ops bq27xxx_battery_hdq_fops = { + .add_slave = bq27xxx_battery_hdq_add_slave, + .remove_slave = bq27xxx_battery_hdq_remove_slave, }; -static struct w1_family w1_bq27000_family = { +static struct w1_family bq27xxx_battery_hdq_family = { .fid = W1_FAMILY_BQ27000, - .fops = &w1_bq27000_fops, + .fops = &bq27xxx_battery_hdq_fops, }; -static int __init w1_bq27000_init(void) +static int __init bq27xxx_battery_hdq_init(void) { if (F_ID) - w1_bq27000_family.fid = F_ID; + bq27xxx_battery_hdq_family.fid = F_ID; - return w1_register_family(&w1_bq27000_family); + return w1_register_family(&bq27xxx_battery_hdq_family); } +module_init(bq27xxx_battery_hdq_init); -static void __exit w1_bq27000_exit(void) +static void __exit bq27xxx_battery_hdq_exit(void) { - w1_unregister_family(&w1_bq27000_family); + w1_unregister_family(&bq27xxx_battery_hdq_family); } - -module_init(w1_bq27000_init); -module_exit(w1_bq27000_exit); +module_exit(bq27xxx_battery_hdq_exit); MODULE_AUTHOR("Texas Instruments Ltd"); -MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); +MODULE_DESCRIPTION("BQ27xxx battery monitor HDQ/1-wire driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); -- cgit v1.2.3 From 16ac345b15529995a6ca0109ad41f96e3db82e56 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 2 Aug 2017 15:59:38 +0530 Subject: power: supply: add const to bin_attribute structures Add const to bin_attribute structures as they are only passed to the functions sysfs_{remove/create}_bin_file or device_{remove/create}_bin_file. The corresponding parameters passed are of type const, so declare the structures to be const. Done using Coccinelle: @m disable optional_qualifier@ identifier s; position p; @@ static struct bin_attribute s@p={...}; @okay1@ position p; identifier m.s; @@ ( sysfs_create_bin_file(...,&s@p,...) | sysfs_remove_bin_file(...,&s@p,...) ) @bad@ position p!={m.p,okay1.p}; identifier m.s; @@ s@p @change depends on !bad disable optional_qualifier@ identifier m.s; @@ static +const struct bin_attribute s={...}; Same script was modified for device_{create/remove}_bin_file functions. Signed-off-by: Bhumika Goyal Signed-off-by: Sebastian Reichel --- drivers/power/supply/ds2780_battery.c | 4 ++-- drivers/power/supply/ds2781_battery.c | 4 ++-- drivers/power/supply/olpc_battery.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/power/supply/ds2780_battery.c b/drivers/power/supply/ds2780_battery.c index 8edd4aa5f475..e5d81b493c45 100644 --- a/drivers/power/supply/ds2780_battery.c +++ b/drivers/power/supply/ds2780_battery.c @@ -663,7 +663,7 @@ stat