From a924501c08fe1267039169d66e739573107fcc0b Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 2 Oct 2019 21:19:41 -0500 Subject: [PATCH] drivers: mmio32: update to use new GPIO API As the mmio32 is more of a library than a proper driver, just implement the new port functions and have pin_interrupt_configure marked pretty much as not supported. Signed-off-by: Kumar Gala --- drivers/gpio/gpio_mmio32.c | 128 +++++++++++++++++++++++++---- include/drivers/gpio/gpio_mmio32.h | 1 - 2 files changed, 113 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpio_mmio32.c b/drivers/gpio/gpio_mmio32.c index 0becd9f331fd67..e89a89bd3e1335 100644 --- a/drivers/gpio/gpio_mmio32.c +++ b/drivers/gpio/gpio_mmio32.c @@ -35,27 +35,28 @@ static int gpio_mmio32_config(struct device *dev, int access_op, struct gpio_mmio32_context *context = dev->driver_data; const struct gpio_mmio32_config *config = context->config; - if (flags & GPIO_INT) { - return -ENOTSUP; - } - - if (access_op != GPIO_ACCESS_BY_PIN) { - return -ENOTSUP; - } - if ((config->mask & (1 << pin)) == 0) { return -EINVAL; /* Pin not in our validity mask */ } - if (flags & ~(GPIO_DIR_MASK | GPIO_POL_MASK)) { + if (flags & ~(GPIO_INPUT | GPIO_OUTPUT | + GPIO_OUTPUT_INIT_LOW | GPIO_OUTPUT_INIT_HIGH | + GPIO_ACTIVE_LOW)) { /* We ignore direction and fake polarity, rest is unsupported */ return -ENOTSUP; } - if ((flags & GPIO_POL_MASK) == GPIO_POL_INV) { - context->invert |= (1 << pin); - } else { - context->invert &= ~(1 << pin); + if ((flags & GPIO_OUTPUT) != 0) { + unsigned int key; + volatile u32_t *reg = config->reg; + + key = irq_lock(); + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + *reg = (*reg | (1 << pin)); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + *reg = (*reg & (config->mask & ~(1 << pin))); + } + irq_unlock(key); } return 0; @@ -68,7 +69,7 @@ static int gpio_mmio32_write(struct device *dev, int access_op, const struct gpio_mmio32_config *config = context->config; volatile u32_t *reg = config->reg; u32_t mask = config->mask; - u32_t invert = context->invert; + u32_t invert = context->common.invert; unsigned int key; if (access_op == GPIO_ACCESS_BY_PIN) { @@ -96,7 +97,7 @@ static int gpio_mmio32_read(struct device *dev, int access_op, const struct gpio_mmio32_config *config = context->config; u32_t bits; - bits = (*config->reg ^ context->invert) & config->mask; + bits = (*config->reg ^ context->common.invert) & config->mask; if (access_op == GPIO_ACCESS_BY_PIN) { *value = (bits >> pin) & 1; if ((config->mask & (1 << pin)) == 0) { @@ -109,10 +110,107 @@ static int gpio_mmio32_read(struct device *dev, int access_op, return 0; } +static int gpio_mmio32_port_get_raw(struct device *dev, u32_t *value) +{ + struct gpio_mmio32_context *context = dev->driver_data; + const struct gpio_mmio32_config *config = context->config; + + *value = *config->reg & config->mask; + + return 0; +} + +static int gpio_mmio32_port_set_masked_raw(struct device *dev, u32_t mask, + u32_t value) +{ + struct gpio_mmio32_context *context = dev->driver_data; + const struct gpio_mmio32_config *config = context->config; + volatile u32_t *reg = config->reg; + unsigned int key; + + mask &= config->mask; + value &= mask; + + /* Update pin state atomically */ + key = irq_lock(); + *reg = (*reg & ~mask) | value; + irq_unlock(key); + + return 0; +} + +static int gpio_mmio32_port_set_bits_raw(struct device *dev, u32_t mask) +{ + struct gpio_mmio32_context *context = dev->driver_data; + const struct gpio_mmio32_config *config = context->config; + volatile u32_t *reg = config->reg; + unsigned int key; + + mask &= config->mask; + + /* Update pin state atomically */ + key = irq_lock(); + *reg = (*reg | mask); + irq_unlock(key); + + return 0; +} + +static int gpio_mmio32_port_clear_bits_raw(struct device *dev, u32_t mask) +{ + struct gpio_mmio32_context *context = dev->driver_data; + const struct gpio_mmio32_config *config = context->config; + volatile u32_t *reg = config->reg; + unsigned int key; + + mask &= config->mask; + + /* Update pin state atomically */ + key = irq_lock(); + *reg = (*reg & ~mask); + irq_unlock(key); + + return 0; +} + +static int gpio_mmio32_port_toggle_bits(struct device *dev, u32_t mask) +{ + struct gpio_mmio32_context *context = dev->driver_data; + const struct gpio_mmio32_config *config = context->config; + volatile u32_t *reg = config->reg; + unsigned int key; + + mask &= config->mask; + + /* Update pin state atomically */ + key = irq_lock(); + *reg = (*reg ^ mask); + irq_unlock(key); + + return 0; +} + +static int gpio_mmio32_pin_interrupt_configure(struct device *dev, + unsigned int pin, enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + if (mode != GPIO_INT_MODE_DISABLED) { + return -ENOTSUP; + } + + return 0; +} + static const struct gpio_driver_api gpio_mmio32_api = { .config = gpio_mmio32_config, .write = gpio_mmio32_write, .read = gpio_mmio32_read, + .port_get_raw = gpio_mmio32_port_get_raw, + .port_set_masked_raw = gpio_mmio32_port_set_masked_raw, + .port_set_bits_raw = gpio_mmio32_port_set_bits_raw, + .port_clear_bits_raw = gpio_mmio32_port_clear_bits_raw, + .port_toggle_bits = gpio_mmio32_port_toggle_bits, + .pin_interrupt_configure = gpio_mmio32_pin_interrupt_configure, }; int gpio_mmio32_init(struct device *dev) diff --git a/include/drivers/gpio/gpio_mmio32.h b/include/drivers/gpio/gpio_mmio32.h index 9392ab00626b17..2a5a6d8f62cbaf 100644 --- a/include/drivers/gpio/gpio_mmio32.h +++ b/include/drivers/gpio/gpio_mmio32.h @@ -20,7 +20,6 @@ struct gpio_mmio32_context { /* gpio_driver_data needs to be first */ struct gpio_driver_data common; const struct gpio_mmio32_config *config; - u32_t invert; /* Mask of 'reg' bits that should be inverted */ }; int gpio_mmio32_init(struct device *dev);