1 /* $OpenBSD: sch311x.c,v 1.12 2009/08/22 03:51:07 mk Exp $ */ 2 /* 3 * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> 4 * Copyright (c) 2009 Michael Knudsen <mk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * SMSC SCH3112, SCH3114, and SCH3116 LPC Super I/O driver. 21 */ 22 23 #include <sys/param.h> 24 #include <sys/device.h> 25 #include <sys/kernel.h> 26 #include <sys/systm.h> 27 #include <sys/types.h> 28 #include <sys/sensors.h> 29 30 #include <machine/bus.h> 31 32 #include <dev/isa/isareg.h> 33 #include <dev/isa/isavar.h> 34 35 /* Device identifiers */ 36 #define SCHSIO_ID_SCH3112 0x7c 37 #define SCHSIO_ID_SCH3114 0x7d 38 #define SCHSIO_ID_SCH3116 0x7f 39 40 #define SCHSIO_IOSIZE 0x02 41 #define SCHSIO_PORT_CONFIG 0x00 42 43 /* These are used in configuration mode */ 44 #define SCHSIO_PORT_INDEX 0x00 45 #define SCHSIO_PORT_DATA 0x01 46 47 #define SCHSIO_CONFIG_ENTER 0x55 48 #define SCHSIO_CONFIG_LEAVE 0xaa 49 50 /* Register definitions */ 51 #define SCHSIO_IDX_LDEVSEL 0x07 /* Logical device select */ 52 #define SCHSIO_IDX_DEVICE 0x20 /* Device ID */ 53 #define SCHSIO_IDX_REV 0x21 /* Device revision */ 54 55 #define SCHSIO_IDX_BASE_HI 0x60 /* Configuration base address */ 56 #define SCHSIO_IDX_BASE_LO 0x61 57 58 /* Logical devices */ 59 #define SCHSIO_LDEV_RUNTIME 0x0a /* holds wdog and sensors */ 60 #define SCHSIO_LDEV_RUNTIME_SZ 0x100 61 62 /* Hardware monitor */ 63 #define SCHSIO_HWM_INTERVAL 5 /* seconds */ 64 65 /* Register access */ 66 #define SCHSIO_HWM_INDEX 0x70 67 #define SCHSIO_HWM_DATA 0x71 68 69 /* Sensor definitions */ 70 /* Voltage */ 71 #define SCHSIO_HWM_VOLT1 0x20 72 #define SCHSIO_HWM_VOLT2 0x21 73 #define SCHSIO_HWM_VOLT3 0x22 74 #define SCHSIO_HWM_VOLT4 0x23 75 #define SCHSIO_HWM_VOLT5 0x24 76 #define SCHSIO_HWM_VOLT6 0x99 77 #define SCHSIO_HWM_VOLT7 0x9a 78 79 /* Temperature */ 80 #define SCHSIO_HWM_TEMP1 0x26 81 #define SCHSIO_HWM_TEMP2 0x25 82 #define SCHSIO_HWM_TEMP3 0x27 83 84 /* Fan speed */ 85 #define SCHSIO_HWM_TACH1_L 0x28 86 #define SCHSIO_HWM_TACH1_U 0x29 87 #define SCHSIO_HWM_TACH2_L 0x2a 88 #define SCHSIO_HWM_TACH2_U 0x2b 89 #define SCHSIO_HWM_TACH3_L 0x2c 90 #define SCHSIO_HWM_TACH3_U 0x2d 91 92 /* 11111 = 90kHz * 10^9 */ 93 #define SCHSIO_FAN_RPM(x) (1000000000 / ((x) * 11111) * 60) 94 95 #define SCHSIO_CONV_VOLT1 66400 96 #define SCHSIO_CONV_VOLT2 20000 97 #define SCHSIO_CONV_VOLT3 43800 98 #define SCHSIO_CONV_VOLT4 66400 99 #define SCHSIO_CONV_VOLT5 160000 100 #define SCHSIO_CONV_VOLT6 43800 101 #define SCHSIO_CONV_VOLT7 43800 102 #define SCHSIO_VOLT_MUV(x, k) (1000000 * (x) / 2560000 * (k)) 103 104 #define SCHSIO_TEMP_MUK(x) (((x) + 273) * 1000000) 105 106 #define SCHSIO_SENSORS 13 107 108 #define SCHSIO_SENSOR_FAN1 0 109 #define SCHSIO_SENSOR_FAN2 1 110 #define SCHSIO_SENSOR_FAN3 2 111 112 #define SCHSIO_SENSOR_VOLT1 3 113 #define SCHSIO_SENSOR_VOLT2 4 114 #define SCHSIO_SENSOR_VOLT3 5 115 #define SCHSIO_SENSOR_VOLT4 6 116 #define SCHSIO_SENSOR_VOLT5 7 117 #define SCHSIO_SENSOR_VOLT6 8 118 #define SCHSIO_SENSOR_VOLT7 9 119 120 #define SCHSIO_SENSOR_TEMP1 10 121 #define SCHSIO_SENSOR_TEMP2 11 122 #define SCHSIO_SENSOR_TEMP3 12 123 124 125 /* Watchdog */ 126 127 /* Register access */ 128 #define SCHSIO_WDT_GPIO 0x47 129 #define SCHSIO_WDT_TIMEOUT 0x65 130 #define SCHSIO_WDT_VAL 0x66 131 #define SCHSIO_WDT_CFG 0x67 132 #define SCHSIO_WDT_CTRL 0x68 133 134 /* Bits */ 135 #define SCHSIO_WDT_GPIO_MASK 0x0f 136 #define SCHSIO_WDT_GPIO_OUT 0x0e 137 138 #define SCHSIO_WDT_TO_SECONDS (1 << 7) 139 140 #define SCHSIO_WDT_CTRL_TRIGGERED (1 << 0) 141 #define SCHSIO_WDT_CFG_KBDEN (1 << 1) 142 #define SCHSIO_WDT_CFG_MSEN (1 << 2) 143 144 /* autoconf(9) flags etc. */ 145 #define SCHSIO_CFFLAGS_WDTEN (1 << 0) 146 147 #define DEVNAME(x) ((x)->sc_dev.dv_xname) 148 149 struct schsio_softc { 150 struct device sc_dev; 151 152 bus_space_tag_t sc_iot; 153 bus_space_handle_t sc_ioh; 154 155 bus_space_handle_t sc_ioh_rr; 156 157 struct ksensordev sc_sensordev; 158 struct ksensor sc_sensor[SCHSIO_SENSORS]; 159 }; 160 161 int schsio_probe(struct device *, void *, void *); 162 void schsio_attach(struct device *, struct device *, void *); 163 164 static __inline void schsio_config_enable(bus_space_tag_t iot, 165 bus_space_handle_t ioh); 166 static __inline void schsio_config_disable(bus_space_tag_t iot, 167 bus_space_handle_t ioh); 168 169 u_int8_t schsio_config_read(bus_space_tag_t iot, bus_space_handle_t ioh, 170 u_int8_t reg); 171 void schsio_config_write(bus_space_tag_t iot, bus_space_handle_t ioh, 172 u_int8_t reg, u_int8_t val); 173 174 /* HWM prototypes */ 175 void schsio_hwm_init(struct schsio_softc *sc); 176 void schsio_hwm_update(void *arg); 177 u_int8_t schsio_hwm_read(struct schsio_softc *sc, u_int8_t reg); 178 179 /* Watchdog prototypes */ 180 181 void schsio_wdt_init(struct schsio_softc *sc); 182 int schsio_wdt_cb(void *arg, int period); 183 184 struct cfattach schsio_ca = { 185 sizeof(struct schsio_softc), 186 schsio_probe, 187 schsio_attach 188 }; 189 190 struct cfdriver schsio_cd = { 191 NULL, "schsio", DV_DULL 192 }; 193 194 static __inline void 195 schsio_config_enable(bus_space_tag_t iot, bus_space_handle_t ioh) 196 { 197 bus_space_write_1(iot, ioh, SCHSIO_PORT_CONFIG, SCHSIO_CONFIG_ENTER); 198 } 199 200 static __inline void 201 schsio_config_disable(bus_space_tag_t iot, bus_space_handle_t ioh) 202 { 203 bus_space_write_1(iot, ioh, SCHSIO_PORT_CONFIG, SCHSIO_CONFIG_LEAVE); 204 } 205 206 u_int8_t 207 schsio_config_read(bus_space_tag_t iot, bus_space_handle_t ioh, 208 u_int8_t reg) 209 { 210 bus_space_write_1(iot, ioh, SCHSIO_PORT_INDEX, reg); 211 return (bus_space_read_1(iot, ioh, SCHSIO_PORT_DATA)); 212 } 213 214 void 215 schsio_config_write(bus_space_tag_t iot, bus_space_handle_t ioh, 216 u_int8_t reg, u_int8_t val) 217 { 218 bus_space_write_1(iot, ioh, SCHSIO_PORT_INDEX, reg); 219 bus_space_write_1(iot, ioh, SCHSIO_PORT_DATA, val); 220 } 221 222 int 223 schsio_probe(struct device *parent, void *match, void *aux) 224 { 225 struct isa_attach_args *ia = aux; 226 bus_space_tag_t iot; 227 bus_space_handle_t ioh; 228 u_int8_t reg; 229 230 /* Match by device ID */ 231 iot = ia->ia_iot; 232 if (bus_space_map(iot, ia->ipa_io[0].base, SCHSIO_IOSIZE, 0, &ioh)) 233 return (0); 234 235 schsio_config_enable(iot, ioh); 236 reg = schsio_config_read(iot, ioh, SCHSIO_IDX_DEVICE); 237 schsio_config_disable(iot, ioh); 238 239 bus_space_unmap(iot, ia->ipa_io[0].base, SCHSIO_IOSIZE); 240 241 switch (reg) { 242 case SCHSIO_ID_SCH3112: 243 case SCHSIO_ID_SCH3114: 244 case SCHSIO_ID_SCH3116: 245 ia->ipa_nio = 1; 246 ia->ipa_io[0].length = SCHSIO_IOSIZE; 247 ia->ipa_nmem = 0; 248 ia->ipa_nirq = 0; 249 ia->ipa_ndrq = 0; 250 ia->ia_aux = (void *)(u_long) reg; 251 252 return (1); 253 break; 254 } 255 256 return (0); 257 } 258 259 void 260 schsio_attach(struct device *parent, struct device *self, void *aux) 261 { 262 struct schsio_softc *sc = (void *)self; 263 struct isa_attach_args *ia = aux; 264 u_int16_t iobase; 265 u_int8_t reg0, reg1; 266 267 /* Map ISA I/O space */ 268 sc->sc_iot = ia->ia_iot; 269 if (bus_space_map(sc->sc_iot, ia->ipa_io[0].base, 270 SCHSIO_IOSIZE, 0, &sc->sc_ioh)) { 271 printf(": can't map i/o space\n"); 272 return; 273 } 274 275 /* Enter configuration mode */ 276 schsio_config_enable(sc->sc_iot, sc->sc_ioh); 277 278 /* Check device ID */ 279 reg0 = (u_int8_t)(u_long) ia->ia_aux; 280 switch (reg0) { 281 case SCHSIO_ID_SCH3112: 282 printf(": SCH3112"); 283 break; 284 case SCHSIO_ID_SCH3114: 285 printf(": SCH3114"); 286 break; 287 case SCHSIO_ID_SCH3116: 288 printf(": SCH3116"); 289 break; 290 } 291 292 /* Read device revision */ 293 reg0 = schsio_config_read(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_REV); 294 printf(" rev 0x%02x", reg0); 295 296 /* Select runtime registers logical device */ 297 schsio_config_write(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_LDEVSEL, 298 SCHSIO_LDEV_RUNTIME); 299 300 reg0 = schsio_config_read(sc->sc_iot, sc->sc_ioh, 301 SCHSIO_IDX_BASE_HI); 302 reg1 = schsio_config_read(sc->sc_iot, sc->sc_ioh, 303 SCHSIO_IDX_BASE_LO); 304 iobase = (reg0 << 8) | reg1; 305 306 if (bus_space_map(sc->sc_iot, iobase, SCHSIO_LDEV_RUNTIME_SZ, 307 0, &sc->sc_ioh_rr)) { 308 printf(": can't map i/o space\n"); 309 return; 310 } 311 312 schsio_wdt_init(sc); 313 schsio_hwm_init(sc); 314 315 printf("\n"); 316 317 /* Escape from configuration mode */ 318 schsio_config_disable(sc->sc_iot, sc->sc_ioh); 319 } 320 321 void 322 schsio_hwm_init(struct schsio_softc *sc) 323 { 324 int i; 325 326 /* Set up sensors */ 327 for (i = SCHSIO_SENSOR_FAN1; i < SCHSIO_SENSOR_FAN3 + 1; i++) 328 sc->sc_sensor[i].type = SENSOR_FANRPM; 329 330 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT1].desc, "+2.5V", 331 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT1].desc)); 332 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT2].desc, "+1.5V (Vccp)", 333 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT2].desc)); 334 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT3].desc, "+3.3V (VCC)", 335 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT3].desc)); 336 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT4].desc, "+5V", 337 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT4].desc)); 338 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT5].desc, "+12V", 339 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT5].desc)); 340 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT6].desc, "+3.3V (VTR)", 341 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT6].desc)); 342 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_VOLT7].desc, "+3V (Vbat)", 343 sizeof(sc->sc_sensor[SCHSIO_SENSOR_VOLT7].desc)); 344 for (i = SCHSIO_SENSOR_VOLT1; i < SCHSIO_SENSOR_VOLT7 + 1; i++) 345 sc->sc_sensor[i].type = SENSOR_VOLTS_DC; 346 347 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_TEMP1].desc, "Internal", 348 sizeof(sc->sc_sensor[SCHSIO_SENSOR_TEMP1].desc)); 349 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_TEMP2].desc, "Remote", 350 sizeof(sc->sc_sensor[SCHSIO_SENSOR_TEMP2].desc)); 351 strlcpy(sc->sc_sensor[SCHSIO_SENSOR_TEMP3].desc, "Remote", 352 sizeof(sc->sc_sensor[SCHSIO_SENSOR_TEMP3].desc)); 353 for (i = SCHSIO_SENSOR_TEMP1; i < SCHSIO_SENSOR_TEMP3 + 1; i++) 354 sc->sc_sensor[i].type = SENSOR_TEMP; 355 356 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), 357 sizeof(sc->sc_sensordev.xname)); 358 359 for (i = 0; i < SCHSIO_SENSORS; i++) 360 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); 361 362 if (sensor_task_register(sc, schsio_hwm_update, 363 SCHSIO_HWM_INTERVAL) == NULL) { 364 printf(": unable to register update task"); 365 return; 366 } 367 sensordev_install(&sc->sc_sensordev); 368 } 369 370 void 371 schsio_hwm_update(void *arg) 372 { 373 struct schsio_softc *sc; 374 u_int16_t tach; 375 int8_t temp; 376 u_int8_t volt; 377 u_int8_t reg0, reg1; 378 379 sc = (struct schsio_softc *)arg; 380 381 reg0 = schsio_hwm_read(sc, SCHSIO_HWM_TACH1_L); 382 reg1 = schsio_hwm_read(sc, SCHSIO_HWM_TACH1_U); 383 tach = (reg1 << 8) | reg0; 384 sc->sc_sensor[SCHSIO_SENSOR_FAN1].value = SCHSIO_FAN_RPM(tach); 385 sc->sc_sensor[SCHSIO_SENSOR_FAN1].flags = 386 (tach == 0xffff) ? SENSOR_FINVALID : 0; 387 388 reg0 = schsio_hwm_read(sc, SCHSIO_HWM_TACH2_L); 389 reg1 = schsio_hwm_read(sc, SCHSIO_HWM_TACH2_U); 390 tach = (reg1 << 8) | reg0; 391 sc->sc_sensor[SCHSIO_SENSOR_FAN2].value = SCHSIO_FAN_RPM(tach); 392 sc->sc_sensor[SCHSIO_SENSOR_FAN2].flags = 393 (tach == 0xffff) ? SENSOR_FINVALID : 0; 394 395 reg0 = schsio_hwm_read(sc, SCHSIO_HWM_TACH3_L); 396 reg1 = schsio_hwm_read(sc, SCHSIO_HWM_TACH3_U); 397 tach = (reg1 << 8) | reg0; 398 sc->sc_sensor[SCHSIO_SENSOR_FAN3].value = SCHSIO_FAN_RPM(tach); 399 sc->sc_sensor[SCHSIO_SENSOR_FAN3].flags = 400 (tach == 0xffff) ? SENSOR_FINVALID : 0; 401 402 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT1); 403 sc->sc_sensor[SCHSIO_SENSOR_VOLT1].value = 404 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT1); 405 406 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT2); 407 sc->sc_sensor[SCHSIO_SENSOR_VOLT2].value = 408 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT2); 409 410 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT3); 411 sc->sc_sensor[SCHSIO_SENSOR_VOLT3].value = 412 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT3); 413 414 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT4); 415 sc->sc_sensor[SCHSIO_SENSOR_VOLT4].value = 416 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT4); 417 418 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT5); 419 sc->sc_sensor[SCHSIO_SENSOR_VOLT5].value = 420 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT5); 421 422 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT6); 423 sc->sc_sensor[SCHSIO_SENSOR_VOLT6].value = 424 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT6); 425 426 volt = schsio_hwm_read(sc, SCHSIO_HWM_VOLT7); 427 sc->sc_sensor[SCHSIO_SENSOR_VOLT7].value = 428 SCHSIO_VOLT_MUV(volt, SCHSIO_CONV_VOLT7); 429 430 temp = schsio_hwm_read(sc, SCHSIO_HWM_TEMP1); 431 sc->sc_sensor[SCHSIO_SENSOR_TEMP1].value = SCHSIO_TEMP_MUK(temp); 432 sc->sc_sensor[SCHSIO_SENSOR_TEMP1].flags = 433 ((uint8_t)temp == 0x80) ? SENSOR_FINVALID : 0; 434 435 temp = schsio_hwm_read(sc, SCHSIO_HWM_TEMP2); 436 sc->sc_sensor[SCHSIO_SENSOR_TEMP2].value = SCHSIO_TEMP_MUK(temp); 437 sc->sc_sensor[SCHSIO_SENSOR_TEMP2].flags = 438 ((uint8_t)temp == 0x80) ? SENSOR_FINVALID : 0; 439 440 temp = schsio_hwm_read(sc, SCHSIO_HWM_TEMP3); 441 sc->sc_sensor[SCHSIO_SENSOR_TEMP3].value = SCHSIO_TEMP_MUK(temp); 442 sc->sc_sensor[SCHSIO_SENSOR_TEMP3].flags = 443 ((uint8_t)temp == 0x80) ? SENSOR_FINVALID : 0; 444 445 } 446 447 u_int8_t 448 schsio_hwm_read(struct schsio_softc *sc, u_int8_t reg) 449 { 450 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_HWM_INDEX, reg); 451 return (bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_HWM_DATA)); 452 } 453 454 void 455 schsio_wdt_init(struct schsio_softc *sc) 456 { 457 u_int8_t reg; 458 459 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_GPIO); 460 if ((reg & SCHSIO_WDT_GPIO_MASK) != SCHSIO_WDT_GPIO_OUT) { 461 if (sc->sc_dev.dv_cfdata->cf_flags & SCHSIO_CFFLAGS_WDTEN) { 462 reg &= ~0x0f; 463 reg |= SCHSIO_WDT_GPIO_OUT; 464 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, 465 SCHSIO_WDT_GPIO, reg); 466 } 467 else { 468 printf(", watchdog disabled"); 469 return; 470 } 471 } 472 473 /* First of all, make sure the wdt is disabled */ 474 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_VAL, 0); 475 476 /* Clear triggered status */ 477 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_CTRL); 478 if (reg & SCHSIO_WDT_CTRL_TRIGGERED) { 479 printf(", warning: watchdog triggered"); 480 reg &= ~SCHSIO_WDT_CTRL_TRIGGERED; 481 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, 482 SCHSIO_WDT_CTRL, reg); 483 } 484 485 /* Disable wdt reset by mouse and kbd */ 486 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_CFG); 487 reg &= ~(SCHSIO_WDT_CFG_MSEN | SCHSIO_WDT_CFG_MSEN); 488 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_CFG, reg); 489 490 wdog_register(sc, schsio_wdt_cb); 491 } 492 493 int 494 schsio_wdt_cb(void *arg, int period) 495 { 496 struct schsio_softc *sc; 497 uint8_t val, minute, reg; 498 499 sc = (struct schsio_softc *)arg; 500 501 if (period > 255) { 502 val = period / 60; 503 minute = 1; 504 } else { 505 val = period; 506 minute = 0; 507 } 508 509 /* Set unit */ 510 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, 511 SCHSIO_WDT_TIMEOUT); 512 if (!minute) 513 reg |= SCHSIO_WDT_TO_SECONDS; 514 else 515 reg &= ~SCHSIO_WDT_TO_SECONDS; 516 517 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_TIMEOUT, 518 reg); 519 520 /* Set value */ 521 bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_VAL, val); 522 523 if (!minute) 524 return val; 525 else 526 return val * 60; 527 } 528 529