2 * BQ27x00 battery driver
4 * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
5 * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
7 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
9 * This package is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 #include <linux/module.h>
19 #include <linux/param.h>
20 #include <linux/jiffies.h>
21 #include <linux/workqueue.h>
22 #include <linux/delay.h>
23 #include <linux/platform_device.h>
24 #include <linux/power_supply.h>
25 #include <linux/idr.h>
26 #include <linux/i2c.h>
27 #include <asm/unaligned.h>
29 #define DRIVER_VERSION "1.0.0"
31 #define BQ27x00_REG_TEMP 0x06
32 #define BQ27x00_REG_VOLT 0x08
33 #define BQ27x00_REG_RSOC 0x0B /* Relative State-of-Charge */
34 #define BQ27x00_REG_AI 0x14
35 #define BQ27x00_REG_FLAGS 0x0A
37 /* If the system has several batteries we need a different name for each
40 static DEFINE_IDR(battery_id
);
41 static DEFINE_MUTEX(battery_mutex
);
43 struct bq27x00_device_info
;
44 struct bq27x00_access_methods
{
45 int (*read
)(u8 reg
, int *rt_value
, int b_single
,
46 struct bq27x00_device_info
*di
);
49 struct bq27x00_device_info
{
56 struct bq27x00_access_methods
*bus
;
57 struct power_supply bat
;
59 struct i2c_client
*client
;
62 static enum power_supply_property bq27x00_battery_props
[] = {
63 POWER_SUPPLY_PROP_PRESENT
,
64 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
65 POWER_SUPPLY_PROP_CURRENT_NOW
,
66 POWER_SUPPLY_PROP_CAPACITY
,
67 POWER_SUPPLY_PROP_TEMP
,
71 * Common code for BQ27x00 devices
74 static int bq27x00_read(u8 reg
, int *rt_value
, int b_single
,
75 struct bq27x00_device_info
*di
)
79 ret
= di
->bus
->read(reg
, rt_value
, b_single
, di
);
80 *rt_value
= be16_to_cpu(*rt_value
);
86 * Return the battery temperature in Celsius degrees
87 * Or < 0 if something fails.
89 static int bq27x00_battery_temperature(struct bq27x00_device_info
*di
)
94 ret
= bq27x00_read(BQ27x00_REG_TEMP
, &temp
, 0, di
);
96 dev_err(di
->dev
, "error reading temperature\n");
100 return (temp
>> 2) - 273;
104 * Return the battery Voltage in milivolts
105 * Or < 0 if something fails.
107 static int bq27x00_battery_voltage(struct bq27x00_device_info
*di
)
112 ret
= bq27x00_read(BQ27x00_REG_VOLT
, &volt
, 0, di
);
114 dev_err(di
->dev
, "error reading voltage\n");
122 * Return the battery average current
123 * Note that current can be negative signed as well
124 * Or 0 if something fails.
126 static int bq27x00_battery_current(struct bq27x00_device_info
*di
)
132 ret
= bq27x00_read(BQ27x00_REG_AI
, &curr
, 0, di
);
134 dev_err(di
->dev
, "error reading current\n");
137 ret
= bq27x00_read(BQ27x00_REG_FLAGS
, &flags
, 0, di
);
139 dev_err(di
->dev
, "error reading flags\n");
142 if ((flags
& (1 << 7)) != 0) {
143 dev_dbg(di
->dev
, "negative current!\n");
150 * Return the battery Relative State-of-Charge
151 * Or < 0 if something fails.
153 static int bq27x00_battery_rsoc(struct bq27x00_device_info
*di
)
158 ret
= bq27x00_read(BQ27x00_REG_RSOC
, &rsoc
, 1, di
);
160 dev_err(di
->dev
, "error reading relative State-of-Charge\n");
167 #define to_bq27x00_device_info(x) container_of((x), \
168 struct bq27x00_device_info, bat);
170 static int bq27x00_battery_get_property(struct power_supply
*psy
,
171 enum power_supply_property psp
,
172 union power_supply_propval
*val
)
174 struct bq27x00_device_info
*di
= to_bq27x00_device_info(psy
);
177 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
178 case POWER_SUPPLY_PROP_PRESENT
:
179 val
->intval
= bq27x00_battery_voltage(di
);
180 if (psp
== POWER_SUPPLY_PROP_PRESENT
)
181 val
->intval
= val
->intval
<= 0 ? 0 : 1;
183 case POWER_SUPPLY_PROP_CURRENT_NOW
:
184 val
->intval
= bq27x00_battery_current(di
);
186 case POWER_SUPPLY_PROP_CAPACITY
:
187 val
->intval
= bq27x00_battery_rsoc(di
);
189 case POWER_SUPPLY_PROP_TEMP
:
190 val
->intval
= bq27x00_battery_temperature(di
);
199 static void bq27x00_powersupply_init(struct bq27x00_device_info
*di
)
201 di
->bat
.type
= POWER_SUPPLY_TYPE_BATTERY
;
202 di
->bat
.properties
= bq27x00_battery_props
;
203 di
->bat
.num_properties
= ARRAY_SIZE(bq27x00_battery_props
);
204 di
->bat
.get_property
= bq27x00_battery_get_property
;
205 di
->bat
.external_power_changed
= NULL
;
209 * BQ27200 specific code
212 static int bq27200_read(u8 reg
, int *rt_value
, int b_single
,
213 struct bq27x00_device_info
*di
)
215 struct i2c_client
*client
= di
->client
;
216 struct i2c_msg msg
[1];
217 unsigned char data
[2];
220 if (!client
->adapter
)
223 msg
->addr
= client
->addr
;
229 err
= i2c_transfer(client
->adapter
, msg
, 1);
237 msg
->flags
= I2C_M_RD
;
238 err
= i2c_transfer(client
->adapter
, msg
, 1);
241 *rt_value
= get_unaligned_be16(data
);
251 static int bq27200_battery_probe(struct i2c_client
*client
,
252 const struct i2c_device_id
*id
)
255 struct bq27x00_device_info
*di
;
256 struct bq27x00_access_methods
*bus
;
260 /* Get new ID for the new battery device */
261 retval
= idr_pre_get(&battery_id
, GFP_KERNEL
);
264 mutex_lock(&battery_mutex
);
265 retval
= idr_get_new(&battery_id
, client
, &num
);
266 mutex_unlock(&battery_mutex
);
270 name
= kasprintf(GFP_KERNEL
, "bq27200-%d", num
);
272 dev_err(&client
->dev
, "failed to allocate device name\n");
277 di
= kzalloc(sizeof(*di
), GFP_KERNEL
);
279 dev_err(&client
->dev
, "failed to allocate device info data\n");
285 bus
= kzalloc(sizeof(*bus
), GFP_KERNEL
);
287 dev_err(&client
->dev
, "failed to allocate access method "
293 i2c_set_clientdata(client
, di
);
294 di
->dev
= &client
->dev
;
296 bus
->read
= &bq27200_read
;
300 bq27x00_powersupply_init(di
);
302 retval
= power_supply_register(&client
->dev
, &di
->bat
);
304 dev_err(&client
->dev
, "failed to register battery\n");
308 dev_info(&client
->dev
, "support ver. %s enabled\n", DRIVER_VERSION
);
319 mutex_lock(&battery_mutex
);
320 idr_remove(&battery_id
, num
);
321 mutex_unlock(&battery_mutex
);
326 static int bq27200_battery_remove(struct i2c_client
*client
)
328 struct bq27x00_device_info
*di
= i2c_get_clientdata(client
);
330 power_supply_unregister(&di
->bat
);
334 mutex_lock(&battery_mutex
);
335 idr_remove(&battery_id
, di
->id
);
336 mutex_unlock(&battery_mutex
);
347 static const struct i2c_device_id bq27200_id
[] = {
352 static struct i2c_driver bq27200_battery_driver
= {
354 .name
= "bq27200-battery",
356 .probe
= bq27200_battery_probe
,
357 .remove
= bq27200_battery_remove
,
358 .id_table
= bq27200_id
,
361 static int __init
bq27x00_battery_init(void)
365 ret
= i2c_add_driver(&bq27200_battery_driver
);
367 printk(KERN_ERR
"Unable to register BQ27200 driver\n");
371 module_init(bq27x00_battery_init
);
373 static void __exit
bq27x00_battery_exit(void)
375 i2c_del_driver(&bq27200_battery_driver
);
377 module_exit(bq27x00_battery_exit
);
379 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
380 MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
381 MODULE_LICENSE("GPL");