* [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge @ 2015-10-05 16:03 Adam Thomson 2015-10-05 16:03 ` [PATCH v6 1/6] mfd: da9150: Add support for Fuel-Gauge Adam Thomson ` (5 more replies) 0 siblings, 6 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm, devicetree, linux-kernel, Support Opensource This patch set adds support for the Dialog DA9150 Fuel-Gauge. In this patch set the following is provided: - MFD Core and DT bindings updates. - Power Supply Fuel-Gauge support and DT bindings documentation. This patch set is baselined against the v4.3-rc4 kernel version. Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - MFD, Power, DT: Update DT compatible & driver name strings for Fuel Gauge, in line with maintainers request. - Power: Update Kconfig and Makefile to use BATTERY_* for config entry instead of FG_*. Also fuel-gauge module now depends on MFD not Charger. - Power: Added helper function to simplify single attribute accesses using QIF interface of fuel-gauge. - Power: Use of devm_* functions for IRQ and power_supply registration. - Power: Added checking of result from platform_get_irq_byname(). Changes in v3: - MFD: Some tidy up of code (gotos, dropped FG header, DEFINE_RES_IRQ_NAMED) - MFD & Power: Drop use of callback function for temperature reading, as requested by Lee Jones. - MFD (DT): Binding doc update to flesh out example text. - MFD (DT): New patch to change MFD binding doc to use relative paths. - MFD: New patch to use DEFINE_RES_IRQ_NAMED for all other IRQ resources. Changes in v2: - Moved temp callback function prototype to be part of power fuel-gauge patch, as requested by Lee Jones. Adam Thomson (6): mfd: da9150: Add support for Fuel-Gauge mfd: da9150: Update DT bindings for Fuel-Gauge support power: Add support for DA9150 Fuel-Gauge power: da9150: Add DT bindings documentation for Fuel-Gauge mfd: da9150: Use relative paths in DT bindings document mfd: da9150: Use DEFINE_RES_IRQ_NAMED() help macro for IRQ resource Documentation/devicetree/bindings/mfd/da9150.txt | 33 +- .../devicetree/bindings/power/da9150-fg.txt | 23 + drivers/mfd/da9150-core.c | 191 +++++-- drivers/power/Kconfig | 10 + drivers/power/Makefile | 1 + drivers/power/da9150-fg.c | 578 +++++++++++++++++++++ include/linux/mfd/da9150/core.h | 19 +- 7 files changed, 810 insertions(+), 45 deletions(-) create mode 100644 Documentation/devicetree/bindings/power/da9150-fg.txt create mode 100644 drivers/power/da9150-fg.c -- 1.9.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 1/6] mfd: da9150: Add support for Fuel-Gauge 2015-10-05 16:03 [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge Adam Thomson @ 2015-10-05 16:03 ` Adam Thomson 2015-10-05 16:03 ` [PATCH v6 2/6] mfd: da9150: Update DT bindings for Fuel-Gauge support Adam Thomson ` (4 subsequent siblings) 5 siblings, 0 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm, devicetree, linux-kernel, Support Opensource Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Acked-by: Lee Jones <lee.jones@linaro.org> --- Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - Update compatible string of fuel-gauge to "dlg, da9150-fuel-gauge". Also made similar change to driver name to keep things consistent. Changes in v3: - Use DEFINE_RES_IRQ_NAMED() helper for defining FG IRQ resource. - Unwanted new line & comments removed. - Remove gotos which can be replaced with straight forward return calls. - Add enum for indexing MFD cells list, which is used to assign pdata for FG sub-device. - Remove use of function pointers for QIF related read/write functions as currently only I2C supported, so call I2C functions directly. - Fold fg.h contents into core.h. Changes in v2: - Moved temp callback function prototype to be part of power fuel-gauge patch, as requested by Lee Jones. drivers/mfd/da9150-core.c | 156 ++++++++++++++++++++++++++++++++++++++-- include/linux/mfd/da9150/core.h | 19 ++++- 2 files changed, 167 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c index 94b9bbd..85ca4b5 100644 --- a/drivers/mfd/da9150-core.c +++ b/drivers/mfd/da9150-core.c @@ -23,6 +23,77 @@ #include <linux/mfd/da9150/core.h> #include <linux/mfd/da9150/registers.h> +/* Raw device access, used for QIF */ +static int da9150_i2c_read_device(struct i2c_client *client, u8 addr, int count, + u8 *buf) +{ + struct i2c_msg xfer; + int ret; + + /* + * Read is split into two transfers as device expects STOP/START rather + * than repeated start to carry out this kind of access. + */ + + /* Write address */ + xfer.addr = client->addr; + xfer.flags = 0; + xfer.len = 1; + xfer.buf = &addr; + + ret = i2c_transfer(client->adapter, &xfer, 1); + if (ret != 1) { + if (ret < 0) + return ret; + else + return -EIO; + } + + /* Read data */ + xfer.addr = client->addr; + xfer.flags = I2C_M_RD; + xfer.len = count; + xfer.buf = buf; + + ret = i2c_transfer(client->adapter, &xfer, 1); + if (ret == 1) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +static int da9150_i2c_write_device(struct i2c_client *client, u8 addr, + int count, const u8 *buf) +{ + struct i2c_msg xfer; + u8 *reg_data; + int ret; + + reg_data = kzalloc(1 + count, GFP_KERNEL); + if (!reg_data) + return -ENOMEM; + + reg_data[0] = addr; + memcpy(®_data[1], buf, count); + + /* Write address & data */ + xfer.addr = client->addr; + xfer.flags = 0; + xfer.len = 1 + count; + xfer.buf = reg_data; + + ret = i2c_transfer(client->adapter, &xfer, 1); + kfree(reg_data); + if (ret == 1) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + static bool da9150_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -107,6 +178,28 @@ static const struct regmap_config da9150_regmap_config = { .volatile_reg = da9150_volatile_reg, }; +void da9150_read_qif(struct da9150 *da9150, u8 addr, int count, u8 *buf) +{ + int ret; + + ret = da9150_i2c_read_device(da9150->core_qif, addr, count, buf); + if (ret < 0) + dev_err(da9150->dev, "Failed to read from QIF 0x%x: %d\n", + addr, ret); +} +EXPORT_SYMBOL_GPL(da9150_read_qif); + +void da9150_write_qif(struct da9150 *da9150, u8 addr, int count, const u8 *buf) +{ + int ret; + + ret = da9150_i2c_write_device(da9150->core_qif, addr, count, buf); + if (ret < 0) + dev_err(da9150->dev, "Failed to write to QIF 0x%x: %d\n", + addr, ret); +} +EXPORT_SYMBOL_GPL(da9150_write_qif); + u8 da9150_reg_read(struct da9150 *da9150, u16 reg) { int val, ret; @@ -297,19 +390,35 @@ static struct resource da9150_charger_resources[] = { }, }; +static struct resource da9150_fg_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_FG, "FG"), +}; + +enum da9150_dev_idx { + DA9150_GPADC_IDX = 0, + DA9150_CHARGER_IDX, + DA9150_FG_IDX, +}; + static struct mfd_cell da9150_devs[] = { - { + [DA9150_GPADC_IDX] = { .name = "da9150-gpadc", .of_compatible = "dlg,da9150-gpadc", .resources = da9150_gpadc_resources, .num_resources = ARRAY_SIZE(da9150_gpadc_resources), }, - { + [DA9150_CHARGER_IDX] = { .name = "da9150-charger", .of_compatible = "dlg,da9150-charger", .resources = da9150_charger_resources, .num_resources = ARRAY_SIZE(da9150_charger_resources), }, + [DA9150_FG_IDX] = { + .name = "da9150-fuel-gauge", + .of_compatible = "dlg,da9150-fuel-gauge", + .resources = da9150_fg_resources, + .num_resources = ARRAY_SIZE(da9150_fg_resources), + }, }; static int da9150_probe(struct i2c_client *client, @@ -317,6 +426,7 @@ static int da9150_probe(struct i2c_client *client, { struct da9150 *da9150; struct da9150_pdata *pdata = dev_get_platdata(&client->dev); + int qif_addr; int ret; da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL); @@ -335,16 +445,41 @@ static int da9150_probe(struct i2c_client *client, return ret; } - da9150->irq_base = pdata ? pdata->irq_base : -1; + /* Setup secondary I2C interface for QIF access */ + qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A); + qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1; + qif_addr |= DA9150_QIF_I2C_ADDR_LSB; + da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr); + if (!da9150->core_qif) { + dev_err(da9150->dev, "Failed to attach QIF client\n"); + return -ENODEV; + } + + i2c_set_clientdata(da9150->core_qif, da9150); + + if (pdata) { + da9150->irq_base = pdata->irq_base; + + da9150_devs[DA9150_FG_IDX].platform_data = pdata->fg_pdata; + da9150_devs[DA9150_FG_IDX].pdata_size = + sizeof(struct da9150_fg_pdata); + } else { + da9150->irq_base = -1; + } ret = regmap_add_irq_chip(da9150->regmap, da9150->irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, da9150->irq_base, &da9150_regmap_irq_chip, &da9150->regmap_irq_data); - if (ret) - return ret; + if (ret) { + dev_err(da9150->dev, "Failed to add regmap irq chip: %d\n", + ret); + goto regmap_irq_fail; + } + da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data); + enable_irq_wake(da9150->irq); ret = mfd_add_devices(da9150->dev, -1, da9150_devs, @@ -352,11 +487,17 @@ static int da9150_probe(struct i2c_client *client, da9150->irq_base, NULL); if (ret) { dev_err(da9150->dev, "Failed to add child devices: %d\n", ret); - regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); - return ret; + goto mfd_fail; } return 0; + +mfd_fail: + regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); +regmap_irq_fail: + i2c_unregister_device(da9150->core_qif); + + return ret; } static int da9150_remove(struct i2c_client *client) @@ -365,6 +506,7 @@ static int da9150_remove(struct i2c_client *client) regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); mfd_remove_devices(da9150->dev); + i2c_unregister_device(da9150->core_qif); return 0; } diff --git a/include/linux/mfd/da9150/core.h b/include/linux/mfd/da9150/core.h index 76e6689..1bf50ca 100644 --- a/include/linux/mfd/da9150/core.h +++ b/include/linux/mfd/da9150/core.h @@ -15,6 +15,7 @@ #define __DA9150_CORE_H #include <linux/device.h> +#include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/regmap.h> @@ -46,23 +47,39 @@ #define DA9150_IRQ_GPADC 19 #define DA9150_IRQ_WKUP 20 +/* I2C sub-device address */ +#define DA9150_QIF_I2C_ADDR_LSB 0x5 + +struct da9150_fg_pdata { + u32 update_interval; /* msecs */ + u8 warn_soc_lvl; /* % value */ + u8 crit_soc_lvl; /* % value */ +}; + struct da9150_pdata { int irq_base; + struct da9150_fg_pdata *fg_pdata; }; struct da9150 { struct device *dev; struct regmap *regmap; + struct i2c_client *core_qif; + struct regmap_irq_chip_data *regmap_irq_data; int irq; int irq_base; }; -/* Device I/O */ +/* Device I/O - Query Interface for FG and standard register access */ +void da9150_read_qif(struct da9150 *da9150, u8 addr, int count, u8 *buf); +void da9150_write_qif(struct da9150 *da9150, u8 addr, int count, const u8 *buf); + u8 da9150_reg_read(struct da9150 *da9150, u16 reg); void da9150_reg_write(struct da9150 *da9150, u16 reg, u8 val); void da9150_set_bits(struct da9150 *da9150, u16 reg, u8 mask, u8 val); void da9150_bulk_read(struct da9150 *da9150, u16 reg, int count, u8 *buf); void da9150_bulk_write(struct da9150 *da9150, u16 reg, int count, const u8 *buf); + #endif /* __DA9150_CORE_H */ -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v6 2/6] mfd: da9150: Update DT bindings for Fuel-Gauge support 2015-10-05 16:03 [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge Adam Thomson 2015-10-05 16:03 ` [PATCH v6 1/6] mfd: da9150: Add support for Fuel-Gauge Adam Thomson @ 2015-10-05 16:03 ` Adam Thomson [not found] ` <cover.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> ` (3 subsequent siblings) 5 siblings, 0 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm, devicetree, linux-kernel, Support Opensource Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Acked-by: Lee Jones <lee.jones@linaro.org> --- Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - Update compatible string of fuel-gauge to "da9150-fuel-gauge". - Node name tidy up, relating to maintainer comments on fuel-gauge DT binding doc. - Removed Ack to patch from Lee Jones, as this has now been modified slightly and didn't want to make assumptions of approval. Changes in v3: - Removal of unwanted new-line. - Flesh out example bindings usage. Changes in v2: - N/A Documentation/devicetree/bindings/mfd/da9150.txt | 27 ++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/da9150.txt b/Documentation/devicetree/bindings/mfd/da9150.txt index d0588ea..970801d 100644 --- a/Documentation/devicetree/bindings/mfd/da9150.txt +++ b/Documentation/devicetree/bindings/mfd/da9150.txt @@ -6,6 +6,7 @@ Device Description ------ ----------- da9150-gpadc : General Purpose ADC da9150-charger : Battery Charger +da9150-fg : Battery Fuel-Gauge ====== @@ -22,7 +23,7 @@ Required properties: Sub-devices: - da9150-gpadc: See Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt - da9150-charger: See Documentation/devicetree/bindings/power/da9150-charger.txt - +- da9150-fg: See Documentation/devicetree/bindings/power/da9150-fg.txt Example: @@ -34,10 +35,28 @@ Example: interrupt-controller; gpadc: da9150-gpadc { - ... + compatible = "dlg,da9150-gpadc"; + #io-channel-cells = <1>; + }; + + charger { + compatible = "dlg,da9150-charger"; + + io-channels = <&gpadc 0>, + <&gpadc 2>, + <&gpadc 8>, + <&gpadc 5>; + io-channel-names = "CHAN_IBUS", + "CHAN_VBUS", + "CHAN_TJUNC", + "CHAN_VBAT"; }; - da9150-charger { - ... + fuel-gauge { + compatible = "dlg,da9150-fuel-gauge"; + + dlg,update-interval = <10000>; + dlg,warn-soc-level = /bits/ 8 <15>; + dlg,crit-soc-level = /bits/ 8 <5> }; }; -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
[parent not found: <cover.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>]
* [PATCH v6 3/6] power: Add support for DA9150 Fuel-Gauge [not found] ` <cover.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> @ 2015-10-05 16:03 ` Adam Thomson 2015-10-05 16:10 ` Fabio Estevam [not found] ` <80d467703ba19bef12e9bcdd246e1de7bd33a8b1.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> 0 siblings, 2 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Support Opensource This adds power supply driver support for the Fuel-Gauge part of the DA9150 combined Charger and Fuel-Gauge device. Signed-off-by: Adam Thomson <Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> Acked-By: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> --- Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - Update compatible string of fuel-gauge to "dlg,da9150-fuel-gauge". Also updated driver name string to keep consistency. - Update Kconfig and Makefile to use BATTERY_* for config entry instead of FG_*. Also fuel-gauge module now depends on MFD not Charger. - Added helper function to simplify single attribute accesses using QIF interface of fuel-gauge. - Use of devm_* functions for IRQ and power_supply registration. - Added checking of result from platform_get_irq_byname(). Changes in v3: - Removed use of temp callback function, at request of Lee Jones. - Comment added to clarify limitation of temperature reading functionality that remains. Changes in v2: - Moved temp callback function prototype to be part of power fuel-gauge patch, rather than MFD, as requested by Lee Jones. drivers/power/Kconfig | 10 + drivers/power/Makefile | 1 + drivers/power/da9150-fg.c | 578 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 589 insertions(+) create mode 100644 drivers/power/da9150-fg.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index f8758d6..8d53f58 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -204,6 +204,16 @@ config CHARGER_DA9150 This driver can also be built as a module. If so, the module will be called da9150-charger. +config BATTERY_DA9150 + tristate "Dialog Semiconductor DA9150 Fuel Gauge support" + depends on MFD_DA9150 + help + Say Y here to enable support for the Fuel-Gauge unit of the DA9150 + Integrated Charger & Fuel-Gauge IC + + This driver can also be built as a module. If so, the module will be + called da9150-fg. + config AXP288_CHARGER tristate "X-Powers AXP288 Charger" depends on MFD_AXP20X && EXTCON_AXP288 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 5752ce8..cbdf89d 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o 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_Z2) += z2_battery.o diff --git a/drivers/power/da9150-fg.c b/drivers/power/da9150-fg.c new file mode 100644 index 0000000..39ebf04 --- /dev/null +++ b/drivers/power/da9150-fg.c @@ -0,0 +1,578 @@ +/* + * DA9150 Fuel-Gauge Driver + * + * Copyright (c) 2015 Dialog Semiconductor + * + * Author: Adam Thomson <Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/power_supply.h> +#include <linux/list.h> +#include <asm/div64.h> +#include <linux/mfd/da9150/core.h> +#include <linux/mfd/da9150/registers.h> + +/* Core2Wire */ +#define DA9150_QIF_READ (0x0 << 7) +#define DA9150_QIF_WRITE (0x1 << 7) +#define DA9150_QIF_CODE_MASK 0x7F + +#define DA9150_QIF_BYTE_SIZE 8 +#define DA9150_QIF_BYTE_MASK 0xFF +#define DA9150_QIF_SHORT_SIZE 2 +#define DA9150_QIF_LONG_SIZE 4 + +/* QIF Codes */ +#define DA9150_QIF_UAVG 6 +#define DA9150_QIF_UAVG_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_IAVG 8 +#define DA9150_QIF_IAVG_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_NTCAVG 12 +#define DA9150_QIF_NTCAVG_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_SHUNT_VAL 36 +#define DA9150_QIF_SHUNT_VAL_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_SD_GAIN 38 +#define DA9150_QIF_SD_GAIN_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_FCC_MAH 40 +#define DA9150_QIF_FCC_MAH_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_SOC_PCT 43 +#define DA9150_QIF_SOC_PCT_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_CHARGE_LIMIT 44 +#define DA9150_QIF_CHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_DISCHARGE_LIMIT 45 +#define DA9150_QIF_DISCHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_FW_MAIN_VER 118 +#define DA9150_QIF_FW_MAIN_VER_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_E_FG_STATUS 126 +#define DA9150_QIF_E_FG_STATUS_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_SYNC 127 +#define DA9150_QIF_SYNC_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_MAX_CODES 128 + +/* QIF Sync Timeout */ +#define DA9150_QIF_SYNC_TIMEOUT 1000 +#define DA9150_QIF_SYNC_RETRIES 10 + +/* QIF E_FG_STATUS */ +#define DA9150_FG_IRQ_LOW_SOC_MASK (1 << 0) +#define DA9150_FG_IRQ_HIGH_SOC_MASK (1 << 1) +#define DA9150_FG_IRQ_SOC_MASK \ + (DA9150_FG_IRQ_LOW_SOC_MASK | DA9150_FG_IRQ_HIGH_SOC_MASK) + +/* Private data */ +struct da9150_fg { + struct da9150 *da9150; + struct device *dev; + + struct mutex io_lock; + + struct power_supply *battery; + struct delayed_work work; + u32 interval; + + int warn_soc; + int crit_soc; + int soc; +}; + +/* Battery Properties */ +static u32 da9150_fg_read_attr(struct da9150_fg *fg, u8 code, u8 size) + +{ + u8 buf[size]; + u8 read_addr; + u32 res = 0; + int i; + + /* Set QIF code (READ mode) */ + read_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_READ; + + da9150_read_qif(fg->da9150, read_addr, size, buf); + for (i = 0; i < size; ++i) + res |= (buf[i] << (i * DA9150_QIF_BYTE_SIZE)); + + return res; +} + +static void da9150_fg_write_attr(struct da9150_fg *fg, u8 code, u8 size, + u32 val) + +{ + u8 buf[size]; + u8 write_addr; + int i; + + /* Set QIF code (WRITE mode) */ + write_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_WRITE; + + for (i = 0; i < size; ++i) { + buf[i] = (val >> (i * DA9150_QIF_BYTE_SIZE)) & + DA9150_QIF_BYTE_MASK; + } + da9150_write_qif(fg->da9150, write_addr, size, buf); +} + +/* Trigger QIF Sync to update QIF readable data */ +static void da9150_fg_read_sync_start(struct da9150_fg *fg) +{ + int i = 0; + u32 res = 0; + + mutex_lock(&fg->io_lock); + + /* Check if QIF sync already requested, and write to sync if not */ + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + if (res > 0) + da9150_fg_write_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE, 0); + + /* Wait for sync to complete */ + res = 0; + while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) { + usleep_range(DA9150_QIF_SYNC_TIMEOUT, + DA9150_QIF_SYNC_TIMEOUT * 2); + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + } + + /* Check if sync completed */ + if (res == 0) + dev_err(fg->dev, "Failed to perform QIF read sync!\n"); +} + +/* + * Should always be called after QIF sync read has been performed, and all + * attributes required have been accessed. + */ +static inline void da9150_fg_read_sync_end(struct da9150_fg *fg) +{ + mutex_unlock(&fg->io_lock); +} + +/* Sync read of single QIF attribute */ +static u32 da9150_fg_read_attr_sync(struct da9150_fg *fg, u8 code, u8 size) +{ + u32 val; + + da9150_fg_read_sync_start(fg); + val = da9150_fg_read_attr(fg, code, size); + da9150_fg_read_sync_end(fg); + + return val; +} + +/* Wait for QIF Sync, write QIF data and wait for ack */ +static void da9150_fg_write_attr_sync(struct da9150_fg *fg, u8 code, u8 size, + u32 val) +{ + int i = 0; + u32 res = 0, sync_val; + + mutex_lock(&fg->io_lock); + + /* Check if QIF sync already requested */ + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + + /* Wait for an existing sync to complete */ + while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) { + usleep_range(DA9150_QIF_SYNC_TIMEOUT, + DA9150_QIF_SYNC_TIMEOUT * 2); + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + } + + if (res == 0) { + dev_err(fg->dev, "Timeout waiting for existing QIF sync!\n"); + mutex_unlock(&fg->io_lock); + return; + } + + /* Write value for QIF code */ + da9150_fg_write_attr(fg, code, size, val); + + /* Wait for write acknowledgment */ + i = 0; + sync_val = res; + while ((res == sync_val) && (i++ < DA9150_QIF_SYNC_RETRIES)) { + usleep_range(DA9150_QIF_SYNC_TIMEOUT, + DA9150_QIF_SYNC_TIMEOUT * 2); + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + } + + mutex_unlock(&fg->io_lock); + + /* Check write was actually successful */ + if (res != (sync_val + 1)) + dev_err(fg->dev, "Error performing QIF sync write for code %d\n", + code); +} + +/* Power Supply attributes */ +static int da9150_fg_capacity(struct da9150_fg *fg, + union power_supply_propval *val) +{ + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT, + DA9150_QIF_SOC_PCT_SIZE); + + if (val->intval > 100) + val->intval = 100; + + return 0; +} + +static int da9150_fg_current_avg(struct da9150_fg *fg, + union power_supply_propval *val) +{ + u32 iavg, sd_gain, shunt_val; + u64 div, res; + + da9150_fg_read_sync_start(fg); + iavg = da9150_fg_read_attr(fg, DA9150_QIF_IAVG, + DA9150_QIF_IAVG_SIZE); + shunt_val = da9150_fg_read_attr(fg, DA9150_QIF_SHUNT_VAL, + DA9150_QIF_SHUNT_VAL_SIZE); + sd_gain = da9150_fg_read_attr(fg, DA9150_QIF_SD_GAIN, + DA9150_QIF_SD_GAIN_SIZE); + da9150_fg_read_sync_end(fg); + + div = (u64) (sd_gain * shunt_val * 65536ULL); + do_div(div, 1000000); + res = (u64) (iavg * 1000000ULL); + do_div(res, div); + + val->intval = (int) res; + + return 0; +} + +static int da9150_fg_voltage_avg(struct da9150_fg *fg, + union power_supply_propval *val) +{ + u64 res; + + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_UAVG, + DA9150_QIF_UAVG_SIZE); + + res = (u64) (val->intval * 186ULL); + do_div(res, 10000); + val->intval = (int) res; + + return 0; +} + +static int da9150_fg_charge_full(struct da9150_fg *fg, + union power_supply_propval *val) +{ + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_FCC_MAH, + DA9150_QIF_FCC_MAH_SIZE); + + val->intval = val->intval * 1000; + + return 0; +} + +/* + * Temperature reading from device is only valid if battery/system provides + * valid NTC to associated pin of DA9150 chip. + */ +static int da9150_fg_temp(struct da9150_fg *fg, + union power_supply_propval *val) +{ + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_NTCAVG, + DA9150_QIF_NTCAVG_SIZE); + + val->intval = (val->intval * 10) / 1048576; + + return 0; +} + +static enum power_supply_property da9150_fg_props[] = { + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_TEMP, +}; + +static int da9150_fg_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct da9150_fg *fg = dev_get_drvdata(psy->dev.parent); + int ret; + + switch (psp) { + case POWER_SUPPLY_PROP_CAPACITY: + ret = da9150_fg_capacity(fg, val); + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + ret = da9150_fg_current_avg(fg, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_AVG: + ret = da9150_fg_voltage_avg(fg, val); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + ret = da9150_fg_charge_full(fg, val); + break; + case POWER_SUPPLY_PROP_TEMP: + ret = da9150_fg_temp(fg, val); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* Repeated SOC check */ +static bool da9150_fg_soc_changed(struct da9150_fg *fg) +{ + union power_supply_propval val; + + da9150_fg_capacity(fg, &val); + if (val.intval != fg->soc) { + fg->soc = val.intval; + return true; + } + + return false; +} + +static void da9150_fg_work(struct work_struct *work) +{ + struct da9150_fg *fg = container_of(work, struct da9150_fg, work.work); + + /* Report if SOC has changed */ + if (da9150_fg_soc_changed(fg)) + power_supply_changed(fg->battery); + + schedule_delayed_work(&fg->work, msecs_to_jiffies(fg->interval)); +} + +/* SOC level event configuration */ +static void da9150_fg_soc_event_config(struct da9150_fg *fg) +{ + int soc; + + soc = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT, + DA9150_QIF_SOC_PCT_SIZE); + + if (soc > fg->warn_soc) { + /* If SOC > warn level, set discharge warn level event */ + da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT, + DA9150_QIF_DISCHARGE_LIMIT_SIZE, + fg->warn_soc + 1); + } else if ((soc <= fg->warn_soc) && (soc > fg->crit_soc)) { + /* + * If SOC <= warn level, set discharge crit level event, + * and set charge warn level event. + */ + da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT, + DA9150_QIF_DISCHARGE_LIMIT_SIZE, + fg->crit_soc + 1); + + da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT, + DA9150_QIF_CHARGE_LIMIT_SIZE, + fg->warn_soc); + } else if (soc <= fg->crit_soc) { + /* If SOC <= crit level, set charge crit level event */ + da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT, + DA9150_QIF_CHARGE_LIMIT_SIZE, + fg->crit_soc); + } +} + +static irqreturn_t da9150_fg_irq(int irq, void *data) +{ + struct da9150_fg *fg = data; + u32 e_fg_status; + + /* Read FG IRQ status info */ + e_fg_status = da9150_fg_read_attr(fg, DA9150_QIF_E_FG_STATUS, + DA9150_QIF_E_FG_STATUS_SIZE); + + /* Handle warning/critical threhold events */ + if (e_fg_status & DA9150_FG_IRQ_SOC_MASK) + da9150_fg_soc_event_config(fg); + + /* Clear any FG IRQs */ + da9150_fg_write_attr(fg, DA9150_QIF_E_FG_STATUS, + DA9150_QIF_E_FG_STATUS_SIZE, e_fg_status); + + return IRQ_HANDLED; +} + +static struct da9150_fg_pdata *da9150_fg_dt_pdata(struct device *dev) +{ + struct device_node *fg_node = dev->of_node; + struct da9150_fg_pdata *pdata; + + pdata = devm_kzalloc(dev, sizeof(struct da9150_fg_pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + of_property_read_u32(fg_node, "dlg,update-interval", + &pdata->update_interval); + of_property_read_u8(fg_node, "dlg,warn-soc-level", + &pdata->warn_soc_lvl); + of_property_read_u8(fg_node, "dlg,crit-soc-level", + &pdata->crit_soc_lvl); + + return pdata; +} + +static const struct power_supply_desc fg_desc = { + .name = "da9150-fg", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = da9150_fg_props, + .num_properties = ARRAY_SIZE(da9150_fg_props), + .get_property = da9150_fg_get_prop, +}; + +static int da9150_fg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct da9150 *da9150 = dev_get_drvdata(dev->parent); + struct da9150_fg_pdata *fg_pdata = dev_get_platdata(dev); + struct da9150_fg *fg; + int ver, irq, ret = 0; + + fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL); + if (fg == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, fg); + fg->da9150 = da9150; + fg->dev = dev; + + mutex_init(&fg->io_lock); + + /* Enable QIF */ + da9150_set_bits(da9150, DA9150_CORE2WIRE_CTRL_A, DA9150_FG_QIF_EN_MASK, + DA9150_FG_QIF_EN_MASK); + + fg->battery = devm_power_supply_register(dev, &fg_desc, NULL); + if (IS_ERR(fg->battery)) { + ret = PTR_ERR(fg->battery); + return ret; + } + + ver = da9150_fg_read_attr(fg, DA9150_QIF_FW_MAIN_VER, + DA9150_QIF_FW_MAIN_VER_SIZE); + dev_info(dev, "Version: 0x%x\n", ver); + + /* Handle DT data if provided */ + if (dev->of_node) { + fg_pdata = da9150_fg_dt_pdata(dev); + dev->platform_data = fg_pdata; + } + + /* Handle any pdata provided */ + if (fg_pdata) { + fg->interval = fg_pdata->update_interval; + + if (fg_pdata->warn_soc_lvl > 100) + dev_warn(dev, "Invalid SOC warning level provided, Ignoring"); + else + fg->warn_soc = fg_pdata->warn_soc_lvl; + + if ((fg_pdata->crit_soc_lvl > 100) || + (fg_pdata->crit_soc_lvl >= fg_pdata->warn_soc_lvl)) + dev_warn(dev, "Invalid SOC critical level provided, Ignoring"); + else + fg->crit_soc = fg_pdata->crit_soc_lvl; + + + } + + /* Configure initial SOC level events */ + da9150_fg_soc_event_config(fg); + + /* + * If an interval period has been provided then setup repeating + * work for reporting data updates. + */ + if (fg->interval) { + INIT_DELAYED_WORK(&fg->work, da9150_fg_work); + schedule_delayed_work(&fg->work, + msecs_to_jiffies(fg->interval)); + } + + /* Register IRQ */ + irq = platform_get_irq_byname(pdev, "FG"); + if (irq < 0) { + dev_err(dev, "Failed to get IRQ FG: %d\n", irq); + goto irq_fail; + } + + ret = devm_request_threaded_irq(dev, irq, NULL, da9150_fg_irq, + IRQF_ONESHOT, "FG", fg); + if (ret) { + dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret); + goto irq_fail; + } + + return 0; + +irq_fail: + if (fg->interval) + cancel_delayed_work(&fg->work); + + return ret; +} + +static int da9150_fg_remove(struct platform_device *pdev) +{ + struct da9150_fg *fg = platform_get_drvdata(pdev); + + if (fg->interval) + cancel_delayed_work(&fg->work); + + return 0; +} + +static int da9150_fg_resume(struct platform_device *pdev) +{ + struct da9150_fg *fg = platform_get_drvdata(pdev); + + /* + * Trigger SOC check to happen now so as to indicate any value change + * since last check before suspend. + */ + if (fg->interval) + flush_delayed_work(&fg->work); + + return 0; +} + +static struct platform_driver da9150_fg_driver = { + .driver = { + .name = "da9150-fuel-gauge", + }, + .probe = da9150_fg_probe, + .remove = da9150_fg_remove, + .resume = da9150_fg_resume, +}; + +module_platform_driver(da9150_fg_driver); + +MODULE_DESCRIPTION("Fuel-Gauge Driver for DA9150"); +MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>"); +MODULE_LICENSE("GPL"); -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v6 3/6] power: Add support for DA9150 Fuel-Gauge 2015-10-05 16:03 ` [PATCH v6 3/6] power: Add support for DA9150 Fuel-Gauge Adam Thomson @ 2015-10-05 16:10 ` Fabio Estevam [not found] ` <80d467703ba19bef12e9bcdd246e1de7bd33a8b1.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> 1 sibling, 0 replies; 9+ messages in thread From: Fabio Estevam @ 2015-10-05 16:10 UTC (permalink / raw) To: Adam Thomson Cc: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel, Support Opensource On Mon, Oct 5, 2015 at 1:03 PM, Adam Thomson <Adam.Thomson.Opensource@diasemi.com> wrote: > + /* Register IRQ */ > + irq = platform_get_irq_byname(pdev, "FG"); > + if (irq < 0) { > + dev_err(dev, "Failed to get IRQ FG: %d\n", irq); You need to do "ret = irq" here. Otherwise you will return success in irq_fail. > + goto irq_fail; ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <80d467703ba19bef12e9bcdd246e1de7bd33a8b1.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>]
* Re: [PATCH v6 3/6] power: Add support for DA9150 Fuel-Gauge [not found] ` <80d467703ba19bef12e9bcdd246e1de7bd33a8b1.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> @ 2015-10-06 18:50 ` kbuild test robot 0 siblings, 0 replies; 9+ messages in thread From: kbuild test robot @ 2015-10-06 18:50 UTC (permalink / raw) To: Adam Thomson Cc: kbuild-all-JC7UmRfGjtg, Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, linux-pm-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Support Opensource [-- Attachment #1: Type: text/plain, Size: 1491 bytes --] Hi Adam, [auto build test WARNING on v4.3-rc4 -- if it's inappropriate base, please ignore] config: s390-allyesconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=s390 All warnings (new ones prefixed by >>): drivers/power/da9150-fg.c: In function 'da9150_fg_read_attr.isra.4': >> drivers/power/da9150-fg.c:108:1: warning: 'da9150_fg_read_attr.isra.4' uses dynamic stack allocation } ^ vim +108 drivers/power/da9150-fg.c 92 static u32 da9150_fg_read_attr(struct da9150_fg *fg, u8 code, u8 size) 93 94 { 95 u8 buf[size]; 96 u8 read_addr; 97 u32 res = 0; 98 int i; 99 100 /* Set QIF code (READ mode) */ 101 read_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_READ; 102 103 da9150_read_qif(fg->da9150, read_addr, size, buf); 104 for (i = 0; i < size; ++i) 105 res |= (buf[i] << (i * DA9150_QIF_BYTE_SIZE)); 106 107 return res; > 108 } 109 110 static void da9150_fg_write_attr(struct da9150_fg *fg, u8 code, u8 size, 111 u32 val) 112 113 { 114 u8 buf[size]; 115 u8 write_addr; 116 int i; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/octet-stream, Size: 38650 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 4/6] power: da9150: Add DT bindings documentation for Fuel-Gauge 2015-10-05 16:03 [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge Adam Thomson ` (2 preceding siblings ...) [not found] ` <cover.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> @ 2015-10-05 16:03 ` Adam Thomson 2015-10-05 16:03 ` [PATCH v6 5/6] mfd: da9150: Use relative paths in DT bindings document Adam Thomson 2015-10-05 16:03 ` [PATCH v6 6/6] mfd: da9150: Use DEFINE_RES_IRQ_NAMED() help macro for IRQ resource Adam Thomson 5 siblings, 0 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm, devicetree, linux-kernel, Support Opensource Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Acked-By: Sebastian Reichel <sre@kernel.org> --- Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - Update compatible string of fuel-gauge to "dlg,da9150-fuel-gauge". - Changed example node name to "fuel-gauge". Changes in v3: - N/A Changes in v2: - N/A .../devicetree/bindings/power/da9150-fg.txt | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/da9150-fg.txt diff --git a/Documentation/devicetree/bindings/power/da9150-fg.txt b/Documentation/devicetree/bindings/power/da9150-fg.txt new file mode 100644 index 0000000..00236fe --- /dev/null +++ b/Documentation/devicetree/bindings/power/da9150-fg.txt @@ -0,0 +1,23 @@ +Dialog Semiconductor DA9150 Fuel-Gauge Power Supply bindings + +Required properties: +- compatible: "dlg,da9150-fuel-gauge" for DA9150 Fuel-Gauge Power Supply + +Optional properties: +- dlg,update-interval: Interval time (milliseconds) between battery level checks. +- dlg,warn-soc-level: Battery discharge level (%) where warning event raised. + [1 - 100] +- dlg,crit-soc-level: Battery discharge level (%) where critical event raised. + This value should be lower than the warning level. + [1 - 100] + + +Example: + + fuel-gauge { + compatible = "dlg,da9150-fuel-gauge"; + + dlg,update-interval = <10000>; + dlg,warn-soc-level = /bits/ 8 <15>; + dlg,crit-soc-level = /bits/ 8 <5>; + }; -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v6 5/6] mfd: da9150: Use relative paths in DT bindings document 2015-10-05 16:03 [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge Adam Thomson ` (3 preceding siblings ...) 2015-10-05 16:03 ` [PATCH v6 4/6] power: da9150: Add DT bindings documentation for Fuel-Gauge Adam Thomson @ 2015-10-05 16:03 ` Adam Thomson 2015-10-05 16:03 ` [PATCH v6 6/6] mfd: da9150: Use DEFINE_RES_IRQ_NAMED() help macro for IRQ resource Adam Thomson 5 siblings, 0 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm, devicetree, linux-kernel, Support Opensource When referencing other DT bindings documentation, use relative path rather than absolute. Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Suggested-by: Lee Jones <lee.jones@linaro.org> Acked-by: Lee Jones <lee.jones@linaro.org> --- Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - N/A Changes in v3: - Initial version. Changes in v2: - N/A Documentation/devicetree/bindings/mfd/da9150.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/da9150.txt b/Documentation/devicetree/bindings/mfd/da9150.txt index 970801d..fd4dca7 100644 --- a/Documentation/devicetree/bindings/mfd/da9150.txt +++ b/Documentation/devicetree/bindings/mfd/da9150.txt @@ -17,13 +17,13 @@ Required properties: the IRQs from da9150 are delivered to. - interrupts: IRQ line info for da9150 chip. - interrupt-controller: da9150 has internal IRQs (own IRQ domain). - (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for + (See ../interrupt-controller/interrupts.txt for further information relating to interrupt properties) Sub-devices: -- da9150-gpadc: See Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt -- da9150-charger: See Documentation/devicetree/bindings/power/da9150-charger.txt -- da9150-fg: See Documentation/devicetree/bindings/power/da9150-fg.txt +- da9150-gpadc: See ../iio/adc/da9150-gpadc.txt +- da9150-charger: See ../power/da9150-charger.txt +- da9150-fg: See ../power/da9150-fg.txt Example: -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v6 6/6] mfd: da9150: Use DEFINE_RES_IRQ_NAMED() help macro for IRQ resource 2015-10-05 16:03 [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge Adam Thomson ` (4 preceding siblings ...) 2015-10-05 16:03 ` [PATCH v6 5/6] mfd: da9150: Use relative paths in DT bindings document Adam Thomson @ 2015-10-05 16:03 ` Adam Thomson 5 siblings, 0 replies; 9+ messages in thread From: Adam Thomson @ 2015-10-05 16:03 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz, Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala Cc: linux-pm, devicetree, linux-kernel, Support Opensource Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Suggested-by: Lee Jones <lee.jones@linaro.org> Acked-by: Lee Jones <lee.jones@linaro.org> --- Changes in v6: - Rebase to v4.3-rc4 Changes in v5: - Rebase to v4.2 Changes in v4: - N/A Changes in v3: - Initial version. Changes in v2: - N/A drivers/mfd/da9150-core.c | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c index 85ca4b5..195fdcf 100644 --- a/drivers/mfd/da9150-core.c +++ b/drivers/mfd/da9150-core.c @@ -355,39 +355,14 @@ static const struct regmap_irq_chip da9150_regmap_irq_chip = { }; static struct resource da9150_gpadc_resources[] = { - { - .name = "GPADC", - .start = DA9150_IRQ_GPADC, - .end = DA9150_IRQ_GPADC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_GPADC, "GPADC"), }; static struct resource da9150_charger_resources[] = { - { - .name = "CHG_STATUS", - .start = DA9150_IRQ_CHG, - .end = DA9150_IRQ_CHG, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG_TJUNC", - .start = DA9150_IRQ_TJUNC, - .end = DA9150_IRQ_TJUNC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG_VFAULT", - .start = DA9150_IRQ_VFAULT, - .end = DA9150_IRQ_VFAULT, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG_VBUS", - .start = DA9150_IRQ_VBUS, - .end = DA9150_IRQ_VBUS, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_CHG, "CHG_STATUS"), + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_TJUNC, "CHG_TJUNC"), + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_VFAULT, "CHG_VFAULT"), + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_VBUS, "CHG_VBUS"), }; static struct resource da9150_fg_resources[] = { -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-10-06 18:50 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-10-05 16:03 [PATCH v6 0/6] Add support for DA9150 Fuel-Gauge Adam Thomson 2015-10-05 16:03 ` [PATCH v6 1/6] mfd: da9150: Add support for Fuel-Gauge Adam Thomson 2015-10-05 16:03 ` [PATCH v6 2/6] mfd: da9150: Update DT bindings for Fuel-Gauge support Adam Thomson [not found] ` <cover.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> 2015-10-05 16:03 ` [PATCH v6 3/6] power: Add support for DA9150 Fuel-Gauge Adam Thomson 2015-10-05 16:10 ` Fabio Estevam [not found] ` <80d467703ba19bef12e9bcdd246e1de7bd33a8b1.1444059987.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org> 2015-10-06 18:50 ` kbuild test robot 2015-10-05 16:03 ` [PATCH v6 4/6] power: da9150: Add DT bindings documentation for Fuel-Gauge Adam Thomson 2015-10-05 16:03 ` [PATCH v6 5/6] mfd: da9150: Use relative paths in DT bindings document Adam Thomson 2015-10-05 16:03 ` [PATCH v6 6/6] mfd: da9150: Use DEFINE_RES_IRQ_NAMED() help macro for IRQ resource Adam Thomson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).