Skip to content

Commit 5abb1b1

Browse files
yonschcarlescufi
authored andcommitted
drivers: misc: Add driver for RaspberryPi Pico PIO
Added a generic driver for RaspberryPi Pico PIO. This driver is an intermediate driver for abstracting the PIO device driver from physical pin configuration. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@fujitsu.com> Signed-off-by: Yonatan Schachter <yonatan.schachter@gmail.com> Signed-off-by: Ionut Catalin Pavel <iocapa@iocapa.com>
1 parent 0695c08 commit 5abb1b1

File tree

12 files changed

+329
-0
lines changed

12 files changed

+329
-0
lines changed

drivers/misc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
add_subdirectory_ifdef(CONFIG_ARM_ETHOS_U ethos_u)
44
add_subdirectory_ifdef(CONFIG_FT800 ft8xx)
55
add_subdirectory_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb)
6+
add_subdirectory_ifdef(CONFIG_PIO_RPI_PICO pio_rpi_pico)

drivers/misc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ menu "Miscellaneous Drivers"
77

88
source "drivers/misc/ft8xx/Kconfig"
99
source "drivers/misc/grove_lcd_rgb/Kconfig"
10+
source "drivers/misc/pio_rpi_pico/Kconfig"
1011

1112
endmenu
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) 2023 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
zephyr_library()
5+
6+
zephyr_library_sources(pio_rpi_pico.c)

drivers/misc/pio_rpi_pico/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2023 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config PIO_RPI_PICO
5+
bool "RaspberryPi Pico PIO"
6+
default y
7+
depends on DT_HAS_RASPBERRYPI_PICO_PIO_ENABLED
8+
depends on RESET
9+
select PICOSDK_USE_PIO
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2023 Tokita, Hiroshi <tokita.hiroshi@fujitsu.com>
3+
* Copyright (c) 2023 Yonatan Schachter
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <zephyr/device.h>
9+
#include <zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h>
10+
#include <zephyr/drivers/pinctrl.h>
11+
12+
#define DT_DRV_COMPAT raspberrypi_pico_pio
13+
14+
struct pio_rpi_pico_config {
15+
PIO pio;
16+
};
17+
18+
int pio_rpi_pico_allocate_sm(const struct device *dev, size_t *sm)
19+
{
20+
const struct pio_rpi_pico_config *config = dev->config;
21+
int retval;
22+
23+
retval = pio_claim_unused_sm(config->pio, false);
24+
if (retval < 0) {
25+
return -EBUSY;
26+
}
27+
28+
*sm = (size_t)retval;
29+
return 0;
30+
}
31+
32+
PIO pio_rpi_pico_get_pio(const struct device *dev)
33+
{
34+
const struct pio_rpi_pico_config *config = dev->config;
35+
36+
return config->pio;
37+
}
38+
39+
static int pio_rpi_pico_init(const struct device *dev)
40+
{
41+
return 0;
42+
}
43+
44+
#define RPI_PICO_PIO_INIT(idx) \
45+
static const struct pio_rpi_pico_config pio_rpi_pico_config_##idx = { \
46+
.pio = (PIO)DT_INST_REG_ADDR(idx), \
47+
}; \
48+
\
49+
DEVICE_DT_INST_DEFINE(idx, &pio_rpi_pico_init, NULL, NULL, \
50+
&pio_rpi_pico_config_##idx, PRE_KERNEL_2, \
51+
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
52+
53+
DT_INST_FOREACH_STATUS_OKAY(RPI_PICO_PIO_INIT)

dts/arm/rpi_pico/rp2040.dtsi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,22 @@
207207
raspberrypi,brown-out-detection;
208208
raspberrypi,brown-out-threshold = <860000>;
209209
};
210+
211+
pio0: pio@50200000 {
212+
compatible = "raspberrypi,pico-pio";
213+
reg = <0x50200000 DT_SIZE_K(4)>;
214+
clocks = <&system_clk>;
215+
resets = <&reset RPI_PICO_RESETS_RESET_PIO0>;
216+
status = "disabled";
217+
};
218+
219+
pio1: pio@50300000 {
220+
compatible = "raspberrypi,pico-pio";
221+
reg = <0x50300000 DT_SIZE_K(4)>;
222+
clocks = <&system_clk>;
223+
resets = <&reset RPI_PICO_RESETS_RESET_PIO1>;
224+
status = "disabled";
225+
};
210226
};
211227

212228
pinctrl: pin-controller {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2023, TOKITA Hiroshi
2+
# Copyright (c) 2023, Yonatan Schachter
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
description: Raspberry Pi Pico PIO device
6+
7+
compatible: "raspberrypi,pico-pio-device"
8+
9+
include: pinctrl-device.yaml
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2023, TOKITA Hiroshi
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Raspberry Pi Pico PIO
5+
6+
compatible: "raspberrypi,pico-pio"
7+
8+
include: [base.yaml, reset-device.yaml]
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright (c) 2023 Tokita, Hiroshi <tokita.hiroshi@fujitsu.com>
3+
* Copyright (c) 2023 Yonatan Schachter
4+
* Copyright (c) 2023 Ionut Pavel <iocapa@iocapa.com>
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#ifndef ZEPHYR_DRIVERS_MISC_PIO_PICO_RPI_PIO_PICO_RPI_H_
10+
#define ZEPHYR_DRIVERS_MISC_PIO_PICO_RPI_PIO_PICO_RPI_H_
11+
12+
#include <zephyr/devicetree/gpio.h>
13+
14+
#include <hardware/pio.h>
15+
16+
/**
17+
* @brief Utility macro to define a PIO program. The program is a list
18+
* of 16 bit instructions, generated by the pioasm tool.
19+
*
20+
* @param name Name of the program.
21+
* @param wrap_target Wrap target as specified by the PIO program.
22+
* @param wrap Wrap source as specified by the PIO program.
23+
* @param ... Comma separated list of PIO instructions.
24+
*/
25+
#define RPI_PICO_PIO_DEFINE_PROGRAM(name, wrap_target, wrap, ...) \
26+
static const uint32_t name ## _wrap_target = wrap_target; \
27+
static const uint32_t name ## _wrap = wrap; \
28+
static const uint16_t name ## _program_instructions[] = { \
29+
__VA_ARGS__ \
30+
}; \
31+
static const struct pio_program name ## _program = { \
32+
.instructions = name ## _program_instructions, \
33+
.length = ARRAY_SIZE(name ## _program_instructions), \
34+
.origin = -1, \
35+
}
36+
37+
/**
38+
* @brief Utility macro to get the wrap target of a program.
39+
*
40+
* @param name Name of the program.
41+
*/
42+
#define RPI_PICO_PIO_GET_WRAP_TARGET(name) name ## _wrap_target
43+
44+
/**
45+
* @brief Utility macro to get the wrap source of a program.
46+
*
47+
* @param name Name of the program.
48+
*/
49+
#define RPI_PICO_PIO_GET_WRAP(name) name ## _wrap
50+
51+
/**
52+
* @brief Utility macro to get a pointer to a PIO program.
53+
*
54+
* @param name Name of the program.
55+
*/
56+
#define RPI_PICO_PIO_GET_PROGRAM(name) &name ## _program
57+
58+
/**
59+
* @brief Get a pin number from a pinctrl / group name and index
60+
*
61+
* Example devicetree fragment(s):
62+
*
63+
* @code{.dts}
64+
* pinctrl {
65+
* pio_child_default: pio_child_default {
66+
* tx_gpio {
67+
* pinmux = <PIO0_P0>, <PIO0_P2>;
68+
* };
69+
*
70+
* rx_gpio {
71+
* pinmux = <PIO0_P1>;
72+
* input-enable;
73+
* };
74+
* };
75+
* };
76+
* @endcode
77+
*
78+
* @code{.dts}
79+
* pio {
80+
* status = "okay";
81+
* c: child {
82+
* pinctrl-0 = <&pio_child_default>;
83+
* pinctrl-names = "default";
84+
* };
85+
* };
86+
* @endcode
87+
*
88+
* Example usage:
89+
*
90+
* @code{.c}
91+
* DT_RPI_PICO_PIO_PIN_BY_NAME(node, default, 0, tx_gpio, 0) // 0
92+
* DT_RPI_PICO_PIO_PIN_BY_NAME(node, default, 0, tx_gpio, 1) // 2
93+
* DT_RPI_PICO_PIO_PIN_BY_NAME(node, default, 0, rx_gpio, 0) // 1
94+
* @endcode
95+
*
96+
* @param node_id node identifier
97+
* @param p_name pinctrl name
98+
* @param p_idx pinctrl index
99+
* @param g_name group name
100+
* @param g_idx group index
101+
* @return pin number
102+
*/
103+
#define DT_RPI_PICO_PIO_PIN_BY_NAME(node_id, p_name, p_idx, g_name, g_idx) \
104+
RP2_GET_PIN_NUM(DT_PROP_BY_IDX( \
105+
DT_CHILD(DT_PINCTRL_BY_NAME(node_id, p_name, p_idx), g_name), pinmux, g_idx))
106+
107+
/**
108+
* @brief Get a pin number from a pinctrl / group name and index
109+
*
110+
* @param inst instance number
111+
* @param p_name pinctrl name
112+
* @param p_idx pinctrl index
113+
* @param g_name group name
114+
* @param g_idx group index
115+
* @return pin number
116+
*
117+
* @see DT_RPI_PICO_PIO_PIN_BY_NAME
118+
*/
119+
#define DT_INST_RPI_PICO_PIO_PIN_BY_NAME(inst, p_name, p_idx, g_name, g_idx) \
120+
DT_RPI_PICO_PIO_PIN_BY_NAME(DT_DRV_INST(inst), p_name, p_idx, g_name, g_idx)
121+
122+
/**
123+
* @brief Get the pin number of a pin by its name.
124+
*
125+
* @param name Name of the pin (e.g. tx, rx, sck).
126+
*/
127+
#define DT_INST_PIO_PIN_BY_NAME(inst, name) \
128+
DT_PIO_PIN_BY_NAME(DT_DRV_INST(inst), name)
129+
130+
/**
131+
* Get PIO object
132+
*
133+
* @param dev Pointer to device structure for rpi_pio device instance
134+
* @return PIO object
135+
*/
136+
PIO pio_rpi_pico_get_pio(const struct device *dev);
137+
138+
/**
139+
* Allocate a state machine.
140+
*
141+
* @param dev Pointer to device structure for rpi_pio device instance
142+
* @param sm Pointer to store allocated state machine
143+
* @retval 0 on success
144+
* @retval -EBUSY if no state machines were available
145+
*/
146+
int pio_rpi_pico_allocate_sm(const struct device *dev, size_t *sm);
147+
148+
#endif /* ZEPHYR_DRIVERS_MISC_PIO_PICO_RPI_PIO_PICO_RPI_H_ */

include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,66 @@
157157
#define ADC_CH2_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_NULL)
158158
#define ADC_CH3_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_NULL)
159159

160+
#define PIO0_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO0)
161+
#define PIO0_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO0)
162+
#define PIO0_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO0)
163+
#define PIO0_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO0)
164+
#define PIO0_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO0)
165+
#define PIO0_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO0)
166+
#define PIO0_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO0)
167+
#define PIO0_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO0)
168+
#define PIO0_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO0)
169+
#define PIO0_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO0)
170+
#define PIO0_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO0)
171+
#define PIO0_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO0)
172+
#define PIO0_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO0)
173+
#define PIO0_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO0)
174+
#define PIO0_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO0)
175+
#define PIO0_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO0)
176+
#define PIO0_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO0)
177+
#define PIO0_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO0)
178+
#define PIO0_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO0)
179+
#define PIO0_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO0)
180+
#define PIO0_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO0)
181+
#define PIO0_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO0)
182+
#define PIO0_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO0)
183+
#define PIO0_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO0)
184+
#define PIO0_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO0)
185+
#define PIO0_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO0)
186+
#define PIO0_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO0)
187+
#define PIO0_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO0)
188+
#define PIO0_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO0)
189+
#define PIO0_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO0)
190+
191+
#define PIO1_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO1)
192+
#define PIO1_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO1)
193+
#define PIO1_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO1)
194+
#define PIO1_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO1)
195+
#define PIO1_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO1)
196+
#define PIO1_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO1)
197+
#define PIO1_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO1)
198+
#define PIO1_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO1)
199+
#define PIO1_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO1)
200+
#define PIO1_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO1)
201+
#define PIO1_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO1)
202+
#define PIO1_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO1)
203+
#define PIO1_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO1)
204+
#define PIO1_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO1)
205+
#define PIO1_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO1)
206+
#define PIO1_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO1)
207+
#define PIO1_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO1)
208+
#define PIO1_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO1)
209+
#define PIO1_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO1)
210+
#define PIO1_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO1)
211+
#define PIO1_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO1)
212+
#define PIO1_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO1)
213+
#define PIO1_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO1)
214+
#define PIO1_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO1)
215+
#define PIO1_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO1)
216+
#define PIO1_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO1)
217+
#define PIO1_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO1)
218+
#define PIO1_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO1)
219+
#define PIO1_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO1)
220+
#define PIO1_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO1)
221+
160222
#endif /* __RP2040_PINCTRL_H__ */

0 commit comments

Comments
 (0)