rk_tsadc.c revision 1.7 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