bq27x00_battery: Add new properties
PATCH 1/1 bq27x00_battery: Add new properties
Forwarding this to lkml and bq27x00 hackers.
Comments, Reviewed-by or Acked-by?
----- Forwarded message from Pali Rohár <[email protected]> -----
Date: Wed, 26 Jan 2011 21:44:08 +0100
From: Pali Rohár <[email protected]>
To: Anton Vorontsov <[email protected]>
Cc: David Woodhouse <[email protected]>
Subject: Re: [PATCH] bq27x00_battery
This patch add support for properties POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_ONLINE in module bq27x00_battery.
drivers/power/bq27x00_battery.c +120 -2
@@ -3,9 +3,14 @@* * Copyright (C) 2008 Rodolfo Giometti <[email protected]> * Copyright (C) 2008 Eurotech S.p.A. <[email protected]> +* Copyright (C) 2011 Pali Rohár <[email protected]> * * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. * +* Datasheets: +* http://focus.ti.com/docs/prod/folders/print/bq27000.html +* http://focus.ti.com/docs/prod/folders/print/bq27500.html +* * This package 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.
@@ -27,8 +32,9 @@#include <linux/slab.h> #include <asm/unaligned.h> -#define DRIVER_VERSION "1.1.0" +#define DRIVER_VERSION "1.2.0" +#define BQ27x00_REG_MODE 0x00#define BQ27x00_REG_TEMP 0x06#define BQ27x00_REG_VOLT 0x08#define BQ27x00_REG_AI 0x14
@@ -36,10 +42,14 @@#define BQ27x00_REG_TTE 0x16#define BQ27x00_REG_TTF 0x18#define BQ27x00_REG_TTECP 0x26 +#define BQ27x00_REG_NAC 0x0C/* Nominal available capaciy */ +#define BQ27x00_REG_LMD 0x12/* Last measured discharge */ +#define BQ27x00_REG_AE 0x22/* Available Enery */ #define BQ27000_RS 20/* Resistor sense */ #define BQ27000_REG_RSOC 0x0B/* Relative State-of-Charge */ #define BQ27000_FLAG_CHGS BIT(7) +#define BQ27000_FLAG_FC BIT(5)#define BQ27500_REG_SOC 0x2C#define BQ27500_FLAG_DSC BIT(0)
@@ -75,7 +85,11 @@ static enum power_supply_property bq27x0POWER_SUPPLY_PROP_VOLTAGE_NOW ,POWER_SUPPLY_PROP_CURRENT_NOW ,POWER_SUPPLY_PROP_CAPACITY , +POWER_SUPPLY_PROP_CHARGE_NOW , +POWER_SUPPLY_PROP_CHARGE_FULL , +POWER_SUPPLY_PROP_ENERGY_NOW ,POWER_SUPPLY_PROP_TEMP , +POWER_SUPPLY_PROP_ONLINE ,POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW ,POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG , POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
@@ -92,6 +106,24 @@ static int bq27x00_read(u8 reg, int *rt_ }/* +* Return the GPIO status (0 or 1) +* Or < 0 if something fails. +*/ +static int bq27x00_battery_gpio (struct bq27x00_device_info *di) +{ +int ret; +int gpio =0 ; + + ret =bq27x00_read (BQ27x00_REG_MODE, &gpio,0 , di); +if (ret) { +dev_err (di->dev,"error reading GPIO status\n" ); +return ret; + } + +return (gpio &0x40 ) >>6 ; +} + +/* * Return the battery temperature in tenths of degree Celsius * Or < 0 if something fails. */
@@ -188,6 +220,75 @@ static int bq27x00_battery_rsoc(struct breturn rsoc; } +/* +* Return the battery Nominal available capaciy in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_nac (struct bq27x00_device_info *di) +{ +int ret; +int nac =0 ; + + ret =bq27x00_read (BQ27x00_REG_NAC, &nac,0 , di); +if (ret) { +dev_err (di->dev,"error reading nominal available capaciy\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + nac *=1000 ; +else + nac = nac *3570 /BQ27000_RS ; + +return nac; +} + +/* +* Return the battery Last measured discharge in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_lmd (struct bq27x00_device_info *di) +{ +int ret; +int lmd =0 ; + + ret =bq27x00_read (BQ27x00_REG_LMD, &lmd,0 , di); +if (ret) { +dev_err (di->dev,"error reading last measured discharge\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + lmd *=1000 ; +else + lmd = lmd *3570 /BQ27000_RS ; + +return lmd; +} + +/* +* Return the battery Available energy in µWh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_energy (struct bq27x00_device_info *di) +{ +int ret; +int ae =0 ; + + ret =bq27x00_read (BQ27x00_REG_LMD, &ae,0 , di); +if (ret) { +dev_err (di->dev,"error reading available energy\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + ae *=1000 ; +else + ae = ae *29200 /BQ27000_RS ; + +return ae; +} +static int bq27x00_battery_status (struct bq27x00_device_info *di,union power_supply_propval *val) {
@@ -209,7 +310,9 @@ static int bq27x00_battery_status(structelse status =POWER_SUPPLY_STATUS_CHARGING ; }else { -if (flags &BQ27000_FLAG_CHGS ) +if (flags &BQ27000_FLAG_FC ) + status =POWER_SUPPLY_STATUS_FULL ; +else if (flags &BQ27000_FLAG_CHGS ) status =POWER_SUPPLY_STATUS_CHARGING ;else status =POWER_SUPPLY_STATUS_DISCHARGING ;
@@ -256,6 +359,9 @@ static int bq27x00_battery_get_property(case POWER_SUPPLY_PROP_STATUS : ret =bq27x00_battery_status (di, val);break ; +case POWER_SUPPLY_PROP_ONLINE : + val->intval =bq27x00_battery_gpio (di); +break ;case POWER_SUPPLY_PROP_VOLTAGE_NOW :case POWER_SUPPLY_PROP_PRESENT : val->intval =bq27x00_battery_voltage (di);
@@ -268,6 +374,15 @@ static int bq27x00_battery_get_property(case POWER_SUPPLY_PROP_CAPACITY : val->intval =bq27x00_battery_rsoc (di);break ; +case POWER_SUPPLY_PROP_CHARGE_NOW : + val->intval =bq27x00_battery_nac (di); +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL : + val->intval =bq27x00_battery_lmd (di); +break ; +case POWER_SUPPLY_PROP_ENERGY_NOW : + val->intval =bq27x00_battery_energy (di); +break ;case POWER_SUPPLY_PROP_TEMP : val->intval =bq27x00_battery_temperature (di);break ;
@@ -472,4 +587,7 @@ module_exit(bq27x00_battery_exit);MODULE_AUTHOR ("Rodolfo Giometti <[email protected]>" );MODULE_DESCRIPTION ("BQ27x00 battery monitor driver" ); +MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );MODULE_LICENSE ("GPL" );
----- End forwarded message -----
Quoted 22 lines · Anton Vorontsov
Forwarding this to lkml and bq27x00 hackers.
Comments, Reviewed-by or Acked-by?
----- Forwarded message from Pali Rohár <[email protected]> -----
Date: Wed, 26 Jan 2011 21:44:08 +0100
From: Pali Rohár <[email protected]>
To: Anton Vorontsov <[email protected]>
Cc: David Woodhouse <[email protected]>
Subject: Re: [PATCH]bq27x00_batteryThis patch add support for properties
POWER_SUPPLY_PROP_CHARGE_NOW,POWER_SUPPLY_PROP_CHARGE_FULL,POWER_SUPPLY_PROP_ENERGY_NOW,POWER_SUPPLY_PROP_ONLINEin modulebq27x00_battery.Signed-off-by Pali Rohár <[email protected]>Tested-by Pali Rohár <[email protected]>
drivers/power/bq27x00_battery.c line 6
Quoted 4 lines
drivers/power/bq27x00_battery.c +1
-0@@ -3,9 +3,14 @@* * Copyright (C) 2008 Rodolfo Giometti <[email protected]> * Copyright (C) 2008 Eurotech S.p.A. <[email protected]> +* Copyright (C) 2011 Pali Rohár <[email protected]>
I think you should put your copyright on the changes you did:
i.e. GPIO settings and so on. Example:
* GPIO setting/management and ... by Pali Rohár <[email protected]>
* Copyright (C) 2011
drivers/power/bq27x00_battery.c line 13
Quoted 7 lines
drivers/power/bq27x00_battery.c +4
-0* * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. * +* Datasheets: +* http://focus.ti.com/docs/prod/folders/print/bq27000.html +* http://focus.ti.com/docs/prod/folders/print/bq27500.html +*
Don't mix copyright messages with info ones. Put these info at the end of this into text.
Quoted 45 lines
drivers/power/bq27x00_battery.c +10
-1* This package 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. @@ -27,8 +32,9 @@#include <linux/slab.h> #include <asm/unaligned.h> -#define DRIVER_VERSION "1.1.0" +#define DRIVER_VERSION "1.2.0" +#define BQ27x00_REG_MODE 0x00#define BQ27x00_REG_TEMP 0x06#define BQ27x00_REG_VOLT 0x08#define BQ27x00_REG_AI 0x14@@ -36,10 +42,14 @@#define BQ27x00_REG_TTE 0x16#define BQ27x00_REG_TTF 0x18#define BQ27x00_REG_TTECP 0x26 +#define BQ27x00_REG_NAC 0x0C/* Nominal available capaciy */ +#define BQ27x00_REG_LMD 0x12/* Last measured discharge */ +#define BQ27x00_REG_AE 0x22/* Available Enery */ #define BQ27000_RS 20/* Resistor sense */ #define BQ27000_REG_RSOC 0x0B/* Relative State-of-Charge */ #define BQ27000_FLAG_CHGS BIT(7) +#define BQ27000_FLAG_FC BIT(5)#define BQ27500_REG_SOC 0x2C#define BQ27500_FLAG_DSC BIT(0)@@ -75,7 +85,11 @@ static enum power_supply_property bq27x0POWER_SUPPLY_PROP_VOLTAGE_NOW ,POWER_SUPPLY_PROP_CURRENT_NOW ,POWER_SUPPLY_PROP_CAPACITY , +POWER_SUPPLY_PROP_CHARGE_NOW , +POWER_SUPPLY_PROP_CHARGE_FULL , +POWER_SUPPLY_PROP_ENERGY_NOW ,POWER_SUPPLY_PROP_TEMP , +POWER_SUPPLY_PROP_ONLINE ,POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW ,POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG , POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,@@ -92,6 +106,24 @@ static int bq27x00_read(u8 reg, int *rt_ }/*
drivers/power/bq27x00_battery.c static int bq27x00_read(u8 reg, int *rt_ · line 118
Quoted 10 lines
drivers/power/bq27x00_battery.c +10
-0+* Return the GPIO status (0 or 1) +* Or < 0 if something fails. +*/ +static int bq27x00_battery_gpio (struct bq27x00_device_info *di) +{ +int ret; +int gpio =0 ; + + ret =bq27x00_read (BQ27x00_REG_MODE, &gpio,0 , di); +if (ret) {
I think you should use ret < 0.
drivers/power/bq27x00_battery.c static int bq27x00_read(u8 reg, int *rt_ · line 123
Quoted 5 lines
drivers/power/bq27x00_battery.c +5
-0+dev_err (di->dev,"error reading GPIO status\n" ); +return ret; + } + +return (gpio &0x40 ) >>6 ;
Why not using:
!!(gpio & 0x40)
or
(gpio & 0x40) ? 1 : 0
? I think it could be more readable... :)
However, I don't understand why you fix gpio=0... it's your machine depending settings? In these case you should use the platform_data mechanism to properly setup the GPIO.
Quoted 7 lines
drivers/power/bq27x00_battery.c +3
-0+} + +/* * Return the battery temperature in tenths of degree Celsius * Or < 0 if something fails. */
drivers/power/bq27x00_battery.c static int bq27x00_battery_rsoc(struct b · line 227
Quoted 8 lines
drivers/power/bq27x00_battery.c +5
-0@@ -188,6 +220,75 @@ static int bq27x00_battery_rsoc(struct breturn rsoc; } +/* +* Return the battery Nominal available capaciy in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_nac (struct bq27x00_device_info *di)
Let me suggest using bq27x00_battery_nac_uAh as function name...
drivers/power/bq27x00_battery.c static int bq27x00_battery_rsoc(struct b · line 233
Quoted 6 lines
drivers/power/bq27x00_battery.c +6
-0+{ +int ret; +int nac =0 ; + + ret =bq27x00_read (BQ27x00_REG_NAC, &nac,0 , di); +if (ret) {
Ditto.
Quoted 7 lines
drivers/power/bq27x00_battery.c +7
-0+dev_err (di->dev,"error reading nominal available capaciy\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + nac *=1000 ; +else
drivers/power/bq27x00_battery.c static int bq27x00_battery_rsoc(struct b · line 250
Quoted 10 lines
drivers/power/bq27x00_battery.c +10
-0+ nac = nac *3570 /BQ27000_RS ; + +return nac; +} + +/* +* Return the battery Last measured discharge in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_lmd (struct bq27x00_device_info *di)
bq27x00_battery_lmd_uAh
drivers/power/bq27x00_battery.c static int bq27x00_battery_rsoc(struct b · line 256
Quoted 6 lines
drivers/power/bq27x00_battery.c +6
-0+{ +int ret; +int lmd =0 ; + + ret =bq27x00_read (BQ27x00_REG_LMD, &lmd,0 , di); +if (ret) {
Ditto.
Quoted 7 lines
drivers/power/bq27x00_battery.c +7
-0+dev_err (di->dev,"error reading last measured discharge\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + lmd *=1000 ; +else
drivers/power/bq27x00_battery.c static int bq27x00_battery_rsoc(struct b · line 273
Quoted 10 lines
drivers/power/bq27x00_battery.c +10
-0+ lmd = lmd *3570 /BQ27000_RS ; + +return lmd; +} + +/* +* Return the battery Available energy in µWh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_energy (struct bq27x00_device_info *di)
bq27x00_battery_energy_uWh
drivers/power/bq27x00_battery.c static int bq27x00_battery_rsoc(struct b · line 279
Quoted 6 lines
drivers/power/bq27x00_battery.c +6
-0+{ +int ret; +int ae =0 ; + + ret =bq27x00_read (BQ27x00_REG_LMD, &ae,0 , di); +if (ret) {
Ditto.
Quoted 62 lines
drivers/power/bq27x00_battery.c +30
-2+dev_err (di->dev,"error reading available energy\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + ae *=1000 ; +else + ae = ae *29200 /BQ27000_RS ; + +return ae; +} +static int bq27x00_battery_status (struct bq27x00_device_info *di,union power_supply_propval *val) {@@ -209,7 +310,9 @@ static int bq27x00_battery_status(structelse status =POWER_SUPPLY_STATUS_CHARGING ; }else { -if (flags &BQ27000_FLAG_CHGS ) +if (flags &BQ27000_FLAG_FC ) + status =POWER_SUPPLY_STATUS_FULL ; +else if (flags &BQ27000_FLAG_CHGS ) status =POWER_SUPPLY_STATUS_CHARGING ;else status =POWER_SUPPLY_STATUS_DISCHARGING ;@@ -256,6 +359,9 @@ static int bq27x00_battery_get_property(case POWER_SUPPLY_PROP_STATUS : ret =bq27x00_battery_status (di, val);break ; +case POWER_SUPPLY_PROP_ONLINE : + val->intval =bq27x00_battery_gpio (di); +break ;case POWER_SUPPLY_PROP_VOLTAGE_NOW :case POWER_SUPPLY_PROP_PRESENT : val->intval =bq27x00_battery_voltage (di);@@ -268,6 +374,15 @@ static int bq27x00_battery_get_property(case POWER_SUPPLY_PROP_CAPACITY : val->intval =bq27x00_battery_rsoc (di);break ; +case POWER_SUPPLY_PROP_CHARGE_NOW : + val->intval =bq27x00_battery_nac (di); +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL : + val->intval =bq27x00_battery_lmd (di); +break ; +case POWER_SUPPLY_PROP_ENERGY_NOW : + val->intval =bq27x00_battery_energy (di); +break ;case POWER_SUPPLY_PROP_TEMP : val->intval =bq27x00_battery_temperature (di);break ;@@ -472,4 +587,7 @@ module_exit(bq27x00_battery_exit);MODULE_AUTHOR ("Rodolfo Giometti <[email protected]>" );MODULE_DESCRIPTION ("BQ27x00 battery monitor driver" ); +MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );MODULE_LICENSE ("GPL" ); ----- End forwarded message -----
Signature · 5 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti Freelance ICT Italia - Consulente ICT Italia - www.consulenti-ict.it
Quoted 1 line · Rodolfo Giometti
On Mon, Jan 31, 2011 at 04:51:47PM +0300, Anton Vorontsov wrote:
[...]
Quoted 6 lines
Why not using:
!!(gpio & 0x40)or
Quoted 7 lines
(gpio & 0x40) ? 1 : 0? I think it could be more readable... :)
However, I don't understand why you fix gpio=0... it's your machine depending settings? In these case you should use the
platform_datamechanism to properly setup the GPIO.
I agree. It looks like a machine-specific configuration, and exporting this GPIO as 'ONLINE' property may break other users.
Instead, I would suggest adding gpiolib support into this driver, and passing 'int online_gpio' via platform data. That way you can pass any GPIOs to this driver, not only bq's.
Pali, you can just split GPIO and 'ONLINE' property additions into a separate patch for now, so we can apply the rest of the changes, and hold on the GPIO stuff.
[...]
Quoted 3 lines
Quoted 1 line
+static int
bq27x00_battery_nac(struct bq27x00_device_info *di)Let me suggest using
bq27x00_battery_nac_uAhas function name...
Regarding these suffixes. I'm not sure. This seems a bit too verbose. So I'd prefer to not introduce these.
Though, whatever you guys like... I'm fine either way.
[...]
Quoted 5 lines
drivers/power/bq27x00_battery.c module_exit(bq27x00_battery_exit); · line 592
Quoted 5 lines
MODULE_AUTHOR("Rodolfo Giometti <[email protected]>");MODULE_DESCRIPTION("BQ27x00 battery monitor driver");drivers/power/bq27x00_battery.c +3
-0+MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );
Btw, this is actually another bugfix. Pali, you might want to separate it into yet another patch.
Thanks!
Signature · 2 lines
Anton Vorontsov Email: [email protected]
2011/1/31 Anton Vorontsov <[email protected]>:
Quoted 20 lines · Rodolfo Giometti
Quoted 1 line · Anton Vorontsov
[...]
Quoted 6 lines
Why not using:
!!(gpio &
0x40)or
Quoted 7 lines
(gpio &
0x40) ? 1 : 0? I think it could be more readable... :)
However, I don't understand why you fix gpio=0... it's your machine depending settings? In these case you should use the
platform_datamechanism to properly setup the GPIO.I agree. It looks like a machine-specific configuration, and exporting this GPIO as 'ONLINE' property may break other users.
Quoted 7 lines
Instead, I would suggest adding gpiolib support into this driver, and passing 'int
online_gpio' via platform data. That way you can pass any GPIOs to this driver, not only bq's.Pali, you can just split GPIO and 'ONLINE' property additions into a separate patch for now, so we can apply the rest of the changes, and hold on the GPIO stuff.
Ok, I delete GPIO and ONLINE additions from this patch.
Quoted 10 lines
[...]
Quoted 3 lines
Quoted 1 line
+static int
bq27x00_battery_nac(struct bq27x00_device_info *di)Let me suggest using
bq27x00_battery_nac_uAhas function name...Regarding these suffixes. I'm not sure. This seems a bit too verbose. So I'd prefer to not introduce these.
Though, whatever you guys like... I'm fine either way.
It think it is not needed to rename functions. In Documentation/power/power_supply_class.txt is written that default units are µA, µV, µAh, ... and functions in my patch return values in these correct units.
Quoted 10 lines
[...]
Quoted 5 lines
drivers/power/bq27x00_battery.c module_exit(bq27x00_battery_exit); · line 592
Quoted 5 lines
MODULE_AUTHOR("Rodolfo Giometti <[email protected]>");
MODULE_DESCRIPTION("BQ27x00 battery monitor driver");drivers/power/bq27x00_battery.c +3
-0+MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );Btw, this is actually another bugfix. Pali, you might want to separate it into yet another patch.
Ok, I separate aliases to new patch.
Quoted 7 lines
Thanks!
--
Anton Vorontsov
Email: [email protected]
Signature · 2 lines
Pali Rohár [email protected]
Quoted 58 lines · Pali Rohár
2011/1/31 Anton Vorontsov <[email protected]>:
Quoted 20 lines · Rodolfo Giometti
Quoted 1 line · Anton Vorontsov
[...]
Quoted 6 lines
Why not using:
!!(gpio & 0x40)or
Quoted 7 lines
(gpio & 0x40) ? 1 : 0? I think it could be more readable... :)
However, I don't understand why you fix gpio=0... it's your machine depending settings? In these case you should use the
platform_datamechanism to properly setup the GPIO.I agree. It looks like a machine-specific configuration, and exporting this GPIO as 'ONLINE' property may break other users.
Quoted 7 lines
Instead, I would suggest adding gpiolib support into this driver, and passing 'int
online_gpio' via platform data. That way you can pass any GPIOs to this driver, not only bq's.Pali, you can just split GPIO and 'ONLINE' property additions into a separate patch for now, so we can apply the rest of the changes, and hold on the GPIO stuff.
Ok, I delete GPIO and ONLINE additions from this patch.
Quoted 10 lines
[...]
Quoted 3 lines
Quoted 1 line
+static int
bq27x00_battery_nac(struct bq27x00_device_info *di)Let me suggest using
bq27x00_battery_nac_uAhas function name...Regarding these suffixes. I'm not sure. This seems a bit too verbose. So I'd prefer to not introduce these.
Though, whatever you guys like... I'm fine either way.
It think it is not needed to rename functions. In
Documentation/power/power_supply_class.txtis written that default units are µA, µV, µAh, ... and functions in my patch return values in these correct units.Quoted 10 lines
[...]
Quoted 5 lines
drivers/power/bq27x00_battery.c module_exit(bq27x00_battery_exit); · line 592
Quoted 5 lines
MODULE_AUTHOR("Rodolfo Giometti <[email protected]>");MODULE_DESCRIPTION("BQ27x00 battery monitor driver");drivers/power/bq27x00_battery.c +3
-0+MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );Btw, this is actually another bugfix. Pali, you might want to separate it into yet another patch.
Quoted 2 lines
Ok, I separate aliases to new patch.
The bq27000 is not an I2C device.
- Lars
Quoted 10 lines
Quoted 7 lines
Thanks!
--
Anton Vorontsov
Email: [email protected]
Quoted 11 lines · Lars-Peter Clausen
Quoted 9 lines · Pali Roh??r
2011/1/31 Anton Vorontsov <[email protected]>:
Quoted 8 lines · Rodolfo Giometti
Quoted 4 lines
drivers/power/bq27x00_battery.c module_exit(bq27x00_battery_exit); · line 592
Quoted 4 lines
drivers/power/bq27x00_battery.c +3
-0+MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );Btw, this is actually another bugfix. Pali, you might want to separate it into yet another patch.
Quoted 3 lines
Quoted 1 line
Ok, I separate aliases to new patch.
The bq27000 is not an I2C device.
Also, even if it were an I2C device this isn't how I2C devices get their module loading information set up - they use MODULE_DEVICE_TABLE().
2011/1/31 Mark Brown <[email protected]>:
Quoted 12 lines · Lars-Peter Clausen
Quoted 10 lines · Pali Roh??r
Quoted 9 lines
2011/1/31 Anton Vorontsov <[email protected]>:
Quoted 8 lines · Rodolfo Giometti
Quoted 4 lines
drivers/power/bq27x00_battery.c module_exit(bq27x00_battery_exit); · line 592
Quoted 4 lines
drivers/power/bq27x00_battery.c +3
-0+MODULE_ALIAS ("i2c:bq27000" ); +MODULE_ALIAS ("i2c:bq27200" ); +MODULE_ALIAS ("i2c:bq27500" );Btw, this is actually another bugfix. Pali, you might want to separate it into yet another patch.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Ok, I separate aliases to new patch.
The bq27000 is not an I2C device.
Also, even if it were an I2C device this isn't how I2C devices get their module loading information set up - they use
MODULE_DEVICE_TABLE().
If bq27000 is not I2C device it will remove line. My patch was primary for Nokia N900 - RX51 board and it has battery bq27200 which is i2c device. For autoloading this module I used MODULE_ALIAS("i2c:bq27200") which works fine. Aliases was used in other i2c modules for Nokia N900 too.
Can you give me example how to use MODULE_DEVICE_TABLE (if alias is not good solution)?
Signature · 2 lines
Pali Rohár [email protected]
Quoted 2 lines · Pali Rohár
Can you give me example how to use
MODULE_DEVICE_TABLE(if alias is not good solution)?
git grep MODULE_DEVICE_TABLE\(i2c
provides quite a few examples.
2011/1/31 Mark Brown <[email protected]>:
Quoted 9 lines · Pali Rohár
Quoted 3 lines
Can you give me example how to use
MODULE_DEVICE_TABLE(if alias is not good solution)?git grep MODULE_DEVICE_TABLE\(i2c
provides quite a few examples.
Thanks. I removed MODULE_ALIAS and added MODULE_DEVICE_TABLE. modinfo tell me that module has alias too (same as my defined).
Signature · 2 lines
Pali Rohár [email protected]
Pali Rohár
Tested-byThis patch adds MODULE_DEVICE_TABLE for module bq27x00_battery.
drivers/power/bq27x00_battery.c 2011-01-31 20:57:05.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 20:58:11.000000000 +0100 +1 -0
@@ -596,6 +596,7 @@ static const struct i2c_device_id bq27x0 { "bq27500", BQ27500 }, {}, }; +MODULE_DEVICE_TABLE(i2c, bq27x00_id); static struct i2c_driver bq27x00_battery_driver = { .driver = {
Quoted 4 lines · Pali Rohár
This patch adds
MODULE_DEVICE_TABLEfor modulebq27x00_battery.Signed-off-by Pali Rohár <[email protected]>Tested-by Pali Rohár <[email protected]>
Lars, if that's OK for you, please take Pali's patches via your tree. I can merge it into battery-2.6.git on request (and after review, of course).
Thanks!
Quoted 11 lines
drivers/power/bq27x00_battery.c 2011-01-31 20:57:05.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 20:58:11.000000000 +0100 +1
-0@@ -596,6 +596,7 @@ static const struct i2c_device_id bq27x0 { "bq27500", BQ27500 }, {}, }; +MODULE_DEVICE_TABLE(i2c, bq27x00_id); static struct i2c_driver bq27x00_battery_driver = { .driver = {
Signature · 2 lines
Anton Vorontsov Email: [email protected]
Quoted 12 lines · Anton Vorontsov
Quoted 4 lines · Pali Rohár
This patch adds
MODULE_DEVICE_TABLEfor modulebq27x00_battery.Signed-off-by Pali Rohár <[email protected]>Tested-by Pali Rohár <[email protected]>Lars, if that's OK for you, please take Pali's patches via your tree. I can merge it into battery-2.6.git on request (and after review, of course).
Thanks!
I'll do. Thanks
- Lars
Quoted 12 lines
Quoted 11 lines
drivers/power/bq27x00_battery.c 2011-01-31 20:57:05.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 20:58:11.000000000 +0100 +1
-0@@ -596,6 +596,7 @@ static const struct i2c_device_id bq27x0 { "bq27500", BQ27500 }, {}, }; +MODULE_DEVICE_TABLE(i2c, bq27x00_id); static struct i2c_driver bq27x00_battery_driver = { .driver = {
Pali Rohár
Tested-byHere is new patch. It is possible to merge it then with changes on git?
===
This patch add support for reporting properties POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_ENERGY_NOW in module bq27x00_battery.
drivers/power/bq27x00_battery.c 2011-01-31 18:43:16.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 17:45:01.000000000 +0100 +14 -1
@@ -4,6 +4,11 @@ * Copyright (C) 2008 Rodolfo Giometti <[email protected]> * Copyright (C) 2008 Eurotech S.p.A. <[email protected]> * + * Support for reporting properties: POWER_SUPPLY_PROP_CHARGE_NOW, + * POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + * POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_ENERGY_NOW + * Copyright (C) 2011 Pali Rohár <[email protected]> + * * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. * * This package is free software; you can redistribute it and/or modify
@@ -15,6 +20,13 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * */ + +/* + * Datasheets: + * http://focus.ti.com/docs/prod/folders/print/bq27000.html + * http://focus.ti.com/docs/prod/folders/print/bq27500.html + */ + #include <linux/module.h> #include <linux/param.h> #include <linux/jiffies.h>
@@ -27,7 +39,7 @@ #include <linux/slab.h> #include <asm/unaligned.h> -#define DRIVER_VERSION "1.1.0" +#define DRIVER_VERSION "1.2.0" #define BQ27x00_REG_TEMP 0x06 #define BQ27x00_REG_VOLT 0x08
@@ -36,12 +48,19 @@ #define BQ27x00_REG_TTE 0x16 #define BQ27x00_REG_TTF 0x18 #define BQ27x00_REG_TTECP 0x26 +#define BQ27x00_REG_NAC 0x0C /* Nominal
available capaciy */
+#define BQ27x00_REG_LMD 0x12 /* Last measured
discharge */
+#define BQ27x00_REG_CYCT 0x2A /* Cycle count total */
+#define BQ27x00_REG_AE 0x22 /* Available enery */
#define BQ27000_RS 20 /* Resistor sense */ #define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ +#define BQ27000_REG_ILMD 0x76 /* Initial last measured
discharge */
#define BQ27000_FLAG_CHGS BIT(7)
+#define BQ27000_FLAG_FC BIT(5)
#define BQ27500_REG_SOC 0x2C
+#define BQ27500_REG_DCAP 0x3C /* Design capacity */
#define BQ27500_FLAG_DSC BIT(0)
#define BQ27500_FLAG_FC BIT(9)
@@ -75,6 +94,11 @@ static enum power_supply_property bq27x0
POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_COUNTER, + POWER_SUPPLY_PROP_ENERGY_NOW,
POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
@@ -188,6 +212,119 @@ static int bq27x00_battery_rsoc(struct b
return rsoc;
}
+/*
+ * Return the battery Nominal available capaciy in µAh
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_nac(struct bq27x00_device_info *di) +{
+ int ret;
+ int nac = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_NAC, &nac, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading nominal available capacity\n");
+ return ret;
+ }
+
+ if (di->chip == BQ27500)
+ nac *= 1000;
+ else
+ nac = nac * 3570 / BQ27000_RS;
+
+ return nac;
+}
+
+/*
+ * Return the battery Last measured discharge in µAh
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_lmd(struct bq27x00_device_info *di) +{
+ int ret;
+ int lmd = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_LMD, &lmd, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading last measured discharge\n");
+ return ret;
+ }
+
+ if (di->chip == BQ27500)
+ lmd *= 1000;
+ else
+ lmd = lmd * 3570 / BQ27000_RS;
+
+ return lmd;
+}
+
+/*
+ * Return the battery Initial last measured discharge in µAh
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_ilmd(struct bq27x00_device_info *di) +{
+ int ret;
+ int ilmd = 0;
+
+ if (di->chip == BQ27500)
+ ret = bq27x00_read(BQ27500_REG_DCAP, &ilmd, 0, di);
+ else
+ ret = bq27x00_read(BQ27000_REG_ILMD, &ilmd, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading initial last measured
discharge\n");
+ return ret;
+ }
+
+ if (di->chip == BQ27500)
+ ilmd *= 1000;
+ else
+ ilmd = ilmd * 256 * 3570 / BQ27000_RS;
+
+ return ilmd;
+}
+
+/*
+ * Return the battery Cycle count total
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_cyct(struct bq27x00_device_info *di) +{
+ int ret;
+ int cyct = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_CYCT, &cyct, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading cycle count total\n");
+ return ret;
+ }
+
+ return cyct;
+}
+
+/*
+ * Return the battery Available energy in µWh
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_energy(struct bq27x00_device_info *di) +{
+ int ret;
+ int ae = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_LMD, &ae, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading available energy\n");
+ return ret;
+ }
+
+ if (di->chip == BQ27500)
+ ae *= 1000;
+ else
+ ae = ae * 29200 / BQ27000_RS;
+
+ return ae;
+}
+
static int bq27x00_battery_status(struct bq27x00_device_info *di,
union power_supply_propval *val)
{
@@ -209,7 +346,9 @@ static int bq27x00_battery_status(struct
else
status = POWER_SUPPLY_STATUS_CHARGING;
} else {- if (flags & BQ27000_FLAG_CHGS)
+ if (flags & BQ27000_FLAG_FC)
+ status = POWER_SUPPLY_STATUS_FULL;
+ else if (flags & BQ27000_FLAG_CHGS)
status = POWER_SUPPLY_STATUS_CHARGING;
else
status = POWER_SUPPLY_STATUS_DISCHARGING;
@@ -268,6 +407,21 @@ static int bq27x00_battery_get_property(
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = bq27x00_battery_rsoc(di);
break;+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ val->intval = bq27x00_battery_nac(di);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ val->intval = bq27x00_battery_lmd(di);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ val->intval = bq27x00_battery_ilmd(di);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_COUNTER:
+ val->intval = bq27x00_battery_cyct(di);
+ break;
+ case POWER_SUPPLY_PROP_ENERGY_NOW:
+ val->intval = bq27x00_battery_energy(di);
+ break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = bq27x00_battery_temperature(di);
break;Hi Pali
Your mail-client seems to mess up the patches whitespace(tabs converted to spaces, trailing whitespace truncated, etc). Could you resend the patches properly formated? I guess there is an option in your mail-client somewhere to disable it from chaning the messages whitespace. Otherwise you could try to use the git send-email tool.
- Lars
Quoted 239 lines · Pali Rohár
Here is new patch. It is possible to merge it then with changes on git?
===
This patch add support for reporting properties
POWER_SUPPLY_PROP_CHARGE_NOW,POWER_SUPPLY_PROP_CHARGE_FULL,POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,POWER_SUPPLY_PROP_CHARGE_COUNTER,POWER_SUPPLY_PROP_ENERGY_NOWin modulebq27x00_battery.Signed-off-by Pali Rohár <[email protected]>Tested-by Pali Rohár <[email protected]>drivers/power/bq27x00_battery.c 2011-01-31 18:43:16.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 17:45:01.000000000 +0100 +14
-1@@ -4,6 +4,11 @@ * Copyright (C) 2008 Rodolfo Giometti <[email protected]> * Copyright (C) 2008 Eurotech S.p.A. <[email protected]> * + * Support for reporting properties: POWER_SUPPLY_PROP_CHARGE_NOW, + * POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + * POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_ENERGY_NOW + * Copyright (C) 2011 Pali Rohár <[email protected]> + * * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. * * This package is free software; you can redistribute it and/or modify@@ -15,6 +20,13 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * */ + +/* + * Datasheets: + * http://focus.ti.com/docs/prod/folders/print/bq27000.html + * http://focus.ti.com/docs/prod/folders/print/bq27500.html + */ + #include <linux/module.h> #include <linux/param.h> #include <linux/jiffies.h>@@ -27,7 +39,7 @@ #include <linux/slab.h> #include <asm/unaligned.h> -#define DRIVER_VERSION "1.1.0" +#define DRIVER_VERSION "1.2.0" #define BQ27x00_REG_TEMP 0x06 #define BQ27x00_REG_VOLT 0x08@@ -36,12 +48,19 @@ #define BQ27x00_REG_TTE 0x16 #define BQ27x00_REG_TTF 0x18 #define BQ27x00_REG_TTECP 0x26 +#define BQ27x00_REG_NAC 0x0C /* Nominalavailable capaciy */
+#defineBQ27x00_REG_LMD0x12/* Last measured
discharge */drivers/power/bq27x00_battery.c 2011-01-31 18:43:16.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 17:45:01.000000000 +0100 +3
-0+#define BQ27x00_REG_CYCT 0x2A /* Cycle count total */ +#define BQ27x00_REG_AE 0x22 /* Available enery */ #define BQ27000_RS 20 /* Resistor sense */ #define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ +#define BQ27000_REG_ILMD 0x76 /* Initial last measureddischarge */
#defineBQ27000_FLAG_CHGSBIT(7)drivers/power/bq27x00_battery.c 2011-01-31 18:43:16.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 17:45:01.000000000 +0100 +120
-0+#define BQ27000_FLAG_FC BIT(5) #define BQ27500_REG_SOC 0x2C +#define BQ27500_REG_DCAP 0x3C /* Design capacity */ #define BQ27500_FLAG_DSC BIT(0) #define BQ27500_FLAG_FC BIT(9)@@ -75,6 +94,11 @@ static enum power_supply_property bq27x0 POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_COUNTER, + POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,@@ -188,6 +212,119 @@ static int bq27x00_battery_rsoc(struct b return rsoc; } +/* + * Return the battery Nominal available capaciy in µAh + * Or < 0 if something fails. + */ +static int bq27x00_battery_nac(struct bq27x00_device_info *di) +{ + int ret; + int nac = 0; + + ret = bq27x00_read(BQ27x00_REG_NAC, &nac, 0, di); + if (ret) { + dev_err(di->dev, "error reading nominal available capacity\n"); + return ret; + } + + if (di->chip == BQ27500) + nac *= 1000; + else + nac = nac * 3570 / BQ27000_RS; + + return nac; +} + +/* + * Return the battery Last measured discharge in µAh + * Or < 0 if something fails. + */ +static int bq27x00_battery_lmd(struct bq27x00_device_info *di) +{ + int ret; + int lmd = 0; + + ret = bq27x00_read(BQ27x00_REG_LMD, &lmd, 0, di); + if (ret) { + dev_err(di->dev, "error reading last measured discharge\n"); + return ret; + } + + if (di->chip == BQ27500) + lmd *= 1000; + else + lmd = lmd * 3570 / BQ27000_RS; + + return lmd; +} + +/* + * Return the battery Initial last measured discharge in µAh + * Or < 0 if something fails. + */ +static int bq27x00_battery_ilmd(struct bq27x00_device_info *di) +{ + int ret; + int ilmd = 0; + + if (di->chip == BQ27500) + ret = bq27x00_read(BQ27500_REG_DCAP, &ilmd, 0, di); + else + ret = bq27x00_read(BQ27000_REG_ILMD, &ilmd, 0, di); + if (ret) { + dev_err(di->dev, "error reading initial last measured discharge\n"); + return ret; + } + + if (di->chip == BQ27500) + ilmd *= 1000; + else + ilmd = ilmd * 256 * 3570 / BQ27000_RS; + + return ilmd; +} + +/* + * Return the battery Cycle count total + * Or < 0 if something fails. + */ +static int bq27x00_battery_cyct(struct bq27x00_device_info *di) +{ + int ret; + int cyct = 0; + + ret = bq27x00_read(BQ27x00_REG_CYCT, &cyct, 0, di); + if (ret) { + dev_err(di->dev, "error reading cycle count total\n"); + return ret; + } + + return cyct; +} + +/* + * Return the battery Available energy in µWh + * Or < 0 if something fails. + */ +static int bq27x00_battery_energy(struct bq27x00_device_info *di) +{ + int ret; + int ae = 0; + + ret = bq27x00_read(BQ27x00_REG_LMD, &ae, 0, di); + if (ret) { + dev_err(di->dev, "error reading available energy\n"); + return ret; + } + + if (di->chip == BQ27500) + ae *= 1000; + else + ae = ae * 29200 / BQ27000_RS; + + return ae; +} + static int bq27x00_battery_status(struct bq27x00_device_info *di, union power_supply_propval *val){
drivers/power/bq27x00_battery.c 2011-01-31 18:43:16.000000000 +0100 renamed from drivers/power/bq27x00_battery.c 2011-01-31 17:45:01.000000000 +0100 +18
-1@@ -209,7 +346,9 @@ static int bq27x00_battery_status(struct else status = POWER_SUPPLY_STATUS_CHARGING; } else { - if (flags & BQ27000_FLAG_CHGS) + if (flags & BQ27000_FLAG_FC) + status = POWER_SUPPLY_STATUS_FULL; + else if (flags & BQ27000_FLAG_CHGS) status = POWER_SUPPLY_STATUS_CHARGING; else status = POWER_SUPPLY_STATUS_DISCHARGING;@@ -268,6 +407,21 @@ static int bq27x00_battery_get_property( case POWER_SUPPLY_PROP_CAPACITY: val->intval = bq27x00_battery_rsoc(di); break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + val->intval = bq27x00_battery_nac(di); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + val->intval = bq27x00_battery_lmd(di); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = bq27x00_battery_ilmd(di); + break; + case POWER_SUPPLY_PROP_CHARGE_COUNTER: + val->intval = bq27x00_battery_cyct(di); + break; + case POWER_SUPPLY_PROP_ENERGY_NOW: + val->intval = bq27x00_battery_energy(di); + break; case POWER_SUPPLY_PROP_TEMP: val->intval = bq27x00_battery_temperature(di); break;
Pali Rohár
Tested-byThis patch add support for reporting properties POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_ENERGY_NOW in module bq27x00_battery.
drivers/power/bq27x00_battery.c +156 -2
@@ -4,6 +4,11 @@* Copyright (C) 2008 Rodolfo Giometti <[email protected]> * Copyright (C) 2008 Eurotech S.p.A. <[email protected]> * +* Support for reporting properties: POWER_SUPPLY_PROP_CHARGE_NOW, +* POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, +* POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_ENERGY_NOW +* Copyright (C) 2011 Pali Rohár <[email protected]> +* * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. * * This package is free software; you can redistribute it and/or modify
@@ -15,6 +20,13 @@* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * */ + +/* +* Datasheets: +* http://focus.ti.com/docs/prod/folders/print/bq27000.html +* http://focus.ti.com/docs/prod/folders/print/bq27500.html +*/ +#include <linux/module.h> #include <linux/param.h> #include <linux/jiffies.h>
@@ -27,7 +39,7 @@#include <linux/slab.h> #include <asm/unaligned.h> -#define DRIVER_VERSION "1.1.0" +#define DRIVER_VERSION "1.2.0"#define BQ27x00_REG_TEMP 0x06#define BQ27x00_REG_VOLT 0x08
@@ -36,12 +48,19 @@#define BQ27x00_REG_TTE 0x16#define BQ27x00_REG_TTF 0x18#define BQ27x00_REG_TTECP 0x26 +#define BQ27x00_REG_NAC 0x0C/* Nominal available capaciy */ +#define BQ27x00_REG_LMD 0x12/* Last measured discharge */ +#define BQ27x00_REG_CYCT 0x2A/* Cycle count total */ +#define BQ27x00_REG_AE 0x22/* Available enery */ #define BQ27000_RS 20/* Resistor sense */ #define BQ27000_REG_RSOC 0x0B/* Relative State-of-Charge */ +#define BQ27000_REG_ILMD 0x76/* Initial last measured discharge */ #define BQ27000_FLAG_CHGS BIT(7) +#define BQ27000_FLAG_FC BIT(5)#define BQ27500_REG_SOC 0x2C +#define BQ27500_REG_DCAP 0x3C/* Design capacity */ #define BQ27500_FLAG_DSC BIT(0)#define BQ27500_FLAG_FC BIT(9)
@@ -75,6 +94,11 @@ static enum power_supply_property bq27x0POWER_SUPPLY_PROP_VOLTAGE_NOW ,POWER_SUPPLY_PROP_CURRENT_NOW ,POWER_SUPPLY_PROP_CAPACITY , +POWER_SUPPLY_PROP_CHARGE_NOW , +POWER_SUPPLY_PROP_CHARGE_FULL , +POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN , +POWER_SUPPLY_PROP_CHARGE_COUNTER , +POWER_SUPPLY_PROP_ENERGY_NOW ,POWER_SUPPLY_PROP_TEMP ,POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW , POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
@@ -188,6 +212,119 @@ static int bq27x00_battery_rsoc(struct breturn rsoc; } +/* +* Return the battery Nominal available capaciy in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_nac (struct bq27x00_device_info *di) +{ +int ret; +int nac =0 ; + + ret =bq27x00_read (BQ27x00_REG_NAC, &nac,0 , di); +if (ret) { +dev_err (di->dev,"error reading nominal available capacity\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + nac *=1000 ; +else + nac = nac *3570 /BQ27000_RS ; + +return nac; +} + +/* +* Return the battery Last measured discharge in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_lmd (struct bq27x00_device_info *di) +{ +int ret; +int lmd =0 ; + + ret =bq27x00_read (BQ27x00_REG_LMD, &lmd,0 , di); +if (ret) { +dev_err (di->dev,"error reading last measured discharge\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + lmd *=1000 ; +else + lmd = lmd *3570 /BQ27000_RS ; + +return lmd; +} + +/* +* Return the battery Initial last measured discharge in µAh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_ilmd (struct bq27x00_device_info *di) +{ +int ret; +int ilmd =0 ; + +if (di->chip ==BQ27500 ) + ret =bq27x00_read (BQ27500_REG_DCAP , &ilmd,0 , di); +else + ret =bq27x00_read (BQ27000_REG_ILMD , &ilmd,0 , di); +if (ret) { +dev_err (di->dev,"error reading initial last measured discharge\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + ilmd *=1000 ; +else + ilmd = ilmd *256 *3570 /BQ27000_RS ; + +return ilmd; +} + +/* +* Return the battery Cycle count total +* Or < 0 if something fails. +*/ +static int bq27x00_battery_cyct (struct bq27x00_device_info *di) +{ +int ret; +int cyct =0 ; + + ret =bq27x00_read (BQ27x00_REG_CYCT, &cyct,0 , di); +if (ret) { +dev_err (di->dev,"error reading cycle count total\n" ); +return ret; + } + +return cyct; +} + +/* +* Return the battery Available energy in µWh +* Or < 0 if something fails. +*/ +static int bq27x00_battery_energy (struct bq27x00_device_info *di) +{ +int ret; +int ae =0 ; + + ret =bq27x00_read (BQ27x00_REG_LMD, &ae,0 , di); +if (ret) { +dev_err (di->dev,"error reading available energy\n" ); +return ret; + } + +if (di->chip ==BQ27500 ) + ae *=1000 ; +else + ae = ae *29200 /BQ27000_RS ; + +return ae; +} +static int bq27x00_battery_status (struct bq27x00_device_info *di,union power_supply_propval *val) {
@@ -209,7 +346,9 @@ static int bq27x00_battery_status(structelse status =POWER_SUPPLY_STATUS_CHARGING ; }else { -if (flags &BQ27000_FLAG_CHGS ) +if (flags &BQ27000_FLAG_FC ) + status =POWER_SUPPLY_STATUS_FULL ; +else if (flags &BQ27000_FLAG_CHGS ) status =POWER_SUPPLY_STATUS_CHARGING ;else status =POWER_SUPPLY_STATUS_DISCHARGING ;
@@ -268,6 +407,21 @@ static int bq27x00_battery_get_property(case POWER_SUPPLY_PROP_CAPACITY : val->intval =bq27x00_battery_rsoc (di);break ; +case POWER_SUPPLY_PROP_CHARGE_NOW : + val->intval =bq27x00_battery_nac (di); +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL : + val->intval =bq27x00_battery_lmd (di); +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN : + val->intval =bq27x00_battery_ilmd (di); +break ; +case POWER_SUPPLY_PROP_CHARGE_COUNTER : + val->intval =bq27x00_battery_cyct (di); +break ; +case POWER_SUPPLY_PROP_ENERGY_NOW : + val->intval =bq27x00_battery_energy (di); +break ;case POWER_SUPPLY_PROP_TEMP : val->intval =bq27x00_battery_temperature (di);break ;