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