]> git.sur5r.net Git - u-boot/blobdiff - drivers/gpio/bcm2835_gpio.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / drivers / gpio / bcm2835_gpio.c
index 8b88d7956e72e62d54ef4e4cd63ac857a4586331..f4b67f1cf0aff523a19bcaf6bcf64833f0c1abca 100644 (file)
@@ -1,18 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2012 Vikram Narayananan
  * <vikram186@gmail.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <dm.h>
+#include <dm/pinctrl.h>
 #include <errno.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <fdtdec.h>
 
 struct bcm2835_gpios {
        struct bcm2835_gpio_regs *reg;
+       struct udevice *pinctrl;
 };
 
 static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio)
@@ -28,7 +30,7 @@ static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio)
        return 0;
 }
 
-static int bcm2835_gpio_direction_output(struct udevice *dev, unsigned gpio,
+static int bcm2835_gpio_direction_output(struct udevice *dev, unsigned int gpio,
                                         int value)
 {
        struct bcm2835_gpios *gpios = dev_get_priv(dev);
@@ -72,19 +74,12 @@ static int bcm2835_gpio_set_value(struct udevice *dev, unsigned gpio,
        return 0;
 }
 
-int bcm2835_gpio_get_func_id(struct udevice *dev, unsigned gpio)
-{
-       struct bcm2835_gpios *gpios = dev_get_priv(dev);
-       u32 val;
-
-       val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
-
-       return (val >> BCM2835_GPIO_FSEL_SHIFT(gpio) & BCM2835_GPIO_FSEL_MASK);
-}
-
 static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset)
 {
-       int funcid = bcm2835_gpio_get_func_id(dev, offset);
+       struct bcm2835_gpios *priv = dev_get_priv(dev);
+       int funcid;
+
+       funcid = pinctrl_get_gpio_mux(priv->pinctrl, 0, offset);
 
        switch (funcid) {
        case BCM2835_GPIO_OUTPUT:
@@ -96,7 +91,6 @@ static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset)
        }
 }
 
-
 static const struct dm_gpio_ops gpio_bcm2835_ops = {
        .direction_input        = bcm2835_gpio_direction_input,
        .direction_output       = bcm2835_gpio_direction_output,
@@ -115,13 +109,34 @@ static int bcm2835_gpio_probe(struct udevice *dev)
        uc_priv->gpio_count = BCM2835_GPIO_COUNT;
        gpios->reg = (struct bcm2835_gpio_regs *)plat->base;
 
+       /* We know we're spawned by the pinctrl driver */
+       gpios->pinctrl = dev->parent;
+
+       return 0;
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+static int bcm2835_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+       struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev);
+       fdt_addr_t addr;
+
+       addr = devfdt_get_addr(dev);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       plat->base = addr;
        return 0;
 }
+#endif
 
 U_BOOT_DRIVER(gpio_bcm2835) = {
        .name   = "gpio_bcm2835",
        .id     = UCLASS_GPIO,
+       .ofdata_to_platdata = of_match_ptr(bcm2835_gpio_ofdata_to_platdata),
+       .platdata_auto_alloc_size = sizeof(struct bcm2835_gpio_platdata),
        .ops    = &gpio_bcm2835_ops,
        .probe  = bcm2835_gpio_probe,
+       .flags  = DM_FLAG_PRE_RELOC,
        .priv_auto_alloc_size = sizeof(struct bcm2835_gpios),
 };