xref: /freebsd/sys/arm64/rockchip/rk_tsadc.c (revision d500a85e640d1cd270747c12e17c511b53864436)
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 /* 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
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
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
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
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
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
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
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
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
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
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
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
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