Skip to content

Commit 62c9aad

Browse files
committed
drivers: pinctrl: Added pinctrl driver for RPi Pico
Added a pinctrl driver for the Raspberry Pi Pico series Signed-off-by: Yonatan Schachter <[email protected]>
1 parent 2eb2990 commit 62c9aad

File tree

10 files changed

+315
-0
lines changed

10 files changed

+315
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@
491491
/dts/bindings/*/nordic* @anangl
492492
/dts/bindings/*/nxp* @mmahadevan108 @dleach02
493493
/dts/bindings/*/openisa* @dleach02
494+
/dts/bindings/*/raspberrypi*pico* @yonsch
494495
/dts/bindings/*/st* @erwango
495496
/dts/bindings/sensor/ams* @alexanderwachter
496497
/dts/bindings/*/sifive* @mateusz-holenko @kgugala @pgielda

drivers/pinctrl/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AF pinctrl_gd32_af.c)
77
zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AFIO pinctrl_gd32_afio.c)
88
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c)
99
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RCAR_PFC pfc_rcar.c)
10+
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.c)
1011
zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c)

drivers/pinctrl/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ config PINCTRL_DYNAMIC
3232
source "drivers/pinctrl/Kconfig.gd32"
3333
source "drivers/pinctrl/Kconfig.nrf"
3434
source "drivers/pinctrl/Kconfig.rcar"
35+
source "drivers/pinctrl/Kconfig.rpi_pico"
3536
source "drivers/pinctrl/Kconfig.stm32"
3637

3738
endif # PINCTRL

drivers/pinctrl/Kconfig.rpi_pico

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2021 Yonatan Schachter
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
DT_COMPAT_RPI_PICO_PINCTRL := raspberrypi,pico-pinctrl
5+
6+
config PINCTRL_RPI_PICO
7+
bool "RaspberryPi Pico pin controller driver"
8+
depends on SOC_FAMILY_RPI_PICO
9+
default $(dt_compat_enabled,$(DT_COMPAT_RPI_PICO_PINCTRL))
10+
select PICOSDK_USE_GPIO
11+
help
12+
RaspberryPi Pico pinctrl driver

drivers/pinctrl/pinctrl_rpi_pico.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2021 Yonatan Schachter
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <drivers/pinctrl.h>
8+
9+
/* pico-sdk includes */
10+
#include <hardware/gpio.h>
11+
12+
static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
13+
{
14+
gpio_init(pin->pin_num);
15+
gpio_set_function(pin->pin_num, pin->alt_func);
16+
gpio_set_pulls(pin->pin_num, pin->pullup, pin->pulldown);
17+
gpio_set_drive_strength(pin->pin_num, pin->drive_strength);
18+
gpio_set_slew_rate(pin->pin_num, (pin->slew_rate ?
19+
GPIO_SLEW_RATE_FAST : GPIO_SLEW_RATE_SLOW));
20+
gpio_set_input_hysteresis_enabled(pin->pin_num, pin->schmitt_enable);
21+
gpio_set_input_enabled(pin->pin_num, pin->input_enable);
22+
}
23+
24+
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
25+
uintptr_t reg)
26+
{
27+
ARG_UNUSED(reg);
28+
29+
for (uint8_t i = 0U; i < pin_cnt; i++) {
30+
pinctrl_configure_pin(pins++);
31+
}
32+
33+
return 0;
34+
}

dts/arm/rpi_pico/rp2040.dtsi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
clock-frequency = <125000000>;
4444
#clock-cells = <0>;
4545
};
46+
47+
pinctrl: pin-controller@40014000 {
48+
compatible = "raspberrypi,pico-pinctrl";
49+
reg = <0x40014000 DT_SIZE_K(4)>;
50+
status = "okay";
51+
label = "PINCTRL";
52+
};
4653
};
4754
};
4855

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Copyright (c) 2021 Teslabs Engineering S.L.
2+
# Copyright (c) 2021 Yonatan Schachter
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
description: |
6+
The RPi Pico pin controller is a node responsible for controlling
7+
pin function selection and pin properties, such as routing a UART0 Rx
8+
to pin 1 and enabling the pullup resistor on that pin.
9+
10+
The node has the 'pinctrl' node label set in your SoC's devicetree,
11+
so you can modify it like this:
12+
13+
&pinctrl {
14+
/* your modifications go here */
15+
};
16+
17+
All device pin configurations should be placed in child nodes of the
18+
'pinctrl' node, as shown in this example:
19+
20+
/* You can put this in places like a board-pinctrl.dtsi file in
21+
* your board directory, or a devicetree overlay in your application.
22+
*/
23+
24+
/* include pre-defined combinations for the SoC variant used by the board */
25+
#include <dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>
26+
27+
&pinctrl {
28+
/* configuration for the usart0 "default" state */
29+
uart0_default: uart0_default {
30+
/* group 1 */
31+
group1 {
32+
/* configure P0 as UART0 TX */
33+
pinmux = <UART0_TX_P0>;
34+
};
35+
/* group 2 */
36+
group2 {
37+
/* configure P1 as UART0 RX */
38+
pinmux = <UART0_RX_P1>;
39+
/* enable input on pin 1 */
40+
input-enable;
41+
};
42+
};
43+
};
44+
45+
The 'uart0_default' child node encodes the pin configurations for a
46+
particular state of a device; in this case, the default (that is, active)
47+
state.
48+
49+
As shown, pin configurations are organized in groups within each child node.
50+
Each group can specify a list of pin function selections in the 'pinmux'
51+
property.
52+
53+
A group can also specify shared pin properties common to all the specified
54+
pins, such as the 'input-enable' property in group 2. Here is a list of
55+
supported standard pin properties:
56+
57+
- bias-disable: Disable pull-up/down (default, not required).
58+
- bias-pull-up: Enable pull-up resistor.
59+
- bias-pull-down: Enable pull-down resistor.
60+
- input-enable: Enable input from the pin.
61+
- input-schmitt-enable: Enable input hysteresys.
62+
- drive-strength: Set the drive strength of the pin, in milliamps. Possible
63+
values are: 2, 4, 8, 12 (default: 4mA)
64+
- slew-rate: If set to 0, slew rate is set to slow. If set to 1, it is set
65+
to fast.
66+
67+
To link pin configurations with a device, use a pinctrl-N property for some
68+
number N, like this example you could place in your board's DTS file:
69+
70+
#include "board-pinctrl.dtsi"
71+
72+
&uart0 {
73+
pinctrl-0 = <&uart0_default>;
74+
pinctrl-1 = <&uart0_sleep>;
75+
pinctrl-names = "default", "sleep";
76+
};
77+
78+
compatible: "raspberrypi,pico-pinctrl"
79+
80+
include:
81+
- name: base.yaml
82+
- name: pincfg-node-group.yaml
83+
child-binding:
84+
child-binding:
85+
property-allowlist:
86+
- bias-disable
87+
- bias-pull-down
88+
- bias-pull-up
89+
- input-enable
90+
- input-schmitt-enable
91+
- drive-strength
92+
- slew-rate
93+
94+
child-binding:
95+
description: |
96+
Definitions for a pinctrl state.
97+
child-binding:
98+
properties:
99+
pinmux:
100+
required: true
101+
type: array
102+
description: |
103+
An array of pins sharing the same group properties. Each
104+
element of the array is an integer constructed from the
105+
pin number and the alternative function of the pin.
106+
drive-strength:
107+
enum:
108+
- 2
109+
- 4
110+
- 8
111+
- 12
112+
default: 4
113+
description: |
114+
The drive strength of a pin, in mA. The default value is 4mA, as this
115+
is the power on reset value.
116+
slew-rate:
117+
enum:
118+
- 0
119+
- 1
120+
default: 0
121+
description: |
122+
The slew rate of a pin. 0 corresponds to slow, and 1 corresponds to fast.
123+
The default value is 0 (slow), as this is the power on reset value.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2021, Yonatan Schachter
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef __RP2040_PINCTRL_H__
8+
#define __RP2040_PINCTRL_H__
9+
10+
#define RP2_PINCTRL_GPIO_FUNC_XIP 0
11+
#define RP2_PINCTRL_GPIO_FUNC_SPI 1
12+
#define RP2_PINCTRL_GPIO_FUNC_UART 2
13+
#define RP2_PINCTRL_GPIO_FUNC_I2C 3
14+
#define RP2_PINCTRL_GPIO_FUNC_PWM 4
15+
#define RP2_PINCTRL_GPIO_FUNC_SIO 5
16+
#define RP2_PINCTRL_GPIO_FUNC_PIO0 6
17+
#define RP2_PINCTRL_GPIO_FUNC_PIO1 7
18+
#define RP2_PINCTRL_GPIO_FUNC_GPCK 8
19+
#define RP2_PINCTRL_GPIO_FUNC_USB 9
20+
#define RP2_PINCTRL_GPIO_FUNC_NULL 0xf
21+
22+
#define RP2_ALT_FUNC_POS 0
23+
#define RP2_ALT_FUNC_MASK 0xf
24+
25+
#define RP2_PIN_NUM_POS 4
26+
#define RP2_PIN_NUM_MASK 0x1f
27+
28+
#define RP2040_PINMUX(pin_num, alt_func) (pin_num << RP2_PIN_NUM_POS | \
29+
alt_func << RP2_ALT_FUNC_POS)
30+
31+
#define UART0_TX_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_UART)
32+
#define UART0_RX_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_UART)
33+
#define UART0_CTS_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_UART)
34+
#define UART0_RTS_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_UART)
35+
#define UART1_TX_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_UART)
36+
#define UART1_RX_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_UART)
37+
#define UART1_CTS_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_UART)
38+
#define UART1_RTS_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_UART)
39+
#define UART1_TX_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_UART)
40+
#define UART1_RX_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_UART)
41+
#define UART1_CTS_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_UART)
42+
#define UART1_RTS_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_UART)
43+
#define UART0_TX_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_UART)
44+
#define UART0_RX_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_UART)
45+
#define UART0_CTS_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_UART)
46+
#define UART0_RTS_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_UART)
47+
#define UART0_TX_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_UART)
48+
#define UART0_RX_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_UART)
49+
#define UART0_CTS_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_UART)
50+
#define UART0_RTS_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_UART)
51+
#define UART1_TX_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_UART)
52+
#define UART1_RX_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_UART)
53+
#define UART1_CTS_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_UART)
54+
#define UART1_RTS_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_UART)
55+
#define UART1_TX_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_UART)
56+
#define UART1_RX_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_UART)
57+
#define UART1_CTS_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_UART)
58+
#define UART1_RTS_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_UART)
59+
#define UART0_TX_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_UART)
60+
#define UART0_RX_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_UART)
61+
62+
#endif /* __RP2040_PINCTRL_H__ */

soc/arm/rpi_pico/Kconfig.defconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ if SOC_FAMILY_RPI_PICO
77

88
source "soc/arm/rpi_pico/*/Kconfig.defconfig.series"
99

10+
config PINCTRL
11+
default y
12+
1013
endif # SOC_FAMILY_RPI_PICO

soc/arm/rpi_pico/rp2/pinctrl_soc.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2021 Yonatan Schachter
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_
8+
#define ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_
9+
10+
#include <dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>
11+
12+
/**
13+
* @brief Type to hold a pin's pinctrl configuration.
14+
*/
15+
struct rpi_pinctrl_soc_pin {
16+
/** Pin number 0..29 */
17+
uint32_t pin_num : 5;
18+
/** Alternative function (UART, SPI, etc.) */
19+
uint32_t alt_func : 4;
20+
/** Maximum current used by a pin, in mA */
21+
uint32_t drive_strength : 4;
22+
/** Slew rate, may be either false (slow) or true (fast) */
23+
uint32_t slew_rate : 1;
24+
/** Enable the internal pull up resistor */
25+
uint32_t pullup : 1;
26+
/** Enable the internal pull down resistor */
27+
uint32_t pulldown : 1;
28+
/** Enable the pin as an input */
29+
uint32_t input_enable : 1;
30+
/** Enable the internal schmitt trigger */
31+
uint32_t schmitt_enable : 1;
32+
};
33+
34+
typedef struct rpi_pinctrl_soc_pin pinctrl_soc_pin_t;
35+
36+
/**
37+
* @brief Utility macro to initialize each pin.
38+
*
39+
* @param node_id Node identifier.
40+
* @param prop Property name.
41+
* @param idx Property entry index.
42+
*/
43+
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
44+
{ \
45+
RP2_GET_PIN_NUM(DT_PROP_BY_IDX(node_id, prop, idx)), \
46+
RP2_GET_PIN_ALT_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \
47+
DT_ENUM_IDX(node_id, drive_strength), \
48+
DT_ENUM_IDX(node_id, slew_rate), \
49+
DT_PROP(node_id, bias_pull_up), \
50+
DT_PROP(node_id, bias_pull_down), \
51+
DT_PROP(node_id, input_enable), \
52+
DT_PROP(node_id, input_schmitt_enable), \
53+
},
54+
55+
/**
56+
* @brief Utility macro to initialize state pins contained in a given property.
57+
*
58+
* @param node_id Node identifier.
59+
* @param prop Property name describing state pins.
60+
*/
61+
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
62+
{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \
63+
DT_FOREACH_PROP_ELEM, pinmux, \
64+
Z_PINCTRL_STATE_PIN_INIT)}
65+
66+
#define RP2_GET_PIN_NUM(pinctrl) \
67+
(((pinctrl) >> RP2_PIN_NUM_POS) & RP2_PIN_NUM_MASK)
68+
#define RP2_GET_PIN_ALT_FUNC(pinctrl) \
69+
(((pinctrl) >> RP2_ALT_FUNC_POS) & RP2_ALT_FUNC_MASK)
70+
71+
#endif /* ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ */

0 commit comments

Comments
 (0)