1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) ST-Ericsson SA 2012 4 * 5 * Battery temperature driver for AB8500 6 * 7 * Author: 8 * Johan Palsson <johan.palsson@stericsson.com> 9 * Karl Komierowski <karl.komierowski@stericsson.com> 10 * Arun R Murthy <arun.murthy@stericsson.com> 11 */ 12 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/device.h> 16 #include <linux/component.h> 17 #include <linux/interrupt.h> 18 #include <linux/delay.h> 19 #include <linux/slab.h> 20 #include <linux/platform_device.h> 21 #include <linux/power_supply.h> 22 #include <linux/completion.h> 23 #include <linux/workqueue.h> 24 #include <linux/jiffies.h> 25 #include <linux/of.h> 26 #include <linux/mfd/core.h> 27 #include <linux/mfd/abx500.h> 28 #include <linux/mfd/abx500/ab8500.h> 29 #include <linux/thermal.h> 30 #include <linux/iio/consumer.h> 31 #include <linux/fixp-arith.h> 32 33 #include "ab8500-bm.h" 34 35 #define BTEMP_THERMAL_LOW_LIMIT -10 36 #define BTEMP_THERMAL_MED_LIMIT 0 37 #define BTEMP_THERMAL_HIGH_LIMIT_52 52 38 #define BTEMP_THERMAL_HIGH_LIMIT_57 57 39 #define BTEMP_THERMAL_HIGH_LIMIT_62 62 40 41 #define BTEMP_BATCTRL_CURR_SRC_7UA 7 42 #define BTEMP_BATCTRL_CURR_SRC_20UA 20 43 44 #define BTEMP_BATCTRL_CURR_SRC_16UA 16 45 #define BTEMP_BATCTRL_CURR_SRC_18UA 18 46 47 #define BTEMP_BATCTRL_CURR_SRC_60UA 60 48 #define BTEMP_BATCTRL_CURR_SRC_120UA 120 49 50 /** 51 * struct ab8500_btemp_interrupts - ab8500 interrupts 52 * @name: name of the interrupt 53 * @isr function pointer to the isr 54 */ 55 struct ab8500_btemp_interrupts { 56 char *name; 57 irqreturn_t (*isr)(int irq, void *data); 58 }; 59 60 struct ab8500_btemp_events { 61 bool batt_rem; 62 bool btemp_high; 63 bool btemp_medhigh; 64 bool btemp_lowmed; 65 bool btemp_low; 66 bool ac_conn; 67 bool usb_conn; 68 }; 69 70 struct ab8500_btemp_ranges { 71 int btemp_high_limit; 72 int btemp_med_limit; 73 int btemp_low_limit; 74 }; 75 76 /** 77 * struct ab8500_btemp - ab8500 BTEMP device information 78 * @dev: Pointer to the structure device 79 * @node: List of AB8500 BTEMPs, hence prepared for reentrance 80 * @curr_source: What current source we use, in uA 81 * @bat_temp: Dispatched battery temperature in degree Celsius 82 * @prev_bat_temp Last measured battery temperature in degree Celsius 83 * @parent: Pointer to the struct ab8500 84 * @tz: Thermal zone for the battery 85 * @adc_bat_ctrl: ADC channel for the battery control 86 * @fg: Pointer to the struct fg 87 * @bm: Platform specific battery management information 88 * @btemp_psy: Structure for BTEMP specific battery properties 89 * @events: Structure for information about events triggered 90 * @btemp_ranges: Battery temperature range structure 91 * @btemp_wq: Work queue for measuring the temperature periodically 92 * @btemp_periodic_work: Work for measuring the temperature periodically 93 * @initialized: True if battery id read. 94 */ 95 struct ab8500_btemp { 96 struct device *dev; 97 struct list_head node; 98 int curr_source; 99 int bat_temp; 100 int prev_bat_temp; 101 struct ab8500 *parent; 102 struct thermal_zone_device *tz; 103 struct iio_channel *bat_ctrl; 104 struct ab8500_fg *fg; 105 struct ab8500_bm_data *bm; 106 struct power_supply *btemp_psy; 107 struct ab8500_btemp_events events; 108 struct ab8500_btemp_ranges btemp_ranges; 109 struct workqueue_struct *btemp_wq; 110 struct delayed_work btemp_periodic_work; 111 bool initialized; 112 }; 113 114 /* BTEMP power supply properties */ 115 static enum power_supply_property ab8500_btemp_props[] = { 116 POWER_SUPPLY_PROP_PRESENT, 117 POWER_SUPPLY_PROP_ONLINE, 118 POWER_SUPPLY_PROP_TEMP, 119 }; 120 121 static LIST_HEAD(ab8500_btemp_list); 122 123 /** 124 * ab8500_btemp_batctrl_volt_to_res() - convert batctrl voltage to resistance 125 * @di: pointer to the ab8500_btemp structure 126 * @v_batctrl: measured batctrl voltage 127 * @inst_curr: measured instant current 128 * 129 * This function returns the battery resistance that is 130 * derived from the BATCTRL voltage. 131 * Returns value in Ohms. 132 */ 133 static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di, 134 int v_batctrl, int inst_curr) 135 { 136 if (is_ab8500_1p1_or_earlier(di->parent)) { 137 /* 138 * For ABB cut1.0 and 1.1 BAT_CTRL is internally 139 * connected to 1.8V through a 450k resistor 140 */ 141 return (450000 * (v_batctrl)) / (1800 - v_batctrl); 142 } 143 144 /* 145 * BAT_CTRL is internally 146 * connected to 1.8V through a 80k resistor 147 */ 148 return (80000 * (v_batctrl)) / (1800 - v_batctrl); 149 } 150 151 /** 152 * ab8500_btemp_read_batctrl_voltage() - measure batctrl voltage 153 * @di: pointer to the ab8500_btemp structure 154 * 155 * This function returns the voltage on BATCTRL. Returns value in mV. 156 */ 157 static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di) 158 { 159 int vbtemp, ret; 160 static int prev; 161 162 ret = iio_read_channel_processed(di->bat_ctrl, &vbtemp); 163 if (ret < 0) { 164 dev_err(di->dev, 165 "%s ADC conversion failed, using previous value", 166 __func__); 167 return prev; 168 } 169 prev = vbtemp; 170 return vbtemp; 171 } 172 173 /** 174 * ab8500_btemp_get_batctrl_res() - get battery resistance 175 * @di: pointer to the ab8500_btemp structure 176 * 177 * This function returns the battery pack identification resistance. 178 * Returns value in Ohms. 179 */ 180 static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di) 181 { 182 int ret; 183 int batctrl = 0; 184 int res; 185 int inst_curr; 186 int i; 187 188 if (!di->fg) 189 di->fg = ab8500_fg_get(); 190 if (!di->fg) { 191 dev_err(di->dev, "No fg found\n"); 192 return -EINVAL; 193 } 194 195 ret = ab8500_fg_inst_curr_start(di->fg); 196 197 if (ret) { 198 dev_err(di->dev, "Failed to start current measurement\n"); 199 return ret; 200 } 201 202 do { 203 msleep(20); 204 } while (!ab8500_fg_inst_curr_started(di->fg)); 205 206 i = 0; 207 208 do { 209 batctrl += ab8500_btemp_read_batctrl_voltage(di); 210 i++; 211 msleep(20); 212 } while (!ab8500_fg_inst_curr_done(di->fg)); 213 batctrl /= i; 214 215 ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr); 216 if (ret) { 217 dev_err(di->dev, "Failed to finalize current measurement\n"); 218 return ret; 219 } 220 221 res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr); 222 223 dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n", 224 __func__, batctrl, res, inst_curr, i); 225 226 return res; 227 } 228 229 /** 230 * ab8500_btemp_id() - Identify the connected battery 231 * @di: pointer to the ab8500_btemp structure 232 * 233 * This function will try to identify the battery by reading the ID 234 * resistor. Some brands use a combined ID resistor with a NTC resistor to 235 * both be able to identify and to read the temperature of it. 236 */ 237 static int ab8500_btemp_id(struct ab8500_btemp *di) 238 { 239 struct power_supply_battery_info *bi = di->bm->bi; 240 int res; 241 242 di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; 243 244 res = ab8500_btemp_get_batctrl_res(di); 245 if (res < 0) { 246 dev_err(di->dev, "%s get batctrl res failed\n", __func__); 247 return -ENXIO; 248 } 249 250 if (power_supply_battery_bti_in_range(bi, res)) { 251 dev_info(di->dev, "Battery detected on BATCTRL (pin C3)" 252 " resistance %d Ohm = %d Ohm +/- %d%%\n", 253 res, bi->bti_resistance_ohm, 254 bi->bti_resistance_tolerance); 255 } else { 256 dev_warn(di->dev, "Battery identified as unknown" 257 ", resistance %d Ohm\n", res); 258 return -ENXIO; 259 } 260 261 return 0; 262 } 263 264 /** 265 * ab8500_btemp_periodic_work() - Measuring the temperature periodically 266 * @work: pointer to the work_struct structure 267 * 268 * Work function for measuring the temperature periodically 269 */ 270 static void ab8500_btemp_periodic_work(struct work_struct *work) 271 { 272 int interval; 273 int bat_temp; 274 struct ab8500_btemp *di = container_of(work, 275 struct ab8500_btemp, btemp_periodic_work.work); 276 /* Assume 25 degrees celsius as start temperature */ 277 static int prev = 25; 278 int ret; 279 280 if (!di->initialized) { 281 /* Identify the battery */ 282 if (ab8500_btemp_id(di) < 0) 283 dev_warn(di->dev, "failed to identify the battery\n"); 284 } 285 286 /* Failover if a reading is erroneous, use last meausurement */ 287 ret = thermal_zone_get_temp(di->tz, &bat_temp); 288 if (ret) { 289 dev_err(di->dev, "error reading temperature\n"); 290 bat_temp = prev; 291 } else { 292 /* Convert from millicentigrades to centigrades */ 293 bat_temp /= 1000; 294 prev = bat_temp; 295 } 296 297 /* 298 * Filter battery temperature. 299 * Allow direct updates on temperature only if two samples result in 300 * same temperature. Else only allow 1 degree change from previous 301 * reported value in the direction of the new measurement. 302 */ 303 if ((bat_temp == di->prev_bat_temp) || !di->initialized) { 304 if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) { 305 di->initialized = true; 306 di->bat_temp = bat_temp; 307 power_supply_changed(di->btemp_psy); 308 } 309 } else if (bat_temp < di->prev_bat_temp) { 310 di->bat_temp--; 311 power_supply_changed(di->btemp_psy); 312 } else if (bat_temp > di->prev_bat_temp) { 313 di->bat_temp++; 314 power_supply_changed(di->btemp_psy); 315 } 316 di->prev_bat_temp = bat_temp; 317 318 if (di->events.ac_conn || di->events.usb_conn) 319 interval = di->bm->temp_interval_chg; 320 else 321 interval = di->bm->temp_interval_nochg; 322 323 /* Schedule a new measurement */ 324 queue_delayed_work(di->btemp_wq, 325 &di->btemp_periodic_work, 326 round_jiffies(interval * HZ)); 327 } 328 329 /** 330 * ab8500_btemp_batctrlindb_handler() - battery removal detected 331 * @irq: interrupt number 332 * @_di: void pointer that has to address of ab8500_btemp 333 * 334 * Returns IRQ status(IRQ_HANDLED) 335 */ 336 static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di) 337 { 338 struct ab8500_btemp *di = _di; 339 dev_err(di->dev, "Battery removal detected!\n"); 340 341 di->events.batt_rem = true; 342 power_supply_changed(di->btemp_psy); 343 344 return IRQ_HANDLED; 345 } 346 347 /** 348 * ab8500_btemp_templow_handler() - battery temp lower than 10 degrees 349 * @irq: interrupt number 350 * @_di: void pointer that has to address of ab8500_btemp 351 * 352 * Returns IRQ status(IRQ_HANDLED) 353 */ 354 static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di) 355 { 356 struct ab8500_btemp *di = _di; 357 358 if (is_ab8500_3p3_or_earlier(di->parent)) { 359 dev_dbg(di->dev, "Ignore false btemp low irq" 360 " for ABB cut 1.0, 1.1, 2.0 and 3.3\n"); 361 } else { 362 dev_crit(di->dev, "Battery temperature lower than -10deg c\n"); 363 364 di->events.btemp_low = true; 365 di->events.btemp_high = false; 366 di->events.btemp_medhigh = false; 367 di->events.btemp_lowmed = false; 368 power_supply_changed(di->btemp_psy); 369 } 370 371 return IRQ_HANDLED; 372 } 373 374 /** 375 * ab8500_btemp_temphigh_handler() - battery temp higher than max temp 376 * @irq: interrupt number 377 * @_di: void pointer that has to address of ab8500_btemp 378 * 379 * Returns IRQ status(IRQ_HANDLED) 380 */ 381 static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di) 382 { 383 struct ab8500_btemp *di = _di; 384 385 dev_crit(di->dev, "Battery temperature is higher than MAX temp\n"); 386 387 di->events.btemp_high = true; 388 di->events.btemp_medhigh = false; 389 di->events.btemp_lowmed = false; 390 di->events.btemp_low = false; 391 power_supply_changed(di->btemp_psy); 392 393 return IRQ_HANDLED; 394 } 395 396 /** 397 * ab8500_btemp_lowmed_handler() - battery temp between low and medium 398 * @irq: interrupt number 399 * @_di: void pointer that has to address of ab8500_btemp 400 * 401 * Returns IRQ status(IRQ_HANDLED) 402 */ 403 static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di) 404 { 405 struct ab8500_btemp *di = _di; 406 407 dev_dbg(di->dev, "Battery temperature is between low and medium\n"); 408 409 di->events.btemp_lowmed = true; 410 di->events.btemp_medhigh = false; 411 di->events.btemp_high = false; 412 di->events.btemp_low = false; 413 power_supply_changed(di->btemp_psy); 414 415 return IRQ_HANDLED; 416 } 417 418 /** 419 * ab8500_btemp_medhigh_handler() - battery temp between medium and high 420 * @irq: interrupt number 421 * @_di: void pointer that has to address of ab8500_btemp 422 * 423 * Returns IRQ status(IRQ_HANDLED) 424 */ 425 static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di) 426 { 427 struct ab8500_btemp *di = _di; 428 429 dev_dbg(di->dev, "Battery temperature is between medium and high\n"); 430 431 di->events.btemp_medhigh = true; 432 di->events.btemp_lowmed = false; 433 di->events.btemp_high = false; 434 di->events.btemp_low = false; 435 power_supply_changed(di->btemp_psy); 436 437 return IRQ_HANDLED; 438 } 439 440 /** 441 * ab8500_btemp_periodic() - Periodic temperature measurements 442 * @di: pointer to the ab8500_btemp structure 443 * @enable: enable or disable periodic temperature measurements 444 * 445 * Starts of stops periodic temperature measurements. Periodic measurements 446 * should only be done when a charger is connected. 447 */ 448 static void ab8500_btemp_periodic(struct ab8500_btemp *di, 449 bool enable) 450 { 451 dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n", 452 enable); 453 /* 454 * Make sure a new measurement is done directly by cancelling 455 * any pending work 456 */ 457 cancel_delayed_work_sync(&di->btemp_periodic_work); 458 459 if (enable) 460 queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0); 461 } 462 463 /** 464 * ab8500_btemp_get_temp() - get battery temperature 465 * @di: pointer to the ab8500_btemp structure 466 * 467 * Returns battery temperature 468 */ 469 static int ab8500_btemp_get_temp(struct ab8500_btemp *di) 470 { 471 int temp = 0; 472 473 /* 474 * The BTEMP events are not reliabe on AB8500 cut3.3 475 * and prior versions 476 */ 477 if (is_ab8500_3p3_or_earlier(di->parent)) { 478 temp = di->bat_temp * 10; 479 } else { 480 if (di->events.btemp_low) { 481 if (temp > di->btemp_ranges.btemp_low_limit) 482 temp = di->btemp_ranges.btemp_low_limit * 10; 483 else 484 temp = di->bat_temp * 10; 485 } else if (di->events.btemp_high) { 486 if (temp < di->btemp_ranges.btemp_high_limit) 487 temp = di->btemp_ranges.btemp_high_limit * 10; 488 else 489 temp = di->bat_temp * 10; 490 } else if (di->events.btemp_lowmed) { 491 if (temp > di->btemp_ranges.btemp_med_limit) 492 temp = di->btemp_ranges.btemp_med_limit * 10; 493 else 494 temp = di->bat_temp * 10; 495 } else if (di->events.btemp_medhigh) { 496 if (temp < di->btemp_ranges.btemp_med_limit) 497 temp = di->btemp_ranges.btemp_med_limit * 10; 498 else 499 temp = di->bat_temp * 10; 500 } else 501 temp = di->bat_temp * 10; 502 } 503 return temp; 504 } 505 506 /** 507 * ab8500_btemp_get_property() - get the btemp properties 508 * @psy: pointer to the power_supply structure 509 * @psp: pointer to the power_supply_property structure 510 * @val: pointer to the power_supply_propval union 511 * 512 * This function gets called when an application tries to get the btemp 513 * properties by reading the sysfs files. 514 * online: presence of the battery 515 * present: presence of the battery 516 * technology: battery technology 517 * temp: battery temperature 518 * Returns error code in case of failure else 0(on success) 519 */ 520 static int ab8500_btemp_get_property(struct power_supply *psy, 521 enum power_supply_property psp, 522 union power_supply_propval *val) 523 { 524 struct ab8500_btemp *di = power_supply_get_drvdata(psy); 525 526 switch (psp) { 527 case POWER_SUPPLY_PROP_PRESENT: 528 case POWER_SUPPLY_PROP_ONLINE: 529 if (di->events.batt_rem) 530 val->intval = 0; 531 else 532 val->intval = 1; 533 break; 534 case POWER_SUPPLY_PROP_TEMP: 535 val->intval = ab8500_btemp_get_temp(di); 536 break; 537 default: 538 return -EINVAL; 539 } 540 return 0; 541 } 542 543 static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data) 544 { 545 struct power_supply *psy; 546 struct power_supply *ext = dev_get_drvdata(dev); 547 const char **supplicants = (const char **)ext->supplied_to; 548 struct ab8500_btemp *di; 549 union power_supply_propval ret; 550 int j; 551 552 psy = (struct power_supply *)data; 553 di = power_supply_get_drvdata(psy); 554 555 /* 556 * For all psy where the name of your driver 557 * appears in any supplied_to 558 */ 559 j = match_string(supplicants, ext->num_supplicants, psy->desc->name); 560 if (j < 0) 561 return 0; 562 563 /* Go through all properties for the psy */ 564 for (j = 0; j < ext->desc->num_properties; j++) { 565 enum power_supply_property prop; 566 prop = ext->desc->properties[j]; 567 568 if (power_supply_get_property(ext, prop, &ret)) 569 continue; 570 571 switch (prop) { 572 case POWER_SUPPLY_PROP_PRESENT: 573 switch (ext->desc->type) { 574 case POWER_SUPPLY_TYPE_MAINS: 575 /* AC disconnected */ 576 if (!ret.intval && di->events.ac_conn) { 577 di->events.ac_conn = false; 578 } 579 /* AC connected */ 580 else if (ret.intval && !di->events.ac_conn) { 581 di->events.ac_conn = true; 582 if (!di->events.usb_conn) 583 ab8500_btemp_periodic(di, true); 584 } 585 break; 586 case POWER_SUPPLY_TYPE_USB: 587 /* USB disconnected */ 588 if (!ret.intval && di->events.usb_conn) { 589 di->events.usb_conn = false; 590 } 591 /* USB connected */ 592 else if (ret.intval && !di->events.usb_conn) { 593 di->events.usb_conn = true; 594 if (!di->events.ac_conn) 595 ab8500_btemp_periodic(di, true); 596 } 597 break; 598 default: 599 break; 600 } 601 break; 602 default: 603 break; 604 } 605 } 606 return 0; 607 } 608 609 /** 610 * ab8500_btemp_external_power_changed() - callback for power supply changes 611 * @psy: pointer to the structure power_supply 612 * 613 * This function is pointing to the function pointer external_power_changed 614 * of the structure power_supply. 615 * This function gets executed when there is a change in the external power 616 * supply to the btemp. 617 */ 618 static void ab8500_btemp_external_power_changed(struct power_supply *psy) 619 { 620 class_for_each_device(power_supply_class, NULL, psy, 621 ab8500_btemp_get_ext_psy_data); 622 } 623 624 /* ab8500 btemp driver interrupts and their respective isr */ 625 static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = { 626 {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler}, 627 {"BTEMP_LOW", ab8500_btemp_templow_handler}, 628 {"BTEMP_HIGH", ab8500_btemp_temphigh_handler}, 629 {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler}, 630 {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler}, 631 }; 632 633 static int __maybe_unused ab8500_btemp_resume(struct device *dev) 634 { 635 struct ab8500_btemp *di = dev_get_drvdata(dev); 636 637 ab8500_btemp_periodic(di, true); 638 639 return 0; 640 } 641 642 static int __maybe_unused ab8500_btemp_suspend(struct device *dev) 643 { 644 struct ab8500_btemp *di = dev_get_drvdata(dev); 645 646 ab8500_btemp_periodic(di, false); 647 648 return 0; 649 } 650 651 static char *supply_interface[] = { 652 "ab8500_chargalg", 653 "ab8500_fg", 654 }; 655 656 static const struct power_supply_desc ab8500_btemp_desc = { 657 .name = "ab8500_btemp", 658 .type = POWER_SUPPLY_TYPE_UNKNOWN, 659 .properties = ab8500_btemp_props, 660 .num_properties = ARRAY_SIZE(ab8500_btemp_props), 661 .get_property = ab8500_btemp_get_property, 662 .external_power_changed = ab8500_btemp_external_power_changed, 663 }; 664 665 static int ab8500_btemp_bind(struct device *dev, struct device *master, 666 void *data) 667 { 668 struct ab8500_btemp *di = dev_get_drvdata(dev); 669 670 /* Create a work queue for the btemp */ 671 di->btemp_wq = 672 alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); 673 if (di->btemp_wq == NULL) { 674 dev_err(dev, "failed to create work queue\n"); 675 return -ENOMEM; 676 } 677 678 /* Kick off periodic temperature measurements */ 679 ab8500_btemp_periodic(di, true); 680 681 return 0; 682 } 683 684 static void ab8500_btemp_unbind(struct device *dev, struct device *master, 685 void *data) 686 { 687 struct ab8500_btemp *di = dev_get_drvdata(dev); 688 689 /* Delete the work queue */ 690 destroy_workqueue(di->btemp_wq); 691 } 692 693 static const struct component_ops ab8500_btemp_component_ops = { 694 .bind = ab8500_btemp_bind, 695 .unbind = ab8500_btemp_unbind, 696 }; 697 698 static int ab8500_btemp_probe(struct platform_device *pdev) 699 { 700 struct power_supply_config psy_cfg = {}; 701 struct device *dev = &pdev->dev; 702 struct ab8500_btemp *di; 703 int irq, i, ret = 0; 704 u8 val; 705 706 di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); 707 if (!di) 708 return -ENOMEM; 709 710 di->bm = &ab8500_bm_data; 711 712 /* get parent data */ 713 di->dev = dev; 714 di->parent = dev_get_drvdata(pdev->dev.parent); 715 716 /* Get thermal zone and ADC */ 717 di->tz = thermal_zone_get_zone_by_name("battery-thermal"); 718 if (IS_ERR(di->tz)) { 719 ret = PTR_ERR(di->tz); 720 /* 721 * This usually just means we are probing before the thermal 722 * zone, so just defer. 723 */ 724 if (ret == -ENODEV) 725 ret = -EPROBE_DEFER; 726 return dev_err_probe(dev, ret, 727 "failed to get battery thermal zone\n"); 728 } 729 di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl"); 730 if (IS_ERR(di->bat_ctrl)) { 731 ret = dev_err_probe(dev, PTR_ERR(di->bat_ctrl), 732 "failed to get BAT CTRL ADC channel\n"); 733 return ret; 734 } 735 736 di->initialized = false; 737 738 psy_cfg.supplied_to = supply_interface; 739 psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); 740 psy_cfg.drv_data = di; 741 742 /* Init work for measuring temperature periodically */ 743 INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, 744 ab8500_btemp_periodic_work); 745 746 /* Set BTEMP thermal limits. Low and Med are fixed */ 747 di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; 748 di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; 749 750 ret = abx500_get_register_interruptible(dev, AB8500_CHARGER, 751 AB8500_BTEMP_HIGH_TH, &val); 752 if (ret < 0) { 753 dev_err(dev, "%s ab8500 read failed\n", __func__); 754 return ret; 755 } 756 switch (val) { 757 case BTEMP_HIGH_TH_57_0: 758 case BTEMP_HIGH_TH_57_1: 759 di->btemp_ranges.btemp_high_limit = 760 BTEMP_THERMAL_HIGH_LIMIT_57; 761 break; 762 case BTEMP_HIGH_TH_52: 763 di->btemp_ranges.btemp_high_limit = 764 BTEMP_THERMAL_HIGH_LIMIT_52; 765 break; 766 case BTEMP_HIGH_TH_62: 767 di->btemp_ranges.btemp_high_limit = 768 BTEMP_THERMAL_HIGH_LIMIT_62; 769 break; 770 } 771 772 /* Register BTEMP power supply class */ 773 di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, 774 &psy_cfg); 775 if (IS_ERR(di->btemp_psy)) { 776 dev_err(dev, "failed to register BTEMP psy\n"); 777 return PTR_ERR(di->btemp_psy); 778 } 779 780 /* Register interrupts */ 781 for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { 782 irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); 783 if (irq < 0) 784 return irq; 785 786 ret = devm_request_threaded_irq(dev, irq, NULL, 787 ab8500_btemp_irq[i].isr, 788 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 789 ab8500_btemp_irq[i].name, di); 790 791 if (ret) { 792 dev_err(dev, "failed to request %s IRQ %d: %d\n" 793 , ab8500_btemp_irq[i].name, irq, ret); 794 return ret; 795 } 796 dev_dbg(dev, "Requested %s IRQ %d: %d\n", 797 ab8500_btemp_irq[i].name, irq, ret); 798 } 799 800 platform_set_drvdata(pdev, di); 801 802 list_add_tail(&di->node, &ab8500_btemp_list); 803 804 return component_add(dev, &ab8500_btemp_component_ops); 805 } 806 807 static int ab8500_btemp_remove(struct platform_device *pdev) 808 { 809 component_del(&pdev->dev, &ab8500_btemp_component_ops); 810 811 return 0; 812 } 813 814 static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume); 815 816 static const struct of_device_id ab8500_btemp_match[] = { 817 { .compatible = "stericsson,ab8500-btemp", }, 818 { }, 819 }; 820 MODULE_DEVICE_TABLE(of, ab8500_btemp_match); 821 822 struct platform_driver ab8500_btemp_driver = { 823 .probe = ab8500_btemp_probe, 824 .remove = ab8500_btemp_remove, 825 .driver = { 826 .name = "ab8500-btemp", 827 .of_match_table = ab8500_btemp_match, 828 .pm = &ab8500_btemp_pm_ops, 829 }, 830 }; 831 MODULE_LICENSE("GPL v2"); 832 MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); 833 MODULE_ALIAS("platform:ab8500-btemp"); 834 MODULE_DESCRIPTION("AB8500 battery temperature driver"); 835