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);
Cache object: f200282c831c3b83ca74a4378ac684c5
|