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