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