Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_subdirectory_ifdef(CONFIG_IPM ipm)
add_subdirectory_ifdef(CONFIG_LED led)
add_subdirectory_ifdef(CONFIG_LED_STRIP led_strip)
add_subdirectory_ifdef(CONFIG_MODEM modem)
add_subdirectory_ifdef(CONFIG_PINCTRL pinctrl)
add_subdirectory_ifdef(CONFIG_PINMUX pinmux)
add_subdirectory_ifdef(CONFIG_PWM pwm)
add_subdirectory_ifdef(CONFIG_SENSOR sensor)
Expand Down
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ source "drivers/i2s/Kconfig"

source "drivers/pwm/Kconfig"

source "drivers/pinctrl/Kconfig"

source "drivers/pinmux/Kconfig"

source "drivers/adc/Kconfig"
Expand Down
2 changes: 1 addition & 1 deletion drivers/adc/adc_sam_afec.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ static void adc_sam_isr(const struct device *dev)
.regs = (Afec *)DT_INST_REG_ADDR(n), \
.cfg_func = adc##n##_sam_cfg_func, \
.periph_id = DT_INST_PROP(n, peripheral_id), \
.afec_trg_pin = ATMEL_SAM_DT_PIN(n, 0), \
.afec_trg_pin = ATMEL_SAM_DT_INST_PIN(n, 0), \
}; \
\
static struct adc_sam_data adc##n##_sam_data = { \
Expand Down
2 changes: 1 addition & 1 deletion drivers/ethernet/eth_sam_gmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -2214,7 +2214,7 @@ static void eth0_irq_config(void)
}

#ifdef CONFIG_SOC_FAMILY_SAM
static const struct soc_gpio_pin pins_eth0[] = ATMEL_SAM_DT_PINS(0);
static const struct soc_gpio_pin pins_eth0[] = ATMEL_SAM_DT_INST_PINS(0);
#endif

static const struct eth_sam_dev_cfg eth0_config = {
Expand Down
3 changes: 1 addition & 2 deletions drivers/i2c/i2c_sam4l_twim.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,7 @@ static const struct i2c_driver_api i2c_sam_twim_driver_api = {
DEVICE_DT_INST_GET(n), 0); \
} \
\
static const struct soc_gpio_pin pins_twim##n[] = \
{ATMEL_SAM_DT_PIN(n, 0), ATMEL_SAM_DT_PIN(n, 1)}; \
static const struct soc_gpio_pin pins_twim##n[] = ATMEL_SAM_DT_INST_PINS(n); \
\
static const struct i2c_sam_twim_dev_cfg i2c##n##_sam_config = {\
.regs = (Twim *)DT_INST_REG_ADDR(n), \
Expand Down
3 changes: 1 addition & 2 deletions drivers/i2c/i2c_sam_twi.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,7 @@ static const struct i2c_driver_api i2c_sam_twi_driver_api = {
DEVICE_DT_INST_GET(n), 0); \
} \
\
static const struct soc_gpio_pin pins_twi##n[] = \
{ATMEL_SAM_DT_PIN(n, 0), ATMEL_SAM_DT_PIN(n, 1)}; \
static const struct soc_gpio_pin pins_twi##n[] = ATMEL_SAM_DT_INST_PINS(n); \
\
static const struct i2c_sam_twi_dev_cfg i2c##n##_sam_config = { \
.regs = (Twi *)DT_INST_REG_ADDR(n), \
Expand Down
3 changes: 1 addition & 2 deletions drivers/i2c/i2c_sam_twihs.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,7 @@ static const struct i2c_driver_api i2c_sam_twihs_driver_api = {
DEVICE_DT_INST_GET(n), 0); \
} \
\
static const struct soc_gpio_pin pins_twihs##n[] = \
{ATMEL_SAM_DT_PIN(n, 0), ATMEL_SAM_DT_PIN(n, 1)}; \
static const struct soc_gpio_pin pins_twihs##n[] = ATMEL_SAM_DT_INST_PINS(n); \
\
static const struct i2c_sam_twihs_dev_cfg i2c##n##_sam_config = {\
.regs = (Twihs *)DT_INST_REG_ADDR(n), \
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2s/i2s_sam_ssc.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ static void i2s0_sam_irq_config(void)
DEVICE_DT_INST_GET(0), 0);
}

static const struct soc_gpio_pin i2s0_pins[] = ATMEL_SAM_DT_PINS(0);
static const struct soc_gpio_pin i2s0_pins[] = ATMEL_SAM_DT_INST_PINS(0);

static const struct i2s_sam_dev_cfg i2s0_sam_config = {
.dev_dma = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(0, tx)),
Expand Down
6 changes: 6 additions & 0 deletions drivers/pinctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_sources_ifdef(CONFIG_USERSPACE pinctrl_handlers.c)

zephyr_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c)
zephyr_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c)
27 changes: 27 additions & 0 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# HW Info driver configuration options

# Copyright (c) 2021 Piotr Mienkowski
# SPDX-License-Identifier: Apache-2.0

menuconfig PINCTRL
bool "Pin Controller driver"
help
Enable pinctrl driver.

if PINCTRL

config PINCTRL_STM32
bool "STM32 pinctrl"
default y
depends on SOC_FAMILY_STM32
help
Enable STM32 pinctrl driver.

config PINCTRL_SAM
bool "Atmel SAM device ID"
default y
depends on SOC_FAMILY_SAM
help
Enable Atmel SAM pinctrl driver.

endif
16 changes: 16 additions & 0 deletions drivers/pinctrl/pinctrl_handlers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2021 Piotr Mienkowski
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <syscall_handler.h>
#include <drivers/pinctrl.h>

int z_vrfy_pinctrl_pin_configure(const pinctrl_dt_pin_spec_t *pin_spec)
{
Z_SYSCALL_MEMORY_READ(pin_spec, sizeof(pinctrl_dt_pin_spec_t));

return z_impl_pinctrl_pin_configure((const struct pinctrl_dt_pin_spec *)pin_spec);
}
#include <syscalls/pinctrl_pin_configure_mrsh.c>
15 changes: 15 additions & 0 deletions drivers/pinctrl/pinctrl_sam.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 Piotr Mienkowski
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <drivers/pinctrl.h>
#include <soc.h>

int z_impl_pinctrl_pin_configure(const pinctrl_dt_pin_spec_t *pin_spec)
{
soc_gpio_configure((const struct soc_gpio_pin *)pin_spec);

return 0;
}
2 changes: 1 addition & 1 deletion drivers/sensor/qdec_sam/qdec_sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static const struct sensor_driver_api qdec_sam_driver_api = {
};

#define QDEC_SAM_INIT(n) \
static const struct soc_gpio_pin pins_tc##n[] = ATMEL_SAM_DT_PINS(n); \
static const struct soc_gpio_pin pins_tc##n[] = ATMEL_SAM_DT_INST_PINS(n); \
\
static const struct qdec_sam_dev_cfg qdec##n##_sam_config = { \
.regs = (Tc *)DT_INST_REG_ADDR(n), \
Expand Down
1 change: 1 addition & 0 deletions drivers/serial/Kconfig.usart_sam
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ config USART_SAM
depends on SOC_FAMILY_SAM
select SERIAL_HAS_DRIVER
select SERIAL_SUPPORT_INTERRUPT
select PINCTRL
help
This option enables the USARTx driver for Atmel SAM MCUs.
4 changes: 2 additions & 2 deletions drivers/serial/uart_sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,8 @@ static const struct uart_driver_api uart_sam_driver_api = {
.regs = (Uart *)DT_INST_REG_ADDR(n), \
.periph_id = DT_INST_PROP(n, peripheral_id), \
\
.pin_rx = ATMEL_SAM_DT_PIN(n, 0), \
.pin_tx = ATMEL_SAM_DT_PIN(n, 1), \
.pin_rx = ATMEL_SAM_DT_INST_PIN(n, 0), \
.pin_tx = ATMEL_SAM_DT_INST_PIN(n, 1), \
\
IRQ_FUNC_INIT \
}
Expand Down
15 changes: 9 additions & 6 deletions drivers/serial/usart_sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
#include <init.h>
#include <soc.h>
#include <drivers/uart.h>
#include <drivers/pinctrl.h>

/* Device constant configuration parameters */
struct usart_sam_dev_cfg {
Usart *regs;
uint32_t periph_id;
struct soc_gpio_pin pin_rx;
struct soc_gpio_pin pin_tx;
unsigned int num_pins;
const pinctrl_dt_pin_spec_t *pins;

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_config_func_t irq_config_func;
Expand Down Expand Up @@ -64,8 +65,7 @@ static int usart_sam_init(const struct device *dev)
soc_pmc_peripheral_enable(cfg->periph_id);

/* Connect pins to the peripheral */
soc_gpio_configure(&cfg->pin_rx);
soc_gpio_configure(&cfg->pin_tx);
pinctrl_pin_list_configure(cfg->pins, cfg->num_pins);

/* Reset and disable USART */
usart->US_CR = US_CR_RSTRX | US_CR_RSTTX
Expand Down Expand Up @@ -324,12 +324,15 @@ static const struct uart_driver_api usart_sam_driver_api = {
};

#define USART_SAM_DECLARE_CFG(n, IRQ_FUNC_INIT) \
static const pinctrl_dt_pin_spec_t pins_usart##n[] = \
PINCTRL_DT_SPEC_GET(DT_DRV_INST(n), 0); \
\
static const struct usart_sam_dev_cfg usart##n##_sam_config = { \
.regs = (Usart *)DT_INST_REG_ADDR(n), \
.periph_id = DT_INST_PROP(n, peripheral_id), \
\
.pin_rx = ATMEL_SAM_DT_PIN(n, 0), \
.pin_tx = ATMEL_SAM_DT_PIN(n, 1), \
.pins = pins_usart##n, \
.num_pins = ARRAY_SIZE(pins_usart##n), \
\
IRQ_FUNC_INIT \
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/spi_sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ static const struct spi_driver_api spi_sam_driver_api = {
static const struct spi_sam_config spi_sam_config_##n = { \
.regs = (Spi *)DT_INST_REG_ADDR(n), \
.periph_id = DT_INST_PROP(n, peripheral_id), \
.num_pins = ATMEL_SAM_DT_NUM_PINS(n), \
.pins = ATMEL_SAM_DT_PINS(n), \
.num_pins = ATMEL_SAM_DT_INST_NUM_PINS(n), \
.pins = ATMEL_SAM_DT_INST_PINS(n), \
}

#define SPI_SAM_DEVICE_INIT(n) \
Expand Down
114 changes: 114 additions & 0 deletions include/drivers/pinctrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2021 Piotr Mienkowski
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Public APIs for PINCTRL drivers
*/

#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_
#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_

#include <zephyr/types.h>
#include <toolchain.h>
#include <soc_pinctrl.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief PINCTRL Driver APIs
* @defgroup pinctrl_interface PINCTRL Driver APIs
* @ingroup io_interfaces
* @{
*/

/**
* @typedef pinctrl_dt_pin_spec_t
*
* @brief Provides a type to hold PINCTRL information specified in devicetree
*
* This type is sufficient to hold a PINCTRL device pointer, pin number,
* and the subset of the flags used to control PINCTRL configuration
* which may be given in devicetree.
*/

/**
* @def PINCTRL_DT_SPEC_GET(node_id, n)
*
* @brief Static initializer for a @p pinctrl_dt_pin_spec
*
* This returns a static initializer for a @p pinctrl_dt_pin_spec structure
* given a devicetree node identifier and a state ID.
*
* Example devicetree fragment:
*
* nodelabel: node {
* pinctrl-0 = <&pincfg_a>, <&pincfg_b>, <&pincfg_c>;
* pinctrl-1 = <&pincfg_ax>, <&pincfg_bx>;
* }
*
* Example usage:
*
* const pinctrl_dt_pin_spec_t spec[] =
* PINCTRL_DT_SPEC_GET(DT_NODELABEL(nodelabel), 0);
*
* It is an error to use this macro unless the node exists, has the given
* property, and that property specifies a list of valid phandles to pin
* configuration node.
*
* @param node_id devicetree node identifier
* @param n an integer id that corresponds to pinctrl-n property.
* @return static initializer for an array of `pinctrl_dt_pin_spec_t`
*/

/**
* @brief Configure a single pin from a @p pinctrl_dt_pin_spec.
*
* @param pin_spec Pin configuration obtained from the device tree.
*
* @retval 0 If successful.
*/
__syscall int pinctrl_pin_configure(const pinctrl_dt_pin_spec_t *pin_spec);

int z_impl_pinctrl_pin_configure(const pinctrl_dt_pin_spec_t *pin_spec);

/**
* @brief Configure pin list from a @p pinctrl_dt_pin_spec array.
*
* @param pin_spec An array of pin spec elements obtained from the device tree.
* @param pin_spec_length number of elements in pin_spec array.
*
* @retval 0 If successful.
*/
static inline int pinctrl_pin_list_configure(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there is any utility in passing a device pointer in here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing device pointer as the first argument of the function?

For the pinctrl_pin_list_configure function that would not be practical since every pinctrl_dt_pin_spec_t item from the list may be associated with a different device. But it probably makes sense to do it for pinctrl_pin_configure function. The function will become

int pinctrl_pin_configure(const struct device * dev, const pinctrl_pin_conf_t *pin_conf);

The current pinctrl_pin_configure, pinctrl_pin_list_configure functions will preserve their arguments but be renamed to pinctrl_pin_configure_dt, pinctrl_pin_list_configure_dt. After the change we will break one less convention and the implementation will be better aligned with the GPIO driver.

const pinctrl_dt_pin_spec_t pin_spec[],
unsigned int pin_spec_length)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size_t?

{
int ret = 0;

for (int i = 0; i < pin_spec_length; i++) {
ret = pinctrl_pin_configure(&pin_spec[i]);
if (ret != 0) {
break;
}
}

return ret;
}

/**
* @}
*/

#ifdef __cplusplus
}
#endif

#include <syscalls/pinctrl.h>

#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_ */
Loading