xref: /freebsd/sys/dev/ftgpio/ftgpio.c (revision 0c428864495af9dc7d2af4d0a5ae21732af9c739)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2016-2023 Stormshield
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 
33 #include <sys/bus.h>
34 #include <sys/eventhandler.h>
35 #include <sys/gpio.h>
36 #include <sys/kernel.h>
37 #include <sys/lock.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
40 
41 #include <machine/bus.h>
42 
43 #include <dev/gpio/gpiobusvar.h>
44 #include <dev/superio/superio.h>
45 
46 #include "gpio_if.h"
47 
48 #define GPIO_LOCK_INIT(_sc)	mtx_init(&(_sc)->mtx,	\
49 		device_get_nameunit(dev), NULL, MTX_DEF)
50 #define GPIO_LOCK_DESTROY(_sc)		mtx_destroy(&(_sc)->mtx)
51 #define GPIO_LOCK(_sc)		mtx_lock(&(_sc)->mtx)
52 #define GPIO_UNLOCK(_sc)	mtx_unlock(&(_sc)->mtx)
53 #define GPIO_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_OWNED)
54 #define GPIO_ASSERT_UNLOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_NOTOWNED)
55 
56 /* Global register set */
57 #define GPIO4_ENABLE 0x28
58 #define GPIO3_ENABLE 0x29
59 #define FULL_UR5_UR6 0x2A
60 #define GPIO1_ENABLE 0x2B
61 #define GPIO2_ENABLE 0x2C
62 
63 /* Logical Device Numbers. */
64 #define FTGPIO_LDN_GPIO			0x06
65 
66 #define FTGPIO_MAX_GROUP 6
67 #define FTGPIO_MAX_PIN   52
68 
69 #define FTGPIO_IS_VALID_PIN(_p)  ((_p) >= 0 && (_p) <= FTGPIO_MAX_PIN)
70 #define FTGPIO_PIN_GETINDEX(_p) ((_p) & 7)
71 #define FTGPIO_PIN_GETGROUP(_p) ((_p) >> 3)
72 
73 #define FTGPIO_GPIO_CAPS (GPIO_PIN_INPUT  | GPIO_PIN_OUTPUT    | GPIO_PIN_INVIN | \
74                           GPIO_PIN_INVOUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)
75 
76 #define GET_BIT(_v, _b) (((_v) >> (_b)) & 1)
77 
78 #define FTGPIO_VERBOSE_PRINTF(dev, ...)         \
79 	do {                                        \
80 		if (__predict_false(bootverbose))       \
81 			device_printf(dev, __VA_ARGS__);    \
82 	} while (0)
83 
84 /*
85  * Note that the values are important.
86  * They match actual register offsets.
87  * See p71 and p72 of F81865's datasheet.
88  */
89 #define REG_OUTPUT_ENABLE         0 /* Not for GPIO0 */
90 #define REG_OUTPUT_DATA           1
91 #define REG_PIN_STATUS            2
92 #define REG_DRIVE_ENABLE          3
93 #define REG_MODE_SELECT_1         4 /* Only for GPIO0 */
94 #define REG_MODE_SELECT_2         5 /* Only for GPIO0 */
95 #define REG_PULSE_WIDTH_SELECT_1  6 /* Only for GPIO0 */
96 #define REG_PULSE_WIDTH_SELECT_2  7 /* Only for GPIO0 */
97 #define REG_INTERRUPT_ENABLE      8 /* Only for GPIO0 */
98 #define REG_INTERRUPT_STATUS      9 /* Only for GPIO0 */
99 
100 struct ftgpio_device {
101 	uint16_t    devid;
102 	const char *descr;
103 } ftgpio_devices[] = {
104 	{
105 		.devid = 0x0704,
106 		.descr = "GPIO Controller on Fintek Super I/O",
107 	},
108 };
109 
110 struct ftgpio_softc {
111 	device_t			dev;
112 	device_t			busdev;
113 	struct mtx			mtx;
114 	struct gpio_pin		pins[FTGPIO_MAX_PIN + 1];
115 };
116 
117 static uint8_t
118 ftgpio_group_get_ioreg(struct ftgpio_softc *sc, uint8_t reg, unsigned group)
119 {
120 	uint8_t ioreg;
121 
122 	KASSERT((group == 0 && REG_OUTPUT_DATA <= reg && reg <= REG_INTERRUPT_STATUS) || \
123 	        (group >= 1 && reg <= REG_DRIVE_ENABLE),
124 		("%s: invalid register %u for group %u", __func__, reg, group));
125 	ioreg = (((0xf - group) << 4) + reg);
126 	return (ioreg);
127 }
128 
129 static uint8_t
130 ftgpio_group_get_output(struct ftgpio_softc *sc, unsigned group)
131 {
132 	uint8_t ioreg, val;
133 
134 	ioreg = ftgpio_group_get_ioreg(sc, REG_OUTPUT_DATA, group);
135 	val   = superio_read(sc->dev, ioreg);
136 	FTGPIO_VERBOSE_PRINTF(sc->dev, "group GPIO%u output is 0x%x (ioreg=0x%x)\n",
137 		group, val, ioreg);
138 	return (val);
139 }
140 
141 static void
142 ftgpio_group_set_output(struct ftgpio_softc *sc, unsigned group, uint8_t group_value)
143 {
144 	uint8_t ioreg;
145 
146 	ioreg = ftgpio_group_get_ioreg(sc, REG_OUTPUT_DATA, group);
147 	superio_write(sc->dev, ioreg, group_value);
148 	FTGPIO_VERBOSE_PRINTF(sc->dev, "set group GPIO%u output to 0x%x (ioreg=0x%x)\n",
149 		group, group_value, ioreg);
150 }
151 
152 static uint8_t
153 ftgpio_group_get_status(struct ftgpio_softc *sc, unsigned group)
154 {
155 	uint8_t ioreg;
156 
157 	ioreg = ftgpio_group_get_ioreg(sc, REG_PIN_STATUS, group);
158 	return (superio_read(sc->dev, ioreg));
159 }
160 
161 static void
162 ftgpio_pin_write(struct ftgpio_softc *sc, uint32_t pin_num, bool pin_value)
163 {
164 	uint32_t pin_flags;
165 	uint8_t  val;
166 	unsigned group, index;
167 
168 	GPIO_ASSERT_LOCKED(sc);
169 	index     = FTGPIO_PIN_GETINDEX(pin_num);
170 	group     = FTGPIO_PIN_GETGROUP(pin_num);
171 	pin_flags = sc->pins[pin_num].gp_flags;
172 	if ((pin_flags & (GPIO_PIN_OUTPUT)) == 0) {
173 		FTGPIO_VERBOSE_PRINTF(sc->dev, "pin %u<GPIO%u%u> is not configured for output\n",
174 			pin_num, group, index);
175 		return;
176 	}
177 
178 	FTGPIO_VERBOSE_PRINTF(sc->dev, "set pin %u<GPIO%u%u> to %s\n",
179 		pin_num, group, index, (pin_value ? "on" : "off"));
180 
181 	val = ftgpio_group_get_output(sc, group);
182 	if (!pin_value != !(pin_flags & GPIO_PIN_INVOUT))
183 		val |=  (1 << index);
184 	else
185 		val &= ~(1 << index);
186 	ftgpio_group_set_output(sc, group, val);
187 }
188 
189 static bool
190 ftgpio_pin_read(struct ftgpio_softc *sc, uint32_t pin_num)
191 {
192 	uint32_t pin_flags;
193 	unsigned group, index;
194 	uint8_t  val;
195 	bool     pin_value;
196 
197 	GPIO_ASSERT_LOCKED(sc);
198 	group     = FTGPIO_PIN_GETGROUP(pin_num);
199 	index     = FTGPIO_PIN_GETINDEX(pin_num);
200 	pin_flags = sc->pins[pin_num].gp_flags;
201 	if ((pin_flags & (GPIO_PIN_OUTPUT | GPIO_PIN_INPUT)) == 0) {
202 		FTGPIO_VERBOSE_PRINTF(sc->dev, "pin %u<GPIO%u%u> is not configured for input or output\n",
203 			pin_num, group, index);
204 		return (false);
205 	}
206 
207 	if (pin_flags & GPIO_PIN_OUTPUT)
208 		val = ftgpio_group_get_output(sc, group);
209 	else
210 		val = ftgpio_group_get_status(sc, group);
211 	pin_value = GET_BIT(val, index);
212 
213 	if (((pin_flags & (GPIO_PIN_OUTPUT|GPIO_PIN_INVOUT)) == (GPIO_PIN_OUTPUT|GPIO_PIN_INVOUT)) ||
214 	    ((pin_flags & (GPIO_PIN_INPUT |GPIO_PIN_INVIN )) == (GPIO_PIN_INPUT |GPIO_PIN_INVIN)))
215 		pin_value = !pin_value;
216 	FTGPIO_VERBOSE_PRINTF(sc->dev, "pin %u<GPIO%u%u> is %s\n",
217 		pin_num, group, index, (pin_value ? "on" : "off"));
218 
219 	return (pin_value);
220 }
221 
222 static void
223 ftgpio_pin_set_drive(struct ftgpio_softc *sc, uint32_t pin_num, bool pin_drive)
224 {
225 	unsigned group, index;
226 	uint8_t  group_drive, ioreg;
227 
228 	index       = FTGPIO_PIN_GETINDEX(pin_num);
229 	group       = FTGPIO_PIN_GETGROUP(pin_num);
230 	ioreg		= ftgpio_group_get_ioreg(sc, REG_DRIVE_ENABLE, group);
231 	group_drive = superio_read(sc->dev, ioreg);
232 	FTGPIO_VERBOSE_PRINTF(sc->dev, "group GPIO%u drive is 0x%x (ioreg=0x%x)\n",
233 		group, group_drive, ioreg);
234 
235 	if (pin_drive)
236 		group_drive |= (1 << index);   /* push pull */
237 	else
238 		group_drive &= ~(1 << index);  /* open drain */
239 	superio_write(sc->dev, ioreg, group_drive);
240 }
241 
242 static bool
243 ftgpio_pin_is_pushpull(struct ftgpio_softc *sc, uint32_t pin_num)
244 {
245 	unsigned group, index;
246 	uint8_t  group_drive, ioreg;
247 	bool is_pushpull;
248 
249 	index       = FTGPIO_PIN_GETINDEX(pin_num);
250 	group       = FTGPIO_PIN_GETGROUP(pin_num);
251 
252 	ioreg		= ftgpio_group_get_ioreg(sc, REG_DRIVE_ENABLE, group);
253 	group_drive = superio_read(sc->dev, ioreg);
254 	FTGPIO_VERBOSE_PRINTF(sc->dev, "group GPIO%u drive is 0x%x (ioreg=0x%x)\n",
255 		group, group_drive, ioreg);
256 
257 	is_pushpull = group_drive & (1 << index);
258 	FTGPIO_VERBOSE_PRINTF(sc->dev, "pin %u<GPIO%u%u> drive is %s\n",
259 		pin_num, group, index, (is_pushpull ? "pushpull" : "opendrain"));
260 
261 	return (is_pushpull);
262 }
263 
264 static void
265 ftgpio_pin_set_io(struct ftgpio_softc *sc, uint32_t pin_num, bool pin_io)
266 {
267 	unsigned group, index;
268 	uint8_t  group_io, ioreg;
269 
270 	index = FTGPIO_PIN_GETINDEX(pin_num);
271 	group = FTGPIO_PIN_GETGROUP(pin_num);
272 	FTGPIO_VERBOSE_PRINTF(sc->dev, "set pin %u<GPIO%u%u> io to %s\n",
273 		pin_num, group, index, (pin_io ? "output" : "input"));
274 
275 	ioreg    = ftgpio_group_get_ioreg(sc, REG_OUTPUT_ENABLE, group);
276 	group_io = superio_read(sc->dev, ioreg);
277 	FTGPIO_VERBOSE_PRINTF(sc->dev, "group GPIO%u io is 0x%x (ioreg=0x%x)\n",
278 		group, group_io, ioreg);
279 	if (pin_io)
280 		group_io |=  (1 << index); /* output */
281 	else
282 		group_io &= ~(1 << index); /* input */
283 	superio_write(sc->dev, ioreg, group_io);
284 	FTGPIO_VERBOSE_PRINTF(sc->dev, "set group GPIO%u io to 0x%x (ioreg=0x%x)\n",
285 		group, group_io, ioreg);
286 }
287 
288 static bool
289 ftgpio_pin_is_output(struct ftgpio_softc *sc, uint32_t pin_num)
290 {
291 	unsigned group, index;
292 	uint8_t  group_io, ioreg;
293 	bool is_output;
294 
295 	index = FTGPIO_PIN_GETINDEX(pin_num);
296 	group = FTGPIO_PIN_GETGROUP(pin_num);
297 
298 	ioreg    = ftgpio_group_get_ioreg(sc, REG_OUTPUT_ENABLE, group);
299 	group_io = superio_read(sc->dev, ioreg);
300 	FTGPIO_VERBOSE_PRINTF(sc->dev, "group GPIO%u io is 0x%x (ioreg=0x%x)\n",
301 		group, group_io, ioreg);
302 
303 	is_output = group_io & (1 << index);
304 	FTGPIO_VERBOSE_PRINTF(sc->dev, "pin %u<GPIO%u%u> io is %s\n",
305 		pin_num, group, index, (is_output ? "output" : "input"));
306 	return (is_output);
307 }
308 
309 static int
310 ftgpio_pin_setflags(struct ftgpio_softc *sc, uint32_t pin_num, uint32_t pin_flags)
311 {
312 	/* check flags consistency */
313 	if ((pin_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
314 		(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
315 		return (EINVAL);
316 
317 	if ((pin_flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) ==
318 		(GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL))
319 		return (EINVAL);
320 
321 	if (pin_flags & GPIO_PIN_OPENDRAIN)
322 		ftgpio_pin_set_drive(sc, pin_num, 0 /* open drain */);
323 	else if (pin_flags & GPIO_PIN_PUSHPULL)
324 		ftgpio_pin_set_drive(sc, pin_num, 1 /* push pull */);
325 
326 	if (pin_flags & GPIO_PIN_INPUT)
327 		ftgpio_pin_set_io(sc, pin_num, 0 /* input */);
328 	else if (pin_flags & GPIO_PIN_OUTPUT)
329 		ftgpio_pin_set_io(sc, pin_num, 1 /* output */);
330 
331 	sc->pins[pin_num].gp_flags = pin_flags;
332 
333 	return (0);
334 }
335 
336 static int
337 ftgpio_probe(device_t dev)
338 {
339 	uint16_t devid;
340 	int      i;
341 
342 	if (superio_vendor(dev) != SUPERIO_VENDOR_FINTEK)
343 		return (ENXIO);
344 	if (superio_get_type(dev) != SUPERIO_DEV_GPIO)
345 		return (ENXIO);
346 
347 	/*
348 	 * There are several GPIO devices, we attach only to one of them
349 	 * and use the rest without attaching.
350 	 */
351 	if (superio_get_ldn(dev) != FTGPIO_LDN_GPIO)
352 		return (ENXIO);
353 
354 	devid = superio_devid(dev);
355 	for (i = 0; i < nitems(ftgpio_devices); i++) {
356 		if (devid == ftgpio_devices[i].devid) {
357 			device_set_desc(dev, ftgpio_devices[i].descr);
358 			return (BUS_PROBE_DEFAULT);
359 		}
360 	}
361 	return (ENXIO);
362 }
363 
364 static int
365 ftgpio_attach(device_t dev)
366 {
367 	struct ftgpio_softc *sc;
368 	int                  i;
369 
370 	sc		= device_get_softc(dev);
371 	sc->dev = dev;
372 
373 	GPIO_LOCK_INIT(sc);
374 	GPIO_LOCK(sc);
375 
376 	for (i = 0; i <= FTGPIO_MAX_PIN; i++) {
377 		struct gpio_pin *pin;
378 
379 		pin           = &sc->pins[i];
380 		pin->gp_pin   = i;
381 		pin->gp_caps  = FTGPIO_GPIO_CAPS;
382 		pin->gp_flags = 0;
383 
384 		if (ftgpio_pin_is_output(sc, i))
385 			pin->gp_flags |= GPIO_PIN_OUTPUT;
386 		else
387 			pin->gp_flags |= GPIO_PIN_INPUT;
388 
389 		if (ftgpio_pin_is_pushpull(sc, i))
390 			pin->gp_flags |= GPIO_PIN_PUSHPULL;
391 		else
392 			pin->gp_flags |= GPIO_PIN_OPENDRAIN;
393 
394 		snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%u%u",
395 			FTGPIO_PIN_GETGROUP(i), FTGPIO_PIN_GETINDEX(i));
396 	}
397 
398 	/* Enable all groups */
399 	superio_write(sc->dev, GPIO1_ENABLE, 0xFF);
400 	superio_write(sc->dev, GPIO2_ENABLE, 0xFF);
401 	superio_write(sc->dev, GPIO3_ENABLE, 0xFF);
402 	superio_write(sc->dev, GPIO4_ENABLE, 0xFF);
403 	superio_write(sc->dev, FULL_UR5_UR6, 0x0A);
404 	FTGPIO_VERBOSE_PRINTF(sc->dev, "groups GPIO1..GPIO6 enabled\n");
405 
406 	GPIO_UNLOCK(sc);
407 	sc->busdev = gpiobus_attach_bus(dev);
408 	if (sc->busdev == NULL) {
409 		GPIO_LOCK_DESTROY(sc);
410 		return (ENXIO);
411 	}
412 
413 	return (0);
414 }
415 
416 static int
417 ftgpio_detach(device_t dev)
418 {
419 	struct ftgpio_softc *sc;
420 
421 	sc = device_get_softc(dev);
422 	gpiobus_detach_bus(dev);
423 	GPIO_ASSERT_UNLOCKED(sc);
424 	GPIO_LOCK_DESTROY(sc);
425 
426 	return (0);
427 }
428 
429 static device_t
430 ftgpio_gpio_get_bus(device_t dev)
431 {
432 	struct ftgpio_softc *sc;
433 
434 	sc = device_get_softc(dev);
435 
436 	return (sc->busdev);
437 }
438 
439 static int
440 ftgpio_gpio_pin_max(device_t dev, int *npins)
441 {
442 	*npins = FTGPIO_MAX_PIN;
443 	return (0);
444 }
445 
446 static int
447 ftgpio_gpio_pin_set(device_t dev, uint32_t pin_num, uint32_t pin_value)
448 {
449 	struct ftgpio_softc *sc;
450 
451 	if (!FTGPIO_IS_VALID_PIN(pin_num))
452 		return (EINVAL);
453 
454 	sc = device_get_softc(dev);
455 	GPIO_LOCK(sc);
456 	if ((sc->pins[pin_num].gp_flags & GPIO_PIN_OUTPUT) == 0) {
457 		GPIO_UNLOCK(sc);
458 		return (EINVAL);
459 	}
460 	ftgpio_pin_write(sc, pin_num, pin_value);
461 	GPIO_UNLOCK(sc);
462 
463 	return (0);
464 }
465 
466 static int
467 ftgpio_gpio_pin_get(device_t dev, uint32_t pin_num, uint32_t *pin_value)
468 {
469 	struct ftgpio_softc *sc;
470 
471 	if (!FTGPIO_IS_VALID_PIN(pin_num))
472 		return (EINVAL);
473 
474 	if (pin_value == NULL)
475 		return (EINVAL);
476 
477 	sc = device_get_softc(dev);
478 	GPIO_LOCK(sc);
479 	*pin_value = ftgpio_pin_read(sc, pin_num);
480 	GPIO_UNLOCK(sc);
481 
482 	return (0);
483 }
484 
485 static int
486 ftgpio_gpio_pin_toggle(device_t dev, uint32_t pin_num)
487 {
488 	struct ftgpio_softc *sc;
489 	bool              pin_value;
490 
491 	if (!FTGPIO_IS_VALID_PIN(pin_num))
492 		return (EINVAL);
493 
494 	sc = device_get_softc(dev);
495 	GPIO_LOCK(sc);
496 	pin_value = ftgpio_pin_read(sc, pin_num);
497 	ftgpio_pin_write(sc, pin_num, !pin_value);
498 	GPIO_UNLOCK(sc);
499 
500 	return (0);
501 }
502 
503 static int
504 ftgpio_gpio_pin_getname(device_t dev, uint32_t pin_num, char *pin_name)
505 {
506 	struct ftgpio_softc *sc;
507 
508 	if (pin_name == NULL)
509 		return (EINVAL);
510 
511 	if (!FTGPIO_IS_VALID_PIN(pin_num))
512 		return (EINVAL);
513 
514 	sc = device_get_softc(dev);
515 	strlcpy(pin_name, sc->pins[pin_num].gp_name, GPIOMAXNAME);
516 
517 	return (0);
518 }
519 
520 static int
521 ftgpio_gpio_pin_getcaps(device_t dev, uint32_t pin_num, uint32_t *pin_caps)
522 {
523 	struct ftgpio_softc *sc;
524 
525 	if (pin_caps == NULL)
526 		return (EINVAL);
527 
528 	if (!FTGPIO_IS_VALID_PIN(pin_num))
529 		return (EINVAL);
530 
531 	sc        = device_get_softc(dev);
532 	*pin_caps = sc->pins[pin_num].gp_caps;
533 
534 	return (0);
535 }
536 
537 static int
538 ftgpio_gpio_pin_getflags(device_t dev, uint32_t pin_num, uint32_t *pin_flags)
539 {
540 	struct ftgpio_softc *sc;
541 
542 	if (pin_flags == NULL)
543 		return (EINVAL);
544 
545 	if (!FTGPIO_IS_VALID_PIN(pin_num))
546 		return (EINVAL);
547 
548 	sc         = device_get_softc(dev);
549 	*pin_flags = sc->pins[pin_num].gp_flags;
550 
551 	return (0);
552 }
553 
554 static int
555 ftgpio_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t pin_flags)
556 {
557 	struct ftgpio_softc *sc;
558 	int               ret;
559 
560 	if (!FTGPIO_IS_VALID_PIN(pin_num)) {
561 		FTGPIO_VERBOSE_PRINTF(dev, "invalid pin number: %u\n", pin_num);
562 		return (EINVAL);
563 	}
564 
565 	sc = device_get_softc(dev);
566 
567 	/* Check for unwanted flags. */
568 	if ((pin_flags & sc->pins[pin_num].gp_caps) != pin_flags) {
569 		FTGPIO_VERBOSE_PRINTF(dev, "invalid pin flags 0x%x, vs caps 0x%x\n",
570 			pin_flags, sc->pins[pin_num].gp_caps);
571 		return (EINVAL);
572 	}
573 
574 	GPIO_LOCK(sc);
575 	ret = ftgpio_pin_setflags(sc, pin_num, pin_flags);
576 	GPIO_UNLOCK(sc);
577 
578 	return (ret);
579 }
580 
581 static device_method_t ftgpio_methods[] = {
582 	/* Device interface */
583 	DEVMETHOD(device_probe,     ftgpio_probe),
584 	DEVMETHOD(device_attach,    ftgpio_attach),
585 	DEVMETHOD(device_detach,    ftgpio_detach),
586 
587 	/* GPIO */
588 	DEVMETHOD(gpio_get_bus,         ftgpio_gpio_get_bus),
589 	DEVMETHOD(gpio_pin_max,         ftgpio_gpio_pin_max),
590 	DEVMETHOD(gpio_pin_set,         ftgpio_gpio_pin_set),
591 	DEVMETHOD(gpio_pin_get,         ftgpio_gpio_pin_get),
592 	DEVMETHOD(gpio_pin_toggle,      ftgpio_gpio_pin_toggle),
593 	DEVMETHOD(gpio_pin_getname,     ftgpio_gpio_pin_getname),
594 	DEVMETHOD(gpio_pin_getcaps,     ftgpio_gpio_pin_getcaps),
595 	DEVMETHOD(gpio_pin_getflags,    ftgpio_gpio_pin_getflags),
596 	DEVMETHOD(gpio_pin_setflags,    ftgpio_gpio_pin_setflags),
597 
598 	DEVMETHOD_END
599 };
600 
601 static driver_t ftgpio_driver = {
602 	"gpio",
603 	ftgpio_methods,
604 	sizeof(struct ftgpio_softc)
605 };
606 
607 DRIVER_MODULE(ftgpio, superio, ftgpio_driver, NULL,  NULL);
608 MODULE_DEPEND(ftgpio, gpiobus, 1, 1, 1);
609 MODULE_DEPEND(ftgpio, superio, 1, 1, 1);
610 MODULE_VERSION(ftgpio, 1);
611