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;
+}

Reply via email to