1/* 2 * BQ27x00 battery driver 3 * 4 * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it> 5 * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it> 6 * 7 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. 8 * 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. 12 * 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. 16 * 17 */ 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 <linux/slab.h> 28#include <asm/unaligned.h> 29 30#define DRIVER_VERSION "1.1.0" 31 32#define BQ27x00_REG_TEMP 0x06 33#define BQ27x00_REG_VOLT 0x08 34#define BQ27x00_REG_AI 0x14 35#define BQ27x00_REG_FLAGS 0x0A 36#define BQ27x00_REG_TTE 0x16 37#define BQ27x00_REG_TTF 0x18 38#define BQ27x00_REG_TTECP 0x26 39 40#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ 41#define BQ27000_FLAG_CHGS BIT(7) 42 43#define BQ27500_REG_SOC 0x2c 44#define BQ27500_FLAG_DSC BIT(0) 45#define BQ27500_FLAG_FC BIT(9) 46 47/* If the system has several batteries we need a different name for each 48 * of them... 49 */ 50static DEFINE_IDR(battery_id); 51static DEFINE_MUTEX(battery_mutex); 52 53struct bq27x00_device_info; 54struct bq27x00_access_methods { 55 int (*read)(u8 reg, int *rt_value, int b_single, 56 struct bq27x00_device_info *di); 57}; 58 59enum bq27x00_chip { BQ27000, BQ27500 }; 60 61struct bq27x00_device_info { 62 struct device *dev; 63 int id; 64 struct bq27x00_access_methods *bus; 65 struct power_supply bat; 66 enum bq27x00_chip chip; 67 68 struct i2c_client *client; 69}; 70 71static enum power_supply_property bq27x00_battery_props[] = { 72 POWER_SUPPLY_PROP_STATUS, 73 POWER_SUPPLY_PROP_PRESENT, 74 POWER_SUPPLY_PROP_VOLTAGE_NOW, 75 POWER_SUPPLY_PROP_CURRENT_NOW, 76 POWER_SUPPLY_PROP_CAPACITY, 77 POWER_SUPPLY_PROP_TEMP, 78 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, 79 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 80 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 81}; 82 83/* 84 * Common code for BQ27x00 devices 85 */ 86 87static int bq27x00_read(u8 reg, int *rt_value, int b_single, 88 struct bq27x00_device_info *di) 89{ 90 return di->bus->read(reg, rt_value, b_single, di); 91} 92 93/* 94 * Return the battery temperature in tenths of degree Celsius 95 * Or < 0 if something fails. 96 */ 97static int bq27x00_battery_temperature(struct bq27x00_device_info *di) 98{ 99 int ret; 100 int temp = 0; 101 102 ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di); 103 if (ret) { 104 dev_err(di->dev, "error reading temperature\n"); 105 return ret; 106 } 107 108 if (di->chip == BQ27500) 109 return temp - 2731; 110 else 111 return ((temp >> 2) - 273) * 10; 112} 113 114/* 115 * Return the battery Voltage in milivolts 116 * Or < 0 if something fails. 117 */ 118static int bq27x00_battery_voltage(struct bq27x00_device_info *di) 119{ 120 int ret; 121 int volt = 0; 122 123 ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di); 124 if (ret) { 125 dev_err(di->dev, "error reading voltage\n"); 126 return ret; 127 } 128 129 return volt * 1000; 130} 131 132/* 133 * Return the battery average current 134 * Note that current can be negative signed as well 135 * Or 0 if something fails. 136 */ 137static int bq27x00_battery_current(struct bq27x00_device_info *di) 138{ 139 int ret; 140 int curr = 0; 141 int flags = 0; 142 143 ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di); 144 if (ret) { 145 dev_err(di->dev, "error reading current\n"); 146 return 0; 147 } 148 149 if (di->chip == BQ27500) { 150 /* bq27500 returns signed value */ 151 curr = (int)(s16)curr; 152 } else { 153 ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di); 154 if (ret < 0) { 155 dev_err(di->dev, "error reading flags\n"); 156 return 0; 157 } 158 if (flags & BQ27000_FLAG_CHGS) { 159 dev_dbg(di->dev, "negative current!\n"); 160 curr = -curr; 161 } 162 } 163 164 return curr * 1000; 165} 166 167/* 168 * Return the battery Relative State-of-Charge 169 * Or < 0 if something fails. 170 */ 171static int bq27x00_battery_rsoc(struct bq27x00_device_info *di) 172{ 173 int ret; 174 int rsoc = 0; 175 176 if (di->chip == BQ27500) 177 ret = bq27x00_read(BQ27500_REG_SOC, &rsoc, 0, di); 178 else 179 ret = bq27x00_read(BQ27000_REG_RSOC, &rsoc, 1, di); 180 if (ret) { 181 dev_err(di->dev, "error reading relative State-of-Charge\n"); 182 return ret; 183 } 184 185 return rsoc; 186} 187 188static int bq27x00_battery_status(struct bq27x00_device_info *di, 189 union power_supply_propval *val) 190{ 191 int flags = 0; 192 int status; 193 int ret; 194 195 ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di); 196 if (ret < 0) { 197 dev_err(di->dev, "error reading flags\n"); 198 return ret; 199 } 200 201 if (di->chip == BQ27500) { 202 if (flags & BQ27500_FLAG_FC) 203 status = POWER_SUPPLY_STATUS_FULL; 204 else if (flags & BQ27500_FLAG_DSC) 205 status = POWER_SUPPLY_STATUS_DISCHARGING; 206 else 207 status = POWER_SUPPLY_STATUS_CHARGING; 208 } else { 209 if (flags & BQ27000_FLAG_CHGS) 210 status = POWER_SUPPLY_STATUS_CHARGING; 211 else 212 status = POWER_SUPPLY_STATUS_DISCHARGING; 213 } 214 215 val->intval = status; 216 return 0; 217} 218 219/* 220 * Read a time register. 221 * Return < 0 if something fails. 222 */ 223static int bq27x00_battery_time(struct bq27x00_device_info *di, int reg, 224 union power_supply_propval *val) 225{ 226 int tval = 0; 227 int ret; 228 229 ret = bq27x00_read(reg, &tval, 0, di); 230 if (ret) { 231 dev_err(di->dev, "error reading register %02x\n", reg); 232 return ret; 233 } 234 235 if (tval == 65535) 236 return -ENODATA; 237 238 val->intval = tval * 60; 239 return 0; 240} 241 242#define to_bq27x00_device_info(x) container_of((x), \ 243 struct bq27x00_device_info, bat); 244 245static int bq27x00_battery_get_property(struct power_supply *psy, 246 enum power_supply_property psp, 247 union power_supply_propval *val) 248{ 249 int ret = 0; 250 struct bq27x00_device_info *di = to_bq27x00_device_info(psy); 251 252 switch (psp) { 253 case POWER_SUPPLY_PROP_STATUS: 254 ret = bq27x00_battery_status(di, val); 255 break; 256 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 257 case POWER_SUPPLY_PROP_PRESENT: 258 val->intval = bq27x00_battery_voltage(di); 259 if (psp == POWER_SUPPLY_PROP_PRESENT) 260 val->intval = val->intval <= 0 ? 0 : 1; 261 break; 262 case POWER_SUPPLY_PROP_CURRENT_NOW: 263 val->intval = bq27x00_battery_current(di); 264 break; 265 case POWER_SUPPLY_PROP_CAPACITY: 266 val->intval = bq27x00_battery_rsoc(di); 267 break; 268 case POWER_SUPPLY_PROP_TEMP: 269 val->intval = bq27x00_battery_temperature(di); 270 break; 271 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 272 ret = bq27x00_battery_time(di, BQ27x00_REG_TTE, val); 273 break; 274 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 275 ret = bq27x00_battery_time(di, BQ27x00_REG_TTECP, val); 276 break; 277 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 278 ret = bq27x00_battery_time(di, BQ27x00_REG_TTF, val); 279 break; 280 default: 281 return -EINVAL; 282 } 283 284 return ret; 285} 286 287static void bq27x00_powersupply_init(struct bq27x00_device_info *di) 288{ 289 di->bat.type = POWER_SUPPLY_TYPE_BATTERY; 290 di->bat.properties = bq27x00_battery_props; 291 di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props); 292 di->bat.get_property = bq27x00_battery_get_property; 293 di->bat.external_power_changed = NULL; 294} 295 296/* 297 * i2c specific code 298 */ 299 300static int bq27x00_read_i2c(u8 reg, int *rt_value, int b_single, 301 struct bq27x00_device_info *di) 302{ 303 struct i2c_client *client = di->client; 304 struct i2c_msg msg[1]; 305 unsigned char data[2]; 306 int err; 307 308 if (!client->adapter) 309 return -ENODEV; 310 311 msg->addr = client->addr; 312 msg->flags = 0; 313 msg->len = 1; 314 msg->buf = data; 315 316 data[0] = reg; 317 err = i2c_transfer(client->adapter, msg, 1); 318 319 if (err >= 0) { 320 if (!b_single) 321 msg->len = 2; 322 else 323 msg->len = 1; 324 325 msg->flags = I2C_M_RD; 326 err = i2c_transfer(client->adapter, msg, 1); 327 if (err >= 0) { 328 if (!b_single) 329 *rt_value = get_unaligned_le16(data); 330 else 331 *rt_value = data[0]; 332 333 return 0; 334 } 335 } 336 return err; 337} 338 339static int bq27x00_battery_probe(struct i2c_client *client, 340 const struct i2c_device_id *id) 341{ 342 char *name; 343 struct bq27x00_device_info *di; 344 struct bq27x00_access_methods *bus; 345 int num; 346 int retval = 0; 347 348 /* Get new ID for the new battery device */ 349 retval = idr_pre_get(&battery_id, GFP_KERNEL); 350 if (retval == 0) 351 return -ENOMEM; 352 mutex_lock(&battery_mutex); 353 retval = idr_get_new(&battery_id, client, &num); 354 mutex_unlock(&battery_mutex); 355 if (retval < 0) 356 return retval; 357 358 name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num); 359 if (!name) { 360 dev_err(&client->dev, "failed to allocate device name\n"); 361 retval = -ENOMEM; 362 goto batt_failed_1; 363 } 364 365 di = kzalloc(sizeof(*di), GFP_KERNEL); 366 if (!di) { 367 dev_err(&client->dev, "failed to allocate device info data\n"); 368 retval = -ENOMEM; 369 goto batt_failed_2; 370 } 371 di->id = num; 372 di->chip = id->driver_data; 373 374 bus = kzalloc(sizeof(*bus), GFP_KERNEL); 375 if (!bus) { 376 dev_err(&client->dev, "failed to allocate access method " 377 "data\n"); 378 retval = -ENOMEM; 379 goto batt_failed_3; 380 } 381 382 i2c_set_clientdata(client, di); 383 di->dev = &client->dev; 384 di->bat.name = name; 385 bus->read = &bq27x00_read_i2c; 386 di->bus = bus; 387 di->client = client; 388 389 bq27x00_powersupply_init(di); 390 391 retval = power_supply_register(&client->dev, &di->bat); 392 if (retval) { 393 dev_err(&client->dev, "failed to register battery\n"); 394 goto batt_failed_4; 395 } 396 397 dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION); 398 399 return 0; 400 401batt_failed_4: 402 kfree(bus); 403batt_failed_3: 404 kfree(di); 405batt_failed_2: 406 kfree(name); 407batt_failed_1: 408 mutex_lock(&battery_mutex); 409 idr_remove(&battery_id, num); 410 mutex_unlock(&battery_mutex); 411 412 return retval; 413} 414 415static int bq27x00_battery_remove(struct i2c_client *client) 416{ 417 struct bq27x00_device_info *di = i2c_get_clientdata(client); 418 419 power_supply_unregister(&di->bat); 420 421 kfree(di->bat.name); 422 423 mutex_lock(&battery_mutex); 424 idr_remove(&battery_id, di->id); 425 mutex_unlock(&battery_mutex); 426 427 kfree(di); 428 429 return 0; 430} 431 432/* 433 * Module stuff 434 */ 435 436static const struct i2c_device_id bq27x00_id[] = { 437 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */ 438 { "bq27500", BQ27500 }, 439 {}, 440}; 441 442static struct i2c_driver bq27x00_battery_driver = { 443 .driver = { 444 .name = "bq27x00-battery", 445 }, 446 .probe = bq27x00_battery_probe, 447 .remove = bq27x00_battery_remove, 448 .id_table = bq27x00_id, 449}; 450 451static int __init bq27x00_battery_init(void) 452{ 453 int ret; 454 455 ret = i2c_add_driver(&bq27x00_battery_driver); 456 if (ret) 457 printk(KERN_ERR "Unable to register BQ27x00 driver\n"); 458 459 return ret; 460} 461module_init(bq27x00_battery_init); 462 463static void __exit bq27x00_battery_exit(void) 464{ 465 i2c_del_driver(&bq27x00_battery_driver); 466} 467module_exit(bq27x00_battery_exit); 468 469MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); 470MODULE_DESCRIPTION("BQ27x00 battery monitor driver"); 471MODULE_LICENSE("GPL"); 472