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 measurement */ 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 power_supply *ext, void *data) 544 { 545 struct power_supply *psy; 546 const char **supplicants = (const char **)ext->supplied_to; 547 struct ab8500_btemp *di; 548 union power_supply_propval ret; 549 int j; 550 551 psy = (struct power_supply *)data; 552 di = power_supply_get_drvdata(psy); 553 554 /* 555 * For all psy where the name of your driver 556 * appears in any supplied_to 557 */ 558 j = match_string(supplicants, ext->num_supplicants, psy->desc->name); 559 if (j < 0) 560 return 0; 561 562 /* Go through all properties for the psy */ 563 for (j = 0; j < ext->desc->num_properties; j++) { 564 enum power_supply_property prop; 565 prop = ext->desc->properties[j]; 566 567 if (power_supply_get_property(ext, prop, &ret)) 568 continue; 569 570 switch (prop) { 571 case POWER_SUPPLY_PROP_PRESENT: 572 switch (ext->desc->type) { 573 case POWER_SUPPLY_TYPE_MAINS: 574 /* AC disconnected */ 575 if (!ret.intval && di->events.ac_conn) { 576 di->events.ac_conn = false; 577 } 578 /* AC connected */ 579 else if (ret.intval && !di->events.ac_conn) { 580 di->events.ac_conn = true; 581 if (!di->events.usb_conn) 582 ab8500_btemp_periodic(di, true); 583 } 584 break; 585 case POWER_SUPPLY_TYPE_USB: 586 /* USB disconnected */ 587 if (!ret.intval && di->events.usb_conn) { 588 di->events.usb_conn = false; 589 } 590 /* USB connected */ 591 else if (ret.intval && !di->events.usb_conn) { 592 di->events.usb_conn = true; 593 if (!di->events.ac_conn) 594 ab8500_btemp_periodic(di, true); 595 } 596 break; 597 default: 598 break; 599 } 600 break; 601 default: 602 break; 603 } 604 } 605 return 0; 606 } 607 608 /** 609 * ab8500_btemp_external_power_changed() - callback for power supply changes 610 * @psy: pointer to the structure power_supply 611 * 612 * This function is pointing to the function pointer external_power_changed 613 * of the structure power_supply. 614 * This function gets executed when there is a change in the external power 615 * supply to the btemp. 616 */ 617 static void ab8500_btemp_external_power_changed(struct power_supply *psy) 618 { 619 power_supply_for_each_psy(psy, ab8500_btemp_get_ext_psy_data); 620 } 621 622 /* ab8500 btemp driver interrupts and their respective isr */ 623 static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = { 624 {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler}, 625 {"BTEMP_LOW", ab8500_btemp_templow_handler}, 626 {"BTEMP_HIGH", ab8500_btemp_temphigh_handler}, 627 {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler}, 628 {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler}, 629 }; 630 631 static int __maybe_unused ab8500_btemp_resume(struct device *dev) 632 { 633 struct ab8500_btemp *di = dev_get_drvdata(dev); 634 635 ab8500_btemp_periodic(di, true); 636 637 return 0; 638 } 639 640 static int __maybe_unused ab8500_btemp_suspend(struct device *dev) 641 { 642 struct ab8500_btemp *di = dev_get_drvdata(dev); 643 644 ab8500_btemp_periodic(di, false); 645 646 return 0; 647 } 648 649 static char *supply_interface[] = { 650 "ab8500_chargalg", 651 "ab8500_fg", 652 }; 653 654 static const struct power_supply_desc ab8500_btemp_desc = { 655 .name = "ab8500_btemp", 656 .type = POWER_SUPPLY_TYPE_UNKNOWN, 657 .properties = ab8500_btemp_props, 658 .num_properties = ARRAY_SIZE(ab8500_btemp_props), 659 .get_property = ab8500_btemp_get_property, 660 .external_power_changed = ab8500_btemp_external_power_changed, 661 }; 662 663 static int ab8500_btemp_bind(struct device *dev, struct device *master, 664 void *data) 665 { 666 struct ab8500_btemp *di = dev_get_drvdata(dev); 667 668 /* Create a work queue for the btemp */ 669 di->btemp_wq = 670 alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); 671 if (di->btemp_wq == NULL) { 672 dev_err(dev, "failed to create work queue\n"); 673 return -ENOMEM; 674 } 675 676 /* Kick off periodic temperature measurements */ 677 ab8500_btemp_periodic(di, true); 678 679 return 0; 680 } 681 682 static void ab8500_btemp_unbind(struct device *dev, struct device *master, 683 void *data) 684 { 685 struct ab8500_btemp *di = dev_get_drvdata(dev); 686 687 /* Delete the work queue */ 688 destroy_workqueue(di->btemp_wq); 689 } 690 691 static const struct component_ops ab8500_btemp_component_ops = { 692 .bind = ab8500_btemp_bind, 693 .unbind = ab8500_btemp_unbind, 694 }; 695 696 static int ab8500_btemp_probe(struct platform_device *pdev) 697 { 698 struct power_supply_config psy_cfg = {}; 699 struct device *dev = &pdev->dev; 700 struct ab8500_btemp *di; 701 int irq, i, ret = 0; 702 u8 val; 703 704 di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); 705 if (!di) 706 return -ENOMEM; 707 708 di->bm = &ab8500_bm_data; 709 710 /* get parent data */ 711 di->dev = dev; 712 di->parent = dev_get_drvdata(pdev->dev.parent); 713 714 /* Get thermal zone and ADC */ 715 di->tz = thermal_zone_get_zone_by_name("battery-thermal"); 716 if (IS_ERR(di->tz)) { 717 ret = PTR_ERR(di->tz); 718 /* 719 * This usually just means we are probing before the thermal 720 * zone, so just defer. 721 */ 722 if (ret == -ENODEV) 723 ret = -EPROBE_DEFER; 724 return dev_err_probe(dev, ret, 725 "failed to get battery thermal zone\n"); 726 } 727 di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl"); 728 if (IS_ERR(di->bat_ctrl)) { 729 ret = dev_err_probe(dev, PTR_ERR(di->bat_ctrl), 730 "failed to get BAT CTRL ADC channel\n"); 731 return ret; 732 } 733 734 di->initialized = false; 735 736 psy_cfg.supplied_to = supply_interface; 737 psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); 738 psy_cfg.drv_data = di; 739 740 /* Init work for measuring temperature periodically */ 741 INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, 742 ab8500_btemp_periodic_work); 743 744 /* Set BTEMP thermal limits. Low and Med are fixed */ 745 di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; 746 di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; 747 748 ret = abx500_get_register_interruptible(dev, AB8500_CHARGER, 749 AB8500_BTEMP_HIGH_TH, &val); 750 if (ret < 0) { 751 dev_err(dev, "%s ab8500 read failed\n", __func__); 752 return ret; 753 } 754 switch (val) { 755 case BTEMP_HIGH_TH_57_0: 756 case BTEMP_HIGH_TH_57_1: 757 di->btemp_ranges.btemp_high_limit = 758 BTEMP_THERMAL_HIGH_LIMIT_57; 759 break; 760 case BTEMP_HIGH_TH_52: 761 di->btemp_ranges.btemp_high_limit = 762 BTEMP_THERMAL_HIGH_LIMIT_52; 763 break; 764 case BTEMP_HIGH_TH_62: 765 di->btemp_ranges.btemp_high_limit = 766 BTEMP_THERMAL_HIGH_LIMIT_62; 767 break; 768 } 769 770 /* Register BTEMP power supply class */ 771 di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, 772 &psy_cfg); 773 if (IS_ERR(di->btemp_psy)) { 774 dev_err(dev, "failed to register BTEMP psy\n"); 775 return PTR_ERR(di->btemp_psy); 776 } 777 778 /* Register interrupts */ 779 for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { 780 irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); 781 if (irq < 0) 782 return irq; 783 784 ret = devm_request_threaded_irq(dev, irq, NULL, 785 ab8500_btemp_irq[i].isr, 786 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 787 ab8500_btemp_irq[i].name, di); 788 789 if (ret) { 790 dev_err(dev, "failed to request %s IRQ %d: %d\n" 791 , ab8500_btemp_irq[i].name, irq, ret); 792 return ret; 793 } 794 dev_dbg(dev, "Requested %s IRQ %d: %d\n", 795 ab8500_btemp_irq[i].name, irq, ret); 796 } 797 798 platform_set_drvdata(pdev, di); 799 800 list_add_tail(&di->node, &ab8500_btemp_list); 801 802 return component_add(dev, &ab8500_btemp_component_ops); 803 } 804 805 static void ab8500_btemp_remove(struct platform_device *pdev) 806 { 807 component_del(&pdev->dev, &ab8500_btemp_component_ops); 808 } 809 810 static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume); 811 812 static const struct of_device_id ab8500_btemp_match[] = { 813 { .compatible = "stericsson,ab8500-btemp", }, 814 { }, 815 }; 816 MODULE_DEVICE_TABLE(of, ab8500_btemp_match); 817 818 struct platform_driver ab8500_btemp_driver = { 819 .probe = ab8500_btemp_probe, 820 .remove = ab8500_btemp_remove, 821 .driver = { 822 .name = "ab8500-btemp", 823 .of_match_table = ab8500_btemp_match, 824 .pm = &ab8500_btemp_pm_ops, 825 }, 826 }; 827 MODULE_LICENSE("GPL v2"); 828 MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); 829 MODULE_ALIAS("platform:ab8500-btemp"); 830 MODULE_DESCRIPTION("AB8500 battery temperature driver"); 831