Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm64/rockchip/rk_tsadc.c
39478 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2019 Michal Meloun <[email protected]>
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/cdefs.h>
29
/*
30
* Thermometer and thermal zones driver for RockChip SoCs.
31
* Calibration data are taken from Linux, because this part of SoC
32
* is undocumented in TRM.
33
*/
34
35
#include <sys/param.h>
36
#include <sys/systm.h>
37
#include <sys/bus.h>
38
#include <sys/gpio.h>
39
#include <sys/kernel.h>
40
#include <sys/module.h>
41
#include <sys/malloc.h>
42
#include <sys/rman.h>
43
#include <sys/sysctl.h>
44
45
#include <machine/bus.h>
46
47
#include <dev/clk/clk.h>
48
#include <dev/hwreset/hwreset.h>
49
#include <dev/syscon/syscon.h>
50
#include <dev/ofw/ofw_bus.h>
51
#include <dev/ofw/ofw_bus_subr.h>
52
53
#include "syscon_if.h"
54
#include "rk_tsadc_if.h"
55
56
/* Version of HW */
57
#define TSADC_V2 1
58
#define TSADC_V3 2
59
#define TSADC_V7 3
60
61
/* Global registers */
62
#define TSADC_USER_CON 0x000
63
#define TSADC_AUTO_CON 0x004
64
#define TSADC_AUTO_CON_POL_HI (1 << 8)
65
#define TSADC_AUTO_SRC_EN(x) (1 << (4 + (x)))
66
#define TSADC_AUTO_Q_SEL (1 << 1) /* V3 only */
67
#define TSADC_AUTO_CON_AUTO (1 << 0)
68
69
#define TSADC_INT_EN 0x008
70
#define TSADC_INT_EN_2CRU_EN_SRC(x) (1 << (8 + (x)))
71
#define TSADC_INT_EN_2GPIO_EN_SRC(x) (1 << (4 + (x)))
72
#define TSADC_INT_PD 0x00c
73
#define TSADC_DATA(x) (0x20 + (x) * 0x04)
74
#define TSADC_COMP_INT(x) (0x30 + (x) * 0x04)
75
#define TSADC_COMP_INT_SRC_EN(x) (1 << (0 + (x)))
76
#define TSADC_COMP_SHUT(x) (0x40 + (x) * 0x04)
77
#define TSADC_HIGHT_INT_DEBOUNCE 0x060
78
#define TSADC_HIGHT_TSHUT_DEBOUNCE 0x064
79
#define TSADC_AUTO_PERIOD 0x068
80
#define TSADC_AUTO_PERIOD_HT 0x06c
81
#define TSADC_COMP0_LOW_INT 0x080 /* V3 only */
82
#define TSADC_COMP1_LOW_INT 0x084 /* V3 only */
83
84
/* V3 GFR registers */
85
#define GRF_SARADC_TESTBIT 0x0e644
86
#define GRF_SARADC_TESTBIT_ON (0x10001 << 2)
87
#define GRF_TSADC_TESTBIT_L 0x0e648
88
#define GRF_TSADC_VCM_EN_L (0x10001 << 7)
89
#define GRF_TSADC_TESTBIT_H 0x0e64c
90
#define GRF_TSADC_VCM_EN_H (0x10001 << 7)
91
#define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2)
92
93
/* V7 GRF register */
94
#define GRF_TSADC_CON 0x0600
95
#define GRF_TSADC_ANA_REG0 (0x10001 << 0)
96
#define GRF_TSADC_ANA_REG1 (0x10001 << 1)
97
#define GRF_TSADC_ANA_REG2 (0x10001 << 2)
98
#define GRF_TSADC_TSEN (0x10001 << 8)
99
100
#define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, (_r), (_v))
101
#define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r))
102
103
static struct sysctl_ctx_list tsadc_sysctl_ctx;
104
105
struct tsensor {
106
char *name;
107
int id;
108
int channel;
109
};
110
111
struct rk_calib_entry {
112
uint32_t raw;
113
int temp;
114
};
115
116
struct tsadc_calib_info {
117
struct rk_calib_entry *table;
118
int nentries;
119
};
120
121
struct tsadc_conf {
122
int version;
123
int q_sel_ntc;
124
int shutdown_temp;
125
int shutdown_mode;
126
int shutdown_pol;
127
struct tsensor *tsensors;
128
int ntsensors;
129
struct tsadc_calib_info calib_info;
130
};
131
132
struct tsadc_softc {
133
device_t dev;
134
struct resource *mem_res;
135
struct resource *irq_res;
136
void *irq_ih;
137
138
clk_t tsadc_clk;
139
clk_t apb_pclk_clk;
140
hwreset_array_t hwreset;
141
struct syscon *grf;
142
143
struct tsadc_conf *conf;
144
145
int shutdown_temp;
146
int shutdown_mode;
147
int shutdown_pol;
148
149
int alarm_temp;
150
};
151
152
static struct rk_calib_entry rk3288_calib_data[] = {
153
{3800, -40000},
154
{3792, -35000},
155
{3783, -30000},
156
{3774, -25000},
157
{3765, -20000},
158
{3756, -15000},
159
{3747, -10000},
160
{3737, -5000},
161
{3728, 0},
162
{3718, 5000},
163
{3708, 10000},
164
{3698, 15000},
165
{3688, 20000},
166
{3678, 25000},
167
{3667, 30000},
168
{3656, 35000},
169
{3645, 40000},
170
{3634, 45000},
171
{3623, 50000},
172
{3611, 55000},
173
{3600, 60000},
174
{3588, 65000},
175
{3575, 70000},
176
{3563, 75000},
177
{3550, 80000},
178
{3537, 85000},
179
{3524, 90000},
180
{3510, 95000},
181
{3496, 100000},
182
{3482, 105000},
183
{3467, 110000},
184
{3452, 115000},
185
{3437, 120000},
186
{3421, 125000},
187
};
188
189
struct tsensor rk3288_tsensors[] = {
190
{ .channel = 0, .id = 2, .name = "reserved"},
191
{ .channel = 1, .id = 0, .name = "CPU"},
192
{ .channel = 2, .id = 1, .name = "GPU"},
193
};
194
195
struct tsadc_conf rk3288_tsadc_conf = {
196
.version = TSADC_V2,
197
.q_sel_ntc = 0,
198
.shutdown_temp = 95000,
199
.shutdown_mode = 1, /* GPIO */
200
.shutdown_pol = 0, /* Low */
201
.tsensors = rk3288_tsensors,
202
.ntsensors = nitems(rk3288_tsensors),
203
.calib_info = {
204
.table = rk3288_calib_data,
205
.nentries = nitems(rk3288_calib_data),
206
}
207
};
208
209
static struct rk_calib_entry rk3328_calib_data[] = {
210
{296, -40000},
211
{304, -35000},
212
{313, -30000},
213
{331, -20000},
214
{340, -15000},
215
{349, -10000},
216
{359, -5000},
217
{368, 0},
218
{378, 5000},
219
{388, 10000},
220
{398, 15000},
221
{408, 20000},
222
{418, 25000},
223
{429, 30000},
224
{440, 35000},
225
{451, 40000},
226
{462, 45000},
227
{473, 50000},
228
{485, 55000},
229
{496, 60000},
230
{508, 65000},
231
{521, 70000},
232
{533, 75000},
233
{546, 80000},
234
{559, 85000},
235
{572, 90000},
236
{586, 95000},
237
{600, 100000},
238
{614, 105000},
239
{629, 110000},
240
{644, 115000},
241
{659, 120000},
242
{675, 125000},
243
};
244
245
static struct tsensor rk3328_tsensors[] = {
246
{ .channel = 0, .id = 0, .name = "CPU"},
247
};
248
249
static struct tsadc_conf rk3328_tsadc_conf = {
250
.version = TSADC_V2,
251
.q_sel_ntc = 1,
252
.shutdown_temp = 95000,
253
.shutdown_mode = 0, /* CRU */
254
.shutdown_pol = 0, /* Low */
255
.tsensors = rk3328_tsensors,
256
.ntsensors = nitems(rk3328_tsensors),
257
.calib_info = {
258
.table = rk3328_calib_data,
259
.nentries = nitems(rk3328_calib_data),
260
}
261
};
262
263
static struct rk_calib_entry rk3399_calib_data[] = {
264
{402, -40000},
265
{410, -35000},
266
{419, -30000},
267
{427, -25000},
268
{436, -20000},
269
{444, -15000},
270
{453, -10000},
271
{461, -5000},
272
{470, 0},
273
{478, 5000},
274
{487, 10000},
275
{496, 15000},
276
{504, 20000},
277
{513, 25000},
278
{521, 30000},
279
{530, 35000},
280
{538, 40000},
281
{547, 45000},
282
{555, 50000},
283
{564, 55000},
284
{573, 60000},
285
{581, 65000},
286
{590, 70000},
287
{599, 75000},
288
{607, 80000},
289
{616, 85000},
290
{624, 90000},
291
{633, 95000},
292
{642, 100000},
293
{650, 105000},
294
{659, 110000},
295
{668, 115000},
296
{677, 120000},
297
{685, 125000},
298
};
299
300
static struct tsensor rk3399_tsensors[] = {
301
{ .channel = 0, .id = 0, .name = "CPU"},
302
{ .channel = 1, .id = 1, .name = "GPU"},
303
};
304
305
static struct tsadc_conf rk3399_tsadc_conf = {
306
.version = TSADC_V3,
307
.q_sel_ntc = 1,
308
.shutdown_temp = 95000,
309
.shutdown_mode = 1, /* GPIO */
310
.shutdown_pol = 0, /* Low */
311
.tsensors = rk3399_tsensors,
312
.ntsensors = nitems(rk3399_tsensors),
313
.calib_info = {
314
.table = rk3399_calib_data,
315
.nentries = nitems(rk3399_calib_data),
316
}
317
};
318
319
static struct rk_calib_entry rk3568_calib_data[] = {
320
{0, -40000},
321
{1584, -40000},
322
{1620, -35000},
323
{1652, -30000},
324
{1688, -25000},
325
{1720, -20000},
326
{1756, -15000},
327
{1788, -10000},
328
{1824, -5000},
329
{1856, 0},
330
{1892, 5000},
331
{1924, 10000},
332
{1956, 15000},
333
{1992, 20000},
334
{2024, 25000},
335
{2060, 30000},
336
{2092, 35000},
337
{2128, 40000},
338
{2160, 45000},
339
{2196, 50000},
340
{2228, 55000},
341
{2264, 60000},
342
{2300, 65000},
343
{2332, 70000},
344
{2368, 75000},
345
{2400, 80000},
346
{2436, 85000},
347
{2468, 90000},
348
{2500, 95000},
349
{2536, 100000},
350
{2572, 105000},
351
{2604, 110000},
352
{2636, 115000},
353
{2672, 120000},
354
{2704, 125000},
355
};
356
357
static struct tsensor rk3568_tsensors[] = {
358
{ .channel = 0, .id = 0, .name = "CPU"},
359
{ .channel = 1, .id = 1, .name = "GPU"},
360
};
361
362
static struct tsadc_conf rk3568_tsadc_conf = {
363
.version = TSADC_V7,
364
.q_sel_ntc = 1,
365
.shutdown_temp = 95000,
366
.shutdown_mode = 1, /* GPIO */
367
.shutdown_pol = 0, /* Low */
368
.tsensors = rk3568_tsensors,
369
.ntsensors = nitems(rk3568_tsensors),
370
.calib_info = {
371
.table = rk3568_calib_data,
372
.nentries = nitems(rk3568_calib_data),
373
}
374
};
375
376
static struct ofw_compat_data compat_data[] = {
377
{"rockchip,rk3288-tsadc", (uintptr_t)&rk3288_tsadc_conf},
378
{"rockchip,rk3328-tsadc", (uintptr_t)&rk3328_tsadc_conf},
379
{"rockchip,rk3399-tsadc", (uintptr_t)&rk3399_tsadc_conf},
380
{"rockchip,rk3568-tsadc", (uintptr_t)&rk3568_tsadc_conf},
381
{NULL, 0}
382
};
383
384
static uint32_t
385
tsadc_temp_to_raw(struct tsadc_softc *sc, int temp)
386
{
387
struct rk_calib_entry *tbl;
388
int denom, ntbl, raw, i;
389
390
tbl = sc->conf->calib_info.table;
391
ntbl = sc->conf->calib_info.nentries;
392
393
if (temp <= tbl[0].temp)
394
return (tbl[0].raw);
395
396
if (temp >= tbl[ntbl - 1].temp)
397
return (tbl[ntbl - 1].raw);
398
399
for (i = 1; i < (ntbl - 1); i++) {
400
/* Exact match */
401
if (temp == tbl[i].temp)
402
return (tbl[i].raw);
403
if (temp < tbl[i].temp)
404
break;
405
}
406
407
/*
408
* Translated value is between i and i - 1 table entries.
409
* Do linear interpolation for it.
410
*/
411
raw = (int)tbl[i - 1].raw - (int)tbl[i].raw;
412
raw *= temp - tbl[i - 1].temp;
413
denom = tbl[i - 1].temp - tbl[i].temp;
414
raw = tbl[i - 1].raw + raw / denom;
415
return (raw);
416
}
417
418
static int
419
tsadc_raw_to_temp(struct tsadc_softc *sc, uint32_t raw)
420
{
421
struct rk_calib_entry *tbl;
422
int denom, ntbl, temp, i;
423
bool descending;
424
425
tbl = sc->conf->calib_info.table;
426
ntbl = sc->conf->calib_info.nentries;
427
descending = tbl[0].raw > tbl[1].raw;
428
429
if (descending) {
430
/* Raw column is in descending order. */
431
if (raw >= tbl[0].raw)
432
return (tbl[0].temp);
433
if (raw <= tbl[ntbl - 1].raw)
434
return (tbl[ntbl - 1].temp);
435
436
for (i = ntbl - 2; i > 0; i--) {
437
/* Exact match */
438
if (raw == tbl[i].raw)
439
return (tbl[i].temp);
440
if (raw < tbl[i].raw)
441
break;
442
}
443
} else {
444
/* Raw column is in ascending order. */
445
if (raw <= tbl[0].raw)
446
return (tbl[0].temp);
447
if (raw >= tbl[ntbl - 1].raw)
448
return (tbl[ntbl - 1].temp);
449
for (i = 1; i < (ntbl - 1); i++) {
450
/* Exact match */
451
if (raw == tbl[i].raw)
452
return (tbl[i].temp);
453
if (raw < tbl[i].raw)
454
break;
455
}
456
}
457
458
/*
459
* Translated value is between i and i - 1 table entries.
460
* Do linear interpolation for it.
461
*/
462
temp = (int)tbl[i - 1].temp - (int)tbl[i].temp;
463
temp *= raw - tbl[i - 1].raw;
464
denom = tbl[i - 1].raw - tbl[i].raw;
465
temp = tbl[i - 1].temp + temp / denom;
466
return (temp);
467
}
468
469
static void
470
tsadc_init_tsensor(struct tsadc_softc *sc, struct tsensor *sensor)
471
{
472
uint32_t val;
473
474
/* Shutdown mode */
475
val = RD4(sc, TSADC_INT_EN);
476
if (sc->shutdown_mode != 0) {
477
/* Signal shutdown of GPIO pin */
478
val &= ~TSADC_INT_EN_2CRU_EN_SRC(sensor->channel);
479
val |= TSADC_INT_EN_2GPIO_EN_SRC(sensor->channel);
480
} else {
481
val |= TSADC_INT_EN_2CRU_EN_SRC(sensor->channel);
482
val &= ~TSADC_INT_EN_2GPIO_EN_SRC(sensor->channel);
483
}
484
WR4(sc, TSADC_INT_EN, val);
485
486
/* Shutdown temperature */
487
val = tsadc_temp_to_raw(sc, sc->shutdown_temp);
488
WR4(sc, TSADC_COMP_SHUT(sensor->channel), val);
489
val = RD4(sc, TSADC_AUTO_CON);
490
val |= TSADC_AUTO_SRC_EN(sensor->channel);
491
WR4(sc, TSADC_AUTO_CON, val);
492
493
/* Alarm temperature */
494
val = tsadc_temp_to_raw(sc, sc->alarm_temp);
495
WR4(sc, TSADC_COMP_INT(sensor->channel), val);
496
val = RD4(sc, TSADC_INT_EN);
497
val |= TSADC_COMP_INT_SRC_EN(sensor->channel);
498
WR4(sc, TSADC_INT_EN, val);
499
}
500
501
static void
502
tsadc_init(struct tsadc_softc *sc)
503
{
504
uint32_t val;
505
506
/* Common part */
507
val = 0; /* XXX Is this right? */
508
if (sc->shutdown_pol != 0)
509
val |= TSADC_AUTO_CON_POL_HI;
510
else
511
val &= ~TSADC_AUTO_CON_POL_HI;
512
if (sc->conf->q_sel_ntc)
513
val |= TSADC_AUTO_Q_SEL;
514
WR4(sc, TSADC_AUTO_CON, val);
515
516
switch (sc->conf->version) {
517
case TSADC_V2:
518
/* V2 init */
519
WR4(sc, TSADC_AUTO_PERIOD, 250); /* 250 ms */
520
WR4(sc, TSADC_AUTO_PERIOD_HT, 50); /* 50 ms */
521
WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
522
WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
523
break;
524
case TSADC_V3:
525
/* V3 init */
526
if (sc->grf == NULL) {
527
/* Errata: adjust interleave to working value */
528
WR4(sc, TSADC_USER_CON, 13 << 6); /* 13 clks */
529
} else {
530
SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_L,
531
GRF_TSADC_VCM_EN_L);
532
SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_H,
533
GRF_TSADC_VCM_EN_H);
534
DELAY(30); /* 15 usec min */
535
536
SYSCON_WRITE_4(sc->grf, GRF_SARADC_TESTBIT,
537
GRF_SARADC_TESTBIT_ON);
538
SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_H,
539
GRF_TSADC_TESTBIT_H_ON);
540
DELAY(180); /* 90 usec min */
541
}
542
WR4(sc, TSADC_AUTO_PERIOD, 1875); /* 2.5 ms */
543
WR4(sc, TSADC_AUTO_PERIOD_HT, 1875); /* 2.5 ms */
544
WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
545
WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
546
break;
547
case TSADC_V7:
548
/* V7 init */
549
WR4(sc, TSADC_USER_CON, 0xfc0); /* 97us, at least 90us */
550
WR4(sc, TSADC_AUTO_PERIOD, 1622); /* 2.5ms */
551
WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
552
WR4(sc, TSADC_AUTO_PERIOD_HT, 1622); /* 2.5ms */
553
WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
554
if (sc->grf) {
555
SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON, GRF_TSADC_TSEN);
556
DELAY(15); /* 10 usec min */
557
SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON,
558
GRF_TSADC_ANA_REG0);
559
SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON,
560
GRF_TSADC_ANA_REG1);
561
SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON,
562
GRF_TSADC_ANA_REG2);
563
DELAY(100); /* 90 usec min */
564
}
565
break;
566
}
567
}
568
569
static int
570
tsadc_read_temp(struct tsadc_softc *sc, struct tsensor *sensor, int *temp)
571
{
572
uint32_t val;
573
574
val = RD4(sc, TSADC_DATA(sensor->channel));
575
*temp = tsadc_raw_to_temp(sc, val);
576
577
#ifdef DEBUG
578
device_printf(sc->dev, "%s: Sensor(id: %d, ch: %d), val: %d temp: %d\n",
579
__func__, sensor->id, sensor->channel, val, *temp);
580
device_printf(sc->dev, "%s: user_con=0x%08x auto_con=0x%08x "
581
"comp_int=0x%08x comp_shut=0x%08x\n",
582
__func__, RD4(sc, TSADC_USER_CON), RD4(sc, TSADC_AUTO_CON),
583
RD4(sc, TSADC_COMP_INT(sensor->channel)),
584
RD4(sc, TSADC_COMP_SHUT(sensor->channel)));
585
#endif
586
return (0);
587
}
588
589
static int
590
tsadc_get_temp(device_t dev, device_t cdev, uintptr_t id, int *val)
591
{
592
struct tsadc_softc *sc;
593
int i, rv;
594
595
sc = device_get_softc(dev);
596
597
if (id >= sc->conf->ntsensors)
598
return (ERANGE);
599
600
for (i = 0; i < sc->conf->ntsensors; i++) {
601
if (sc->conf->tsensors->id == id) {
602
rv =tsadc_read_temp(sc, sc->conf->tsensors + id, val);
603
return (rv);
604
}
605
}
606
return (ERANGE);
607
}
608
609
static int
610
tsadc_sysctl_temperature(SYSCTL_HANDLER_ARGS)
611
{
612
struct tsadc_softc *sc;
613
int val;
614
int rv;
615
int id;
616
617
/* Write request */
618
if (req->newptr != NULL)
619
return (EINVAL);
620
621
sc = arg1;
622
id = arg2;
623
624
if (id >= sc->conf->ntsensors)
625
return (ERANGE);
626
rv = tsadc_read_temp(sc, sc->conf->tsensors + id, &val);
627
if (rv != 0)
628
return (rv);
629
630
val = val / 100;
631
val += 2731;
632
rv = sysctl_handle_int(oidp, &val, 0, req);
633
return (rv);
634
}
635
636
static int
637
tsadc_init_sysctl(struct tsadc_softc *sc)
638
{
639
int i;
640
struct sysctl_oid *oid, *tmp;
641
642
sysctl_ctx_init(&tsadc_sysctl_ctx);
643
/* create node for hw.temp */
644
oid = SYSCTL_ADD_NODE(&tsadc_sysctl_ctx,
645
SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "temperature",
646
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "");
647
if (oid == NULL)
648
return (ENXIO);
649
650
/* Add sensors */
651
for (i = sc->conf->ntsensors - 1; i >= 0; i--) {
652
tmp = SYSCTL_ADD_PROC(&tsadc_sysctl_ctx,
653
SYSCTL_CHILDREN(oid), OID_AUTO, sc->conf->tsensors[i].name,
654
CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, i,
655
tsadc_sysctl_temperature, "IK", "SoC Temperature");
656
if (tmp == NULL)
657
return (ENXIO);
658
}
659
660
return (0);
661
}
662
663
static int
664
tsadc_intr(void *arg)
665
{
666
struct tsadc_softc *sc;
667
uint32_t val;
668
669
sc = (struct tsadc_softc *)arg;
670
671
val = RD4(sc, TSADC_INT_PD);
672
WR4(sc, TSADC_INT_PD, val);
673
674
/* XXX Handle shutdown and alarm interrupts. */
675
if (val & 0x00F0) {
676
device_printf(sc->dev, "Alarm: device temperature "
677
"is above of shutdown level.\n");
678
} else if (val & 0x000F) {
679
device_printf(sc->dev, "Alarm: device temperature "
680
"is above of alarm level.\n");
681
}
682
return (FILTER_HANDLED);
683
}
684
685
static int
686
tsadc_probe(device_t dev)
687
{
688
689
if (!ofw_bus_status_okay(dev))
690
return (ENXIO);
691
692
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
693
return (ENXIO);
694
695
device_set_desc(dev, "RockChip temperature sensors");
696
return (BUS_PROBE_DEFAULT);
697
}
698
699
static int
700
tsadc_attach(device_t dev)
701
{
702
struct tsadc_softc *sc;
703
phandle_t node;
704
uint32_t val;
705
int i, rid, rv;
706
707
sc = device_get_softc(dev);
708
sc->dev = dev;
709
node = ofw_bus_get_node(sc->dev);
710
sc->conf = (struct tsadc_conf *)
711
ofw_bus_search_compatible(dev, compat_data)->ocd_data;
712
sc->alarm_temp = 90000;
713
714
rid = 0;
715
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
716
RF_ACTIVE);
717
if (sc->mem_res == NULL) {
718
device_printf(dev, "Cannot allocate memory resources\n");
719
goto fail;
720
}
721
722
rid = 0;
723
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
724
if (sc->irq_res == NULL) {
725
device_printf(dev, "Cannot allocate IRQ resources\n");
726
goto fail;
727
}
728
729
if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
730
tsadc_intr, NULL, sc, &sc->irq_ih))) {
731
device_printf(dev,
732
"WARNING: unable to register interrupt handler\n");
733
goto fail;
734
}
735
736
/* FDT resources */
737
rv = hwreset_array_get_ofw(dev, 0, &sc->hwreset);
738
if (rv != 0) {
739
device_printf(dev, "Cannot get resets\n");
740
goto fail;
741
}
742
rv = clk_get_by_ofw_name(dev, 0, "tsadc", &sc->tsadc_clk);
743
if (rv != 0) {
744
device_printf(dev, "Cannot get 'tsadc' clock: %d\n", rv);
745
goto fail;
746
}
747
rv = clk_get_by_ofw_name(dev, 0, "apb_pclk", &sc->apb_pclk_clk);
748
if (rv != 0) {
749
device_printf(dev, "Cannot get 'apb_pclk' clock: %d\n", rv);
750
goto fail;
751
}
752
753
/* grf is optional */
754
rv = syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf);
755
if (rv != 0 && rv != ENOENT) {
756
device_printf(dev, "Cannot get 'grf' syscon: %d\n", rv);
757
goto fail;
758
}
759
760
rv = OF_getencprop(node, "rockchip,hw-tshut-temp",
761
&sc->shutdown_temp, sizeof(sc->shutdown_temp));
762
if (rv <= 0)
763
sc->shutdown_temp = sc->conf->shutdown_temp;
764
765
rv = OF_getencprop(node, "rockchip,hw-tshut-mode",
766
&sc->shutdown_mode, sizeof(sc->shutdown_mode));
767
if (rv <= 0)
768
sc->shutdown_mode = sc->conf->shutdown_mode;
769
770
rv = OF_getencprop(node, "rockchip,hw-tshut-polarity",
771
&sc->shutdown_pol, sizeof(sc->shutdown_pol));
772
if (rv <= 0)
773
sc->shutdown_pol = sc->conf->shutdown_pol;
774
775
/* Wakeup controller */
776
rv = hwreset_array_assert(sc->hwreset);
777
if (rv != 0) {
778
device_printf(dev, "Cannot assert reset\n");
779
goto fail;
780
}
781
782
/* Set the assigned clocks parent and freq */
783
rv = clk_set_assigned(sc->dev, node);
784
if (rv != 0 && rv != ENOENT) {
785
device_printf(dev, "clk_set_assigned failed\n");
786
goto fail;
787
}
788
789
rv = clk_enable(sc->tsadc_clk);
790
if (rv != 0) {
791
device_printf(dev, "Cannot enable 'tsadc_clk' clock: %d\n", rv);
792
goto fail;
793
}
794
rv = clk_enable(sc->apb_pclk_clk);
795
if (rv != 0) {
796
device_printf(dev, "Cannot enable 'apb_pclk' clock: %d\n", rv);
797
goto fail;
798
}
799
rv = hwreset_array_deassert(sc->hwreset);
800
if (rv != 0) {
801
device_printf(dev, "Cannot deassert reset\n");
802
goto fail;
803
}
804
805
tsadc_init(sc);
806
for (i = 0; i < sc->conf->ntsensors; i++)
807
tsadc_init_tsensor(sc, sc->conf->tsensors + i);
808
809
/* Enable auto mode */
810
val = RD4(sc, TSADC_AUTO_CON);
811
val |= TSADC_AUTO_CON_AUTO;
812
WR4(sc, TSADC_AUTO_CON, val);
813
814
rv = tsadc_init_sysctl(sc);
815
if (rv != 0) {
816
device_printf(sc->dev, "Cannot initialize sysctls\n");
817
goto fail_sysctl;
818
}
819
820
OF_device_register_xref(OF_xref_from_node(node), dev);
821
bus_attach_children(dev);
822
return (0);
823
824
fail_sysctl:
825
sysctl_ctx_free(&tsadc_sysctl_ctx);
826
fail:
827
if (sc->irq_ih != NULL)
828
bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
829
if (sc->tsadc_clk != NULL)
830
clk_release(sc->tsadc_clk);
831
if (sc->apb_pclk_clk != NULL)
832
clk_release(sc->apb_pclk_clk);
833
if (sc->hwreset != NULL)
834
hwreset_array_release(sc->hwreset);
835
if (sc->irq_res != NULL)
836
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
837
if (sc->mem_res != NULL)
838
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
839
840
return (ENXIO);
841
}
842
843
static int
844
tsadc_detach(device_t dev)
845
{
846
struct tsadc_softc *sc;
847
sc = device_get_softc(dev);
848
849
if (sc->irq_ih != NULL)
850
bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
851
sysctl_ctx_free(&tsadc_sysctl_ctx);
852
if (sc->tsadc_clk != NULL)
853
clk_release(sc->tsadc_clk);
854
if (sc->apb_pclk_clk != NULL)
855
clk_release(sc->apb_pclk_clk);
856
if (sc->hwreset != NULL)
857
hwreset_array_release(sc->hwreset);
858
if (sc->irq_res != NULL)
859
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
860
if (sc->mem_res != NULL)
861
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
862
863
return (ENXIO);
864
}
865
866
static device_method_t rk_tsadc_methods[] = {
867
/* Device interface */
868
DEVMETHOD(device_probe, tsadc_probe),
869
DEVMETHOD(device_attach, tsadc_attach),
870
DEVMETHOD(device_detach, tsadc_detach),
871
872
/* TSADC interface */
873
DEVMETHOD(rk_tsadc_get_temperature, tsadc_get_temp),
874
875
DEVMETHOD_END
876
};
877
878
static DEFINE_CLASS_0(rk_tsadc, rk_tsadc_driver, rk_tsadc_methods,
879
sizeof(struct tsadc_softc));
880
EARLY_DRIVER_MODULE(rk_tsadc, simplebus, rk_tsadc_driver, NULL, NULL,
881
BUS_PASS_TIMER + BUS_PASS_ORDER_LAST);
882
883