Skip to content

Commit 0bdba34

Browse files
committed
drivers: gpio: Added support for raspberry pi
Signed-off-by: Yonatan Schachter <[email protected]>
1 parent 4b3b956 commit 0bdba34

File tree

8 files changed

+236
-0
lines changed

8 files changed

+236
-0
lines changed

boards/arm/raspberrypi_pico/raspberrypi_pico.dts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@
1414
zephyr,flash = &flash0;
1515
zephyr,console = &uart0;
1616
};
17+
18+
leds {
19+
compatible = "gpio-leds";
20+
led0: led_0 {
21+
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
22+
label = "LED";
23+
};
24+
};
25+
26+
aliases {
27+
led0 = &led0;
28+
};
1729
};
1830

1931
&flash0 {
@@ -29,3 +41,7 @@
2941
tx-pin = <0>;
3042
rx-pin = <1>;
3143
};
44+
45+
&gpio0 {
46+
status = "okay";
47+
};

drivers/gpio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SAM4L gpio_sam4l.c)
2626
zephyr_library_sources_ifdef(CONFIG_GPIO_SX1509B gpio_sx1509b.c)
2727
zephyr_library_sources_ifdef(CONFIG_GPIO_INTEL_APL gpio_intel_apl.c)
2828
zephyr_library_sources_ifdef(CONFIG_GPIO_STELLARIS gpio_stellaris.c)
29+
zephyr_library_sources_ifdef(CONFIG_GPIO_RASPBERRYPI gpio_raspberrypi.c)
2930
zephyr_library_sources_ifdef(CONFIG_GPIO_RV32M1 gpio_rv32m1.c)
3031
zephyr_library_sources_ifdef(CONFIG_GPIO_HT16K33 gpio_ht16k33.c)
3132
zephyr_library_sources_ifdef(CONFIG_GPIO_LMP90XXX gpio_lmp90xxx.c)

drivers/gpio/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ source "drivers/gpio/Kconfig.xec"
6767

6868
source "drivers/gpio/Kconfig.stellaris"
6969

70+
source "drivers/gpio/Kconfig.raspberrypi"
71+
7072
source "drivers/gpio/Kconfig.rv32m1"
7173

7274
source "drivers/gpio/Kconfig.ht16k33"

drivers/gpio/Kconfig.raspberrypi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright (c) 2021 Yonatan Schachter
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config GPIO_RASPBERRYPI
5+
bool "Raspberry Pi GPIO driver"

drivers/gpio/gpio_raspberrypi.c

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
* Copyright (c) 2021, Yonatan Schachter
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <errno.h>
8+
#include <drivers/gpio.h>
9+
#include <hardware/gpio.h>
10+
#include <hardware/regs/intctrl.h>
11+
#include <hardware/structs/iobank0.h>
12+
13+
#include "gpio_utils.h"
14+
15+
#define DT_DRV_COMPAT raspberrypi_rp2_gpio
16+
17+
#define IRQ_PRIORITY 0
18+
#define ALL_EVENTS (GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE \
19+
| GPIO_IRQ_LEVEL_LOW | GPIO_IRQ_LEVEL_HIGH)
20+
21+
struct gpio_raspberrypi_config {
22+
struct gpio_driver_config common;
23+
};
24+
25+
struct gpio_raspberrypi_data {
26+
struct gpio_driver_data common;
27+
sys_slist_t callbacks;
28+
uint32_t int_enabled_mask;
29+
};
30+
31+
static int gpio_raspberrypi_configure(const struct device *dev,
32+
gpio_pin_t pin,
33+
gpio_flags_t flags)
34+
{
35+
if (flags & GPIO_SINGLE_ENDED) {
36+
return -ENOTSUP;
37+
}
38+
39+
gpio_init(pin);
40+
41+
if (flags & GPIO_OUTPUT) {
42+
gpio_set_dir(pin, GPIO_OUT);
43+
44+
if (flags & GPIO_OUTPUT_INIT_HIGH)
45+
gpio_put(pin, 1);
46+
else if (flags & GPIO_OUTPUT_INIT_LOW)
47+
gpio_put(pin, 0);
48+
49+
} else if (flags & GPIO_INPUT) {
50+
gpio_set_dir(pin, GPIO_IN);
51+
if (flags & GPIO_PULL_UP)
52+
gpio_pull_up(pin);
53+
else if (flags & GPIO_PULL_DOWN)
54+
gpio_pull_down(pin);
55+
}
56+
57+
return 0;
58+
}
59+
60+
static int gpio_raspberrypi_port_get_raw(const struct device *dev, uint32_t *value)
61+
{
62+
*value = gpio_get_all();
63+
return 0;
64+
}
65+
66+
static int gpio_raspberrypi_port_set_masked_raw(const struct device *port,
67+
uint32_t mask, uint32_t value)
68+
{
69+
gpio_put_masked(mask, value);
70+
return 0;
71+
}
72+
73+
static int gpio_raspberrypi_port_set_bits_raw(const struct device *port,
74+
uint32_t pins)
75+
{
76+
gpio_set_mask(pins);
77+
return 0;
78+
}
79+
80+
static int gpio_raspberrypi_port_clear_bits_raw(const struct device *port,
81+
uint32_t pins)
82+
{
83+
gpio_clr_mask(pins);
84+
return 0;
85+
}
86+
87+
static int gpio_raspberrypi_port_toggle_bits(const struct device *port,
88+
uint32_t pins)
89+
{
90+
gpio_xor_mask(pins);
91+
return 0;
92+
}
93+
94+
static int gpio_raspberrypi_pin_interrupt_configure(const struct device *dev,
95+
gpio_pin_t pin,
96+
enum gpio_int_mode mode,
97+
enum gpio_int_trig trig)
98+
{
99+
uint32_t events = 0;
100+
struct gpio_raspberrypi_data *data = dev->data;
101+
102+
if (mode != GPIO_INT_DISABLE) {
103+
if (mode & GPIO_INT_EDGE) {
104+
if (trig & GPIO_INT_LOW_0)
105+
events |= GPIO_IRQ_EDGE_FALL;
106+
if (trig & GPIO_INT_HIGH_1)
107+
events |= GPIO_IRQ_EDGE_RISE;
108+
} else {
109+
if (trig & GPIO_INT_LOW_0)
110+
events |= GPIO_IRQ_LEVEL_LOW;
111+
if (trig & GPIO_INT_HIGH_1)
112+
events |= GPIO_IRQ_LEVEL_HIGH;
113+
}
114+
gpio_set_irq_enabled(pin, events, true);
115+
}
116+
WRITE_BIT(data->int_enabled_mask, pin, mode != GPIO_INT_DISABLE);
117+
return 0;
118+
}
119+
120+
static int gpio_raspberrypi_manage_callback(const struct device *dev,
121+
struct gpio_callback *callback, bool set)
122+
{
123+
struct gpio_raspberrypi_data *data = dev->data;
124+
125+
return gpio_manage_callback(&data->callbacks, callback, set);
126+
}
127+
128+
static const struct gpio_driver_api gpio_raspberrypi_driver_api = {
129+
.pin_configure = gpio_raspberrypi_configure,
130+
.port_get_raw = gpio_raspberrypi_port_get_raw,
131+
.port_set_masked_raw = gpio_raspberrypi_port_set_masked_raw,
132+
.port_set_bits_raw = gpio_raspberrypi_port_set_bits_raw,
133+
.port_clear_bits_raw = gpio_raspberrypi_port_clear_bits_raw,
134+
.port_toggle_bits = gpio_raspberrypi_port_toggle_bits,
135+
.pin_interrupt_configure = gpio_raspberrypi_pin_interrupt_configure,
136+
.manage_callback = gpio_raspberrypi_manage_callback,
137+
};
138+
139+
static void gpio_raspberrypi_isr(const struct device *dev)
140+
{
141+
struct gpio_raspberrypi_data *data = dev->data;
142+
uint32_t pin;
143+
uint32_t events;
144+
io_irq_ctrl_hw_t *irq_ctrl_base;
145+
io_rw_32 *status_reg;
146+
147+
irq_ctrl_base = &iobank0_hw->proc0_irq_ctrl;
148+
for (pin = 0; pin < NUM_BANK0_GPIOS; pin++) {
149+
status_reg = &irq_ctrl_base->ints[pin / 8];
150+
events = (*status_reg >> 4 * (pin % 8)) & ALL_EVENTS;
151+
if (events) {
152+
gpio_acknowledge_irq(pin, ALL_EVENTS);
153+
gpio_fire_callbacks(&data->callbacks, dev, BIT(pin));
154+
}
155+
}
156+
}
157+
158+
static int gpio_raspberrypi_init(const struct device *dev)
159+
{
160+
IRQ_CONNECT(IO_IRQ_BANK0, IRQ_PRIORITY, gpio_raspberrypi_isr,
161+
DEVICE_DT_GET(DT_INST(0, raspberrypi_rp2_gpio)), 0);
162+
irq_enable(IO_IRQ_BANK0);
163+
return 0;
164+
}
165+
166+
#define GPIO_RASPBERRYPI_INIT(idx) \
167+
static const struct gpio_raspberrypi_config gpio_raspberrypi_##idx##_config = { \
168+
}; \
169+
\
170+
static struct gpio_raspberrypi_data gpio_raspberrypi_##idx##_data; \
171+
\
172+
DEVICE_DT_INST_DEFINE(idx, gpio_raspberrypi_init, NULL, \
173+
&gpio_raspberrypi_##idx##_data, \
174+
&gpio_raspberrypi_##idx##_config, \
175+
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
176+
&gpio_raspberrypi_driver_api);
177+
178+
DT_INST_FOREACH_STATUS_OKAY(GPIO_RASPBERRYPI_INIT)

dts/arm/raspberrypi/rp2040.dtsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@
4646
};
4747

4848
soc {
49+
gpio0: gpio@40014000 {
50+
compatible = "raspberrypi,rp2-gpio";
51+
reg = <0x40014000 DT_SIZE_K(4)>;
52+
gpio-controller;
53+
#gpio-cells = <2>;
54+
label = "GPIO_0";
55+
status = "disabled";
56+
};
57+
4958
uart0: uart@40034000 {
5059
compatible = "raspberrypi,rp2-uart";
5160
reg = <0x40034000 DT_SIZE_K(4)>;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright (c) 2021, Yonatan Schachter
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Raspberry Pi GPIO
5+
6+
compatible: "raspberrypi,rp2-gpio"
7+
8+
include: [gpio-controller.yaml, base.yaml]
9+
10+
properties:
11+
reg:
12+
required: true
13+
14+
label:
15+
required: true
16+
17+
"#gpio-cells":
18+
const: 2
19+
20+
gpio-cells:
21+
- pin
22+
- flags

soc/arm/raspberrypi/rp2/Kconfig.defconfig.series

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,8 @@ config UART_RASPBERRYPI
4242
default y
4343
depends on SERIAL
4444

45+
config GPIO_RASPBERRYPI
46+
default y
47+
depends on GPIO
4548

4649
endif # SOC_SERIES_RP2XXX

0 commit comments

Comments
 (0)