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
tsadc_temp_to_raw(struct tsadc_softc * sc,int temp)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
tsadc_raw_to_temp(struct tsadc_softc * sc,uint32_t raw)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
tsadc_init_tsensor(struct tsadc_softc * sc,struct tsensor * sensor)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
tsadc_init(struct tsadc_softc * sc)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
tsadc_read_temp(struct tsadc_softc * sc,struct tsensor * sensor,int * temp)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
tsadc_get_temp(device_t dev,device_t cdev,uintptr_t id,int * val)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
tsadc_sysctl_temperature(SYSCTL_HANDLER_ARGS)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
tsadc_init_sysctl(struct tsadc_softc * sc)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
tsadc_intr(void * arg)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
tsadc_probe(device_t dev)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
tsadc_attach(device_t dev)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
tsadc_detach(device_t dev)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);
881