Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.39-rc2 709 lines 18 kB view raw
1/* 2 * Gas Gauge driver for TI's BQ20Z75 3 * 4 * Copyright (c) 2010, NVIDIA Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21#include <linux/init.h> 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/err.h> 25#include <linux/power_supply.h> 26#include <linux/i2c.h> 27#include <linux/slab.h> 28#include <linux/interrupt.h> 29#include <linux/gpio.h> 30 31#include <linux/power/bq20z75.h> 32 33enum { 34 REG_MANUFACTURER_DATA, 35 REG_TEMPERATURE, 36 REG_VOLTAGE, 37 REG_CURRENT, 38 REG_CAPACITY, 39 REG_TIME_TO_EMPTY, 40 REG_TIME_TO_FULL, 41 REG_STATUS, 42 REG_CYCLE_COUNT, 43 REG_SERIAL_NUMBER, 44 REG_REMAINING_CAPACITY, 45 REG_REMAINING_CAPACITY_CHARGE, 46 REG_FULL_CHARGE_CAPACITY, 47 REG_FULL_CHARGE_CAPACITY_CHARGE, 48 REG_DESIGN_CAPACITY, 49 REG_DESIGN_CAPACITY_CHARGE, 50 REG_DESIGN_VOLTAGE, 51}; 52 53/* Battery Mode defines */ 54#define BATTERY_MODE_OFFSET 0x03 55#define BATTERY_MODE_MASK 0x8000 56enum bq20z75_battery_mode { 57 BATTERY_MODE_AMPS, 58 BATTERY_MODE_WATTS 59}; 60 61/* manufacturer access defines */ 62#define MANUFACTURER_ACCESS_STATUS 0x0006 63#define MANUFACTURER_ACCESS_SLEEP 0x0011 64 65/* battery status value bits */ 66#define BATTERY_DISCHARGING 0x40 67#define BATTERY_FULL_CHARGED 0x20 68#define BATTERY_FULL_DISCHARGED 0x10 69 70#define BQ20Z75_DATA(_psp, _addr, _min_value, _max_value) { \ 71 .psp = _psp, \ 72 .addr = _addr, \ 73 .min_value = _min_value, \ 74 .max_value = _max_value, \ 75} 76 77static const struct bq20z75_device_data { 78 enum power_supply_property psp; 79 u8 addr; 80 int min_value; 81 int max_value; 82} bq20z75_data[] = { 83 [REG_MANUFACTURER_DATA] = 84 BQ20Z75_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535), 85 [REG_TEMPERATURE] = 86 BQ20Z75_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535), 87 [REG_VOLTAGE] = 88 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000), 89 [REG_CURRENT] = 90 BQ20Z75_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 91 32767), 92 [REG_CAPACITY] = 93 BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100), 94 [REG_REMAINING_CAPACITY] = 95 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535), 96 [REG_REMAINING_CAPACITY_CHARGE] = 97 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535), 98 [REG_FULL_CHARGE_CAPACITY] = 99 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535), 100 [REG_FULL_CHARGE_CAPACITY_CHARGE] = 101 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535), 102 [REG_TIME_TO_EMPTY] = 103 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 104 65535), 105 [REG_TIME_TO_FULL] = 106 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 107 65535), 108 [REG_STATUS] = 109 BQ20Z75_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535), 110 [REG_CYCLE_COUNT] = 111 BQ20Z75_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535), 112 [REG_DESIGN_CAPACITY] = 113 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0, 114 65535), 115 [REG_DESIGN_CAPACITY_CHARGE] = 116 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0, 117 65535), 118 [REG_DESIGN_VOLTAGE] = 119 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0, 120 65535), 121 [REG_SERIAL_NUMBER] = 122 BQ20Z75_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535), 123}; 124 125static enum power_supply_property bq20z75_properties[] = { 126 POWER_SUPPLY_PROP_STATUS, 127 POWER_SUPPLY_PROP_HEALTH, 128 POWER_SUPPLY_PROP_PRESENT, 129 POWER_SUPPLY_PROP_TECHNOLOGY, 130 POWER_SUPPLY_PROP_CYCLE_COUNT, 131 POWER_SUPPLY_PROP_VOLTAGE_NOW, 132 POWER_SUPPLY_PROP_CURRENT_NOW, 133 POWER_SUPPLY_PROP_CAPACITY, 134 POWER_SUPPLY_PROP_TEMP, 135 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 136 POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 137 POWER_SUPPLY_PROP_SERIAL_NUMBER, 138 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 139 POWER_SUPPLY_PROP_ENERGY_NOW, 140 POWER_SUPPLY_PROP_ENERGY_FULL, 141 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 142 POWER_SUPPLY_PROP_CHARGE_NOW, 143 POWER_SUPPLY_PROP_CHARGE_FULL, 144 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 145}; 146 147struct bq20z75_info { 148 struct i2c_client *client; 149 struct power_supply power_supply; 150 struct bq20z75_platform_data *pdata; 151 bool is_present; 152 bool gpio_detect; 153 bool enable_detection; 154 int irq; 155}; 156 157static int bq20z75_read_word_data(struct i2c_client *client, u8 address) 158{ 159 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 160 s32 ret = 0; 161 int retries = 1; 162 163 if (bq20z75_device->pdata) 164 retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1); 165 166 while (retries > 0) { 167 ret = i2c_smbus_read_word_data(client, address); 168 if (ret >= 0) 169 break; 170 retries--; 171 } 172 173 if (ret < 0) { 174 dev_dbg(&client->dev, 175 "%s: i2c read at address 0x%x failed\n", 176 __func__, address); 177 return ret; 178 } 179 180 return le16_to_cpu(ret); 181} 182 183static int bq20z75_write_word_data(struct i2c_client *client, u8 address, 184 u16 value) 185{ 186 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 187 s32 ret = 0; 188 int retries = 1; 189 190 if (bq20z75_device->pdata) 191 retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1); 192 193 while (retries > 0) { 194 ret = i2c_smbus_write_word_data(client, address, 195 le16_to_cpu(value)); 196 if (ret >= 0) 197 break; 198 retries--; 199 } 200 201 if (ret < 0) { 202 dev_dbg(&client->dev, 203 "%s: i2c write to address 0x%x failed\n", 204 __func__, address); 205 return ret; 206 } 207 208 return 0; 209} 210 211static int bq20z75_get_battery_presence_and_health( 212 struct i2c_client *client, enum power_supply_property psp, 213 union power_supply_propval *val) 214{ 215 s32 ret; 216 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 217 218 if (psp == POWER_SUPPLY_PROP_PRESENT && 219 bq20z75_device->gpio_detect) { 220 ret = gpio_get_value( 221 bq20z75_device->pdata->battery_detect); 222 if (ret == bq20z75_device->pdata->battery_detect_present) 223 val->intval = 1; 224 else 225 val->intval = 0; 226 bq20z75_device->is_present = val->intval; 227 return ret; 228 } 229 230 /* Write to ManufacturerAccess with 231 * ManufacturerAccess command and then 232 * read the status */ 233 ret = bq20z75_write_word_data(client, 234 bq20z75_data[REG_MANUFACTURER_DATA].addr, 235 MANUFACTURER_ACCESS_STATUS); 236 if (ret < 0) { 237 if (psp == POWER_SUPPLY_PROP_PRESENT) 238 val->intval = 0; /* battery removed */ 239 return ret; 240 } 241 242 ret = bq20z75_read_word_data(client, 243 bq20z75_data[REG_MANUFACTURER_DATA].addr); 244 if (ret < 0) 245 return ret; 246 247 if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value || 248 ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) { 249 val->intval = 0; 250 return 0; 251 } 252 253 /* Mask the upper nibble of 2nd byte and 254 * lower byte of response then 255 * shift the result by 8 to get status*/ 256 ret &= 0x0F00; 257 ret >>= 8; 258 if (psp == POWER_SUPPLY_PROP_PRESENT) { 259 if (ret == 0x0F) 260 /* battery removed */ 261 val->intval = 0; 262 else 263 val->intval = 1; 264 } else if (psp == POWER_SUPPLY_PROP_HEALTH) { 265 if (ret == 0x09) 266 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 267 else if (ret == 0x0B) 268 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 269 else if (ret == 0x0C) 270 val->intval = POWER_SUPPLY_HEALTH_DEAD; 271 else 272 val->intval = POWER_SUPPLY_HEALTH_GOOD; 273 } 274 275 return 0; 276} 277 278static int bq20z75_get_battery_property(struct i2c_client *client, 279 int reg_offset, enum power_supply_property psp, 280 union power_supply_propval *val) 281{ 282 s32 ret; 283 284 ret = bq20z75_read_word_data(client, 285 bq20z75_data[reg_offset].addr); 286 if (ret < 0) 287 return ret; 288 289 /* returned values are 16 bit */ 290 if (bq20z75_data[reg_offset].min_value < 0) 291 ret = (s16)ret; 292 293 if (ret >= bq20z75_data[reg_offset].min_value && 294 ret <= bq20z75_data[reg_offset].max_value) { 295 val->intval = ret; 296 if (psp == POWER_SUPPLY_PROP_STATUS) { 297 if (ret & BATTERY_FULL_CHARGED) 298 val->intval = POWER_SUPPLY_STATUS_FULL; 299 else if (ret & BATTERY_FULL_DISCHARGED) 300 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 301 else if (ret & BATTERY_DISCHARGING) 302 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 303 else 304 val->intval = POWER_SUPPLY_STATUS_CHARGING; 305 } 306 } else { 307 if (psp == POWER_SUPPLY_PROP_STATUS) 308 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 309 else 310 val->intval = 0; 311 } 312 313 return 0; 314} 315 316static void bq20z75_unit_adjustment(struct i2c_client *client, 317 enum power_supply_property psp, union power_supply_propval *val) 318{ 319#define BASE_UNIT_CONVERSION 1000 320#define BATTERY_MODE_CAP_MULT_WATT (10 * BASE_UNIT_CONVERSION) 321#define TIME_UNIT_CONVERSION 60 322#define TEMP_KELVIN_TO_CELSIUS 2731 323 switch (psp) { 324 case POWER_SUPPLY_PROP_ENERGY_NOW: 325 case POWER_SUPPLY_PROP_ENERGY_FULL: 326 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 327 /* bq20z75 provides energy in units of 10mWh. 328 * Convert to µWh 329 */ 330 val->intval *= BATTERY_MODE_CAP_MULT_WATT; 331 break; 332 333 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 334 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 335 case POWER_SUPPLY_PROP_CURRENT_NOW: 336 case POWER_SUPPLY_PROP_CHARGE_NOW: 337 case POWER_SUPPLY_PROP_CHARGE_FULL: 338 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 339 val->intval *= BASE_UNIT_CONVERSION; 340 break; 341 342 case POWER_SUPPLY_PROP_TEMP: 343 /* bq20z75 provides battery temperature in 0.1K 344 * so convert it to 0.1°C 345 */ 346 val->intval -= TEMP_KELVIN_TO_CELSIUS; 347 break; 348 349 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 350 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 351 /* bq20z75 provides time to empty and time to full in minutes. 352 * Convert to seconds 353 */ 354 val->intval *= TIME_UNIT_CONVERSION; 355 break; 356 357 default: 358 dev_dbg(&client->dev, 359 "%s: no need for unit conversion %d\n", __func__, psp); 360 } 361} 362 363static enum bq20z75_battery_mode 364bq20z75_set_battery_mode(struct i2c_client *client, 365 enum bq20z75_battery_mode mode) 366{ 367 int ret, original_val; 368 369 original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET); 370 if (original_val < 0) 371 return original_val; 372 373 if ((original_val & BATTERY_MODE_MASK) == mode) 374 return mode; 375 376 if (mode == BATTERY_MODE_AMPS) 377 ret = original_val & ~BATTERY_MODE_MASK; 378 else 379 ret = original_val | BATTERY_MODE_MASK; 380 381 ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret); 382 if (ret < 0) 383 return ret; 384 385 return original_val & BATTERY_MODE_MASK; 386} 387 388static int bq20z75_get_battery_capacity(struct i2c_client *client, 389 int reg_offset, enum power_supply_property psp, 390 union power_supply_propval *val) 391{ 392 s32 ret; 393 enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS; 394 395 if (power_supply_is_amp_property(psp)) 396 mode = BATTERY_MODE_AMPS; 397 398 mode = bq20z75_set_battery_mode(client, mode); 399 if (mode < 0) 400 return mode; 401 402 ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr); 403 if (ret < 0) 404 return ret; 405 406 if (psp == POWER_SUPPLY_PROP_CAPACITY) { 407 /* bq20z75 spec says that this can be >100 % 408 * even if max value is 100 % */ 409 val->intval = min(ret, 100); 410 } else 411 val->intval = ret; 412 413 ret = bq20z75_set_battery_mode(client, mode); 414 if (ret < 0) 415 return ret; 416 417 return 0; 418} 419 420static char bq20z75_serial[5]; 421static int bq20z75_get_battery_serial_number(struct i2c_client *client, 422 union power_supply_propval *val) 423{ 424 int ret; 425 426 ret = bq20z75_read_word_data(client, 427 bq20z75_data[REG_SERIAL_NUMBER].addr); 428 if (ret < 0) 429 return ret; 430 431 ret = sprintf(bq20z75_serial, "%04x", ret); 432 val->strval = bq20z75_serial; 433 434 return 0; 435} 436 437static int bq20z75_get_property_index(struct i2c_client *client, 438 enum power_supply_property psp) 439{ 440 int count; 441 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++) 442 if (psp == bq20z75_data[count].psp) 443 return count; 444 445 dev_warn(&client->dev, 446 "%s: Invalid Property - %d\n", __func__, psp); 447 448 return -EINVAL; 449} 450 451static int bq20z75_get_property(struct power_supply *psy, 452 enum power_supply_property psp, 453 union power_supply_propval *val) 454{ 455 int ret = 0; 456 struct bq20z75_info *bq20z75_device = container_of(psy, 457 struct bq20z75_info, power_supply); 458 struct i2c_client *client = bq20z75_device->client; 459 460 switch (psp) { 461 case POWER_SUPPLY_PROP_PRESENT: 462 case POWER_SUPPLY_PROP_HEALTH: 463 ret = bq20z75_get_battery_presence_and_health(client, psp, val); 464 if (psp == POWER_SUPPLY_PROP_PRESENT) 465 return 0; 466 break; 467 468 case POWER_SUPPLY_PROP_TECHNOLOGY: 469 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 470 break; 471 472 case POWER_SUPPLY_PROP_ENERGY_NOW: 473 case POWER_SUPPLY_PROP_ENERGY_FULL: 474 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 475 case POWER_SUPPLY_PROP_CHARGE_NOW: 476 case POWER_SUPPLY_PROP_CHARGE_FULL: 477 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 478 case POWER_SUPPLY_PROP_CAPACITY: 479 ret = bq20z75_get_property_index(client, psp); 480 if (ret < 0) 481 break; 482 483 ret = bq20z75_get_battery_capacity(client, ret, psp, val); 484 break; 485 486 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 487 ret = bq20z75_get_battery_serial_number(client, val); 488 break; 489 490 case POWER_SUPPLY_PROP_STATUS: 491 case POWER_SUPPLY_PROP_CYCLE_COUNT: 492 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 493 case POWER_SUPPLY_PROP_CURRENT_NOW: 494 case POWER_SUPPLY_PROP_TEMP: 495 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 496 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 497 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 498 ret = bq20z75_get_property_index(client, psp); 499 if (ret < 0) 500 break; 501 502 ret = bq20z75_get_battery_property(client, ret, psp, val); 503 break; 504 505 default: 506 dev_err(&client->dev, 507 "%s: INVALID property\n", __func__); 508 return -EINVAL; 509 } 510 511 if (!bq20z75_device->enable_detection) 512 goto done; 513 514 if (!bq20z75_device->gpio_detect && 515 bq20z75_device->is_present != (ret >= 0)) { 516 bq20z75_device->is_present = (ret >= 0); 517 power_supply_changed(&bq20z75_device->power_supply); 518 } 519 520done: 521 if (!ret) { 522 /* Convert units to match requirements for power supply class */ 523 bq20z75_unit_adjustment(client, psp, val); 524 } 525 526 dev_dbg(&client->dev, 527 "%s: property = %d, value = %x\n", __func__, psp, val->intval); 528 529 if (ret && bq20z75_device->is_present) 530 return ret; 531 532 /* battery not present, so return NODATA for properties */ 533 if (ret) 534 return -ENODATA; 535 536 return 0; 537} 538 539static irqreturn_t bq20z75_irq(int irq, void *devid) 540{ 541 struct power_supply *battery = devid; 542 543 power_supply_changed(battery); 544 545 return IRQ_HANDLED; 546} 547 548static int __devinit bq20z75_probe(struct i2c_client *client, 549 const struct i2c_device_id *id) 550{ 551 struct bq20z75_info *bq20z75_device; 552 struct bq20z75_platform_data *pdata = client->dev.platform_data; 553 int rc; 554 int irq; 555 556 bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL); 557 if (!bq20z75_device) 558 return -ENOMEM; 559 560 bq20z75_device->client = client; 561 bq20z75_device->enable_detection = false; 562 bq20z75_device->gpio_detect = false; 563 bq20z75_device->power_supply.name = "battery"; 564 bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY; 565 bq20z75_device->power_supply.properties = bq20z75_properties; 566 bq20z75_device->power_supply.num_properties = 567 ARRAY_SIZE(bq20z75_properties); 568 bq20z75_device->power_supply.get_property = bq20z75_get_property; 569 570 if (pdata) { 571 bq20z75_device->gpio_detect = 572 gpio_is_valid(pdata->battery_detect); 573 bq20z75_device->pdata = pdata; 574 } 575 576 i2c_set_clientdata(client, bq20z75_device); 577 578 if (!bq20z75_device->gpio_detect) 579 goto skip_gpio; 580 581 rc = gpio_request(pdata->battery_detect, dev_name(&client->dev)); 582 if (rc) { 583 dev_warn(&client->dev, "Failed to request gpio: %d\n", rc); 584 bq20z75_device->gpio_detect = false; 585 goto skip_gpio; 586 } 587 588 rc = gpio_direction_input(pdata->battery_detect); 589 if (rc) { 590 dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc); 591 gpio_free(pdata->battery_detect); 592 bq20z75_device->gpio_detect = false; 593 goto skip_gpio; 594 } 595 596 irq = gpio_to_irq(pdata->battery_detect); 597 if (irq <= 0) { 598 dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); 599 gpio_free(pdata->battery_detect); 600 bq20z75_device->gpio_detect = false; 601 goto skip_gpio; 602 } 603 604 rc = request_irq(irq, bq20z75_irq, 605 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 606 dev_name(&client->dev), &bq20z75_device->power_supply); 607 if (rc) { 608 dev_warn(&client->dev, "Failed to request irq: %d\n", rc); 609 gpio_free(pdata->battery_detect); 610 bq20z75_device->gpio_detect = false; 611 goto skip_gpio; 612 } 613 614 bq20z75_device->irq = irq; 615 616skip_gpio: 617 618 rc = power_supply_register(&client->dev, &bq20z75_device->power_supply); 619 if (rc) { 620 dev_err(&client->dev, 621 "%s: Failed to register power supply\n", __func__); 622 goto exit_psupply; 623 } 624 625 dev_info(&client->dev, 626 "%s: battery gas gauge device registered\n", client->name); 627 628 return 0; 629 630exit_psupply: 631 if (bq20z75_device->irq) 632 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply); 633 if (bq20z75_device->gpio_detect) 634 gpio_free(pdata->battery_detect); 635 636 kfree(bq20z75_device); 637 638 return rc; 639} 640 641static int __devexit bq20z75_remove(struct i2c_client *client) 642{ 643 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 644 645 if (bq20z75_device->irq) 646 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply); 647 if (bq20z75_device->gpio_detect) 648 gpio_free(bq20z75_device->pdata->battery_detect); 649 650 power_supply_unregister(&bq20z75_device->power_supply); 651 kfree(bq20z75_device); 652 bq20z75_device = NULL; 653 654 return 0; 655} 656 657#if defined CONFIG_PM 658static int bq20z75_suspend(struct i2c_client *client, 659 pm_message_t state) 660{ 661 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 662 s32 ret; 663 664 /* write to manufacturer access with sleep command */ 665 ret = bq20z75_write_word_data(client, 666 bq20z75_data[REG_MANUFACTURER_DATA].addr, 667 MANUFACTURER_ACCESS_SLEEP); 668 if (bq20z75_device->is_present && ret < 0) 669 return ret; 670 671 return 0; 672} 673#else 674#define bq20z75_suspend NULL 675#endif 676/* any smbus transaction will wake up bq20z75 */ 677#define bq20z75_resume NULL 678 679static const struct i2c_device_id bq20z75_id[] = { 680 { "bq20z75", 0 }, 681 {} 682}; 683MODULE_DEVICE_TABLE(i2c, bq20z75_id); 684 685static struct i2c_driver bq20z75_battery_driver = { 686 .probe = bq20z75_probe, 687 .remove = __devexit_p(bq20z75_remove), 688 .suspend = bq20z75_suspend, 689 .resume = bq20z75_resume, 690 .id_table = bq20z75_id, 691 .driver = { 692 .name = "bq20z75-battery", 693 }, 694}; 695 696static int __init bq20z75_battery_init(void) 697{ 698 return i2c_add_driver(&bq20z75_battery_driver); 699} 700module_init(bq20z75_battery_init); 701 702static void __exit bq20z75_battery_exit(void) 703{ 704 i2c_del_driver(&bq20z75_battery_driver); 705} 706module_exit(bq20z75_battery_exit); 707 708MODULE_DESCRIPTION("BQ20z75 battery monitor driver"); 709MODULE_LICENSE("GPL");