Add driver model support to this driver, while retaining support for the
legacy system. Driver model GPIO support is enabled with CONFIG_DM_GPIO
as usual.
Since gpio_is_valid() no longer exists, we can use the -EINVAL error
returned from gpio_request().
Signed-off-by: Simon Glass s...@chromium.org
---
arch/arm/include/asm/omap_gpio.h | 19 +++-
drivers/gpio/omap_gpio.c | 221 +++
drivers/mmc/omap_hsmmc.c | 15 ++-
3 files changed, 248 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h
index 5d25d04..839af54 100644
--- a/arch/arm/include/asm/omap_gpio.h
+++ b/arch/arm/include/asm/omap_gpio.h
@@ -23,6 +23,21 @@
#include asm/arch/cpu.h
+enum gpio_method {
+ METHOD_GPIO_24XX= 4,
+};
+
+#ifdef CONFIG_DM_GPIO
+
+/* Information about a GPIO bank */
+struct omap_gpio_platdata {
+ int bank_index;
+ ulong base; /* address of registers in physical memory */
+ enum gpio_method method;
+};
+
+#else
+
struct gpio_bank {
void *base;
int method;
@@ -30,8 +45,6 @@ struct gpio_bank {
extern const struct gpio_bank *const omap_gpio_bank;
-#define METHOD_GPIO_24XX 4
-
/**
* Check if gpio is valid.
*
@@ -39,4 +52,6 @@ extern const struct gpio_bank *const omap_gpio_bank;
* @return 1 if ok, 0 on error
*/
int gpio_is_valid(int gpio);
+#endif
+
#endif /* _GPIO_H_ */
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index d2d2640..a4651bc 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -19,6 +19,7 @@
* Written by Juha Yrjölä juha.yrj...@nokia.com
*/
#include common.h
+#include dm.h
#include asm/gpio.h
#include asm/io.h
#include asm/errno.h
@@ -26,6 +27,20 @@
#define OMAP_GPIO_DIR_OUT 0
#define OMAP_GPIO_DIR_IN 1
+#ifdef CONFIG_DM_GPIO
+
+#define GPIO_NAME_SIZE 20
+#define GPIO_PER_BANK 32
+
+struct gpio_bank {
+ char label[GPIO_PER_BANK][GPIO_NAME_SIZE];
+ /* TODO(s...@chromium.org): Can we use a struct here? */
+ void *base; /* address of registers in physical memory */
+ enum gpio_method method;
+};
+
+#endif
+
static inline int get_gpio_index(int gpio)
{
return gpio 0x1f;
@@ -130,6 +145,8 @@ static int _get_gpio_value(const struct gpio_bank *bank,
int gpio)
return (__raw_readl(reg) (1 gpio)) != 0;
}
+#ifndef CONFIG_DM_GPIO
+
static inline const struct gpio_bank *get_gpio_bank(int gpio)
{
return omap_gpio_bank[gpio 5];
@@ -226,3 +243,207 @@ int gpio_free(unsigned gpio)
{
return 0;
}
+
+#else /* new driver model interface CONFIG_DM_GPIO */
+
+/**
+ * gpio_is_requested() - check if a GPIO has been requested
+ *
+ * @bank: Bank to check
+ * @offset:GPIO offset within bank to check
+ * @return true if marked as requested, false if not
+ */
+static inline bool gpio_is_requested(struct gpio_bank *bank, int offset)
+{
+ return *bank-label[offset] != '\0';
+}
+
+static int omap_gpio_is_output(struct gpio_bank *bank, int offset)
+{
+ return _get_gpio_direction(bank, offset) == OMAP_GPIO_DIR_OUT;
+}
+
+static int check_requested(struct udevice *dev, unsigned offset,
+ const char *func)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+ struct gpio_dev_priv *uc_priv = dev-uclass_priv;
+
+ if (!gpio_is_requested(bank, offset)) {
+ printf(omap_gpio: %s: error: gpio %s%d not requested\n,
+ func, uc_priv-bank_name, offset);
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+/* set GPIO pin 'gpio' as an input */
+static int omap_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+ int ret;
+
+ ret = check_requested(dev, offset, __func__);
+ if (ret)
+ return ret;
+
+ /* Configure GPIO direction as input. */
+ _set_gpio_direction(bank, offset, 1);
+
+ return 0;
+}
+
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+static int omap_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+ int ret;
+
+ ret = check_requested(dev, offset, __func__);
+ if (ret)
+ return ret;
+
+ _set_gpio_dataout(bank, offset, value);
+ _set_gpio_direction(bank, offset, 0);
+
+ return 0;
+}
+
+/* read GPIO IN value of pin 'gpio' */
+static int omap_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+ struct gpio_bank *bank = dev_get_priv(dev);
+ int ret;
+
+ ret = check_requested(dev, offset, __func__);
+ if (ret)
+ return ret;
+
+ return _get_gpio_value(bank, offset);
+}
+
+/* write GPIO OUT value to pin 'gpio' */
+static int omap_gpio_set_value(struct udevice