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