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