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