xref: /netbsd-src/sys/arch/evbarm/tsarm/tspld.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: tspld.c,v 1.11 2005/11/12 05:34:28 hamajima Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004 Jesse Off
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *        This product includes software developed by the NetBSD
18  *        Foundation, Inc. and its contributors.
19  * 4. Neither the name of The NetBSD Foundation nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: tspld.c,v 1.11 2005/11/12 05:34:28 hamajima Exp $");
39 
40 #include <sys/param.h>
41 #include <sys/callout.h>
42 #include <sys/kernel.h>
43 #include <sys/sysctl.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
46 #include <sys/wdog.h>
47 
48 #include <machine/bus.h>
49 #include <machine/cpu.h>
50 #include <machine/autoconf.h>
51 #include "isa.h"
52 #if NISA > 0
53 #include <dev/isa/isavar.h>
54 #include <machine/isa_machdep.h>
55 #endif
56 
57 #include <evbarm/tsarm/tsarmreg.h>
58 #include <evbarm/tsarm/tspldvar.h>
59 #include <arm/ep93xx/ep93xxvar.h>
60 #include <arm/ep93xx/ep93xxreg.h>
61 #include <arm/ep93xx/epgpioreg.h>
62 #include <arm/arm32/machdep.h>
63 #include <arm/cpufunc.h>
64 #include <dev/sysmon/sysmonvar.h>
65 
66 int	tspldmatch (struct device *, struct cfdata *, void *);
67 void	tspldattach (struct device *, struct device *, void *);
68 static int	tspld_wdog_setmode (struct sysmon_wdog *);
69 static int	tspld_wdog_tickle (struct sysmon_wdog *);
70 int tspld_search (struct device *, struct cfdata *, const int *, void *);
71 int tspld_print (void *, const char *);
72 void boardtemp_poll (void *);
73 
74 struct tspld_softc {
75         struct device           sc_dev;
76         bus_space_tag_t         sc_iot;
77 	bus_space_handle_t	sc_wdogfeed_ioh;
78 	bus_space_handle_t	sc_wdogctrl_ioh;
79 	struct sysmon_wdog	sc_wdog;
80 	bus_space_handle_t	sc_ssph;
81 	bus_space_handle_t	sc_gpioh;
82 	unsigned const char *	sc_com2mode;
83 	unsigned const char *	sc_model;
84 	unsigned char		sc_pldrev[4];
85 	uint32_t		sc_rs485;
86 	uint32_t		sc_adc;
87 	uint32_t		sc_jp[6];
88 	uint32_t		sc_blaster_present;
89 	uint32_t		sc_blaster_boot;
90 	uint32_t		boardtemp;
91 	uint32_t		boardtemp_5s;
92 	uint32_t		boardtemp_30s;
93 	struct callout		boardtemp_callout;
94 };
95 
96 CFATTACH_DECL(tspld, sizeof(struct tspld_softc),
97     tspldmatch, tspldattach, NULL, NULL);
98 
99 void	tspld_callback __P((struct device *));
100 
101 #define GPIO_GET(x)	bus_space_read_4(sc->sc_iot, sc->sc_gpioh, \
102 	(EP93XX_GPIO_ ## x))
103 
104 #define GPIO_SET(x, y)	bus_space_write_4(sc->sc_iot, sc->sc_gpioh, \
105 	(EP93XX_GPIO_ ## x), (y))
106 
107 #define GPIO_SETBITS(x, y)	bus_space_write_4(sc->sc_iot, sc->sc_gpioh, \
108 	(EP93XX_GPIO_ ## x), GPIO_GET(x) | (y))
109 
110 #define GPIO_CLEARBITS(x, y)	bus_space_write_4(sc->sc_iot, sc->sc_gpioh, \
111 	(EP93XX_GPIO_ ## x), GPIO_GET(x) & (~(y)))
112 
113 #define SSP_GET(x)	bus_space_read_4(sc->sc_iot, sc->sc_ssph, \
114 	(EP93XX_SSP_ ## x))
115 
116 #define SSP_SET(x, y)	bus_space_write_4(sc->sc_iot, sc->sc_ssph, \
117 	(EP93XX_SSP_ ## x), (y))
118 
119 #define SSP_SETBITS(x, y)	bus_space_write_4(sc->sc_iot, sc->sc_ssph, \
120 	(EP93XX_SSP_ ## x), SSP_GET(x) | (y))
121 
122 #define SSP_CLEARBITS(x, y)	bus_space_write_4(sc->sc_iot, sc->sc_ssph, \
123 	(EP93XX_SSP_ ## x), SSP_GET(x) & (~(y)))
124 
125 int
126 tspldmatch(parent, match, aux)
127 	struct device *parent;
128 	struct cfdata *match;
129 	void *aux;
130 {
131 
132 	return 1;
133 }
134 
135 void
136 boardtemp_poll(arg)
137 	void *arg;
138 {
139 	struct tspld_softc *sc = arg;
140 	u_int16_t val;
141 
142 	/* Disable chip select */
143 	GPIO_SET(PFDDR, 0x0);
144 
145 	val = SSP_GET(SSPDR) & 0xffff;
146 	sc->boardtemp = ((int16_t)val >> 3) * 62500;
147 	sc->boardtemp_5s = sc->boardtemp_5s / 20 * 19 + sc->boardtemp / 20;
148 	sc->boardtemp_30s = sc->boardtemp_30s / 120 * 119 + sc->boardtemp / 120;
149 
150 	callout_schedule(&sc->boardtemp_callout, hz / 4);
151 
152 	/* Enable chip select */
153 	GPIO_SET(PFDDR, 0x4);
154 
155 	/* Send read command */
156 	SSP_SET(SSPDR, 0x8000);
157 }
158 
159 void
160 tspldattach(parent, self, aux)
161 	struct device *parent, *self;
162 	void *aux;
163 {
164 	int	i, rev, features, jp, model;
165 	struct tspld_softc *sc = (struct tspld_softc *)self;
166 	bus_space_handle_t 	ioh;
167         const struct sysctlnode *node;
168 
169 	if (sysctl_createv(NULL, 0, NULL, NULL,
170 				CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
171 				NULL, NULL, 0, NULL, 0,
172 				CTL_HW, CTL_EOL) != 0) {
173 		printf("%s: could not create sysctl\n",
174 			sc->sc_dev.dv_xname);
175 		return;
176 	}
177 	if (sysctl_createv(NULL, 0, NULL, &node,
178         			0, CTLTYPE_NODE, sc->sc_dev.dv_xname,
179         			NULL,
180         			NULL, 0, NULL, 0,
181 				CTL_HW, CTL_CREATE, CTL_EOL) != 0) {
182                 printf("%s: could not create sysctl\n",
183 			sc->sc_dev.dv_xname);
184 		return;
185 	}
186 
187 	sc->sc_iot = &ep93xx_bs_tag;
188 	bus_space_map(sc->sc_iot, TS7XXX_IO16_HWBASE + TS7XXX_MODEL, 2, 0,
189 		&ioh);
190 	model = bus_space_read_2(sc->sc_iot, ioh, 0) & 0x7;
191 	sc->sc_model = (model ? "TS-7250" : "TS-7200");
192 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
193         			0, CTLTYPE_STRING, "boardmodel",
194         			SYSCTL_DESCR("Technologic Systems board model"),
195         			NULL, 0, __UNCONST(sc->sc_model), 0,
196 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
197 				!= 0) {
198                 printf("%s: could not create sysctl\n",
199 			sc->sc_dev.dv_xname);
200 		return;
201 	}
202 	bus_space_unmap(sc->sc_iot, ioh, 2);
203 
204 	bus_space_map(sc->sc_iot, TS7XXX_IO16_HWBASE + TS7XXX_PLDREV, 2, 0,
205 		&ioh);
206 	rev = bus_space_read_2(sc->sc_iot, ioh, 0) & 0x7;
207 	rev = 'A' + rev - 1;
208 	sc->sc_pldrev[0] = rev;
209 	sc->sc_pldrev[1] = 0;
210 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
211         			0, CTLTYPE_STRING, "pldrev",
212         			SYSCTL_DESCR("CPLD revision"),
213         			NULL, 0, sc->sc_pldrev, 0,
214 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
215 				!= 0) {
216                 printf("%s: could not create sysctl\n",
217 			sc->sc_dev.dv_xname);
218 		return;
219 	}
220 	bus_space_unmap(sc->sc_iot, ioh, 2);
221 
222 	bus_space_map(sc->sc_iot, TS7XXX_IO16_HWBASE + TS7XXX_FEATURES, 2, 0,
223 		&ioh);
224 	features = bus_space_read_2(sc->sc_iot, ioh, 0) & 0x7;
225 	bus_space_unmap(sc->sc_iot, ioh, 2);
226 
227         bus_space_map(sc->sc_iot, TS7XXX_IO8_HWBASE + TS7XXX_STATUS1, 1, 0,
228 		&ioh);
229 	i = bus_space_read_1(sc->sc_iot, ioh, 0) & 0x1f;
230 	jp = (~((i & 0x18) >> 1) & 0xc) | (i & 0x3);
231 	bus_space_unmap(sc->sc_iot, ioh, 1);
232 
233 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
234         			0, CTLTYPE_INT, "blaster_present",
235         			SYSCTL_DESCR("Whether or not a TS-9420/TS-9202 blaster board is connected"),
236         			NULL, 0, &sc->sc_blaster_present, 0,
237 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
238 				!= 0) {
239                 printf("%s: could not create sysctl\n",
240 			sc->sc_dev.dv_xname);
241 		return;
242 	}
243 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
244         			0, CTLTYPE_INT, "blaster_boot",
245         			SYSCTL_DESCR("Whether or not a blast board was used to boot"),
246         			NULL, 0, &sc->sc_blaster_boot, 0,
247 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
248 				!= 0) {
249                 printf("%s: could not create sysctl\n",
250 			sc->sc_dev.dv_xname);
251 		return;
252 	}
253         bus_space_map(sc->sc_iot, TS7XXX_IO16_HWBASE + TS7XXX_STATUS2, 2, 0,
254 		&ioh);
255 	i = bus_space_read_2(sc->sc_iot, ioh, 0) & 0x6;
256 	sc->sc_blaster_boot = sc->sc_blaster_present = 0;
257 	if (i & 0x2)
258 		sc->sc_blaster_boot = 1;
259 	if (i & 0x4)
260 		sc->sc_blaster_present = 1;
261 	jp |= (i << 4);
262 	bus_space_unmap(sc->sc_iot, ioh, 1);
263 
264 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
265         			0, CTLTYPE_INT, "rs485_avail",
266         			SYSCTL_DESCR("RS485 level driver for COM2 available"),
267         			NULL, 0, &sc->sc_rs485, 0,
268 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
269 				!= 0) {
270                 printf("%s: could not create sysctl\n",
271 			sc->sc_dev.dv_xname);
272 		return;
273 	}
274 	sc->sc_com2mode = "rs232";
275 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
276         			0, CTLTYPE_STRING, "com2_mode",
277         			SYSCTL_DESCR("line driver type for COM2"),
278         			NULL, 0, __UNCONST(sc->sc_com2mode), 0,
279 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
280 				!= 0) {
281                 printf("%s: could not create sysctl\n",
282 			sc->sc_dev.dv_xname);
283 		return;
284 	}
285 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
286         			0, CTLTYPE_INT, "max197adc_avail",
287         			SYSCTL_DESCR("Maxim 197 Analog to Digital Converter available"),
288         			NULL, 0, &sc->sc_adc, 0,
289 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
290 				!= 0) {
291                 printf("%s: could not create sysctl\n",
292 			sc->sc_dev.dv_xname);
293 		return;
294 	}
295 	printf(": Technologic Systems %s rev %c, features 0x%x",
296 		sc->sc_model, rev, features);
297 	sc->sc_adc = sc->sc_rs485 = 0;
298 	if (features == 0x1) {
299 		printf("<MAX197-ADC>");
300 		sc->sc_adc = 1;
301 	} else if (features == 0x2) {
302 		printf("<RS485>");
303 		sc->sc_rs485 = 1;
304 	} else if (features == 0x3) {
305 		printf("<MAX197-ADC,RS485>");
306 		sc->sc_adc = sc->sc_rs485 = 1;
307 	}
308 	printf("\n");
309 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
310         			0, CTLTYPE_INT, "jp1",
311         			SYSCTL_DESCR("onboard jumper setting"),
312         			NULL, 0, &sc->sc_jp[0], 0,
313 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
314 				!= 0) {
315                 printf("%s: could not create sysctl\n",
316 			sc->sc_dev.dv_xname);
317 		return;
318 	}
319 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
320         			0, CTLTYPE_INT, "jp2",
321         			SYSCTL_DESCR("onboard jumper setting"),
322         			NULL, 0, &sc->sc_jp[1], 0,
323 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
324 				!= 0) {
325                 printf("%s: could not create sysctl\n",
326 			sc->sc_dev.dv_xname);
327 		return;
328 	}
329 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
330         			0, CTLTYPE_INT, "jp3",
331         			SYSCTL_DESCR("onboard jumper setting"),
332         			NULL, 0, &sc->sc_jp[2], 0,
333 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
334 				!= 0) {
335                 printf("%s: could not create sysctl\n",
336 			sc->sc_dev.dv_xname);
337 		return;
338 	}
339 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
340         			0, CTLTYPE_INT, "jp4",
341         			SYSCTL_DESCR("onboard jumper setting"),
342         			NULL, 0, &sc->sc_jp[3], 0,
343 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
344 				!= 0) {
345                 printf("%s: could not create sysctl\n",
346 			sc->sc_dev.dv_xname);
347 		return;
348 	}
349 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
350         			0, CTLTYPE_INT, "jp5",
351         			SYSCTL_DESCR("onboard jumper setting"),
352         			NULL, 0, &sc->sc_jp[4], 0,
353 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
354 				!= 0) {
355                 printf("%s: could not create sysctl\n",
356 			sc->sc_dev.dv_xname);
357 		return;
358 	}
359 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
360         			0, CTLTYPE_INT, "jp6",
361         			SYSCTL_DESCR("onboard jumper setting"),
362         			NULL, 0, &sc->sc_jp[5], 0,
363 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
364 				!= 0) {
365                 printf("%s: could not create sysctl\n",
366 			sc->sc_dev.dv_xname);
367 		return;
368 	}
369 	printf("%s: jumpers 0x%x", sc->sc_dev.dv_xname, jp);
370 	if (jp) {
371 		printf("<");
372 		for(i = 0; i < 5; i++) {
373 			if (jp & (1 << i)) {
374 				sc->sc_jp[i + 1] = 1;
375 				printf("JP%d", i + 2);
376 				jp &= ~(1 << i);
377 				if (jp) printf(",");
378 			} else {
379 				sc->sc_jp[i + 2] = 0;
380 			}
381 		}
382 		printf(">");
383 	}
384 	printf("\n");
385 
386 
387         bus_space_map(sc->sc_iot, EP93XX_APB_HWBASE + EP93XX_APB_SSP,
388 		EP93XX_APB_SSP_SIZE, 0, &sc->sc_ssph);
389         bus_space_map(sc->sc_iot, EP93XX_APB_HWBASE + EP93XX_APB_GPIO,
390 		EP93XX_APB_GPIO_SIZE, 0, &sc->sc_gpioh);
391 	SSP_SETBITS(SSPCR1, 0x10);
392 	SSP_SET(SSPCR0, 0xf);
393 	SSP_SET(SSPCPSR, 0xfe);
394 	SSP_CLEARBITS(SSPCR1, 0x10);
395 	SSP_SETBITS(SSPCR1, 0x10);
396 	GPIO_SET(PFDR, 0x0);
397 	callout_init(&sc->boardtemp_callout);
398 	callout_setfunc(&sc->boardtemp_callout, boardtemp_poll, sc);
399 	boardtemp_poll(sc);
400 	delay(1000);
401 	boardtemp_poll(sc);
402 	sc->boardtemp_5s = sc->boardtemp_30s = sc->boardtemp;
403 #define DEGF(c)	((c) * 9 / 5 + 32000000)
404 	printf("%s: board temperature %d.%02d degC (%d.%02d degF)\n",
405 		sc->sc_dev.dv_xname,
406 		sc->boardtemp / 1000000, sc->boardtemp / 10000 % 100,
407 		DEGF(sc->boardtemp) / 1000000, DEGF(sc->boardtemp) / 10000 % 100);
408 #undef DEGF
409 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
410         			0, CTLTYPE_INT, "board_temp",
411         			SYSCTL_DESCR("board temperature in micro degrees Celsius"),
412         			NULL, 0, &sc->boardtemp, 0,
413 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
414 				!= 0) {
415                 printf("%s: could not create sysctl\n",
416 			sc->sc_dev.dv_xname);
417 		return;
418 	}
419 
420 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
421         			0, CTLTYPE_INT, "board_temp_5s",
422         			SYSCTL_DESCR("5 second average board temperature in micro degrees Celsius"),
423         			NULL, 0, &sc->boardtemp_5s, 0,
424 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
425 				!= 0) {
426                 printf("%s: could not create sysctl\n",
427 			sc->sc_dev.dv_xname);
428 		return;
429 	}
430 
431 	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
432         			0, CTLTYPE_INT, "board_temp_30s",
433         			SYSCTL_DESCR("30 second average board temperature in micro degrees Celsius"),
434         			NULL, 0, &sc->boardtemp_30s, 0,
435 				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
436 				!= 0) {
437                 printf("%s: could not create sysctl\n",
438 			sc->sc_dev.dv_xname);
439 		return;
440 	}
441 
442         bus_space_map(sc->sc_iot, TS7XXX_IO16_HWBASE + TS7XXX_WDOGCTRL, 2, 0,
443 		&sc->sc_wdogctrl_ioh);
444         bus_space_map(sc->sc_iot, TS7XXX_IO16_HWBASE + TS7XXX_WDOGFEED, 2, 0,
445 		&sc->sc_wdogfeed_ioh);
446 
447 	sc->sc_wdog.smw_name = sc->sc_dev.dv_xname;
448 	sc->sc_wdog.smw_cookie = sc;
449 	sc->sc_wdog.smw_setmode = tspld_wdog_setmode;
450 	sc->sc_wdog.smw_tickle = tspld_wdog_tickle;
451 	sc->sc_wdog.smw_period = 8;
452 	sysmon_wdog_register(&sc->sc_wdog);
453 	tspld_wdog_setmode(&sc->sc_wdog);
454 
455 	/* Set the on board peripherals bus callback */
456 	config_defer(self, tspld_callback);
457 }
458 
459 int
460 tspld_search(parent, cf, ldesc, aux)
461 	struct device *parent;
462 	struct cfdata *cf;
463 	const int *ldesc;
464 	void *aux;
465 {
466 	struct tspld_softc *sc = (struct tspld_softc *)parent;
467 	struct tspld_attach_args sa;
468 
469 	sa.ta_iot = sc->sc_iot;
470 
471 	if (config_match(parent, cf, &sa) > 0)
472 		config_attach(parent, cf, &sa, tspld_print);
473 
474 	return (0);
475 }
476 
477 int
478 tspld_print(aux, name)
479 	void *aux;
480 	const char *name;
481 {
482 
483 	return (UNCONF);
484 }
485 
486 void
487 tspld_callback(self)
488 	struct device *self;
489 {
490 #if NISA > 0
491 	extern void isa_bs_mallocok(void);
492 	struct isabus_attach_args iba;
493 
494 	/*
495 	 * Attach the ISA bus behind this bridge.
496 	 */
497 	memset(&iba, 0, sizeof(iba));
498 	iba.iba_iot = &isa_io_bs_tag;
499 	iba.iba_memt = &isa_mem_bs_tag;
500 	isa_bs_mallocok();
501 	config_found_ia(self, "isabus", &iba, isabusprint);
502 #endif
503 	/*
504 	 *  Attach each devices
505 	 */
506 	config_search_ia(tspld_search, self, "tspldbus", NULL);
507 
508 }
509 
510 static int
511 tspld_wdog_tickle(smw)
512 	struct sysmon_wdog *smw;
513 {
514 	struct tspld_softc *sc = (struct tspld_softc *)smw->smw_cookie;
515 
516 	bus_space_write_2(sc->sc_iot, sc->sc_wdogfeed_ioh, 0, 0x5);
517 	return 0;
518 }
519 
520 static int
521 tspld_wdog_setmode(smw)
522 	struct sysmon_wdog *smw;
523 {
524 	int i, ret = 0;
525 	struct tspld_softc *sc = (struct tspld_softc *)smw->smw_cookie;
526 
527 	i = disable_interrupts(I32_bit|F32_bit);
528 	if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
529 		bus_space_write_2(sc->sc_iot, sc->sc_wdogfeed_ioh, 0, 0x5);
530 		bus_space_write_2(sc->sc_iot, sc->sc_wdogctrl_ioh, 0, 0);
531 	} else {
532 		bus_space_write_2(sc->sc_iot, sc->sc_wdogfeed_ioh, 0, 0x5);
533 		switch (smw->smw_period) {
534 		case 1:
535 			bus_space_write_2(sc->sc_iot, sc->sc_wdogctrl_ioh, 0,
536 				0x3);
537 			break;
538 		case 2:
539 			bus_space_write_2(sc->sc_iot, sc->sc_wdogctrl_ioh, 0,
540 				0x5);
541 			break;
542 		case 4:
543 			bus_space_write_2(sc->sc_iot, sc->sc_wdogctrl_ioh, 0,
544 				0x6);
545 			break;
546 		case 8:
547 			bus_space_write_2(sc->sc_iot, sc->sc_wdogctrl_ioh, 0,
548 				0x7);
549 			break;
550 		default:
551 			ret = EINVAL;
552 		}
553 	}
554 	restore_interrupts(i);
555 	return ret;
556 }
557