]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/rockchip/rk_tsadc.c
efidev: Allow for optionally including efidev and efirtc into the kernel
[FreeBSD/FreeBSD.git] / sys / arm64 / rockchip / rk_tsadc.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2019 Michal Meloun <mmel@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 /*
30  * Thermometer and thermal zones driver for RockChip SoCs.
31  * Calibration data are taken from Linux, because this part of SoC
32  * is undocumented in TRM.
33  */
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/bus.h>
38 #include <sys/gpio.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/malloc.h>
42 #include <sys/rman.h>
43 #include <sys/sysctl.h>
44
45 #include <machine/bus.h>
46
47 #include <dev/clk/clk.h>
48 #include <dev/hwreset/hwreset.h>
49 #include <dev/syscon/syscon.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52
53 #include "syscon_if.h"
54 #include "rk_tsadc_if.h"
55
56 /* Version of HW */
57 #define TSADC_V2                                1
58 #define TSADC_V3                                2
59 #define TSADC_V7                                3
60
61 /* Global registers */
62 #define TSADC_USER_CON                          0x000
63 #define TSADC_AUTO_CON                          0x004
64 #define  TSADC_AUTO_CON_POL_HI                          (1 << 8)
65 #define  TSADC_AUTO_SRC_EN(x)                           (1 << (4 + (x)))
66 #define  TSADC_AUTO_Q_SEL                               (1 << 1) /* V3 only */
67 #define  TSADC_AUTO_CON_AUTO                            (1 << 0)
68
69 #define TSADC_INT_EN                            0x008
70 #define  TSADC_INT_EN_2CRU_EN_SRC(x)                    (1 << (8 + (x)))
71 #define  TSADC_INT_EN_2GPIO_EN_SRC(x)                   (1 << (4 + (x)))
72 #define TSADC_INT_PD                            0x00c
73 #define TSADC_DATA(x)                           (0x20 + (x) * 0x04)
74 #define TSADC_COMP_INT(x)                       (0x30 + (x) * 0x04)
75 #define  TSADC_COMP_INT_SRC_EN(x)                       (1 << (0 + (x)))
76 #define TSADC_COMP_SHUT(x)                      (0x40 + (x) * 0x04)
77 #define TSADC_HIGHT_INT_DEBOUNCE                0x060
78 #define TSADC_HIGHT_TSHUT_DEBOUNCE              0x064
79 #define TSADC_AUTO_PERIOD                       0x068
80 #define TSADC_AUTO_PERIOD_HT                    0x06c
81 #define TSADC_COMP0_LOW_INT                     0x080   /* V3 only */
82 #define TSADC_COMP1_LOW_INT                     0x084   /* V3 only */
83
84 /* V3 GFR registers */
85 #define GRF_SARADC_TESTBIT                      0x0e644
86 #define  GRF_SARADC_TESTBIT_ON                          (0x10001 << 2)
87 #define GRF_TSADC_TESTBIT_L                     0x0e648
88 #define  GRF_TSADC_VCM_EN_L                             (0x10001 << 7)
89 #define GRF_TSADC_TESTBIT_H                     0x0e64c
90 #define  GRF_TSADC_VCM_EN_H                             (0x10001 << 7)
91 #define  GRF_TSADC_TESTBIT_H_ON                         (0x10001 << 2)
92
93 /* V7 GRF register */
94 #define GRF_TSADC_CON                           0x0600
95 #define  GRF_TSADC_ANA_REG0                     (0x10001 << 0)
96 #define  GRF_TSADC_ANA_REG1                     (0x10001 << 1)
97 #define  GRF_TSADC_ANA_REG2                     (0x10001 << 2)
98 #define  GRF_TSADC_TSEN                         (0x10001 << 8)
99
100 #define WR4(_sc, _r, _v)        bus_write_4((_sc)->mem_res, (_r), (_v))
101 #define RD4(_sc, _r)            bus_read_4((_sc)->mem_res, (_r))
102
103 static struct sysctl_ctx_list tsadc_sysctl_ctx;
104
105 struct tsensor {
106         char                    *name;
107         int                     id;
108         int                     channel;
109 };
110
111 struct rk_calib_entry {
112         uint32_t        raw;
113         int             temp;
114 };
115
116 struct tsadc_calib_info {
117         struct rk_calib_entry   *table;
118         int                     nentries;
119 };
120
121 struct tsadc_conf {
122         int                     version;
123         int                     q_sel_ntc;
124         int                     shutdown_temp;
125         int                     shutdown_mode;
126         int                     shutdown_pol;
127         struct tsensor          *tsensors;
128         int                     ntsensors;
129         struct tsadc_calib_info calib_info;
130 };
131
132 struct tsadc_softc {
133         device_t                dev;
134         struct resource         *mem_res;
135         struct resource         *irq_res;
136         void                    *irq_ih;
137
138         clk_t                   tsadc_clk;
139         clk_t                   apb_pclk_clk;
140         hwreset_array_t         hwreset;
141         struct syscon           *grf;
142
143         struct tsadc_conf       *conf;
144
145         int                     shutdown_temp;
146         int                     shutdown_mode;
147         int                     shutdown_pol;
148
149         int                     alarm_temp;
150 };
151
152 static struct rk_calib_entry rk3288_calib_data[] = {
153         {3800, -40000},
154         {3792, -35000},
155         {3783, -30000},
156         {3774, -25000},
157         {3765, -20000},
158         {3756, -15000},
159         {3747, -10000},
160         {3737, -5000},
161         {3728, 0},
162         {3718, 5000},
163         {3708, 10000},
164         {3698, 15000},
165         {3688, 20000},
166         {3678, 25000},
167         {3667, 30000},
168         {3656, 35000},
169         {3645, 40000},
170         {3634, 45000},
171         {3623, 50000},
172         {3611, 55000},
173         {3600, 60000},
174         {3588, 65000},
175         {3575, 70000},
176         {3563, 75000},
177         {3550, 80000},
178         {3537, 85000},
179         {3524, 90000},
180         {3510, 95000},
181         {3496, 100000},
182         {3482, 105000},
183         {3467, 110000},
184         {3452, 115000},
185         {3437, 120000},
186         {3421, 125000},
187 };
188
189 struct tsensor rk3288_tsensors[] = {
190         { .channel = 0, .id = 2, .name = "reserved"},
191         { .channel = 1, .id = 0, .name = "CPU"},
192         { .channel = 2, .id = 1, .name = "GPU"},
193 };
194
195 struct tsadc_conf rk3288_tsadc_conf = {
196         .version =              TSADC_V2,
197         .q_sel_ntc =            0,
198         .shutdown_temp =        95000,
199         .shutdown_mode =        1, /* GPIO */
200         .shutdown_pol =         0, /* Low  */
201         .tsensors =             rk3288_tsensors,
202         .ntsensors =            nitems(rk3288_tsensors),
203         .calib_info =   {
204                         .table = rk3288_calib_data,
205                         .nentries = nitems(rk3288_calib_data),
206         }
207 };
208
209 static struct rk_calib_entry rk3328_calib_data[] = {
210         {296, -40000},
211         {304, -35000},
212         {313, -30000},
213         {331, -20000},
214         {340, -15000},
215         {349, -10000},
216         {359, -5000},
217         {368, 0},
218         {378, 5000},
219         {388, 10000},
220         {398, 15000},
221         {408, 20000},
222         {418, 25000},
223         {429, 30000},
224         {440, 35000},
225         {451, 40000},
226         {462, 45000},
227         {473, 50000},
228         {485, 55000},
229         {496, 60000},
230         {508, 65000},
231         {521, 70000},
232         {533, 75000},
233         {546, 80000},
234         {559, 85000},
235         {572, 90000},
236         {586, 95000},
237         {600, 100000},
238         {614, 105000},
239         {629, 110000},
240         {644, 115000},
241         {659, 120000},
242         {675, 125000},
243 };
244
245 static struct tsensor rk3328_tsensors[] = {
246         { .channel = 0, .id = 0, .name = "CPU"},
247 };
248
249 static struct tsadc_conf rk3328_tsadc_conf = {
250         .version =              TSADC_V2,
251         .q_sel_ntc =            1,
252         .shutdown_temp =        95000,
253         .shutdown_mode =        0, /* CRU */
254         .shutdown_pol =         0, /* Low  */
255         .tsensors =             rk3328_tsensors,
256         .ntsensors =            nitems(rk3328_tsensors),
257         .calib_info =   {
258                         .table = rk3328_calib_data,
259                         .nentries = nitems(rk3328_calib_data),
260         }
261 };
262
263 static struct rk_calib_entry rk3399_calib_data[] = {
264         {402, -40000},
265         {410, -35000},
266         {419, -30000},
267         {427, -25000},
268         {436, -20000},
269         {444, -15000},
270         {453, -10000},
271         {461, -5000},
272         {470, 0},
273         {478, 5000},
274         {487, 10000},
275         {496, 15000},
276         {504, 20000},
277         {513, 25000},
278         {521, 30000},
279         {530, 35000},
280         {538, 40000},
281         {547, 45000},
282         {555, 50000},
283         {564, 55000},
284         {573, 60000},
285         {581, 65000},
286         {590, 70000},
287         {599, 75000},
288         {607, 80000},
289         {616, 85000},
290         {624, 90000},
291         {633, 95000},
292         {642, 100000},
293         {650, 105000},
294         {659, 110000},
295         {668, 115000},
296         {677, 120000},
297         {685, 125000},
298 };
299
300 static struct tsensor rk3399_tsensors[] = {
301         { .channel = 0, .id = 0, .name = "CPU"},
302         { .channel = 1, .id = 1, .name = "GPU"},
303 };
304
305 static struct tsadc_conf rk3399_tsadc_conf = {
306         .version =              TSADC_V3,
307         .q_sel_ntc =            1,
308         .shutdown_temp =        95000,
309         .shutdown_mode =        1, /* GPIO */
310         .shutdown_pol =         0, /* Low  */
311         .tsensors =             rk3399_tsensors,
312         .ntsensors =            nitems(rk3399_tsensors),
313         .calib_info =   {
314                         .table = rk3399_calib_data,
315                         .nentries = nitems(rk3399_calib_data),
316         }
317 };
318
319 static struct rk_calib_entry rk3568_calib_data[] = {
320         {0, -40000},
321         {1584, -40000},
322         {1620, -35000},
323         {1652, -30000},
324         {1688, -25000},
325         {1720, -20000},
326         {1756, -15000},
327         {1788, -10000},
328         {1824, -5000},
329         {1856, 0},
330         {1892, 5000},
331         {1924, 10000},
332         {1956, 15000},
333         {1992, 20000},
334         {2024, 25000},
335         {2060, 30000},
336         {2092, 35000},
337         {2128, 40000},
338         {2160, 45000},
339         {2196, 50000},
340         {2228, 55000},
341         {2264, 60000},
342         {2300, 65000},
343         {2332, 70000},
344         {2368, 75000},
345         {2400, 80000},
346         {2436, 85000},
347         {2468, 90000},
348         {2500, 95000},
349         {2536, 100000},
350         {2572, 105000},
351         {2604, 110000},
352         {2636, 115000},
353         {2672, 120000},
354         {2704, 125000},
355 };
356
357 static struct tsensor rk3568_tsensors[] = {
358         { .channel = 0, .id = 0, .name = "CPU"},
359         { .channel = 1, .id = 1, .name = "GPU"},
360 };
361
362 static struct tsadc_conf rk3568_tsadc_conf = {
363         .version =              TSADC_V7,
364         .q_sel_ntc =            1,
365         .shutdown_temp =        95000,
366         .shutdown_mode =        1, /* GPIO */
367         .shutdown_pol =         0, /* Low  */
368         .tsensors =             rk3568_tsensors,
369         .ntsensors =            nitems(rk3568_tsensors),
370         .calib_info =   {
371                         .table = rk3568_calib_data,
372                         .nentries = nitems(rk3568_calib_data),
373         }
374 };
375
376 static struct ofw_compat_data compat_data[] = {
377         {"rockchip,rk3288-tsadc",       (uintptr_t)&rk3288_tsadc_conf},
378         {"rockchip,rk3328-tsadc",       (uintptr_t)&rk3328_tsadc_conf},
379         {"rockchip,rk3399-tsadc",       (uintptr_t)&rk3399_tsadc_conf},
380         {"rockchip,rk3568-tsadc",       (uintptr_t)&rk3568_tsadc_conf},
381         {NULL,          0}
382 };
383
384 static uint32_t
385 tsadc_temp_to_raw(struct tsadc_softc *sc, int temp)
386 {
387         struct rk_calib_entry *tbl;
388         int denom, ntbl, raw, i;
389
390         tbl = sc->conf->calib_info.table;
391         ntbl = sc->conf->calib_info.nentries;
392
393         if (temp <= tbl[0].temp)
394                 return (tbl[0].raw);
395
396         if (temp >= tbl[ntbl - 1].temp)
397                 return (tbl[ntbl - 1].raw);
398
399         for (i = 1; i < (ntbl - 1); i++) {
400                 /* Exact match */
401                 if (temp == tbl[i].temp)
402                         return (tbl[i].raw);
403                 if (temp < tbl[i].temp)
404                         break;
405         }
406
407         /*
408         * Translated value is between i and i - 1 table entries.
409         * Do linear interpolation for it.
410         */
411         raw = (int)tbl[i - 1].raw - (int)tbl[i].raw;
412         raw *= temp - tbl[i - 1].temp;
413         denom = tbl[i - 1].temp - tbl[i].temp;
414         raw = tbl[i - 1].raw + raw / denom;
415         return (raw);
416 }
417
418 static int
419 tsadc_raw_to_temp(struct tsadc_softc *sc, uint32_t raw)
420 {
421         struct rk_calib_entry *tbl;
422         int denom, ntbl, temp, i;
423         bool descending;
424
425         tbl = sc->conf->calib_info.table;
426         ntbl = sc->conf->calib_info.nentries;
427         descending = tbl[0].raw > tbl[1].raw;
428
429         if (descending) {
430                 /* Raw column is in descending order. */
431                 if (raw >= tbl[0].raw)
432                         return (tbl[0].temp);
433                 if (raw <= tbl[ntbl - 1].raw)
434                         return (tbl[ntbl - 1].temp);
435
436                 for (i = ntbl - 2; i > 0; i--) {
437                         /* Exact match */
438                         if (raw == tbl[i].raw)
439                                 return (tbl[i].temp);
440                         if (raw < tbl[i].raw)
441                                 break;
442                 }
443         } else {
444                 /* Raw column is in ascending order. */
445                 if (raw <= tbl[0].raw)
446                         return (tbl[0].temp);
447                 if (raw >= tbl[ntbl - 1].raw)
448                         return (tbl[ntbl - 1].temp);
449                 for (i = 1; i < (ntbl - 1); i++) {
450                         /* Exact match */
451                         if (raw == tbl[i].raw)
452                                 return (tbl[i].temp);
453                         if (raw < tbl[i].raw)
454                                 break;
455                 }
456         }
457
458         /*
459         * Translated value is between i and i - 1 table entries.
460         * Do linear interpolation for it.
461         */
462         temp  = (int)tbl[i - 1].temp - (int)tbl[i].temp;
463         temp *= raw - tbl[i - 1].raw;
464         denom = tbl[i - 1].raw - tbl[i].raw;
465         temp = tbl[i - 1].temp + temp / denom;
466         return (temp);
467 }
468
469 static void
470 tsadc_init_tsensor(struct tsadc_softc *sc, struct tsensor *sensor)
471 {
472         uint32_t val;
473
474         /* Shutdown mode */
475         val = RD4(sc, TSADC_INT_EN);
476         if (sc->shutdown_mode != 0) {
477                 /* Signal shutdown of GPIO pin */
478                 val &= ~TSADC_INT_EN_2CRU_EN_SRC(sensor->channel);
479                 val |= TSADC_INT_EN_2GPIO_EN_SRC(sensor->channel);
480         } else {
481                 val |= TSADC_INT_EN_2CRU_EN_SRC(sensor->channel);
482                 val &= ~TSADC_INT_EN_2GPIO_EN_SRC(sensor->channel);
483         }
484         WR4(sc, TSADC_INT_EN, val);
485
486         /* Shutdown temperature */
487         val =  tsadc_raw_to_temp(sc, sc->shutdown_temp);
488         WR4(sc, TSADC_COMP_SHUT(sensor->channel), val);
489         val = RD4(sc, TSADC_AUTO_CON);
490         val |= TSADC_AUTO_SRC_EN(sensor->channel);
491         WR4(sc, TSADC_AUTO_CON, val);
492
493         /* Alarm temperature */
494         val =  tsadc_temp_to_raw(sc, sc->alarm_temp);
495         WR4(sc, TSADC_COMP_INT(sensor->channel), val);
496         val = RD4(sc, TSADC_INT_EN);
497         val |= TSADC_COMP_INT_SRC_EN(sensor->channel);
498         WR4(sc, TSADC_INT_EN, val);
499 }
500
501 static void
502 tsadc_init(struct tsadc_softc *sc)
503 {
504         uint32_t val;
505
506         /* Common part */
507         val = 0;        /* XXX Is this right? */
508         if (sc->shutdown_pol != 0)
509                 val |= TSADC_AUTO_CON_POL_HI;
510         else
511                 val &= ~TSADC_AUTO_CON_POL_HI;
512         if (sc->conf->q_sel_ntc)
513                 val |= TSADC_AUTO_Q_SEL;
514         WR4(sc, TSADC_AUTO_CON, val);
515
516         switch (sc->conf->version) {
517         case TSADC_V2:
518                 /* V2 init */
519                 WR4(sc, TSADC_AUTO_PERIOD, 250);        /* 250 ms */
520                 WR4(sc, TSADC_AUTO_PERIOD_HT, 50);      /*  50 ms */
521                 WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
522                 WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
523                 break;
524         case TSADC_V3:
525                 /* V3 init */
526                 if (sc->grf == NULL) {
527                         /* Errata: adjust interleave to working value */
528                         WR4(sc, TSADC_USER_CON, 13 << 6);       /* 13 clks */
529                 } else {
530                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_L,
531                             GRF_TSADC_VCM_EN_L);
532                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_H,
533                             GRF_TSADC_VCM_EN_H);
534                         DELAY(30);  /* 15 usec min */
535
536                         SYSCON_WRITE_4(sc->grf, GRF_SARADC_TESTBIT,
537                             GRF_SARADC_TESTBIT_ON);
538                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_H,
539                             GRF_TSADC_TESTBIT_H_ON);
540                         DELAY(180);  /* 90 usec min */
541                 }
542                 WR4(sc, TSADC_AUTO_PERIOD, 1875);       /* 2.5 ms */
543                 WR4(sc, TSADC_AUTO_PERIOD_HT, 1875);    /* 2.5 ms */
544                 WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
545                 WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
546                 break;
547         case TSADC_V7:
548                 /* V7 init */
549                 WR4(sc, TSADC_USER_CON, 0xfc0);         /* 97us, at least 90us */
550                 WR4(sc, TSADC_AUTO_PERIOD, 1622);       /* 2.5ms */
551                 WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
552                 WR4(sc, TSADC_AUTO_PERIOD_HT, 1622);    /* 2.5ms */
553                 WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
554                 if (sc->grf) {
555                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON, GRF_TSADC_TSEN);
556                         DELAY(15);                      /* 10 usec min */
557                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON,
558                             GRF_TSADC_ANA_REG0);
559                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON,
560                             GRF_TSADC_ANA_REG1);
561                         SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON,
562                             GRF_TSADC_ANA_REG2);
563                         DELAY(100);                     /* 90 usec min */
564                 }
565                 break;
566         }
567 }
568
569 static int
570 tsadc_read_temp(struct tsadc_softc *sc, struct tsensor *sensor, int *temp)
571 {
572         uint32_t val;
573
574         val = RD4(sc, TSADC_DATA(sensor->channel));
575         *temp = tsadc_raw_to_temp(sc, val);
576
577 #ifdef DEBUG
578         device_printf(sc->dev, "%s: Sensor(id: %d, ch: %d), val: %d temp: %d\n",
579             __func__, sensor->id, sensor->channel, val, *temp);
580         device_printf(sc->dev, "%s: user_con=0x%08x auto_con=0x%08x "
581             "comp_int=0x%08x comp_shut=0x%08x\n",
582             __func__, RD4(sc, TSADC_USER_CON), RD4(sc, TSADC_AUTO_CON),
583             RD4(sc, TSADC_COMP_INT(sensor->channel)),
584             RD4(sc, TSADC_COMP_SHUT(sensor->channel)));
585 #endif
586         return (0);
587 }
588
589 static int
590 tsadc_get_temp(device_t dev, device_t cdev, uintptr_t id, int *val)
591 {
592         struct tsadc_softc *sc;
593         int i, rv;
594
595         sc = device_get_softc(dev);
596
597         if (id >= sc->conf->ntsensors)
598                 return (ERANGE);
599
600         for (i = 0; i < sc->conf->ntsensors; i++) {
601                 if (sc->conf->tsensors->id == id) {
602                         rv =tsadc_read_temp(sc, sc->conf->tsensors + id, val);
603                         return (rv);
604                 }
605         }
606         return (ERANGE);
607 }
608
609 static int
610 tsadc_sysctl_temperature(SYSCTL_HANDLER_ARGS)
611 {
612         struct tsadc_softc *sc;
613         int val;
614         int rv;
615         int id;
616
617         /* Write request */
618         if (req->newptr != NULL)
619                 return (EINVAL);
620
621         sc = arg1;
622         id = arg2;
623
624         if (id >= sc->conf->ntsensors)
625                 return (ERANGE);
626         rv =  tsadc_read_temp(sc, sc->conf->tsensors + id, &val);
627         if (rv != 0)
628                 return (rv);
629
630         val = val / 100;
631         val +=  2731;
632         rv = sysctl_handle_int(oidp, &val, 0, req);
633         return (rv);
634 }
635
636 static int
637 tsadc_init_sysctl(struct tsadc_softc *sc)
638 {
639         int i;
640         struct sysctl_oid *oid, *tmp;
641
642         sysctl_ctx_init(&tsadc_sysctl_ctx);
643         /* create node for hw.temp */
644         oid = SYSCTL_ADD_NODE(&tsadc_sysctl_ctx,
645             SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "temperature",
646             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "");
647         if (oid == NULL)
648                 return (ENXIO);
649
650         /* Add sensors */
651         for (i = sc->conf->ntsensors  - 1; i >= 0; i--) {
652                 tmp = SYSCTL_ADD_PROC(&tsadc_sysctl_ctx,
653                     SYSCTL_CHILDREN(oid), OID_AUTO, sc->conf->tsensors[i].name,
654                     CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, i,
655                     tsadc_sysctl_temperature, "IK", "SoC Temperature");
656                 if (tmp == NULL)
657                         return (ENXIO);
658         }
659
660         return (0);
661 }
662
663 static int
664 tsadc_intr(void *arg)
665 {
666         struct tsadc_softc *sc;
667         uint32_t val;
668
669         sc = (struct tsadc_softc *)arg;
670
671         val = RD4(sc, TSADC_INT_PD);
672         WR4(sc, TSADC_INT_PD, val);
673
674         /* XXX Handle shutdown and alarm interrupts. */
675         if (val & 0x00F0) {
676                 device_printf(sc->dev, "Alarm: device temperature "
677                     "is above of shutdown level.\n");
678         } else if (val & 0x000F) {
679                 device_printf(sc->dev, "Alarm: device temperature "
680                     "is above of alarm level.\n");
681         }
682         return (FILTER_HANDLED);
683 }
684
685 static int
686 tsadc_probe(device_t dev)
687 {
688
689         if (!ofw_bus_status_okay(dev))
690                 return (ENXIO);
691
692         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
693                 return (ENXIO);
694
695         device_set_desc(dev, "RockChip temperature sensors");
696         return (BUS_PROBE_DEFAULT);
697 }
698
699 static int
700 tsadc_attach(device_t dev)
701 {
702         struct tsadc_softc *sc;
703         phandle_t node;
704         uint32_t val;
705         int i, rid, rv;
706
707         sc = device_get_softc(dev);
708         sc->dev = dev;
709         node = ofw_bus_get_node(sc->dev);
710         sc->conf = (struct tsadc_conf *)
711             ofw_bus_search_compatible(dev, compat_data)->ocd_data;
712         sc->alarm_temp = 90000;
713
714         rid = 0;
715         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
716             RF_ACTIVE);
717         if (sc->mem_res == NULL) {
718                 device_printf(dev, "Cannot allocate memory resources\n");
719                 goto fail;
720         }
721
722         rid = 0;
723         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
724         if (sc->irq_res == NULL) {
725                 device_printf(dev, "Cannot allocate IRQ resources\n");
726                 goto fail;
727         }
728
729         if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
730             tsadc_intr, NULL, sc, &sc->irq_ih))) {
731                 device_printf(dev,
732                     "WARNING: unable to register interrupt handler\n");
733                 goto fail;
734         }
735
736         /* FDT resources */
737         rv = hwreset_array_get_ofw(dev, 0, &sc->hwreset);
738         if (rv != 0) {
739                 device_printf(dev, "Cannot get resets\n");
740                 goto fail;
741         }
742         rv = clk_get_by_ofw_name(dev, 0, "tsadc", &sc->tsadc_clk);
743         if (rv != 0) {
744                 device_printf(dev, "Cannot get 'tsadc' clock: %d\n", rv);
745                 goto fail;
746         }
747         rv = clk_get_by_ofw_name(dev, 0, "apb_pclk", &sc->apb_pclk_clk);
748         if (rv != 0) {
749                 device_printf(dev, "Cannot get 'apb_pclk' clock: %d\n", rv);
750                 goto fail;
751         }
752
753         /* grf is optional */
754         rv = syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf);
755         if (rv != 0 && rv != ENOENT) {
756                 device_printf(dev, "Cannot get 'grf' syscon: %d\n", rv);
757                 goto fail;
758         }
759
760         rv = OF_getencprop(node, "rockchip,hw-tshut-temp",
761             &sc->shutdown_temp, sizeof(sc->shutdown_temp));
762         if (rv <= 0)
763                 sc->shutdown_temp = sc->conf->shutdown_temp;
764
765         rv = OF_getencprop(node, "rockchip,hw-tshut-mode",
766             &sc->shutdown_mode, sizeof(sc->shutdown_mode));
767         if (rv <= 0)
768                 sc->shutdown_mode = sc->conf->shutdown_mode;
769
770         rv = OF_getencprop(node, "rockchip,hw-tshut-polarity",
771             &sc->shutdown_pol, sizeof(sc->shutdown_pol));
772         if (rv <= 0)
773                 sc->shutdown_pol = sc->conf->shutdown_pol;
774
775         /* Wakeup controller */
776         rv = hwreset_array_assert(sc->hwreset);
777         if (rv != 0) {
778                 device_printf(dev, "Cannot assert reset\n");
779                 goto fail;
780         }
781
782         /* Set the assigned clocks parent and freq */
783         rv = clk_set_assigned(sc->dev, node);
784         if (rv != 0 && rv != ENOENT) {
785                 device_printf(dev, "clk_set_assigned failed\n");
786                 goto fail;
787         }
788
789         rv = clk_enable(sc->tsadc_clk);
790         if (rv != 0) {
791                 device_printf(dev, "Cannot enable 'tsadc_clk' clock: %d\n", rv);
792                 goto fail;
793         }
794         rv = clk_enable(sc->apb_pclk_clk);
795         if (rv != 0) {
796                 device_printf(dev, "Cannot enable 'apb_pclk' clock: %d\n", rv);
797                 goto fail;
798         }
799         rv = hwreset_array_deassert(sc->hwreset);
800         if (rv != 0) {
801                 device_printf(dev, "Cannot deassert reset\n");
802                 goto fail;
803         }
804
805         tsadc_init(sc);
806         for (i = 0; i < sc->conf->ntsensors; i++)
807                 tsadc_init_tsensor(sc, sc->conf->tsensors + i);
808
809         /* Enable auto mode */
810         val = RD4(sc, TSADC_AUTO_CON);
811         val |= TSADC_AUTO_CON_AUTO;
812         WR4(sc, TSADC_AUTO_CON, val);
813
814         rv = tsadc_init_sysctl(sc);
815         if (rv != 0) {
816                 device_printf(sc->dev, "Cannot initialize sysctls\n");
817                 goto fail_sysctl;
818         }
819
820         OF_device_register_xref(OF_xref_from_node(node), dev);
821         return (bus_generic_attach(dev));
822
823 fail_sysctl:
824         sysctl_ctx_free(&tsadc_sysctl_ctx);
825 fail:
826         if (sc->irq_ih != NULL)
827                 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
828         if (sc->tsadc_clk != NULL)
829                 clk_release(sc->tsadc_clk);
830         if (sc->apb_pclk_clk != NULL)
831                 clk_release(sc->apb_pclk_clk);
832         if (sc->hwreset != NULL)
833                 hwreset_array_release(sc->hwreset);
834         if (sc->irq_res != NULL)
835                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
836         if (sc->mem_res != NULL)
837                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
838
839         return (ENXIO);
840 }
841
842 static int
843 tsadc_detach(device_t dev)
844 {
845         struct tsadc_softc *sc;
846         sc = device_get_softc(dev);
847
848         if (sc->irq_ih != NULL)
849                 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
850         sysctl_ctx_free(&tsadc_sysctl_ctx);
851         if (sc->tsadc_clk != NULL)
852                 clk_release(sc->tsadc_clk);
853         if (sc->apb_pclk_clk != NULL)
854                 clk_release(sc->apb_pclk_clk);
855         if (sc->hwreset != NULL)
856                 hwreset_array_release(sc->hwreset);
857         if (sc->irq_res != NULL)
858                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
859         if (sc->mem_res != NULL)
860                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
861
862         return (ENXIO);
863 }
864
865 static device_method_t rk_tsadc_methods[] = {
866         /* Device interface */
867         DEVMETHOD(device_probe,                 tsadc_probe),
868         DEVMETHOD(device_attach,                tsadc_attach),
869         DEVMETHOD(device_detach,                tsadc_detach),
870
871         /* TSADC interface */
872         DEVMETHOD(rk_tsadc_get_temperature,     tsadc_get_temp),
873
874         DEVMETHOD_END
875 };
876
877 static DEFINE_CLASS_0(rk_tsadc, rk_tsadc_driver, rk_tsadc_methods,
878     sizeof(struct tsadc_softc));
879 EARLY_DRIVER_MODULE(rk_tsadc, simplebus, rk_tsadc_driver, NULL, NULL,
880     BUS_PASS_TIMER + BUS_PASS_ORDER_LAST);