drivers: pinctrl: Added pinctrl driver for RPi Pico
Added a pinctrl driver for the Raspberry Pi Pico series Signed-off-by: Yonatan Schachter <yonatan.schachter@gmail.com>
This commit is contained in:
parent
db5b2780bf
commit
fd59038312
|
@ -491,6 +491,7 @@
|
|||
/dts/bindings/*/nordic* @anangl
|
||||
/dts/bindings/*/nxp* @mmahadevan108 @dleach02
|
||||
/dts/bindings/*/openisa* @dleach02
|
||||
/dts/bindings/*/raspberrypi*pico* @yonsch
|
||||
/dts/bindings/*/st* @erwango
|
||||
/dts/bindings/sensor/ams* @alexanderwachter
|
||||
/dts/bindings/*/sifive* @mateusz-holenko @kgugala @pgielda
|
||||
|
|
|
@ -7,4 +7,5 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AF pinctrl_gd32_af.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AFIO pinctrl_gd32_afio.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RCAR_PFC pfc_rcar.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c)
|
||||
|
|
|
@ -32,6 +32,7 @@ config PINCTRL_DYNAMIC
|
|||
source "drivers/pinctrl/Kconfig.gd32"
|
||||
source "drivers/pinctrl/Kconfig.nrf"
|
||||
source "drivers/pinctrl/Kconfig.rcar"
|
||||
source "drivers/pinctrl/Kconfig.rpi_pico"
|
||||
source "drivers/pinctrl/Kconfig.stm32"
|
||||
|
||||
endif # PINCTRL
|
||||
|
|
12
drivers/pinctrl/Kconfig.rpi_pico
Normal file
12
drivers/pinctrl/Kconfig.rpi_pico
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Copyright (c) 2021 Yonatan Schachter
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
DT_COMPAT_RPI_PICO_PINCTRL := raspberrypi,pico-pinctrl
|
||||
|
||||
config PINCTRL_RPI_PICO
|
||||
bool "RaspberryPi Pico pin controller driver"
|
||||
depends on SOC_FAMILY_RPI_PICO
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_RPI_PICO_PINCTRL))
|
||||
select PICOSDK_USE_GPIO
|
||||
help
|
||||
RaspberryPi Pico pinctrl driver
|
34
drivers/pinctrl/pinctrl_rpi_pico.c
Normal file
34
drivers/pinctrl/pinctrl_rpi_pico.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Yonatan Schachter
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/pinctrl.h>
|
||||
|
||||
/* pico-sdk includes */
|
||||
#include <hardware/gpio.h>
|
||||
|
||||
static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
|
||||
{
|
||||
gpio_init(pin->pin_num);
|
||||
gpio_set_function(pin->pin_num, pin->alt_func);
|
||||
gpio_set_pulls(pin->pin_num, pin->pullup, pin->pulldown);
|
||||
gpio_set_drive_strength(pin->pin_num, pin->drive_strength);
|
||||
gpio_set_slew_rate(pin->pin_num, (pin->slew_rate ?
|
||||
GPIO_SLEW_RATE_FAST : GPIO_SLEW_RATE_SLOW));
|
||||
gpio_set_input_hysteresis_enabled(pin->pin_num, pin->schmitt_enable);
|
||||
gpio_set_input_enabled(pin->pin_num, pin->input_enable);
|
||||
}
|
||||
|
||||
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
|
||||
uintptr_t reg)
|
||||
{
|
||||
ARG_UNUSED(reg);
|
||||
|
||||
for (uint8_t i = 0U; i < pin_cnt; i++) {
|
||||
pinctrl_configure_pin(pins++);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -43,6 +43,13 @@
|
|||
clock-frequency = <125000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
pinctrl: pin-controller@40014000 {
|
||||
compatible = "raspberrypi,pico-pinctrl";
|
||||
reg = <0x40014000 DT_SIZE_K(4)>;
|
||||
status = "okay";
|
||||
label = "PINCTRL";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
123
dts/bindings/pinctrl/raspberrypi,pico-pinctrl.yaml
Normal file
123
dts/bindings/pinctrl/raspberrypi,pico-pinctrl.yaml
Normal file
|
@ -0,0 +1,123 @@
|
|||
# Copyright (c) 2021 Teslabs Engineering S.L.
|
||||
# Copyright (c) 2021 Yonatan Schachter
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
The RPi Pico pin controller is a node responsible for controlling
|
||||
pin function selection and pin properties, such as routing a UART0 Rx
|
||||
to pin 1 and enabling the pullup resistor on that pin.
|
||||
|
||||
The node has the 'pinctrl' node label set in your SoC's devicetree,
|
||||
so you can modify it like this:
|
||||
|
||||
&pinctrl {
|
||||
/* your modifications go here */
|
||||
};
|
||||
|
||||
All device pin configurations should be placed in child nodes of the
|
||||
'pinctrl' node, as shown in this example:
|
||||
|
||||
/* You can put this in places like a board-pinctrl.dtsi file in
|
||||
* your board directory, or a devicetree overlay in your application.
|
||||
*/
|
||||
|
||||
/* include pre-defined combinations for the SoC variant used by the board */
|
||||
#include <dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>
|
||||
|
||||
&pinctrl {
|
||||
/* configuration for the usart0 "default" state */
|
||||
uart0_default: uart0_default {
|
||||
/* group 1 */
|
||||
group1 {
|
||||
/* configure P0 as UART0 TX */
|
||||
pinmux = <UART0_TX_P0>;
|
||||
};
|
||||
/* group 2 */
|
||||
group2 {
|
||||
/* configure P1 as UART0 RX */
|
||||
pinmux = <UART0_RX_P1>;
|
||||
/* enable input on pin 1 */
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
The 'uart0_default' child node encodes the pin configurations for a
|
||||
particular state of a device; in this case, the default (that is, active)
|
||||
state.
|
||||
|
||||
As shown, pin configurations are organized in groups within each child node.
|
||||
Each group can specify a list of pin function selections in the 'pinmux'
|
||||
property.
|
||||
|
||||
A group can also specify shared pin properties common to all the specified
|
||||
pins, such as the 'input-enable' property in group 2. Here is a list of
|
||||
supported standard pin properties:
|
||||
|
||||
- bias-disable: Disable pull-up/down (default, not required).
|
||||
- bias-pull-up: Enable pull-up resistor.
|
||||
- bias-pull-down: Enable pull-down resistor.
|
||||
- input-enable: Enable input from the pin.
|
||||
- input-schmitt-enable: Enable input hysteresys.
|
||||
- drive-strength: Set the drive strength of the pin, in milliamps. Possible
|
||||
values are: 2, 4, 8, 12 (default: 4mA)
|
||||
- slew-rate: If set to 0, slew rate is set to slow. If set to 1, it is set
|
||||
to fast.
|
||||
|
||||
To link pin configurations with a device, use a pinctrl-N property for some
|
||||
number N, like this example you could place in your board's DTS file:
|
||||
|
||||
#include "board-pinctrl.dtsi"
|
||||
|
||||
&uart0 {
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-1 = <&uart0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
compatible: "raspberrypi,pico-pinctrl"
|
||||
|
||||
include:
|
||||
- name: base.yaml
|
||||
- name: pincfg-node-group.yaml
|
||||
child-binding:
|
||||
child-binding:
|
||||
property-allowlist:
|
||||
- bias-disable
|
||||
- bias-pull-down
|
||||
- bias-pull-up
|
||||
- input-enable
|
||||
- input-schmitt-enable
|
||||
- drive-strength
|
||||
- slew-rate
|
||||
|
||||
child-binding:
|
||||
description: |
|
||||
Definitions for a pinctrl state.
|
||||
child-binding:
|
||||
properties:
|
||||
pinmux:
|
||||
required: true
|
||||
type: array
|
||||
description: |
|
||||
An array of pins sharing the same group properties. Each
|
||||
element of the array is an integer constructed from the
|
||||
pin number and the alternative function of the pin.
|
||||
drive-strength:
|
||||
enum:
|
||||
- 2
|
||||
- 4
|
||||
- 8
|
||||
- 12
|
||||
default: 4
|
||||
description: |
|
||||
The drive strength of a pin, in mA. The default value is 4mA, as this
|
||||
is the power on reset value.
|
||||
slew-rate:
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
default: 0
|
||||
description: |
|
||||
The slew rate of a pin. 0 corresponds to slow, and 1 corresponds to fast.
|
||||
The default value is 0 (slow), as this is the power on reset value.
|
62
include/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h
Normal file
62
include/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Yonatan Schachter
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __RP2040_PINCTRL_H__
|
||||
#define __RP2040_PINCTRL_H__
|
||||
|
||||
#define RP2_PINCTRL_GPIO_FUNC_XIP 0
|
||||
#define RP2_PINCTRL_GPIO_FUNC_SPI 1
|
||||
#define RP2_PINCTRL_GPIO_FUNC_UART 2
|
||||
#define RP2_PINCTRL_GPIO_FUNC_I2C 3
|
||||
#define RP2_PINCTRL_GPIO_FUNC_PWM 4
|
||||
#define RP2_PINCTRL_GPIO_FUNC_SIO 5
|
||||
#define RP2_PINCTRL_GPIO_FUNC_PIO0 6
|
||||
#define RP2_PINCTRL_GPIO_FUNC_PIO1 7
|
||||
#define RP2_PINCTRL_GPIO_FUNC_GPCK 8
|
||||
#define RP2_PINCTRL_GPIO_FUNC_USB 9
|
||||
#define RP2_PINCTRL_GPIO_FUNC_NULL 0xf
|
||||
|
||||
#define RP2_ALT_FUNC_POS 0
|
||||
#define RP2_ALT_FUNC_MASK 0xf
|
||||
|
||||
#define RP2_PIN_NUM_POS 4
|
||||
#define RP2_PIN_NUM_MASK 0x1f
|
||||
|
||||
#define RP2040_PINMUX(pin_num, alt_func) (pin_num << RP2_PIN_NUM_POS | \
|
||||
alt_func << RP2_ALT_FUNC_POS)
|
||||
|
||||
#define UART0_TX_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RX_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_CTS_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RTS_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_TX_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RX_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_CTS_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RTS_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_TX_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RX_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_CTS_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RTS_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_TX_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RX_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_CTS_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RTS_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_TX_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RX_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_CTS_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RTS_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_TX_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RX_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_CTS_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RTS_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_TX_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RX_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_CTS_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART1_RTS_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_TX_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
#define UART0_RX_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_UART)
|
||||
|
||||
#endif /* __RP2040_PINCTRL_H__ */
|
|
@ -7,4 +7,7 @@ if SOC_FAMILY_RPI_PICO
|
|||
|
||||
source "soc/arm/rpi_pico/*/Kconfig.defconfig.series"
|
||||
|
||||
config PINCTRL
|
||||
default y
|
||||
|
||||
endif # SOC_FAMILY_RPI_PICO
|
||||
|
|
71
soc/arm/rpi_pico/rp2/pinctrl_soc.h
Normal file
71
soc/arm/rpi_pico/rp2/pinctrl_soc.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Yonatan Schachter
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_
|
||||
#define ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_
|
||||
|
||||
#include <dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>
|
||||
|
||||
/**
|
||||
* @brief Type to hold a pin's pinctrl configuration.
|
||||
*/
|
||||
struct rpi_pinctrl_soc_pin {
|
||||
/** Pin number 0..29 */
|
||||
uint32_t pin_num : 5;
|
||||
/** Alternative function (UART, SPI, etc.) */
|
||||
uint32_t alt_func : 4;
|
||||
/** Maximum current used by a pin, in mA */
|
||||
uint32_t drive_strength : 4;
|
||||
/** Slew rate, may be either false (slow) or true (fast) */
|
||||
uint32_t slew_rate : 1;
|
||||
/** Enable the internal pull up resistor */
|
||||
uint32_t pullup : 1;
|
||||
/** Enable the internal pull down resistor */
|
||||
uint32_t pulldown : 1;
|
||||
/** Enable the pin as an input */
|
||||
uint32_t input_enable : 1;
|
||||
/** Enable the internal schmitt trigger */
|
||||
uint32_t schmitt_enable : 1;
|
||||
};
|
||||
|
||||
typedef struct rpi_pinctrl_soc_pin pinctrl_soc_pin_t;
|
||||
|
||||
/**
|
||||
* @brief Utility macro to initialize each pin.
|
||||
*
|
||||
* @param node_id Node identifier.
|
||||
* @param prop Property name.
|
||||
* @param idx Property entry index.
|
||||
*/
|
||||
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
|
||||
{ \
|
||||
RP2_GET_PIN_NUM(DT_PROP_BY_IDX(node_id, prop, idx)), \
|
||||
RP2_GET_PIN_ALT_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \
|
||||
DT_ENUM_IDX(node_id, drive_strength), \
|
||||
DT_ENUM_IDX(node_id, slew_rate), \
|
||||
DT_PROP(node_id, bias_pull_up), \
|
||||
DT_PROP(node_id, bias_pull_down), \
|
||||
DT_PROP(node_id, input_enable), \
|
||||
DT_PROP(node_id, input_schmitt_enable), \
|
||||
},
|
||||
|
||||
/**
|
||||
* @brief Utility macro to initialize state pins contained in a given property.
|
||||
*
|
||||
* @param node_id Node identifier.
|
||||
* @param prop Property name describing state pins.
|
||||
*/
|
||||
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
|
||||
{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \
|
||||
DT_FOREACH_PROP_ELEM, pinmux, \
|
||||
Z_PINCTRL_STATE_PIN_INIT)}
|
||||
|
||||
#define RP2_GET_PIN_NUM(pinctrl) \
|
||||
(((pinctrl) >> RP2_PIN_NUM_POS) & RP2_PIN_NUM_MASK)
|
||||
#define RP2_GET_PIN_ALT_FUNC(pinctrl) \
|
||||
(((pinctrl) >> RP2_ALT_FUNC_POS) & RP2_ALT_FUNC_MASK)
|
||||
|
||||
#endif /* ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ */
|
Loading…
Reference in a new issue