Module Name: src
Committed By: thorpej
Date: Wed Jan 23 04:23:01 UTC 2019
Modified Files:
src/sys/dev/fdt: fdt_pinctrl.c
Log Message:
Implement subroutines for parsing out some of the generic properties
specified in the pinctrl bindings, and adapt Meson, Rockchip, and
Allwinner pinctrl back-ends to use them.
Ok jmcneill@
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/dev/fdt/fdt_pinctrl.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/fdt/fdt_pinctrl.c
diff -u src/sys/dev/fdt/fdt_pinctrl.c:1.6 src/sys/dev/fdt/fdt_pinctrl.c:1.7
--- src/sys/dev/fdt/fdt_pinctrl.c:1.6 Mon Jan 14 12:23:53 2019
+++ src/sys/dev/fdt/fdt_pinctrl.c Wed Jan 23 04:23:01 2019
@@ -1,6 +1,7 @@
-/* $NetBSD: fdt_pinctrl.c,v 1.6 2019/01/14 12:23:53 mlelstv Exp $ */
+/* $NetBSD: fdt_pinctrl.c,v 1.7 2019/01/23 04:23:01 thorpej Exp $ */
/*-
+ * Copyright (c) 2019 Jason R. Thorpe
* Copyright (c) 2017 Jared McNeill <[email protected]>
* Copyright (c) 2015 Martin Fouts
* All rights reserved.
@@ -28,10 +29,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.6 2019/01/14 12:23:53 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.7 2019/01/23 04:23:01 thorpej Exp $");
#include <sys/param.h>
#include <sys/bus.h>
+#include <sys/gpio.h>
#include <sys/kmem.h>
#include <sys/queue.h>
@@ -166,3 +168,192 @@ fdtbus_pinctrl_configure(void)
{
fdtbus_pinctrl_configure_node(OF_finddevice("/"));
}
+
+/*
+ * Helper routines for parsing put properties related to pinctrl bindings.
+ */
+
+/*
+ * Pin mux settings apply to sets of pins specified by one of 3
+ * sets of properties:
+ *
+ * - "pins" + "function"
+ * - "groups" + "function"
+ * - "pinmux"
+ *
+ * Eactly one of those 3 combinations must be specified.
+ */
+
+const char *
+fdtbus_pinctrl_parse_function(int phandle)
+{
+ return fdtbus_get_string(phandle, "function");
+}
+
+const void *
+fdtbus_pinctrl_parse_pins(int phandle, int *pins_len)
+{
+ int len;
+
+ /*
+ * The pinctrl bindings specify that entries in "pins"
+ * may be integers or strings; this is determined by
+ * the hardware-specific binding.
+ */
+
+ len = OF_getproplen(phandle, "pins");
+ if (len > 0) {
+ return fdtbus_get_prop(phandle, "pins", pins_len);
+ }
+
+ return NULL;
+}
+
+const char *
+fdtbus_pinctrl_parse_groups(int phandle, int *groups_len)
+{
+ int len;
+
+ len = OF_getproplen(phandle, "groups");
+ if (len > 0) {
+ *groups_len = len;
+ return fdtbus_get_string(phandle, "groups");
+ }
+
+ return NULL;
+}
+
+const u_int *
+fdtbus_pinctrl_parse_pinmux(int phandle, int *pinmux_len)
+{
+ int len;
+
+ len = OF_getproplen(phandle, "pinmux");
+ if (len > 0) {
+ return fdtbus_get_prop(phandle, "pinmux", pinmux_len);
+ }
+
+ return NULL;
+}
+
+int
+fdtbus_pinctrl_parse_bias(int phandle, int *pull_strength)
+{
+ const char *bias_prop = NULL;
+ int bias = -1;
+
+ /*
+ * bias-pull-{up,down,pin-default} properties have an optional
+ * argument: the pull strength in Ohms. (In practice, this is
+ * sometimes a hardware-specific constant.)
+ *
+ * XXXJRT How to represent bias-pull-pin-default?
+ */
+
+ if (of_hasprop(phandle, "bias-disable")) {
+ bias = 0;
+ } else if (of_hasprop(phandle, "bias-pull-up")) {
+ bias_prop = "bias-pull-up";
+ bias = GPIO_PIN_PULLUP;
+ } else if (of_hasprop(phandle, "bias-pull-down")) {
+ bias_prop = "bias-pull-down";
+ bias = GPIO_PIN_PULLDOWN;
+ }
+
+ if (pull_strength) {
+ *pull_strength = -1;
+ if (bias_prop) {
+ uint32_t val;
+ if (of_getprop_uint32(phandle, bias_prop, &val) == 0) {
+ *pull_strength = (int)val;
+ }
+ }
+ }
+
+ return bias;
+}
+
+int
+fdtbus_pinctrl_parse_drive(int phandle)
+{
+ int drive = -1;
+
+ if (of_hasprop(phandle, "drive-push-pull"))
+ drive = GPIO_PIN_PUSHPULL;
+ else if (of_hasprop(phandle, "drive-open-drain"))
+ drive = GPIO_PIN_OPENDRAIN;
+ else if (of_hasprop(phandle, "drive-open-source"))
+ drive = 0;
+
+ return drive;
+}
+
+int
+fdtbus_pinctrl_parse_drive_strength(int phandle)
+{
+ int val;
+
+ /*
+ * drive-strength has as an argument the target strength
+ * in mA.
+ */
+
+ if (of_getprop_uint32(phandle, "drive-strength", &val) == 0)
+ return val;
+
+ return -1;
+}
+int fdtbus_pinctrl_parse_input_output(int phandle, int *output_value)
+{
+ int direction = -1;
+ int pinval = -1;
+
+ if (of_hasprop(phandle, "input-enable")) {
+ direction = GPIO_PIN_INPUT;
+ } else if (of_hasprop(phandle, "input-disable")) {
+ /*
+ * XXXJRT How to represent this? This is more than
+ * just "don't set the direction" - it's an active
+ * command that might involve disabling an input
+ * buffer on the pin.
+ */
+ }
+
+ if (of_hasprop(phandle, "output-enable")) {
+ if (direction == -1)
+ direction = 0;
+ direction |= GPIO_PIN_OUTPUT;
+ } else if (of_hasprop(phandle, "output-disable")) {
+ if (direction == -1)
+ direction = 0;
+ direction |= GPIO_PIN_TRISTATE;
+ }
+
+ if (of_hasprop(phandle, "output-low")) {
+ if (direction == -1)
+ direction = 0;
+ direction |= GPIO_PIN_OUTPUT;
+ pinval = GPIO_PIN_LOW;
+ } else if (of_hasprop(phandle, "output-high")) {
+ if (direction == -1)
+ direction = 0;
+ direction |= GPIO_PIN_OUTPUT;
+ pinval = GPIO_PIN_HIGH;
+ }
+
+ if (output_value)
+ *output_value = pinval;
+
+ /*
+ * XXX input-schmitt-enable
+ * XXX input-schmitt-disable
+ */
+
+ if (direction != -1
+ && (direction & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
+ == (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
+ direction |= GPIO_PIN_INOUT;
+ }
+
+ return direction;
+}