Skip to content

Commit

Permalink
drivers: stellaris: update to use new GPIO API
Browse files Browse the repository at this point in the history
Update driver code and board files to use new GPIO configuration flags
such as GPIO_ACTIVE_LOW. Also add implementation of new port_* driver
API as well as gpio_pin_interrupt_configure function.

Signed-off-by: Kumar Gala <[email protected]>
  • Loading branch information
galak committed Oct 26, 2019
1 parent f515f53 commit 41c0217
Showing 1 changed file with 118 additions and 34 deletions.
152 changes: 118 additions & 34 deletions drivers/gpio/gpio_stellaris.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ struct gpio_stellaris_runtime {
#define GPIO_RW_ADDR(base, offset, p) \
(GPIO_REG_ADDR(base, offset) | (1 << (p + 2)))

#define GPIO_RW_MASK_ADDR(base, offset, mask) \
(GPIO_REG_ADDR(base, offset) | (mask << 2))

enum gpio_regs {
GPIO_DATA_OFFSET = 0x000,
GPIO_DIR_OFFSET = 0x400,
Expand Down Expand Up @@ -80,9 +83,12 @@ static int gpio_stellaris_configure(struct device *dev, int access_op,
u32_t base = cfg->base;
u32_t port_map = cfg->port_map;

/* Check for an invalid pin configuration */
if ((flags & GPIO_INT) && (flags & GPIO_DIR_OUT)) {
return -EINVAL;
if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
return -ENOTSUP;
}

if ((flags & GPIO_SINGLE_ENDED) != 0) {
return -ENOTSUP;
}

/* Supports access by pin now,you can add access by port when needed */
Expand All @@ -95,42 +101,27 @@ static int gpio_stellaris_configure(struct device *dev, int access_op,
return -EINVAL;
}

/* Pin digital enable */
sys_set_bit(GPIO_REG_ADDR(base, GPIO_DEN_OFFSET), pin);
if ((flags & GPIO_OUTPUT) != 0) {
mm_reg_t mask_addr;

/* Input-0,output-1 */
if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) {
mask_addr = GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, BIT(pin));
if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
sys_write32(BIT(pin), mask_addr);
} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
sys_write32(0, mask_addr);
}
sys_set_bit(GPIO_REG_ADDR(base, GPIO_DIR_OFFSET), pin);
/* Pin digital enable */
sys_set_bit(GPIO_REG_ADDR(base, GPIO_DEN_OFFSET), pin);
} else if ((flags & GPIO_INPUT) != 0) {
sys_clear_bit(GPIO_REG_ADDR(base, GPIO_DIR_OFFSET), pin);
/* Pin digital enable */
sys_set_bit(GPIO_REG_ADDR(base, GPIO_DEN_OFFSET), pin);
} else {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_DIR_OFFSET), pin);
/* Pin digital disable */
sys_clear_bit(GPIO_REG_ADDR(base, GPIO_DEN_OFFSET), pin);
}

/* Check if GPIO port needs interrupt support */
if (flags & GPIO_INT) {

/* GPIO interrupt edge trigger enable or level trigger enable */
if (flags & GPIO_INT_EDGE) {
sys_clear_bit(GPIO_REG_ADDR(base, GPIO_IS_OFFSET), pin);
} else {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IS_OFFSET), pin);
}

/* GPIO interrupt both edge sense */
if (flags & GPIO_INT_DOUBLE_EDGE) {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IBE_OFFSET), pin);
}

/*
* GPIO interrupt rising edge & high level enable or
* falling edge & low level enable
*/
if (flags & GPIO_INT_ACTIVE_HIGH) {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IEV_OFFSET), pin);
} else {
sys_clear_bit(GPIO_REG_ADDR(base,
GPIO_IEV_OFFSET), pin);
}
}
return 0;
}

Expand Down Expand Up @@ -172,6 +163,93 @@ static int gpio_stellaris_read(struct device *dev,
return 0;
}

static int gpio_stellaris_port_get_raw(struct device *dev, u32_t *value)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
u32_t base = cfg->base;

*value = sys_read32(GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, 0xff));

return 0;
}

static int gpio_stellaris_port_set_masked_raw(struct device *dev, u32_t mask,
u32_t value)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
u32_t base = cfg->base;

sys_write32(value, GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, mask));

return 0;
}

static int gpio_stellaris_port_set_bits_raw(struct device *dev, u32_t mask)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
u32_t base = cfg->base;

sys_write32(mask, GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, mask));

return 0;
}

static int gpio_stellaris_port_clear_bits_raw(struct device *dev, u32_t mask)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
u32_t base = cfg->base;

sys_write32(0, GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, mask));

return 0;
}

static int gpio_stellaris_port_toggle_bits(struct device *dev, u32_t mask)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
u32_t base = cfg->base;
u32_t value;

value = sys_read32(GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, 0xff));
value ^= mask;
sys_write32(value, GPIO_RW_MASK_ADDR(base, GPIO_DATA_OFFSET, 0xff));

return 0;
}

static int gpio_stellaris_pin_interrupt_configure(struct device *dev,
unsigned int pin, enum gpio_int_mode mode,
enum gpio_int_trig trig)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
u32_t base = cfg->base;

/* Check if GPIO port needs interrupt support */
if (mode == GPIO_INT_MODE_DISABLED) {
/* Set the mask to disable the interrupt */
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IM_OFFSET), pin);
} else {
if (mode == GPIO_INT_MODE_EDGE) {
sys_clear_bit(GPIO_REG_ADDR(base, GPIO_IS_OFFSET), pin);
} else {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IS_OFFSET), pin);
}

if (trig == GPIO_INT_TRIG_BOTH) {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IBE_OFFSET), pin);
} else if (trig == GPIO_INT_TRIG_HIGH) {
sys_set_bit(GPIO_REG_ADDR(base, GPIO_IEV_OFFSET), pin);
} else {
sys_clear_bit(GPIO_REG_ADDR(base,
GPIO_IEV_OFFSET), pin);
}
/* Clear the Mask to enable the interrupt */
sys_clear_bit(GPIO_REG_ADDR(base, GPIO_IM_OFFSET), pin);
}

return 0;
}

static int gpio_stellaris_init(struct device *dev)
{
const struct gpio_stellaris_config *cfg = DEV_CFG(dev);
Expand Down Expand Up @@ -225,6 +303,12 @@ static const struct gpio_driver_api gpio_stellaris_driver_api = {
.config = gpio_stellaris_configure,
.write = gpio_stellaris_write,
.read = gpio_stellaris_read,
.port_get_raw = gpio_stellaris_port_get_raw,
.port_set_masked_raw = gpio_stellaris_port_set_masked_raw,
.port_set_bits_raw = gpio_stellaris_port_set_bits_raw,
.port_clear_bits_raw = gpio_stellaris_port_clear_bits_raw,
.port_toggle_bits = gpio_stellaris_port_toggle_bits,
.pin_interrupt_configure = gpio_stellaris_pin_interrupt_configure,
.manage_callback = gpio_stellaris_manage_callback,
.enable_callback = gpio_stellaris_enable_callback,
.disable_callback = gpio_stellaris_disable_callback,
Expand Down

0 comments on commit 41c0217

Please sign in to comment.