drivers: pinctrl: add RZT2M driver
This adds a new driver for Renesas RZ/T2M. The driver allows configuration of pin direction, pull up/down resistors, drive strength and slew rate, and selection of function for a pin. Signed-off-by: Wojciech Sipak <wsipak@antmicro.com>
This commit is contained in:
parent
4e35d0e354
commit
9e44f59e9a
11 changed files with 287 additions and 1 deletions
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/dts-v1/;
|
/dts-v1/;
|
||||||
|
#include <dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h>
|
||||||
#include <arm/renesas/rzt2m.dtsi>
|
#include <arm/renesas/rzt2m.dtsi>
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
@ -18,10 +19,36 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
uart0_default: uart0_default {
|
||||||
|
group1 {
|
||||||
|
pinmux = <UART0TX_P16_5>;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART0RX_P16_6>;
|
||||||
|
input-enable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uart3_default: uart3_default {
|
||||||
|
group1 {
|
||||||
|
pinmux = <UART3TX_P18_0>;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART3RX_P17_7>;
|
||||||
|
input-enable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
&uart0 {
|
&uart0 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
pinctrl-0 = <&uart0_default>;
|
||||||
|
pinctrl-names = "default";
|
||||||
};
|
};
|
||||||
|
|
||||||
&uart3 {
|
&uart3 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
pinctrl-0 = <&uart3_default>;
|
||||||
|
pinctrl-names = "default";
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,3 +37,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c)
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c)
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c)
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_PINCTRL_RZT2M pinctrl_rzt2m.c)
|
||||||
|
|
|
@ -65,5 +65,6 @@ source "drivers/pinctrl/Kconfig.ti_cc32xx"
|
||||||
source "drivers/pinctrl/Kconfig.numaker"
|
source "drivers/pinctrl/Kconfig.numaker"
|
||||||
source "drivers/pinctrl/Kconfig.eos_s3"
|
source "drivers/pinctrl/Kconfig.eos_s3"
|
||||||
source "drivers/pinctrl/Kconfig.ra"
|
source "drivers/pinctrl/Kconfig.ra"
|
||||||
|
source "drivers/pinctrl/Kconfig.rzt2m"
|
||||||
|
|
||||||
endif # PINCTRL
|
endif # PINCTRL
|
||||||
|
|
9
drivers/pinctrl/Kconfig.rzt2m
Normal file
9
drivers/pinctrl/Kconfig.rzt2m
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config PINCTRL_RZT2M
|
||||||
|
bool "Renesas RZ/T2M pin controller driver"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_RENESAS_RZT2M_PINCTRL_ENABLED
|
||||||
|
help
|
||||||
|
Renesas RZ/T2M pinctrl driver
|
63
drivers/pinctrl/pinctrl_rzt2m.c
Normal file
63
drivers/pinctrl/pinctrl_rzt2m.c
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT renesas_rzt2m_pinctrl
|
||||||
|
|
||||||
|
#include <zephyr/arch/cpu.h>
|
||||||
|
#include <zephyr/drivers/pinctrl.h>
|
||||||
|
#include <soc.h>
|
||||||
|
|
||||||
|
#define PORT_NSR DT_INST_REG_ADDR_BY_NAME(0, port_nsr)
|
||||||
|
#define PTADR DT_INST_REG_ADDR_BY_NAME(0, ptadr)
|
||||||
|
|
||||||
|
/* Port m mode control register */
|
||||||
|
#define PMC(port) (PORT_NSR + 0x400 + port)
|
||||||
|
/* Port m function control register */
|
||||||
|
#define PFC(port) (PORT_NSR + 0x600 + (0x4 * port))
|
||||||
|
/* IO Buffer m function switching register */
|
||||||
|
#define DRCTL(port, pin) (PORT_NSR + 0xa00 + (0x8 * port) + pin)
|
||||||
|
/* Port m region select register */
|
||||||
|
#define RSELP(port) (PTADR + port)
|
||||||
|
|
||||||
|
#define DRCTL_DRIVE_STRENGTH(val) (val & 0x3)
|
||||||
|
#define DRCTL_PULL_UP_DOWN(val) ((val & 0x3) << 2)
|
||||||
|
#define DRCTL_SCHMITT(val) ((val & 0x1) << 4)
|
||||||
|
#define DRCTL_SLEW_RATE(val) ((val & 0x1) << 5)
|
||||||
|
#define DRCTL_CONFIG(drive, pull, schmitt, slew) \
|
||||||
|
(DRCTL_DRIVE_STRENGTH(drive) | DRCTL_PULL_UP_DOWN(pull) | DRCTL_SCHMITT(schmitt) | \
|
||||||
|
DRCTL_SLEW_RATE(slew))
|
||||||
|
#define PFC_FUNC_MASK(pin) (0xf << (pin * 4))
|
||||||
|
|
||||||
|
static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
|
||||||
|
{
|
||||||
|
uint8_t rselp = sys_read8(RSELP(pin->port));
|
||||||
|
uint32_t pfc = sys_read32(PFC(pin->port)) & ~(PFC_FUNC_MASK(pin->pin));
|
||||||
|
uint8_t pmc = sys_read8(PMC(pin->port));
|
||||||
|
|
||||||
|
/* Set proper bit in the RSELP register to use as non-safety domain. */
|
||||||
|
sys_write8(rselp | BIT(pin->pin), RSELP(pin->port));
|
||||||
|
sys_write8(DRCTL_CONFIG(
|
||||||
|
pin->drive_strength, (pin->pull_up == 1 ? 1U : (pin->pull_down == 1 ? 2U : 0)),
|
||||||
|
pin->schmitt_enable, pin->slew_rate),
|
||||||
|
DRCTL(pin->port, pin->pin));
|
||||||
|
|
||||||
|
/* Select function for the pin. */
|
||||||
|
sys_write32(pfc | pin->func << (pin->pin * 4), PFC(pin->port));
|
||||||
|
|
||||||
|
/* Set proper bit in the PMC register to use the pin as a peripheral IO. */
|
||||||
|
sys_write8(pmc | BIT(pin->pin), PMC(pin->port));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -7,5 +7,6 @@ config UART_RZT2M
|
||||||
depends on DT_HAS_RENESAS_RZT2M_UART_ENABLED
|
depends on DT_HAS_RENESAS_RZT2M_UART_ENABLED
|
||||||
select SERIAL_HAS_DRIVER
|
select SERIAL_HAS_DRIVER
|
||||||
select SERIAL_SUPPORT_INTERRUPT
|
select SERIAL_SUPPORT_INTERRUPT
|
||||||
|
select PINCTRL
|
||||||
help
|
help
|
||||||
Enable Renesas RZ/T2M UART Driver.
|
Enable Renesas RZ/T2M UART Driver.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "zephyr/spinlock.h"
|
#include "zephyr/spinlock.h"
|
||||||
#include "zephyr/sys/printk.h"
|
#include "zephyr/sys/printk.h"
|
||||||
#include <zephyr/drivers/uart.h>
|
#include <zephyr/drivers/uart.h>
|
||||||
|
#include <zephyr/drivers/pinctrl.h>
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
#include <zephyr/irq.h>
|
#include <zephyr/irq.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(uart_renesas_rzt2m, CONFIG_UART_LOG_LEVEL);
|
||||||
|
|
||||||
struct rzt2m_device_config {
|
struct rzt2m_device_config {
|
||||||
mm_reg_t base;
|
mm_reg_t base;
|
||||||
|
const struct pinctrl_dev_config *pin_config;
|
||||||
uart_irq_config_func_t irq_config_func;
|
uart_irq_config_func_t irq_config_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -297,6 +299,12 @@ static int rzt2m_uart_init(const struct device *dev)
|
||||||
*CCR3(config->base) = CCR3_DEFAULT_VALUE;
|
*CCR3(config->base) = CCR3_DEFAULT_VALUE;
|
||||||
*CCR4(config->base) = CCR4_DEFAULT_VALUE;
|
*CCR4(config->base) = CCR4_DEFAULT_VALUE;
|
||||||
|
|
||||||
|
/* Configure pinmuxes */
|
||||||
|
ret = pinctrl_apply_state(config->pin_config, PINCTRL_STATE_DEFAULT);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
*CFCLR(config->base) = CFCLR_ALL_FLAG_CLEAR;
|
*CFCLR(config->base) = CFCLR_ALL_FLAG_CLEAR;
|
||||||
*FFCLR(config->base) = FFCLR_MASK_DRC;
|
*FFCLR(config->base) = FFCLR_MASK_DRC;
|
||||||
|
|
||||||
|
@ -414,6 +422,7 @@ static void uart_rzt2m_isr(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UART_RZT2M_INIT(n) \
|
#define UART_RZT2M_INIT(n) \
|
||||||
|
PINCTRL_DT_INST_DEFINE(n); \
|
||||||
static struct rzt2m_device_data rzt2m_uart_##n##data = { \
|
static struct rzt2m_device_data rzt2m_uart_##n##data = { \
|
||||||
.uart_cfg = \
|
.uart_cfg = \
|
||||||
{ \
|
{ \
|
||||||
|
@ -427,7 +436,9 @@ static void uart_rzt2m_isr(const struct device *dev)
|
||||||
}; \
|
}; \
|
||||||
UART_RZT2M_CONFIG_FUNC(n); \
|
UART_RZT2M_CONFIG_FUNC(n); \
|
||||||
static const struct rzt2m_device_config rzt2m_uart_##n##_config = { \
|
static const struct rzt2m_device_config rzt2m_uart_##n##_config = { \
|
||||||
.base = DT_INST_REG_ADDR(n), .irq_config_func = uart##n##_rzt2m_irq_config}; \
|
.base = DT_INST_REG_ADDR(n), \
|
||||||
|
.irq_config_func = uart##n##_rzt2m_irq_config, \
|
||||||
|
.pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \
|
||||||
DEVICE_DT_INST_DEFINE(n, &rzt2m_uart_init, NULL, &rzt2m_uart_##n##data, \
|
DEVICE_DT_INST_DEFINE(n, &rzt2m_uart_init, NULL, &rzt2m_uart_##n##data, \
|
||||||
&rzt2m_uart_##n##_config, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
|
&rzt2m_uart_##n##_config, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
|
||||||
&rzt2m_uart_api);
|
&rzt2m_uart_api);
|
||||||
|
|
|
@ -113,5 +113,10 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pinctrl: pinctrl@800a0000 {
|
||||||
|
compatible = "renesas,rzt2m-pinctrl";
|
||||||
|
reg = <0x800a0000 0x1000 0x81030c00 0x1000>;
|
||||||
|
reg-names = "port_nsr", "ptadr";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
93
dts/bindings/pinctrl/renesas,rzt2m-pinctrl.yaml
Normal file
93
dts/bindings/pinctrl/renesas,rzt2m-pinctrl.yaml
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The Renesas RZ/T2M pin controller is a node responsible for controlling
|
||||||
|
pin function selection and pin properties, such as routing the TX and RX of UART0
|
||||||
|
to pin 5 and pin 6 of port 16.
|
||||||
|
|
||||||
|
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/renesas-rzt2m-pinctrl.h>
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
uart0_default: uart0_default {
|
||||||
|
group1 {
|
||||||
|
pinmux = <UART0TX_P16_5>;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART0RX_P16_6>;
|
||||||
|
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.
|
||||||
|
|
||||||
|
compatible: "renesas,rzt2m-pinctrl"
|
||||||
|
|
||||||
|
include: base.yaml
|
||||||
|
|
||||||
|
child-binding:
|
||||||
|
description: |
|
||||||
|
Definitions for a pinctrl state.
|
||||||
|
child-binding:
|
||||||
|
|
||||||
|
include:
|
||||||
|
- name: pincfg-node.yaml
|
||||||
|
property-allowlist:
|
||||||
|
- input-enable
|
||||||
|
- bias-pull-up
|
||||||
|
- bias-pull-down
|
||||||
|
- bias-high-impedance
|
||||||
|
- input-schmitt-enable
|
||||||
|
|
||||||
|
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:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- "low"
|
||||||
|
- "middle"
|
||||||
|
- "high"
|
||||||
|
- "ultrahigh"
|
||||||
|
default: "low"
|
||||||
|
description: |
|
||||||
|
The drive strength of a pin, relative to full-driver strength.
|
||||||
|
The default value is "low", which is the reset value.
|
||||||
|
slew-rate:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- "slow"
|
||||||
|
- "fast"
|
||||||
|
default: "slow"
|
||||||
|
description: |
|
||||||
|
Select slew rate for a pin. The default is slow, which is the reset value.
|
18
include/zephyr/dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h
Normal file
18
include/zephyr/dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RENESAS_RZT2M_PINCTRL_H__
|
||||||
|
#define __RENESAS_RZT2M_PINCTRL_H__
|
||||||
|
|
||||||
|
#define RZT2M_PINMUX(port, pin, func) ((port << 16) | (pin << 8) | func)
|
||||||
|
|
||||||
|
#define UART0TX_P16_5 RZT2M_PINMUX(16, 5, 1)
|
||||||
|
#define UART0RX_P16_6 RZT2M_PINMUX(16, 6, 2)
|
||||||
|
|
||||||
|
#define UART3TX_P18_0 RZT2M_PINMUX(18, 0, 4)
|
||||||
|
#define UART3RX_P17_7 RZT2M_PINMUX(17, 7, 4)
|
||||||
|
|
||||||
|
#endif /* __RENESAS_RZT2M_PINCTRL_H__ */
|
57
soc/arm/renesas_rzt2m/pinctrl_soc.h
Normal file
57
soc/arm/renesas_rzt2m/pinctrl_soc.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_
|
||||||
|
#define ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct pinctrl_soc_pin_t {
|
||||||
|
uint32_t port;
|
||||||
|
uint32_t pin;
|
||||||
|
uint32_t func;
|
||||||
|
uint32_t input_enable: 1;
|
||||||
|
uint32_t output_enable: 1;
|
||||||
|
uint32_t pull_up: 1;
|
||||||
|
uint32_t pull_down: 1;
|
||||||
|
uint32_t high_impedance: 1;
|
||||||
|
uint32_t slew_rate: 2;
|
||||||
|
uint8_t drive_strength;
|
||||||
|
uint32_t schmitt_enable: 1;
|
||||||
|
} pinctrl_soc_pin_t;
|
||||||
|
|
||||||
|
#define RZT2M_GET_PORT(pinctrl) ((pinctrl >> 16) & 0xff)
|
||||||
|
#define RZT2M_GET_PIN(pinctrl) ((pinctrl >> 8) & 0xff)
|
||||||
|
#define RZT2M_GET_FUNC(pinctrl) (pinctrl & 0xff)
|
||||||
|
|
||||||
|
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
|
||||||
|
{ \
|
||||||
|
.port = RZT2M_GET_PORT(DT_PROP_BY_IDX(node_id, prop, idx)), \
|
||||||
|
.pin = RZT2M_GET_PIN(DT_PROP_BY_IDX(node_id, prop, idx)), \
|
||||||
|
.func = RZT2M_GET_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \
|
||||||
|
.input_enable = DT_PROP(node_id, input_enable), \
|
||||||
|
.pull_up = DT_PROP(node_id, bias_pull_up), \
|
||||||
|
.pull_down = DT_PROP(node_id, bias_pull_down), \
|
||||||
|
.high_impedance = DT_PROP(node_id, bias_high_impedance), \
|
||||||
|
.slew_rate = DT_ENUM_IDX(node_id, slew_rate), \
|
||||||
|
.drive_strength = DT_ENUM_IDX(node_id, drive_strength), \
|
||||||
|
.schmitt_enable = DT_PROP(node_id, input_schmitt_enable), \
|
||||||
|
},
|
||||||
|
|
||||||
|
#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)}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_SOC_ARM_RENESAS_RZT2M_PINCTRL_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue