summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>2013-07-02 20:30:46 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-07-05 08:27:11 +0200
commit414ee7154ac3f105930d1a441b082eeb86c5b24a (patch)
treee59e8771b1ccfb94c8aee16a37c87aa3b3cbeed8 /drivers/gpio
parentf10119f27e4bd6c3f92036bfe5e8119c652f8aa3 (diff)
downloadbarebox-414ee7154ac3f105930d1a441b082eeb86c5b24a.tar.gz
barebox-414ee7154ac3f105930d1a441b082eeb86c5b24a.tar.xz
GPIO: add Marvell Orion/MVEBU SoC GPIO driver
This adds a DT only driver for the GPIO controller found on Marvell Orion/MVEBU SoCs (Armada 370/XP, Dove, Kirkwood, MV78x00, Orion5x). Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig8
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-orion.c132
3 files changed, 141 insertions, 0 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e976db4831..d5ac532f7d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -30,6 +30,14 @@ config GPIO_GENERIC_PLATFORM
config GPIO_IMX
def_bool ARCH_IMX
+config GPIO_ORION
+ bool "GPIO support for Marvell Orion/MVEBU SoCs"
+ depends on ARCH_MVEBU
+ help
+ Say yes here to add the driver for the GPIO controller
+ found on Marvell Orion and MVEBU SoCs (Armada 370/XP,
+ Dove, Kirkwood, MV78x00, Orion5x).
+
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index c1ec5bf772..adb668f4e5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_GPIO_BCM2835) += gpio-bcm2835.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_IMX) += gpio-imx.o
+obj-$(CONFIG_GPIO_ORION) += gpio-orion.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
diff --git a/drivers/gpio/gpio-orion.c b/drivers/gpio/gpio-orion.c
new file mode 100644
index 0000000000..855763ea66
--- /dev/null
+++ b/drivers/gpio/gpio-orion.c
@@ -0,0 +1,132 @@
+/*
+ * Marvell Orion/MVEBU SoC GPIO driver
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <gpio.h>
+#include <init.h>
+#include <io.h>
+#include <malloc.h>
+
+struct orion_gpio_regs {
+ u32 data_o;
+ u32 data_o_en;
+ u32 blink;
+ u32 data_i_pol;
+ u32 data_i;
+ u32 irq_cause;
+ u32 irq_mask;
+ u32 irq_level_mask;
+};
+
+struct orion_gpio_chip {
+ struct gpio_chip chip;
+ struct orion_gpio_regs __iomem *regs;
+};
+
+static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned off)
+{
+ struct orion_gpio_chip *gpio =
+ container_of(chip, struct orion_gpio_chip, chip);
+ writel(readl(&gpio->regs->data_o_en) | BIT(off),
+ &gpio->regs->data_o_en);
+ return 0;
+}
+
+static int orion_gpio_direction_output(
+ struct gpio_chip *chip, unsigned off, int value)
+{
+ struct orion_gpio_chip *gpio =
+ container_of(chip, struct orion_gpio_chip, chip);
+ gpio->chip.ops->set(chip, off, value);
+ writel(readl(&gpio->regs->data_o_en) & ~BIT(off),
+ &gpio->regs->data_o_en);
+ return 0;
+}
+
+static int orion_gpio_get_value(struct gpio_chip *chip, unsigned off)
+{
+ struct orion_gpio_chip *gpio =
+ container_of(chip, struct orion_gpio_chip, chip);
+ return (readl(&gpio->regs->data_i) & BIT(off)) ? 1 : 0;
+}
+
+static void orion_gpio_set_value(
+ struct gpio_chip *chip, unsigned off, int value)
+{
+ struct orion_gpio_chip *gpio =
+ container_of(chip, struct orion_gpio_chip, chip);
+ u32 val;
+
+ val = readl(&gpio->regs->data_o);
+ if (value)
+ val |= BIT(off);
+ else
+ val &= ~BIT(off);
+ writel(val, &gpio->regs->data_o);
+}
+
+static struct gpio_ops orion_gpio_ops = {
+ .direction_input = orion_gpio_direction_input,
+ .direction_output = orion_gpio_direction_output,
+ .get = orion_gpio_get_value,
+ .set = orion_gpio_set_value,
+};
+
+static int orion_gpio_probe(struct device_d *dev)
+{
+ struct orion_gpio_chip *gpio;
+
+ dev->id = of_alias_get_id(dev->device_node, "gpio");
+ if (dev->id < 0)
+ return dev->id;
+
+ gpio = xzalloc(sizeof(*gpio));
+ gpio->regs = dev_request_mem_region(dev, 0);
+ if (!gpio->regs) {
+ free(gpio);
+ return -EINVAL;
+ }
+ gpio->chip.dev = dev;
+ gpio->chip.ops = &orion_gpio_ops;
+ gpio->chip.base = dev->id * 32;
+ gpio->chip.ngpio = 32;
+ of_property_read_u32(dev->device_node, "ngpios", &gpio->chip.ngpio);
+
+ gpiochip_add(&gpio->chip);
+
+ dev_dbg(dev, "probed gpio%d with base %d\n", dev->id, gpio->chip.base);
+
+ return 0;
+}
+
+static struct of_device_id orion_gpio_dt_ids[] = {
+ { .compatible = "marvell,orion-gpio", },
+ { }
+};
+
+static struct driver_d orion_gpio_driver = {
+ .name = "orion-gpio",
+ .probe = orion_gpio_probe,
+ .of_compatible = DRV_OF_COMPAT(orion_gpio_dt_ids),
+};
+
+static int orion_gpio_init(void)
+{
+ return platform_driver_register(&orion_gpio_driver);
+}
+postcore_initcall(orion_gpio_init);