Home | History | Annotate | Line # | Download | only in rockchip
rk_tsadc.c revision 1.4
      1 /*	$NetBSD: rk_tsadc.c,v 1.4 2019/05/14 07:45:03 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.4 2019/05/14 07:45:03 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  * - fix for RK3328, and port to other rockchips (will require moving some
     44  *   part into per-chipset sections, such as code<->temp tables)
     45  */
     46 
     47 #include <sys/param.h>
     48 #include <sys/bus.h>
     49 #include <sys/device.h>
     50 #include <sys/intr.h>
     51 #include <sys/systm.h>
     52 #include <sys/time.h>
     53 #include <sys/kmem.h>
     54 
     55 #include <dev/fdt/fdtvar.h>
     56 #include <dev/fdt/syscon.h>
     57 
     58 #include <dev/sysmon/sysmonvar.h>
     59 
     60 //#define RKTSADC_DEBUG
     61 #ifdef RKTSADC_DEBUG
     62 #define DPRINTF(fmt, ...) \
     63 	printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
     64 #else
     65 #define DPRINTF(fmt, ...)
     66 #endif
     67 
     68 /* Register definitions */
     69 #define TSADC_USER_CON                          0x00
     70 #define  TSADC_USER_CON_ADC_STATUS              __BIT(12)
     71 #define  TSADC_USER_CON_INTER_PD_SOC            __BITS(11,6)
     72 #define  TSADC_USER_CON_START                   __BIT(5)
     73 #define  TSADC_USER_CON_START_MODE              __BIT(4)
     74 #define  TSADC_USER_CON_ADC_POWER_CTRL          __BIT(3)
     75 #define  TSADC_USER_CON_ADC_INPUT_SRC_SEL       __BITS(2,0)
     76 #define TSADC_AUTO_CON                          0x04
     77 #define  TSADC_AUTO_CON_LAST_TSHUT_2CRU         __BIT(25)
     78 #define  TSADC_AUTO_CON_LAST_TSHUT_2GPIO        __BIT(24)
     79 #define  TSADC_AUTO_CON_SAMPLE_DLY_SEL          __BIT(17)
     80 #define  TSADC_AUTO_CON_AUTO_STATUS             __BIT(16)
     81 #define  TSADC_AUTO_CON_SRC1_LT_EN              __BIT(13)
     82 #define  TSADC_AUTO_CON_SRC0_LT_EN              __BIT(12)
     83 #define  TSADC_AUTO_CON_TSHUT_POLARITY          __BIT(8)
     84 #define  TSADC_AUTO_CON_SRC1_EN                 __BIT(5)
     85 #define  TSADC_AUTO_CON_SRC0_EN                 __BIT(4)
     86 #define  TSADC_AUTO_CON_Q_SEL                   __BIT(1)
     87 #define  TSADC_AUTO_CON_AUTO_EN                 __BIT(0)
     88 #define TSADC_INT_EN                            0x08
     89 #define  TSADC_INT_EN_EOC_INT_EN                __BIT(16)
     90 #define  TSADC_INT_EN_LT_INTEN_SRC1             __BIT(13)
     91 #define  TSADC_INT_EN_LT_INTEN_SRC0             __BIT(12)
     92 #define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC1        __BIT(9)
     93 #define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC0        __BIT(8)
     94 #define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1       __BIT(5)
     95 #define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0       __BIT(4)
     96 #define  TSADC_INT_EN_HT_INTEN_SRC1             __BIT(1)
     97 #define  TSADC_INT_EN_HT_INTEN_SRC0             __BIT(0)
     98 #define TSADC_INT_PD                            0x0c
     99 #define  TSADC_INT_PD_EOC_INT_PD                __BIT(16)
    100 #define  TSADC_INT_PD_LT_IRQ_SRC1               __BIT(13)
    101 #define  TSADC_INT_PD_LT_IRQ_SRC0               __BIT(12)
    102 #define  TSADC_INT_PD_TSHUT_O_SRC1              __BIT(5)
    103 #define  TSADC_INT_PD_TSHUT_O_SRC0              __BIT(4)
    104 #define  TSADC_INT_PD_HT_IRQ_SRC1               __BIT(1)
    105 #define  TSADC_INT_PD_HT_IRQ_SRC0               __BIT(0)
    106 #define TSADC_DATA0                             0x20
    107 #define  TSADC_DATA0_ADC_DATA                   __BITS(11,0)
    108 #define TSADC_DATA1                             0x24
    109 #define  TSADC_DATA1_ADC_DATA                   __BITS(11,0)
    110 #define TSADC_COMP0_INT                         0x30
    111 #define  TSADC_COMP0_INT_COMP_SRC0              __BITS(11,0)
    112 #define TSADC_COMP1_INT                         0x34
    113 #define  TSADC_COMP1_INT_COMP_SRC1              __BITS(11,0)
    114 #define TSADC_COMP0_SHUT                        0x40
    115 #define  TSADC_COMP0_SHUT_COMP_SRC0             __BITS(11,0)
    116 #define TSADC_COMP1_SHUT                        0x44
    117 #define  TSADC_COMP1_SHUT_COMP_SRC1             __BITS(11,0)
    118 #define TSADC_HIGH_INT_DEBOUNCE                 0x60
    119 #define  TSADC_HIGH_INT_DEBOUNCE_TEMP           __BITS(7,0)
    120 #define TSADC_HIGH_TSHUT_DEBOUNCE               0x64
    121 #define  TSADC_HIGH_TSHUT_DEBOUNCE_TEMP         __BITS(7,0)
    122 #define TSADC_AUTO_PERIOD                       0x68
    123 #define  TSADC_AUTO_PERIOD_TEMP                 __BITS(31,0)
    124 #define TSADC_AUTO_PERIOD_HT                    0x6c
    125 #define  TSADC_AUTO_PERIOD_HT_TEMP              __BITS(31,0)
    126 #define TSADC_COMP0_LOW_INT                     0x80
    127 #define  TSADC_COMP0_LOW_INT_COMP_SRC0          __BITS(11,0)
    128 #define TSADC_COMP1_LOW_INT                     0x84
    129 #define  TSADC_COMP1_LOW_INT_COMP_SRC1          __BITS(11,0)
    130 
    131 #define RK3328_TSADC_AUTO_PERIOD_TIME           250 /* 250ms */
    132 #define RK3399_TSADC_AUTO_PERIOD_TIME           1875 /* 2.5ms */
    133 #define TSADC_HT_DEBOUNCE_COUNT                 4
    134 
    135 /*
    136  * All this magic is taking from the Linux rockchip_thermal driver.
    137  *
    138  * VCM means "voltage common mode", but the documentation for RK3399
    139  * does not mention this and I don't know what any of this really
    140  * is for.
    141  */
    142 #define RK3399_GRF_SARADC_TESTBIT               0xe644
    143 #define  RK3399_GRF_SARADC_TESTBIT_ON           (0x10001 << 2)
    144 #define RK3399_GRF_TSADC_TESTBIT_L              0xe648
    145 #define  RK3399_GRF_TSADC_TESTBIT_VCM_EN_L      (0x10001 << 7)
    146 #define RK3399_GRF_TSADC_TESTBIT_H              0xe64c
    147 #define  RK3399_GRF_TSADC_TESTBIT_VCM_EN_H      (0x10001 << 7)
    148 #define  RK3399_GRF_TSADC_TESTBIT_H_ON          (0x10001 << 2)
    149 
    150 #define TEMP_uC_TO_uK             273150000
    151 
    152 #define TSHUT_MODE_CPU    0
    153 #define TSHUT_MODE_GPIO   1
    154 
    155 #define TSHUT_LOW_ACTIVE  0
    156 #define TSHUT_HIGH_ACTIVE 1
    157 
    158 #define TSHUT_DEF_TEMP    95000
    159 
    160 #define TSADC_DATA_MAX    0xfff
    161 
    162 #define NUM_SENSORS       2
    163 
    164 typedef struct rk_data_array {
    165 	uint32_t data;  /* register value */
    166 	int temp;       /* micro-degC */
    167 } rk_data_array;
    168 
    169 struct rk_tsadc_softc;
    170 typedef struct rk_data_table {
    171 	const rk_data_array	*rdt_array;
    172 	size_t			 rdt_size;
    173 	void			(*rdt_init)(struct rk_tsadc_softc *, int, int);
    174 	bool			 rdt_decr;  /* lower values -> higher temp */
    175 	unsigned		 rdt_min, rdt_max;
    176 	unsigned		 rdt_auto_period;
    177 } rk_data_table;
    178 
    179 /* Per-sensor data */
    180 struct rk_tsadc_sensor {
    181 	envsys_data_t	s_data;
    182 	bool		s_attached;
    183 	/* TSADC register offsets for this sensor */
    184 	unsigned	s_data_reg;
    185 	unsigned	s_comp_tshut;
    186 	unsigned	s_comp_int;
    187 	/* enable bit in AUTO_CON register */
    188 	unsigned	s_comp_int_en;
    189 	/* warn/crit values in micro Kelvin */
    190 	int		s_warn;
    191 	int		s_tshut;
    192 };
    193 
    194 struct rk_tsadc_softc {
    195 	device_t		sc_dev;
    196 	int			sc_phandle;
    197 	bus_space_tag_t		sc_bst;
    198 	bus_space_handle_t	sc_bsh;
    199 	size_t			sc_size;
    200 	uint32_t		sc_data_mask;
    201 	void			*sc_ih;
    202 
    203 	struct sysmon_envsys	*sc_sme;
    204 	struct rk_tsadc_sensor	sc_sensors[NUM_SENSORS];
    205 
    206 	struct clk		*sc_clock;
    207 	struct clk		*sc_clockapb;
    208 	struct fdtbus_reset	*sc_reset;
    209 	struct syscon		*sc_syscon;
    210 
    211 	const rk_data_table	*sc_rdt;
    212 };
    213 
    214 static int rk_tsadc_match(device_t, cfdata_t, void *);
    215 static void rk_tsadc_attach(device_t, device_t, void *);
    216 static int rk_tsadc_detach(device_t, int);
    217 static int rk_tsadc_init_clocks(struct rk_tsadc_softc *);
    218 static void rk_tsadc_init_counts(struct rk_tsadc_softc *);
    219 static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s);
    220 static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int);
    221 static void rk_tsadc_init_rk3328(struct rk_tsadc_softc *, int, int);
    222 static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int);
    223 static void rk_tsadc_init_enable(struct rk_tsadc_softc *);
    224 static void rk_tsadc_init(struct rk_tsadc_softc *, int, int);
    225 static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *);
    226 static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *,
    227                                 sysmon_envsys_lim_t *, uint32_t *);
    228 
    229 static int rk_tsadc_intr(void *);
    230 static int rk_tsadc_data_to_temp(struct rk_tsadc_softc *, uint32_t);
    231 static uint32_t rk_tsadc_temp_to_data(struct rk_tsadc_softc *, int);
    232 
    233 /* RK3328/RK3399 compatible sensors */
    234 static const struct rk_tsadc_sensor rk_tsadc_sensors[] = {
    235 	{
    236 	  .s_data = { .desc = "CPU" },
    237 	  .s_data_reg = TSADC_DATA0,
    238 	  .s_comp_tshut = TSADC_COMP0_SHUT,
    239 	  .s_comp_int = TSADC_COMP0_INT,
    240 	  .s_comp_int_en = TSADC_AUTO_CON_SRC0_EN,
    241 	  /*
    242 	   * XXX DT has:
    243 	   * cpu_alert1: cpu_alert1 {
    244 	   *	temperature = <75000>;
    245 	   *	hysteresis = <2000>;
    246 	   * cpu_crit: cpu_crit {
    247 	   *    temperature = <95000>;
    248 	   *    hysteresis = <2000>;
    249 	   * pull out of here?
    250 	   * do something with hysteresis?  put in debounce?
    251 	   *
    252 	   * Note that tshut may be overriden by the board specific DT.
    253 	   */
    254 	  .s_warn = 75000000,
    255 	  .s_tshut = 95000000,
    256 	}, {
    257 	  .s_data = { .desc = "GPU" },
    258 	  .s_data_reg = TSADC_DATA1,
    259 	  .s_comp_tshut = TSADC_COMP1_SHUT,
    260 	  .s_comp_int = TSADC_COMP1_INT,
    261 	  .s_comp_int_en = TSADC_AUTO_CON_SRC1_EN,
    262 	  .s_warn = 75000000,
    263 	  .s_tshut = 95000000,
    264 	},
    265 };
    266 
    267 /* Table from RK3328 manual */
    268 static const rk_data_array rk3328_data_array[] = {
    269 #define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
    270 	ENTRY(TSADC_DATA_MAX,    -40),
    271 	ENTRY(3800, -40),
    272 	ENTRY(3792, -35),
    273 	ENTRY(3783, -30),
    274 	ENTRY(3774, -25),
    275 	ENTRY(3765, -20),
    276 	ENTRY(3756, -15),
    277 	ENTRY(3747, -10),
    278 	ENTRY(3737,  -5),
    279 	ENTRY(3728,   0),
    280 	ENTRY(3718,   5),
    281 	ENTRY(3708,  10),
    282 	ENTRY(3698,  15),
    283 	ENTRY(3688,  20),
    284 	ENTRY(3678,  25),
    285 	ENTRY(3667,  30),
    286 	ENTRY(3656,  35),
    287 	ENTRY(3645,  40),
    288 	ENTRY(3634,  45),
    289 	ENTRY(3623,  50),
    290 	ENTRY(3611,  55),
    291 	ENTRY(3600,  60),
    292 	ENTRY(3588,  65),
    293 	ENTRY(3575,  70),
    294 	ENTRY(3563,  75),
    295 	ENTRY(3550,  80),
    296 	ENTRY(3537,  85),
    297 	ENTRY(3524,  90),
    298 	ENTRY(3510,  95),
    299 	ENTRY(3496, 100),
    300 	ENTRY(3482, 105),
    301 	ENTRY(3467, 110),
    302 	ENTRY(3452, 115),
    303 	ENTRY(3437, 120),
    304 	ENTRY(3421, 125),
    305 	ENTRY(0,    125),
    306 #undef ENTRY
    307 };
    308 
    309 /* Table from RK3399 manual */
    310 static const rk_data_array rk3399_data_array[] = {
    311 #define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
    312 	ENTRY(0,   -40),
    313 	ENTRY(402, -40),
    314 	ENTRY(410, -35),
    315 	ENTRY(419, -30),
    316 	ENTRY(427, -25),
    317 	ENTRY(436, -20),
    318 	ENTRY(444, -15),
    319 	ENTRY(453, -10),
    320 	ENTRY(461,  -5),
    321 	ENTRY(470,   0),
    322 	ENTRY(478,   5),
    323 	ENTRY(487,  10),
    324 	ENTRY(496,  15),
    325 	ENTRY(504,  20),
    326 	ENTRY(513,  25),
    327 	ENTRY(521,  30),
    328 	ENTRY(530,  35),
    329 	ENTRY(538,  40),
    330 	ENTRY(547,  45),
    331 	ENTRY(555,  50),
    332 	ENTRY(564,  55),
    333 	ENTRY(573,  60),
    334 	ENTRY(581,  65),
    335 	ENTRY(590,  70),
    336 	ENTRY(599,  75),
    337 	ENTRY(607,  80),
    338 	ENTRY(616,  85),
    339 	ENTRY(624,  90),
    340 	ENTRY(633,  95),
    341 	ENTRY(642, 100),
    342 	ENTRY(650, 105),
    343 	ENTRY(659, 110),
    344 	ENTRY(668, 115),
    345 	ENTRY(677, 120),
    346 	ENTRY(685, 125),
    347 	ENTRY(TSADC_DATA_MAX, 125),
    348 #undef ENTRY
    349 };
    350 
    351 static const rk_data_table rk3328_data_table = {
    352 	.rdt_array = rk3328_data_array,
    353 	.rdt_size = __arraycount(rk3328_data_array),
    354 	.rdt_init = rk_tsadc_init_rk3328,
    355 	.rdt_decr = true,
    356 	.rdt_max = 3801,
    357 	.rdt_min = 3420,
    358 	.rdt_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME,
    359 };
    360 
    361 static const rk_data_table rk3399_data_table = {
    362 	.rdt_array = rk3399_data_array,
    363 	.rdt_size = __arraycount(rk3399_data_array),
    364 	.rdt_init = rk_tsadc_init_rk3399,
    365 	.rdt_decr = false,
    366 	.rdt_max = 686,
    367 	.rdt_min = 401,
    368 	.rdt_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME,
    369 };
    370 
    371 static const char * const compatible_rk3328[] = {
    372 #if 0
    373 	/*
    374 	 * does not yet report sane values.  should be between 3421 and 3800,
    375 	 * but CPU tends to report < 1000 and the GPU reports 600-1600.
    376 	 */
    377 	"rockchip,rk3328-tsadc",
    378 #endif
    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 	/* Default to tshut via gpio and tshut low is active */
    434 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode",
    435 			      &mode) != 0) {
    436 		aprint_error(": could not get TSHUT mode, default to GPIO");
    437 		mode = TSHUT_MODE_GPIO;
    438 	}
    439 	if (mode != TSHUT_MODE_CPU && mode != TSHUT_MODE_GPIO) {
    440 		aprint_error(": TSHUT mode should be 0 or 1\n");
    441 		goto fail;
    442 	}
    443 
    444 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-polarity",
    445 			      &polarity) != 0) {
    446 		aprint_error(": could not get TSHUT polarity, default to low");
    447 		polarity = TSHUT_LOW_ACTIVE;
    448 	}
    449 	if (of_getprop_uint32(phandle,
    450 			      "rockchip,hw-tshut-temp", &tshut_temp) != 0) {
    451 		aprint_error(": could not get TSHUT temperature, default to %u",
    452 			     TSHUT_DEF_TEMP);
    453 		tshut_temp = TSHUT_DEF_TEMP;
    454 	}
    455 	tshut_temp *= 1000;	/* convert fdt ms -> us */
    456 
    457 	memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors));
    458 	for (unsigned n = 0; n < NUM_SENSORS; n++) {
    459 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
    460 
    461 		rks->s_data.flags = ENVSYS_FMONLIMITS;
    462 		rks->s_data.units = ENVSYS_STEMP;
    463 		rks->s_data.state = ENVSYS_SINVALID;
    464 
    465 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &rks->s_data))
    466 			goto fail;
    467 		rks->s_attached = true;
    468 		rks->s_tshut = tshut_temp;
    469 #if 0
    470 		// testing
    471 		rks->s_tshut = 68000000;
    472 		rks->s_warn = 61000000;
    473 #endif
    474 	}
    475 
    476 	sc->sc_syscon = fdtbus_syscon_acquire(phandle, "rockchip,grf");
    477 	if (sc->sc_syscon == NULL) {
    478 		aprint_error(": couldn't get grf syscon\n");
    479 		goto fail;
    480 	}
    481 	if (fdtbus_get_reg(phandle, 0, &addr, &sc->sc_size) != 0) {
    482 		aprint_error(": couldn't get registers\n");
    483 		sc->sc_size = 0;
    484 		goto fail;
    485 	}
    486 	if (bus_space_map(sc->sc_bst, addr, sc->sc_size, 0, &sc->sc_bsh) != 0) {
    487 		aprint_error(": couldn't map registers\n");
    488 		sc->sc_size = 0;
    489 		goto fail;
    490 	}
    491 
    492 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    493 		aprint_error(": failed to decode interrupt\n");
    494 		goto fail;
    495 	}
    496 
    497 	sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
    498 	    rk_tsadc_intr, sc);
    499 	if (sc->sc_ih == NULL) {
    500 		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
    501 		    intrstr);
    502 		goto fail;
    503 	}
    504 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
    505 
    506 	if (rk_tsadc_init_clocks(sc)) {
    507 		aprint_error(": couldn't enable clocks\n");
    508 		return;
    509 	}
    510 
    511 	if (of_match_compatible(faa->faa_phandle, compatible_rk3328)) {
    512 		sc->sc_rdt = &rk3328_data_table;
    513 	} else {
    514 		KASSERT(of_match_compatible(faa->faa_phandle, compatible_rk3399));
    515 		sc->sc_rdt = &rk3399_data_table;
    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 < 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_rdt->rdt_auto_period);
    602 	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rdt->rdt_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 < NUM_SENSORS; n++) {
    614 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
    615 		uint32_t data = rk_tsadc_temp_to_data(sc, rks->s_tshut);
    616 		uint32_t warndata = rk_tsadc_temp_to_data(sc, rks->s_warn);
    617 
    618 		DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u",
    619 			sc->sc_sme->sme_name, rks->s_data.desc,
    620 			rks->s_tshut, data,
    621 			rks->s_warn, warndata);
    622 
    623 		if (data == sc->sc_data_mask) {
    624 			aprint_error_dev(sc->sc_dev,
    625 			    "Failed converting critical temp %u.%06u to code",
    626 			    rks->s_tshut / 1000000, rks->s_tshut % 1000000);
    627 			continue;
    628 		}
    629 		if (warndata == sc->sc_data_mask) {
    630 			aprint_error_dev(sc->sc_dev,
    631 			    "Failed converting warn temp %u.%06u to code",
    632 			    rks->s_warn / 1000000, rks->s_warn % 1000000);
    633 			continue;
    634 		}
    635 
    636 		TSADC_WRITE(sc, rks->s_comp_tshut, data);
    637 		TSADC_WRITE(sc, rks->s_comp_int, warndata);
    638 
    639 		val |= rks->s_comp_int_en;
    640 	}
    641 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
    642 }
    643 
    644 static void
    645 rk_tsadc_init_tshut(struct rk_tsadc_softc *sc, int mode, int polarity)
    646 {
    647 	uint32_t val;
    648 
    649 	/* Handle TSHUT temp setting. */
    650 	rk_tsadc_tshut_set(sc);
    651 
    652 	/* Handle TSHUT mode setting. */
    653 	val = TSADC_READ(sc, TSADC_INT_EN);
    654 	if (mode == TSHUT_MODE_CPU) {
    655 		val |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
    656 		       TSADC_INT_EN_TSHUT_2CRU_EN_SRC0;
    657 		val &= ~(TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
    658 			 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0);
    659 	} else {
    660 		KASSERT(mode == TSHUT_MODE_GPIO);
    661 		val &= ~(TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 |
    662 			 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0);
    663 		val &= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 |
    664 		       TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0;
    665 	}
    666 	TSADC_WRITE(sc, TSADC_INT_EN, val);
    667 
    668 	/* Handle TSHUT polarity setting. */
    669 	val = TSADC_READ(sc, TSADC_AUTO_CON);
    670 	if (polarity == TSHUT_HIGH_ACTIVE)
    671 		val |= TSADC_AUTO_CON_TSHUT_POLARITY;
    672 	else
    673 		val &= ~TSADC_AUTO_CON_TSHUT_POLARITY;
    674 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
    675 }
    676 
    677 static void
    678 rk_tsadc_init_rk3328(struct rk_tsadc_softc *sc, int mode, int polarity)
    679 {
    680 
    681 	rk_tsadc_init_tshut(sc, mode, polarity);
    682 	rk_tsadc_init_counts(sc);
    683 }
    684 
    685 static void
    686 rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity)
    687 {
    688 
    689 	syscon_lock(sc->sc_syscon);
    690 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_L,
    691 				      RK3399_GRF_TSADC_TESTBIT_VCM_EN_L);
    692 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
    693 				      RK3399_GRF_TSADC_TESTBIT_VCM_EN_H);
    694 
    695 	DELAY(20);
    696 	syscon_write_4(sc->sc_syscon, RK3399_GRF_SARADC_TESTBIT,
    697 				      RK3399_GRF_SARADC_TESTBIT_ON);
    698 	syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H,
    699 				      RK3399_GRF_TSADC_TESTBIT_H_ON);
    700 	DELAY(100);
    701 	syscon_unlock(sc->sc_syscon);
    702 
    703 	rk_tsadc_init_counts(sc);
    704 	rk_tsadc_init_tshut(sc, mode, polarity);
    705 }
    706 
    707 static void
    708 rk_tsadc_init_enable(struct rk_tsadc_softc *sc)
    709 {
    710 	uint32_t val;
    711 
    712 	val = TSADC_READ(sc, TSADC_AUTO_CON);
    713 	val |= TSADC_AUTO_CON_AUTO_STATUS |
    714 	       TSADC_AUTO_CON_SRC1_LT_EN | TSADC_AUTO_CON_SRC0_LT_EN;
    715 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
    716 
    717 	/* Finally, register & enable the controller */
    718 	sysmon_envsys_register(sc->sc_sme);
    719 
    720 	val = TSADC_READ(sc, TSADC_AUTO_CON);
    721 	val |= TSADC_AUTO_CON_AUTO_EN | TSADC_AUTO_CON_Q_SEL;
    722 	TSADC_WRITE(sc, TSADC_AUTO_CON, val);
    723 }
    724 
    725 static void
    726 rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity)
    727 {
    728 
    729 	(*sc->sc_rdt->rdt_init)(sc, mode, polarity);
    730 	rk_tsadc_init_enable(sc);
    731 }
    732 
    733 /* run time support */
    734 
    735 static struct rk_tsadc_sensor *
    736 rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata)
    737 {
    738 
    739 	for (unsigned n = 0; n < NUM_SENSORS; n++) {
    740 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
    741 
    742 		if (&rks->s_data == edata)
    743 			return rks;
    744 	}
    745 	return NULL;
    746 }
    747 
    748 static void
    749 rk_tsadc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    750 {
    751 	struct rk_tsadc_softc * const sc = sme->sme_cookie;
    752 	struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
    753 	unsigned data;
    754 	int temp;
    755 
    756 	if (rks == NULL)
    757 		return;
    758 
    759 	data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask;
    760 	temp = rk_tsadc_data_to_temp(sc, data);
    761 
    762 	DPRINTF("(%s:%s): temp/data %d/%u",
    763 		sc->sc_sme->sme_name, rks->s_data.desc,
    764 		temp, data);
    765 
    766 	if (temp == sc->sc_data_mask) {
    767 		edata->state = ENVSYS_SINVALID;
    768 	} else {
    769 		edata->value_cur = temp + TEMP_uC_TO_uK;
    770 		edata->state = ENVSYS_SVALID;
    771 	}
    772 }
    773 
    774 static void
    775 rk_tsadc_get_limits(struct sysmon_envsys *sme,
    776 		    envsys_data_t *edata,
    777 		    sysmon_envsys_lim_t *lim,
    778 		    uint32_t *props)
    779 {
    780 	struct rk_tsadc_softc *sc = sme->sme_cookie;
    781 	struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata);
    782 
    783 	if (rks == NULL)
    784 		return;
    785 
    786 	lim->sel_critmax = rks->s_tshut + TEMP_uC_TO_uK;
    787 	lim->sel_warnmax = rks->s_warn + TEMP_uC_TO_uK;
    788 
    789 	*props = PROP_CRITMAX | PROP_WARNMAX;
    790 }
    791 
    792 /* XXX do something with interrupts that don't happen yet.  */
    793 static int
    794 rk_tsadc_intr(void *arg)
    795 {
    796 	struct rk_tsadc_softc * const sc = arg;
    797 	uint32_t val;
    798 
    799 	/* XXX */
    800 	DPRINTF("(%s): interrupted", sc->sc_sme->sme_name);
    801 	for (unsigned n; n < __arraycount(rk_tsadc_sensors); n++) {
    802 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
    803 
    804 		rk_tsadc_refresh(sc->sc_sme, (envsys_data_t *)rks);
    805 	}
    806 
    807 	/* ack interrupt */
    808 	val = TSADC_READ(sc, TSADC_INT_PD);
    809 	TSADC_WRITE(sc, TSADC_INT_PD, val & ~TSADC_INT_PD_EOC_INT_PD);
    810 
    811 	return 1;
    812 }
    813 
    814 /*
    815  * Convert TDASC data codes to temp and reverse.  The manual only has codes
    816  * and temperature values in 5 degC intervals, but says that interpolation
    817  * can be done to achieve better resolution between these values, and that
    818  * the spacing is linear.
    819  */
    820 static int
    821 rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data)
    822 {
    823 	unsigned i;
    824 	const rk_data_table *rdt = sc->sc_rdt;
    825 
    826 	if (data > rdt->rdt_max || data < rdt->rdt_min) {
    827 		DPRINTF("data out of range (%u > %u || %u < %u)", data, rdt->rdt_max, data, rdt->rdt_min);
    828 		return sc->sc_data_mask;
    829 	}
    830 	for (i = 1; i < rdt->rdt_size; i++) {
    831 		if (rdt->rdt_array[i].data >= data) {
    832 			int temprange, offset;
    833 			uint32_t datarange, datadiff;
    834 			unsigned first, secnd;
    835 
    836 			if (rdt->rdt_array[i].data == data)
    837 				return rdt->rdt_array[i].temp;
    838 
    839 			/* must interpolate */
    840 			if (rdt->rdt_decr) {
    841 				first = i;
    842 				secnd = i+1;
    843 			} else {
    844 				first = i;
    845 				secnd = i-1;
    846 			}
    847 
    848 			temprange = rdt->rdt_array[first].temp -
    849 				    rdt->rdt_array[secnd].temp;
    850 			datarange = rdt->rdt_array[first].data -
    851 				    rdt->rdt_array[secnd].data;
    852 			datadiff = data - rdt->rdt_array[secnd].data;
    853 
    854 			offset = (temprange * datadiff) / datarange;
    855 			return rdt->rdt_array[secnd].temp + offset;
    856 		}
    857 	}
    858 	panic("didn't find range");
    859 }
    860 
    861 static uint32_t
    862 rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp)
    863 {
    864 	unsigned i;
    865 	const rk_data_table *rdt = sc->sc_rdt;
    866 
    867 	for (i = 1; i < rdt->rdt_size; i++) {
    868 		if (rdt->rdt_array[i].temp >= temp) {
    869 			int temprange, tempdiff;
    870 			uint32_t datarange, offset;
    871 			unsigned first, secnd;
    872 
    873 			if (rdt->rdt_array[i].temp == temp)
    874 				return rdt->rdt_array[i].data;
    875 
    876 			/* must interpolate */
    877 			if (rdt->rdt_decr) {
    878 				first = i;
    879 				secnd = i+1;
    880 			} else {
    881 				first = i;
    882 				secnd = i-1;
    883 			}
    884 
    885 			datarange = rdt->rdt_array[first].data -
    886 				    rdt->rdt_array[secnd].data;
    887 			temprange = rdt->rdt_array[first].temp -
    888 				    rdt->rdt_array[secnd].temp;
    889 			tempdiff = temp - rdt->rdt_array[secnd].temp;
    890 
    891 			offset = (datarange * tempdiff) / temprange;
    892 			return rdt->rdt_array[secnd].data + offset;
    893 		}
    894 	}
    895 
    896 	return sc->sc_data_mask;
    897 }
    898