drivers: pinctrl: Update atmel sam driver to new api

This update current Atmel sam pinctrl initiative to current Zephyr
pinctrl API. It update current devicetree bindings and add the sam
pinctrl driver.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
This commit is contained in:
Gerson Fernando Budke 2022-03-10 21:56:45 -03:00 committed by Marti Bolivar
commit cb201430cf
8 changed files with 305 additions and 11 deletions

View file

@ -9,6 +9,7 @@ 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_NRF pinctrl_nrf.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RCAR_PFC pfc_rcar.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_RPI_PICO pinctrl_rpi_pico.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_KINETIS pinctrl_kinetis.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_KINETIS pinctrl_kinetis.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_XEC pinctrl_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_XEC pinctrl_mchp_xec.c)

View file

@ -34,6 +34,7 @@ source "drivers/pinctrl/Kconfig.gd32"
source "drivers/pinctrl/Kconfig.nrf" source "drivers/pinctrl/Kconfig.nrf"
source "drivers/pinctrl/Kconfig.rcar" source "drivers/pinctrl/Kconfig.rcar"
source "drivers/pinctrl/Kconfig.rpi_pico" source "drivers/pinctrl/Kconfig.rpi_pico"
source "drivers/pinctrl/Kconfig.sam"
source "drivers/pinctrl/Kconfig.stm32" source "drivers/pinctrl/Kconfig.stm32"
source "drivers/pinctrl/Kconfig.kinetis" source "drivers/pinctrl/Kconfig.kinetis"
source "drivers/pinctrl/Kconfig.xec" source "drivers/pinctrl/Kconfig.xec"

View file

@ -0,0 +1,11 @@
# Copyright (c) 2022, Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0
DT_COMPAT_ATMEL_SAM_PINCTRL := atmel,sam-pinctrl
config PINCTRL_SAM
bool "Atmel SAM pin controller driver"
depends on SOC_FAMILY_SAM
default $(dt_compat_enabled,$(DT_COMPAT_ATMEL_SAM_PINCTRL))
help
Atmel pin controller driver is used on SAM and SAM4L SoC series

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2022, Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <drivers/pinctrl.h>
#include <soc_gpio.h>
/** Utility macro that expands to the GPIO port address if it exists */
#define SAM_PORT_ADDR_OR_NONE(nodelabel) \
IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \
(DT_REG_ADDR(DT_NODELABEL(nodelabel)),))
/** Utility macro that expands to the GPIO Peripheral ID if it exists */
#define SAM_PORT_PERIPH_ID_OR_NONE(nodelabel) \
IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \
(DT_PROP(DT_NODELABEL(nodelabel), peripheral_id),))
/** SAM port addresses */
static const uint32_t sam_port_addrs[] = {
#ifdef ID_GPIO
SAM_PORT_ADDR_OR_NONE(gpioa)
SAM_PORT_ADDR_OR_NONE(gpiob)
SAM_PORT_ADDR_OR_NONE(gpioc)
#else
SAM_PORT_ADDR_OR_NONE(pioa)
SAM_PORT_ADDR_OR_NONE(piob)
SAM_PORT_ADDR_OR_NONE(pioc)
SAM_PORT_ADDR_OR_NONE(piod)
SAM_PORT_ADDR_OR_NONE(pioe)
SAM_PORT_ADDR_OR_NONE(piof)
#endif
};
/** SAM port peripheral id */
static const uint32_t sam_port_periph_id[] = {
#ifdef ID_GPIO
SAM_PORT_PERIPH_ID_OR_NONE(gpioa)
SAM_PORT_PERIPH_ID_OR_NONE(gpiob)
SAM_PORT_PERIPH_ID_OR_NONE(gpioc)
#else
SAM_PORT_PERIPH_ID_OR_NONE(pioa)
SAM_PORT_PERIPH_ID_OR_NONE(piob)
SAM_PORT_PERIPH_ID_OR_NONE(pioc)
SAM_PORT_PERIPH_ID_OR_NONE(piod)
SAM_PORT_PERIPH_ID_OR_NONE(pioe)
SAM_PORT_PERIPH_ID_OR_NONE(piof)
#endif
};
static void pinctrl_configure_pin(pinctrl_soc_pin_t pin)
{
struct soc_gpio_pin soc_pin;
uint8_t port_idx, port_func;
port_idx = SAM_PINMUX_PORT_GET(pin);
__ASSERT_NO_MSG(port_idx < ARRAY_SIZE(sam_port_addrs));
port_func = SAM_PINMUX_FUNC_GET(pin);
#ifdef ID_GPIO
soc_pin.regs = (Gpio *) sam_port_addrs[port_idx];
#else
soc_pin.regs = (Pio *) sam_port_addrs[port_idx];
#endif
soc_pin.periph_id = sam_port_periph_id[port_idx];
soc_pin.mask = 1 << SAM_PINMUX_PIN_GET(pin);
soc_pin.flags = SAM_PINCTRL_FLAGS_GET(pin) << SOC_GPIO_FLAGS_POS;
if (port_func == SAM_PINMUX_FUNC_periph) {
soc_pin.flags |= (SAM_PINMUX_PERIPH_GET(pin)
<< SOC_GPIO_FUNC_POS);
}
soc_gpio_configure(&soc_pin);
}
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;
}

View file

@ -1,22 +1,87 @@
# Copyright (c) 2020, Linaro Limited # Copyright (c) 2020, Linaro Limited
# Copyright (c) 2021, Gerson Fernando Budke # Copyright (c) 2021, Teslabs Engineering S.L.
# Copyright (c) 2021-2022, Gerson Fernando Budke <nandojve@gmail.com>
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
description: | description: |
Atmel SAM Pinctrl container node Atmel SAM Pinctrl container node
The Atmel SAM pins implements following pin configuration option: The Atmel SAM pin controller is a singleton node responsible for controlling
pin function selection and pin properties. For example, you can use this node
to route USART0 RX to pin PA10 and enable the pull-up resistor on the pin.
* bias-pull-up The node has the 'pinctrl' node label set in your SoC's devicetree, so you can
* bias-pull-down modify it like this:
* drive-open-drain
These options define devicetree flags that are converted to SoC flags at &pinctrl {
ATMEL_SAM_PIN_FLAGS(). /* 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/sam4sXc-pinctrl.h>
&pinctrl {
/* configuration for the usart0 "default" state */
usart0_default: usart0_default {
/* group 1 */
group1 {
/* configure PA6 as USART0 TX and PA8 as USART0 CTS */
pinmux = <PA6A_USART0_TXD0>, <PA8A_USART0_CTS0>;
};
/* group 2 */
group2 {
/* configure PA5 as USART0 RX and PA7 as USART0 RTS */
pinmux = <PA5A_USART0_RXD0>, <PA7A_USART0_RTS0>;
/* both PA5 and PA7 have pull-up enabled */
bias-pull-up;
};
};
};
The 'usart0_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 'bias-pull-up' property in group 2. Here is a list of
supported standard pin properties:
- bias-pull-up: Enable pull-up resistor.
- bias-pull-down: Enable pull-down resistor.
- drive-open-drain: Open-drain drive mode.
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"
&usart0 {
pinctrl-0 = <&usart0_default>;
pinctrl-names = "default";
};
compatible: "atmel,sam-pinctrl" compatible: "atmel,sam-pinctrl"
include: [base.yaml, pincfg-node.yaml] include:
- name: base.yaml
- name: pincfg-node-group.yaml
child-binding:
child-binding:
property-allowlist:
- bias-pull-up
- bias-pull-down
- drive-open-drain
properties: properties:
"#address-cells": "#address-cells":
@ -27,7 +92,17 @@ properties:
const: 1 const: 1
child-binding: child-binding:
description: Atmel pins description: |
Each child node defines the configuration for a particular state.
child-binding:
description: |
The grandchild nodes group pins that share the same pin configuration.
properties: properties:
"atmel,pins": pinmux:
type: phandle-array required: true
type: array
description: |
An array of pins sharing the same group properties. The pins should
be defined using pre-defined macros or, alternatively, using the
SAM_PINMUX utility macros depending on the pinmux model used by the
SoC series.

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2022, Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* Atmel SAM SoC specific helpers for pinctrl driver
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_SAM_COMMON_H_
#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_SAM_COMMON_H_
#include <devicetree.h>
#include <zephyr/types.h>
#include <dt-bindings/pinctrl/atmel_sam_pinctrl.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @cond INTERNAL_HIDDEN */
/** @brief Type for SAM pin.
*
* Bits:
* - 0-15: SAM pinmux bit field (@ref SAM_PINMUX).
* - 16-21: Pin flags bit field (@ref SAM_PINFLAGS).
* - 22-31: Reserved.
*/
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) << SAM_PINCTRL_PINMUX_POS) \
| (DT_PROP(node_id, bias_pull_up) << SAM_PINCTRL_PULLUP_POS) \
| (DT_PROP(node_id, bias_pull_down) << SAM_PINCTRL_PULLDOWN_POS) \
| (DT_PROP(node_id, drive_open_drain) << SAM_PINCTRL_OPENDRAIN_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, pinmux, \
Z_PINCTRL_STATE_PIN_INIT)}
/** @endcond */
/**
* @brief Pin flags/attributes
* @anchor SAM_PINFLAGS
*
* @{
*/
#define SAM_PINCTRL_FLAGS_DEFAULT (0U)
#define SAM_PINCTRL_FLAGS_POS (0U)
#define SAM_PINCTRL_FLAGS_MASK (0x7 << SAM_PINCTRL_FLAGS_POS)
#define SAM_PINCTRL_FLAG_MASK (1U)
#define SAM_PINCTRL_PULLUP_POS (SAM_PINCTRL_FLAGS_POS)
#define SAM_PINCTRL_PULLUP (1U << SAM_PINCTRL_PULLUP_POS)
#define SAM_PINCTRL_PULLDOWN_POS (SAM_PINCTRL_PULLUP_POS + 1U)
#define SAM_PINCTRL_PULLDOWN (1U << SAM_PINCTRL_PULLDOWN_POS)
#define SAM_PINCTRL_OPENDRAIN_POS (SAM_PINCTRL_PULLDOWN_POS + 1U)
#define SAM_PINCTRL_OPENDRAIN (1U << SAM_PINCTRL_OPENDRAIN_POS)
/** @} */
/**
* Obtain Flag value from pinctrl_soc_pin_t configuration.
*
* @param pincfg pinctrl_soc_pin_t bit field value.
* @param pos attribute/flags bit position (@ref SAM_PINFLAGS).
*/
#define SAM_PINCTRL_FLAG_GET(pincfg, pos) \
(((pincfg) >> pos) & SAM_PINCTRL_FLAG_MASK)
#define SAM_PINCTRL_FLAGS_GET(pincfg) \
(((pincfg) >> SAM_PINCTRL_FLAGS_POS) & SAM_PINCTRL_FLAGS_MASK)
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_SAM_COMMON_H_ */

View file

@ -10,6 +10,9 @@ if SOC_FAMILY_SAM
config SYS_CLOCK_HW_CYCLES_PER_SEC config SYS_CLOCK_HW_CYCLES_PER_SEC
default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency)
config PINCTRL
default y
config WATCHDOG config WATCHDOG
default y default y

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2022, Gerson Fernando Budke <nandojve@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* Atmel SAM SoC specific helpers for pinctrl driver
*/
#ifndef ZEPHYR_SOC_ARM_ATMEL_SAM_COMMON_PINCTRL_SOC_H_
#define ZEPHYR_SOC_ARM_ATMEL_SAM_COMMON_PINCTRL_SOC_H_
#include <drivers/pinctrl/pinctrl_soc_sam_common.h>
#endif /* ZEPHYR_SOC_ARM_ATMEL_SAM_COMMON_PINCTRL_SOC_H_ */