drivers: gpio: Added support for raspberry pi
Added GPIO support for the RP2040 SoC. Only one core is supported. Signed-off-by: Yonatan Schachter <yonatan.schachter@gmail.com>
This commit is contained in:
parent
cd7bd5f450
commit
a2aa02dbc8
|
@ -266,6 +266,7 @@
|
|||
/drivers/gpio/*eos_s3* @wtatarski @kowalewskijan @kgugala
|
||||
/drivers/gpio/*rcar* @julien-massot
|
||||
/drivers/gpio/*esp32* @glaubermaroto
|
||||
/drivers/gpio/*rpi_pico* @yonsch
|
||||
/drivers/hwinfo/ @alexanderwachter
|
||||
/drivers/i2c/i2c_common.c @sjg20
|
||||
/drivers/i2c/i2c_emul.c @sjg20
|
||||
|
|
|
@ -30,6 +30,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SAM4L gpio_sam4l.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GPIO_SX1509B gpio_sx1509b.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_INTEL gpio_intel.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_STELLARIS gpio_stellaris.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_RPI_PICO gpio_rpi_pico.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_RV32M1 gpio_rv32m1.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_LMP90XXX gpio_lmp90xxx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_LITEX gpio_litex.c)
|
||||
|
|
|
@ -77,6 +77,8 @@ source "drivers/gpio/Kconfig.xec"
|
|||
|
||||
source "drivers/gpio/Kconfig.stellaris"
|
||||
|
||||
source "drivers/gpio/Kconfig.rpi_pico"
|
||||
|
||||
source "drivers/gpio/Kconfig.rv32m1"
|
||||
|
||||
source "drivers/gpio/Kconfig.lmp90xxx"
|
||||
|
|
10
drivers/gpio/Kconfig.rpi_pico
Normal file
10
drivers/gpio/Kconfig.rpi_pico
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2021 Yonatan Schachter
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Workaround for not being able to have commas in macro arguments
|
||||
DT_COMPAT_RPI_PICO_GPIO := raspberrypi,pico-gpio
|
||||
|
||||
config GPIO_RPI_PICO
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_RPI_PICO_GPIO))
|
||||
select PICOSDK_USE_GPIO
|
||||
bool "Raspberry Pi Pico GPIO driver"
|
192
drivers/gpio/gpio_rpi_pico.c
Normal file
192
drivers/gpio/gpio_rpi_pico.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Yonatan Schachter
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <drivers/gpio.h>
|
||||
|
||||
/* pico-sdk includes */
|
||||
#include <hardware/gpio.h>
|
||||
#include <hardware/regs/intctrl.h>
|
||||
#include <hardware/structs/iobank0.h>
|
||||
|
||||
#include "gpio_utils.h"
|
||||
|
||||
#define DT_DRV_COMPAT raspberrypi_pico_gpio
|
||||
|
||||
#define ALL_EVENTS (GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE \
|
||||
| GPIO_IRQ_LEVEL_LOW | GPIO_IRQ_LEVEL_HIGH)
|
||||
|
||||
struct gpio_rpi_config {
|
||||
struct gpio_driver_config common;
|
||||
void (*bank_config_func)(void);
|
||||
};
|
||||
|
||||
struct gpio_rpi_data {
|
||||
struct gpio_driver_data common;
|
||||
sys_slist_t callbacks;
|
||||
uint32_t int_enabled_mask;
|
||||
};
|
||||
|
||||
static int gpio_rpi_configure(const struct device *dev,
|
||||
gpio_pin_t pin,
|
||||
gpio_flags_t flags)
|
||||
{
|
||||
if (flags & GPIO_SINGLE_ENDED) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
gpio_init(pin);
|
||||
|
||||
if (flags & GPIO_OUTPUT) {
|
||||
gpio_set_dir(pin, GPIO_OUT);
|
||||
|
||||
if (flags & GPIO_OUTPUT_INIT_HIGH) {
|
||||
gpio_put(pin, 1);
|
||||
} else if (flags & GPIO_OUTPUT_INIT_LOW) {
|
||||
gpio_put(pin, 0);
|
||||
}
|
||||
} else if (flags & GPIO_INPUT) {
|
||||
gpio_set_dir(pin, GPIO_IN);
|
||||
if (flags & GPIO_PULL_UP) {
|
||||
gpio_pull_up(pin);
|
||||
} else if (flags & GPIO_PULL_DOWN) {
|
||||
gpio_pull_down(pin);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_port_get_raw(const struct device *dev, uint32_t *value)
|
||||
{
|
||||
*value = gpio_get_all();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_port_set_masked_raw(const struct device *port,
|
||||
uint32_t mask, uint32_t value)
|
||||
{
|
||||
gpio_put_masked(mask, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_port_set_bits_raw(const struct device *port,
|
||||
uint32_t pins)
|
||||
{
|
||||
gpio_set_mask(pins);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_port_clear_bits_raw(const struct device *port,
|
||||
uint32_t pins)
|
||||
{
|
||||
gpio_clr_mask(pins);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_port_toggle_bits(const struct device *port,
|
||||
uint32_t pins)
|
||||
{
|
||||
gpio_xor_mask(pins);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_pin_interrupt_configure(const struct device *dev,
|
||||
gpio_pin_t pin,
|
||||
enum gpio_int_mode mode,
|
||||
enum gpio_int_trig trig)
|
||||
{
|
||||
struct gpio_rpi_data *data = dev->data;
|
||||
uint32_t events = 0;
|
||||
|
||||
if (mode != GPIO_INT_DISABLE) {
|
||||
if (mode & GPIO_INT_EDGE) {
|
||||
if (trig & GPIO_INT_LOW_0) {
|
||||
events |= GPIO_IRQ_EDGE_FALL;
|
||||
}
|
||||
if (trig & GPIO_INT_HIGH_1) {
|
||||
events |= GPIO_IRQ_EDGE_RISE;
|
||||
}
|
||||
} else {
|
||||
if (trig & GPIO_INT_LOW_0) {
|
||||
events |= GPIO_IRQ_LEVEL_LOW;
|
||||
}
|
||||
if (trig & GPIO_INT_HIGH_1) {
|
||||
events |= GPIO_IRQ_LEVEL_HIGH;
|
||||
}
|
||||
}
|
||||
gpio_set_irq_enabled(pin, events, true);
|
||||
}
|
||||
WRITE_BIT(data->int_enabled_mask, pin, mode != GPIO_INT_DISABLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_rpi_manage_callback(const struct device *dev,
|
||||
struct gpio_callback *callback, bool set)
|
||||
{
|
||||
struct gpio_rpi_data *data = dev->data;
|
||||
|
||||
return gpio_manage_callback(&data->callbacks, callback, set);
|
||||
}
|
||||
|
||||
static const struct gpio_driver_api gpio_rpi_driver_api = {
|
||||
.pin_configure = gpio_rpi_configure,
|
||||
.port_get_raw = gpio_rpi_port_get_raw,
|
||||
.port_set_masked_raw = gpio_rpi_port_set_masked_raw,
|
||||
.port_set_bits_raw = gpio_rpi_port_set_bits_raw,
|
||||
.port_clear_bits_raw = gpio_rpi_port_clear_bits_raw,
|
||||
.port_toggle_bits = gpio_rpi_port_toggle_bits,
|
||||
.pin_interrupt_configure = gpio_rpi_pin_interrupt_configure,
|
||||
.manage_callback = gpio_rpi_manage_callback,
|
||||
};
|
||||
|
||||
static void gpio_rpi_isr(const struct device *dev)
|
||||
{
|
||||
struct gpio_rpi_data *data = dev->data;
|
||||
io_irq_ctrl_hw_t *irq_ctrl_base;
|
||||
const io_rw_32 *status_reg;
|
||||
uint32_t events;
|
||||
uint32_t pin;
|
||||
|
||||
irq_ctrl_base = &iobank0_hw->proc0_irq_ctrl;
|
||||
for (pin = 0; pin < NUM_BANK0_GPIOS; pin++) {
|
||||
status_reg = &irq_ctrl_base->ints[pin / 8];
|
||||
events = (*status_reg >> 4 * (pin % 8)) & ALL_EVENTS;
|
||||
if (events) {
|
||||
gpio_acknowledge_irq(pin, ALL_EVENTS);
|
||||
gpio_fire_callbacks(&data->callbacks, dev, BIT(pin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int gpio_rpi_bank_init(const struct device *dev)
|
||||
{
|
||||
const struct gpio_rpi_config *config = dev->config;
|
||||
|
||||
config->bank_config_func();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GPIO_RPI_INIT(idx) \
|
||||
static void bank_##idx##_config_func(void) \
|
||||
{ \
|
||||
IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), \
|
||||
gpio_rpi_isr, DEVICE_DT_INST_GET(idx), 0); \
|
||||
irq_enable(DT_INST_IRQN(idx)); \
|
||||
} \
|
||||
static const struct gpio_rpi_config gpio_rpi_##idx##_config = { \
|
||||
.bank_config_func = bank_##idx##_config_func, \
|
||||
}; \
|
||||
\
|
||||
static struct gpio_rpi_data gpio_rpi_##idx##_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, gpio_rpi_bank_init, NULL, \
|
||||
&gpio_rpi_##idx##_data, \
|
||||
&gpio_rpi_##idx##_config, \
|
||||
POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \
|
||||
&gpio_rpi_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_RPI_INIT)
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <arm/armv6-m.dtsi>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <mem.h>
|
||||
|
||||
#include "rpi_pico_common.dtsi"
|
||||
|
@ -51,6 +52,16 @@
|
|||
label = "PINCTRL";
|
||||
};
|
||||
|
||||
gpio0: gpio@40014000 {
|
||||
compatible = "raspberrypi,pico-gpio";
|
||||
reg = <0x40014000 DT_SIZE_K(4)>;
|
||||
interrupts = <13 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
label = "GPIO_0";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart0: uart@40034000 {
|
||||
compatible = "raspberrypi,pico-uart";
|
||||
reg = <0x40034000 DT_SIZE_K(4)>;
|
||||
|
|
22
dts/bindings/gpio/raspberrypi,pico-gpio.yaml
Normal file
22
dts/bindings/gpio/raspberrypi,pico-gpio.yaml
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2021, Yonatan Schachter
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Raspberry Pi Pico GPIO
|
||||
|
||||
compatible: "raspberrypi,pico-gpio"
|
||||
|
||||
include: [gpio-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
label:
|
||||
required: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
gpio-cells:
|
||||
- pin
|
||||
- flags
|
|
@ -3,3 +3,4 @@ k_mem_partition_attr_t
|
|||
mbedtls_pk_context
|
||||
z_arch_esf_t
|
||||
pinctrl_soc_pin_t
|
||||
io_rw_32
|
||||
|
|
Loading…
Reference in a new issue