Merge tag 'for-5.14-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / drivers / power / supply / ab8500_btemp.c
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/iio/consumer.h>
30
31 #include "ab8500-bm.h"
32
33 #define VTVOUT_V                        1800
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  * @adc_btemp_ball:     ADC channel for the battery ball temperature
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 iio_channel *btemp_ball;
103         struct iio_channel *bat_ctrl;
104         struct ab8500_fg *fg;
105         struct abx500_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_TECHNOLOGY,
119         POWER_SUPPLY_PROP_TEMP,
120 };
121
122 static LIST_HEAD(ab8500_btemp_list);
123
124 /**
125  * ab8500_btemp_batctrl_volt_to_res() - convert batctrl voltage to resistance
126  * @di:         pointer to the ab8500_btemp structure
127  * @v_batctrl:  measured batctrl voltage
128  * @inst_curr:  measured instant current
129  *
130  * This function returns the battery resistance that is
131  * derived from the BATCTRL voltage.
132  * Returns value in Ohms.
133  */
134 static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,
135         int v_batctrl, int inst_curr)
136 {
137         int rbs;
138
139         if (is_ab8500_1p1_or_earlier(di->parent)) {
140                 /*
141                  * For ABB cut1.0 and 1.1 BAT_CTRL is internally
142                  * connected to 1.8V through a 450k resistor
143                  */
144                 return (450000 * (v_batctrl)) / (1800 - v_batctrl);
145         }
146
147         if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL) {
148                 /*
149                  * If the battery has internal NTC, we use the current
150                  * source to calculate the resistance.
151                  */
152                 rbs = (v_batctrl * 1000
153                        - di->bm->gnd_lift_resistance * inst_curr)
154                       / di->curr_source;
155         } else {
156                 /*
157                  * BAT_CTRL is internally
158                  * connected to 1.8V through a 80k resistor
159                  */
160                 rbs = (80000 * (v_batctrl)) / (1800 - v_batctrl);
161         }
162
163         return rbs;
164 }
165
166 /**
167  * ab8500_btemp_read_batctrl_voltage() - measure batctrl voltage
168  * @di:         pointer to the ab8500_btemp structure
169  *
170  * This function returns the voltage on BATCTRL. Returns value in mV.
171  */
172 static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di)
173 {
174         int vbtemp, ret;
175         static int prev;
176
177         ret = iio_read_channel_processed(di->bat_ctrl, &vbtemp);
178         if (ret < 0) {
179                 dev_err(di->dev,
180                         "%s ADC conversion failed, using previous value",
181                         __func__);
182                 return prev;
183         }
184         prev = vbtemp;
185         return vbtemp;
186 }
187
188 /**
189  * ab8500_btemp_curr_source_enable() - enable/disable batctrl current source
190  * @di:         pointer to the ab8500_btemp structure
191  * @enable:     enable or disable the current source
192  *
193  * Enable or disable the current sources for the BatCtrl AD channel
194  */
195 static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
196         bool enable)
197 {
198         int curr;
199         int ret = 0;
200
201         /*
202          * BATCTRL current sources are included on AB8500 cut2.0
203          * and future versions
204          */
205         if (is_ab8500_1p1_or_earlier(di->parent))
206                 return 0;
207
208         /* Only do this for batteries with internal NTC */
209         if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) {
210
211                 if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA)
212                         curr = BAT_CTRL_7U_ENA;
213                 else
214                         curr = BAT_CTRL_20U_ENA;
215
216                 dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source);
217
218                 ret = abx500_mask_and_set_register_interruptible(di->dev,
219                         AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
220                         FORCE_BAT_CTRL_CMP_HIGH, FORCE_BAT_CTRL_CMP_HIGH);
221                 if (ret) {
222                         dev_err(di->dev, "%s failed setting cmp_force\n",
223                                 __func__);
224                         return ret;
225                 }
226
227                 /*
228                  * We have to wait one 32kHz cycle before enabling
229                  * the current source, since ForceBatCtrlCmpHigh needs
230                  * to be written in a separate cycle
231                  */
232                 udelay(32);
233
234                 ret = abx500_set_register_interruptible(di->dev,
235                         AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
236                         FORCE_BAT_CTRL_CMP_HIGH | curr);
237                 if (ret) {
238                         dev_err(di->dev, "%s failed enabling current source\n",
239                                 __func__);
240                         goto disable_curr_source;
241                 }
242         } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) {
243                 dev_dbg(di->dev, "Disable BATCTRL curr source\n");
244
245                 /* Write 0 to the curr bits */
246                 ret = abx500_mask_and_set_register_interruptible(
247                         di->dev,
248                         AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
249                         BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA,
250                         ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA));
251
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 */
259                 ret = abx500_mask_and_set_register_interruptible(di->dev,
260                         AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
261                         BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA,
262                         BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA);
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' */
277                 ret = abx500_mask_and_set_register_interruptible(di->dev,
278                         AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
279                         FORCE_BAT_CTRL_CMP_HIGH, ~FORCE_BAT_CTRL_CMP_HIGH);
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 */
294         ret = abx500_mask_and_set_register_interruptible(di->dev,
295                 AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
296                 BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA,
297                 ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA));
298
299         if (ret) {
300                 dev_err(di->dev, "%s failed disabling current source\n",
301                         __func__);
302                 return ret;
303         }
304 enable_pu_comp:
305         /* Enable Pull-Up and comparator */
306         ret = abx500_mask_and_set_register_interruptible(di->dev,
307                 AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
308                 BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA,
309                 BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA);
310         if (ret) {
311                 dev_err(di->dev, "%s failed enabling PU and comp\n",
312                         __func__);
313                 return ret;
314         }
315
316 disable_force_comp:
317         /*
318          * We have to wait one 32kHz cycle before disabling
319          * ForceBatCtrlCmpHigh since this needs to be written
320          * in a separate cycle
321          */
322         udelay(32);
323
324         /* Disable 'force comparator' */
325         ret = abx500_mask_and_set_register_interruptible(di->dev,
326                 AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
327                 FORCE_BAT_CTRL_CMP_HIGH, ~FORCE_BAT_CTRL_CMP_HIGH);
328         if (ret) {
329                 dev_err(di->dev, "%s failed disabling force comp\n",
330                         __func__);
331                 return ret;
332         }
333
334         return ret;
335 }
336
337 /**
338  * ab8500_btemp_get_batctrl_res() - get battery resistance
339  * @di:         pointer to the ab8500_btemp structure
340  *
341  * This function returns the battery pack identification resistance.
342  * Returns value in Ohms.
343  */
344 static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di)
345 {
346         int ret;
347         int batctrl = 0;
348         int res;
349         int inst_curr;
350         int i;
351
352         /*
353          * BATCTRL current sources are included on AB8500 cut2.0
354          * and future versions
355          */
356         ret = ab8500_btemp_curr_source_enable(di, true);
357         if (ret) {
358                 dev_err(di->dev, "%s curr source enabled failed\n", __func__);
359                 return ret;
360         }
361
362         if (!di->fg)
363                 di->fg = ab8500_fg_get();
364         if (!di->fg) {
365                 dev_err(di->dev, "No fg found\n");
366                 return -EINVAL;
367         }
368
369         ret = ab8500_fg_inst_curr_start(di->fg);
370
371         if (ret) {
372                 dev_err(di->dev, "Failed to start current measurement\n");
373                 return ret;
374         }
375
376         do {
377                 msleep(20);
378         } while (!ab8500_fg_inst_curr_started(di->fg));
379
380         i = 0;
381
382         do {
383                 batctrl += ab8500_btemp_read_batctrl_voltage(di);
384                 i++;
385                 msleep(20);
386         } while (!ab8500_fg_inst_curr_done(di->fg));
387         batctrl /= i;
388
389         ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr);
390         if (ret) {
391                 dev_err(di->dev, "Failed to finalize current measurement\n");
392                 return ret;
393         }
394
395         res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr);
396
397         ret = ab8500_btemp_curr_source_enable(di, false);
398         if (ret) {
399                 dev_err(di->dev, "%s curr source disable failed\n", __func__);
400                 return ret;
401         }
402
403         dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n",
404                 __func__, batctrl, res, inst_curr, i);
405
406         return res;
407 }
408
409 /**
410  * ab8500_btemp_res_to_temp() - resistance to temperature
411  * @di:         pointer to the ab8500_btemp structure
412  * @tbl:        pointer to the resiatance to temperature table
413  * @tbl_size:   size of the resistance to temperature table
414  * @res:        resistance to calculate the temperature from
415  *
416  * This function returns the battery temperature in degrees Celsius
417  * based on the NTC resistance.
418  */
419 static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di,
420         const struct abx500_res_to_temp *tbl, int tbl_size, int res)
421 {
422         int i;
423         /*
424          * Calculate the formula for the straight line
425          * Simple interpolation if we are within
426          * the resistance table limits, extrapolate
427          * if resistance is outside the limits.
428          */
429         if (res > tbl[0].resist)
430                 i = 0;
431         else if (res <= tbl[tbl_size - 1].resist)
432                 i = tbl_size - 2;
433         else {
434                 i = 0;
435                 while (!(res <= tbl[i].resist &&
436                         res > tbl[i + 1].resist))
437                         i++;
438         }
439
440         return tbl[i].temp + ((tbl[i + 1].temp - tbl[i].temp) *
441                 (res - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist);
442 }
443
444 /**
445  * ab8500_btemp_measure_temp() - measure battery temperature
446  * @di:         pointer to the ab8500_btemp structure
447  *
448  * Returns battery temperature (on success) else the previous temperature
449  */
450 static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
451 {
452         int temp, ret;
453         static int prev;
454         int rbat, rntc, vntc;
455         u8 id;
456
457         id = di->bm->batt_id;
458
459         if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL &&
460                         id != BATTERY_UNKNOWN) {
461
462                 rbat = ab8500_btemp_get_batctrl_res(di);
463                 if (rbat < 0) {
464                         dev_err(di->dev, "%s get batctrl res failed\n",
465                                 __func__);
466                         /*
467                          * Return out-of-range temperature so that
468                          * charging is stopped
469                          */
470                         return BTEMP_THERMAL_LOW_LIMIT;
471                 }
472
473                 temp = ab8500_btemp_res_to_temp(di,
474                         di->bm->bat_type[id].r_to_t_tbl,
475                         di->bm->bat_type[id].n_temp_tbl_elements, rbat);
476         } else {
477                 ret = iio_read_channel_processed(di->btemp_ball, &vntc);
478                 if (ret < 0) {
479                         dev_err(di->dev,
480                                 "%s ADC conversion failed,"
481                                 " using previous value\n", __func__);
482                         return prev;
483                 }
484                 /*
485                  * The PCB NTC is sourced from VTVOUT via a 230kOhm
486                  * resistor.
487                  */
488                 rntc = 230000 * vntc / (VTVOUT_V - vntc);
489
490                 temp = ab8500_btemp_res_to_temp(di,
491                         di->bm->bat_type[id].r_to_t_tbl,
492                         di->bm->bat_type[id].n_temp_tbl_elements, rntc);
493                 prev = temp;
494         }
495         dev_dbg(di->dev, "Battery temperature is %d\n", temp);
496         return temp;
497 }
498
499 /**
500  * ab8500_btemp_id() - Identify the connected battery
501  * @di:         pointer to the ab8500_btemp structure
502  *
503  * This function will try to identify the battery by reading the ID
504  * resistor. Some brands use a combined ID resistor with a NTC resistor to
505  * both be able to identify and to read the temperature of it.
506  */
507 static int ab8500_btemp_id(struct ab8500_btemp *di)
508 {
509         int res;
510         u8 i;
511
512         di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA;
513         di->bm->batt_id = BATTERY_UNKNOWN;
514
515         res =  ab8500_btemp_get_batctrl_res(di);
516         if (res < 0) {
517                 dev_err(di->dev, "%s get batctrl res failed\n", __func__);
518                 return -ENXIO;
519         }
520
521         /* BATTERY_UNKNOWN is defined on position 0, skip it! */
522         for (i = BATTERY_UNKNOWN + 1; i < di->bm->n_btypes; i++) {
523                 if ((res <= di->bm->bat_type[i].resis_high) &&
524                         (res >= di->bm->bat_type[i].resis_low)) {
525                         dev_dbg(di->dev, "Battery detected on %s"
526                                 " low %d < res %d < high: %d"
527                                 " index: %d\n",
528                                 di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL ?
529                                 "BATCTRL" : "BATTEMP",
530                                 di->bm->bat_type[i].resis_low, res,
531                                 di->bm->bat_type[i].resis_high, i);
532
533                         di->bm->batt_id = i;
534                         break;
535                 }
536         }
537
538         if (di->bm->batt_id == BATTERY_UNKNOWN) {
539                 dev_warn(di->dev, "Battery identified as unknown"
540                         ", resistance %d Ohm\n", res);
541                 return -ENXIO;
542         }
543
544         /*
545          * We only have to change current source if the
546          * detected type is Type 1.
547          */
548         if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL &&
549             di->bm->batt_id == 1) {
550                 dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n");
551                 di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA;
552         }
553
554         return di->bm->batt_id;
555 }
556
557 /**
558  * ab8500_btemp_periodic_work() - Measuring the temperature periodically
559  * @work:       pointer to the work_struct structure
560  *
561  * Work function for measuring the temperature periodically
562  */
563 static void ab8500_btemp_periodic_work(struct work_struct *work)
564 {
565         int interval;
566         int bat_temp;
567         struct ab8500_btemp *di = container_of(work,
568                 struct ab8500_btemp, btemp_periodic_work.work);
569
570         if (!di->initialized) {
571                 /* Identify the battery */
572                 if (ab8500_btemp_id(di) < 0)
573                         dev_warn(di->dev, "failed to identify the battery\n");
574         }
575
576         bat_temp = ab8500_btemp_measure_temp(di);
577         /*
578          * Filter battery temperature.
579          * Allow direct updates on temperature only if two samples result in
580          * same temperature. Else only allow 1 degree change from previous
581          * reported value in the direction of the new measurement.
582          */
583         if ((bat_temp == di->prev_bat_temp) || !di->initialized) {
584                 if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) {
585                         di->initialized = true;
586                         di->bat_temp = bat_temp;
587                         power_supply_changed(di->btemp_psy);
588                 }
589         } else if (bat_temp < di->prev_bat_temp) {
590                 di->bat_temp--;
591                 power_supply_changed(di->btemp_psy);
592         } else if (bat_temp > di->prev_bat_temp) {
593                 di->bat_temp++;
594                 power_supply_changed(di->btemp_psy);
595         }
596         di->prev_bat_temp = bat_temp;
597
598         if (di->events.ac_conn || di->events.usb_conn)
599                 interval = di->bm->temp_interval_chg;
600         else
601                 interval = di->bm->temp_interval_nochg;
602
603         /* Schedule a new measurement */
604         queue_delayed_work(di->btemp_wq,
605                 &di->btemp_periodic_work,
606                 round_jiffies(interval * HZ));
607 }
608
609 /**
610  * ab8500_btemp_batctrlindb_handler() - battery removal detected
611  * @irq:       interrupt number
612  * @_di:       void pointer that has to address of ab8500_btemp
613  *
614  * Returns IRQ status(IRQ_HANDLED)
615  */
616 static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di)
617 {
618         struct ab8500_btemp *di = _di;
619         dev_err(di->dev, "Battery removal detected!\n");
620
621         di->events.batt_rem = true;
622         power_supply_changed(di->btemp_psy);
623
624         return IRQ_HANDLED;
625 }
626
627 /**
628  * ab8500_btemp_templow_handler() - battery temp lower than 10 degrees
629  * @irq:       interrupt number
630  * @_di:       void pointer that has to address of ab8500_btemp
631  *
632  * Returns IRQ status(IRQ_HANDLED)
633  */
634 static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di)
635 {
636         struct ab8500_btemp *di = _di;
637
638         if (is_ab8500_3p3_or_earlier(di->parent)) {
639                 dev_dbg(di->dev, "Ignore false btemp low irq"
640                         " for ABB cut 1.0, 1.1, 2.0 and 3.3\n");
641         } else {
642                 dev_crit(di->dev, "Battery temperature lower than -10deg c\n");
643
644                 di->events.btemp_low = true;
645                 di->events.btemp_high = false;
646                 di->events.btemp_medhigh = false;
647                 di->events.btemp_lowmed = false;
648                 power_supply_changed(di->btemp_psy);
649         }
650
651         return IRQ_HANDLED;
652 }
653
654 /**
655  * ab8500_btemp_temphigh_handler() - battery temp higher than max temp
656  * @irq:       interrupt number
657  * @_di:       void pointer that has to address of ab8500_btemp
658  *
659  * Returns IRQ status(IRQ_HANDLED)
660  */
661 static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di)
662 {
663         struct ab8500_btemp *di = _di;
664
665         dev_crit(di->dev, "Battery temperature is higher than MAX temp\n");
666
667         di->events.btemp_high = true;
668         di->events.btemp_medhigh = false;
669         di->events.btemp_lowmed = false;
670         di->events.btemp_low = false;
671         power_supply_changed(di->btemp_psy);
672
673         return IRQ_HANDLED;
674 }
675
676 /**
677  * ab8500_btemp_lowmed_handler() - battery temp between low and medium
678  * @irq:       interrupt number
679  * @_di:       void pointer that has to address of ab8500_btemp
680  *
681  * Returns IRQ status(IRQ_HANDLED)
682  */
683 static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di)
684 {
685         struct ab8500_btemp *di = _di;
686
687         dev_dbg(di->dev, "Battery temperature is between low and medium\n");
688
689         di->events.btemp_lowmed = true;
690         di->events.btemp_medhigh = false;
691         di->events.btemp_high = false;
692         di->events.btemp_low = false;
693         power_supply_changed(di->btemp_psy);
694
695         return IRQ_HANDLED;
696 }
697
698 /**
699  * ab8500_btemp_medhigh_handler() - battery temp between medium and high
700  * @irq:       interrupt number
701  * @_di:       void pointer that has to address of ab8500_btemp
702  *
703  * Returns IRQ status(IRQ_HANDLED)
704  */
705 static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di)
706 {
707         struct ab8500_btemp *di = _di;
708
709         dev_dbg(di->dev, "Battery temperature is between medium and high\n");
710
711         di->events.btemp_medhigh = true;
712         di->events.btemp_lowmed = false;
713         di->events.btemp_high = false;
714         di->events.btemp_low = false;
715         power_supply_changed(di->btemp_psy);
716
717         return IRQ_HANDLED;
718 }
719
720 /**
721  * ab8500_btemp_periodic() - Periodic temperature measurements
722  * @di:         pointer to the ab8500_btemp structure
723  * @enable:     enable or disable periodic temperature measurements
724  *
725  * Starts of stops periodic temperature measurements. Periodic measurements
726  * should only be done when a charger is connected.
727  */
728 static void ab8500_btemp_periodic(struct ab8500_btemp *di,
729         bool enable)
730 {
731         dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n",
732                 enable);
733         /*
734          * Make sure a new measurement is done directly by cancelling
735          * any pending work
736          */
737         cancel_delayed_work_sync(&di->btemp_periodic_work);
738
739         if (enable)
740                 queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0);
741 }
742
743 /**
744  * ab8500_btemp_get_temp() - get battery temperature
745  * @di:         pointer to the ab8500_btemp structure
746  *
747  * Returns battery temperature
748  */
749 static int ab8500_btemp_get_temp(struct ab8500_btemp *di)
750 {
751         int temp = 0;
752
753         /*
754          * The BTEMP events are not reliabe on AB8500 cut3.3
755          * and prior versions
756          */
757         if (is_ab8500_3p3_or_earlier(di->parent)) {
758                 temp = di->bat_temp * 10;
759         } else {
760                 if (di->events.btemp_low) {
761                         if (temp > di->btemp_ranges.btemp_low_limit)
762                                 temp = di->btemp_ranges.btemp_low_limit * 10;
763                         else
764                                 temp = di->bat_temp * 10;
765                 } else if (di->events.btemp_high) {
766                         if (temp < di->btemp_ranges.btemp_high_limit)
767                                 temp = di->btemp_ranges.btemp_high_limit * 10;
768                         else
769                                 temp = di->bat_temp * 10;
770                 } else if (di->events.btemp_lowmed) {
771                         if (temp > di->btemp_ranges.btemp_med_limit)
772                                 temp = di->btemp_ranges.btemp_med_limit * 10;
773                         else
774                                 temp = di->bat_temp * 10;
775                 } else if (di->events.btemp_medhigh) {
776                         if (temp < di->btemp_ranges.btemp_med_limit)
777                                 temp = di->btemp_ranges.btemp_med_limit * 10;
778                         else
779                                 temp = di->bat_temp * 10;
780                 } else
781                         temp = di->bat_temp * 10;
782         }
783         return temp;
784 }
785
786 /**
787  * ab8500_btemp_get_property() - get the btemp properties
788  * @psy:        pointer to the power_supply structure
789  * @psp:        pointer to the power_supply_property structure
790  * @val:        pointer to the power_supply_propval union
791  *
792  * This function gets called when an application tries to get the btemp
793  * properties by reading the sysfs files.
794  * online:      presence of the battery
795  * present:     presence of the battery
796  * technology:  battery technology
797  * temp:        battery temperature
798  * Returns error code in case of failure else 0(on success)
799  */
800 static int ab8500_btemp_get_property(struct power_supply *psy,
801         enum power_supply_property psp,
802         union power_supply_propval *val)
803 {
804         struct ab8500_btemp *di = power_supply_get_drvdata(psy);
805
806         switch (psp) {
807         case POWER_SUPPLY_PROP_PRESENT:
808         case POWER_SUPPLY_PROP_ONLINE:
809                 if (di->events.batt_rem)
810                         val->intval = 0;
811                 else
812                         val->intval = 1;
813                 break;
814         case POWER_SUPPLY_PROP_TECHNOLOGY:
815                 val->intval = di->bm->bat_type[di->bm->batt_id].name;
816                 break;
817         case POWER_SUPPLY_PROP_TEMP:
818                 val->intval = ab8500_btemp_get_temp(di);
819                 break;
820         default:
821                 return -EINVAL;
822         }
823         return 0;
824 }
825
826 static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
827 {
828         struct power_supply *psy;
829         struct power_supply *ext = dev_get_drvdata(dev);
830         const char **supplicants = (const char **)ext->supplied_to;
831         struct ab8500_btemp *di;
832         union power_supply_propval ret;
833         int j;
834
835         psy = (struct power_supply *)data;
836         di = power_supply_get_drvdata(psy);
837
838         /*
839          * For all psy where the name of your driver
840          * appears in any supplied_to
841          */
842         j = match_string(supplicants, ext->num_supplicants, psy->desc->name);
843         if (j < 0)
844                 return 0;
845
846         /* Go through all properties for the psy */
847         for (j = 0; j < ext->desc->num_properties; j++) {
848                 enum power_supply_property prop;
849                 prop = ext->desc->properties[j];
850
851                 if (power_supply_get_property(ext, prop, &ret))
852                         continue;
853
854                 switch (prop) {
855                 case POWER_SUPPLY_PROP_PRESENT:
856                         switch (ext->desc->type) {
857                         case POWER_SUPPLY_TYPE_MAINS:
858                                 /* AC disconnected */
859                                 if (!ret.intval && di->events.ac_conn) {
860                                         di->events.ac_conn = false;
861                                 }
862                                 /* AC connected */
863                                 else if (ret.intval && !di->events.ac_conn) {
864                                         di->events.ac_conn = true;
865                                         if (!di->events.usb_conn)
866                                                 ab8500_btemp_periodic(di, true);
867                                 }
868                                 break;
869                         case POWER_SUPPLY_TYPE_USB:
870                                 /* USB disconnected */
871                                 if (!ret.intval && di->events.usb_conn) {
872                                         di->events.usb_conn = false;
873                                 }
874                                 /* USB connected */
875                                 else if (ret.intval && !di->events.usb_conn) {
876                                         di->events.usb_conn = true;
877                                         if (!di->events.ac_conn)
878                                                 ab8500_btemp_periodic(di, true);
879                                 }
880                                 break;
881                         default:
882                                 break;
883                         }
884                         break;
885                 default:
886                         break;
887                 }
888         }
889         return 0;
890 }
891
892 /**
893  * ab8500_btemp_external_power_changed() - callback for power supply changes
894  * @psy:       pointer to the structure power_supply
895  *
896  * This function is pointing to the function pointer external_power_changed
897  * of the structure power_supply.
898  * This function gets executed when there is a change in the external power
899  * supply to the btemp.
900  */
901 static void ab8500_btemp_external_power_changed(struct power_supply *psy)
902 {
903         struct ab8500_btemp *di = power_supply_get_drvdata(psy);
904
905         class_for_each_device(power_supply_class, NULL,
906                 di->btemp_psy, ab8500_btemp_get_ext_psy_data);
907 }
908
909 /* ab8500 btemp driver interrupts and their respective isr */
910 static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = {
911         {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler},
912         {"BTEMP_LOW", ab8500_btemp_templow_handler},
913         {"BTEMP_HIGH", ab8500_btemp_temphigh_handler},
914         {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler},
915         {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler},
916 };
917
918 static int __maybe_unused ab8500_btemp_resume(struct device *dev)
919 {
920         struct ab8500_btemp *di = dev_get_drvdata(dev);
921
922         ab8500_btemp_periodic(di, true);
923
924         return 0;
925 }
926
927 static int __maybe_unused ab8500_btemp_suspend(struct device *dev)
928 {
929         struct ab8500_btemp *di = dev_get_drvdata(dev);
930
931         ab8500_btemp_periodic(di, false);
932
933         return 0;
934 }
935
936 static char *supply_interface[] = {
937         "ab8500_chargalg",
938         "ab8500_fg",
939 };
940
941 static const struct power_supply_desc ab8500_btemp_desc = {
942         .name                   = "ab8500_btemp",
943         .type                   = POWER_SUPPLY_TYPE_BATTERY,
944         .properties             = ab8500_btemp_props,
945         .num_properties         = ARRAY_SIZE(ab8500_btemp_props),
946         .get_property           = ab8500_btemp_get_property,
947         .external_power_changed = ab8500_btemp_external_power_changed,
948 };
949
950 static int ab8500_btemp_bind(struct device *dev, struct device *master,
951                              void *data)
952 {
953         struct ab8500_btemp *di = dev_get_drvdata(dev);
954
955         /* Create a work queue for the btemp */
956         di->btemp_wq =
957                 alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0);
958         if (di->btemp_wq == NULL) {
959                 dev_err(dev, "failed to create work queue\n");
960                 return -ENOMEM;
961         }
962
963         /* Kick off periodic temperature measurements */
964         ab8500_btemp_periodic(di, true);
965
966         return 0;
967 }
968
969 static void ab8500_btemp_unbind(struct device *dev, struct device *master,
970                                 void *data)
971 {
972         struct ab8500_btemp *di = dev_get_drvdata(dev);
973
974         /* Delete the work queue */
975         destroy_workqueue(di->btemp_wq);
976         flush_scheduled_work();
977 }
978
979 static const struct component_ops ab8500_btemp_component_ops = {
980         .bind = ab8500_btemp_bind,
981         .unbind = ab8500_btemp_unbind,
982 };
983
984 static int ab8500_btemp_probe(struct platform_device *pdev)
985 {
986         struct power_supply_config psy_cfg = {};
987         struct device *dev = &pdev->dev;
988         struct ab8500_btemp *di;
989         int irq, i, ret = 0;
990         u8 val;
991
992         di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
993         if (!di)
994                 return -ENOMEM;
995
996         di->bm = &ab8500_bm_data;
997
998         /* get parent data */
999         di->dev = dev;
1000         di->parent = dev_get_drvdata(pdev->dev.parent);
1001
1002         /* Get ADC channels */
1003         di->btemp_ball = devm_iio_channel_get(dev, "btemp_ball");
1004         if (IS_ERR(di->btemp_ball)) {
1005                 ret = dev_err_probe(dev, PTR_ERR(di->btemp_ball),
1006                                     "failed to get BTEMP BALL ADC channel\n");
1007                 return ret;
1008         }
1009         di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl");
1010         if (IS_ERR(di->bat_ctrl)) {
1011                 ret = dev_err_probe(dev, PTR_ERR(di->bat_ctrl),
1012                                     "failed to get BAT CTRL ADC channel\n");
1013                 return ret;
1014         }
1015
1016         di->initialized = false;
1017
1018         psy_cfg.supplied_to = supply_interface;
1019         psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
1020         psy_cfg.drv_data = di;
1021
1022         /* Init work for measuring temperature periodically */
1023         INIT_DEFERRABLE_WORK(&di->btemp_periodic_work,
1024                 ab8500_btemp_periodic_work);
1025
1026         /* Set BTEMP thermal limits. Low and Med are fixed */
1027         di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT;
1028         di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT;
1029
1030         ret = abx500_get_register_interruptible(dev, AB8500_CHARGER,
1031                 AB8500_BTEMP_HIGH_TH, &val);
1032         if (ret < 0) {
1033                 dev_err(dev, "%s ab8500 read failed\n", __func__);
1034                 return ret;
1035         }
1036         switch (val) {
1037         case BTEMP_HIGH_TH_57_0:
1038         case BTEMP_HIGH_TH_57_1:
1039                 di->btemp_ranges.btemp_high_limit =
1040                         BTEMP_THERMAL_HIGH_LIMIT_57;
1041                 break;
1042         case BTEMP_HIGH_TH_52:
1043                 di->btemp_ranges.btemp_high_limit =
1044                         BTEMP_THERMAL_HIGH_LIMIT_52;
1045                 break;
1046         case BTEMP_HIGH_TH_62:
1047                 di->btemp_ranges.btemp_high_limit =
1048                         BTEMP_THERMAL_HIGH_LIMIT_62;
1049                 break;
1050         }
1051
1052         /* Register BTEMP power supply class */
1053         di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc,
1054                                                    &psy_cfg);
1055         if (IS_ERR(di->btemp_psy)) {
1056                 dev_err(dev, "failed to register BTEMP psy\n");
1057                 return PTR_ERR(di->btemp_psy);
1058         }
1059
1060         /* Register interrupts */
1061         for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
1062                 irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
1063                 if (irq < 0)
1064                         return irq;
1065
1066                 ret = devm_request_threaded_irq(dev, irq, NULL,
1067                         ab8500_btemp_irq[i].isr,
1068                         IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
1069                         ab8500_btemp_irq[i].name, di);
1070
1071                 if (ret) {
1072                         dev_err(dev, "failed to request %s IRQ %d: %d\n"
1073                                 , ab8500_btemp_irq[i].name, irq, ret);
1074                         return ret;
1075                 }
1076                 dev_dbg(dev, "Requested %s IRQ %d: %d\n",
1077                         ab8500_btemp_irq[i].name, irq, ret);
1078         }
1079
1080         platform_set_drvdata(pdev, di);
1081
1082         list_add_tail(&di->node, &ab8500_btemp_list);
1083
1084         return component_add(dev, &ab8500_btemp_component_ops);
1085 }
1086
1087 static int ab8500_btemp_remove(struct platform_device *pdev)
1088 {
1089         component_del(&pdev->dev, &ab8500_btemp_component_ops);
1090
1091         return 0;
1092 }
1093
1094 static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume);
1095
1096 static const struct of_device_id ab8500_btemp_match[] = {
1097         { .compatible = "stericsson,ab8500-btemp", },
1098         { },
1099 };
1100 MODULE_DEVICE_TABLE(of, ab8500_btemp_match);
1101
1102 struct platform_driver ab8500_btemp_driver = {
1103         .probe = ab8500_btemp_probe,
1104         .remove = ab8500_btemp_remove,
1105         .driver = {
1106                 .name = "ab8500-btemp",
1107                 .of_match_table = ab8500_btemp_match,
1108                 .pm = &ab8500_btemp_pm_ops,
1109         },
1110 };
1111 MODULE_LICENSE("GPL v2");
1112 MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
1113 MODULE_ALIAS("platform:ab8500-btemp");
1114 MODULE_DESCRIPTION("AB8500 battery temperature driver");