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