Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TOPIC-GPIO] drivers: mmio32: update to use new GPIO API #20028

Merged
merged 1 commit into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 113 additions & 15 deletions drivers/gpio/gpio_mmio32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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)
Expand Down
1 change: 0 additions & 1 deletion include/drivers/gpio/gpio_mmio32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down