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 power_supply_for_each_device(psy, ab8500_btemp_get_ext_psy_data); 621 } 622 623 /* ab8500 btemp driver interrupts and their respective isr */ 624 static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = { 625 {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler}, 626 {"BTEMP_LOW", ab8500_btemp_templow_handler}, 627 {"BTEMP_HIGH", ab8500_btemp_temphigh_handler}, 628 {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler}, 629 {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler}, 630 }; 631 632 static int __maybe_unused ab8500_btemp_resume(struct device *dev) 633 { 634 struct ab8500_btemp *di = dev_get_drvdata(dev); 635 636 ab8500_btemp_periodic(di, true); 637 638 return 0; 639 } 640 641 static int __maybe_unused ab8500_btemp_suspend(struct device *dev) 642 { 643 struct ab8500_btemp *di = dev_get_drvdata(dev); 644 645 ab8500_btemp_periodic(di, false); 646 647 return 0; 648 } 649 650 static char *supply_interface[] = { 651 "ab8500_chargalg", 652 "ab8500_fg", 653 }; 654 655 static const struct power_supply_desc ab8500_btemp_desc = { 656 .name = "ab8500_btemp", 657 .type = POWER_SUPPLY_TYPE_UNKNOWN, 658 .properties = ab8500_btemp_props, 659 .num_properties = ARRAY_SIZE(ab8500_btemp_props), 660 .get_property = ab8500_btemp_get_property, 661 .external_power_changed = ab8500_btemp_external_power_changed, 662 }; 663 664 static int ab8500_btemp_bind(struct device *dev, struct device *master, 665 void *data) 666 { 667 struct ab8500_btemp *di = dev_get_drvdata(dev); 668 669 /* Create a work queue for the btemp */ 670 di->btemp_wq = 671 alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); 672 if (di->btemp_wq == NULL) { 673 dev_err(dev, "failed to create work queue\n"); 674 return -ENOMEM; 675 } 676 677 /* Kick off periodic temperature measurements */ 678 ab8500_btemp_periodic(di, true); 679 680 return 0; 681 } 682 683 static void ab8500_btemp_unbind(struct device *dev, struct device *master, 684 void *data) 685 { 686 struct ab8500_btemp *di = dev_get_drvdata(dev); 687 688 /* Delete the work queue */ 689 destroy_workqueue(di->btemp_wq); 690 } 691 692 static const struct component_ops ab8500_btemp_component_ops = { 693 .bind = ab8500_btemp_bind, 694 .unbind = ab8500_btemp_unbind, 695 }; 696 697 static int ab8500_btemp_probe(struct platform_device *pdev) 698 { 699 struct power_supply_config psy_cfg = {}; 700 struct device *dev = &pdev->dev; 701 struct ab8500_btemp *di; 702 int irq, i, ret = 0; 703 u8 val; 704 705 di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); 706 if (!di) 707 return -ENOMEM; 708 709 di->bm = &ab8500_bm_data; 710 711 /* get parent data */ 712 di->dev = dev; 713 di->parent = dev_get_drvdata(pdev->dev.parent); 714 715 /* Get thermal zone and ADC */ 716 di->tz = thermal_zone_get_zone_by_name("battery-thermal"); 717 if (IS_ERR(di->tz)) { 718 ret = PTR_ERR(di->tz); 719 /* 720 * This usually just means we are probing before the thermal 721 * zone, so just defer. 722 */ 723 if (ret == -ENODEV) 724 ret = -EPROBE_DEFER; 725 return dev_err_probe(dev, ret, 726 "failed to get battery thermal zone\n"); 727 } 728 di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl"); 729 if (IS_ERR(di->bat_ctrl)) { 730 ret = dev_err_probe(dev, PTR_ERR(di->bat_ctrl), 731 "failed to get BAT CTRL ADC channel\n"); 732 return ret; 733 } 734 735 di->initialized = false; 736 737 psy_cfg.supplied_to = supply_interface; 738 psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); 739 psy_cfg.drv_data = di; 740 741 /* Init work for measuring temperature periodically */ 742 INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, 743 ab8500_btemp_periodic_work); 744 745 /* Set BTEMP thermal limits. Low and Med are fixed */ 746 di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; 747 di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; 748 749 ret = abx500_get_register_interruptible(dev, AB8500_CHARGER, 750 AB8500_BTEMP_HIGH_TH, &val); 751 if (ret < 0) { 752 dev_err(dev, "%s ab8500 read failed\n", __func__); 753 return ret; 754 } 755 switch (val) { 756 case BTEMP_HIGH_TH_57_0: 757 case BTEMP_HIGH_TH_57_1: 758 di->btemp_ranges.btemp_high_limit = 759 BTEMP_THERMAL_HIGH_LIMIT_57; 760 break; 761 case BTEMP_HIGH_TH_52: 762 di->btemp_ranges.btemp_high_limit = 763 BTEMP_THERMAL_HIGH_LIMIT_52; 764 break; 765 case BTEMP_HIGH_TH_62: 766 di->btemp_ranges.btemp_high_limit = 767 BTEMP_THERMAL_HIGH_LIMIT_62; 768 break; 769 } 770 771 /* Register BTEMP power supply class */ 772 di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, 773 &psy_cfg); 774 if (IS_ERR(di->btemp_psy)) { 775 dev_err(dev, "failed to register BTEMP psy\n"); 776 return PTR_ERR(di->btemp_psy); 777 } 778 779 /* Register interrupts */ 780 for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { 781 irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); 782 if (irq < 0) 783 return irq; 784 785 ret = devm_request_threaded_irq(dev, irq, NULL, 786 ab8500_btemp_irq[i].isr, 787 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 788 ab8500_btemp_irq[i].name, di); 789 790 if (ret) { 791 dev_err(dev, "failed to request %s IRQ %d: %d\n" 792 , ab8500_btemp_irq[i].name, irq, ret); 793 return ret; 794 } 795 dev_dbg(dev, "Requested %s IRQ %d: %d\n", 796 ab8500_btemp_irq[i].name, irq, ret); 797 } 798 799 platform_set_drvdata(pdev, di); 800 801 list_add_tail(&di->node, &ab8500_btemp_list); 802 803 return component_add(dev, &ab8500_btemp_component_ops); 804 } 805 806 static void ab8500_btemp_remove(struct platform_device *pdev) 807 { 808 component_del(&pdev->dev, &ab8500_btemp_component_ops); 809 } 810 811 static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume); 812 813 static const struct of_device_id ab8500_btemp_match[] = { 814 { .compatible = "stericsson,ab8500-btemp", }, 815 { }, 816 }; 817 MODULE_DEVICE_TABLE(of, ab8500_btemp_match); 818 819 struct platform_driver ab8500_btemp_driver = { 820 .probe = ab8500_btemp_probe, 821 .remove_new = ab8500_btemp_remove, 822 .driver = { 823 .name = "ab8500-btemp", 824 .of_match_table = ab8500_btemp_match, 825 .pm = &ab8500_btemp_pm_ops, 826 }, 827 }; 828 MODULE_LICENSE("GPL v2"); 829 MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); 830 MODULE_ALIAS("platform:ab8500-btemp"); 831 MODULE_DESCRIPTION("AB8500 battery temperature driver"); 832