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