xref: /freebsd/sys/dev/bhnd/cores/chipc/chipc_gpio.c (revision 7cc42f6d)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2017 The FreeBSD Foundation
5  * All rights reserved.
6  *
7  * This software was developed by Landon Fuller under sponsorship from
8  * the FreeBSD Foundation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33 
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/bus.h>
40 #include <sys/gpio.h>
41 #include <sys/limits.h>
42 #include <sys/module.h>
43 
44 #include <machine/_inttypes.h>
45 #include <machine/bus.h>
46 #include <sys/rman.h>
47 #include <machine/resource.h>
48 
49 #include <dev/bhnd/bhnd.h>
50 #include <dev/gpio/gpiobusvar.h>
51 
52 #include "gpio_if.h"
53 
54 #include "bhnd_nvram_map.h"
55 
56 #include "chipcreg.h"
57 #include "chipc_gpiovar.h"
58 
59 /*
60  * ChipCommon GPIO driver
61  */
62 
63 static int			chipc_gpio_check_flags(
64 				    struct chipc_gpio_softc *sc,
65 				    uint32_t pin_num, uint32_t flags,
66 				    chipc_gpio_pin_mode *mode);
67 static int			chipc_gpio_pin_update(
68 				    struct chipc_gpio_softc *sc,
69 				    struct chipc_gpio_update *update,
70 				    uint32_t pin_num, uint32_t flags);
71 static int			chipc_gpio_commit_update(
72 				    struct chipc_gpio_softc *sc,
73 				    struct chipc_gpio_update *update);
74 static chipc_gpio_pin_mode	chipc_gpio_pin_get_mode(
75 				    struct chipc_gpio_softc *sc,
76 				    uint32_t pin_num);
77 
78 /* Debugging flags */
79 static u_long chipc_gpio_debug = 0;
80 TUNABLE_ULONG("hw.bhnd_chipc.gpio_debug", &chipc_gpio_debug);
81 
82 enum {
83 	/** Allow userspace GPIO access on bridged network (e.g. wi-fi)
84 	  * adapters */
85 	CC_GPIO_DEBUG_ADAPTER_GPIOC = 1 << 0,
86 };
87 
88 #define	CC_GPIO_DEBUG(_type)	(CC_GPIO_DEBUG_ ## _type & chipc_gpio_debug)
89 
90 static struct bhnd_device_quirk chipc_gpio_quirks[];
91 
92 /* Supported parent core device identifiers */
93 static const struct bhnd_device chipc_gpio_devices[] = {
94 	BHND_DEVICE(BCM, CC, "Broadcom ChipCommon GPIO", chipc_gpio_quirks),
95 	BHND_DEVICE_END
96 };
97 
98 /* Device quirks table */
99 static struct bhnd_device_quirk chipc_gpio_quirks[] = {
100 	BHND_CORE_QUIRK	(HWREV_LTE(10),	CC_GPIO_QUIRK_NO_EVENTS),
101 	BHND_CORE_QUIRK	(HWREV_LTE(15),	CC_GPIO_QUIRK_NO_DCTIMER),
102 	BHND_CORE_QUIRK	(HWREV_LTE(19),	CC_GPIO_QUIRK_NO_PULLUPDOWN),
103 
104 	BHND_DEVICE_QUIRK_END
105 };
106 
107 static int
108 chipc_gpio_probe(device_t dev)
109 {
110 	const struct bhnd_device	*id;
111 	device_t			 chipc;
112 
113 	/* Look for compatible chipc parent */
114 	chipc = device_get_parent(dev);
115 	id = bhnd_device_lookup(chipc, chipc_gpio_devices,
116 	    sizeof(chipc_gpio_devices[0]));
117 	if (id == NULL)
118 		return (ENXIO);
119 
120 	device_set_desc(dev, id->desc);
121 	return (BUS_PROBE_NOWILDCARD);
122 }
123 
124 static int
125 chipc_gpio_attach(device_t dev)
126 {
127 	struct chipc_gpio_softc	*sc;
128 	device_t		 chipc;
129 	int			 error;
130 
131 	chipc = device_get_parent(dev);
132 
133 	sc = device_get_softc(dev);
134 	sc->dev = dev;
135 	sc->quirks = bhnd_device_quirks(chipc, chipc_gpio_devices,
136 	    sizeof(chipc_gpio_devices[0]));
137 
138 	/* If this is a bridged wi-fi adapter, we don't want to support
139 	 * userspace requests via gpioc(4) */
140 	if (bhnd_get_attach_type(chipc) == BHND_ATTACH_ADAPTER) {
141 		if (!CC_GPIO_DEBUG(ADAPTER_GPIOC))
142 			sc->quirks |= CC_GPIO_QUIRK_NO_GPIOC;
143 	}
144 
145 	CC_GPIO_LOCK_INIT(sc);
146 
147 	sc->mem_rid = 0;
148 	sc->mem_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
149 	    RF_ACTIVE|RF_SHAREABLE);
150 	if (sc->mem_res == NULL) {
151 		device_printf(dev, "failed to allocate chipcommon registers\n");
152 		error = ENXIO;
153 		goto failed;
154 	}
155 
156 	/*
157 	 * If hardware 'pulsate' support is available, set the timer duty-cycle
158 	 * to either the NVRAM 'leddc' value if available, or the default duty
159 	 * cycle.
160 	 */
161 	if (!CC_GPIO_QUIRK(sc, NO_DCTIMER)) {
162 		uint32_t dctimerval;
163 
164 		error = bhnd_nvram_getvar_uint32(chipc, BHND_NVAR_LEDDC,
165 		    &dctimerval);
166 		if (error == ENOENT) {
167 			/* Fall back on default duty cycle */
168 			dctimerval = CHIPC_GPIOTIMERVAL_DEFAULT;
169 		} else if (error) {
170 			device_printf(dev, "error reading %s from NVRAM: %d\n",
171 			    BHND_NVAR_LEDDC, error);
172 			goto failed;
173 		}
174 
175 		CC_GPIO_WR4(sc, CHIPC_GPIOTIMERVAL, dctimerval);
176 	}
177 
178 	/* Attach gpioc/gpiobus */
179 	if (CC_GPIO_QUIRK(sc, NO_GPIOC)) {
180 		sc->gpiobus = NULL;
181 	} else {
182 		if ((sc->gpiobus = gpiobus_attach_bus(dev)) == NULL) {
183 			device_printf(dev, "failed to attach gpiobus\n");
184 			error = ENXIO;
185 			goto failed;
186 		}
187 	}
188 
189 	/* Register as the bus GPIO provider */
190 	if ((error = bhnd_register_provider(dev, BHND_SERVICE_GPIO))) {
191 		device_printf(dev, "failed to register gpio with bus: %d\n",
192 		    error);
193 		goto failed;
194 	}
195 
196 	return (0);
197 
198 failed:
199 	device_delete_children(dev);
200 
201 	if (sc->mem_res != NULL) {
202 		bhnd_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
203 		    sc->mem_res);
204 	}
205 
206 	CC_GPIO_LOCK_DESTROY(sc);
207 
208 	return (error);
209 }
210 
211 static int
212 chipc_gpio_detach(device_t dev)
213 {
214 	struct chipc_gpio_softc	*sc;
215 	int			 error;
216 
217 	sc = device_get_softc(dev);
218 
219 	if ((error = bus_generic_detach(dev)))
220 		return (error);
221 
222 	if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY)))
223 		return (error);
224 
225 	bhnd_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res);
226 	CC_GPIO_LOCK_DESTROY(sc);
227 
228 	return (0);
229 }
230 
231 static device_t
232 chipc_gpio_get_bus(device_t dev)
233 {
234 	struct chipc_gpio_softc *sc = device_get_softc(dev);
235 
236 	return (sc->gpiobus);
237 }
238 
239 static int
240 chipc_gpio_pin_max(device_t dev, int *maxpin)
241 {
242 	*maxpin = CC_GPIO_NPINS-1;
243 	return (0);
244 }
245 
246 static int
247 chipc_gpio_pin_set(device_t dev, uint32_t pin_num, uint32_t pin_value)
248 {
249 	struct chipc_gpio_softc	*sc;
250 	bool			 pin_high;
251 	int			 error;
252 
253 	sc = device_get_softc(dev);
254 	error = 0;
255 
256 	if (!CC_GPIO_VALID_PIN(pin_num))
257 		return (EINVAL);
258 
259 	switch (pin_value) {
260 	case GPIO_PIN_HIGH:
261 		pin_high = true;
262 		break;
263 	case GPIO_PIN_LOW:
264 		pin_high = false;
265 		break;
266 	default:
267 		return (EINVAL);
268 	}
269 
270 	CC_GPIO_LOCK(sc);
271 
272 	switch (chipc_gpio_pin_get_mode(sc, pin_num)) {
273 	case CC_GPIO_PIN_INPUT:
274 	case CC_GPIO_PIN_TRISTATE:
275 		error = ENODEV;
276 		break;
277 
278 	case CC_GPIO_PIN_OUTPUT:
279 		CC_GPIO_WRFLAG(sc, pin_num, GPIOOUT, pin_high);
280 		break;
281 	}
282 
283 	CC_GPIO_UNLOCK(sc);
284 
285 	return (error);
286 }
287 
288 static int
289 chipc_gpio_pin_get(device_t dev, uint32_t pin_num, uint32_t *pin_value)
290 {
291 	struct chipc_gpio_softc	*sc;
292 	bool			 pin_high;
293 
294 	if (!CC_GPIO_VALID_PIN(pin_num))
295 		return (EINVAL);
296 
297 	sc = device_get_softc(dev);
298 	pin_high = false;
299 
300 	CC_GPIO_LOCK(sc);
301 
302 	switch (chipc_gpio_pin_get_mode(sc, pin_num)) {
303 	case CC_GPIO_PIN_INPUT:
304 		pin_high = CC_GPIO_RDFLAG(sc, pin_num, GPIOIN);
305 		break;
306 
307 	case CC_GPIO_PIN_OUTPUT:
308 		pin_high = CC_GPIO_RDFLAG(sc, pin_num, GPIOOUT);
309 		break;
310 
311 	case CC_GPIO_PIN_TRISTATE:
312 		pin_high = false;
313 		break;
314 	}
315 
316 	CC_GPIO_UNLOCK(sc);
317 
318 	*pin_value = pin_high ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
319 
320 	return (0);
321 }
322 
323 static int
324 chipc_gpio_pin_toggle(device_t dev, uint32_t pin_num)
325 {
326 	struct chipc_gpio_softc	*sc;
327 	bool			 pin_high;
328 	int			 error;
329 
330 	if (!CC_GPIO_VALID_PIN(pin_num))
331 		return (EINVAL);
332 
333 	sc = device_get_softc(dev);
334 	error = 0;
335 
336 	CC_GPIO_LOCK(sc);
337 
338 	switch (chipc_gpio_pin_get_mode(sc, pin_num)) {
339 	case CC_GPIO_PIN_INPUT:
340 	case CC_GPIO_PIN_TRISTATE:
341 		error = ENODEV;
342 		break;
343 
344 	case CC_GPIO_PIN_OUTPUT:
345 		pin_high = CC_GPIO_RDFLAG(sc, pin_num, GPIOOUT);
346 		CC_GPIO_WRFLAG(sc, pin_num, GPIOOUT, !pin_high);
347 		break;
348 	}
349 
350 	CC_GPIO_UNLOCK(sc);
351 
352 	return (error);
353 }
354 
355 static int
356 chipc_gpio_pin_getcaps(device_t dev, uint32_t pin_num, uint32_t *caps)
357 {
358 	struct chipc_gpio_softc	*sc = device_get_softc(dev);
359 
360 	if (!CC_GPIO_VALID_PIN(pin_num))
361 		return (EINVAL);
362 
363 	*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
364 
365 	if (!CC_GPIO_QUIRK(sc, NO_PULLUPDOWN))
366 		*caps |= (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
367 
368 	if (!CC_GPIO_QUIRK(sc, NO_DCTIMER))
369 		*caps |= GPIO_PIN_PULSATE;
370 
371 	return (0);
372 }
373 
374 static int
375 chipc_gpio_pin_getflags(device_t dev, uint32_t pin_num, uint32_t *flags)
376 {
377 	struct chipc_gpio_softc *sc = device_get_softc(dev);
378 
379 	if (!CC_GPIO_VALID_PIN(pin_num))
380 		return (EINVAL);
381 
382 	CC_GPIO_LOCK(sc);
383 
384 	switch (chipc_gpio_pin_get_mode(sc, pin_num)) {
385 	case CC_GPIO_PIN_INPUT:
386 		*flags = GPIO_PIN_INPUT;
387 
388 		if (!CC_GPIO_QUIRK(sc, NO_PULLUPDOWN)) {
389 			if (CC_GPIO_RDFLAG(sc, pin_num, GPIOPU)) {
390 				*flags |= GPIO_PIN_PULLUP;
391 			} else if (CC_GPIO_RDFLAG(sc, pin_num, GPIOPD)) {
392 				*flags |= GPIO_PIN_PULLDOWN;
393 			}
394 		}
395 		break;
396 
397 	case CC_GPIO_PIN_OUTPUT:
398 		*flags = GPIO_PIN_OUTPUT;
399 
400 		if (!CC_GPIO_QUIRK(sc, NO_DCTIMER)) {
401 			if (CC_GPIO_RDFLAG(sc, pin_num, GPIOTIMEROUTMASK))
402 				*flags |= GPIO_PIN_PULSATE;
403 		}
404 
405 		break;
406 
407 	case CC_GPIO_PIN_TRISTATE:
408 		*flags = GPIO_PIN_TRISTATE|GPIO_PIN_OUTPUT;
409 		break;
410 	}
411 
412 	CC_GPIO_UNLOCK(sc);
413 
414 	return (0);
415 }
416 
417 static int
418 chipc_gpio_pin_getname(device_t dev, uint32_t pin_num, char *name)
419 {
420 	int ret;
421 
422 	if (!CC_GPIO_VALID_PIN(pin_num))
423 		return (EINVAL);
424 
425 	ret = snprintf(name, GPIOMAXNAME, "bhnd_gpio%02" PRIu32, pin_num);
426 
427 	if (ret < 0)
428 		return (ENXIO);
429 
430 	if (ret >= GPIOMAXNAME)
431 		return (ENOMEM);
432 
433 	return (0);
434 }
435 
436 static int
437 chipc_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
438 {
439 	struct chipc_gpio_softc		*sc;
440 	struct chipc_gpio_update	 upd;
441 	int				 error;
442 
443 	sc = device_get_softc(dev);
444 
445 	if (!CC_GPIO_VALID_PIN(pin_num))
446 		return (EINVAL);
447 
448 	/* Produce an update descriptor */
449 	memset(&upd, 0, sizeof(upd));
450 	if ((error = chipc_gpio_pin_update(sc, &upd, pin_num, flags)))
451 		return (error);
452 
453 	/* Commit the update */
454 	CC_GPIO_LOCK(sc);
455 	error = chipc_gpio_commit_update(sc, &upd);
456 	CC_GPIO_UNLOCK(sc);
457 
458 	return (error);
459 }
460 
461 static int
462 chipc_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
463     uint32_t change_pins, uint32_t *orig_pins)
464 {
465 	struct chipc_gpio_softc		*sc;
466 	struct chipc_gpio_update	 upd;
467 	uint32_t			 out, outen, ctrl;
468 	uint32_t			 num_pins;
469 	int				 error;
470 
471 	sc = device_get_softc(dev);
472 
473 	if (first_pin >= CC_GPIO_NPINS)
474 		return (EINVAL);
475 
476 	/* Determine the actual number of referenced pins */
477 	if (clear_pins == 0 && change_pins == 0) {
478 		num_pins = CC_GPIO_NPINS - first_pin;
479 	} else {
480 		int num_clear_pins, num_change_pins;
481 
482 		num_clear_pins = flsl((u_long)clear_pins);
483 		num_change_pins = flsl((u_long)change_pins);
484 		num_pins = MAX(num_clear_pins, num_change_pins);
485 	}
486 
487 	/* Validate the full pin range */
488 	if (!CC_GPIO_VALID_PINS(first_pin, num_pins))
489 		return (EINVAL);
490 
491 	/* Produce an update descriptor for all pins, relative to the current
492 	 * pin state */
493 	CC_GPIO_LOCK(sc);
494 	memset(&upd, 0, sizeof(upd));
495 
496 	out = CC_GPIO_RD4(sc, CHIPC_GPIOOUT);
497 	outen = CC_GPIO_RD4(sc, CHIPC_GPIOOUTEN);
498 	ctrl = CC_GPIO_RD4(sc, CHIPC_GPIOCTRL);
499 
500 	for (uint32_t i = 0; i < num_pins; i++) {
501 		uint32_t	pin;
502 		bool		pin_high;
503 
504 		pin = first_pin + i;
505 
506 		/* The pin must be configured for output */
507 		if ((outen & (1 << pin)) == 0) {
508 			CC_GPIO_UNLOCK(sc);
509 			return (EINVAL);
510 		}
511 
512 		/* The pin must not tristated */
513 		if ((ctrl & (1 << pin)) != 0) {
514 			CC_GPIO_UNLOCK(sc);
515 			return (EINVAL);
516 		}
517 
518 		/* Fetch current state */
519 		if (out & (1 << pin)) {
520 			pin_high = true;
521 		} else {
522 			pin_high = false;
523 		}
524 
525 		/* Apply clear/toggle request */
526 		if (clear_pins & (1 << pin))
527 			pin_high = false;
528 
529 		if (change_pins & (1 << pin))
530 			pin_high = !pin_high;
531 
532 		/* Add to our update descriptor */
533 		CC_GPIO_UPDATE(&upd, pin, out, pin_high);
534 	}
535 
536 	/* Commit the update */
537 	error = chipc_gpio_commit_update(sc, &upd);
538 	CC_GPIO_UNLOCK(sc);
539 
540 	return (error);
541 }
542 
543 static int
544 chipc_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
545     uint32_t *pin_flags)
546 {
547 	struct chipc_gpio_softc		*sc;
548 	struct chipc_gpio_update	 upd;
549 	int				 error;
550 
551 	sc = device_get_softc(dev);
552 
553 	if (!CC_GPIO_VALID_PINS(first_pin, num_pins))
554 		return (EINVAL);
555 
556 	/* Produce an update descriptor */
557 	memset(&upd, 0, sizeof(upd));
558 	for (uint32_t i = 0; i < num_pins; i++) {
559 		uint32_t pin, flags;
560 
561 		pin = first_pin + i;
562 		flags = pin_flags[i];
563 
564 		/* As per the gpio_config_32 API documentation, any pins for
565 		 * which neither GPIO_PIN_OUTPUT or GPIO_PIN_INPUT are set
566 		 * should be ignored and left unmodified */
567 		if ((flags & (GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) == 0)
568 			continue;
569 
570 		if ((error = chipc_gpio_pin_update(sc, &upd, pin, flags)))
571 			return (error);
572 	}
573 
574 	/* Commit the update */
575 	CC_GPIO_LOCK(sc);
576 	error = chipc_gpio_commit_update(sc, &upd);
577 	CC_GPIO_UNLOCK(sc);
578 
579 	return (error);
580 }
581 
582 /**
583  * Commit a single @p reg register update.
584  */
585 static void
586 chipc_gpio_commit_reg(struct chipc_gpio_softc *sc, bus_size_t offset,
587     struct chipc_gpio_reg *reg)
588 {
589 	uint32_t value;
590 
591 	CC_GPIO_LOCK_ASSERT(sc, MA_OWNED);
592 
593 	if (reg->mask == 0)
594 		return;
595 
596 	value = bhnd_bus_read_4(sc->mem_res, offset);
597 	value &= ~reg->mask;
598 	value |= reg->value;
599 
600 	bhnd_bus_write_4(sc->mem_res, offset, value);
601 }
602 
603 /**
604  * Commit the set of GPIO register updates described by @p update.
605  */
606 static int
607 chipc_gpio_commit_update(struct chipc_gpio_softc *sc,
608     struct chipc_gpio_update *update)
609 {
610 	CC_GPIO_LOCK_ASSERT(sc, MA_OWNED);
611 
612 	/* Commit pulldown/pullup before potentially disabling an output pin */
613 	chipc_gpio_commit_reg(sc, CHIPC_GPIOPD, &update->pulldown);
614 	chipc_gpio_commit_reg(sc, CHIPC_GPIOPU, &update->pullup);
615 
616 	/* Commit output settings before potentially enabling an output pin */
617 	chipc_gpio_commit_reg(sc, CHIPC_GPIOTIMEROUTMASK,
618 	    &update->timeroutmask);
619 	chipc_gpio_commit_reg(sc, CHIPC_GPIOOUT, &update->out);
620 
621 	/* Commit input/output/tristate modes */
622 	chipc_gpio_commit_reg(sc, CHIPC_GPIOOUTEN, &update->outen);
623 	chipc_gpio_commit_reg(sc, CHIPC_GPIOCTRL, &update->ctrl);
624 
625 	return (0);
626 }
627 
628 /**
629  * Apply the changes described by @p flags for @p pin_num to the given @p update
630  * descriptor.
631  */
632 static int
633 chipc_gpio_pin_update(struct chipc_gpio_softc *sc,
634     struct chipc_gpio_update *update, uint32_t pin_num, uint32_t flags)
635 {
636 	chipc_gpio_pin_mode	mode;
637 	int			error;
638 
639 	if (!CC_GPIO_VALID_PIN(pin_num))
640 		return (EINVAL);
641 
642 	/* Verify flag compatibility and determine the pin mode */
643 	if ((error = chipc_gpio_check_flags(sc, pin_num, flags, &mode)))
644 		return (error);
645 
646 	/* Apply the mode-specific changes */
647 	switch (mode) {
648 	case CC_GPIO_PIN_INPUT:
649 		CC_GPIO_UPDATE(update, pin_num, pullup, false);
650 		CC_GPIO_UPDATE(update, pin_num, pulldown, false);
651 		CC_GPIO_UPDATE(update, pin_num, out, false);
652 		CC_GPIO_UPDATE(update, pin_num, outen, false);
653 		CC_GPIO_UPDATE(update, pin_num, timeroutmask, false);
654 		CC_GPIO_UPDATE(update, pin_num, ctrl, false);
655 
656 		if (flags & GPIO_PIN_PULLUP) {
657 			CC_GPIO_UPDATE(update, pin_num, pullup, true);
658 		} else if (flags & GPIO_PIN_PULLDOWN) {
659 			CC_GPIO_UPDATE(update, pin_num, pulldown, true);
660 		}
661 
662 		return (0);
663 
664 	case CC_GPIO_PIN_OUTPUT:
665 		CC_GPIO_UPDATE(update, pin_num, pullup, false);
666 		CC_GPIO_UPDATE(update, pin_num, pulldown, false);
667 		CC_GPIO_UPDATE(update, pin_num, outen, true);
668 		CC_GPIO_UPDATE(update, pin_num, timeroutmask, false);
669 		CC_GPIO_UPDATE(update, pin_num, ctrl, false);
670 
671 		if (flags & GPIO_PIN_PRESET_HIGH) {
672 			CC_GPIO_UPDATE(update, pin_num, out, true);
673 		} else if (flags & GPIO_PIN_PRESET_LOW) {
674 			CC_GPIO_UPDATE(update, pin_num, out, false);
675 		}
676 
677 		if (flags & GPIO_PIN_PULSATE)
678 			CC_GPIO_UPDATE(update, pin_num, timeroutmask, true);
679 
680 		return (0);
681 
682 	case CC_GPIO_PIN_TRISTATE:
683 		CC_GPIO_UPDATE(update, pin_num, pullup, false);
684 		CC_GPIO_UPDATE(update, pin_num, pulldown, false);
685 		CC_GPIO_UPDATE(update, pin_num, out, false);
686 		CC_GPIO_UPDATE(update, pin_num, outen, false);
687 		CC_GPIO_UPDATE(update, pin_num, timeroutmask, false);
688 		CC_GPIO_UPDATE(update, pin_num, ctrl, true);
689 
690 		if (flags & GPIO_PIN_OUTPUT)
691 			CC_GPIO_UPDATE(update, pin_num, outen, true);
692 
693 		return (0);
694 	}
695 
696 	device_printf(sc->dev, "unknown pin mode %d\n", mode);
697 	return (EINVAL);
698 }
699 
700 /**
701  * Verify that @p flags are valid for use with @p pin_num, and on success,
702  * return the pin mode described by @p flags in @p mode.
703  *
704  * @param	sc	GPIO driver instance state.
705  * @param	pin_num	The pin number to configure.
706  * @param	flags	The pin flags to be validated.
707  * @param[out]	mode	On success, will be populated with the GPIO pin mode
708  *			defined by @p flags.
709  *
710  * @retval 0		success
711  * @retval EINVAL	if @p flags are invalid.
712  */
713 static int
714 chipc_gpio_check_flags(struct chipc_gpio_softc *sc, uint32_t pin_num,
715     uint32_t flags, chipc_gpio_pin_mode *mode)
716 {
717 	uint32_t mode_flag, input_flag, output_flag;
718 
719 	CC_GPIO_ASSERT_VALID_PIN(sc, pin_num);
720 
721 	mode_flag = flags & (GPIO_PIN_OUTPUT | GPIO_PIN_INPUT |
722 	    GPIO_PIN_TRISTATE);
723 	output_flag = flags & (GPIO_PIN_PRESET_HIGH | GPIO_PIN_PRESET_LOW
724 	    | GPIO_PIN_PULSATE);
725 	input_flag = flags & (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
726 
727 	switch (mode_flag) {
728 	case GPIO_PIN_OUTPUT:
729 		/* No input flag(s) should be set */
730 		if (input_flag != 0)
731 			return (EINVAL);
732 
733 		/* Validate our output flag(s) */
734 		switch (output_flag) {
735 		case GPIO_PIN_PRESET_HIGH:
736 		case GPIO_PIN_PRESET_LOW:
737 		case (GPIO_PIN_PRESET_HIGH|GPIO_PIN_PULSATE):
738 		case (GPIO_PIN_PRESET_LOW|GPIO_PIN_PULSATE):
739 		case 0:
740 			/* Check for unhandled flags */
741 			if ((flags & ~(mode_flag | output_flag)) != 0)
742 				return (EINVAL);
743 
744 			*mode = CC_GPIO_PIN_OUTPUT;
745 			return (0);
746 
747 		default:
748 			/* Incompatible output flags */
749 			return (EINVAL);
750 		}
751 
752 	case GPIO_PIN_INPUT:
753 		/* No output flag(s) should be set */
754 		if (output_flag != 0)
755 			return (EINVAL);
756 
757 		/* Validate our input flag(s) */
758 		switch (input_flag) {
759 		case GPIO_PIN_PULLUP:
760 		case GPIO_PIN_PULLDOWN:
761 		case 0:
762 			/* Check for unhandled flags */
763 			if ((flags & ~(mode_flag | input_flag)) != 0)
764 				return (EINVAL);
765 
766 			*mode = CC_GPIO_PIN_INPUT;
767 			return (0);
768 
769 		default:
770 			/* Incompatible input flags */
771 			return (EINVAL);
772 		}
773 
774 		break;
775 
776 	case (GPIO_PIN_TRISTATE|GPIO_PIN_OUTPUT):
777 	case GPIO_PIN_TRISTATE:
778 		/* No input or output flag(s) should be set */
779 		if (input_flag != 0 || output_flag != 0)
780 			return (EINVAL);
781 
782 		/* Check for unhandled flags */
783 		if ((flags & ~mode_flag) != 0)
784 			return (EINVAL);
785 
786 		*mode = CC_GPIO_PIN_TRISTATE;
787 		return (0);
788 
789 	default:
790 		/* Incompatible mode flags */
791 		return (EINVAL);
792 	}
793 }
794 
795 /**
796  * Return the current pin mode for @p pin_num.
797  *
798  * @param sc		GPIO driver instance state.
799  * @param pin_num	The pin number to query.
800  */
801 static chipc_gpio_pin_mode
802 chipc_gpio_pin_get_mode(struct chipc_gpio_softc *sc, uint32_t pin_num)
803 {
804 	CC_GPIO_LOCK_ASSERT(sc, MA_OWNED);
805 	CC_GPIO_ASSERT_VALID_PIN(sc, pin_num);
806 
807 	if (CC_GPIO_RDFLAG(sc, pin_num, GPIOCTRL)) {
808 		return (CC_GPIO_PIN_TRISTATE);
809 	} else if (CC_GPIO_RDFLAG(sc, pin_num, GPIOOUTEN)) {
810 		return (CC_GPIO_PIN_OUTPUT);
811 	} else {
812 		return (CC_GPIO_PIN_INPUT);
813 	}
814 }
815 
816 static device_method_t chipc_gpio_methods[] = {
817 	/* Device interface */
818 	DEVMETHOD(device_probe,		chipc_gpio_probe),
819 	DEVMETHOD(device_attach,	chipc_gpio_attach),
820 	DEVMETHOD(device_detach,	chipc_gpio_detach),
821 
822 	/* GPIO interface */
823 	DEVMETHOD(gpio_get_bus,		chipc_gpio_get_bus),
824 	DEVMETHOD(gpio_pin_max,		chipc_gpio_pin_max),
825 	DEVMETHOD(gpio_pin_getname,	chipc_gpio_pin_getname),
826 	DEVMETHOD(gpio_pin_getflags,	chipc_gpio_pin_getflags),
827 	DEVMETHOD(gpio_pin_getcaps,	chipc_gpio_pin_getcaps),
828 	DEVMETHOD(gpio_pin_setflags,	chipc_gpio_pin_setflags),
829 	DEVMETHOD(gpio_pin_get,		chipc_gpio_pin_get),
830 	DEVMETHOD(gpio_pin_set,		chipc_gpio_pin_set),
831 	DEVMETHOD(gpio_pin_toggle,	chipc_gpio_pin_toggle),
832 	DEVMETHOD(gpio_pin_access_32,	chipc_gpio_pin_access_32),
833 	DEVMETHOD(gpio_pin_config_32,	chipc_gpio_pin_config_32),
834 
835 	DEVMETHOD_END
836 };
837 
838 static devclass_t gpio_devclass;
839 
840 DEFINE_CLASS_0(gpio, chipc_gpio_driver, chipc_gpio_methods, sizeof(struct chipc_gpio_softc));
841 EARLY_DRIVER_MODULE(chipc_gpio, bhnd_chipc, chipc_gpio_driver,
842     gpio_devclass, NULL, NULL, BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
843 
844 MODULE_DEPEND(chipc_gpio, bhnd, 1, 1, 1);
845 MODULE_DEPEND(chipc_gpio, gpiobus, 1, 1, 1);
846 MODULE_VERSION(chipc_gpio, 1);
847