gpio: RV32M1: introduce gpio driver / DT bindings
Add a GPIO driver. Signed-off-by: Michael Scott <mike@foundries.io>
This commit is contained in:
parent
cdb1714c6c
commit
0f314ebdda
7 changed files with 570 additions and 0 deletions
|
@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SAM gpio_sam.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GPIO_SX1509B gpio_sx1509b.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_INTEL_APL gpio_intel_apl.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_STELLARIS gpio_stellaris.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_RV32M1 gpio_rv32m1.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_SHELL gpio_shell.c)
|
||||
|
||||
|
|
|
@ -72,4 +72,6 @@ source "drivers/gpio/Kconfig.intel"
|
|||
|
||||
source "drivers/gpio/Kconfig.stellaris"
|
||||
|
||||
source "drivers/gpio/Kconfig.rv32m1"
|
||||
|
||||
endif # GPIO
|
||||
|
|
47
drivers/gpio/Kconfig.rv32m1
Normal file
47
drivers/gpio/Kconfig.rv32m1
Normal file
|
@ -0,0 +1,47 @@
|
|||
# Kconfig.rv32m1 - RV32M1 GPIO configuration options
|
||||
#
|
||||
# Copyright (c) 2018 Foundries.io
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
menuconfig GPIO_RV32M1
|
||||
bool "RV32M1 GPIO driver"
|
||||
depends on GPIO && SOC_OPENISA_RV32M1_RISCV32
|
||||
select HAS_DTS_GPIO
|
||||
help
|
||||
Enable the RV32M1 GPIO driver.
|
||||
|
||||
if GPIO_RV32M1
|
||||
|
||||
config GPIO_RV32M1_PORTA
|
||||
bool "Port A"
|
||||
depends on PINMUX_RV32M1_PORTA
|
||||
help
|
||||
Enable Port A.
|
||||
|
||||
config GPIO_RV32M1_PORTB
|
||||
bool "Port B"
|
||||
depends on RV32M1_INTMUX && PINMUX_RV32M1_PORTB
|
||||
help
|
||||
Enable Port B.
|
||||
|
||||
config GPIO_RV32M1_PORTC
|
||||
bool "Port C"
|
||||
depends on RV32M1_INTMUX && PINMUX_RV32M1_PORTC
|
||||
help
|
||||
Enable Port C.
|
||||
|
||||
config GPIO_RV32M1_PORTD
|
||||
bool "Port D"
|
||||
depends on RV32M1_INTMUX && PINMUX_RV32M1_PORTD
|
||||
help
|
||||
Enable Port D.
|
||||
|
||||
config GPIO_RV32M1_PORTE
|
||||
bool "Port E"
|
||||
depends on RV32M1_INTMUX && PINMUX_RV32M1_PORTE
|
||||
help
|
||||
Enable Port E.
|
||||
|
||||
endif # GPIO_RV32M1
|
419
drivers/gpio/gpio_rv32m1.c
Normal file
419
drivers/gpio/gpio_rv32m1.c
Normal file
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright (c) 2017, NXP
|
||||
* Copyright (c) 2018 Foundries.io
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <device.h>
|
||||
#include <gpio.h>
|
||||
#include <soc.h>
|
||||
#include <fsl_common.h>
|
||||
#include <fsl_port.h>
|
||||
|
||||
#include "gpio_utils.h"
|
||||
|
||||
struct gpio_rv32m1_config {
|
||||
GPIO_Type *gpio_base;
|
||||
PORT_Type *port_base;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct gpio_rv32m1_data {
|
||||
/* port ISR callback routine address */
|
||||
sys_slist_t callbacks;
|
||||
/* pin callback routine enable flags, by pin number */
|
||||
u32_t pin_callback_enables;
|
||||
};
|
||||
|
||||
static int gpio_rv32m1_configure(struct device *dev,
|
||||
int access_op, u32_t pin, int flags)
|
||||
{
|
||||
const struct gpio_rv32m1_config *config = dev->config->config_info;
|
||||
GPIO_Type *gpio_base = config->gpio_base;
|
||||
PORT_Type *port_base = config->port_base;
|
||||
port_interrupt_t port_interrupt = 0;
|
||||
u32_t mask = 0;
|
||||
u32_t pcr = 0;
|
||||
u8_t i;
|
||||
|
||||
/* Check for an invalid pin configuration */
|
||||
if ((flags & GPIO_INT) && (flags & GPIO_DIR_OUT)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if GPIO port supports interrupts */
|
||||
if ((flags & GPIO_INT) && ((config->flags & GPIO_INT) == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The flags contain options that require touching registers in the
|
||||
* GPIO module and the corresponding PORT module.
|
||||
*
|
||||
* Start with the GPIO module and set up the pin direction register.
|
||||
* 0 - pin is input, 1 - pin is output
|
||||
*/
|
||||
|
||||
if (access_op == GPIO_ACCESS_BY_PIN) {
|
||||
if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) {
|
||||
gpio_base->PDDR &= ~BIT(pin);
|
||||
} else { /* GPIO_DIR_OUT */
|
||||
gpio_base->PDDR |= BIT(pin);
|
||||
}
|
||||
} else { /* GPIO_ACCESS_BY_PORT */
|
||||
if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) {
|
||||
gpio_base->PDDR = 0x0;
|
||||
} else { /* GPIO_DIR_OUT */
|
||||
gpio_base->PDDR = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now do the PORT module. Figure out the pullup/pulldown
|
||||
* configuration, but don't write it to the PCR register yet.
|
||||
*/
|
||||
mask |= PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
|
||||
|
||||
if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) {
|
||||
/* Enable the pull and select the pullup resistor. */
|
||||
pcr |= PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
|
||||
|
||||
} else if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) {
|
||||
/* Enable the pull and select the pulldown resistor (deselect
|
||||
* the pullup resistor.
|
||||
*/
|
||||
pcr |= PORT_PCR_PE_MASK;
|
||||
}
|
||||
|
||||
/* Still in the PORT module. Figure out the interrupt configuration,
|
||||
* but don't write it to the PCR register yet.
|
||||
*/
|
||||
mask |= PORT_PCR_IRQC_MASK;
|
||||
|
||||
if (flags & GPIO_INT) {
|
||||
if (flags & GPIO_INT_EDGE) {
|
||||
if (flags & GPIO_INT_ACTIVE_HIGH) {
|
||||
port_interrupt = kPORT_InterruptRisingEdge;
|
||||
} else if (flags & GPIO_INT_DOUBLE_EDGE) {
|
||||
port_interrupt = kPORT_InterruptEitherEdge;
|
||||
} else {
|
||||
port_interrupt = kPORT_InterruptFallingEdge;
|
||||
}
|
||||
} else { /* GPIO_INT_LEVEL */
|
||||
if (flags & GPIO_INT_ACTIVE_HIGH) {
|
||||
port_interrupt = kPORT_InterruptLogicOne;
|
||||
} else {
|
||||
port_interrupt = kPORT_InterruptLogicZero;
|
||||
}
|
||||
}
|
||||
pcr |= PORT_PCR_IRQC(port_interrupt);
|
||||
}
|
||||
|
||||
mask |= PORT_PCR_MUX_MASK;
|
||||
|
||||
/* Now we can write the PORT PCR register(s). If accessing by pin, we
|
||||
* only need to write one PCR register. Otherwise, write all the PCR
|
||||
* registers in the PORT module (one for each pin).
|
||||
*/
|
||||
if (access_op == GPIO_ACCESS_BY_PIN) {
|
||||
port_base->PCR[pin] = (port_base->PCR[pin] & ~mask) | pcr |
|
||||
PORT_PCR_MUX(kPORT_MuxAsGpio);
|
||||
} else { /* GPIO_ACCESS_BY_PORT */
|
||||
for (i = 0; i < ARRAY_SIZE(port_base->PCR); i++) {
|
||||
port_base->PCR[i] = (port_base->PCR[pin] & ~mask) | pcr
|
||||
| PORT_PCR_MUX(kPORT_MuxAsGpio);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rv32m1_write(struct device *dev,
|
||||
int access_op, u32_t pin, u32_t value)
|
||||
{
|
||||
const struct gpio_rv32m1_config *config = dev->config->config_info;
|
||||
GPIO_Type *gpio_base = config->gpio_base;
|
||||
|
||||
if (access_op == GPIO_ACCESS_BY_PIN) {
|
||||
if (value) {
|
||||
/* Set the data output for the corresponding pin.
|
||||
* Writing zeros to the other bits leaves the data
|
||||
* output unchanged for the other pins.
|
||||
*/
|
||||
gpio_base->PSOR = BIT(pin);
|
||||
} else {
|
||||
/* Clear the data output for the corresponding pin.
|
||||
* Writing zeros to the other bits leaves the data
|
||||
* output unchanged for the other pins.
|
||||
*/
|
||||
gpio_base->PCOR = BIT(pin);
|
||||
}
|
||||
} else { /* GPIO_ACCESS_BY_PORT */
|
||||
/* Write the data output for all the pins */
|
||||
gpio_base->PDOR = value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rv32m1_read(struct device *dev,
|
||||
int access_op, u32_t pin, u32_t *value)
|
||||
{
|
||||
const struct gpio_rv32m1_config *config = dev->config->config_info;
|
||||
GPIO_Type *gpio_base = config->gpio_base;
|
||||
|
||||
*value = gpio_base->PDIR;
|
||||
|
||||
if (access_op == GPIO_ACCESS_BY_PIN) {
|
||||
*value = (*value & BIT(pin)) >> pin;
|
||||
}
|
||||
|
||||
/* nothing more to do for GPIO_ACCESS_BY_PORT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rv32m1_manage_callback(struct device *dev,
|
||||
struct gpio_callback *callback, bool set)
|
||||
{
|
||||
struct gpio_rv32m1_data *data = dev->driver_data;
|
||||
|
||||
_gpio_manage_callback(&data->callbacks, callback, set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rv32m1_enable_callback(struct device *dev,
|
||||
int access_op, u32_t pin)
|
||||
{
|
||||
struct gpio_rv32m1_data *data = dev->driver_data;
|
||||
|
||||
if (access_op == GPIO_ACCESS_BY_PIN) {
|
||||
data->pin_callback_enables |= BIT(pin);
|
||||
} else {
|
||||
data->pin_callback_enables = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rv32m1_disable_callback(struct device *dev,
|
||||
int access_op, u32_t pin)
|
||||
{
|
||||
struct gpio_rv32m1_data *data = dev->driver_data;
|
||||
|
||||
if (access_op == GPIO_ACCESS_BY_PIN) {
|
||||
data->pin_callback_enables &= ~BIT(pin);
|
||||
} else {
|
||||
data->pin_callback_enables = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gpio_rv32m1_port_isr(void *arg)
|
||||
{
|
||||
struct device *dev = (struct device *)arg;
|
||||
const struct gpio_rv32m1_config *config = dev->config->config_info;
|
||||
struct gpio_rv32m1_data *data = dev->driver_data;
|
||||
u32_t enabled_int, int_status;
|
||||
|
||||
int_status = config->port_base->ISFR;
|
||||
enabled_int = int_status & data->pin_callback_enables;
|
||||
|
||||
_gpio_fire_callbacks(&data->callbacks, dev, enabled_int);
|
||||
|
||||
/* Clear the port interrupts */
|
||||
config->port_base->ISFR = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
|
||||
static const struct gpio_driver_api gpio_rv32m1_driver_api = {
|
||||
.config = gpio_rv32m1_configure,
|
||||
.write = gpio_rv32m1_write,
|
||||
.read = gpio_rv32m1_read,
|
||||
.manage_callback = gpio_rv32m1_manage_callback,
|
||||
.enable_callback = gpio_rv32m1_enable_callback,
|
||||
.disable_callback = gpio_rv32m1_disable_callback,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_GPIO_RV32M1_PORTA
|
||||
static int gpio_rv32m1_porta_init(struct device *dev);
|
||||
|
||||
static const struct gpio_rv32m1_config gpio_rv32m1_porta_config = {
|
||||
.gpio_base = (GPIO_Type *) GPIO_A_BASE_ADDRESS,
|
||||
.port_base = PORTA,
|
||||
#ifdef GPIO_A_IRQ
|
||||
.flags = GPIO_INT,
|
||||
#else
|
||||
.flags = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct gpio_rv32m1_data gpio_rv32m1_porta_data;
|
||||
|
||||
DEVICE_AND_API_INIT(gpio_rv32m1_porta, GPIO_A_LABEL,
|
||||
gpio_rv32m1_porta_init,
|
||||
&gpio_rv32m1_porta_data, &gpio_rv32m1_porta_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&gpio_rv32m1_driver_api);
|
||||
|
||||
static int gpio_rv32m1_porta_init(struct device *dev)
|
||||
{
|
||||
#ifdef GPIO_A_IRQ
|
||||
IRQ_CONNECT(GPIO_A_IRQ, GPIO_A_IRQ_PRIORITY,
|
||||
gpio_rv32m1_port_isr, DEVICE_GET(gpio_rv32m1_porta), 0);
|
||||
|
||||
irq_enable(GPIO_A_IRQ);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_GPIO_RV32M1_PORTA */
|
||||
|
||||
#ifdef CONFIG_GPIO_RV32M1_PORTB
|
||||
static int gpio_rv32m1_portb_init(struct device *dev);
|
||||
|
||||
static const struct gpio_rv32m1_config gpio_rv32m1_portb_config = {
|
||||
.gpio_base = (GPIO_Type *) GPIO_B_BASE_ADDRESS,
|
||||
.port_base = PORTB,
|
||||
#ifdef GPIO_B_IRQ
|
||||
.flags = GPIO_INT,
|
||||
#else
|
||||
.flags = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct gpio_rv32m1_data gpio_rv32m1_portb_data;
|
||||
|
||||
DEVICE_AND_API_INIT(gpio_rv32m1_portb, GPIO_B_LABEL,
|
||||
gpio_rv32m1_portb_init,
|
||||
&gpio_rv32m1_portb_data, &gpio_rv32m1_portb_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&gpio_rv32m1_driver_api);
|
||||
|
||||
static int gpio_rv32m1_portb_init(struct device *dev)
|
||||
{
|
||||
#ifdef GPIO_B_IRQ
|
||||
IRQ_CONNECT(GPIO_B_IRQ, GPIO_B_IRQ_PRIORITY,
|
||||
gpio_rv32m1_port_isr, DEVICE_GET(gpio_rv32m1_portb), 0);
|
||||
|
||||
irq_enable(GPIO_B_IRQ);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_GPIO_RV32M1_PORTB */
|
||||
|
||||
#ifdef CONFIG_GPIO_RV32M1_PORTC
|
||||
static int gpio_rv32m1_portc_init(struct device *dev);
|
||||
|
||||
static const struct gpio_rv32m1_config gpio_rv32m1_portc_config = {
|
||||
.gpio_base = (GPIO_Type *) GPIO_C_BASE_ADDRESS,
|
||||
.port_base = PORTC,
|
||||
#ifdef GPIO_C_IRQ
|
||||
.flags = GPIO_INT,
|
||||
#else
|
||||
.flags = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct gpio_rv32m1_data gpio_rv32m1_portc_data;
|
||||
|
||||
DEVICE_AND_API_INIT(gpio_rv32m1_portc, GPIO_C_LABEL,
|
||||
gpio_rv32m1_portc_init,
|
||||
&gpio_rv32m1_portc_data, &gpio_rv32m1_portc_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&gpio_rv32m1_driver_api);
|
||||
|
||||
static int gpio_rv32m1_portc_init(struct device *dev)
|
||||
{
|
||||
#ifdef GPIO_C_IRQ
|
||||
IRQ_CONNECT(GPIO_C_IRQ, GPIO_C_IRQ_PRIORITY,
|
||||
gpio_rv32m1_port_isr, DEVICE_GET(gpio_rv32m1_portc), 0);
|
||||
|
||||
irq_enable(GPIO_C_IRQ);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_GPIO_RV32M1_PORTC */
|
||||
|
||||
#ifdef CONFIG_GPIO_RV32M1_PORTD
|
||||
static int gpio_rv32m1_portd_init(struct device *dev);
|
||||
|
||||
static const struct gpio_rv32m1_config gpio_rv32m1_portd_config = {
|
||||
.gpio_base = (GPIO_Type *) GPIO_D_BASE_ADDRESS,
|
||||
.port_base = PORTD,
|
||||
#ifdef GPIO_D_IRQ
|
||||
.flags = GPIO_INT,
|
||||
#else
|
||||
.flags = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct gpio_rv32m1_data gpio_rv32m1_portd_data;
|
||||
|
||||
DEVICE_AND_API_INIT(gpio_rv32m1_portd, GPIO_D_LABEL,
|
||||
gpio_rv32m1_portd_init,
|
||||
&gpio_rv32m1_portd_data, &gpio_rv32m1_portd_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&gpio_rv32m1_driver_api);
|
||||
|
||||
static int gpio_rv32m1_portd_init(struct device *dev)
|
||||
{
|
||||
#ifdef GPIO_D_IRQ
|
||||
IRQ_CONNECT(GPIO_D_IRQ, GPIO_D_IRQ_PRIORITY,
|
||||
gpio_rv32m1_port_isr, DEVICE_GET(gpio_rv32m1_portd), 0);
|
||||
|
||||
irq_enable(GPIO_D_IRQ);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_GPIO_RV32M1_PORTD */
|
||||
|
||||
#ifdef CONFIG_GPIO_RV32M1_PORTE
|
||||
static int gpio_rv32m1_porte_init(struct device *dev);
|
||||
|
||||
static const struct gpio_rv32m1_config gpio_rv32m1_porte_config = {
|
||||
.gpio_base = (GPIO_Type *) GPIO_E_BASE_ADDRESS,
|
||||
.port_base = PORTE,
|
||||
#ifdef GPIO_E_IRQ
|
||||
.flags = GPIO_INT,
|
||||
#else
|
||||
.flags = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct gpio_rv32m1_data gpio_rv32m1_porte_data;
|
||||
|
||||
DEVICE_AND_API_INIT(gpio_rv32m1_porte, GPIO_E_LABEL,
|
||||
gpio_rv32m1_porte_init,
|
||||
&gpio_rv32m1_porte_data, &gpio_rv32m1_porte_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&gpio_rv32m1_driver_api);
|
||||
|
||||
static int gpio_rv32m1_porte_init(struct device *dev)
|
||||
{
|
||||
#ifdef GPIO_E_IRQ
|
||||
IRQ_CONNECT(GPIO_E_IRQ, GPIO_E_IRQ_PRIORITY,
|
||||
gpio_rv32m1_port_isr, DEVICE_GET(gpio_rv32m1_porte), 0);
|
||||
|
||||
irq_enable(GPIO_E_IRQ);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_GPIO_RV32M1_PORTE */
|
37
dts/bindings/gpio/openisa,rv32m1-gpio.yaml
Normal file
37
dts/bindings/gpio/openisa,rv32m1-gpio.yaml
Normal file
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
title: OpenISA GPIO
|
||||
version: 0.1
|
||||
|
||||
description: >
|
||||
This is a representation of the OpenISA GPIO nodes
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
type: string
|
||||
category: required
|
||||
description: compatible strings
|
||||
constraint: "openisa,rv32m1-gpio"
|
||||
generation: define
|
||||
|
||||
reg:
|
||||
type: int
|
||||
description: mmio register space
|
||||
generation: define
|
||||
category: required
|
||||
|
||||
interrupts:
|
||||
type: compound
|
||||
category: required
|
||||
description: required interrupts
|
||||
generation: define
|
||||
|
||||
label:
|
||||
type: string
|
||||
category: required
|
||||
description: Human readable string describing the device (used by Zephyr for API name)
|
||||
generation: define
|
||||
|
||||
"#cells":
|
||||
- pin
|
||||
- flags
|
||||
...
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/openisa-intmux.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
|
@ -19,6 +20,11 @@
|
|||
pinmux-c = &pinmux_c;
|
||||
pinmux-d = &pinmux_d;
|
||||
pinmux-e = &pinmux_e;
|
||||
gpio-a = &gpioa;
|
||||
gpio-b = &gpiob;
|
||||
gpio-c = &gpioc;
|
||||
gpio-d = &gpiod;
|
||||
gpio-e = &gpioe;
|
||||
};
|
||||
|
||||
cpus {
|
||||
|
@ -143,5 +149,56 @@
|
|||
reg = <0x41037000 0xd0>;
|
||||
clocks = <&pcc1 0xdc>;
|
||||
};
|
||||
|
||||
gpioa: gpio@48020000 {
|
||||
compatible = "openisa,rv32m1-gpio";
|
||||
reg = <0x48020000 0x14>;
|
||||
interrupt-parent = <&event>;
|
||||
interrupts = <18>;
|
||||
label = "GPIO_0";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpiob: gpio@48020040 {
|
||||
compatible = "openisa,rv32m1-gpio";
|
||||
reg = <0x48020040 0x14>;
|
||||
interrupt-parent = <&intmux>;
|
||||
interrupts = <INTMUX_LEVEL2_IRQ(INTMUX_CH1, 15)>;
|
||||
label = "GPIO_1";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpioc: gpio@48020080 {
|
||||
compatible = "openisa,rv32m1-gpio";
|
||||
reg = <0x48020080 0x14>;
|
||||
interrupt-parent = <&intmux>;
|
||||
interrupts = <INTMUX_LEVEL2_IRQ(INTMUX_CH1, 16)>;
|
||||
label = "GPIO_2";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpiod: gpio@480200c0 {
|
||||
compatible = "openisa,rv32m1-gpio";
|
||||
reg = <0x480200c0 0x14>;
|
||||
interrupt-parent = <&intmux>;
|
||||
interrupts = <INTMUX_LEVEL2_IRQ(INTMUX_CH1, 17)>;
|
||||
label = "GPIO_3";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpioe: gpio@4100f000 {
|
||||
compatible = "openisa,rv32m1-gpio";
|
||||
reg = <0x4100f000 0x14>;
|
||||
interrupt-parent = <&intmux>;
|
||||
interrupts = <INTMUX_LEVEL2_IRQ(INTMUX_CH1, 27)>;
|
||||
label = "GPIO_4";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
clocks = <&pcc1 0x3c>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -170,4 +170,11 @@ endif # MULTI_LEVEL_INTERRUPTS
|
|||
config PINMUX_RV32M1
|
||||
def_bool y
|
||||
|
||||
if GPIO
|
||||
|
||||
config GPIO_RV32M1
|
||||
def_bool y
|
||||
|
||||
endif # GPIO
|
||||
|
||||
endif # SOC_OPENISA_RV32M1_RISCV32
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue