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 v3.1-rc3 794 lines 21 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 int last_state; 156 int poll_time; 157 struct delayed_work work; 158 int ignore_changes; 159}; 160 161static int bq20z75_read_word_data(struct i2c_client *client, u8 address) 162{ 163 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 164 s32 ret = 0; 165 int retries = 1; 166 167 if (bq20z75_device->pdata) 168 retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1); 169 170 while (retries > 0) { 171 ret = i2c_smbus_read_word_data(client, address); 172 if (ret >= 0) 173 break; 174 retries--; 175 } 176 177 if (ret < 0) { 178 dev_dbg(&client->dev, 179 "%s: i2c read at address 0x%x failed\n", 180 __func__, address); 181 return ret; 182 } 183 184 return le16_to_cpu(ret); 185} 186 187static int bq20z75_write_word_data(struct i2c_client *client, u8 address, 188 u16 value) 189{ 190 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 191 s32 ret = 0; 192 int retries = 1; 193 194 if (bq20z75_device->pdata) 195 retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1); 196 197 while (retries > 0) { 198 ret = i2c_smbus_write_word_data(client, address, 199 le16_to_cpu(value)); 200 if (ret >= 0) 201 break; 202 retries--; 203 } 204 205 if (ret < 0) { 206 dev_dbg(&client->dev, 207 "%s: i2c write to address 0x%x failed\n", 208 __func__, address); 209 return ret; 210 } 211 212 return 0; 213} 214 215static int bq20z75_get_battery_presence_and_health( 216 struct i2c_client *client, enum power_supply_property psp, 217 union power_supply_propval *val) 218{ 219 s32 ret; 220 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 221 222 if (psp == POWER_SUPPLY_PROP_PRESENT && 223 bq20z75_device->gpio_detect) { 224 ret = gpio_get_value( 225 bq20z75_device->pdata->battery_detect); 226 if (ret == bq20z75_device->pdata->battery_detect_present) 227 val->intval = 1; 228 else 229 val->intval = 0; 230 bq20z75_device->is_present = val->intval; 231 return ret; 232 } 233 234 /* Write to ManufacturerAccess with 235 * ManufacturerAccess command and then 236 * read the status */ 237 ret = bq20z75_write_word_data(client, 238 bq20z75_data[REG_MANUFACTURER_DATA].addr, 239 MANUFACTURER_ACCESS_STATUS); 240 if (ret < 0) { 241 if (psp == POWER_SUPPLY_PROP_PRESENT) 242 val->intval = 0; /* battery removed */ 243 return ret; 244 } 245 246 ret = bq20z75_read_word_data(client, 247 bq20z75_data[REG_MANUFACTURER_DATA].addr); 248 if (ret < 0) 249 return ret; 250 251 if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value || 252 ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) { 253 val->intval = 0; 254 return 0; 255 } 256 257 /* Mask the upper nibble of 2nd byte and 258 * lower byte of response then 259 * shift the result by 8 to get status*/ 260 ret &= 0x0F00; 261 ret >>= 8; 262 if (psp == POWER_SUPPLY_PROP_PRESENT) { 263 if (ret == 0x0F) 264 /* battery removed */ 265 val->intval = 0; 266 else 267 val->intval = 1; 268 } else if (psp == POWER_SUPPLY_PROP_HEALTH) { 269 if (ret == 0x09) 270 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 271 else if (ret == 0x0B) 272 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 273 else if (ret == 0x0C) 274 val->intval = POWER_SUPPLY_HEALTH_DEAD; 275 else 276 val->intval = POWER_SUPPLY_HEALTH_GOOD; 277 } 278 279 return 0; 280} 281 282static int bq20z75_get_battery_property(struct i2c_client *client, 283 int reg_offset, enum power_supply_property psp, 284 union power_supply_propval *val) 285{ 286 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 287 s32 ret; 288 289 ret = bq20z75_read_word_data(client, 290 bq20z75_data[reg_offset].addr); 291 if (ret < 0) 292 return ret; 293 294 /* returned values are 16 bit */ 295 if (bq20z75_data[reg_offset].min_value < 0) 296 ret = (s16)ret; 297 298 if (ret >= bq20z75_data[reg_offset].min_value && 299 ret <= bq20z75_data[reg_offset].max_value) { 300 val->intval = ret; 301 if (psp != POWER_SUPPLY_PROP_STATUS) 302 return 0; 303 304 if (ret & BATTERY_FULL_CHARGED) 305 val->intval = POWER_SUPPLY_STATUS_FULL; 306 else if (ret & BATTERY_FULL_DISCHARGED) 307 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 308 else if (ret & BATTERY_DISCHARGING) 309 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 310 else 311 val->intval = POWER_SUPPLY_STATUS_CHARGING; 312 313 if (bq20z75_device->poll_time == 0) 314 bq20z75_device->last_state = val->intval; 315 else if (bq20z75_device->last_state != val->intval) { 316 cancel_delayed_work_sync(&bq20z75_device->work); 317 power_supply_changed(&bq20z75_device->power_supply); 318 bq20z75_device->poll_time = 0; 319 } 320 } else { 321 if (psp == POWER_SUPPLY_PROP_STATUS) 322 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 323 else 324 val->intval = 0; 325 } 326 327 return 0; 328} 329 330static void bq20z75_unit_adjustment(struct i2c_client *client, 331 enum power_supply_property psp, union power_supply_propval *val) 332{ 333#define BASE_UNIT_CONVERSION 1000 334#define BATTERY_MODE_CAP_MULT_WATT (10 * BASE_UNIT_CONVERSION) 335#define TIME_UNIT_CONVERSION 60 336#define TEMP_KELVIN_TO_CELSIUS 2731 337 switch (psp) { 338 case POWER_SUPPLY_PROP_ENERGY_NOW: 339 case POWER_SUPPLY_PROP_ENERGY_FULL: 340 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 341 /* bq20z75 provides energy in units of 10mWh. 342 * Convert to µWh 343 */ 344 val->intval *= BATTERY_MODE_CAP_MULT_WATT; 345 break; 346 347 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 348 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 349 case POWER_SUPPLY_PROP_CURRENT_NOW: 350 case POWER_SUPPLY_PROP_CHARGE_NOW: 351 case POWER_SUPPLY_PROP_CHARGE_FULL: 352 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 353 val->intval *= BASE_UNIT_CONVERSION; 354 break; 355 356 case POWER_SUPPLY_PROP_TEMP: 357 /* bq20z75 provides battery temperature in 0.1K 358 * so convert it to 0.1°C 359 */ 360 val->intval -= TEMP_KELVIN_TO_CELSIUS; 361 break; 362 363 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 364 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 365 /* bq20z75 provides time to empty and time to full in minutes. 366 * Convert to seconds 367 */ 368 val->intval *= TIME_UNIT_CONVERSION; 369 break; 370 371 default: 372 dev_dbg(&client->dev, 373 "%s: no need for unit conversion %d\n", __func__, psp); 374 } 375} 376 377static enum bq20z75_battery_mode 378bq20z75_set_battery_mode(struct i2c_client *client, 379 enum bq20z75_battery_mode mode) 380{ 381 int ret, original_val; 382 383 original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET); 384 if (original_val < 0) 385 return original_val; 386 387 if ((original_val & BATTERY_MODE_MASK) == mode) 388 return mode; 389 390 if (mode == BATTERY_MODE_AMPS) 391 ret = original_val & ~BATTERY_MODE_MASK; 392 else 393 ret = original_val | BATTERY_MODE_MASK; 394 395 ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret); 396 if (ret < 0) 397 return ret; 398 399 return original_val & BATTERY_MODE_MASK; 400} 401 402static int bq20z75_get_battery_capacity(struct i2c_client *client, 403 int reg_offset, enum power_supply_property psp, 404 union power_supply_propval *val) 405{ 406 s32 ret; 407 enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS; 408 409 if (power_supply_is_amp_property(psp)) 410 mode = BATTERY_MODE_AMPS; 411 412 mode = bq20z75_set_battery_mode(client, mode); 413 if (mode < 0) 414 return mode; 415 416 ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr); 417 if (ret < 0) 418 return ret; 419 420 if (psp == POWER_SUPPLY_PROP_CAPACITY) { 421 /* bq20z75 spec says that this can be >100 % 422 * even if max value is 100 % */ 423 val->intval = min(ret, 100); 424 } else 425 val->intval = ret; 426 427 ret = bq20z75_set_battery_mode(client, mode); 428 if (ret < 0) 429 return ret; 430 431 return 0; 432} 433 434static char bq20z75_serial[5]; 435static int bq20z75_get_battery_serial_number(struct i2c_client *client, 436 union power_supply_propval *val) 437{ 438 int ret; 439 440 ret = bq20z75_read_word_data(client, 441 bq20z75_data[REG_SERIAL_NUMBER].addr); 442 if (ret < 0) 443 return ret; 444 445 ret = sprintf(bq20z75_serial, "%04x", ret); 446 val->strval = bq20z75_serial; 447 448 return 0; 449} 450 451static int bq20z75_get_property_index(struct i2c_client *client, 452 enum power_supply_property psp) 453{ 454 int count; 455 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++) 456 if (psp == bq20z75_data[count].psp) 457 return count; 458 459 dev_warn(&client->dev, 460 "%s: Invalid Property - %d\n", __func__, psp); 461 462 return -EINVAL; 463} 464 465static int bq20z75_get_property(struct power_supply *psy, 466 enum power_supply_property psp, 467 union power_supply_propval *val) 468{ 469 int ret = 0; 470 struct bq20z75_info *bq20z75_device = container_of(psy, 471 struct bq20z75_info, power_supply); 472 struct i2c_client *client = bq20z75_device->client; 473 474 switch (psp) { 475 case POWER_SUPPLY_PROP_PRESENT: 476 case POWER_SUPPLY_PROP_HEALTH: 477 ret = bq20z75_get_battery_presence_and_health(client, psp, val); 478 if (psp == POWER_SUPPLY_PROP_PRESENT) 479 return 0; 480 break; 481 482 case POWER_SUPPLY_PROP_TECHNOLOGY: 483 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 484 break; 485 486 case POWER_SUPPLY_PROP_ENERGY_NOW: 487 case POWER_SUPPLY_PROP_ENERGY_FULL: 488 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 489 case POWER_SUPPLY_PROP_CHARGE_NOW: 490 case POWER_SUPPLY_PROP_CHARGE_FULL: 491 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 492 case POWER_SUPPLY_PROP_CAPACITY: 493 ret = bq20z75_get_property_index(client, psp); 494 if (ret < 0) 495 break; 496 497 ret = bq20z75_get_battery_capacity(client, ret, psp, val); 498 break; 499 500 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 501 ret = bq20z75_get_battery_serial_number(client, val); 502 break; 503 504 case POWER_SUPPLY_PROP_STATUS: 505 case POWER_SUPPLY_PROP_CYCLE_COUNT: 506 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 507 case POWER_SUPPLY_PROP_CURRENT_NOW: 508 case POWER_SUPPLY_PROP_TEMP: 509 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 510 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 511 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 512 ret = bq20z75_get_property_index(client, psp); 513 if (ret < 0) 514 break; 515 516 ret = bq20z75_get_battery_property(client, ret, psp, val); 517 break; 518 519 default: 520 dev_err(&client->dev, 521 "%s: INVALID property\n", __func__); 522 return -EINVAL; 523 } 524 525 if (!bq20z75_device->enable_detection) 526 goto done; 527 528 if (!bq20z75_device->gpio_detect && 529 bq20z75_device->is_present != (ret >= 0)) { 530 bq20z75_device->is_present = (ret >= 0); 531 power_supply_changed(&bq20z75_device->power_supply); 532 } 533 534done: 535 if (!ret) { 536 /* Convert units to match requirements for power supply class */ 537 bq20z75_unit_adjustment(client, psp, val); 538 } 539 540 dev_dbg(&client->dev, 541 "%s: property = %d, value = %x\n", __func__, psp, val->intval); 542 543 if (ret && bq20z75_device->is_present) 544 return ret; 545 546 /* battery not present, so return NODATA for properties */ 547 if (ret) 548 return -ENODATA; 549 550 return 0; 551} 552 553static irqreturn_t bq20z75_irq(int irq, void *devid) 554{ 555 struct power_supply *battery = devid; 556 557 power_supply_changed(battery); 558 559 return IRQ_HANDLED; 560} 561 562static void bq20z75_external_power_changed(struct power_supply *psy) 563{ 564 struct bq20z75_info *bq20z75_device; 565 566 bq20z75_device = container_of(psy, struct bq20z75_info, power_supply); 567 568 if (bq20z75_device->ignore_changes > 0) { 569 bq20z75_device->ignore_changes--; 570 return; 571 } 572 573 /* cancel outstanding work */ 574 cancel_delayed_work_sync(&bq20z75_device->work); 575 576 schedule_delayed_work(&bq20z75_device->work, HZ); 577 bq20z75_device->poll_time = bq20z75_device->pdata->poll_retry_count; 578} 579 580static void bq20z75_delayed_work(struct work_struct *work) 581{ 582 struct bq20z75_info *bq20z75_device; 583 s32 ret; 584 585 bq20z75_device = container_of(work, struct bq20z75_info, work.work); 586 587 ret = bq20z75_read_word_data(bq20z75_device->client, 588 bq20z75_data[REG_STATUS].addr); 589 /* if the read failed, give up on this work */ 590 if (ret < 0) { 591 bq20z75_device->poll_time = 0; 592 return; 593 } 594 595 if (ret & BATTERY_FULL_CHARGED) 596 ret = POWER_SUPPLY_STATUS_FULL; 597 else if (ret & BATTERY_FULL_DISCHARGED) 598 ret = POWER_SUPPLY_STATUS_NOT_CHARGING; 599 else if (ret & BATTERY_DISCHARGING) 600 ret = POWER_SUPPLY_STATUS_DISCHARGING; 601 else 602 ret = POWER_SUPPLY_STATUS_CHARGING; 603 604 if (bq20z75_device->last_state != ret) { 605 bq20z75_device->poll_time = 0; 606 power_supply_changed(&bq20z75_device->power_supply); 607 return; 608 } 609 if (bq20z75_device->poll_time > 0) { 610 schedule_delayed_work(&bq20z75_device->work, HZ); 611 bq20z75_device->poll_time--; 612 return; 613 } 614} 615 616static int __devinit bq20z75_probe(struct i2c_client *client, 617 const struct i2c_device_id *id) 618{ 619 struct bq20z75_info *bq20z75_device; 620 struct bq20z75_platform_data *pdata = client->dev.platform_data; 621 int rc; 622 int irq; 623 624 bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL); 625 if (!bq20z75_device) 626 return -ENOMEM; 627 628 bq20z75_device->client = client; 629 bq20z75_device->enable_detection = false; 630 bq20z75_device->gpio_detect = false; 631 bq20z75_device->power_supply.name = "battery"; 632 bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY; 633 bq20z75_device->power_supply.properties = bq20z75_properties; 634 bq20z75_device->power_supply.num_properties = 635 ARRAY_SIZE(bq20z75_properties); 636 bq20z75_device->power_supply.get_property = bq20z75_get_property; 637 /* ignore first notification of external change, it is generated 638 * from the power_supply_register call back 639 */ 640 bq20z75_device->ignore_changes = 1; 641 bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN; 642 bq20z75_device->power_supply.external_power_changed = 643 bq20z75_external_power_changed; 644 645 if (pdata) { 646 bq20z75_device->gpio_detect = 647 gpio_is_valid(pdata->battery_detect); 648 bq20z75_device->pdata = pdata; 649 } 650 651 i2c_set_clientdata(client, bq20z75_device); 652 653 if (!bq20z75_device->gpio_detect) 654 goto skip_gpio; 655 656 rc = gpio_request(pdata->battery_detect, dev_name(&client->dev)); 657 if (rc) { 658 dev_warn(&client->dev, "Failed to request gpio: %d\n", rc); 659 bq20z75_device->gpio_detect = false; 660 goto skip_gpio; 661 } 662 663 rc = gpio_direction_input(pdata->battery_detect); 664 if (rc) { 665 dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc); 666 gpio_free(pdata->battery_detect); 667 bq20z75_device->gpio_detect = false; 668 goto skip_gpio; 669 } 670 671 irq = gpio_to_irq(pdata->battery_detect); 672 if (irq <= 0) { 673 dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); 674 gpio_free(pdata->battery_detect); 675 bq20z75_device->gpio_detect = false; 676 goto skip_gpio; 677 } 678 679 rc = request_irq(irq, bq20z75_irq, 680 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 681 dev_name(&client->dev), &bq20z75_device->power_supply); 682 if (rc) { 683 dev_warn(&client->dev, "Failed to request irq: %d\n", rc); 684 gpio_free(pdata->battery_detect); 685 bq20z75_device->gpio_detect = false; 686 goto skip_gpio; 687 } 688 689 bq20z75_device->irq = irq; 690 691skip_gpio: 692 693 rc = power_supply_register(&client->dev, &bq20z75_device->power_supply); 694 if (rc) { 695 dev_err(&client->dev, 696 "%s: Failed to register power supply\n", __func__); 697 goto exit_psupply; 698 } 699 700 dev_info(&client->dev, 701 "%s: battery gas gauge device registered\n", client->name); 702 703 INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work); 704 705 bq20z75_device->enable_detection = true; 706 707 return 0; 708 709exit_psupply: 710 if (bq20z75_device->irq) 711 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply); 712 if (bq20z75_device->gpio_detect) 713 gpio_free(pdata->battery_detect); 714 715 kfree(bq20z75_device); 716 717 return rc; 718} 719 720static int __devexit bq20z75_remove(struct i2c_client *client) 721{ 722 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 723 724 if (bq20z75_device->irq) 725 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply); 726 if (bq20z75_device->gpio_detect) 727 gpio_free(bq20z75_device->pdata->battery_detect); 728 729 power_supply_unregister(&bq20z75_device->power_supply); 730 731 cancel_delayed_work_sync(&bq20z75_device->work); 732 733 kfree(bq20z75_device); 734 bq20z75_device = NULL; 735 736 return 0; 737} 738 739#if defined CONFIG_PM 740static int bq20z75_suspend(struct i2c_client *client, 741 pm_message_t state) 742{ 743 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 744 s32 ret; 745 746 if (bq20z75_device->poll_time > 0) 747 cancel_delayed_work_sync(&bq20z75_device->work); 748 749 /* write to manufacturer access with sleep command */ 750 ret = bq20z75_write_word_data(client, 751 bq20z75_data[REG_MANUFACTURER_DATA].addr, 752 MANUFACTURER_ACCESS_SLEEP); 753 if (bq20z75_device->is_present && ret < 0) 754 return ret; 755 756 return 0; 757} 758#else 759#define bq20z75_suspend NULL 760#endif 761/* any smbus transaction will wake up bq20z75 */ 762#define bq20z75_resume NULL 763 764static const struct i2c_device_id bq20z75_id[] = { 765 { "bq20z75", 0 }, 766 {} 767}; 768MODULE_DEVICE_TABLE(i2c, bq20z75_id); 769 770static struct i2c_driver bq20z75_battery_driver = { 771 .probe = bq20z75_probe, 772 .remove = __devexit_p(bq20z75_remove), 773 .suspend = bq20z75_suspend, 774 .resume = bq20z75_resume, 775 .id_table = bq20z75_id, 776 .driver = { 777 .name = "bq20z75-battery", 778 }, 779}; 780 781static int __init bq20z75_battery_init(void) 782{ 783 return i2c_add_driver(&bq20z75_battery_driver); 784} 785module_init(bq20z75_battery_init); 786 787static void __exit bq20z75_battery_exit(void) 788{ 789 i2c_del_driver(&bq20z75_battery_driver); 790} 791module_exit(bq20z75_battery_exit); 792 793MODULE_DESCRIPTION("BQ20z75 battery monitor driver"); 794MODULE_LICENSE("GPL");