Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ab8500_btemp.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) ST-Ericsson SA 2012
3  *
4  * Battery temperature driver for AB8500
5  *
6  * License Terms: GNU General Public License v2
7  * Author:
8  * Johan Palsson <[email protected]>
9  * Karl Komierowski <[email protected]>
10  * Arun R Murthy <[email protected]>
11  */
12 
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/interrupt.h>
17 #include <linux/delay.h>
18 #include <linux/slab.h>
19 #include <linux/platform_device.h>
20 #include <linux/power_supply.h>
21 #include <linux/completion.h>
22 #include <linux/workqueue.h>
24 #include <linux/mfd/abx500.h>
27 #include <linux/jiffies.h>
28 
29 #define VTVOUT_V 1800
30 
31 #define BTEMP_THERMAL_LOW_LIMIT -10
32 #define BTEMP_THERMAL_MED_LIMIT 0
33 #define BTEMP_THERMAL_HIGH_LIMIT_52 52
34 #define BTEMP_THERMAL_HIGH_LIMIT_57 57
35 #define BTEMP_THERMAL_HIGH_LIMIT_62 62
36 
37 #define BTEMP_BATCTRL_CURR_SRC_7UA 7
38 #define BTEMP_BATCTRL_CURR_SRC_20UA 20
39 
40 #define to_ab8500_btemp_device_info(x) container_of((x), \
41  struct ab8500_btemp, btemp_psy);
42 
49  char *name;
50  irqreturn_t (*isr)(int irq, void *data);
51 };
52 
54  bool batt_rem;
55  bool btemp_high;
58  bool btemp_low;
59  bool ac_conn;
60  bool usb_conn;
61 };
62 
67 };
68 
87 struct ab8500_btemp {
88  struct device *dev;
89  struct list_head node;
91  int bat_temp;
93  struct ab8500 *parent;
95  struct ab8500_fg *fg;
103 };
104 
105 /* BTEMP power supply properties */
106 static enum power_supply_property ab8500_btemp_props[] = {
111 };
112 
113 static LIST_HEAD(ab8500_btemp_list);
114 
120 {
121  struct ab8500_btemp *btemp;
122  btemp = list_first_entry(&ab8500_btemp_list, struct ab8500_btemp, node);
123 
124  return btemp;
125 }
126 
137 static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,
138  int v_batctrl, int inst_curr)
139 {
140  int rbs;
141 
142  if (is_ab8500_1p1_or_earlier(di->parent)) {
143  /*
144  * For ABB cut1.0 and 1.1 BAT_CTRL is internally
145  * connected to 1.8V through a 450k resistor
146  */
147  return (450000 * (v_batctrl)) / (1800 - v_batctrl);
148  }
149 
150  if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL) {
151  /*
152  * If the battery has internal NTC, we use the current
153  * source to calculate the resistance, 7uA or 20uA
154  */
155  rbs = (v_batctrl * 1000
156  - di->bat->gnd_lift_resistance * inst_curr)
157  / di->curr_source;
158  } else {
159  /*
160  * BAT_CTRL is internally
161  * connected to 1.8V through a 80k resistor
162  */
163  rbs = (80000 * (v_batctrl)) / (1800 - v_batctrl);
164  }
165 
166  return rbs;
167 }
168 
175 static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di)
176 {
177  int vbtemp;
178  static int prev;
179 
180  vbtemp = ab8500_gpadc_convert(di->gpadc, BAT_CTRL);
181  if (vbtemp < 0) {
182  dev_err(di->dev,
183  "%s gpadc conversion failed, using previous value",
184  __func__);
185  return prev;
186  }
187  prev = vbtemp;
188  return vbtemp;
189 }
190 
198 static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
199  bool enable)
200 {
201  int curr;
202  int ret = 0;
203 
204  /*
205  * BATCTRL current sources are included on AB8500 cut2.0
206  * and future versions
207  */
208  if (is_ab8500_1p1_or_earlier(di->parent))
209  return 0;
210 
211  /* Only do this for batteries with internal NTC */
212  if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) {
214  curr = BAT_CTRL_7U_ENA;
215  else
216  curr = BAT_CTRL_20U_ENA;
217 
218  dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source);
219 
223  if (ret) {
224  dev_err(di->dev, "%s failed setting cmp_force\n",
225  __func__);
226  return ret;
227  }
228 
229  /*
230  * We have to wait one 32kHz cycle before enabling
231  * the current source, since ForceBatCtrlCmpHigh needs
232  * to be written in a separate cycle
233  */
234  udelay(32);
235 
238  FORCE_BAT_CTRL_CMP_HIGH | curr);
239  if (ret) {
240  dev_err(di->dev, "%s failed enabling current source\n",
241  __func__);
242  goto disable_curr_source;
243  }
244  } else if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) {
245  dev_dbg(di->dev, "Disable BATCTRL curr source\n");
246 
247  /* Write 0 to the curr bits */
252  if (ret) {
253  dev_err(di->dev, "%s failed disabling current source\n",
254  __func__);
255  goto disable_curr_source;
256  }
257 
258  /* Enable Pull-Up and comparator */
263  if (ret) {
264  dev_err(di->dev, "%s failed enabling PU and comp\n",
265  __func__);
266  goto enable_pu_comp;
267  }
268 
269  /*
270  * We have to wait one 32kHz cycle before disabling
271  * ForceBatCtrlCmpHigh since this needs to be written
272  * in a separate cycle
273  */
274  udelay(32);
275 
276  /* Disable 'force comparator' */
280  if (ret) {
281  dev_err(di->dev, "%s failed disabling force comp\n",
282  __func__);
283  goto disable_force_comp;
284  }
285  }
286  return ret;
287 
288  /*
289  * We have to try unsetting FORCE_BAT_CTRL_CMP_HIGH one more time
290  * if we got an error above
291  */
292 disable_curr_source:
293  /* Write 0 to the curr bits */
298  if (ret) {
299  dev_err(di->dev, "%s failed disabling current source\n",
300  __func__);
301  return ret;
302  }
303 enable_pu_comp:
304  /* Enable Pull-Up and comparator */
309  if (ret) {
310  dev_err(di->dev, "%s failed enabling PU and comp\n",
311  __func__);
312  return ret;
313  }
314 
315 disable_force_comp:
316  /*
317  * We have to wait one 32kHz cycle before disabling
318  * ForceBatCtrlCmpHigh since this needs to be written
319  * in a separate cycle
320  */
321  udelay(32);
322 
323  /* Disable 'force comparator' */
327  if (ret) {
328  dev_err(di->dev, "%s failed disabling force comp\n",
329  __func__);
330  return ret;
331  }
332 
333  return ret;
334 }
335 
343 static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di)
344 {
345  int ret;
346  int batctrl = 0;
347  int res;
348  int inst_curr;
349  int i;
350 
351  /*
352  * BATCTRL current sources are included on AB8500 cut2.0
353  * and future versions
354  */
355  ret = ab8500_btemp_curr_source_enable(di, true);
356  if (ret) {
357  dev_err(di->dev, "%s curr source enabled failed\n", __func__);
358  return ret;
359  }
360 
361  if (!di->fg)
362  di->fg = ab8500_fg_get();
363  if (!di->fg) {
364  dev_err(di->dev, "No fg found\n");
365  return -EINVAL;
366  }
367 
368  ret = ab8500_fg_inst_curr_start(di->fg);
369 
370  if (ret) {
371  dev_err(di->dev, "Failed to start current measurement\n");
372  return ret;
373  }
374 
375  /*
376  * Since there is no interrupt when current measurement is done,
377  * loop for over 250ms (250ms is one sample conversion time
378  * with 32.768 Khz RTC clock). Note that a stop time must be set
379  * since the ab8500_btemp_read_batctrl_voltage call can block and
380  * take an unknown amount of time to complete.
381  */
382  i = 0;
383 
384  do {
385  batctrl += ab8500_btemp_read_batctrl_voltage(di);
386  i++;
387  msleep(20);
388  } while (!ab8500_fg_inst_curr_done(di->fg));
389  batctrl /= i;
390 
391  ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr);
392  if (ret) {
393  dev_err(di->dev, "Failed to finalize current measurement\n");
394  return ret;
395  }
396 
397  res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr);
398 
399  ret = ab8500_btemp_curr_source_enable(di, false);
400  if (ret) {
401  dev_err(di->dev, "%s curr source disable failed\n", __func__);
402  return ret;
403  }
404 
405  dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n",
406  __func__, batctrl, res, inst_curr, i);
407 
408  return res;
409 }
410 
421 static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di,
422  const struct abx500_res_to_temp *tbl, int tbl_size, int res)
423 {
424  int i, temp;
425  /*
426  * Calculate the formula for the straight line
427  * Simple interpolation if we are within
428  * the resistance table limits, extrapolate
429  * if resistance is outside the limits.
430  */
431  if (res > tbl[0].resist)
432  i = 0;
433  else if (res <= tbl[tbl_size - 1].resist)
434  i = tbl_size - 2;
435  else {
436  i = 0;
437  while (!(res <= tbl[i].resist &&
438  res > tbl[i + 1].resist))
439  i++;
440  }
441 
442  temp = tbl[i].temp + ((tbl[i + 1].temp - tbl[i].temp) *
443  (res - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist);
444  return temp;
445 }
446 
453 static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
454 {
455  int temp;
456  static int prev;
457  int rbat, rntc, vntc;
458  u8 id;
459 
460  id = di->bat->batt_id;
461 
462  if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL &&
463  id != BATTERY_UNKNOWN) {
464 
465  rbat = ab8500_btemp_get_batctrl_res(di);
466  if (rbat < 0) {
467  dev_err(di->dev, "%s get batctrl res failed\n",
468  __func__);
469  /*
470  * Return out-of-range temperature so that
471  * charging is stopped
472  */
474  }
475 
476  temp = ab8500_btemp_res_to_temp(di,
477  di->bat->bat_type[id].r_to_t_tbl,
478  di->bat->bat_type[id].n_temp_tbl_elements, rbat);
479  } else {
481  if (vntc < 0) {
482  dev_err(di->dev,
483  "%s gpadc conversion failed,"
484  " using previous value\n", __func__);
485  return prev;
486  }
487  /*
488  * The PCB NTC is sourced from VTVOUT via a 230kOhm
489  * resistor.
490  */
491  rntc = 230000 * vntc / (VTVOUT_V - vntc);
492 
493  temp = ab8500_btemp_res_to_temp(di,
494  di->bat->bat_type[id].r_to_t_tbl,
495  di->bat->bat_type[id].n_temp_tbl_elements, rntc);
496  prev = temp;
497  }
498  dev_dbg(di->dev, "Battery temperature is %d\n", temp);
499  return temp;
500 }
501 
510 static int ab8500_btemp_id(struct ab8500_btemp *di)
511 {
512  int res;
513  u8 i;
514 
516  di->bat->batt_id = BATTERY_UNKNOWN;
517 
518  res = ab8500_btemp_get_batctrl_res(di);
519  if (res < 0) {
520  dev_err(di->dev, "%s get batctrl res failed\n", __func__);
521  return -ENXIO;
522  }
523 
524  /* BATTERY_UNKNOWN is defined on position 0, skip it! */
525  for (i = BATTERY_UNKNOWN + 1; i < di->bat->n_btypes; i++) {
526  if ((res <= di->bat->bat_type[i].resis_high) &&
527  (res >= di->bat->bat_type[i].resis_low)) {
528  dev_dbg(di->dev, "Battery detected on %s"
529  " low %d < res %d < high: %d"
530  " index: %d\n",
531  di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL ?
532  "BATCTRL" : "BATTEMP",
533  di->bat->bat_type[i].resis_low, res,
534  di->bat->bat_type[i].resis_high, i);
535 
536  di->bat->batt_id = i;
537  break;
538  }
539  }
540 
541  if (di->bat->batt_id == BATTERY_UNKNOWN) {
542  dev_warn(di->dev, "Battery identified as unknown"
543  ", resistance %d Ohm\n", res);
544  return -ENXIO;
545  }
546 
547  /*
548  * We only have to change current source if the
549  * detected type is Type 1, else we use the 7uA source
550  */
551  if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL &&
552  di->bat->batt_id == 1) {
553  dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n");
555  }
556 
557  return di->bat->batt_id;
558 }
559 
566 static void ab8500_btemp_periodic_work(struct work_struct *work)
567 {
568  int interval;
569  struct ab8500_btemp *di = container_of(work,
570  struct ab8500_btemp, btemp_periodic_work.work);
571 
572  di->bat_temp = ab8500_btemp_measure_temp(di);
573 
574  if (di->bat_temp != di->prev_bat_temp) {
575  di->prev_bat_temp = di->bat_temp;
577  }
578 
579  if (di->events.ac_conn || di->events.usb_conn)
580  interval = di->bat->temp_interval_chg;
581  else
582  interval = di->bat->temp_interval_nochg;
583 
584  /* Schedule a new measurement */
586  &di->btemp_periodic_work,
587  round_jiffies(interval * HZ));
588 }
589 
597 static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di)
598 {
599  struct ab8500_btemp *di = _di;
600  dev_err(di->dev, "Battery removal detected!\n");
601 
602  di->events.batt_rem = true;
604 
605  return IRQ_HANDLED;
606 }
607 
615 static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di)
616 {
617  struct ab8500_btemp *di = _di;
618 
619  if (is_ab8500_2p0_or_earlier(di->parent)) {
620  dev_dbg(di->dev, "Ignore false btemp low irq"
621  " for ABB cut 1.0, 1.1 and 2.0\n");
622  } else {
623  dev_crit(di->dev, "Battery temperature lower than -10deg c\n");
624 
625  di->events.btemp_low = true;
626  di->events.btemp_high = false;
627  di->events.btemp_medhigh = false;
628  di->events.btemp_lowmed = false;
630  }
631 
632  return IRQ_HANDLED;
633 }
634 
642 static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di)
643 {
644  struct ab8500_btemp *di = _di;
645 
646  dev_crit(di->dev, "Battery temperature is higher than MAX temp\n");
647 
648  di->events.btemp_high = true;
649  di->events.btemp_medhigh = false;
650  di->events.btemp_lowmed = false;
651  di->events.btemp_low = false;
653 
654  return IRQ_HANDLED;
655 }
656 
664 static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di)
665 {
666  struct ab8500_btemp *di = _di;
667 
668  dev_dbg(di->dev, "Battery temperature is between low and medium\n");
669 
670  di->events.btemp_lowmed = true;
671  di->events.btemp_medhigh = false;
672  di->events.btemp_high = false;
673  di->events.btemp_low = false;
675 
676  return IRQ_HANDLED;
677 }
678 
686 static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di)
687 {
688  struct ab8500_btemp *di = _di;
689 
690  dev_dbg(di->dev, "Battery temperature is between medium and high\n");
691 
692  di->events.btemp_medhigh = true;
693  di->events.btemp_lowmed = false;
694  di->events.btemp_high = false;
695  di->events.btemp_low = false;
697 
698  return IRQ_HANDLED;
699 }
700 
709 static void ab8500_btemp_periodic(struct ab8500_btemp *di,
710  bool enable)
711 {
712  dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n",
713  enable);
714  /*
715  * Make sure a new measurement is done directly by cancelling
716  * any pending work
717  */
719 
720  if (enable)
722 }
723 
730 static int ab8500_btemp_get_temp(struct ab8500_btemp *di)
731 {
732  int temp = 0;
733 
734  /*
735  * The BTEMP events are not reliabe on AB8500 cut2.0
736  * and prior versions
737  */
738  if (is_ab8500_2p0_or_earlier(di->parent)) {
739  temp = di->bat_temp * 10;
740  } else {
741  if (di->events.btemp_low) {
742  if (temp > di->btemp_ranges.btemp_low_limit)
743  temp = di->btemp_ranges.btemp_low_limit;
744  else
745  temp = di->bat_temp * 10;
746  } else if (di->events.btemp_high) {
747  if (temp < di->btemp_ranges.btemp_high_limit)
748  temp = di->btemp_ranges.btemp_high_limit;
749  else
750  temp = di->bat_temp * 10;
751  } else if (di->events.btemp_lowmed) {
752  if (temp > di->btemp_ranges.btemp_med_limit)
753  temp = di->btemp_ranges.btemp_med_limit;
754  else
755  temp = di->bat_temp * 10;
756  } else if (di->events.btemp_medhigh) {
757  if (temp < di->btemp_ranges.btemp_med_limit)
758  temp = di->btemp_ranges.btemp_med_limit;
759  else
760  temp = di->bat_temp * 10;
761  } else
762  temp = di->bat_temp * 10;
763  }
764  return temp;
765 }
766 
774 {
775  return btemp->bat_temp * 1000;
776 }
777 
792 static int ab8500_btemp_get_property(struct power_supply *psy,
793  enum power_supply_property psp,
794  union power_supply_propval *val)
795 {
796  struct ab8500_btemp *di;
797 
798  di = to_ab8500_btemp_device_info(psy);
799 
800  switch (psp) {
803  if (di->events.batt_rem)
804  val->intval = 0;
805  else
806  val->intval = 1;
807  break;
809  val->intval = di->bat->bat_type[di->bat->batt_id].name;
810  break;
812  val->intval = ab8500_btemp_get_temp(di);
813  break;
814  default:
815  return -EINVAL;
816  }
817  return 0;
818 }
819 
820 static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
821 {
822  struct power_supply *psy;
823  struct power_supply *ext;
824  struct ab8500_btemp *di;
825  union power_supply_propval ret;
826  int i, j;
827  bool psy_found = false;
828 
829  psy = (struct power_supply *)data;
830  ext = dev_get_drvdata(dev);
831  di = to_ab8500_btemp_device_info(psy);
832 
833  /*
834  * For all psy where the name of your driver
835  * appears in any supplied_to
836  */
837  for (i = 0; i < ext->num_supplicants; i++) {
838  if (!strcmp(ext->supplied_to[i], psy->name))
839  psy_found = true;
840  }
841 
842  if (!psy_found)
843  return 0;
844 
845  /* Go through all properties for the psy */
846  for (j = 0; j < ext->num_properties; j++) {
847  enum power_supply_property prop;
848  prop = ext->properties[j];
849 
850  if (ext->get_property(ext, prop, &ret))
851  continue;
852 
853  switch (prop) {
855  switch (ext->type) {
857  /* AC disconnected */
858  if (!ret.intval && di->events.ac_conn) {
859  di->events.ac_conn = false;
860  }
861  /* AC connected */
862  else if (ret.intval && !di->events.ac_conn) {
863  di->events.ac_conn = true;
864  if (!di->events.usb_conn)
865  ab8500_btemp_periodic(di, true);
866  }
867  break;
869  /* USB disconnected */
870  if (!ret.intval && di->events.usb_conn) {
871  di->events.usb_conn = false;
872  }
873  /* USB connected */
874  else if (ret.intval && !di->events.usb_conn) {
875  di->events.usb_conn = true;
876  if (!di->events.ac_conn)
877  ab8500_btemp_periodic(di, true);
878  }
879  break;
880  default:
881  break;
882  }
883  break;
884  default:
885  break;
886  }
887  }
888  return 0;
889 }
890 
900 static void ab8500_btemp_external_power_changed(struct power_supply *psy)
901 {
902  struct ab8500_btemp *di = to_ab8500_btemp_device_info(psy);
903 
905  &di->btemp_psy, ab8500_btemp_get_ext_psy_data);
906 }
907 
908 /* ab8500 btemp driver interrupts and their respective isr */
909 static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = {
910  {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler},
911  {"BTEMP_LOW", ab8500_btemp_templow_handler},
912  {"BTEMP_HIGH", ab8500_btemp_temphigh_handler},
913  {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler},
914  {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler},
915 };
916 
917 #if defined(CONFIG_PM)
918 static int ab8500_btemp_resume(struct platform_device *pdev)
919 {
920  struct ab8500_btemp *di = platform_get_drvdata(pdev);
921 
922  ab8500_btemp_periodic(di, true);
923 
924  return 0;
925 }
926 
927 static int ab8500_btemp_suspend(struct platform_device *pdev,
929 {
930  struct ab8500_btemp *di = platform_get_drvdata(pdev);
931 
932  ab8500_btemp_periodic(di, false);
933 
934  return 0;
935 }
936 #else
937 #define ab8500_btemp_suspend NULL
938 #define ab8500_btemp_resume NULL
939 #endif
940 
941 static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
942 {
943  struct ab8500_btemp *di = platform_get_drvdata(pdev);
944  int i, irq;
945 
946  /* Disable interrupts */
947  for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
948  irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
949  free_irq(irq, di);
950  }
951 
952  /* Delete the work queue */
954 
957  platform_set_drvdata(pdev, NULL);
958  kfree(di);
959 
960  return 0;
961 }
962 
963 static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
964 {
965  int irq, i, ret = 0;
966  u8 val;
967  struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
968  struct ab8500_btemp *di;
969 
970  if (!plat_data) {
971  dev_err(&pdev->dev, "No platform data\n");
972  return -EINVAL;
973  }
974 
975  di = kzalloc(sizeof(*di), GFP_KERNEL);
976  if (!di)
977  return -ENOMEM;
978 
979  /* get parent data */
980  di->dev = &pdev->dev;
981  di->parent = dev_get_drvdata(pdev->dev.parent);
982  di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
983 
984  /* get btemp specific platform data */
985  di->pdata = plat_data->btemp;
986  if (!di->pdata) {
987  dev_err(di->dev, "no btemp platform data supplied\n");
988  ret = -EINVAL;
989  goto free_device_info;
990  }
991 
992  /* get battery specific platform data */
993  di->bat = plat_data->battery;
994  if (!di->bat) {
995  dev_err(di->dev, "no battery platform data supplied\n");
996  ret = -EINVAL;
997  goto free_device_info;
998  }
999 
1000  /* BTEMP supply */
1001  di->btemp_psy.name = "ab8500_btemp";
1003  di->btemp_psy.properties = ab8500_btemp_props;
1004  di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props);
1005  di->btemp_psy.get_property = ab8500_btemp_get_property;
1006  di->btemp_psy.supplied_to = di->pdata->supplied_to;
1007  di->btemp_psy.num_supplicants = di->pdata->num_supplicants;
1008  di->btemp_psy.external_power_changed =
1009  ab8500_btemp_external_power_changed;
1010 
1011 
1012  /* Create a work queue for the btemp */
1013  di->btemp_wq =
1014  create_singlethread_workqueue("ab8500_btemp_wq");
1015  if (di->btemp_wq == NULL) {
1016  dev_err(di->dev, "failed to create work queue\n");
1017  ret = -ENOMEM;
1018  goto free_device_info;
1019  }
1020 
1021  /* Init work for measuring temperature periodically */
1023  ab8500_btemp_periodic_work);
1024 
1025  /* Identify the battery */
1026  if (ab8500_btemp_id(di) < 0)
1027  dev_warn(di->dev, "failed to identify the battery\n");
1028 
1029  /* Set BTEMP thermal limits. Low and Med are fixed */
1030  di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT;
1031  di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT;
1032 
1034  AB8500_BTEMP_HIGH_TH, &val);
1035  if (ret < 0) {
1036  dev_err(di->dev, "%s ab8500 read failed\n", __func__);
1037  goto free_btemp_wq;
1038  }
1039  switch (val) {
1040  case BTEMP_HIGH_TH_57_0:
1041  case BTEMP_HIGH_TH_57_1:
1042  di->btemp_ranges.btemp_high_limit =
1044  break;
1045  case BTEMP_HIGH_TH_52:
1046  di->btemp_ranges.btemp_high_limit =
1048  break;
1049  case BTEMP_HIGH_TH_62:
1050  di->btemp_ranges.btemp_high_limit =
1052  break;
1053  }
1054 
1055  /* Register BTEMP power supply class */
1056  ret = power_supply_register(di->dev, &di->btemp_psy);
1057  if (ret) {
1058  dev_err(di->dev, "failed to register BTEMP psy\n");
1059  goto free_btemp_wq;
1060  }
1061 
1062  /* Register interrupts */
1063  for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
1064  irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
1065  ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr,
1067  ab8500_btemp_irq[i].name, di);
1068 
1069  if (ret) {
1070  dev_err(di->dev, "failed to request %s IRQ %d: %d\n"
1071  , ab8500_btemp_irq[i].name, irq, ret);
1072  goto free_irq;
1073  }
1074  dev_dbg(di->dev, "Requested %s IRQ %d: %d\n",
1075  ab8500_btemp_irq[i].name, irq, ret);
1076  }
1077 
1078  platform_set_drvdata(pdev, di);
1079 
1080  /* Kick off periodic temperature measurements */
1081  ab8500_btemp_periodic(di, true);
1082  list_add_tail(&di->node, &ab8500_btemp_list);
1083 
1084  return ret;
1085 
1086 free_irq:
1088 
1089  /* We also have to free all successfully registered irqs */
1090  for (i = i - 1; i >= 0; i--) {
1091  irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
1092  free_irq(irq, di);
1093  }
1094 free_btemp_wq:
1096 free_device_info:
1097  kfree(di);
1098 
1099  return ret;
1100 }
1101 
1102 static struct platform_driver ab8500_btemp_driver = {
1103  .probe = ab8500_btemp_probe,
1104  .remove = __devexit_p(ab8500_btemp_remove),
1105  .suspend = ab8500_btemp_suspend,
1106  .resume = ab8500_btemp_resume,
1107  .driver = {
1108  .name = "ab8500-btemp",
1109  .owner = THIS_MODULE,
1110  },
1111 };
1112 
1113 static int __init ab8500_btemp_init(void)
1114 {
1115  return platform_driver_register(&ab8500_btemp_driver);
1116 }
1117 
1118 static void __exit ab8500_btemp_exit(void)
1119 {
1120  platform_driver_unregister(&ab8500_btemp_driver);
1121 }
1122 
1123 subsys_initcall_sync(ab8500_btemp_init);
1124 module_exit(ab8500_btemp_exit);
1125 
1126 MODULE_LICENSE("GPL v2");
1127 MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
1128 MODULE_ALIAS("platform:ab8500-btemp");
1129 MODULE_DESCRIPTION("AB8500 battery temperature driver");