drivers: pinctrl: nrf: initial support
Add initial support for nRF pin controller driver. The implementation in this patch does not yet support any peripheral. Only states representation and basic driver functionality is introduced. Note: The nrf_pin_configure function has been marked as __unused since it may not be used in certain scenarios until all peripherals are supported by the pinctrl driver. For example, if only UART/E is supported but the board does not enable UART, the function will never get called. However, that board will likely have other peripherals that will gain support in the future. Thanks to Marti Bolivar for bindings documentation. Co-authored-by: Marti Bolivar <marti.bolivar@nordicsemi.no> Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
5aedcabf51
commit
22c8c02145
|
@ -5,4 +5,5 @@ zephyr_library()
|
|||
zephyr_library_sources(common.c)
|
||||
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_STM32 pinctrl_stm32.c)
|
||||
|
|
|
@ -30,6 +30,7 @@ config PINCTRL_DYNAMIC
|
|||
peripheral at early boot stages depending on a certain input.
|
||||
|
||||
source "drivers/pinctrl/Kconfig.gd32"
|
||||
source "drivers/pinctrl/Kconfig.nrf"
|
||||
source "drivers/pinctrl/Kconfig.stm32"
|
||||
|
||||
endif # PINCTRL
|
||||
|
|
10
drivers/pinctrl/Kconfig.nrf
Normal file
10
drivers/pinctrl/Kconfig.nrf
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config PINCTRL_NRF
|
||||
bool "nRF pin controller driver"
|
||||
depends on SOC_FAMILY_NRF
|
||||
select PINCTRL_STORE_REG
|
||||
default y
|
||||
help
|
||||
nRF pin controller driver
|
64
drivers/pinctrl/pinctrl_nrf.c
Normal file
64
drivers/pinctrl/pinctrl_nrf.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/pinctrl.h>
|
||||
|
||||
#include <hal/nrf_gpio.h>
|
||||
|
||||
BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) &&
|
||||
(NRF_PULL_DOWN == NRF_GPIO_PIN_PULLDOWN) &&
|
||||
(NRF_PULL_UP == NRF_GPIO_PIN_PULLUP)),
|
||||
"nRF pinctrl pull settings do not match HAL values");
|
||||
|
||||
BUILD_ASSERT(((NRF_DRIVE_S0S1 == NRF_GPIO_PIN_S0S1) &&
|
||||
(NRF_DRIVE_H0S1 == NRF_GPIO_PIN_H0S1) &&
|
||||
(NRF_DRIVE_S0H1 == NRF_GPIO_PIN_S0H1) &&
|
||||
(NRF_DRIVE_H0H1 == NRF_GPIO_PIN_H0H1) &&
|
||||
(NRF_DRIVE_D0S1 == NRF_GPIO_PIN_D0S1) &&
|
||||
(NRF_DRIVE_D0H1 == NRF_GPIO_PIN_D0H1) &&
|
||||
(NRF_DRIVE_S0D1 == NRF_GPIO_PIN_S0D1) &&
|
||||
(NRF_DRIVE_H0D1 == NRF_GPIO_PIN_H0D1) &&
|
||||
#if defined(GPIO_PIN_CNF_DRIVE_E0E1)
|
||||
(NRF_DRIVE_E0E1 == NRF_GPIO_PIN_E0E1) &&
|
||||
#endif /* defined(GPIO_PIN_CNF_DRIVE_E0E1) */
|
||||
(1U)),
|
||||
"nRF pinctrl drive settings do not match HAL values");
|
||||
|
||||
/**
|
||||
* @brief Configure pin settings.
|
||||
*
|
||||
* @param pin Pin configuration.
|
||||
* @param dir Pin direction.
|
||||
* @param input Pin input buffer connection.
|
||||
*/
|
||||
__unused static void nrf_pin_configure(pinctrl_soc_pin_t pin,
|
||||
nrf_gpio_pin_dir_t dir,
|
||||
nrf_gpio_pin_input_t input)
|
||||
{
|
||||
/* force input direction and disconnected buffer for low power */
|
||||
if (NRF_GET_LP(pin) == NRF_LP_ENABLE) {
|
||||
dir = NRF_GPIO_PIN_DIR_INPUT;
|
||||
input = NRF_GPIO_PIN_INPUT_DISCONNECT;
|
||||
}
|
||||
|
||||
nrf_gpio_cfg(NRF_GET_PIN(pin), dir, input, NRF_GET_PULL(pin),
|
||||
NRF_GET_DRIVE(pin), NRF_GPIO_PIN_NOSENSE);
|
||||
}
|
||||
|
||||
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++) {
|
||||
switch (NRF_GET_FUN(pins[i])) {
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <dt-bindings/i2c/i2c.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/nrf-pinctrl.h>
|
||||
|
||||
#include <arm/nordic/override.dtsi>
|
||||
/*
|
||||
|
@ -16,6 +17,16 @@
|
|||
#define NRF_DEFAULT_IRQ_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/ {
|
||||
pinctrl: pin-controller {
|
||||
/* Pin controller is a "virtual" device since nRF SoCs do pin
|
||||
* control in a distributed way (GPIO registers and PSEL
|
||||
* registers on each peripheral).
|
||||
*/
|
||||
compatible = "nordic,nrf-pinctrl";
|
||||
};
|
||||
};
|
||||
|
||||
&systick {
|
||||
/*
|
||||
* Nordic SoCs rely by default on the RTC for system clock
|
||||
|
|
110
dts/bindings/pinctrl/nordic,nrf-pinctrl.yaml
Normal file
110
dts/bindings/pinctrl/nordic,nrf-pinctrl.yaml
Normal file
|
@ -0,0 +1,110 @@
|
|||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
The nRF pin controller is a singleton node responsible for controlling
|
||||
pin function selection and pin properties. For example, you can use this
|
||||
node to route UART0 RX to pin P0.1 and enable the pull-up resistor on the
|
||||
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.
|
||||
*/
|
||||
&pinctrl {
|
||||
/* configuration for uart0 device, default state */
|
||||
uart0_default: uart0_default {
|
||||
/* group 1 ('group1' name is arbitrary) */
|
||||
group1 {
|
||||
/* configure P0.1 as UART_TX and P0.2 as UART_RTS */
|
||||
psels = <NRF_PSEL(UART_TX, 0, 1)>, <NRF_PSEL(UART_RTS, 0, 2)>;
|
||||
};
|
||||
/* group 2 */
|
||||
group2 {
|
||||
/* configure P0.3 as UART_RX and P0.4 as UART_CTS */
|
||||
psels = <NRF_PSEL(UART_RX, 0, 3)>, <NRF_PSEL(UART_CTS, 0, 4)>;
|
||||
/* both P0.3 and P0.4 are configured with pull-up */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
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. You would specify the low-power configuration for the same device
|
||||
in a separate child node.
|
||||
|
||||
As shown, pin configurations are organized in groups within each child node.
|
||||
Each group can specify a list of pin function selections in the 'psels'
|
||||
property. The NRF_PSEL macro is used to specify a pin function selection.
|
||||
Available pin functions can be found in the
|
||||
include/dt-bindings/pinctrl/nrf-pinctrl.h header file.
|
||||
|
||||
A group can also specify shared pin properties common to all the specified
|
||||
pins, such as the 'bias-pull-up' property in group 2. Here is a list of
|
||||
supported standard pin properties:
|
||||
|
||||
- bias-disable: Disable pull-up/down (default behavior, not required).
|
||||
- bias-pull-up: Enable pull-up resistor.
|
||||
- bias-pull-down: Enable pull-down resistor.
|
||||
- low-power-enable: Configure pin as an input with input buffer
|
||||
disconnected.
|
||||
|
||||
Note that bias options are mutually exclusive.
|
||||
|
||||
To link this pin configuration 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-names = "default";
|
||||
};
|
||||
|
||||
compatible: "nordic,nrf-pinctrl"
|
||||
|
||||
include:
|
||||
- name: base.yaml
|
||||
- name: pincfg-node-group.yaml
|
||||
child-binding:
|
||||
child-binding:
|
||||
property-allowlist:
|
||||
- bias-disable
|
||||
- bias-pull-down
|
||||
- bias-pull-up
|
||||
- low-power-enable
|
||||
|
||||
child-binding:
|
||||
description: |
|
||||
nRF pin controller pin configuration state nodes.
|
||||
child-binding:
|
||||
description: |
|
||||
nRF pin controller pin configuration group.
|
||||
properties:
|
||||
psels:
|
||||
required: true
|
||||
type: array
|
||||
description: |
|
||||
An array of pins sharing the same group properties. The pins should
|
||||
be defined using the NRF_PSEL utility macro that encodes the port,
|
||||
pin and function.
|
||||
|
||||
drive-mode:
|
||||
type: int
|
||||
default: 0
|
||||
description: |
|
||||
Pin output drive mode. Available drive modes are pre-defined in
|
||||
nrf-pinctrl.h. Note that extra modes may not be available on certain
|
||||
devices. Defaults to standard mode for 0 and 1 (NRF_DRIVE_S0S1), the
|
||||
SoC default.
|
121
include/dt-bindings/pinctrl/nrf-pinctrl.h
Normal file
121
include/dt-bindings/pinctrl/nrf-pinctrl.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_NRF_PINCTRL_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_NRF_PINCTRL_H_
|
||||
|
||||
/*
|
||||
* The whole nRF pin configuration information is encoded in a 32-bit bitfield
|
||||
* organized as follows:
|
||||
*
|
||||
* - 31..16: Pin function.
|
||||
* - 15..13: Reserved.
|
||||
* - 12: Pin low power mode.
|
||||
* - 11..8: Pin output drive configuration.
|
||||
* - 7..6: Pin pull configuration.
|
||||
* - 5..0: Pin number (combination of port and pin).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name nRF pin configuration bit field positions and masks.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Position of the function field. */
|
||||
#define NRF_FUN_POS 16U
|
||||
/** Mask for the function field. */
|
||||
#define NRF_FUN_MSK 0xFFFFU
|
||||
/** Position of the low power field. */
|
||||
#define NRF_LP_POS 12U
|
||||
/** Mask for the low power field. */
|
||||
#define NRF_LP_MSK 0x1U
|
||||
/** Position of the drive configuration field. */
|
||||
#define NRF_DRIVE_POS 8U
|
||||
/** Mask for the drive configuration field. */
|
||||
#define NRF_DRIVE_MSK 0xFU
|
||||
/** Position of the pull configuration field. */
|
||||
#define NRF_PULL_POS 6U
|
||||
/** Mask for the pull configuration field. */
|
||||
#define NRF_PULL_MSK 0x3U
|
||||
/** Position of the pin field. */
|
||||
#define NRF_PIN_POS 0U
|
||||
/** Mask for the pin field. */
|
||||
#define NRF_PIN_MSK 0x3FU
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name nRF pinctrl pin functions.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name nRF pinctrl output drive.
|
||||
* @note Values match nrf_gpio_pin_drive_t constants.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Standard '0', standard '1'. */
|
||||
#define NRF_DRIVE_S0S1 0U
|
||||
/** High drive '0', standard '1'. */
|
||||
#define NRF_DRIVE_H0S1 1U
|
||||
/** Standard '0', high drive '1'. */
|
||||
#define NRF_DRIVE_S0H1 2U
|
||||
/** High drive '0', high drive '1'. */
|
||||
#define NRF_DRIVE_H0H1 3U
|
||||
/** Disconnect '0' standard '1'. */
|
||||
#define NRF_DRIVE_D0S1 4U
|
||||
/** Disconnect '0', high drive '1'. */
|
||||
#define NRF_DRIVE_D0H1 5U
|
||||
/** Standard '0', disconnect '1'. */
|
||||
#define NRF_DRIVE_S0D1 6U
|
||||
/** High drive '0', disconnect '1'. */
|
||||
#define NRF_DRIVE_H0D1 7U
|
||||
/** Extra high drive '0', extra high drive '1'. */
|
||||
#define NRF_DRIVE_E0E1 11U
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name nRF pinctrl pull-up/down.
|
||||
* @note Values match nrf_gpio_pin_pull_t constants.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Pull-up disabled. */
|
||||
#define NRF_PULL_NONE 0U
|
||||
/** Pull-down enabled. */
|
||||
#define NRF_PULL_DOWN 1U
|
||||
/** Pull-up enabled. */
|
||||
#define NRF_PULL_UP 3U
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name nRF pinctrl low power mode.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Input. */
|
||||
#define NRF_LP_DISABLE 0U
|
||||
/** Output. */
|
||||
#define NRF_LP_ENABLE 1U
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Utility macro to build nRF psels property entry.
|
||||
*
|
||||
* @param fun Pin function configuration (see NRF_FUNC_{name} macros).
|
||||
* @param port Port (0 or 1).
|
||||
* @param pin Pin (0..31).
|
||||
*/
|
||||
#define NRF_PSEL(fun, port, pin) \
|
||||
((((((port) * 32U) + (pin)) & NRF_PIN_MSK) << NRF_PIN_POS) | \
|
||||
((NRF_FUN_ ## fun & NRF_FUN_MSK) << NRF_FUN_POS))
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_NRF_PINCTRL_H_ */
|
|
@ -2,3 +2,4 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_NRF soc_nrf_common.S)
|
||||
zephyr_include_directories(.)
|
||||
|
|
95
soc/arm/nordic_nrf/common/pinctrl_soc.h
Normal file
95
soc/arm/nordic_nrf/common/pinctrl_soc.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* nRF SoC specific helpers for pinctrl driver
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_ARM_NORDIC_NRF_COMMON_PINCTRL_SOC_H_
|
||||
#define ZEPHYR_SOC_ARM_NORDIC_NRF_COMMON_PINCTRL_SOC_H_
|
||||
|
||||
#include <devicetree.h>
|
||||
#include <dt-bindings/pinctrl/nrf-pinctrl.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
||||
/** Type for nRF pin. */
|
||||
typedef uint32_t 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) \
|
||||
(DT_PROP_BY_IDX(node_id, prop, idx) | \
|
||||
((NRF_PULL_DOWN * DT_PROP(node_id, bias_pull_down)) << NRF_PULL_POS) |\
|
||||
((NRF_PULL_UP * DT_PROP(node_id, bias_pull_up)) << NRF_PULL_POS) | \
|
||||
(DT_PROP(node_id, drive_mode) << NRF_DRIVE_POS) | \
|
||||
((NRF_LP_ENABLE * DT_PROP(node_id, low_power_enable)) << NRF_LP_POS) \
|
||||
),
|
||||
|
||||
/**
|
||||
* @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, psels, \
|
||||
Z_PINCTRL_STATE_PIN_INIT)}
|
||||
|
||||
/**
|
||||
* @brief Utility macro to obtain pin function.
|
||||
*
|
||||
* @param pincfg Pin configuration bit field.
|
||||
*/
|
||||
#define NRF_GET_FUN(pincfg) (((pincfg) >> NRF_FUN_POS) & NRF_FUN_MSK)
|
||||
|
||||
/**
|
||||
* @brief Utility macro to obtain pin low power flag.
|
||||
*
|
||||
* @param pincfg Pin configuration bit field.
|
||||
*/
|
||||
#define NRF_GET_LP(pincfg) (((pincfg) >> NRF_LP_POS) & NRF_LP_MSK)
|
||||
|
||||
/**
|
||||
* @brief Utility macro to obtain pin drive mode.
|
||||
*
|
||||
* @param pincfg Pin configuration bit field.
|
||||
*/
|
||||
#define NRF_GET_DRIVE(pincfg) (((pincfg) >> NRF_DRIVE_POS) & NRF_DRIVE_MSK)
|
||||
|
||||
/**
|
||||
* @brief Utility macro to obtain pin pull configuration.
|
||||
*
|
||||
* @param pincfg Pin configuration bit field.
|
||||
*/
|
||||
#define NRF_GET_PULL(pincfg) (((pincfg) >> NRF_PULL_POS) & NRF_PULL_MSK)
|
||||
|
||||
/**
|
||||
* @brief Utility macro to obtain port and pin combination.
|
||||
*
|
||||
* @param pincfg Pin configuration bit field.
|
||||
*/
|
||||
#define NRF_GET_PIN(pincfg) (((pincfg) >> NRF_PIN_POS) & NRF_PIN_MSK)
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_SOC_ARM_NORDIC_NRF_COMMON_PINCTRL_SOC_H_ */
|
Loading…
Reference in a new issue