rk_tsadc.c revision 1.13 1 /* $NetBSD: rk_tsadc.c,v 1.13 2021/06/12 00:04:46 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 * 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.13 2021/06/12 00:04:46 mrg 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 mK -> uK */
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