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 <kumar.gala@linaro.org>
This commit is contained in:
Kumar Gala 2019-10-02 21:19:41 -05:00 committed by Carles Cufí
commit 8f4da10356
2 changed files with 113 additions and 16 deletions

View file

@ -35,27 +35,28 @@ static int gpio_mmio32_config(struct device *dev, int access_op,
struct gpio_mmio32_context *context = dev->driver_data; struct gpio_mmio32_context *context = dev->driver_data;
const struct gpio_mmio32_config *config = context->config; 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) { if ((config->mask & (1 << pin)) == 0) {
return -EINVAL; /* Pin not in our validity mask */ 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 */ /* We ignore direction and fake polarity, rest is unsupported */
return -ENOTSUP; return -ENOTSUP;
} }
if ((flags & GPIO_POL_MASK) == GPIO_POL_INV) { if ((flags & GPIO_OUTPUT) != 0) {
context->invert |= (1 << pin); unsigned int key;
} else { volatile u32_t *reg = config->reg;
context->invert &= ~(1 << pin);
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; 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; const struct gpio_mmio32_config *config = context->config;
volatile u32_t *reg = config->reg; volatile u32_t *reg = config->reg;
u32_t mask = config->mask; u32_t mask = config->mask;
u32_t invert = context->invert; u32_t invert = context->common.invert;
unsigned int key; unsigned int key;
if (access_op == GPIO_ACCESS_BY_PIN) { 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; const struct gpio_mmio32_config *config = context->config;
u32_t bits; 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) { if (access_op == GPIO_ACCESS_BY_PIN) {
*value = (bits >> pin) & 1; *value = (bits >> pin) & 1;
if ((config->mask & (1 << pin)) == 0) { if ((config->mask & (1 << pin)) == 0) {
@ -109,10 +110,107 @@ static int gpio_mmio32_read(struct device *dev, int access_op,
return 0; 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 = { static const struct gpio_driver_api gpio_mmio32_api = {
.config = gpio_mmio32_config, .config = gpio_mmio32_config,
.write = gpio_mmio32_write, .write = gpio_mmio32_write,
.read = gpio_mmio32_read, .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) int gpio_mmio32_init(struct device *dev)

View file

@ -20,7 +20,6 @@ struct gpio_mmio32_context {
/* gpio_driver_data needs to be first */ /* gpio_driver_data needs to be first */
struct gpio_driver_data common; struct gpio_driver_data common;
const struct gpio_mmio32_config *config; const struct gpio_mmio32_config *config;
u32_t invert; /* Mask of 'reg' bits that should be inverted */
}; };
int gpio_mmio32_init(struct device *dev); int gpio_mmio32_init(struct device *dev);