[U-Boot] [PATCH v3 33/54] dm: Add basic support for pin multiplexing (pinctrl)
Simon Glass
sjg at chromium.org
Tue Jun 23 23:38:55 CEST 2015
Add a uclass which permits pin multiplexing to be configured for a
particular function. It uses the concept of a peripheral ID to specify
the peripheral to adjust. Typically peripheral IDs are SPI0, SPI1,
MMC0, etc.
The uclass provides two methods:
- get_periph_id() - returns the peripheral ID for a particular driver model
device. This can be used to look up (say) an I2C device, and then find
its peripheral ID so that the pins for that device can be requested.
- request() - allows a particular function to be requested. This change
may impact multiple pins on the chip. For example, an I2C bus requires
two pins (clock and data) and the request() method will set up both pins.
This also allows GPIO drivers which sit under the 'pinctrl' device tree
node to be detected and used.
At some point this could be expanded to support a full interface with
support for the full device tree bindings. In that case the concept of
peripheral ID might not be needed.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
Changes in v3: None
Changes in v2: None
drivers/Kconfig | 2 ++
drivers/Makefile | 1 +
drivers/pinctrl/Kconfig | 19 +++++++++++
drivers/pinctrl/Makefile | 8 +++++
drivers/pinctrl/pinctrl-uclass.c | 51 +++++++++++++++++++++++++++
include/dm/uclass-id.h | 1 +
include/pinctrl.h | 74 ++++++++++++++++++++++++++++++++++++++++
scripts/Makefile.spl | 1 +
8 files changed, 157 insertions(+)
create mode 100644 drivers/pinctrl/Kconfig
create mode 100644 drivers/pinctrl/Makefile
create mode 100644 drivers/pinctrl/pinctrl-uclass.c
create mode 100644 include/pinctrl.h
diff --git a/drivers/Kconfig b/drivers/Kconfig
index ee942e2..17a61e4 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -32,6 +32,8 @@ source "drivers/spi/Kconfig"
source "drivers/gpio/Kconfig"
+source "drivers/pinctrl/Kconfig"
+
source "drivers/power/Kconfig"
source "drivers/hwmon/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index c090aba..b68c4ee 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LED) += led/
obj-y += misc/
obj-y += pcmcia/
obj-y += dfu/
+obj-$(CONFIG_PINCTRL) += pinctrl/
obj-y += rtc/
obj-y += sound/
obj-y += tpm/
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
new file mode 100644
index 0000000..e667361
--- /dev/null
+++ b/drivers/pinctrl/Kconfig
@@ -0,0 +1,19 @@
+config PINCTRL
+ bool "Pin multiplexing driver support"
+ help
+ Support pin multiplexing control in U-Boot. Most SoCs have their own
+ own multiplexing arrangement where a single pin can be used for
+ several functions. An SoC pinctrl driver allows the required
+ function to be selected for each pin. The driver is typically
+ controlled by the device tree.
+
+config SPL_PINCTRL_SUPPORT
+ bool "Enable pin multiplexing (pinctrl) support in SPL"
+ depends on PINCTRL
+ help
+ The pinctrl subsystem can add a substantial overhead to the SPL
+ image since it typically requires quite a few tables either in the
+ driver or in the device tree. If this is acceptable and you need
+ to adjust pin multiplexing in SPL in order to boot into U-Boot,
+ enable this option. You will need to enable device tree in SPL
+ for this to work.
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
new file mode 100644
index 0000000..6e63ee7
--- /dev/null
+++ b/drivers/pinctrl/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg at chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_PINCTRL) += pinctrl-uclass.o
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
new file mode 100644
index 0000000..82bd980
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg at chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <pinctrl.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+ if (!ops->request)
+ return -ENOSYS;
+
+ return ops->request(dev, func, flags);
+}
+
+int pinctrl_request_noflags(struct udevice *dev, int func)
+{
+ return pinctrl_request(dev, func, 0);
+}
+
+int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph)
+{
+ struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+ if (!ops->get_periph_id)
+ return -ENOSYS;
+
+ return ops->get_periph_id(dev, periph);
+}
+
+static int pinctrl_post_bind(struct udevice *dev)
+{
+ /* Scan the bus for devices */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+UCLASS_DRIVER(pinctrl) = {
+ .id = UCLASS_PINCTRL,
+ .name = "pinctrl",
+ .post_bind = pinctrl_post_bind,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index cba7c0a..14a1614 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -41,6 +41,7 @@ enum uclass_id {
UCLASS_PCH, /* x86 platform controller hub */
UCLASS_PCI, /* PCI bus */
UCLASS_PCI_GENERIC, /* Generic PCI bus device */
+ UCLASS_PINCTRL, /* Pin multiplexing control */
UCLASS_PMIC, /* PMIC I/O device */
UCLASS_REGULATOR, /* Regulator device */
UCLASS_RTC, /* Real time clock device */
diff --git a/include/pinctrl.h b/include/pinctrl.h
new file mode 100644
index 0000000..e7aca2e
--- /dev/null
+++ b/include/pinctrl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg at chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PINCTRL_H
+#define __PINCTRL_H
+
+struct pinctrl_ops {
+ /**
+ * request() - Request a particular pinctrl function
+ *
+ * This activates the selected function.
+ *
+ * @dev: Device to adjust (UCLASS_PINCTRL)
+ * @func: Function number (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+ int (*request)(struct udevice *dev, int func, int flags);
+
+ /**
+ * get_periph_id() - get the peripheral ID for a device
+ *
+ * This generally looks at the peripheral's device tree node to work
+ * out the peripheral ID. The return value is normally interpreted as
+ * enum periph_id. so long as this is defined by the platform (which it
+ * should be).
+ *
+ * @dev: Pinctrl device to use for decoding
+ * @periph: Device to check
+ * @return peripheral ID of @periph, or -ENOENT on error
+ */
+ int (*get_periph_id)(struct udevice *dev, struct udevice *periph);
+};
+
+#define pinctrl_get_ops(dev) ((struct pinctrl_ops *)(dev)->driver->ops)
+
+/**
+ * pinctrl_request() - Request a particular pinctrl function
+ *
+ * @dev: Device to check (UCLASS_PINCTRL)
+ * @func: Function number (driver-specific)
+ * @flags: Flags (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+int pinctrl_request(struct udevice *dev, int func, int flags);
+
+/**
+ * pinctrl_request_noflags() - Request a particular pinctrl function
+ *
+ * This is similar to pinctrl_request() but uses 0 for @flags.
+ *
+ * @dev: Device to check (UCLASS_PINCTRL)
+ * @func: Function number (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+int pinctrl_request_noflags(struct udevice *dev, int func);
+
+/**
+ * pinctrl_get_periph_id() - get the peripheral ID for a device
+ *
+ * This generally looks at the peripheral's device tree node to work out the
+ * peripheral ID. The return value is normally interpreted as enum periph_id.
+ * so long as this is defined by the platform (which it should be).
+ *
+ * @dev: Pinctrl device to use for decoding
+ * @periph: Device to check
+ * @return peripheral ID of @periph, or -ENOENT on error
+ */
+int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
+
+#endif
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 6b32618..24ca58b 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -77,6 +77,7 @@ libs-$(CONFIG_SPL_NET_SUPPORT) += net/
libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/
libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/
libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/
+libs-$(CONFIG_SPL_PINCTRL_SUPPORT) += drivers/pinctrl/
libs-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/
libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/
libs-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/
--
2.4.3.573.g4eafbef
More information about the U-Boot
mailing list