Re: [PATCH v2 1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge
And one more comment: On Sun, 2014-02-02 at 02:23 +0400, Vladimir Barinov wrote: > +static int modelgauge_get_property(struct power_supply *psy, > +enum power_supply_property psp, > +union power_supply_propval *val) > +{ > + struct modelgauge_priv *priv = container_of(psy, > + struct modelgauge_priv, > + battery); > + struct regmap *regmap = priv->regmap; > + struct modelgauge_platform_data *pdata = priv->pdata; > + int reg; > + int ret; > + > + switch (psp) { > + case POWER_SUPPLY_PROP_STATUS: > + if (pdata && pdata->get_charging_status) > + val->intval = pdata->get_charging_status(); > + else > + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; > + break; > + case POWER_SUPPLY_PROP_VOLTAGE_NOW: > + ret = regmap_read(regmap, MODELGAUGE_VCELL_REG, ®); > + if (ret < 0) > + return ret; > + > + val->intval = modelgauge_lsb_to_uvolts(priv, reg); > + break; > + case POWER_SUPPLY_PROP_VOLTAGE_OCV: > + /* Unlock model access */ > + regmap_write(regmap, MODELGAUGE_UNLOCK_REG, > + MODELGAUGE_UNLOCK_VALUE); > + ret = regmap_read(regmap, MODELGAUGE_OCV_REG, ®); > + /* Lock model access */ > + regmap_write(regmap, MODELGAUGE_UNLOCK_REG, 0); > + if (ret < 0) > + return ret; > + > + val->intval = modelgauge_lsb_to_uvolts(priv, reg); > + break; > + case POWER_SUPPLY_PROP_CAPACITY: > + ret = regmap_read(regmap, MODELGAUGE_SOC_REG, ®); > + if (ret < 0) > + return ret; > + > + val->intval = reg / (1 << priv->soc_shift); > + break; > + case POWER_SUPPLY_PROP_TEMP: > + if (pdata && pdata->get_temperature) > + val->intval = pdata->get_temperature(); > + else > + val->intval = 25; If pdata->get_temperature() is not supplied then probably the driver should not support POWER_SUPPLY_PROP_TEMP at all. I think it is better not to report any temperature than to report a wrong one. Best regards, Krzysztof -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge
Hi, On Sun, 2014-02-02 at 02:23 +0400, Vladimir Barinov wrote: > Index: battery-2.6/drivers/power/modelgauge_battery.c > === > --- /dev/null 1970-01-01 00:00:00.0 + > +++ battery-2.6/drivers/power/modelgauge_battery.c2014-02-02 > 01:29:34.314614874 +0400 > @@ -0,0 +1,838 @@ > +/* > + * Maxim ModelGauge ICs fuel gauge driver > + * > + * Author: Vladimir Barinov > + * Copyright (C) 2013 Cogent Embedded, Inc. > + * > + * 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. > + */ (...) > +static int modelgauge_probe(struct i2c_client *client, > + const struct i2c_device_id *id) > +{ > + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); > + struct modelgauge_priv *priv; > + int ret; > + > + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) > + return -EIO; > + > + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + if (client->dev.of_node) > + priv->pdata = modelgauge_parse_dt(&client->dev); > + else > + priv->pdata = client->dev.platform_data; > + > + priv->dev = &client->dev; > + priv->chip = id->driver_data; > + > + i2c_set_clientdata(client, priv); > + > + priv->regmap = devm_regmap_init_i2c(client, &modelgauge_regmap); > + if (IS_ERR(priv->regmap)) > + return PTR_ERR(priv->regmap); > + > + priv->battery.name = "modelgauge_battery"; > + priv->battery.type = POWER_SUPPLY_TYPE_BATTERY; > + priv->battery.get_property = modelgauge_get_property; > + priv->battery.properties= modelgauge_battery_props; > + priv->battery.num_properties= ARRAY_SIZE(modelgauge_battery_props); > + > + INIT_WORK(&priv->load_work, modelgauge_load_model_work); > + INIT_DELAYED_WORK(&priv->rcomp_work, modelgauge_update_rcomp_work); > + > + ret = modelgauge_init(priv); > + if (ret) > + return ret; > + > + ret = power_supply_register(&client->dev, &priv->battery); > + if (ret) { > + dev_err(priv->dev, "failed: power supply register\n"); > + goto err_supply; > + } > + > + if (client->irq) { > + switch (priv->chip) { > + case ID_MAX17040: > + case ID_MAX17041: > + dev_err(priv->dev, "alert line is not supported\n"); > + ret = -EINVAL; > + goto err_irq; > + default: > + ret = devm_request_threaded_irq(priv->dev, client->irq, > + NULL, > + modelgauge_irq_handler, > + IRQF_TRIGGER_FALLING, > + priv->battery.name, > + priv); Shouldn't it be also IRQF_ONESHOT? Without this you may get an error: genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq > + if (ret) { > + dev_err(priv->dev, "failed to request irq %d\n", > + client->irq); > + goto err_irq; > + } > + } > + } > + > + return 0; > + > +err_irq: > + power_supply_unregister(&priv->battery); > +err_supply: > + cancel_work_sync(&priv->load_work); > + cancel_delayed_work_sync(&priv->rcomp_work); > + return ret; > +} > + > +static int modelgauge_remove(struct i2c_client *client) > +{ > + struct modelgauge_priv *priv = i2c_get_clientdata(client); > + > + cancel_work_sync(&priv->load_work); > + cancel_delayed_work_sync(&priv->rcomp_work); > + > + power_supply_unregister(&priv->battery); > + return 0; > +} > + > +#ifdef CONFIG_PM_SLEEP > +static int modelgauge_suspend(struct device *dev) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct modelgauge_priv *priv = i2c_get_clientdata(client); > + struct modelgauge_platform_data *pdata = priv->pdata; > + > + if (pdata && pdata->get_temperature) > + cancel_delayed_work_sync(&priv->rcomp_work); > + > + switch (priv->chip) { > + case ID_MAX17040: > + case ID_MAX17041: > + return 0; > + default: > + if (client->irq) { > + disable_irq(client->irq); > + enable_irq_wake(client->irq); > + } > + } > + > + return 0; > +} > + > +static int modelgauge_resume(struct device *dev) > +{ > + struc
[PATCH v2 1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge
Add Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips Signed-off-by: Vladimir Barinov --- drivers/power/Kconfig|9 drivers/power/Makefile |1 drivers/power/modelgauge_battery.c | 838 +++ include/linux/platform_data/battery-modelgauge.h | 31 4 files changed, 879 insertions(+) Index: battery-2.6/drivers/power/Kconfig === --- battery-2.6.orig/drivers/power/Kconfig 2014-02-02 01:29:07.434614235 +0400 +++ battery-2.6/drivers/power/Kconfig 2014-02-02 01:29:29.070614750 +0400 @@ -205,6 +205,15 @@ with MAX17042. This driver also supports max17047/50 chips which are improved version of max17042. +config BATTERY_MODELGAUGE + tristate "Maxim ModelGauge ICs fuel gauge" + depends on I2C + select REGMAP_I2C + help + ModelGauge(TM) is a Maxim algorithm incorporated in + MAX17040/41/43/44/48/49/58/59 fuel-gauges for lithium-ion (Li+) + batteries. + config BATTERY_Z2 tristate "Z2 battery driver" depends on I2C && MACH_ZIPIT2 Index: battery-2.6/drivers/power/Makefile === --- battery-2.6.orig/drivers/power/Makefile 2014-02-02 01:29:07.462614237 +0400 +++ battery-2.6/drivers/power/Makefile 2014-02-02 01:29:12.978614368 +0400 @@ -32,6 +32,7 @@ obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o +obj-$(CONFIG_BATTERY_MODELGAUGE) += modelgauge_battery.o obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o Index: battery-2.6/drivers/power/modelgauge_battery.c === --- /dev/null 1970-01-01 00:00:00.0 + +++ battery-2.6/drivers/power/modelgauge_battery.c 2014-02-02 01:29:34.314614874 +0400 @@ -0,0 +1,838 @@ +/* + * Maxim ModelGauge ICs fuel gauge driver + * + * Author: Vladimir Barinov + * Copyright (C) 2013 Cogent Embedded, Inc. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "modelgauge" + +/* Register offsets for ModelGauge ICs */ +#define MODELGAUGE_VCELL_REG 0x02 +#define MODELGAUGE_SOC_REG 0x04 +#define MODELGAUGE_MODE_REG0x06 +#define MODELGAUGE_VERSION_REG 0x08 +#define MODELGAUGE_HIBRT_REG 0x0A +#define MODELGAUGE_CONFIG_REG 0x0C +#define MODELGAUGE_OCV_REG 0x0E +#define MODELGAUGE_VALRT_REG 0x14 +#define MODELGAUGE_CRATE_REG 0x16 +#define MODELGAUGE_VRESETID_REG0x18 +#define MODELGAUGE_STATUS_REG 0x1A +#define MODELGAUGE_UNLOCK_REG 0x3E +#define MODELGAUGE_TABLE_REG 0x40 +#define MODELGAUGE_RCOMPSEG_REG0x80 +#define MODELGAUGE_CMD_REG 0xFE + +/* MODE register bits */ +#define MODELGAUGE_MODE_QUICKSTART (1 << 14) +#define MODELGAUGE_MODE_ENSLEEP(1 << 13) +#define MODELGAUGE_MODE_HIBSTAT(1 << 12) + +/* CONFIG register bits */ +#define MODELGAUGE_CONFIG_SLEEP(1 << 7) +#define MODELGAUGE_CONFIG_ALSC (1 << 6) +#define MODELGAUGE_CONFIG_ALRT (1 << 5) +#define MODELGAUGE_CONFIG_ATHD_MASK0x1f + +/* STATUS register bits */ +#define MODELGAUGE_STATUS_ENVR (1 << 14) +#define MODELGAUGE_STATUS_SC (1 << 13) +#define MODELGAUGE_STATUS_HD (1 << 12) +#define MODELGAUGE_STATUS_VR (1 << 11) +#define MODELGAUGE_STATUS_VL (1 << 10) +#define MODELGAUGE_STATUS_VH (1 << 9) +#define MODELGAUGE_STATUS_RI (1 << 8) + +/* VRESETID register bits */ +#define MODELGAUGE_VRESETID_DIS(1 << 8) + +#define MODELGAUGE_UNLOCK_VALUE0x4a57 +#define MODELGAUGE_RESET_VALUE 0x5400 + +#define MODELGAUGE_RCOMP_UPDATE_DELAY 6 + +/* Capacity threshold where an interrupt is generated on the ALRT pin */ +#define MODELGAUGE_EMPTY_ATHD 15 +/* Enable alert for 1% soc change */ +#define MODELGAUGE_SOC_CHANGE_ALERT1 +/* Hibernate threshold (crate), where IC enters hibernate mode */ +#define MODELGAUGE_HIBRT_THD 20 +/* Active threshold (mV), where IC exits hibernate mode */ +#define MODELGAUGE_ACTIVE_THD 60 +/* Voltage (mV), when IC alerts if battery voltage less then und