1 1.30 mlelstv /* $NetBSD: itesio_isa.c,v 1.30 2022/06/29 15:56:58 mlelstv Exp $ */ 2 1.1 xtraeme /* Derived from $OpenBSD: it.c,v 1.19 2006/04/10 00:57:54 deraadt Exp $ */ 3 1.1 xtraeme 4 1.1 xtraeme /* 5 1.13 xtraeme * Copyright (c) 2006-2007 Juan Romero Pardines <xtraeme (at) netbsd.org> 6 1.1 xtraeme * Copyright (c) 2003 Julien Bordet <zejames (at) greyhats.org> 7 1.1 xtraeme * All rights reserved. 8 1.1 xtraeme * 9 1.1 xtraeme * Redistribution and use in source and binary forms, with or without 10 1.1 xtraeme * modification, are permitted provided that the following conditions 11 1.1 xtraeme * are met: 12 1.1 xtraeme * 1. Redistributions of source code must retain the above copyright 13 1.1 xtraeme * notice, this list of conditions and the following disclaimer. 14 1.1 xtraeme * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 xtraeme * notice, this list of conditions and the following disclaimer in the 16 1.1 xtraeme * documentation and/or other materials provided with the distribution. 17 1.1 xtraeme * 18 1.1 xtraeme * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 xtraeme * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITD TO, THE IMPLIED WARRANTIES 20 1.1 xtraeme * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 xtraeme * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 xtraeme * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 xtraeme * NOT LIMITD TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 xtraeme * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 xtraeme * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 xtraeme * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 xtraeme * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 xtraeme */ 29 1.1 xtraeme 30 1.1 xtraeme /* 31 1.1 xtraeme * Driver for the iTE IT87xxF Super I/O. Currently supporting 32 1.11 xtraeme * the Environmental Controller to monitor the sensors and the 33 1.11 xtraeme * Watchdog Timer. 34 1.1 xtraeme */ 35 1.1 xtraeme 36 1.1 xtraeme #include <sys/cdefs.h> 37 1.30 mlelstv __KERNEL_RCSID(0, "$NetBSD: itesio_isa.c,v 1.30 2022/06/29 15:56:58 mlelstv Exp $"); 38 1.1 xtraeme 39 1.1 xtraeme #include <sys/param.h> 40 1.1 xtraeme #include <sys/kernel.h> 41 1.1 xtraeme #include <sys/device.h> 42 1.23 jmcneill #include <sys/module.h> 43 1.1 xtraeme #include <sys/bus.h> 44 1.29 nonaka #include <sys/kmem.h> 45 1.1 xtraeme 46 1.1 xtraeme #include <dev/isa/isareg.h> 47 1.1 xtraeme #include <dev/isa/isavar.h> 48 1.1 xtraeme 49 1.1 xtraeme #include <dev/sysmon/sysmonvar.h> 50 1.1 xtraeme 51 1.1 xtraeme #include <dev/isa/itesio_isavar.h> 52 1.1 xtraeme 53 1.1 xtraeme #define IT_VOLTSTART_IDX 3 /* voltage start index */ 54 1.1 xtraeme #define IT_FANSTART_IDX 12 /* fan start index */ 55 1.1 xtraeme 56 1.29 nonaka /* IT8625: 3 temps, 10 volts, 6 fans */ 57 1.29 nonaka #define IT8625_NUM_SENSORS 19 58 1.29 nonaka #define IT8625_VOLTSTART_IDX 3 /* voltage start index */ 59 1.29 nonaka #define IT8625_FANSTART_IDX 13 /* fan start index */ 60 1.29 nonaka 61 1.1 xtraeme #if defined(ITESIO_DEBUG) 62 1.1 xtraeme #define DPRINTF(x) do { printf x; } while (0) 63 1.1 xtraeme #else 64 1.1 xtraeme #define DPRINTF(x) 65 1.1 xtraeme #endif 66 1.1 xtraeme 67 1.1 xtraeme /* 68 1.1 xtraeme * IT87-compatible chips can typically measure voltages up to 4.096 V. 69 1.1 xtraeme * To measure higher voltages the input is attenuated with (external) 70 1.1 xtraeme * resistors. Negative voltages are measured using a reference 71 1.1 xtraeme * voltage. So we have to convert the sensor values back to real 72 1.1 xtraeme * voltages by applying the appropriate resistor factor. 73 1.1 xtraeme */ 74 1.1 xtraeme #define RFACT_NONE 10000 75 1.1 xtraeme #define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y)) 76 1.1 xtraeme 77 1.1 xtraeme /* autoconf(9) functions */ 78 1.14 xtraeme static int itesio_isa_match(device_t, cfdata_t, void *); 79 1.1 xtraeme static void itesio_isa_attach(device_t, device_t, void *); 80 1.1 xtraeme static int itesio_isa_detach(device_t, int); 81 1.1 xtraeme 82 1.1 xtraeme CFATTACH_DECL_NEW(itesio, sizeof(struct itesio_softc), 83 1.1 xtraeme itesio_isa_match, itesio_isa_attach, itesio_isa_detach, NULL); 84 1.1 xtraeme 85 1.1 xtraeme /* driver functions */ 86 1.1 xtraeme static uint8_t itesio_ecreadreg(struct itesio_softc *, int); 87 1.1 xtraeme static void itesio_ecwritereg(struct itesio_softc *, int, int); 88 1.1 xtraeme static uint8_t itesio_readreg(bus_space_tag_t, bus_space_handle_t, int); 89 1.1 xtraeme static void itesio_writereg(bus_space_tag_t, bus_space_handle_t, int, int); 90 1.1 xtraeme static void itesio_enter(bus_space_tag_t, bus_space_handle_t); 91 1.1 xtraeme static void itesio_exit(bus_space_tag_t, bus_space_handle_t); 92 1.1 xtraeme 93 1.10 xtraeme /* sysmon_envsys(9) glue */ 94 1.1 xtraeme static void itesio_setup_sensors(struct itesio_softc *); 95 1.1 xtraeme static void itesio_refresh_temp(struct itesio_softc *, envsys_data_t *); 96 1.1 xtraeme static void itesio_refresh_volts(struct itesio_softc *, envsys_data_t *); 97 1.1 xtraeme static void itesio_refresh_fans(struct itesio_softc *, envsys_data_t *); 98 1.4 xtraeme static void itesio_refresh(struct sysmon_envsys *, envsys_data_t *); 99 1.29 nonaka static void itesio_refresh_it8705_fans(struct itesio_softc *, 100 1.29 nonaka envsys_data_t *); 101 1.29 nonaka static void itesio_setup_it8625_sensors(struct itesio_softc *); 102 1.29 nonaka static void itesio_refresh_it8625_volts(struct itesio_softc *, 103 1.29 nonaka envsys_data_t *); 104 1.29 nonaka static void itesio_refresh_it8625_fans(struct itesio_softc *, 105 1.29 nonaka envsys_data_t *); 106 1.1 xtraeme 107 1.9 xtraeme /* sysmon_wdog glue */ 108 1.19 pgoyette static bool itesio_wdt_suspend(device_t, const pmf_qual_t *); 109 1.9 xtraeme static int itesio_wdt_setmode(struct sysmon_wdog *); 110 1.9 xtraeme static int itesio_wdt_tickle(struct sysmon_wdog *); 111 1.9 xtraeme 112 1.1 xtraeme /* rfact values for voltage sensors */ 113 1.1 xtraeme static const int itesio_vrfact[] = { 114 1.1 xtraeme RFACT_NONE, /* VCORE_A */ 115 1.1 xtraeme RFACT_NONE, /* VCORE_B */ 116 1.1 xtraeme RFACT_NONE, /* +3.3V */ 117 1.1 xtraeme RFACT(68, 100), /* +5V */ 118 1.1 xtraeme RFACT(30, 10), /* +12V */ 119 1.16 xtraeme RFACT(21, 10), /* -5V */ 120 1.16 xtraeme RFACT(83, 20), /* -12V */ 121 1.1 xtraeme RFACT(68, 100), /* STANDBY */ 122 1.1 xtraeme RFACT_NONE /* VBAT */ 123 1.1 xtraeme }; 124 1.1 xtraeme 125 1.29 nonaka static const struct itesio_config itesio_config[] = { 126 1.29 nonaka { 127 1.29 nonaka .chipid = ITESIO_ID8625, 128 1.29 nonaka .no_wdt = true, 129 1.29 nonaka .num_sensors = IT8625_NUM_SENSORS, 130 1.29 nonaka .voltstart_idx = IT8625_VOLTSTART_IDX, 131 1.29 nonaka .fanstart_idx = IT8625_FANSTART_IDX, 132 1.29 nonaka .setup_sensors = itesio_setup_it8625_sensors, 133 1.29 nonaka .refresh_volts = itesio_refresh_it8625_volts, 134 1.29 nonaka .refresh_fans = itesio_refresh_it8625_fans, 135 1.29 nonaka }, 136 1.29 nonaka { .chipid = ITESIO_ID8628, }, 137 1.29 nonaka { .chipid = ITESIO_ID8655, }, 138 1.29 nonaka { 139 1.29 nonaka .chipid = ITESIO_ID8705, 140 1.29 nonaka .no_wdt = true, 141 1.29 nonaka .refresh_fans = itesio_refresh_it8705_fans, 142 1.29 nonaka }, 143 1.29 nonaka { 144 1.29 nonaka .chipid = ITESIO_ID8712, 145 1.29 nonaka .refresh_fans = itesio_refresh_it8705_fans, 146 1.29 nonaka }, 147 1.29 nonaka { .chipid = ITESIO_ID8716, }, 148 1.29 nonaka { .chipid = ITESIO_ID8718, }, 149 1.29 nonaka { .chipid = ITESIO_ID8720, }, 150 1.29 nonaka { .chipid = ITESIO_ID8721, }, 151 1.29 nonaka { .chipid = ITESIO_ID8726, }, 152 1.29 nonaka { .chipid = ITESIO_ID8728, }, 153 1.29 nonaka { .chipid = ITESIO_ID8771, }, 154 1.29 nonaka { .chipid = ITESIO_ID8772, }, 155 1.29 nonaka }; 156 1.29 nonaka 157 1.29 nonaka static const struct itesio_config * 158 1.29 nonaka itesio_isa_find_config(uint16_t chipid) 159 1.29 nonaka { 160 1.29 nonaka const struct itesio_config *ic; 161 1.29 nonaka size_t i; 162 1.29 nonaka 163 1.29 nonaka for (i = 0; i < __arraycount(itesio_config); i++) { 164 1.29 nonaka ic = &itesio_config[i]; 165 1.29 nonaka if (chipid == ic->chipid) 166 1.29 nonaka return ic; 167 1.29 nonaka } 168 1.29 nonaka return NULL; 169 1.29 nonaka } 170 1.29 nonaka 171 1.1 xtraeme static int 172 1.14 xtraeme itesio_isa_match(device_t parent, cfdata_t match, void *aux) 173 1.1 xtraeme { 174 1.1 xtraeme struct isa_attach_args *ia = aux; 175 1.1 xtraeme bus_space_handle_t ioh; 176 1.29 nonaka const struct itesio_config *ic; 177 1.1 xtraeme uint16_t cr; 178 1.1 xtraeme 179 1.1 xtraeme /* Must supply an address */ 180 1.1 xtraeme if (ia->ia_nio < 1) 181 1.1 xtraeme return 0; 182 1.1 xtraeme 183 1.1 xtraeme if (ISA_DIRECT_CONFIG(ia)) 184 1.1 xtraeme return 0; 185 1.1 xtraeme 186 1.1 xtraeme if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 187 1.1 xtraeme return 0; 188 1.1 xtraeme 189 1.1 xtraeme if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) 190 1.1 xtraeme return 0; 191 1.1 xtraeme 192 1.1 xtraeme itesio_enter(ia->ia_iot, ioh); 193 1.1 xtraeme cr = (itesio_readreg(ia->ia_iot, ioh, ITESIO_CHIPID1) << 8); 194 1.1 xtraeme cr |= itesio_readreg(ia->ia_iot, ioh, ITESIO_CHIPID2); 195 1.1 xtraeme itesio_exit(ia->ia_iot, ioh); 196 1.1 xtraeme bus_space_unmap(ia->ia_iot, ioh, 2); 197 1.1 xtraeme 198 1.29 nonaka ic = itesio_isa_find_config(cr); 199 1.29 nonaka if (ic == NULL) 200 1.1 xtraeme return 0; 201 1.29 nonaka 202 1.29 nonaka ia->ia_nio = 1; 203 1.29 nonaka ia->ia_io[0].ir_size = 2; 204 1.29 nonaka ia->ia_niomem = 0; 205 1.29 nonaka ia->ia_nirq = 0; 206 1.29 nonaka ia->ia_ndrq = 0; 207 1.29 nonaka return 1; 208 1.1 xtraeme } 209 1.1 xtraeme 210 1.1 xtraeme static void 211 1.1 xtraeme itesio_isa_attach(device_t parent, device_t self, void *aux) 212 1.1 xtraeme { 213 1.1 xtraeme struct itesio_softc *sc = device_private(self); 214 1.1 xtraeme struct isa_attach_args *ia = aux; 215 1.29 nonaka const struct itesio_config *ic; 216 1.29 nonaka uint32_t i; 217 1.29 nonaka int error; 218 1.1 xtraeme uint8_t cr; 219 1.1 xtraeme 220 1.9 xtraeme sc->sc_iot = ia->ia_iot; 221 1.1 xtraeme 222 1.9 xtraeme if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0, 223 1.18 jakllsch &sc->sc_pnp_ioh)) { 224 1.18 jakllsch aprint_error(": can't map pnp i/o space\n"); 225 1.1 xtraeme return; 226 1.1 xtraeme } 227 1.6 jmcneill 228 1.6 jmcneill aprint_naive("\n"); 229 1.6 jmcneill 230 1.1 xtraeme /* 231 1.1 xtraeme * Enter to the Super I/O MB PNP mode. 232 1.1 xtraeme */ 233 1.18 jakllsch itesio_enter(sc->sc_iot, sc->sc_pnp_ioh); 234 1.1 xtraeme /* 235 1.1 xtraeme * Get info from the Super I/O Global Configuration Registers: 236 1.1 xtraeme * Chip IDs and Device Revision. 237 1.1 xtraeme */ 238 1.18 jakllsch sc->sc_chipid = (itesio_readreg(sc->sc_iot, sc->sc_pnp_ioh, 239 1.9 xtraeme ITESIO_CHIPID1) << 8); 240 1.18 jakllsch sc->sc_chipid |= itesio_readreg(sc->sc_iot, sc->sc_pnp_ioh, 241 1.9 xtraeme ITESIO_CHIPID2); 242 1.18 jakllsch sc->sc_devrev = (itesio_readreg(sc->sc_iot, sc->sc_pnp_ioh, 243 1.9 xtraeme ITESIO_DEVREV) & 0x0f); 244 1.1 xtraeme /* 245 1.1 xtraeme * Select the EC LDN to get the Base Address. 246 1.1 xtraeme */ 247 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_LDNSEL, 248 1.18 jakllsch ITESIO_EC_LDN); 249 1.1 xtraeme sc->sc_hwmon_baseaddr = 250 1.18 jakllsch (itesio_readreg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_EC_MSB) << 8); 251 1.18 jakllsch sc->sc_hwmon_baseaddr |= itesio_readreg(sc->sc_iot, sc->sc_pnp_ioh, 252 1.9 xtraeme ITESIO_EC_LSB); 253 1.1 xtraeme /* 254 1.9 xtraeme * We are done, exit MB PNP mode. 255 1.1 xtraeme */ 256 1.18 jakllsch itesio_exit(sc->sc_iot, sc->sc_pnp_ioh); 257 1.1 xtraeme 258 1.29 nonaka ic = itesio_isa_find_config(sc->sc_chipid); 259 1.29 nonaka if (ic == NULL) { 260 1.29 nonaka aprint_error(": unknown chipid: %04x", sc->sc_chipid); 261 1.29 nonaka goto out2; 262 1.29 nonaka } 263 1.29 nonaka sc->sc_config = *ic; 264 1.29 nonaka if (sc->sc_config.num_sensors == 0) 265 1.29 nonaka sc->sc_config.num_sensors = IT_NUM_SENSORS; 266 1.29 nonaka if (sc->sc_config.voltstart_idx == 0) 267 1.29 nonaka sc->sc_config.voltstart_idx = IT_VOLTSTART_IDX; 268 1.29 nonaka if (sc->sc_config.fanstart_idx == 0) 269 1.29 nonaka sc->sc_config.fanstart_idx = IT_FANSTART_IDX; 270 1.29 nonaka if (sc->sc_config.setup_sensors == NULL) 271 1.29 nonaka sc->sc_config.setup_sensors = itesio_setup_sensors; 272 1.29 nonaka if (sc->sc_config.refresh_temp == NULL) 273 1.29 nonaka sc->sc_config.refresh_temp = itesio_refresh_temp; 274 1.29 nonaka if (sc->sc_config.refresh_volts == NULL) 275 1.29 nonaka sc->sc_config.refresh_volts = itesio_refresh_volts; 276 1.29 nonaka if (sc->sc_config.refresh_fans == NULL) 277 1.29 nonaka sc->sc_config.refresh_fans = itesio_refresh_fans; 278 1.29 nonaka 279 1.1 xtraeme aprint_normal(": iTE IT%4xF Super I/O (rev %d)\n", 280 1.1 xtraeme sc->sc_chipid, sc->sc_devrev); 281 1.1 xtraeme aprint_normal_dev(self, "Hardware Monitor registers at 0x%x\n", 282 1.1 xtraeme sc->sc_hwmon_baseaddr); 283 1.1 xtraeme 284 1.18 jakllsch if (bus_space_map(sc->sc_iot, sc->sc_hwmon_baseaddr, 8, 0, 285 1.9 xtraeme &sc->sc_ec_ioh)) { 286 1.1 xtraeme aprint_error_dev(self, "cannot map hwmon i/o space\n"); 287 1.15 xtraeme goto out2; 288 1.1 xtraeme } 289 1.1 xtraeme 290 1.1 xtraeme sc->sc_hwmon_mapped = true; 291 1.1 xtraeme 292 1.1 xtraeme /* Activate monitoring */ 293 1.1 xtraeme cr = itesio_ecreadreg(sc, ITESIO_EC_CONFIG); 294 1.1 xtraeme SET(cr, 0x01); 295 1.1 xtraeme itesio_ecwritereg(sc, ITESIO_EC_CONFIG, cr); 296 1.1 xtraeme 297 1.1 xtraeme #ifdef notyet 298 1.1 xtraeme /* Enable beep alarms */ 299 1.1 xtraeme cr = itesio_ecreadreg(sc, ITESIO_EC_BEEPEER); 300 1.1 xtraeme SET(cr, 0x02); /* Voltage exceeds limit */ 301 1.1 xtraeme SET(cr, 0x04); /* Temperature exceeds limit */ 302 1.1 xtraeme itesio_ecwritereg(sc, ITESIO_EC_BEEPEER, cr); 303 1.1 xtraeme #endif 304 1.1 xtraeme 305 1.4 xtraeme /* 306 1.4 xtraeme * Initialize and attach sensors. 307 1.4 xtraeme */ 308 1.29 nonaka (*sc->sc_config.setup_sensors)(sc); 309 1.4 xtraeme sc->sc_sme = sysmon_envsys_create(); 310 1.29 nonaka for (i = 0; i < sc->sc_config.num_sensors; i++) { 311 1.4 xtraeme if (sysmon_envsys_sensor_attach(sc->sc_sme, 312 1.4 xtraeme &sc->sc_sensor[i])) { 313 1.4 xtraeme sysmon_envsys_destroy(sc->sc_sme); 314 1.30 mlelstv sc->sc_sme = NULL; 315 1.15 xtraeme goto out; 316 1.4 xtraeme } 317 1.1 xtraeme } 318 1.1 xtraeme /* 319 1.1 xtraeme * Hook into the system monitor. 320 1.1 xtraeme */ 321 1.4 xtraeme sc->sc_sme->sme_name = device_xname(self); 322 1.4 xtraeme sc->sc_sme->sme_cookie = sc; 323 1.4 xtraeme sc->sc_sme->sme_refresh = itesio_refresh; 324 1.1 xtraeme 325 1.29 nonaka if ((error = sysmon_envsys_register(sc->sc_sme))) { 326 1.5 xtraeme aprint_error_dev(self, 327 1.29 nonaka "unable to register with sysmon (%d)\n", error); 328 1.4 xtraeme sysmon_envsys_destroy(sc->sc_sme); 329 1.30 mlelstv sc->sc_sme = NULL; 330 1.15 xtraeme goto out; 331 1.1 xtraeme } 332 1.1 xtraeme sc->sc_hwmon_enabled = true; 333 1.9 xtraeme 334 1.20 pgoyette if (!pmf_device_register(self, NULL, NULL)) 335 1.20 pgoyette aprint_error_dev(self, "couldn't establish power handler\n"); 336 1.20 pgoyette 337 1.29 nonaka /* Some chips don't support the WDT */ 338 1.29 nonaka if (sc->sc_config.no_wdt) 339 1.15 xtraeme goto out2; 340 1.9 xtraeme 341 1.9 xtraeme /* 342 1.9 xtraeme * Initialize the watchdog timer. 343 1.9 xtraeme */ 344 1.9 xtraeme sc->sc_smw.smw_name = device_xname(self); 345 1.9 xtraeme sc->sc_smw.smw_cookie = sc; 346 1.9 xtraeme sc->sc_smw.smw_setmode = itesio_wdt_setmode; 347 1.9 xtraeme sc->sc_smw.smw_tickle = itesio_wdt_tickle; 348 1.9 xtraeme sc->sc_smw.smw_period = 60; 349 1.9 xtraeme 350 1.9 xtraeme if (sysmon_wdog_register(&sc->sc_smw)) { 351 1.9 xtraeme aprint_error_dev(self, "unable to register watchdog timer\n"); 352 1.15 xtraeme goto out2; 353 1.9 xtraeme } 354 1.9 xtraeme sc->sc_wdt_enabled = true; 355 1.9 xtraeme aprint_normal_dev(self, "Watchdog Timer present\n"); 356 1.19 pgoyette 357 1.20 pgoyette pmf_device_deregister(self); 358 1.19 pgoyette if (!pmf_device_register(self, itesio_wdt_suspend, NULL)) 359 1.19 pgoyette aprint_error_dev(self, "couldn't establish power handler\n"); 360 1.19 pgoyette 361 1.15 xtraeme return; 362 1.15 xtraeme 363 1.15 xtraeme out: 364 1.18 jakllsch bus_space_unmap(sc->sc_iot, sc->sc_ec_ioh, 8); 365 1.15 xtraeme out2: 366 1.18 jakllsch bus_space_unmap(sc->sc_iot, sc->sc_pnp_ioh, 2); 367 1.1 xtraeme } 368 1.1 xtraeme 369 1.1 xtraeme static int 370 1.1 xtraeme itesio_isa_detach(device_t self, int flags) 371 1.1 xtraeme { 372 1.1 xtraeme struct itesio_softc *sc = device_private(self); 373 1.1 xtraeme 374 1.1 xtraeme if (sc->sc_hwmon_enabled) 375 1.4 xtraeme sysmon_envsys_unregister(sc->sc_sme); 376 1.1 xtraeme if (sc->sc_hwmon_mapped) 377 1.18 jakllsch bus_space_unmap(sc->sc_iot, sc->sc_ec_ioh, 8); 378 1.9 xtraeme if (sc->sc_wdt_enabled) { 379 1.12 wiz sysmon_wdog_unregister(&sc->sc_smw); 380 1.18 jakllsch bus_space_unmap(sc->sc_iot, sc->sc_pnp_ioh, 2); 381 1.9 xtraeme } 382 1.9 xtraeme 383 1.29 nonaka if (sc->sc_sensor != NULL) { 384 1.29 nonaka kmem_free(sc->sc_sensor, 385 1.29 nonaka sizeof(sc->sc_sensor[0]) * sc->sc_config.num_sensors); 386 1.29 nonaka } 387 1.29 nonaka 388 1.1 xtraeme return 0; 389 1.1 xtraeme } 390 1.1 xtraeme 391 1.19 pgoyette static bool 392 1.19 pgoyette itesio_wdt_suspend(device_t dev, const pmf_qual_t *qual) 393 1.19 pgoyette { 394 1.19 pgoyette struct itesio_softc *sc = device_private(dev); 395 1.19 pgoyette 396 1.19 pgoyette /* Don't allow suspend if watchdog is armed */ 397 1.19 pgoyette if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED) 398 1.19 pgoyette return false; 399 1.19 pgoyette return true; 400 1.19 pgoyette } 401 1.19 pgoyette 402 1.1 xtraeme /* 403 1.1 xtraeme * Functions to read/write to the Environmental Controller. 404 1.1 xtraeme */ 405 1.1 xtraeme static uint8_t 406 1.1 xtraeme itesio_ecreadreg(struct itesio_softc *sc, int reg) 407 1.1 xtraeme { 408 1.18 jakllsch bus_space_write_1(sc->sc_iot, sc->sc_ec_ioh, ITESIO_EC_ADDR, reg); 409 1.18 jakllsch return bus_space_read_1(sc->sc_iot, sc->sc_ec_ioh, ITESIO_EC_DATA); 410 1.1 xtraeme } 411 1.1 xtraeme 412 1.1 xtraeme static void 413 1.1 xtraeme itesio_ecwritereg(struct itesio_softc *sc, int reg, int val) 414 1.1 xtraeme { 415 1.18 jakllsch bus_space_write_1(sc->sc_iot, sc->sc_ec_ioh, ITESIO_EC_ADDR, reg); 416 1.18 jakllsch bus_space_write_1(sc->sc_iot, sc->sc_ec_ioh, ITESIO_EC_DATA, val); 417 1.1 xtraeme } 418 1.1 xtraeme 419 1.1 xtraeme /* 420 1.1 xtraeme * Functions to enter/exit/read/write to the Super I/O. 421 1.1 xtraeme */ 422 1.1 xtraeme static uint8_t 423 1.1 xtraeme itesio_readreg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg) 424 1.1 xtraeme { 425 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, reg); 426 1.1 xtraeme return bus_space_read_1(iot, ioh, ITESIO_DATA); 427 1.1 xtraeme } 428 1.1 xtraeme 429 1.1 xtraeme static void 430 1.1 xtraeme itesio_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, int val) 431 1.1 xtraeme { 432 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, reg); 433 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_DATA, val); 434 1.1 xtraeme } 435 1.1 xtraeme 436 1.1 xtraeme static void 437 1.1 xtraeme itesio_enter(bus_space_tag_t iot, bus_space_handle_t ioh) 438 1.1 xtraeme { 439 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, 0x87); 440 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, 0x01); 441 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, 0x55); 442 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, 0x55); 443 1.1 xtraeme } 444 1.1 xtraeme 445 1.1 xtraeme static void 446 1.1 xtraeme itesio_exit(bus_space_tag_t iot, bus_space_handle_t ioh) 447 1.1 xtraeme { 448 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_ADDR, 0x02); 449 1.1 xtraeme bus_space_write_1(iot, ioh, ITESIO_DATA, 0x02); 450 1.1 xtraeme } 451 1.1 xtraeme 452 1.1 xtraeme 453 1.1 xtraeme #define COPYDESCR(x, y) \ 454 1.1 xtraeme do { \ 455 1.1 xtraeme strlcpy((x), (y), sizeof(x)); \ 456 1.1 xtraeme } while (0) 457 1.1 xtraeme /* 458 1.1 xtraeme * sysmon_envsys(9) glue. 459 1.1 xtraeme */ 460 1.1 xtraeme static void 461 1.29 nonaka itesio_setup_sensors_common(struct itesio_softc *sc) 462 1.1 xtraeme { 463 1.29 nonaka const struct itesio_config *ic = &sc->sc_config; 464 1.29 nonaka size_t allocsz; 465 1.29 nonaka uint32_t i; 466 1.29 nonaka 467 1.29 nonaka allocsz = sizeof(sc->sc_sensor[0]) * ic->num_sensors; 468 1.29 nonaka sc->sc_sensor = kmem_zalloc(allocsz, KM_SLEEP); 469 1.1 xtraeme 470 1.1 xtraeme /* temperatures */ 471 1.29 nonaka for (i = 0; i < ic->voltstart_idx; i++) 472 1.4 xtraeme sc->sc_sensor[i].units = ENVSYS_STEMP; 473 1.1 xtraeme 474 1.29 nonaka /* voltages */ 475 1.29 nonaka for (i = ic->voltstart_idx; i < ic->fanstart_idx; i++) { 476 1.29 nonaka sc->sc_sensor[i].units = ENVSYS_SVOLTS_DC; 477 1.29 nonaka sc->sc_sensor[i].flags = ENVSYS_FCHANGERFACT; 478 1.29 nonaka } 479 1.29 nonaka 480 1.29 nonaka /* fans */ 481 1.29 nonaka for (i = ic->fanstart_idx; i < ic->num_sensors; i++) 482 1.29 nonaka sc->sc_sensor[i].units = ENVSYS_SFANRPM; 483 1.29 nonaka 484 1.29 nonaka /* all */ 485 1.29 nonaka for (i = 0; i < ic->num_sensors; i++) 486 1.29 nonaka sc->sc_sensor[i].state = ENVSYS_SINVALID; 487 1.29 nonaka } 488 1.29 nonaka 489 1.29 nonaka static void 490 1.29 nonaka itesio_setup_sensors(struct itesio_softc *sc) 491 1.29 nonaka { 492 1.29 nonaka 493 1.29 nonaka itesio_setup_sensors_common(sc); 494 1.29 nonaka 495 1.29 nonaka /* temperatures */ 496 1.4 xtraeme COPYDESCR(sc->sc_sensor[0].desc, "CPU Temp"); 497 1.4 xtraeme COPYDESCR(sc->sc_sensor[1].desc, "System Temp"); 498 1.4 xtraeme COPYDESCR(sc->sc_sensor[2].desc, "Aux Temp"); 499 1.1 xtraeme 500 1.1 xtraeme /* voltages */ 501 1.4 xtraeme COPYDESCR(sc->sc_sensor[3].desc, "VCORE_A"); 502 1.4 xtraeme COPYDESCR(sc->sc_sensor[4].desc, "VCORE_B"); 503 1.4 xtraeme COPYDESCR(sc->sc_sensor[5].desc, "+3.3V"); 504 1.4 xtraeme COPYDESCR(sc->sc_sensor[6].desc, "+5V"); 505 1.4 xtraeme COPYDESCR(sc->sc_sensor[7].desc, "+12V"); 506 1.16 xtraeme COPYDESCR(sc->sc_sensor[8].desc, "-5V"); 507 1.16 xtraeme COPYDESCR(sc->sc_sensor[9].desc, "-12V"); 508 1.4 xtraeme COPYDESCR(sc->sc_sensor[10].desc, "STANDBY"); 509 1.4 xtraeme COPYDESCR(sc->sc_sensor[11].desc, "VBAT"); 510 1.1 xtraeme 511 1.1 xtraeme /* fans */ 512 1.4 xtraeme COPYDESCR(sc->sc_sensor[12].desc, "CPU Fan"); 513 1.4 xtraeme COPYDESCR(sc->sc_sensor[13].desc, "System Fan"); 514 1.4 xtraeme COPYDESCR(sc->sc_sensor[14].desc, "Aux Fan"); 515 1.29 nonaka } 516 1.29 nonaka 517 1.29 nonaka static void 518 1.29 nonaka itesio_setup_it8625_sensors(struct itesio_softc *sc) 519 1.29 nonaka { 520 1.29 nonaka 521 1.29 nonaka itesio_setup_sensors_common(sc); 522 1.29 nonaka 523 1.29 nonaka /* temperatures */ 524 1.29 nonaka COPYDESCR(sc->sc_sensor[0].desc, "Temp0"); 525 1.29 nonaka COPYDESCR(sc->sc_sensor[1].desc, "Temp1"); 526 1.29 nonaka COPYDESCR(sc->sc_sensor[2].desc, "Temp2"); 527 1.22 pgoyette 528 1.29 nonaka /* voltages */ 529 1.29 nonaka COPYDESCR(sc->sc_sensor[3].desc, "VIN0"); 530 1.29 nonaka COPYDESCR(sc->sc_sensor[4].desc, "VIN1"); 531 1.29 nonaka COPYDESCR(sc->sc_sensor[5].desc, "VIN2"); 532 1.29 nonaka COPYDESCR(sc->sc_sensor[6].desc, "VIN3"); 533 1.29 nonaka COPYDESCR(sc->sc_sensor[7].desc, "VIN4"); 534 1.29 nonaka COPYDESCR(sc->sc_sensor[8].desc, "VIN5"); 535 1.29 nonaka COPYDESCR(sc->sc_sensor[9].desc, "VIN6"); 536 1.29 nonaka COPYDESCR(sc->sc_sensor[10].desc, "Internal 3VSB"); 537 1.29 nonaka COPYDESCR(sc->sc_sensor[11].desc, "VBAT"); 538 1.29 nonaka COPYDESCR(sc->sc_sensor[12].desc, "Internal AVCC3"); 539 1.29 nonaka 540 1.29 nonaka /* fans */ 541 1.29 nonaka COPYDESCR(sc->sc_sensor[13].desc, "Fan0"); 542 1.29 nonaka COPYDESCR(sc->sc_sensor[14].desc, "Fan1"); 543 1.29 nonaka COPYDESCR(sc->sc_sensor[15].desc, "Fan2"); 544 1.29 nonaka COPYDESCR(sc->sc_sensor[16].desc, "Fan3"); 545 1.29 nonaka COPYDESCR(sc->sc_sensor[17].desc, "Fan4"); 546 1.29 nonaka COPYDESCR(sc->sc_sensor[18].desc, "Fan5"); 547 1.1 xtraeme } 548 1.1 xtraeme #undef COPYDESCR 549 1.1 xtraeme 550 1.1 xtraeme static void 551 1.1 xtraeme itesio_refresh_temp(struct itesio_softc *sc, envsys_data_t *edata) 552 1.1 xtraeme { 553 1.1 xtraeme int sdata; 554 1.1 xtraeme 555 1.1 xtraeme sdata = itesio_ecreadreg(sc, ITESIO_EC_SENSORTEMPBASE + edata->sensor); 556 1.1 xtraeme /* sensor is not connected or reporting invalid data */ 557 1.1 xtraeme if (sdata == 0 || sdata >= 0xfa) { 558 1.1 xtraeme edata->state = ENVSYS_SINVALID; 559 1.1 xtraeme return; 560 1.1 xtraeme } 561 1.1 xtraeme 562 1.1 xtraeme DPRINTF(("%s: sdata[temp%d] 0x%x\n", __func__, edata->sensor, sdata)); 563 1.1 xtraeme /* Convert temperature to uK */ 564 1.1 xtraeme edata->value_cur = sdata * 1000000 + 273150000; 565 1.1 xtraeme edata->state = ENVSYS_SVALID; 566 1.1 xtraeme } 567 1.1 xtraeme 568 1.1 xtraeme static void 569 1.1 xtraeme itesio_refresh_volts(struct itesio_softc *sc, envsys_data_t *edata) 570 1.1 xtraeme { 571 1.1 xtraeme uint8_t vbatcr = 0; 572 1.1 xtraeme int i, sdata; 573 1.1 xtraeme 574 1.29 nonaka i = edata->sensor - sc->sc_config.voltstart_idx; 575 1.1 xtraeme 576 1.1 xtraeme sdata = itesio_ecreadreg(sc, ITESIO_EC_SENSORVOLTBASE + i); 577 1.1 xtraeme /* not connected */ 578 1.1 xtraeme if (sdata == 0 || sdata == 0xff) { 579 1.1 xtraeme edata->state = ENVSYS_SINVALID; 580 1.1 xtraeme return; 581 1.1 xtraeme } 582 1.1 xtraeme 583 1.1 xtraeme /* 584 1.1 xtraeme * update VBAT voltage reading every time we read it, to get 585 1.1 xtraeme * latest value. 586 1.1 xtraeme */ 587 1.1 xtraeme if (i == 8) { 588 1.1 xtraeme vbatcr = itesio_ecreadreg(sc, ITESIO_EC_CONFIG); 589 1.1 xtraeme SET(vbatcr, ITESIO_EC_UPDATEVBAT); 590 1.1 xtraeme itesio_ecwritereg(sc, ITESIO_EC_CONFIG, vbatcr); 591 1.1 xtraeme } 592 1.1 xtraeme 593 1.1 xtraeme DPRINTF(("%s: sdata[volt%d] 0x%x\n", __func__, i, sdata)); 594 1.1 xtraeme 595 1.1 xtraeme /* voltage returned as (mV << 4) */ 596 1.1 xtraeme edata->value_cur = (sdata << 4); 597 1.16 xtraeme /* negative values */ 598 1.16 xtraeme if (i == 5 || i == 6) 599 1.16 xtraeme edata->value_cur -= ITESIO_EC_VREF; 600 1.1 xtraeme /* rfact is (factor * 10^4) */ 601 1.1 xtraeme if (edata->rfact) 602 1.21 jakllsch edata->value_cur *= edata->rfact; 603 1.21 jakllsch else 604 1.21 jakllsch edata->value_cur *= itesio_vrfact[i]; 605 1.1 xtraeme /* division by 10 gets us back to uVDC */ 606 1.1 xtraeme edata->value_cur /= 10; 607 1.16 xtraeme if (i == 5 || i == 6) 608 1.16 xtraeme edata->value_cur += ITESIO_EC_VREF * 1000; 609 1.16 xtraeme 610 1.1 xtraeme edata->state = ENVSYS_SVALID; 611 1.1 xtraeme } 612 1.1 xtraeme 613 1.1 xtraeme static void 614 1.29 nonaka itesio_refresh_it8625_volts(struct itesio_softc *sc, envsys_data_t *edata) 615 1.29 nonaka { 616 1.29 nonaka int i, sdata; 617 1.29 nonaka 618 1.29 nonaka i = edata->sensor - sc->sc_config.voltstart_idx; 619 1.29 nonaka 620 1.29 nonaka if (i < 9) 621 1.29 nonaka sdata = itesio_ecreadreg(sc, ITESIO_EC_SENSORVOLTBASE + i); 622 1.29 nonaka else 623 1.29 nonaka sdata = itesio_ecreadreg(sc, 624 1.29 nonaka ITESIO_EC_SENSORVOLTEXTBASE + i - 9); 625 1.29 nonaka /* not connected */ 626 1.29 nonaka if (sdata == 0 || sdata == 0xff) { 627 1.29 nonaka edata->state = ENVSYS_SINVALID; 628 1.29 nonaka return; 629 1.29 nonaka } 630 1.29 nonaka 631 1.29 nonaka DPRINTF(("%s: sdata[volt%d] 0x%x\n", __func__, i, sdata)); 632 1.29 nonaka 633 1.29 nonaka if (i == 7) { 634 1.29 nonaka /* Internal 3VSB: reading value * 2 * 10.9mV */ 635 1.29 nonaka edata->value_cur = sdata * 2 * 109; 636 1.29 nonaka } else { 637 1.29 nonaka /* other: reading value * 10.9mV */ 638 1.29 nonaka edata->value_cur = sdata * 109; 639 1.29 nonaka } 640 1.29 nonaka /* rfact is (factor * 10^4) */ 641 1.29 nonaka if (edata->rfact) 642 1.29 nonaka edata->value_cur *= edata->rfact; 643 1.29 nonaka else 644 1.29 nonaka edata->value_cur *= RFACT_NONE; 645 1.29 nonaka /* division by 100 gets us back to uVDC */ 646 1.29 nonaka edata->value_cur /= 100; 647 1.29 nonaka edata->state = ENVSYS_SVALID; 648 1.29 nonaka } 649 1.29 nonaka 650 1.29 nonaka static void 651 1.1 xtraeme itesio_refresh_fans(struct itesio_softc *sc, envsys_data_t *edata) 652 1.1 xtraeme { 653 1.29 nonaka uint8_t mode; 654 1.29 nonaka uint16_t sdata; 655 1.29 nonaka int i; 656 1.29 nonaka 657 1.29 nonaka i = edata->sensor - sc->sc_config.fanstart_idx; 658 1.29 nonaka 659 1.29 nonaka mode = itesio_ecreadreg(sc, ITESIO_EC_FAN16_CER); 660 1.29 nonaka sdata = itesio_ecreadreg(sc, ITESIO_EC_SENSORFANBASE + i); 661 1.29 nonaka if (mode & (1 << i)) 662 1.29 nonaka sdata += (itesio_ecreadreg(sc, 663 1.29 nonaka ITESIO_EC_SENSORFANEXTBASE + i) << 8); 664 1.29 nonaka edata->state = ENVSYS_SVALID; 665 1.29 nonaka if (sdata == 0 || 666 1.29 nonaka sdata == ((mode & (1 << i)) ? 0xffff : 0xff)) 667 1.29 nonaka edata->state = ENVSYS_SINVALID; 668 1.29 nonaka else { 669 1.29 nonaka edata->value_cur = 1350000 / 2 / sdata; 670 1.29 nonaka edata->state = ENVSYS_SVALID; 671 1.29 nonaka } 672 1.29 nonaka DPRINTF(("%s: 16bit sdata[fan%d] 0x%x\n", __func__, i, sdata)); 673 1.29 nonaka } 674 1.29 nonaka 675 1.29 nonaka static void 676 1.29 nonaka itesio_refresh_it8705_fans(struct itesio_softc *sc, envsys_data_t *edata) 677 1.29 nonaka { 678 1.29 nonaka uint16_t sdata; 679 1.1 xtraeme int i, divisor, odivisor, ndivisor; 680 1.1 xtraeme 681 1.29 nonaka i = edata->sensor - sc->sc_config.fanstart_idx; 682 1.1 xtraeme 683 1.29 nonaka /* 684 1.29 nonaka * Use the Fan Tachometer Divisor Register for 685 1.29 nonaka * IT8705F and IT8712F. 686 1.29 nonaka */ 687 1.29 nonaka divisor = odivisor = ndivisor = 688 1.29 nonaka itesio_ecreadreg(sc, ITESIO_EC_FAN_TDR); 689 1.29 nonaka sdata = itesio_ecreadreg(sc, ITESIO_EC_SENSORFANBASE + i); 690 1.29 nonaka if (sdata == 0xff) { 691 1.29 nonaka edata->state = ENVSYS_SINVALID; 692 1.29 nonaka if (i == 2) 693 1.29 nonaka ndivisor |= 0x40; 694 1.29 nonaka else { 695 1.29 nonaka ndivisor &= ~(7 << (i * 3)); 696 1.29 nonaka ndivisor |= ((divisor + 1) & 7) << (i * 3); 697 1.1 xtraeme } 698 1.1 xtraeme } else { 699 1.29 nonaka if (i == 2) 700 1.29 nonaka divisor = divisor & 1 ? 3 : 1; 701 1.29 nonaka 702 1.29 nonaka if ((sdata << (divisor & 7)) == 0) 703 1.1 xtraeme edata->state = ENVSYS_SINVALID; 704 1.1 xtraeme else { 705 1.29 nonaka edata->value_cur = 706 1.29 nonaka 1350000 / (sdata << (divisor & 7)); 707 1.1 xtraeme edata->state = ENVSYS_SVALID; 708 1.1 xtraeme } 709 1.1 xtraeme } 710 1.29 nonaka DPRINTF(("%s: 8bit sdata[fan%d] 0x%x div: 0x%x\n", __func__, 711 1.29 nonaka i, sdata, divisor)); 712 1.29 nonaka if (ndivisor != odivisor) 713 1.29 nonaka itesio_ecwritereg(sc, ITESIO_EC_FAN_TDR, ndivisor); 714 1.29 nonaka } 715 1.29 nonaka 716 1.29 nonaka static void 717 1.29 nonaka itesio_refresh_it8625_fans(struct itesio_softc *sc, envsys_data_t *edata) 718 1.29 nonaka { 719 1.29 nonaka uint16_t sdata; 720 1.29 nonaka int i; 721 1.29 nonaka 722 1.29 nonaka i = edata->sensor - sc->sc_config.fanstart_idx; 723 1.29 nonaka 724 1.29 nonaka switch (i) { 725 1.29 nonaka case 0: 726 1.29 nonaka case 1: 727 1.29 nonaka case 2: 728 1.29 nonaka sdata = itesio_ecreadreg(sc, ITESIO_EC_SENSORFANBASE + i); 729 1.29 nonaka sdata += (itesio_ecreadreg(sc, 730 1.29 nonaka ITESIO_EC_SENSORFANEXTBASE + i) << 8); 731 1.29 nonaka break; 732 1.29 nonaka case 3: 733 1.29 nonaka sdata = itesio_ecreadreg(sc, IT8625_EC_SENSORFAN4_LSB); 734 1.29 nonaka sdata += itesio_ecreadreg(sc, IT8625_EC_SENSORFAN4_MSB) << 8; 735 1.29 nonaka break; 736 1.29 nonaka case 4: 737 1.29 nonaka sdata = itesio_ecreadreg(sc, IT8625_EC_SENSORFAN5_LSB); 738 1.29 nonaka sdata += itesio_ecreadreg(sc, IT8625_EC_SENSORFAN5_MSB) << 8; 739 1.29 nonaka break; 740 1.29 nonaka case 5: 741 1.29 nonaka sdata = itesio_ecreadreg(sc, IT8625_EC_SENSORFAN6_LSB); 742 1.29 nonaka sdata += itesio_ecreadreg(sc, IT8625_EC_SENSORFAN6_MSB) << 8; 743 1.29 nonaka break; 744 1.29 nonaka default: 745 1.29 nonaka edata->state = ENVSYS_SINVALID; 746 1.29 nonaka return; 747 1.29 nonaka } 748 1.29 nonaka edata->state = ENVSYS_SVALID; 749 1.29 nonaka if (sdata == 0 || sdata == 0xffff) 750 1.29 nonaka edata->state = ENVSYS_SINVALID; 751 1.29 nonaka else { 752 1.29 nonaka edata->value_cur = 1350000 / 2 / sdata; 753 1.29 nonaka edata->state = ENVSYS_SVALID; 754 1.29 nonaka } 755 1.29 nonaka DPRINTF(("%s: 16bit sdata[fan%d] 0x%x\n", __func__, i, sdata)); 756 1.1 xtraeme } 757 1.1 xtraeme 758 1.4 xtraeme static void 759 1.4 xtraeme itesio_refresh(struct sysmon_envsys *sme, struct envsys_data *edata) 760 1.1 xtraeme { 761 1.1 xtraeme struct itesio_softc *sc = sme->sme_cookie; 762 1.1 xtraeme 763 1.29 nonaka if (edata->sensor < sc->sc_config.voltstart_idx) 764 1.29 nonaka (*sc->sc_config.refresh_temp)(sc, edata); 765 1.29 nonaka else if (edata->sensor >= sc->sc_config.voltstart_idx && 766 1.29 nonaka edata->sensor < sc->sc_config.fanstart_idx) 767 1.29 nonaka (*sc->sc_config.refresh_volts)(sc, edata); 768 1.1 xtraeme else 769 1.29 nonaka (*sc->sc_config.refresh_fans)(sc, edata); 770 1.1 xtraeme } 771 1.9 xtraeme 772 1.9 xtraeme static int 773 1.9 xtraeme itesio_wdt_setmode(struct sysmon_wdog *smw) 774 1.9 xtraeme { 775 1.9 xtraeme struct itesio_softc *sc = smw->smw_cookie; 776 1.9 xtraeme int period = smw->smw_period; 777 1.9 xtraeme 778 1.9 xtraeme /* Enter MB PNP mode and select the WDT LDN */ 779 1.18 jakllsch itesio_enter(sc->sc_iot, sc->sc_pnp_ioh); 780 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_LDNSEL, 781 1.18 jakllsch ITESIO_WDT_LDN); 782 1.9 xtraeme 783 1.9 xtraeme if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { 784 1.9 xtraeme /* Disable the watchdog */ 785 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_CTL, 0); 786 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_CNF, 0); 787 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_TMO_MSB, 0); 788 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_TMO_LSB, 0); 789 1.9 xtraeme } else { 790 1.9 xtraeme /* Enable the watchdog */ 791 1.9 xtraeme if (period > ITESIO_WDT_MAXTIMO || period < 1) 792 1.9 xtraeme period = smw->smw_period = ITESIO_WDT_MAXTIMO; 793 1.9 xtraeme 794 1.9 xtraeme period *= 2; 795 1.9 xtraeme 796 1.9 xtraeme /* set the timeout and start the watchdog */ 797 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_TMO_MSB, 798 1.9 xtraeme period >> 8); 799 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_TMO_LSB, 800 1.9 xtraeme period & 0xff); 801 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_CNF, 802 1.9 xtraeme ITESIO_WDT_CNF_SECS | ITESIO_WDT_CNF_KRST | 803 1.9 xtraeme ITESIO_WDT_CNF_PWROK); 804 1.9 xtraeme } 805 1.9 xtraeme /* we are done, exit MB PNP mode */ 806 1.18 jakllsch itesio_exit(sc->sc_iot, sc->sc_pnp_ioh); 807 1.9 xtraeme 808 1.9 xtraeme return 0; 809 1.9 xtraeme } 810 1.9 xtraeme 811 1.9 xtraeme static int 812 1.9 xtraeme itesio_wdt_tickle(struct sysmon_wdog *smw) 813 1.9 xtraeme { 814 1.9 xtraeme struct itesio_softc *sc = smw->smw_cookie; 815 1.9 xtraeme int period = smw->smw_period * 2; 816 1.9 xtraeme 817 1.9 xtraeme /* refresh timeout value and exit */ 818 1.18 jakllsch itesio_enter(sc->sc_iot, sc->sc_pnp_ioh); 819 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_LDNSEL, 820 1.18 jakllsch ITESIO_WDT_LDN); 821 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_TMO_MSB, 822 1.9 xtraeme period >> 8); 823 1.18 jakllsch itesio_writereg(sc->sc_iot, sc->sc_pnp_ioh, ITESIO_WDT_TMO_LSB, 824 1.9 xtraeme period & 0xff); 825 1.18 jakllsch itesio_exit(sc->sc_iot, sc->sc_pnp_ioh); 826 1.9 xtraeme 827 1.9 xtraeme return 0; 828 1.9 xtraeme } 829 1.23 jmcneill 830 1.25 pgoyette MODULE(MODULE_CLASS_DRIVER, itesio, "sysmon_envsys,sysmon_wdog"); 831 1.23 jmcneill 832 1.23 jmcneill #ifdef _MODULE 833 1.23 jmcneill #include "ioconf.c" 834 1.23 jmcneill #endif 835 1.23 jmcneill 836 1.23 jmcneill static int 837 1.23 jmcneill itesio_modcmd(modcmd_t cmd, void *opaque) 838 1.23 jmcneill { 839 1.23 jmcneill switch (cmd) { 840 1.23 jmcneill case MODULE_CMD_INIT: 841 1.23 jmcneill #ifdef _MODULE 842 1.23 jmcneill return config_init_component(cfdriver_ioconf_itesio, 843 1.23 jmcneill cfattach_ioconf_itesio, cfdata_ioconf_itesio); 844 1.23 jmcneill #else 845 1.23 jmcneill return 0; 846 1.23 jmcneill #endif 847 1.23 jmcneill case MODULE_CMD_FINI: 848 1.23 jmcneill #ifdef _MODULE 849 1.23 jmcneill return config_fini_component(cfdriver_ioconf_itesio, 850 1.23 jmcneill cfattach_ioconf_itesio, cfdata_ioconf_itesio); 851 1.23 jmcneill #else 852 1.23 jmcneill return 0; 853 1.23 jmcneill #endif 854 1.23 jmcneill default: 855 1.23 jmcneill return ENOTTY; 856 1.23 jmcneill } 857 1.23 jmcneill } 858