devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
To: U-Boot Mailing List <u-boot-0aAXYlwwYIKGBzrmiIFOJg@public.gmane.org>
Cc: Devicetree Discuss
	<devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org>,
	Albert ARIBAUD
	<albert.u.boot-LhW3hqR2+23R7s880joybQ@public.gmane.org>,
	Tom Warren <twarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH v2 04/17] fdt: Add basic support for decoding GPIO definitions
Date: Fri,  2 Dec 2011 18:11:27 -0800	[thread overview]
Message-ID: <1322878300-5551-5-git-send-email-sjg@chromium.org> (raw)
In-Reply-To: <1322878300-5551-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

This adds some support into fdtdec for reading GPIO definitions from
the fdt. We permit up to FDT_GPIO_MAX GPIOs in the system. Each GPIO
is of the form:

gpio-function-name = <phandle gpio_num flags>;

where:

phandle is a pointer to the GPIO node
gpio_num is the number of the GPIO (0 to 223)
flags is some flags, proposed as follows:

   bit    meaning
   0      0=input, 1=output
   1      for output only: inital value of output
   2      0=polarity normal, 1=active low (inverted)

An example is:

enable-propounder = <&gpio 43 1>;

which means that GPIO 43 is an output and we can enable the propounder by
setting gpio 43 high.

Two main functions are provided:

fdtdec_decode_gpio() reads a GPIO property from an fdt node and decodes it
into a structure.

fdtdec_setup_gpio() sets up the GPIO by calling gpio_request and
gpio_direction_input/output() for you.

Both functions can cope with the property being missing, which is taken to
mean that that GPIO function is not available or is not needed.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---

 include/fdtdec.h |   49 ++++++++++++++++++++++++++++++++
 lib/fdtdec.c     |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 974520a..57db42b 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -61,6 +61,26 @@ enum fdt_compat_id {
 	COMPAT_COUNT,
 };
 
+/* For now we allow 224 GPIOs. We can extend this later if required */
+enum {
+	FDT_GPIO_NONE = 255,	/* an invalid GPIO used to end our list */
+	FDT_GPIO_MAX  = 224,	/* maximum valid GPIO number */
+
+	FDT_GPIO_OUTPUT	= 1 << 0,	/* set as output (else input) */
+	FDT_GPIO_HIGH	= 1 << 1,	/* set output as high (else low) */
+	FDT_GPIO_ACTIVE_LOW = 1 << 2,	/* input is active low (else high) */
+};
+
+/* This is the state of a GPIO pin as defined by the fdt */
+struct fdt_gpio_state {
+	const char *name;	/* name of the fdt property defining this */
+	u8 gpio;		/* GPIO number, or FDT_GPIO_NONE if none */
+	u8 flags;		/* FDT_GPIO_... flags */
+};
+
+/* This tells us whether a fdt_gpio_state record is valid or not */
+#define fdt_gpio_isvalid(x) ((x)->gpio != FDT_GPIO_NONE)
+
 /**
  * Find the next numbered alias for a peripheral. This is used to enumerate
  * all the peripherals of a certain type.
@@ -181,3 +201,32 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
  * @return 1 if the properly is present; 0 if it isn't present or is 0
  */
 int fdtdec_get_bool(const void *blob, int node, const char *prop_name);
+
+/**
+ * Decode a single GPIOs from an FDT.
+ *
+ * If the property is not found, then the GPIO structure will still be
+ * initialised, with gpio set to FDT_GPIO_NONE. This makes it easy to
+ * provide optional GPIOs.
+ *
+ * @param blob		FDT blob to use
+ * @param node		Node to look at
+ * @param prop_name	Node property name
+ * @param gpio		gpio elements to fill from FDT
+ * @return 0 if ok, -FDT_ERR_NOTFOUND if the property is missing.
+ */
+int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
+		struct fdt_gpio_state *gpio);
+
+/**
+ * Set up a GPIO pin according to the provided gpio information. This sets it
+ * to either input or output. If an output, then the defined value is
+ * assigned.
+ *
+ * If the gpio is FDT_GPIO_NONE, no action is taken. This makes it easy to
+ * deal with optional GPIOs.
+ *
+ * @param gpio		GPIO info to use for set up
+ * @return 0 if all ok or gpio was FDT_GPIO_NONE; -1 on error
+ */
+int fdtdec_setup_gpio(struct fdt_gpio_state *gpio);
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 8f972b7..8eed752 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -24,6 +24,9 @@
 #include <libfdt.h>
 #include <fdtdec.h>
 
+/* we need the generic GPIO interface here */
+#include <asm-generic/gpio.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -231,3 +234,83 @@ int fdtdec_get_bool(const void *blob, int node, const char *prop_name)
 
 	return 1;
 }
+
+/**
+ * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no
+ * terminating item.
+ *
+ * @param blob		FDT blob to use
+ * @param node		Node to look at
+ * @param prop_name	Node property name
+ * @param gpio		Array of gpio elements to fill from FDT. This will be
+ *			untouched if either 0 or an error is returned
+ * @param max_count	Maximum number of elements allowed
+ * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
+ * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
+ */
+static int fdtdec_decode_gpios(const void *blob, int node,
+		const char *prop_name, struct fdt_gpio_state *gpio,
+		int max_count)
+{
+	const struct fdt_property *prop;
+	const u32 *cell;
+	const char *name;
+	int len, i;
+
+	debug("%s: %s\n", __func__, prop_name);
+	assert(max_count > 0);
+	prop = fdt_get_property(blob, node, prop_name, &len);
+	if (!prop) {
+		debug("FDT: %s: property '%s' missing\n", __func__, prop_name);
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	/* We will use the name to tag the GPIO */
+	name = fdt_string(blob, prop->nameoff);
+	cell = (u32 *)prop->data;
+	len /= sizeof(u32) * 3;		/* 3 cells per GPIO record */
+	if (len > max_count) {
+		debug("FDT: %s: too many GPIOs / cells for "
+			"property '%s'\n", __func__, prop_name);
+		return -FDT_ERR_BADLAYOUT;
+	}
+
+	/* Read out the GPIO data from the cells */
+	for (i = 0; i < len; i++, cell += 3) {
+		gpio[i].gpio = fdt32_to_cpu(cell[1]);
+		gpio[i].flags = fdt32_to_cpu(cell[2]);
+		gpio[i].name = name;
+	}
+
+	return len;
+}
+
+int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
+		struct fdt_gpio_state *gpio)
+{
+	int err;
+
+	debug("%s: %s\n", __func__, prop_name);
+	gpio->gpio = FDT_GPIO_NONE;
+	err = fdtdec_decode_gpios(blob, node, prop_name, gpio, 1);
+	return err == 1 ? 0 : err;
+}
+
+int fdtdec_setup_gpio(struct fdt_gpio_state *gpio)
+{
+	/*
+	 * Return success if there is no GPIO defined. This is used for
+	 * optional GPIOs)
+	 */
+	if (!fdt_gpio_isvalid(gpio))
+		return 0;
+
+	if (gpio_request(gpio->gpio, gpio->name))
+		return -1;
+	if (gpio->flags & FDT_GPIO_OUTPUT) {
+		return gpio_direction_output(gpio->gpio,
+					     gpio->flags & FDT_GPIO_HIGH);
+	} else {
+		return gpio_direction_input(gpio->gpio);
+	}
+}
-- 
1.7.3.1

  parent reply	other threads:[~2011-12-03  2:11 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1322878300-5551-1-git-send-email-sjg@chromium.org>
2011-12-03  2:11 ` [PATCH v2 01/17] fdt: Tidy up a few fdtdec problems Simon Glass
2011-12-05 21:27   ` Stephen Warren
2011-12-05 21:40     ` Simon Glass
     [not found]       ` <CAPnjgZ0h39vB2H4MuCwVqb2Tgcr4==yN8Pj6a3s9dciyXPBu1A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-05 22:07         ` Stephen Warren
     [not found]           ` <4EDD4091.1030708-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2011-12-05 22:11             ` Simon Glass
2011-12-05 22:18               ` Scott Wood
2011-12-05 22:25                 ` Stephen Warren
2011-12-05 22:53                   ` Simon Glass
2011-12-03  2:11 ` [PATCH v2 06/17] arm: fdt: Add skeleton device tree file from kernel Simon Glass
     [not found] ` <1322878300-5551-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2011-12-03  2:11   ` [PATCH v2 02/17] fdt: Add functions to access phandles, arrays and bools Simon Glass
     [not found]     ` <1322878300-5551-3-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2011-12-05 21:59       ` Stephen Warren
     [not found]         ` <4EDD3EDE.4000609-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2011-12-05 22:07           ` Simon Glass
     [not found]             ` <CAPnjgZ30Bmxp4eGCgYss9GHt=SN5X5-sSHrPJpZFjVjprpa_Ag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-05 22:36               ` Stephen Warren
2011-12-05 23:56                 ` Simon Glass
2011-12-03  2:11   ` Simon Glass [this message]
     [not found]     ` <1322878300-5551-5-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2011-12-05 21:46       ` [PATCH v2 04/17] fdt: Add basic support for decoding GPIO definitions Stephen Warren
2011-12-05 21:56         ` Simon Glass
     [not found]           ` <CAPnjgZ3ARCTXVN2MKhfrdCCmmb21zbYdSq8AuQFPdoA=xFr7Mg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-05 22:22             ` Stephen Warren
     [not found]               ` <4EDD440C.80002-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2011-12-05 22:52                 ` Simon Glass
     [not found]                   ` <CAPnjgZ03+tfMhkqo4=uarcAf1E8hTfvSF_Y0=V70tuqP866QQQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-05 23:03                     ` Stephen Warren
     [not found]                       ` <4EDD4DA7.6070902-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2011-12-05 23:29                         ` Simon Glass
2011-12-06  3:55                   ` Mike Frysinger
2011-12-07  1:21                     ` Simon Glass
2011-12-03  2:11   ` [PATCH v2 05/17] arm: fdt: Ensure that an embedded fdt is word-aligned Simon Glass
2011-12-03  2:11   ` [PATCH v2 07/17] tegra: fdt: Add Tegra2x device tree file from kernel Simon Glass
2011-12-03  2:11   ` [PATCH v2 08/17] tegra: fdt: Add device tree file for Tegra2 Seaboard " Simon Glass
2011-12-03  2:11   ` [PATCH v2 09/17] tegra: usb: fdt: Add additional device tree definitions for USB ports Simon Glass
     [not found]     ` <1322878300-5551-10-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2011-12-05 23:25       ` Stephen Warren
2011-12-06  0:55         ` Simon Glass
     [not found]           ` <CAPnjgZ1J_cOS_E+ZiDoZUh79V7LUFzVkx-0nhbPTDwuGCGvDnQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-06 20:28             ` Stephen Warren
2011-12-06 21:09               ` Simon Glass
     [not found]                 ` <CAPnjgZ035Cen11ObFXjKUCqypvVKzkewhfY2F=yGH8=RWxVuSA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-07 23:36                   ` Stephen Warren
     [not found]                     ` <4EDFF898.1070708-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2011-12-08 21:10                       ` Simon Glass
     [not found]                         ` <CAPnjgZ1adfU652Z2ob30GTWZiCnah4WsJNfVrroWvtM5LXW93Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-12 18:13                           ` Stephen Warren
2011-12-12 18:53                             ` Simon Glass
2011-12-03  2:11   ` [PATCH v2 10/17] tegra: usb: fdt: Add USB definitions for Tegra2 Seaboard Simon Glass
     [not found]     ` <1322878300-5551-11-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2011-12-05 23:26       ` Stephen Warren
2011-12-03  2:11   ` [PATCH v2 17/17] tegra: fdt: Enable FDT support for Seaboard Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1322878300-5551-5-git-send-email-sjg@chromium.org \
    --to=sjg-f7+t8e8rja9g9huczpvpmw@public.gmane.org \
    --cc=albert.u.boot-LhW3hqR2+23R7s880joybQ@public.gmane.org \
    --cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
    --cc=twarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    --cc=u-boot-0aAXYlwwYIKGBzrmiIFOJg@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).