xref: /openbsd/sys/dev/isa/sch311x.c (revision cecf84d4)
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