Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
omap-bandgap.c
Go to the documentation of this file.
1 /*
2  * OMAP4 Bandgap temperature sensor driver
3  *
4  * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
5  * Author: J Keerthy <[email protected]>
6  * Author: Moiz Sonasath <[email protected]>
7  * Couple of fixes, DT and MFD adaptation:
8  * Eduardo Valentin <[email protected]>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * version 2 as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  *
24  */
25 
26 #include <linux/module.h>
27 #include <linux/export.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/interrupt.h>
31 #include <linux/clk.h>
32 #include <linux/gpio.h>
33 #include <linux/platform_device.h>
34 #include <linux/err.h>
35 #include <linux/types.h>
36 #include <linux/mutex.h>
37 #include <linux/reboot.h>
38 #include <linux/of_device.h>
39 #include <linux/of_platform.h>
40 #include <linux/of_irq.h>
41 
42 #include "omap-bandgap.h"
43 
44 static u32 omap_bandgap_readl(struct omap_bandgap *bg_ptr, u32 reg)
45 {
46  return readl(bg_ptr->base + reg);
47 }
48 
49 static void omap_bandgap_writel(struct omap_bandgap *bg_ptr, u32 val, u32 reg)
50 {
51  writel(val, bg_ptr->base + reg);
52 }
53 
54 static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on)
55 {
56  struct temp_sensor_registers *tsr;
57  int i;
58  u32 ctrl;
59 
60  if (!OMAP_BANDGAP_HAS(bg_ptr, POWER_SWITCH))
61  return 0;
62 
63  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
64  tsr = bg_ptr->conf->sensors[i].registers;
65  ctrl = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
66  ctrl &= ~tsr->bgap_tempsoff_mask;
67  /* active on 0 */
68  ctrl |= !on << __ffs(tsr->bgap_tempsoff_mask);
69 
70  /* write BGAP_TEMPSOFF should be reset to 0 */
71  omap_bandgap_writel(bg_ptr, ctrl, tsr->temp_sensor_ctrl);
72  }
73 
74  return 0;
75 }
76 
77 /* This is the Talert handler. Call it only if HAS(TALERT) is set */
78 static irqreturn_t talert_irq_handler(int irq, void *data)
79 {
80  struct omap_bandgap *bg_ptr = data;
81  struct temp_sensor_registers *tsr;
82  u32 t_hot = 0, t_cold = 0, temp, ctrl;
83  int i;
84 
85  bg_ptr = data;
86  /* Read the status of t_hot */
87  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
88  tsr = bg_ptr->conf->sensors[i].registers;
89  t_hot = omap_bandgap_readl(bg_ptr, tsr->bgap_status);
90  t_hot &= tsr->status_hot_mask;
91 
92  /* Read the status of t_cold */
93  t_cold = omap_bandgap_readl(bg_ptr, tsr->bgap_status);
94  t_cold &= tsr->status_cold_mask;
95 
96  if (!t_cold && !t_hot)
97  continue;
98 
99  ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
100  /*
101  * One TALERT interrupt: Two sources
102  * If the interrupt is due to t_hot then mask t_hot and
103  * and unmask t_cold else mask t_cold and unmask t_hot
104  */
105  if (t_hot) {
106  ctrl &= ~tsr->mask_hot_mask;
107  ctrl |= tsr->mask_cold_mask;
108  } else if (t_cold) {
109  ctrl &= ~tsr->mask_cold_mask;
110  ctrl |= tsr->mask_hot_mask;
111  }
112 
113  omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl);
114 
115  /* read temperature */
116  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
117  temp &= tsr->bgap_dtemp_mask;
118 
119  /* report temperature to whom may concern */
120  if (bg_ptr->conf->report_temperature)
121  bg_ptr->conf->report_temperature(bg_ptr, i);
122  }
123 
124  return IRQ_HANDLED;
125 }
126 
127 /* This is the Tshut handler. Call it only if HAS(TSHUT) is set */
128 static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data)
129 {
130  orderly_poweroff(true);
131 
132  return IRQ_HANDLED;
133 }
134 
135 static
136 int adc_to_temp_conversion(struct omap_bandgap *bg_ptr, int id, int adc_val,
137  int *t)
138 {
139  struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data;
140 
141  /* look up for temperature in the table and return the temperature */
142  if (adc_val < ts_data->adc_start_val || adc_val > ts_data->adc_end_val)
143  return -ERANGE;
144 
145  *t = bg_ptr->conv_table[adc_val - ts_data->adc_start_val];
146 
147  return 0;
148 }
149 
150 static int temp_to_adc_conversion(long temp, struct omap_bandgap *bg_ptr, int i,
151  int *adc)
152 {
153  struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[i].ts_data;
154  int high, low, mid;
155 
156  low = 0;
157  high = ts_data->adc_end_val - ts_data->adc_start_val;
158  mid = (high + low) / 2;
159 
160  if (temp < bg_ptr->conv_table[low] || temp > bg_ptr->conv_table[high])
161  return -EINVAL;
162 
163  while (low < high) {
164  if (temp < bg_ptr->conv_table[mid])
165  high = mid - 1;
166  else
167  low = mid + 1;
168  mid = (low + high) / 2;
169  }
170 
171  *adc = ts_data->adc_start_val + low;
172 
173  return 0;
174 }
175 
176 /* Talert masks. Call it only if HAS(TALERT) is set */
177 static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id,
178  u32 t_hot, u32 t_cold)
179 {
180  struct temp_sensor_registers *tsr;
181  u32 temp, reg_val;
182 
183  /* Read the current on die temperature */
184  tsr = bg_ptr->conf->sensors[id].registers;
185  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
186  temp &= tsr->bgap_dtemp_mask;
187 
188  reg_val = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
189  if (temp < t_hot)
190  reg_val |= tsr->mask_hot_mask;
191  else
192  reg_val &= ~tsr->mask_hot_mask;
193 
194  if (t_cold < temp)
195  reg_val |= tsr->mask_cold_mask;
196  else
197  reg_val &= ~tsr->mask_cold_mask;
198  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl);
199 
200  return 0;
201 }
202 
203 static
204 int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, int i,
205  u32 *sum)
206 {
207  int temp, ret;
208 
209  ret = adc_to_temp_conversion(bg_ptr, i, adc_val, &temp);
210  if (ret < 0)
211  return ret;
212 
213  temp += hyst_val;
214 
215  return temp_to_adc_conversion(temp, bg_ptr, i, sum);
216 }
217 
218 /* Talert Thot threshold. Call it only if HAS(TALERT) is set */
219 static
220 int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot)
221 {
222  struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data;
223  struct temp_sensor_registers *tsr;
224  u32 thresh_val, reg_val;
225  int cold, err = 0;
226 
227  tsr = bg_ptr->conf->sensors[id].registers;
228 
229  /* obtain the T cold value */
230  thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
231  cold = (thresh_val & tsr->threshold_tcold_mask) >>
233  if (t_hot <= cold) {
234  /* change the t_cold to t_hot - 5000 millidegrees */
235  err |= add_hyst(t_hot, -ts_data->hyst_val, bg_ptr, id, &cold);
236  /* write the new t_cold value */
237  reg_val = thresh_val & (~tsr->threshold_tcold_mask);
238  reg_val |= cold << __ffs(tsr->threshold_tcold_mask);
239  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
240  thresh_val = reg_val;
241  }
242 
243  /* write the new t_hot value */
244  reg_val = thresh_val & ~tsr->threshold_thot_mask;
245  reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask));
246  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
247  if (err) {
248  dev_err(bg_ptr->dev, "failed to reprogram thot threshold\n");
249  return -EIO;
250  }
251 
252  return temp_sensor_unmask_interrupts(bg_ptr, id, t_hot, cold);
253 }
254 
255 /* Talert Thot and Tcold thresholds. Call it only if HAS(TALERT) is set */
256 static
257 int temp_sensor_init_talert_thresholds(struct omap_bandgap *bg_ptr, int id,
258  int t_hot, int t_cold)
259 {
260  struct temp_sensor_registers *tsr;
261  u32 reg_val, thresh_val;
262 
263  tsr = bg_ptr->conf->sensors[id].registers;
264  thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
265 
266  /* write the new t_cold value */
267  reg_val = thresh_val & ~tsr->threshold_tcold_mask;
268  reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask));
269  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
270 
271  thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
272 
273  /* write the new t_hot value */
274  reg_val = thresh_val & ~tsr->threshold_thot_mask;
275  reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask));
276  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
277 
278  reg_val = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
279  reg_val |= tsr->mask_hot_mask;
280  reg_val |= tsr->mask_cold_mask;
281  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl);
282 
283  return 0;
284 }
285 
286 /* Talert Tcold threshold. Call it only if HAS(TALERT) is set */
287 static
288 int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id,
289  int t_cold)
290 {
291  struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data;
292  struct temp_sensor_registers *tsr;
293  u32 thresh_val, reg_val;
294  int hot, err = 0;
295 
296  tsr = bg_ptr->conf->sensors[id].registers;
297  /* obtain the T cold value */
298  thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
299  hot = (thresh_val & tsr->threshold_thot_mask) >>
301 
302  if (t_cold >= hot) {
303  /* change the t_hot to t_cold + 5000 millidegrees */
304  err |= add_hyst(t_cold, ts_data->hyst_val, bg_ptr, id, &hot);
305  /* write the new t_hot value */
306  reg_val = thresh_val & (~tsr->threshold_thot_mask);
307  reg_val |= hot << __ffs(tsr->threshold_thot_mask);
308  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
309  thresh_val = reg_val;
310  }
311 
312  /* write the new t_cold value */
313  reg_val = thresh_val & ~tsr->threshold_tcold_mask;
314  reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask));
315  omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
316  if (err) {
317  dev_err(bg_ptr->dev, "failed to reprogram tcold threshold\n");
318  return -EIO;
319  }
320 
321  return temp_sensor_unmask_interrupts(bg_ptr, id, hot, t_cold);
322 }
323 
324 /* This is Tshut Thot config. Call it only if HAS(TSHUT_CONFIG) is set */
325 static int temp_sensor_configure_tshut_hot(struct omap_bandgap *bg_ptr,
326  int id, int tshut_hot)
327 {
328  struct temp_sensor_registers *tsr;
329  u32 reg_val;
330 
331  tsr = bg_ptr->conf->sensors[id].registers;
332  reg_val = omap_bandgap_readl(bg_ptr, tsr->tshut_threshold);
333  reg_val &= ~tsr->tshut_hot_mask;
334  reg_val |= tshut_hot << __ffs(tsr->tshut_hot_mask);
335  omap_bandgap_writel(bg_ptr, reg_val, tsr->tshut_threshold);
336 
337  return 0;
338 }
339 
340 /* This is Tshut Tcold config. Call it only if HAS(TSHUT_CONFIG) is set */
341 static int temp_sensor_configure_tshut_cold(struct omap_bandgap *bg_ptr,
342  int id, int tshut_cold)
343 {
344  struct temp_sensor_registers *tsr;
345  u32 reg_val;
346 
347  tsr = bg_ptr->conf->sensors[id].registers;
348  reg_val = omap_bandgap_readl(bg_ptr, tsr->tshut_threshold);
349  reg_val &= ~tsr->tshut_cold_mask;
350  reg_val |= tshut_cold << __ffs(tsr->tshut_cold_mask);
351  omap_bandgap_writel(bg_ptr, reg_val, tsr->tshut_threshold);
352 
353  return 0;
354 }
355 
356 /* This is counter config. Call it only if HAS(COUNTER) is set */
357 static int configure_temp_sensor_counter(struct omap_bandgap *bg_ptr, int id,
358  u32 counter)
359 {
360  struct temp_sensor_registers *tsr;
361  u32 val;
362 
363  tsr = bg_ptr->conf->sensors[id].registers;
364  val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter);
365  val &= ~tsr->counter_mask;
366  val |= counter << __ffs(tsr->counter_mask);
367  omap_bandgap_writel(bg_ptr, val, tsr->bgap_counter);
368 
369  return 0;
370 }
371 
372 #define bandgap_is_valid(b) \
373  (!IS_ERR_OR_NULL(b))
374 #define bandgap_is_valid_sensor_id(b, i) \
375  ((i) >= 0 && (i) < (b)->conf->sensor_count)
376 static inline int omap_bandgap_validate(struct omap_bandgap *bg_ptr, int id)
377 {
378  if (!bandgap_is_valid(bg_ptr)) {
379  pr_err("%s: invalid bandgap pointer\n", __func__);
380  return -EINVAL;
381  }
382 
383  if (!bandgap_is_valid_sensor_id(bg_ptr, id)) {
384  dev_err(bg_ptr->dev, "%s: sensor id out of range (%d)\n",
385  __func__, id);
386  return -ERANGE;
387  }
388 
389  return 0;
390 }
391 
392 /* Exposed APIs */
401 int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id,
402  int *thot)
403 {
404  struct temp_sensor_registers *tsr;
405  u32 temp;
406  int ret;
407 
408  ret = omap_bandgap_validate(bg_ptr, id);
409  if (ret)
410  return ret;
411 
412  if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT))
413  return -ENOTSUPP;
414 
415  tsr = bg_ptr->conf->sensors[id].registers;
416  temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
417  temp = (temp & tsr->threshold_thot_mask) >>
419  ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp);
420  if (ret) {
421  dev_err(bg_ptr->dev, "failed to read thot\n");
422  return -EIO;
423  }
424 
425  *thot = temp;
426 
427  return 0;
428 }
429 
438 int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val)
439 {
440  struct temp_sensor_data *ts_data;
441  struct temp_sensor_registers *tsr;
442  u32 t_hot;
443  int ret;
444 
445  ret = omap_bandgap_validate(bg_ptr, id);
446  if (ret)
447  return ret;
448 
449  if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT))
450  return -ENOTSUPP;
451 
452  ts_data = bg_ptr->conf->sensors[id].ts_data;
453  tsr = bg_ptr->conf->sensors[id].registers;
454 
455  if (val < ts_data->min_temp + ts_data->hyst_val)
456  return -EINVAL;
457  ret = temp_to_adc_conversion(val, bg_ptr, id, &t_hot);
458  if (ret < 0)
459  return ret;
460 
461  mutex_lock(&bg_ptr->bg_mutex);
462  temp_sensor_configure_thot(bg_ptr, id, t_hot);
463  mutex_unlock(&bg_ptr->bg_mutex);
464 
465  return 0;
466 }
467 
476 int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id,
477  int *tcold)
478 {
479  struct temp_sensor_registers *tsr;
480  u32 temp;
481  int ret;
482 
483  ret = omap_bandgap_validate(bg_ptr, id);
484  if (ret)
485  return ret;
486 
487  if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT))
488  return -ENOTSUPP;
489 
490  tsr = bg_ptr->conf->sensors[id].registers;
491  temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
492  temp = (temp & tsr->threshold_tcold_mask)
493  >> __ffs(tsr->threshold_tcold_mask);
494  ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp);
495  if (ret)
496  return -EIO;
497 
498  *tcold = temp;
499 
500  return 0;
501 }
502 
511 int omap_bandgap_write_tcold(struct omap_bandgap *bg_ptr, int id, int val)
512 {
513  struct temp_sensor_data *ts_data;
514  struct temp_sensor_registers *tsr;
515  u32 t_cold;
516  int ret;
517 
518  ret = omap_bandgap_validate(bg_ptr, id);
519  if (ret)
520  return ret;
521 
522  if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT))
523  return -ENOTSUPP;
524 
525  ts_data = bg_ptr->conf->sensors[id].ts_data;
526  tsr = bg_ptr->conf->sensors[id].registers;
527  if (val > ts_data->max_temp + ts_data->hyst_val)
528  return -EINVAL;
529 
530  ret = temp_to_adc_conversion(val, bg_ptr, id, &t_cold);
531  if (ret < 0)
532  return ret;
533 
534  mutex_lock(&bg_ptr->bg_mutex);
535  temp_sensor_configure_tcold(bg_ptr, id, t_cold);
536  mutex_unlock(&bg_ptr->bg_mutex);
537 
538  return 0;
539 }
540 
550  int *interval)
551 {
552  struct temp_sensor_registers *tsr;
553  u32 time;
554  int ret;
555 
556  ret = omap_bandgap_validate(bg_ptr, id);
557  if (ret)
558  return ret;
559 
560  if (!OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
561  return -ENOTSUPP;
562 
563  tsr = bg_ptr->conf->sensors[id].registers;
564  time = omap_bandgap_readl(bg_ptr, tsr->bgap_counter);
565  if (ret)
566  return ret;
567  time = (time & tsr->counter_mask) >> __ffs(tsr->counter_mask);
568  time = time * 1000 / bg_ptr->clk_rate;
569 
570  *interval = time;
571 
572  return 0;
573 }
574 
584  int id, u32 interval)
585 {
586  int ret = omap_bandgap_validate(bg_ptr, id);
587  if (ret)
588  return ret;
589 
590  if (!OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
591  return -ENOTSUPP;
592 
593  interval = interval * bg_ptr->clk_rate / 1000;
594  mutex_lock(&bg_ptr->bg_mutex);
595  configure_temp_sensor_counter(bg_ptr, id, interval);
596  mutex_unlock(&bg_ptr->bg_mutex);
597 
598  return 0;
599 }
600 
609 int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id,
610  int *temperature)
611 {
612  struct temp_sensor_registers *tsr;
613  u32 temp;
614  int ret;
615 
616  ret = omap_bandgap_validate(bg_ptr, id);
617  if (ret)
618  return ret;
619 
620  tsr = bg_ptr->conf->sensors[id].registers;
621  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
622  temp &= tsr->bgap_dtemp_mask;
623 
624  ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp);
625  if (ret)
626  return -EIO;
627 
628  *temperature = temp;
629 
630  return 0;
631 }
632 
642 int omap_bandgap_set_sensor_data(struct omap_bandgap *bg_ptr, int id,
643  void *data)
644 {
645  int ret = omap_bandgap_validate(bg_ptr, id);
646  if (ret)
647  return ret;
648 
649  bg_ptr->conf->sensors[id].data = data;
650 
651  return 0;
652 }
653 
662 void *omap_bandgap_get_sensor_data(struct omap_bandgap *bg_ptr, int id)
663 {
664  int ret = omap_bandgap_validate(bg_ptr, id);
665  if (ret)
666  return ERR_PTR(ret);
667 
668  return bg_ptr->conf->sensors[id].data;
669 }
670 
671 static int
672 omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id)
673 {
674  struct temp_sensor_registers *tsr;
675  u32 temp = 0, counter = 1000;
676 
677  tsr = bg_ptr->conf->sensors[id].registers;
678  /* Select single conversion mode */
679  if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) {
680  temp = omap_bandgap_readl(bg_ptr, tsr->bgap_mode_ctrl);
681  temp &= ~(1 << __ffs(tsr->mode_ctrl_mask));
682  omap_bandgap_writel(bg_ptr, temp, tsr->bgap_mode_ctrl);
683  }
684 
685  /* Start of Conversion = 1 */
686  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
687  temp |= 1 << __ffs(tsr->bgap_soc_mask);
688  omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl);
689  /* Wait until DTEMP is updated */
690  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
691  temp &= (tsr->bgap_dtemp_mask);
692  while ((temp == 0) && --counter) {
693  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
694  temp &= (tsr->bgap_dtemp_mask);
695  }
696  /* Start of Conversion = 0 */
697  temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
698  temp &= ~(1 << __ffs(tsr->bgap_soc_mask));
699  omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl);
700 
701  return 0;
702 }
703 
710 static int enable_continuous_mode(struct omap_bandgap *bg_ptr)
711 {
712  struct temp_sensor_registers *tsr;
713  int i;
714  u32 val;
715 
716  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
717  /* Perform a single read just before enabling continuous */
718  omap_bandgap_force_single_read(bg_ptr, i);
719  tsr = bg_ptr->conf->sensors[i].registers;
720  val = omap_bandgap_readl(bg_ptr, tsr->bgap_mode_ctrl);
721  val |= 1 << __ffs(tsr->mode_ctrl_mask);
722  omap_bandgap_writel(bg_ptr, val, tsr->bgap_mode_ctrl);
723  }
724 
725  return 0;
726 }
727 
728 static int omap_bandgap_tshut_init(struct omap_bandgap *bg_ptr,
729  struct platform_device *pdev)
730 {
731  int gpio_nr = bg_ptr->tshut_gpio;
732  int status;
733 
734  /* Request for gpio_86 line */
735  status = gpio_request(gpio_nr, "tshut");
736  if (status < 0) {
737  dev_err(bg_ptr->dev,
738  "Could not request for TSHUT GPIO:%i\n", 86);
739  return status;
740  }
741  status = gpio_direction_input(gpio_nr);
742  if (status) {
743  dev_err(bg_ptr->dev,
744  "Cannot set input TSHUT GPIO %d\n", gpio_nr);
745  return status;
746  }
747 
748  status = request_irq(gpio_to_irq(gpio_nr),
749  omap_bandgap_tshut_irq_handler,
750  IRQF_TRIGGER_RISING, "tshut",
751  NULL);
752  if (status) {
753  gpio_free(gpio_nr);
754  dev_err(bg_ptr->dev, "request irq failed for TSHUT");
755  }
756 
757  return 0;
758 }
759 
760 /* Initialization of Talert. Call it only if HAS(TALERT) is set */
761 static int omap_bandgap_talert_init(struct omap_bandgap *bg_ptr,
762  struct platform_device *pdev)
763 {
764  int ret;
765 
766  bg_ptr->irq = platform_get_irq(pdev, 0);
767  if (bg_ptr->irq < 0) {
768  dev_err(&pdev->dev, "get_irq failed\n");
769  return bg_ptr->irq;
770  }
771  ret = request_threaded_irq(bg_ptr->irq, NULL,
772  talert_irq_handler,
774  "talert", bg_ptr);
775  if (ret) {
776  dev_err(&pdev->dev, "Request threaded irq failed.\n");
777  return ret;
778  }
779 
780  return 0;
781 }
782 
783 static const struct of_device_id of_omap_bandgap_match[];
784 static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev)
785 {
786  struct device_node *node = pdev->dev.of_node;
787  const struct of_device_id *of_id;
788  struct omap_bandgap *bg_ptr;
789  struct resource *res;
790  u32 prop;
791  int i;
792 
793  /* just for the sake */
794  if (!node) {
795  dev_err(&pdev->dev, "no platform information available\n");
796  return ERR_PTR(-EINVAL);
797  }
798 
799  bg_ptr = devm_kzalloc(&pdev->dev, sizeof(struct omap_bandgap),
800  GFP_KERNEL);
801  if (!bg_ptr) {
802  dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
803  return ERR_PTR(-ENOMEM);
804  }
805 
806  of_id = of_match_device(of_omap_bandgap_match, &pdev->dev);
807  if (of_id)
808  bg_ptr->conf = of_id->data;
809 
810  i = 0;
811  do {
812  void __iomem *chunk;
813 
814  res = platform_get_resource(pdev, IORESOURCE_MEM, i);
815  if (!res)
816  break;
817  chunk = devm_request_and_ioremap(&pdev->dev, res);
818  if (i == 0)
819  bg_ptr->base = chunk;
820  if (!chunk) {
821  dev_err(&pdev->dev,
822  "failed to request the IO (%d:%pR).\n",
823  i, res);
824  return ERR_PTR(-EADDRNOTAVAIL);
825  }
826  i++;
827  } while (res);
828 
829  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT)) {
830  if (of_property_read_u32(node, "ti,tshut-gpio", &prop) < 0) {
831  dev_err(&pdev->dev, "missing tshut gpio in device tree\n");
832  return ERR_PTR(-EINVAL);
833  }
834  bg_ptr->tshut_gpio = prop;
835  if (!gpio_is_valid(bg_ptr->tshut_gpio)) {
836  dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
837  bg_ptr->tshut_gpio);
838  return ERR_PTR(-EINVAL);
839  }
840  }
841 
842  return bg_ptr;
843 }
844 
845 static
846 int __devinit omap_bandgap_probe(struct platform_device *pdev)
847 {
848  struct omap_bandgap *bg_ptr;
849  int clk_rate, ret = 0, i;
850 
851  bg_ptr = omap_bandgap_build(pdev);
852  if (IS_ERR_OR_NULL(bg_ptr)) {
853  dev_err(&pdev->dev, "failed to fetch platform data\n");
854  return PTR_ERR(bg_ptr);
855  }
856  bg_ptr->dev = &pdev->dev;
857 
858  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT)) {
859  ret = omap_bandgap_tshut_init(bg_ptr, pdev);
860  if (ret) {
861  dev_err(&pdev->dev,
862  "failed to initialize system tshut IRQ\n");
863  return ret;
864  }
865  }
866 
867  bg_ptr->fclock = clk_get(NULL, bg_ptr->conf->fclock_name);
868  ret = IS_ERR_OR_NULL(bg_ptr->fclock);
869  if (ret) {
870  dev_err(&pdev->dev, "failed to request fclock reference\n");
871  goto free_irqs;
872  }
873 
874  bg_ptr->div_clk = clk_get(NULL, bg_ptr->conf->div_ck_name);
875  ret = IS_ERR_OR_NULL(bg_ptr->div_clk);
876  if (ret) {
877  dev_err(&pdev->dev,
878  "failed to request div_ts_ck clock ref\n");
879  goto free_irqs;
880  }
881 
882  bg_ptr->conv_table = bg_ptr->conf->conv_table;
883  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
884  struct temp_sensor_registers *tsr;
885  u32 val;
886 
887  tsr = bg_ptr->conf->sensors[i].registers;
888  /*
889  * check if the efuse has a non-zero value if not
890  * it is an untrimmed sample and the temperatures
891  * may not be accurate
892  */
893  val = omap_bandgap_readl(bg_ptr, tsr->bgap_efuse);
894  if (ret || !val)
895  dev_info(&pdev->dev,
896  "Non-trimmed BGAP, Temp not accurate\n");
897  }
898 
899  clk_rate = clk_round_rate(bg_ptr->div_clk,
900  bg_ptr->conf->sensors[0].ts_data->max_freq);
901  if (clk_rate < bg_ptr->conf->sensors[0].ts_data->min_freq ||
902  clk_rate == 0xffffffff) {
903  ret = -ENODEV;
904  dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
905  goto put_clks;
906  }
907 
908  ret = clk_set_rate(bg_ptr->div_clk, clk_rate);
909  if (ret)
910  dev_err(&pdev->dev, "Cannot re-set clock rate. Continuing\n");
911 
912  bg_ptr->clk_rate = clk_rate;
913  clk_enable(bg_ptr->fclock);
914 
915  mutex_init(&bg_ptr->bg_mutex);
916  bg_ptr->dev = &pdev->dev;
917  platform_set_drvdata(pdev, bg_ptr);
918 
919  omap_bandgap_power(bg_ptr, true);
920 
921  /* Set default counter to 1 for now */
922  if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
923  for (i = 0; i < bg_ptr->conf->sensor_count; i++)
924  configure_temp_sensor_counter(bg_ptr, i, 1);
925 
926  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
927  struct temp_sensor_data *ts_data;
928 
929  ts_data = bg_ptr->conf->sensors[i].ts_data;
930 
931  if (OMAP_BANDGAP_HAS(bg_ptr, TALERT))
932  temp_sensor_init_talert_thresholds(bg_ptr, i,
933  ts_data->t_hot,
934  ts_data->t_cold);
935  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) {
936  temp_sensor_configure_tshut_hot(bg_ptr, i,
937  ts_data->tshut_hot);
938  temp_sensor_configure_tshut_cold(bg_ptr, i,
939  ts_data->tshut_cold);
940  }
941  }
942 
943  if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
944  enable_continuous_mode(bg_ptr);
945 
946  /* Set .250 seconds time as default counter */
947  if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
948  for (i = 0; i < bg_ptr->conf->sensor_count; i++)
949  configure_temp_sensor_counter(bg_ptr, i,
950  bg_ptr->clk_rate / 4);
951 
952  /* Every thing is good? Then expose the sensors */
953  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
954  char *domain;
955 
956  if (bg_ptr->conf->sensors[i].register_cooling)
957  bg_ptr->conf->sensors[i].register_cooling(bg_ptr, i);
958 
959  domain = bg_ptr->conf->sensors[i].domain;
960  if (bg_ptr->conf->expose_sensor)
961  bg_ptr->conf->expose_sensor(bg_ptr, i, domain);
962  }
963 
964  /*
965  * Enable the Interrupts once everything is set. Otherwise irq handler
966  * might be called as soon as it is enabled where as rest of framework
967  * is still getting initialised.
968  */
969  if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
970  ret = omap_bandgap_talert_init(bg_ptr, pdev);
971  if (ret) {
972  dev_err(&pdev->dev, "failed to initialize Talert IRQ\n");
973  i = bg_ptr->conf->sensor_count;
974  goto disable_clk;
975  }
976  }
977 
978  return 0;
979 
980 disable_clk:
981  clk_disable(bg_ptr->fclock);
982 put_clks:
983  clk_put(bg_ptr->fclock);
984  clk_put(bg_ptr->div_clk);
985 free_irqs:
986  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT)) {
987  free_irq(gpio_to_irq(bg_ptr->tshut_gpio), NULL);
988  gpio_free(bg_ptr->tshut_gpio);
989  }
990 
991  return ret;
992 }
993 
994 static
995 int __devexit omap_bandgap_remove(struct platform_device *pdev)
996 {
997  struct omap_bandgap *bg_ptr = platform_get_drvdata(pdev);
998  int i;
999 
1000  /* First thing is to remove sensor interfaces */
1001  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
1002  if (bg_ptr->conf->sensors[i].register_cooling)
1003  bg_ptr->conf->sensors[i].unregister_cooling(bg_ptr, i);
1004 
1005  if (bg_ptr->conf->remove_sensor)
1006  bg_ptr->conf->remove_sensor(bg_ptr, i);
1007  }
1008 
1009  omap_bandgap_power(bg_ptr, false);
1010 
1011  clk_disable(bg_ptr->fclock);
1012  clk_put(bg_ptr->fclock);
1013  clk_put(bg_ptr->div_clk);
1014 
1015  if (OMAP_BANDGAP_HAS(bg_ptr, TALERT))
1016  free_irq(bg_ptr->irq, bg_ptr);
1017 
1018  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT)) {
1019  free_irq(gpio_to_irq(bg_ptr->tshut_gpio), NULL);
1020  gpio_free(bg_ptr->tshut_gpio);
1021  }
1022 
1023  return 0;
1024 }
1025 
1026 #ifdef CONFIG_PM
1027 static int omap_bandgap_save_ctxt(struct omap_bandgap *bg_ptr)
1028 {
1029  int i;
1030 
1031  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
1032  struct temp_sensor_registers *tsr;
1033  struct temp_sensor_regval *rval;
1034 
1035  rval = &bg_ptr->conf->sensors[i].regval;
1036  tsr = bg_ptr->conf->sensors[i].registers;
1037 
1038  if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
1039  rval->bg_mode_ctrl = omap_bandgap_readl(bg_ptr,
1040  tsr->bgap_mode_ctrl);
1041  if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
1042  rval->bg_counter = omap_bandgap_readl(bg_ptr,
1043  tsr->bgap_counter);
1044  if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
1045  rval->bg_threshold = omap_bandgap_readl(bg_ptr,
1046  tsr->bgap_threshold);
1047  rval->bg_ctrl = omap_bandgap_readl(bg_ptr,
1048  tsr->bgap_mask_ctrl);
1049  }
1050 
1051  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG))
1052  rval->tshut_threshold = omap_bandgap_readl(bg_ptr,
1053  tsr->tshut_threshold);
1054  }
1055 
1056  return 0;
1057 }
1058 
1059 static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr)
1060 {
1061  int i;
1062  u32 temp = 0;
1063 
1064  for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
1065  struct temp_sensor_registers *tsr;
1066  struct temp_sensor_regval *rval;
1067  u32 val = 0;
1068 
1069  rval = &bg_ptr->conf->sensors[i].regval;
1070  tsr = bg_ptr->conf->sensors[i].registers;
1071 
1072  if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
1073  val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter);
1074 
1075  if (val == 0) {
1076  if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG))
1077  omap_bandgap_writel(bg_ptr,
1078  rval->tshut_threshold,
1079  tsr->tshut_threshold);
1080  /* Force immediate temperature measurement and update
1081  * of the DTEMP field
1082  */
1083  omap_bandgap_force_single_read(bg_ptr, i);
1084 
1085  if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
1086  omap_bandgap_writel(bg_ptr, rval->bg_counter,
1087  tsr->bgap_counter);
1088  if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
1089  omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl,
1090  tsr->bgap_mode_ctrl);
1091  if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
1092  omap_bandgap_writel(bg_ptr,
1093  rval->bg_threshold,
1094  tsr->bgap_threshold);
1095  omap_bandgap_writel(bg_ptr, rval->bg_ctrl,
1096  tsr->bgap_mask_ctrl);
1097  }
1098  } else {
1099  temp = omap_bandgap_readl(bg_ptr,
1100  tsr->temp_sensor_ctrl);
1101  temp &= (tsr->bgap_dtemp_mask);
1102  omap_bandgap_force_single_read(bg_ptr, i);
1103  if (temp == 0 && OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
1104  temp = omap_bandgap_readl(bg_ptr,
1105  tsr->bgap_mask_ctrl);
1106  temp |= 1 << __ffs(tsr->mode_ctrl_mask);
1107  omap_bandgap_writel(bg_ptr, temp,
1108  tsr->bgap_mask_ctrl);
1109  }
1110  }
1111  }
1112 
1113  return 0;
1114 }
1115 
1116 static int omap_bandgap_suspend(struct device *dev)
1117 {
1118  struct omap_bandgap *bg_ptr = dev_get_drvdata(dev);
1119  int err;
1120 
1121  err = omap_bandgap_save_ctxt(bg_ptr);
1122  omap_bandgap_power(bg_ptr, false);
1123  clk_disable(bg_ptr->fclock);
1124 
1125  return err;
1126 }
1127 
1128 static int omap_bandgap_resume(struct device *dev)
1129 {
1130  struct omap_bandgap *bg_ptr = dev_get_drvdata(dev);
1131 
1132  clk_enable(bg_ptr->fclock);
1133  omap_bandgap_power(bg_ptr, true);
1134 
1135  return omap_bandgap_restore_ctxt(bg_ptr);
1136 }
1137 static const struct dev_pm_ops omap_bandgap_dev_pm_ops = {
1138  SET_SYSTEM_SLEEP_PM_OPS(omap_bandgap_suspend,
1139  omap_bandgap_resume)
1140 };
1141 
1142 #define DEV_PM_OPS (&omap_bandgap_dev_pm_ops)
1143 #else
1144 #define DEV_PM_OPS NULL
1145 #endif
1146 
1147 static const struct of_device_id of_omap_bandgap_match[] = {
1148 #ifdef CONFIG_OMAP4_THERMAL
1149  {
1150  .compatible = "ti,omap4430-bandgap",
1151  .data = (void *)&omap4430_data,
1152  },
1153  {
1154  .compatible = "ti,omap4460-bandgap",
1155  .data = (void *)&omap4460_data,
1156  },
1157  {
1158  .compatible = "ti,omap4470-bandgap",
1159  .data = (void *)&omap4470_data,
1160  },
1161 #endif
1162 #ifdef CONFIG_OMAP5_THERMAL
1163  {
1164  .compatible = "ti,omap5430-bandgap",
1165  .data = (void *)&omap5430_data,
1166  },
1167 #endif
1168  /* Sentinel */
1169  { },
1170 };
1171 MODULE_DEVICE_TABLE(of, of_omap_bandgap_match);
1172 
1173 static struct platform_driver omap_bandgap_sensor_driver = {
1174  .probe = omap_bandgap_probe,
1175  .remove = omap_bandgap_remove,
1176  .driver = {
1177  .name = "omap-bandgap",
1178  .pm = DEV_PM_OPS,
1179  .of_match_table = of_omap_bandgap_match,
1180  },
1181 };
1182 
1183 module_platform_driver(omap_bandgap_sensor_driver);
1184 
1185 MODULE_DESCRIPTION("OMAP4+ bandgap temperature sensor driver");
1186 MODULE_LICENSE("GPL v2");
1187 MODULE_ALIAS("platform:omap-bandgap");
1188 MODULE_AUTHOR("Texas Instrument Inc.");