xref: /netbsd-src/sys/arch/arm/rockchip/rk_tsadc.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1 /*	$NetBSD: rk_tsadc.c,v 1.12 2021/01/27 03:10:19 thorpej 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.12 2021/01/27 03:10:19 thorpej 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 struct device_compatible_entry compat_data[] = {
378 	{ .compat = "rockchip,rk3328-tsadc",	.data = &rk3328_data_table },
379 	{ .compat = "rockchip,rk3399-tsadc",	.data = &rk3399_data_table },
380 	DEVICE_COMPAT_EOL
381 };
382 
383 #define	TSADC_READ(sc, reg)		\
384 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
385 #define	TSADC_WRITE(sc, reg, val)	\
386 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
387 
388 CFATTACH_DECL3_NEW(rk_tsadc, sizeof(struct rk_tsadc_softc),
389 	rk_tsadc_match, rk_tsadc_attach, rk_tsadc_detach, NULL, NULL, NULL,
390 	DVF_DETACH_SHUTDOWN);
391 
392 /* init/teardown support */
393 static int
394 rk_tsadc_match(device_t parent, cfdata_t cf, void *aux)
395 {
396 	struct fdt_attach_args * const faa = aux;
397 
398 	return of_compatible_match(faa->faa_phandle, compat_data);
399 }
400 
401 static void
402 rk_tsadc_attach(device_t parent, device_t self, void *aux)
403 {
404 	struct rk_tsadc_softc * const sc = device_private(self);
405 	struct fdt_attach_args * const faa = aux;
406 	char intrstr[128];
407 	const int phandle = faa->faa_phandle;
408 	bus_addr_t addr;
409 	int mode, polarity, tshut_temp;
410 
411 	sc->sc_dev = self;
412 	sc->sc_phandle = phandle;
413 	sc->sc_bst = faa->faa_bst;
414 
415 	aprint_naive("\n");
416 	aprint_normal(": RK3328/3399 Temperature Sensor ADC\n");
417 
418 	sc->sc_sme = sysmon_envsys_create();
419 
420 	sc->sc_sme->sme_name = device_xname(self);
421 	sc->sc_sme->sme_cookie = sc;
422 	sc->sc_sme->sme_refresh = rk_tsadc_refresh;
423 	sc->sc_sme->sme_get_limits = rk_tsadc_get_limits;
424 	sc->sc_data_mask = TSADC_DATA_MAX;
425 
426 	pmf_device_register(self, NULL, NULL);
427 
428 	sc->sc_rd = of_compatible_lookup(faa->faa_phandle, compat_data)->data;
429 
430 	/* Default to tshut via gpio and tshut low is active */
431 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode",
432 			      &mode) != 0) {
433 		aprint_error(": could not get TSHUT mode, default to GPIO");
434 		mode = TSHUT_MODE_GPIO;
435 	}
436 	if (mode != TSHUT_MODE_CPU && mode != TSHUT_MODE_GPIO) {
437 		aprint_error(": TSHUT mode should be 0 or 1\n");
438 		goto fail;
439 	}
440 
441 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-polarity",
442 			      &polarity) != 0) {
443 		aprint_error(": could not get TSHUT polarity, default to low");
444 		polarity = TSHUT_LOW_ACTIVE;
445 	}
446 	if (of_getprop_uint32(phandle,
447 			      "rockchip,hw-tshut-temp", &tshut_temp) != 0) {
448 		aprint_error(": could not get TSHUT temperature, default to %u",
449 			     TSHUT_DEF_TEMP);
450 		tshut_temp = TSHUT_DEF_TEMP;
451 	}
452 	tshut_temp *= 1000;	/* convert fdt ms -> us */
453 
454 	memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors));
455 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
456 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
457 
458 		rks->s_data.flags = ENVSYS_FMONLIMITS;
459 		rks->s_data.units = ENVSYS_STEMP;
460 		rks->s_data.state = ENVSYS_SINVALID;
461 
462 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &rks->s_data))
463 			goto fail;
464 		rks->s_attached = true;
465 		rks->s_tshut = tshut_temp;
466 #if 0
467 		// testing
468 		rks->s_tshut = 68000000;
469 		rks->s_warn = 61000000;
470 #endif
471 	}
472 
473 	sc->sc_syscon = fdtbus_syscon_acquire(phandle, "rockchip,grf");
474 	if (sc->sc_syscon == NULL) {
475 		aprint_error(": couldn't get grf syscon\n");
476 		goto fail;
477 	}
478 	if (fdtbus_get_reg(phandle, 0, &addr, &sc->sc_size) != 0) {
479 		aprint_error(": couldn't get registers\n");
480 		sc->sc_size = 0;
481 		goto fail;
482 	}
483 	if (bus_space_map(sc->sc_bst, addr, sc->sc_size, 0, &sc->sc_bsh) != 0) {
484 		aprint_error(": couldn't map registers\n");
485 		sc->sc_size = 0;
486 		goto fail;
487 	}
488 
489 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
490 		aprint_error(": failed to decode interrupt\n");
491 		goto fail;
492 	}
493 
494 	sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
495 	    rk_tsadc_intr, sc, device_xname(self));
496 	if (sc->sc_ih == NULL) {
497 		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
498 		    intrstr);
499 		goto fail;
500 	}
501 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
502 
503 	if (rk_tsadc_init_clocks(sc)) {
504 		aprint_error(": couldn't enable clocks\n");
505 		return;
506 	}
507 
508 	/*
509 	 * Manual says to setup auto period (both), high temp (interrupt),
510 	 * high temp (shutdown), enable high temp resets (TSHUT to GPIO
511 	 * or reset chip), set the debounce times, and, finally, enable the
512 	 * controller iself.
513 	 */
514 	rk_tsadc_init(sc, mode, polarity);
515 
516 	return;
517 
518 fail:
519 	rk_tsadc_detach(self, 0);
520 }
521 
522 static int
523 rk_tsadc_detach(device_t self, int flags)
524 {
525 	struct rk_tsadc_softc *sc = device_private(self);
526 
527 	pmf_device_deregister(self);
528 
529 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
530 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
531 
532 		if (rks->s_attached) {
533 			sysmon_envsys_sensor_detach(sc->sc_sme, &rks->s_data);
534 			rks->s_attached = false;
535 		}
536 	}
537 
538 	sysmon_envsys_unregister(sc->sc_sme);
539 
540 	if (sc->sc_clockapb)
541 		clk_disable(sc->sc_clockapb);
542 	if (sc->sc_clock)
543 		clk_disable(sc->sc_clock);
544 
545 	if (sc->sc_ih)
546 		fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
547 
548 	if (sc->sc_size)
549 		bus_space_unmap(sc->sc_bst, sc->sc_bsh, sc->sc_size);
550 
551 	sysmon_envsys_destroy(sc->sc_sme);
552 
553 	return 0;
554 }
555 
556 static int
557 rk_tsadc_init_clocks(struct rk_tsadc_softc *sc)
558 {
559 	int error;
560 
561 	fdtbus_clock_assign(sc->sc_phandle);
562 
563 	sc->sc_reset = fdtbus_reset_get(sc->sc_phandle, "tsadc-apb");
564 	sc->sc_clock = fdtbus_clock_get(sc->sc_phandle, "tsadc");
565 	sc->sc_clockapb = fdtbus_clock_get(sc->sc_phandle, "apb_pclk");
566 	if (sc->sc_reset == NULL ||
567 	    sc->sc_clock == NULL ||
568 	    sc->sc_clockapb == NULL)
569 		return EINVAL;
570 
571 	fdtbus_reset_assert(sc->sc_reset);
572 
573 	error = clk_enable(sc->sc_clock);
574 	if (error) {
575 		fdtbus_reset_deassert(sc->sc_reset);
576 		return error;
577 	}
578 
579 	error = clk_enable(sc->sc_clockapb);
580 
581 	DELAY(20);
582 	fdtbus_reset_deassert(sc->sc_reset);
583 
584 	return error;
585 }
586 
587 static void
588 rk_tsadc_init_counts(struct rk_tsadc_softc *sc)
589 {
590 
591 	TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rd->rd_auto_period);
592 	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rd->rd_auto_period);
593 	TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
594 	TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
595 }
596 
597 /* Configure the hardware with the tshut setup. */
598 static void
599 rk_tsadc_tshut_set(struct rk_tsadc_softc *sc)
600 {
601 	uint32_t val = TSADC_READ(sc, TSADC_AUTO_CON);
602 
603 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
604 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
605 		uint32_t data, warndata;
606 
607 		if (!rks->s_attached)
608 			continue;
609 
610 		data = rk_tsadc_temp_to_data(sc, rks->s_tshut);
611 		warndata = rk_tsadc_temp_to_data(sc, rks->s_warn);
612 
613 		DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u",
614 			sc->sc_sme->sme_name, rks->s_data.desc,
615 			rks->s_tshut, data,
616 			rks->s_warn, warndata);
617 
618 		if (data == sc->sc_data_mask) {
619 			aprint_error_dev(sc->sc_dev,
620 			    "Failed converting critical temp %u.%06u to code",
621 			    rks->s_tshut / 1000000, rks->s_tshut % 1000000);
622 			continue;
623 		}
624 		if (warndata == sc->sc_data_mask) {
625 			aprint_error_dev(sc->sc_dev,
626 			    "Failed converting warn temp %u.%06u to code",
627 			    rks->s_warn / 1000000, rks->s_warn % 1000000);
628 			continue;
629 		}
630 
631 		TSADC_WRITE(sc, rks->s_comp_tshut, data);
632 		TSADC_WRITE(sc, rks->s_comp_int, warndata);
633 
634 		val |= rks->s_comp_int_en;
635 	}
636 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
637 }
638 
639 static void
640 rk_tsadc_init_tshut(struct rk_tsadc_softc *sc, int mode, int polarity)
641 {
642 	uint32_t val;
643 
644 	/* Handle TSHUT temp setting. */
645 	rk_tsadc_tshut_set(sc);
646 
647 	/* Handle TSHUT mode setting. */
648 	val = TSADC_READ(sc, TSADC_INT_EN);
649 	if (mode == TSHUT_MODE_CPU) {
650 		val |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
651 		       TSADC_INT_EN_TSHUT_2CRU_EN_SRC0;
652 		val &= ~(TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
653 			 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0);
654 	} else {
655 		KASSERT(mode == TSHUT_MODE_GPIO);
656 		val &= ~(TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
657 			 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0);
658 		val |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
659 		       TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0;
660 	}
661 	TSADC_WRITE(sc, TSADC_INT_EN, val);
662 
663 	/* Handle TSHUT polarity setting. */
664 	val = TSADC_READ(sc, TSADC_AUTO_CON);
665 	if (polarity == TSHUT_HIGH_ACTIVE)
666 		val |= TSADC_AUTO_CON_TSHUT_POLARITY;
667 	else
668 		val &= ~TSADC_AUTO_CON_TSHUT_POLARITY;
669 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
670 }
671 
672 static void
673 rk_tsadc_init_rk3328(struct rk_tsadc_softc *sc, int mode, int polarity)
674 {
675 
676 	rk_tsadc_init_tshut(sc, mode, polarity);
677 	rk_tsadc_init_counts(sc);
678 }
679 
680 static void
681 rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity)
682 {
683 
684 	syscon_lock(sc->sc_syscon);
685 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_L,
686 				      RK3399_GRF_TSADC_TESTBIT_VCM_EN_L);
687 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
688 				      RK3399_GRF_TSADC_TESTBIT_VCM_EN_H);
689 
690 	DELAY(20);
691 	syscon_write_4(sc->sc_syscon, RK3399_GRF_SARADC_TESTBIT,
692 				      RK3399_GRF_SARADC_TESTBIT_ON);
693 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
694 				      RK3399_GRF_TSADC_TESTBIT_H_ON);
695 	DELAY(100);
696 	syscon_unlock(sc->sc_syscon);
697 
698 	rk_tsadc_init_counts(sc);
699 	rk_tsadc_init_tshut(sc, mode, polarity);
700 }
701 
702 static void
703 rk_tsadc_init_enable(struct rk_tsadc_softc *sc)
704 {
705 	uint32_t val;
706 
707 	val = TSADC_READ(sc, TSADC_AUTO_CON);
708 	val |= TSADC_AUTO_CON_AUTO_STATUS |
709 	       TSADC_AUTO_CON_SRC1_LT_EN | TSADC_AUTO_CON_SRC0_LT_EN;
710 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
711 
712 	/* Finally, register & enable the controller */
713 	sysmon_envsys_register(sc->sc_sme);
714 
715 	val = TSADC_READ(sc, TSADC_AUTO_CON);
716 	val |= TSADC_AUTO_CON_AUTO_EN | TSADC_AUTO_CON_Q_SEL;
717 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
718 }
719 
720 static void
721 rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity)
722 {
723 
724 	(*sc->sc_rd->rd_init)(sc, mode, polarity);
725 	rk_tsadc_init_enable(sc);
726 }
727 
728 /* run time support */
729 
730 /* given edata, find the matching rk sensor structure */
731 static struct rk_tsadc_sensor *
732 rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata)
733 {
734 
735 	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
736 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
737 
738 		if (&rks->s_data == edata)
739 			return rks;
740 	}
741 	return NULL;
742 }
743 
744 static void
745 rk_tsadc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
746 {
747 	struct rk_tsadc_softc * const sc = sme->sme_cookie;
748 	struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
749 	unsigned data;
750 	int temp;
751 
752 	if (rks == NULL)
753 		return;
754 
755 	data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask;
756 	temp = rk_tsadc_data_to_temp(sc, data);
757 
758 	DPRINTF("(%s:%s): temp/data %d/%u",
759 		sc->sc_sme->sme_name, rks->s_data.desc,
760 		temp, data);
761 
762 	if (temp == sc->sc_data_mask) {
763 		edata->state = ENVSYS_SINVALID;
764 	} else {
765 		edata->value_cur = temp + TEMP_uC_TO_uK;
766 		edata->state = ENVSYS_SVALID;
767 	}
768 }
769 
770 static void
771 rk_tsadc_get_limits(struct sysmon_envsys *sme,
772 		    envsys_data_t *edata,
773 		    sysmon_envsys_lim_t *lim,
774 		    uint32_t *props)
775 {
776 	struct rk_tsadc_softc *sc = sme->sme_cookie;
777 	struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
778 
779 	if (rks == NULL)
780 		return;
781 
782 	lim->sel_critmax = rks->s_tshut + TEMP_uC_TO_uK;
783 	lim->sel_warnmax = rks->s_warn + TEMP_uC_TO_uK;
784 
785 	*props = PROP_CRITMAX | PROP_WARNMAX;
786 }
787 
788 /* XXX do something with interrupts that don't happen yet.  */
789 static int
790 rk_tsadc_intr(void *arg)
791 {
792 	struct rk_tsadc_softc * const sc = arg;
793 	uint32_t val;
794 
795 	/* XXX */
796 	DPRINTF("(%s): interrupted", sc->sc_sme->sme_name);
797 	for (unsigned n = 0; n < __arraycount(rk_tsadc_sensors); n++) {
798 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
799 
800 		rk_tsadc_refresh(sc->sc_sme, (envsys_data_t *)rks);
801 	}
802 
803 	/* ack interrupt */
804 	val = TSADC_READ(sc, TSADC_INT_PD);
805 	TSADC_WRITE(sc, TSADC_INT_PD, val & ~TSADC_INT_PD_EOC_INT_PD);
806 
807 	return 1;
808 }
809 
810 /*
811  * Convert TDASC data codes to temp and reverse.  The manual only has codes
812  * and temperature values in 5 degC intervals, but says that interpolation
813  * can be done to achieve better resolution between these values, and that
814  * the spacing is linear.
815  */
816 static int
817 rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data)
818 {
819 	unsigned i;
820 	const rk_data *rd = sc->sc_rd;
821 
822 	if (data > rd->rd_max || data < rd->rd_min) {
823 		DPRINTF("data out of range (%u > %u || %u < %u)",
824 			data, rd->rd_max, data, rd->rd_min);
825 		return sc->sc_data_mask;
826 	}
827 	for (i = 1; i < rd->rd_size; i++) {
828 		if (rd->rd_array[i].data >= data) {
829 			int temprange, offset;
830 			uint32_t datarange, datadiff;
831 			unsigned first, secnd;
832 
833 			if (rd->rd_array[i].data == data)
834 				return rd->rd_array[i].temp;
835 
836 			/* must interpolate */
837 			if (rd->rd_decr) {
838 				first = i;
839 				secnd = i+1;
840 			} else {
841 				first = i;
842 				secnd = i-1;
843 			}
844 
845 			temprange = rd->rd_array[first].temp -
846 				    rd->rd_array[secnd].temp;
847 			datarange = rd->rd_array[first].data -
848 				    rd->rd_array[secnd].data;
849 			datadiff = data - rd->rd_array[secnd].data;
850 
851 			offset = (temprange * datadiff) / datarange;
852 			return rd->rd_array[secnd].temp + offset;
853 		}
854 	}
855 	panic("didn't find range");
856 }
857 
858 static uint32_t
859 rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp)
860 {
861 	unsigned i;
862 	const rk_data *rd = sc->sc_rd;
863 
864 	for (i = 1; i < rd->rd_size; i++) {
865 		if (rd->rd_array[i].temp >= temp) {
866 			int temprange, tempdiff;
867 			uint32_t datarange, offset;
868 			unsigned first, secnd;
869 
870 			if (rd->rd_array[i].temp == temp)
871 				return rd->rd_array[i].data;
872 
873 			/* must interpolate */
874 			if (rd->rd_decr) {
875 				first = i;
876 				secnd = i+1;
877 			} else {
878 				first = i;
879 				secnd = i-1;
880 			}
881 
882 			datarange = rd->rd_array[first].data -
883 				    rd->rd_array[secnd].data;
884 			temprange = rd->rd_array[first].temp -
885 				    rd->rd_array[secnd].temp;
886 			tempdiff = temp - rd->rd_array[secnd].temp;
887 
888 			offset = (datarange * tempdiff) / temprange;
889 			return rd->rd_array[secnd].data + offset;
890 		}
891 	}
892 
893 	return sc->sc_data_mask;
894 }
895