Home | History | Annotate | Line # | Download | only in rockchip
rk_tsadc.c revision 1.6
      1 /*	$NetBSD: rk_tsadc.c,v 1.6 2019/06/01 19:32:19 joerg 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.6 2019/06/01 19:32:19 joerg 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