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