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
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/pinctrl/renesas-rzt2m-pinctrl.h>
|
||||
#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 {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&uart3 {
|
||||
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_RA pinctrl_ra.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.eos_s3"
|
||||
source "drivers/pinctrl/Kconfig.ra"
|
||||
source "drivers/pinctrl/Kconfig.rzt2m"
|
||||
|
||||
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
|
||||
select SERIAL_HAS_DRIVER
|
||||
select SERIAL_SUPPORT_INTERRUPT
|
||||
select PINCTRL
|
||||
help
|
||||
Enable Renesas RZ/T2M UART Driver.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "zephyr/spinlock.h"
|
||||
#include "zephyr/sys/printk.h"
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/irq.h>
|
||||
#include <stdint.h>
|
||||
|
@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(uart_renesas_rzt2m, CONFIG_UART_LOG_LEVEL);
|
|||
|
||||
struct rzt2m_device_config {
|
||||
mm_reg_t base;
|
||||
const struct pinctrl_dev_config *pin_config;
|
||||
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;
|
||||
*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;
|
||||
*FFCLR(config->base) = FFCLR_MASK_DRC;
|
||||
|
||||
|
@ -414,6 +422,7 @@ static void uart_rzt2m_isr(const struct device *dev)
|
|||
}
|
||||
|
||||
#define UART_RZT2M_INIT(n) \
|
||||
PINCTRL_DT_INST_DEFINE(n); \
|
||||
static struct rzt2m_device_data rzt2m_uart_##n##data = { \
|
||||
.uart_cfg = \
|
||||
{ \
|
||||
|
@ -427,7 +436,9 @@ static void uart_rzt2m_isr(const struct device *dev)
|
|||
}; \
|
||||
UART_RZT2M_CONFIG_FUNC(n); \
|
||||
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, \
|
||||
&rzt2m_uart_##n##_config, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
|
||||
&rzt2m_uart_api);
|
||||
|
|
|
@ -113,5 +113,10 @@
|
|||
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…
Reference in a new issue