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