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