Add a simple framework for handling gpio controllers and pins on FDT-enabled
authorkettenis <kettenis@openbsd.org>
Mon, 11 Jul 2016 14:49:41 +0000 (14:49 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 11 Jul 2016 14:49:41 +0000 (14:49 +0000)
platforms.

ok visa@, jsg@

sys/dev/ofw/ofw_gpio.c [new file with mode: 0644]
sys/dev/ofw/ofw_gpio.h [new file with mode: 0644]

diff --git a/sys/dev/ofw/ofw_gpio.c b/sys/dev/ofw/ofw_gpio.c
new file mode 100644 (file)
index 0000000..668210a
--- /dev/null
@@ -0,0 +1,84 @@
+/*     $OpenBSD: ofw_gpio.c,v 1.1 2016/07/11 14:49:41 kettenis Exp $   */
+/*
+ * Copyright (c) 2016 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_gpio.h>
+
+LIST_HEAD(, gpio_controller) gpio_controllers =
+       LIST_HEAD_INITIALIZER(gpio_controllers);
+
+void
+gpio_controller_register(struct gpio_controller *gc)
+{
+       gc->gc_cells = OF_getpropint(gc->gc_node, "#gpio-cells", 2);
+       gc->gc_phandle = OF_getpropint(gc->gc_node, "phandle", 0);
+       if (gc->gc_phandle == 0)
+               return;
+
+       LIST_INSERT_HEAD(&gpio_controllers, gc, gc_list);
+}
+
+void
+gpio_controller_config_pin(uint32_t *cells, int config)
+{
+       struct gpio_controller *gc;
+       uint32_t phandle = cells[0];
+
+       LIST_FOREACH(gc, &gpio_controllers, gc_list) {
+               if (gc->gc_phandle == phandle)
+                       break;
+       }
+
+       if (gc && gc->gc_config_pin)
+               gc->gc_config_pin(gc->gc_cookie, &cells[1], config);
+}
+
+int
+gpio_controller_get_pin(uint32_t *cells)
+{
+       struct gpio_controller *gc;
+       uint32_t phandle = cells[0];
+       int val = 0;
+
+       LIST_FOREACH(gc, &gpio_controllers, gc_list) {
+               if (gc->gc_phandle == phandle)
+                       break;
+       }
+
+       if (gc && gc->gc_get_pin)
+               val = gc->gc_get_pin(gc->gc_cookie, &cells[1]);
+
+       return val;
+}
+
+void
+gpio_controller_set_pin(uint32_t *cells, int val)
+{
+       struct gpio_controller *gc;
+       uint32_t phandle = cells[0];
+
+       LIST_FOREACH(gc, &gpio_controllers, gc_list) {
+               if (gc->gc_phandle == phandle)
+                       break;
+       }
+
+       if (gc && gc->gc_set_pin)
+               gc->gc_set_pin(gc->gc_cookie, &cells[1], val);
+}
diff --git a/sys/dev/ofw/ofw_gpio.h b/sys/dev/ofw/ofw_gpio.h
new file mode 100644 (file)
index 0000000..52f00b0
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $OpenBSD: ofw_gpio.h,v 1.1 2016/07/11 14:49:41 kettenis Exp $   */
+/*
+ * Copyright (c) 2016 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DEV_OFW_GPIO_H_
+#define _DEV_OFW_GPIO_H_
+
+#define GPIO_ACTIVE_HIGH       0
+#define GPIO_ACTIVE_LOW                1
+
+struct gpio_controller {
+       int     gc_node;
+       void    *gc_cookie;
+       void    (*gc_config_pin)(void *, uint32_t *, int);
+       int     (*gc_get_pin)(void *, uint32_t *);
+       void    (*gc_set_pin)(void *, uint32_t *, int);
+
+       LIST_ENTRY(gpio_controller) gc_list;
+       uint32_t gc_phandle;
+       uint32_t gc_cells;
+};
+
+void   gpio_controller_register(struct gpio_controller *);
+
+#define GPIO_CONFIG_INPUT      0x0000
+#define GPIO_CONFIG_OUTPUT     0x0001
+void   gpio_controller_config_pin(uint32_t *, int);
+
+int    gpio_controller_get_pin(uint32_t *);
+void   gpio_controller_set_pin(uint32_t *, int);
+
+#endif /* _DEV_OFW_GPIO_H_ */