xref: /netbsd-src/sys/arch/arm/rockchip/rk_tsadc.c (revision d90047b5d07facf36e6c01dcc0bded8997ce9cc2)
1 /*	$NetBSD: rk_tsadc.c,v 1.7 2019/07/03 20:55:21 jmcneill Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 
33 __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.7 2019/07/03 20:55:21 jmcneill Exp $");
34 
35 /*
36  * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399.
37  *
38  * TODO:
39  * - handle setting various temp values
40  * - handle DT trips/temp value defaults
41  * - interrupts aren't triggered (test by lowering warn/crit values), and
42  *   once they work, make the interrupt do something
43  */
44 
45 #include <sys/param.h>
46 #include <sys/bus.h>
47 #include <sys/device.h>
48 #include <sys/intr.h>
49 #include <sys/systm.h>
50 #include <sys/time.h>
51 #include <sys/kmem.h>
52 
53 #include <dev/fdt/fdtvar.h>
54 #include <dev/fdt/syscon.h>
55 
56 #include <dev/sysmon/sysmonvar.h>
57 
58 #ifdef RKTSADC_DEBUG
59 #define DPRINTF(fmt, ...) \
60 	printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
61 #else
62 #define DPRINTF(fmt, ...)
63 #endif
64 
65 /* Register definitions */
66 #define TSADC_USER_CON                          0x00
67 #define  TSADC_USER_CON_ADC_STATUS              __BIT(12)
68 #define  TSADC_USER_CON_INTER_PD_SOC            __BITS(11,6)
69 #define  TSADC_USER_CON_START                   __BIT(5)
70 #define  TSADC_USER_CON_START_MODE              __BIT(4)
71 #define  TSADC_USER_CON_ADC_POWER_CTRL          __BIT(3)
72 #define  TSADC_USER_CON_ADC_INPUT_SRC_SEL       __BITS(2,0)
73 #define TSADC_AUTO_CON                          0x04
74 #define  TSADC_AUTO_CON_LAST_TSHUT_2CRU         __BIT(25)
75 #define  TSADC_AUTO_CON_LAST_TSHUT_2GPIO        __BIT(24)
76 #define  TSADC_AUTO_CON_SAMPLE_DLY_SEL          __BIT(17)
77 #define  TSADC_AUTO_CON_AUTO_STATUS             __BIT(16)
78 #define  TSADC_AUTO_CON_SRC1_LT_EN              __BIT(13)
79 #define  TSADC_AUTO_CON_SRC0_LT_EN              __BIT(12)
80 #define  TSADC_AUTO_CON_TSHUT_POLARITY          __BIT(8)
81 #define  TSADC_AUTO_CON_SRC1_EN                 __BIT(5)
82 #define  TSADC_AUTO_CON_SRC0_EN                 __BIT(4)
83 #define  TSADC_AUTO_CON_Q_SEL                   __BIT(1)
84 #define  TSADC_AUTO_CON_AUTO_EN                 __BIT(0)
85 #define TSADC_INT_EN                            0x08
86 #define  TSADC_INT_EN_EOC_INT_EN                __BIT(16)
87 #define  TSADC_INT_EN_LT_INTEN_SRC1             __BIT(13)
88 #define  TSADC_INT_EN_LT_INTEN_SRC0             __BIT(12)
89 #define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC1        __BIT(9)
90 #define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC0        __BIT(8)
91 #define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1       __BIT(5)
92 #define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0       __BIT(4)
93 #define  TSADC_INT_EN_HT_INTEN_SRC1             __BIT(1)
94 #define  TSADC_INT_EN_HT_INTEN_SRC0             __BIT(0)
95 #define TSADC_INT_PD                            0x0c
96 #define  TSADC_INT_PD_EOC_INT_PD                __BIT(16)
97 #define  TSADC_INT_PD_LT_IRQ_SRC1               __BIT(13)
98 #define  TSADC_INT_PD_LT_IRQ_SRC0               __BIT(12)
99 #define  TSADC_INT_PD_TSHUT_O_SRC1              __BIT(5)
100 #define  TSADC_INT_PD_TSHUT_O_SRC0              __BIT(4)
101 #define  TSADC_INT_PD_HT_IRQ_SRC1               __BIT(1)
102 #define  TSADC_INT_PD_HT_IRQ_SRC0               __BIT(0)
103 #define TSADC_DATA0                             0x20
104 #define  TSADC_DATA0_ADC_DATA                   __BITS(11,0)
105 #define TSADC_DATA1                             0x24
106 #define  TSADC_DATA1_ADC_DATA                   __BITS(11,0)
107 #define TSADC_COMP0_INT                         0x30
108 #define  TSADC_COMP0_INT_COMP_SRC0              __BITS(11,0)
109 #define TSADC_COMP1_INT                         0x34
110 #define  TSADC_COMP1_INT_COMP_SRC1              __BITS(11,0)
111 #define TSADC_COMP0_SHUT                        0x40
112 #define  TSADC_COMP0_SHUT_COMP_SRC0             __BITS(11,0)
113 #define TSADC_COMP1_SHUT                        0x44
114 #define  TSADC_COMP1_SHUT_COMP_SRC1             __BITS(11,0)
115 #define TSADC_HIGH_INT_DEBOUNCE                 0x60
116 #define  TSADC_HIGH_INT_DEBOUNCE_TEMP           __BITS(7,0)
117 #define TSADC_HIGH_TSHUT_DEBOUNCE               0x64
118 #define  TSADC_HIGH_TSHUT_DEBOUNCE_TEMP         __BITS(7,0)
119 #define TSADC_AUTO_PERIOD                       0x68
120 #define  TSADC_AUTO_PERIOD_TEMP                 __BITS(31,0)
121 #define TSADC_AUTO_PERIOD_HT                    0x6c
122 #define  TSADC_AUTO_PERIOD_HT_TEMP              __BITS(31,0)
123 #define TSADC_COMP0_LOW_INT                     0x80
124 #define  TSADC_COMP0_LOW_INT_COMP_SRC0          __BITS(11,0)
125 #define TSADC_COMP1_LOW_INT                     0x84
126 #define  TSADC_COMP1_LOW_INT_COMP_SRC1          __BITS(11,0)
127 
128 #define RK3328_TSADC_AUTO_PERIOD_TIME           250 /* 250ms */
129 #define RK3399_TSADC_AUTO_PERIOD_TIME           1875 /* 2.5ms */
130 #define TSADC_HT_DEBOUNCE_COUNT                 4
131 
132 /*
133  * All this magic is taking from the Linux rockchip_thermal driver.
134  *
135  * VCM means "voltage common mode", but the documentation for RK3399
136  * does not mention this and I don't know what any of this really
137  * is for.
138  */
139 #define RK3399_GRF_SARADC_TESTBIT               0xe644
140 #define  RK3399_GRF_SARADC_TESTBIT_ON           (0x10001 << 2)
141 #define RK3399_GRF_TSADC_TESTBIT_L              0xe648
142 #define  RK3399_GRF_TSADC_TESTBIT_VCM_EN_L      (0x10001 << 7)
143 #define RK3399_GRF_TSADC_TESTBIT_H              0xe64c
144 #define  RK3399_GRF_TSADC_TESTBIT_VCM_EN_H      (0x10001 << 7)
145 #define  RK3399_GRF_TSADC_TESTBIT_H_ON          (0x10001 << 2)
146 
147 #define TEMP_uC_TO_uK             273150000
148 
149 #define TSHUT_MODE_CPU    0
150 #define TSHUT_MODE_GPIO   1
151 
152 #define TSHUT_LOW_ACTIVE  0
153 #define TSHUT_HIGH_ACTIVE 1
154 
155 #define TSHUT_DEF_TEMP    95000
156 
157 #define TSADC_DATA_MAX    0xfff
158 
159 #define MAX_SENSORS       2
160 
161 typedef struct rk_data_array {
162 	uint32_t data;  /* register value */
163 	int temp;       /* micro-degC */
164 } rk_data_array;
165 
166 struct rk_tsadc_softc;
167 typedef struct rk_data {
168 	const rk_data_array	*rd_array;
169 	size_t			 rd_size;
170 	void			(*rd_init)(struct rk_tsadc_softc *, int, int);
171 	bool			 rd_decr;  /* lower values -> higher temp */
172 	unsigned		 rd_min, rd_max;
173 	unsigned		 rd_auto_period;
174 	unsigned		 rd_num_sensors;
175 } rk_data;
176 
177 /* Per-sensor data */
178 struct rk_tsadc_sensor {
179 	envsys_data_t	s_data;
180 	bool		s_attached;
181 	/* TSADC register offsets for this sensor */
182 	unsigned	s_data_reg;
183 	unsigned	s_comp_tshut;
184 	unsigned	s_comp_int;
185 	/* enable bit in AUTO_CON register */
186 	unsigned	s_comp_int_en;
187 	/* warn/crit values in micro Kelvin */
188 	int		s_warn;
189 	int		s_tshut;
190 };
191 
192 struct rk_tsadc_softc {
193 	device_t		sc_dev;
194 	int			sc_phandle;
195 	bus_space_tag_t		sc_bst;
196 	bus_space_handle_t	sc_bsh;
197 	size_t			sc_size;
198 	uint32_t		sc_data_mask;
199 	void			*sc_ih;
200 
201 	struct sysmon_envsys	*sc_sme;
202 	struct rk_tsadc_sensor	sc_sensors[MAX_SENSORS];
203 
204 	struct clk		*sc_clock;
205 	struct clk		*sc_clockapb;
206 	struct fdtbus_reset	*sc_reset;
207 	struct syscon		*sc_syscon;
208 
209 	const rk_data		*sc_rd;
210 };
211 
212 static int rk_tsadc_match(device_t, cfdata_t, void *);
213 static void rk_tsadc_attach(device_t, device_t, void *);
214 static int rk_tsadc_detach(device_t, int);
215 static int rk_tsadc_init_clocks(struct rk_tsadc_softc *);
216 static void rk_tsadc_init_counts(struct rk_tsadc_softc *);
217 static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s);
218 static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int);
219 static void rk_tsadc_init_rk3328(struct rk_tsadc_softc *, int, int);
220 static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int);
221 static void rk_tsadc_init_enable(struct rk_tsadc_softc *);
222 static void rk_tsadc_init(struct rk_tsadc_softc *, int, int);
223 static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *);
224 static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *,
225                                 sysmon_envsys_lim_t *, uint32_t *);
226 
227 static int rk_tsadc_intr(void *);
228 static int rk_tsadc_data_to_temp(struct rk_tsadc_softc *, uint32_t);
229 static uint32_t rk_tsadc_temp_to_data(struct rk_tsadc_softc *, int);
230 
231 /* RK3328/RK3399 compatible sensors */
232 static const struct rk_tsadc_sensor rk_tsadc_sensors[] = {
233 	{
234 	  .s_data = { .desc = "CPU" },
235 	  .s_data_reg = TSADC_DATA0,
236 	  .s_comp_tshut = TSADC_COMP0_SHUT,
237 	  .s_comp_int = TSADC_COMP0_INT,
238 	  .s_comp_int_en = TSADC_AUTO_CON_SRC0_EN,
239 	  /*
240 	   * XXX DT has:
241 	   * cpu_alert1: cpu_alert1 {
242 	   *	temperature = <75000>;
243 	   *	hysteresis = <2000>;
244 	   * cpu_crit: cpu_crit {
245 	   *    temperature = <95000>;
246 	   *    hysteresis = <2000>;
247 	   * pull out of here?
248 	   * do something with hysteresis?  put in debounce?
249 	   *
250 	   * Note that tshut may be overriden by the board specific DT.
251 	   */
252 	  .s_warn = 75000000,
253 	  .s_tshut = 95000000,
254 	}, {
255 	  .s_data = { .desc = "GPU" },
256 	  .s_data_reg = TSADC_DATA1,
257 	  .s_comp_tshut = TSADC_COMP1_SHUT,
258 	  .s_comp_int = TSADC_COMP1_INT,
259 	  .s_comp_int_en = TSADC_AUTO_CON_SRC1_EN,
260 	  .s_warn = 75000000,
261 	  .s_tshut = 95000000,
262 	},
263 };
264 
265 /*
266  * Table from RK3328 manual.  Note that the manual lists valid numbers as
267  * 4096 - number.  This also means it is increasing not decreasing for
268  * higher temps, and the min and max are also offset from 4096.
269  */
270 #define RK3328_DATA_OFFSET (4096)
271 static const rk_data_array rk3328_data_array[] = {
272 #define ENTRY(d,C) \
273 	{ .data = RK3328_DATA_OFFSET - (d), .temp = (C) * 1000 * 1000, }
274 	ENTRY(TSADC_DATA_MAX,    -40),
275 	ENTRY(3800, -40),
276 	ENTRY(3792, -35),
277 	ENTRY(3783, -30),
278 	ENTRY(3774, -25),
279 	ENTRY(3765, -20),
280 	ENTRY(3756, -15),
281 	ENTRY(3747, -10),
282 	ENTRY(3737,  -5),
283 	ENTRY(3728,   0),
284 	ENTRY(3718,   5),
285 	ENTRY(3708,  10),
286 	ENTRY(3698,  15),
287 	ENTRY(3688,  20),
288 	ENTRY(3678,  25),
289 	ENTRY(3667,  30),
290 	ENTRY(3656,  35),
291 	ENTRY(3645,  40),
292 	ENTRY(3634,  45),
293 	ENTRY(3623,  50),
294 	ENTRY(3611,  55),
295 	ENTRY(3600,  60),
296 	ENTRY(3588,  65),
297 	ENTRY(3575,  70),
298 	ENTRY(3563,  75),
299 	ENTRY(3550,  80),
300 	ENTRY(3537,  85),
301 	ENTRY(3524,  90),
302 	ENTRY(3510,  95),
303 	ENTRY(3496, 100),
304 	ENTRY(3482, 105),
305 	ENTRY(3467, 110),
306 	ENTRY(3452, 115),
307 	ENTRY(3437, 120),
308 	ENTRY(3421, 125),
309 	ENTRY(0,    125),
310 #undef ENTRY
311 };
312 
313 /* Table from RK3399 manual */
314 static const rk_data_array rk3399_data_array[] = {
315 #define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
316 	ENTRY(0,   -40),
317 	ENTRY(402, -40),
318 	ENTRY(410, -35),
319 	ENTRY(419, -30),
320 	ENTRY(427, -25),
321 	ENTRY(436, -20),
322 	ENTRY(444, -15),
323 	ENTRY(453, -10),
324 	ENTRY(461,  -5),
325 	ENTRY(470,   0),
326 	ENTRY(478,   5),
327 	ENTRY(487,  10),
328 	ENTRY(496,  15),
329 	ENTRY(504,  20),
330 	ENTRY(513,  25),
331 	ENTRY(521,  30),
332 	ENTRY(530,  35),
333 	ENTRY(538,  40),
334 	ENTRY(547,  45),
335 	ENTRY(555,  50),
336 	ENTRY(564,  55),
337 	ENTRY(573,  60),
338 	ENTRY(581,  65),
339 	ENTRY(590,  70),
340 	ENTRY(599,  75),
341 	ENTRY(607,  80),
342 	ENTRY(616,  85),
343 	ENTRY(624,  90),
344 	ENTRY(633,  95),
345 	ENTRY(642, 100),
346 	ENTRY(650, 105),
347 	ENTRY(659, 110),
348 	ENTRY(668, 115),
349 	ENTRY(677, 120),
350 	ENTRY(685, 125),
351 	ENTRY(TSADC_DATA_MAX, 125),
352 #undef ENTRY
353 };
354 
355 static const rk_data rk3328_data_table = {
356 	.rd_array = rk3328_data_array,
357 	.rd_size = __arraycount(rk3328_data_array),
358 	.rd_init = rk_tsadc_init_rk3328,
359 	.rd_decr = false,
360 	.rd_max = RK3328_DATA_OFFSET - 3420,
361 	.rd_min = RK3328_DATA_OFFSET - 3801,
362 	.rd_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME,
363 	.rd_num_sensors = 1,
364 };
365 
366 static const rk_data rk3399_data_table = {
367 	.rd_array = rk3399_data_array,
368 	.rd_size = __arraycount(rk3399_data_array),
369 	.rd_init = rk_tsadc_init_rk3399,
370 	.rd_decr = false,
371 	.rd_max = 686,
372 	.rd_min = 401,
373 	.rd_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME,
374 	.rd_num_sensors = 2,
375 };
376 
377 static const char * const compatible_rk3328[] = {
378 	"rockchip,rk3328-tsadc",
379 	NULL
380 };
381 
382 static const char * const compatible_rk3399[] = {
383 	"rockchip,rk3399-tsadc",
384 	NULL
385 };
386 
387 #define	TSADC_READ(sc, reg)		\
388 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
389 #define	TSADC_WRITE(sc, reg, val)	\
390 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
391 
392 CFATTACH_DECL3_NEW(rk_tsadc, sizeof(struct rk_tsadc_softc),
393 	rk_tsadc_match, rk_tsadc_attach, rk_tsadc_detach, NULL, NULL, NULL,
394 	DVF_DETACH_SHUTDOWN);
395 
396 /* init/teardown support */
397 static int
398 rk_tsadc_match(device_t parent, cfdata_t cf, void *aux)
399 {
400 	struct fdt_attach_args * const faa = aux;
401 
402 	return of_match_compatible(faa->faa_phandle, compatible_rk3328) ||
403 	       of_match_compatible(faa->faa_phandle, compatible_rk3399);
404 }
405 
406 static void
407 rk_tsadc_attach(device_t parent, device_t self, void *aux)
408 {
409 	struct rk_tsadc_softc * const sc = device_private(self);
410 	struct fdt_attach_args * const faa = aux;
411 	char intrstr[128];
412 	const int phandle = faa->faa_phandle;
413 	bus_addr_t addr;
414 	int mode, polarity, tshut_temp;
415 
416 	sc->sc_dev = self;
417 	sc->sc_phandle = phandle;
418 	sc->sc_bst = faa->faa_bst;
419 
420 	aprint_naive("\n");
421 	aprint_normal(": RK3328/3399 Temperature Sensor ADC\n");
422 
423 	sc->sc_sme = sysmon_envsys_create();
424 
425 	sc->sc_sme->sme_name = device_xname(self);
426 	sc->sc_sme->sme_cookie = sc;
427 	sc->sc_sme->sme_refresh = rk_tsadc_refresh;
428 	sc->sc_sme->sme_get_limits = rk_tsadc_get_limits;
429 	sc->sc_data_mask = TSADC_DATA_MAX;
430 
431 	pmf_device_register(self, NULL, NULL);
432 
433 	if (of_match_compatible(faa->faa_phandle, compatible_rk3328)) {
434 		sc->sc_rd = &rk3328_data_table;
435 	} else {
436 		KASSERT(of_match_compatible(faa->faa_phandle, compatible_rk3399));
437 		sc->sc_rd = &rk3399_data_table;
438 	}
439 
440 	/* Default to tshut via gpio and tshut low is active */
441 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode",
442 			      &mode) != 0) {
443 		aprint_error(": could not get TSHUT mode, default to GPIO");
444 		mode = TSHUT_MODE_GPIO;
445 	}
446 	if (mode != TSHUT_MODE_CPU && mode != TSHUT_MODE_GPIO) {
447 		aprint_error(": TSHUT mode should be 0 or 1\n");
448 		goto fail;
449 	}
450 
451 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-polarity",
452 			      &polarity) != 0) {
453 		aprint_error(": could not get TSHUT polarity, default to low");
454 		polarity = TSHUT_LOW_ACTIVE;
455 	}
456 	if (of_getprop_uint32(phandle,
457 			      "rockchip,hw-tshut-temp", &tshut_temp) != 0) {
458 		aprint_error(": could not get TSHUT temperature, default to %u",
459 			     TSHUT_DEF_TEMP);
460 		tshut_temp = TSHUT_DEF_TEMP;
461 	}
462 	tshut_temp *= 1000;	/* convert fdt ms -> us */
463 
464 	memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors));
465 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
466 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
467 
468 		rks->s_data.flags = ENVSYS_FMONLIMITS;
469 		rks->s_data.units = ENVSYS_STEMP;
470 		rks->s_data.state = ENVSYS_SINVALID;
471 
472 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &rks->s_data))
473 			goto fail;
474 		rks->s_attached = true;
475 		rks->s_tshut = tshut_temp;
476 #if 0
477 		// testing
478 		rks->s_tshut = 68000000;
479 		rks->s_warn = 61000000;
480 #endif
481 	}
482 
483 	sc->sc_syscon = fdtbus_syscon_acquire(phandle, "rockchip,grf");
484 	if (sc->sc_syscon == NULL) {
485 		aprint_error(": couldn't get grf syscon\n");
486 		goto fail;
487 	}
488 	if (fdtbus_get_reg(phandle, 0, &addr, &sc->sc_size) != 0) {
489 		aprint_error(": couldn't get registers\n");
490 		sc->sc_size = 0;
491 		goto fail;
492 	}
493 	if (bus_space_map(sc->sc_bst, addr, sc->sc_size, 0, &sc->sc_bsh) != 0) {
494 		aprint_error(": couldn't map registers\n");
495 		sc->sc_size = 0;
496 		goto fail;
497 	}
498 
499 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
500 		aprint_error(": failed to decode interrupt\n");
501 		goto fail;
502 	}
503 
504 	sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
505 	    rk_tsadc_intr, sc);
506 	if (sc->sc_ih == NULL) {
507 		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
508 		    intrstr);
509 		goto fail;
510 	}
511 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
512 
513 	if (rk_tsadc_init_clocks(sc)) {
514 		aprint_error(": couldn't enable clocks\n");
515 		return;
516 	}
517 
518 	/*
519 	 * Manual says to setup auto period (both), high temp (interrupt),
520 	 * high temp (shutdown), enable high temp resets (TSHUT to GPIO
521 	 * or reset chip), set the debounce times, and, finally, enable the
522 	 * controller iself.
523 	 */
524 	rk_tsadc_init(sc, mode, polarity);
525 
526 	return;
527 
528 fail:
529 	rk_tsadc_detach(self, 0);
530 }
531 
532 static int
533 rk_tsadc_detach(device_t self, int flags)
534 {
535 	struct rk_tsadc_softc *sc = device_private(self);
536 
537 	pmf_device_deregister(self);
538 
539 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
540 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
541 
542 		if (rks->s_attached) {
543 			sysmon_envsys_sensor_detach(sc->sc_sme, &rks->s_data);
544 			rks->s_attached = false;
545 		}
546 	}
547 
548 	sysmon_envsys_unregister(sc->sc_sme);
549 
550 	if (sc->sc_clockapb)
551 		clk_disable(sc->sc_clockapb);
552 	if (sc->sc_clock)
553 		clk_disable(sc->sc_clock);
554 
555 	if (sc->sc_ih)
556 		fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
557 
558 	if (sc->sc_size)
559 		bus_space_unmap(sc->sc_bst, sc->sc_bsh, sc->sc_size);
560 
561 	sysmon_envsys_destroy(sc->sc_sme);
562 
563 	return 0;
564 }
565 
566 static int
567 rk_tsadc_init_clocks(struct rk_tsadc_softc *sc)
568 {
569 	int error;
570 
571 	fdtbus_clock_assign(sc->sc_phandle);
572 
573 	sc->sc_reset = fdtbus_reset_get(sc->sc_phandle, "tsadc-apb");
574 	sc->sc_clock = fdtbus_clock_get(sc->sc_phandle, "tsadc");
575 	sc->sc_clockapb = fdtbus_clock_get(sc->sc_phandle, "apb_pclk");
576 	if (sc->sc_reset == NULL ||
577 	    sc->sc_clock == NULL ||
578 	    sc->sc_clockapb == NULL)
579 		return EINVAL;
580 
581 	fdtbus_reset_assert(sc->sc_reset);
582 
583 	error = clk_enable(sc->sc_clock);
584 	if (error) {
585 		fdtbus_reset_deassert(sc->sc_reset);
586 		return error;
587 	}
588 
589 	error = clk_enable(sc->sc_clockapb);
590 
591 	DELAY(20);
592 	fdtbus_reset_deassert(sc->sc_reset);
593 
594 	return error;
595 }
596 
597 static void
598 rk_tsadc_init_counts(struct rk_tsadc_softc *sc)
599 {
600 
601 	TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rd->rd_auto_period);
602 	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rd->rd_auto_period);
603 	TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
604 	TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
605 }
606 
607 /* Configure the hardware with the tshut setup. */
608 static void
609 rk_tsadc_tshut_set(struct rk_tsadc_softc *sc)
610 {
611 	uint32_t val = TSADC_READ(sc, TSADC_AUTO_CON);
612 
613 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
614 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
615 		uint32_t data, warndata;
616 
617 		if (!rks->s_attached)
618 			continue;
619 
620 		data = rk_tsadc_temp_to_data(sc, rks->s_tshut);
621 		warndata = rk_tsadc_temp_to_data(sc, rks->s_warn);
622 
623 		DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u",
624 			sc->sc_sme->sme_name, rks->s_data.desc,
625 			rks->s_tshut, data,
626 			rks->s_warn, warndata);
627 
628 		if (data == sc->sc_data_mask) {
629 			aprint_error_dev(sc->sc_dev,
630 			    "Failed converting critical temp %u.%06u to code",
631 			    rks->s_tshut / 1000000, rks->s_tshut % 1000000);
632 			continue;
633 		}
634 		if (warndata == sc->sc_data_mask) {
635 			aprint_error_dev(sc->sc_dev,
636 			    "Failed converting warn temp %u.%06u to code",
637 			    rks->s_warn / 1000000, rks->s_warn % 1000000);
638 			continue;
639 		}
640 
641 		TSADC_WRITE(sc, rks->s_comp_tshut, data);
642 		TSADC_WRITE(sc, rks->s_comp_int, warndata);
643 
644 		val |= rks->s_comp_int_en;
645 	}
646 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
647 }
648 
649 static void
650 rk_tsadc_init_tshut(struct rk_tsadc_softc *sc, int mode, int polarity)
651 {
652 	uint32_t val;
653 
654 	/* Handle TSHUT temp setting. */
655 	rk_tsadc_tshut_set(sc);
656 
657 	/* Handle TSHUT mode setting. */
658 	val = TSADC_READ(sc, TSADC_INT_EN);
659 	if (mode == TSHUT_MODE_CPU) {
660 		val |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
661 		       TSADC_INT_EN_TSHUT_2CRU_EN_SRC0;
662 		val &= ~(TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
663 			 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0);
664 	} else {
665 		KASSERT(mode == TSHUT_MODE_GPIO);
666 		val &= ~(TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
667 			 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0);
668 		val |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
669 		       TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0;
670 	}
671 	TSADC_WRITE(sc, TSADC_INT_EN, val);
672 
673 	/* Handle TSHUT polarity setting. */
674 	val = TSADC_READ(sc, TSADC_AUTO_CON);
675 	if (polarity == TSHUT_HIGH_ACTIVE)
676 		val |= TSADC_AUTO_CON_TSHUT_POLARITY;
677 	else
678 		val &= ~TSADC_AUTO_CON_TSHUT_POLARITY;
679 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
680 }
681 
682 static void
683 rk_tsadc_init_rk3328(struct rk_tsadc_softc *sc, int mode, int polarity)
684 {
685 
686 	rk_tsadc_init_tshut(sc, mode, polarity);
687 	rk_tsadc_init_counts(sc);
688 }
689 
690 static void
691 rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity)
692 {
693 
694 	syscon_lock(sc->sc_syscon);
695 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_L,
696 				      RK3399_GRF_TSADC_TESTBIT_VCM_EN_L);
697 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
698 				      RK3399_GRF_TSADC_TESTBIT_VCM_EN_H);
699 
700 	DELAY(20);
701 	syscon_write_4(sc->sc_syscon, RK3399_GRF_SARADC_TESTBIT,
702 				      RK3399_GRF_SARADC_TESTBIT_ON);
703 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
704 				      RK3399_GRF_TSADC_TESTBIT_H_ON);
705 	DELAY(100);
706 	syscon_unlock(sc->sc_syscon);
707 
708 	rk_tsadc_init_counts(sc);
709 	rk_tsadc_init_tshut(sc, mode, polarity);
710 }
711 
712 static void
713 rk_tsadc_init_enable(struct rk_tsadc_softc *sc)
714 {
715 	uint32_t val;
716 
717 	val = TSADC_READ(sc, TSADC_AUTO_CON);
718 	val |= TSADC_AUTO_CON_AUTO_STATUS |
719 	       TSADC_AUTO_CON_SRC1_LT_EN | TSADC_AUTO_CON_SRC0_LT_EN;
720 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
721 
722 	/* Finally, register & enable the controller */
723 	sysmon_envsys_register(sc->sc_sme);
724 
725 	val = TSADC_READ(sc, TSADC_AUTO_CON);
726 	val |= TSADC_AUTO_CON_AUTO_EN | TSADC_AUTO_CON_Q_SEL;
727 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
728 }
729 
730 static void
731 rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity)
732 {
733 
734 	(*sc->sc_rd->rd_init)(sc, mode, polarity);
735 	rk_tsadc_init_enable(sc);
736 }
737 
738 /* run time support */
739 
740 /* given edata, find the matching rk sensor structure */
741 static struct rk_tsadc_sensor *
742 rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata)
743 {
744 
745 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
746 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
747 
748 		if (&rks->s_data == edata)
749 			return rks;
750 	}
751 	return NULL;
752 }
753 
754 static void
755 rk_tsadc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
756 {
757 	struct rk_tsadc_softc * const sc = sme->sme_cookie;
758 	struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
759 	unsigned data;
760 	int temp;
761 
762 	if (rks == NULL)
763 		return;
764 
765 	data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask;
766 	temp = rk_tsadc_data_to_temp(sc, data);
767 
768 	DPRINTF("(%s:%s): temp/data %d/%u",
769 		sc->sc_sme->sme_name, rks->s_data.desc,
770 		temp, data);
771 
772 	if (temp == sc->sc_data_mask) {
773 		edata->state = ENVSYS_SINVALID;
774 	} else {
775 		edata->value_cur = temp + TEMP_uC_TO_uK;
776 		edata->state = ENVSYS_SVALID;
777 	}
778 }
779 
780 static void
781 rk_tsadc_get_limits(struct sysmon_envsys *sme,
782 		    envsys_data_t *edata,
783 		    sysmon_envsys_lim_t *lim,
784 		    uint32_t *props)
785 {
786 	struct rk_tsadc_softc *sc = sme->sme_cookie;
787 	struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
788 
789 	if (rks == NULL)
790 		return;
791 
792 	lim->sel_critmax = rks->s_tshut + TEMP_uC_TO_uK;
793 	lim->sel_warnmax = rks->s_warn + TEMP_uC_TO_uK;
794 
795 	*props = PROP_CRITMAX | PROP_WARNMAX;
796 }
797 
798 /* XXX do something with interrupts that don't happen yet.  */
799 static int
800 rk_tsadc_intr(void *arg)
801 {
802 	struct rk_tsadc_softc * const sc = arg;
803 	uint32_t val;
804 
805 	/* XXX */
806 	DPRINTF("(%s): interrupted", sc->sc_sme->sme_name);
807 	for (unsigned n = 0; n < __arraycount(rk_tsadc_sensors); n++) {
808 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
809 
810 		rk_tsadc_refresh(sc->sc_sme, (envsys_data_t *)rks);
811 	}
812 
813 	/* ack interrupt */
814 	val = TSADC_READ(sc, TSADC_INT_PD);
815 	TSADC_WRITE(sc, TSADC_INT_PD, val & ~TSADC_INT_PD_EOC_INT_PD);
816 
817 	return 1;
818 }
819 
820 /*
821  * Convert TDASC data codes to temp and reverse.  The manual only has codes
822  * and temperature values in 5 degC intervals, but says that interpolation
823  * can be done to achieve better resolution between these values, and that
824  * the spacing is linear.
825  */
826 static int
827 rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data)
828 {
829 	unsigned i;
830 	const rk_data *rd = sc->sc_rd;
831 
832 	if (data > rd->rd_max || data < rd->rd_min) {
833 		DPRINTF("data out of range (%u > %u || %u < %u)",
834 			data, rd->rd_max, data, rd->rd_min);
835 		return sc->sc_data_mask;
836 	}
837 	for (i = 1; i < rd->rd_size; i++) {
838 		if (rd->rd_array[i].data >= data) {
839 			int temprange, offset;
840 			uint32_t datarange, datadiff;
841 			unsigned first, secnd;
842 
843 			if (rd->rd_array[i].data == data)
844 				return rd->rd_array[i].temp;
845 
846 			/* must interpolate */
847 			if (rd->rd_decr) {
848 				first = i;
849 				secnd = i+1;
850 			} else {
851 				first = i;
852 				secnd = i-1;
853 			}
854 
855 			temprange = rd->rd_array[first].temp -
856 				    rd->rd_array[secnd].temp;
857 			datarange = rd->rd_array[first].data -
858 				    rd->rd_array[secnd].data;
859 			datadiff = data - rd->rd_array[secnd].data;
860 
861 			offset = (temprange * datadiff) / datarange;
862 			return rd->rd_array[secnd].temp + offset;
863 		}
864 	}
865 	panic("didn't find range");
866 }
867 
868 static uint32_t
869 rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp)
870 {
871 	unsigned i;
872 	const rk_data *rd = sc->sc_rd;
873 
874 	for (i = 1; i < rd->rd_size; i++) {
875 		if (rd->rd_array[i].temp >= temp) {
876 			int temprange, tempdiff;
877 			uint32_t datarange, offset;
878 			unsigned first, secnd;
879 
880 			if (rd->rd_array[i].temp == temp)
881 				return rd->rd_array[i].data;
882 
883 			/* must interpolate */
884 			if (rd->rd_decr) {
885 				first = i;
886 				secnd = i+1;
887 			} else {
888 				first = i;
889 				secnd = i-1;
890 			}
891 
892 			datarange = rd->rd_array[first].data -
893 				    rd->rd_array[secnd].data;
894 			temprange = rd->rd_array[first].temp -
895 				    rd->rd_array[secnd].temp;
896 			tempdiff = temp - rd->rd_array[secnd].temp;
897 
898 			offset = (datarange * tempdiff) / temprange;
899 			return rd->rd_array[secnd].data + offset;
900 		}
901 	}
902 
903 	return sc->sc_data_mask;
904 }
905