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