drivers: pinctrl: Add R-Car Gen4 support
Renesas R-Car Gen4 is different from Gen3 regarding pinmux. While Gen3 had only one base address to manage all pins, Gen4 has one set of pinmux registers per GPIO banks. We could expose one pinmux register per GPIO controllers, but that would break potential compatibility with Linux Device tree. Instead create a reg_base array to parse all reg base from device tree and identify proper base address based on the pin definition. This imply to add a pfc_base parameter to most of the pfc_rcar function. Signed-off-by: Julien Massot <julien.massot@iot.bzh> Signed-off-by: Pierre Marzin <pierre.marzin@iot.bzh> Signed-off-by: Aymeric Aillet <aymeric.aillet@iot.bzh>
This commit is contained in:
parent
eb879413be
commit
1738543c5d
12 changed files with 281 additions and 140 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021 IoT.bzh
|
||||
* Copyright (c) 2021-2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -7,6 +7,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT renesas_rcar_pfc
|
||||
|
||||
#include "pfc_rcar.h"
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
|
@ -14,12 +15,25 @@
|
|||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/device_mmio.h>
|
||||
|
||||
DEVICE_MMIO_TOPLEVEL_STATIC(pfc, DT_DRV_INST(0));
|
||||
|
||||
#define PFC_REG_BASE DEVICE_MMIO_TOPLEVEL_GET(pfc)
|
||||
#define PFC_RCAR_PMMR 0x0
|
||||
|
||||
/* Gen3 only has one base address, Gen4 has one per GPIO controller */
|
||||
#if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
|
||||
#define PFC_RCAR_GPSR 0x100
|
||||
#define PFC_RCAR_IPSR 0x200
|
||||
DEVICE_MMIO_TOPLEVEL_STATIC(pfc, DT_DRV_INST(0));
|
||||
static uintptr_t reg_base[1];
|
||||
#elif defined(CONFIG_SOC_SERIES_RCAR_GEN4)
|
||||
#define PFC_RCAR_GPSR 0x040
|
||||
#define PFC_RCAR_IPSR 0x060
|
||||
/* swap both arguments */
|
||||
#define PFC_REG_ADDRESS(idx, node_id) DT_REG_ADDR_BY_IDX(node_id, idx)
|
||||
static const uintptr_t reg_base[] = {
|
||||
LISTIFY(DT_NUM_REGS(DT_DRV_INST(0)), PFC_REG_ADDRESS, (,), DT_DRV_INST(0))
|
||||
};
|
||||
#else
|
||||
#error Unsupported SoC Series
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Each drive step is either encoded in 2 or 3 bits.
|
||||
|
@ -33,18 +47,25 @@ DEVICE_MMIO_TOPLEVEL_STATIC(pfc, DT_DRV_INST(0));
|
|||
/* Some registers such as IPSR GPSR or DRVCTRL are protected and
|
||||
* must be preceded to a write to PMMR with the inverse value.
|
||||
*/
|
||||
static void pfc_rcar_write(uint32_t offs, uint32_t val)
|
||||
static void pfc_rcar_write(uintptr_t pfc_base, uint32_t offs, uint32_t val)
|
||||
{
|
||||
sys_write32(~val, PFC_REG_BASE + PFC_RCAR_PMMR);
|
||||
sys_write32(val, PFC_REG_BASE + offs);
|
||||
sys_write32(~val, pfc_base + PFC_RCAR_PMMR);
|
||||
sys_write32(val, pfc_base + offs);
|
||||
}
|
||||
|
||||
/* Set the pin either in gpio or peripheral */
|
||||
static void pfc_rcar_set_gpsr(uint16_t pin, bool peripheral)
|
||||
static void pfc_rcar_set_gpsr(uintptr_t pfc_base,
|
||||
uint16_t pin, bool peripheral)
|
||||
{
|
||||
#if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
|
||||
/* On Gen3 we have multiple GPSR at one base address */
|
||||
uint8_t bank = pin / 32;
|
||||
#elif defined(CONFIG_SOC_SERIES_RCAR_GEN4)
|
||||
/* On Gen4 we have one GPSR at multiple base address */
|
||||
uint8_t bank = 0;
|
||||
#endif
|
||||
uint8_t bit = pin % 32;
|
||||
uint32_t val = sys_read32(PFC_REG_BASE + PFC_RCAR_GPSR +
|
||||
uint32_t val = sys_read32(pfc_base + PFC_RCAR_GPSR +
|
||||
bank * sizeof(uint32_t));
|
||||
|
||||
if (peripheral) {
|
||||
|
@ -52,18 +73,19 @@ static void pfc_rcar_set_gpsr(uint16_t pin, bool peripheral)
|
|||
} else {
|
||||
val &= ~BIT(bit);
|
||||
}
|
||||
pfc_rcar_write(PFC_RCAR_GPSR + bank * sizeof(uint32_t), val);
|
||||
pfc_rcar_write(pfc_base, PFC_RCAR_GPSR + bank * sizeof(uint32_t), val);
|
||||
}
|
||||
|
||||
/* Set peripheral function */
|
||||
static void pfc_rcar_set_ipsr(const struct rcar_pin_func *rcar_func)
|
||||
static void pfc_rcar_set_ipsr(uintptr_t pfc_base,
|
||||
const struct rcar_pin_func *rcar_func)
|
||||
{
|
||||
uint16_t reg_offs = PFC_RCAR_IPSR + rcar_func->bank * sizeof(uint32_t);
|
||||
uint32_t val = sys_read32(PFC_REG_BASE + reg_offs);
|
||||
uint32_t val = sys_read32(pfc_base + reg_offs);
|
||||
|
||||
val &= ~(0xFU << rcar_func->shift);
|
||||
val |= (rcar_func->func << rcar_func->shift);
|
||||
pfc_rcar_write(reg_offs, val);
|
||||
pfc_rcar_write(pfc_base, reg_offs, val);
|
||||
}
|
||||
|
||||
static uint32_t pfc_rcar_get_drive_reg(uint16_t pin, uint8_t *offset,
|
||||
|
@ -90,7 +112,8 @@ static uint32_t pfc_rcar_get_drive_reg(uint16_t pin, uint8_t *offset,
|
|||
* using DRVCTRLx registers, some pins have 8 steps (3 bits size encoded)
|
||||
* some have 4 steps (2 bits size encoded).
|
||||
*/
|
||||
static int pfc_rcar_set_drive_strength(uint16_t pin, uint8_t strength)
|
||||
static int pfc_rcar_set_drive_strength(uintptr_t pfc_base, uint16_t pin,
|
||||
uint8_t strength)
|
||||
{
|
||||
uint8_t offset, size, step;
|
||||
uint32_t reg, val;
|
||||
|
@ -110,11 +133,11 @@ static int pfc_rcar_set_drive_strength(uint16_t pin, uint8_t strength)
|
|||
*/
|
||||
strength = (strength / step) - 1U;
|
||||
/* clear previous drive strength value */
|
||||
val = sys_read32(PFC_REG_BASE + reg);
|
||||
val = sys_read32(pfc_base + reg);
|
||||
val &= ~GENMASK(offset + size - 1U, offset);
|
||||
val |= strength << offset;
|
||||
|
||||
pfc_rcar_write(reg, val);
|
||||
pfc_rcar_write(pfc_base, reg, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -138,7 +161,7 @@ static const struct pfc_bias_reg *pfc_rcar_get_bias_reg(uint16_t pin,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int pfc_rcar_set_bias(uint16_t pin, uint16_t flags)
|
||||
int pfc_rcar_set_bias(uintptr_t pfc_base, uint16_t pin, uint16_t flags)
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t bit;
|
||||
|
@ -149,19 +172,19 @@ int pfc_rcar_set_bias(uint16_t pin, uint16_t flags)
|
|||
}
|
||||
|
||||
/* pull enable/disable*/
|
||||
val = sys_read32(PFC_REG_BASE + bias_reg->puen);
|
||||
val = sys_read32(pfc_base + bias_reg->puen);
|
||||
if ((flags & RCAR_PIN_FLAGS_PUEN) == 0U) {
|
||||
sys_write32(val & ~BIT(bit), PFC_REG_BASE + bias_reg->puen);
|
||||
sys_write32(val & ~BIT(bit), pfc_base + bias_reg->puen);
|
||||
return 0;
|
||||
}
|
||||
sys_write32(val | BIT(bit), PFC_REG_BASE + bias_reg->puen);
|
||||
sys_write32(val | BIT(bit), pfc_base + bias_reg->puen);
|
||||
|
||||
/* pull - up/down */
|
||||
val = sys_read32(PFC_REG_BASE + bias_reg->pud);
|
||||
val = sys_read32(pfc_base + bias_reg->pud);
|
||||
if (flags & RCAR_PIN_FLAGS_PUD) {
|
||||
sys_write32(val | BIT(bit), PFC_REG_BASE + bias_reg->pud);
|
||||
sys_write32(val | BIT(bit), pfc_base + bias_reg->pud);
|
||||
} else {
|
||||
sys_write32(val & ~BIT(bit), PFC_REG_BASE + bias_reg->pud);
|
||||
sys_write32(val & ~BIT(bit), pfc_base + bias_reg->pud);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -169,10 +192,23 @@ int pfc_rcar_set_bias(uint16_t pin, uint16_t flags)
|
|||
int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t reg_index;
|
||||
uintptr_t pfc_base;
|
||||
|
||||
ret = pfc_rcar_get_reg_index(pin->pin, ®_index);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (reg_index >= ARRAY_SIZE(reg_base)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pfc_base = reg_base[reg_index];
|
||||
|
||||
/* Set pin as GPIO if capable */
|
||||
if (RCAR_IS_GP_PIN(pin->pin)) {
|
||||
pfc_rcar_set_gpsr(pin->pin, false);
|
||||
pfc_rcar_set_gpsr(pfc_base, pin->pin, false);
|
||||
} else if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) == 0U) {
|
||||
/* A function must be set for non GPIO capable pin */
|
||||
return -EINVAL;
|
||||
|
@ -180,14 +216,14 @@ int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
|
|||
|
||||
/* Select function for pin */
|
||||
if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) != 0U) {
|
||||
pfc_rcar_set_ipsr(&pin->func);
|
||||
pfc_rcar_set_ipsr(pfc_base, &pin->func);
|
||||
|
||||
if (RCAR_IS_GP_PIN(pin->pin)) {
|
||||
pfc_rcar_set_gpsr(pin->pin, true);
|
||||
pfc_rcar_set_gpsr(pfc_base, pin->pin, true);
|
||||
}
|
||||
|
||||
if ((pin->flags & RCAR_PIN_FLAGS_PULL_SET) != 0U) {
|
||||
ret = pfc_rcar_set_bias(pin->pin, pin->flags);
|
||||
ret = pfc_rcar_set_bias(pfc_base, pin->pin, pin->flags);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -195,7 +231,7 @@ int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
|
|||
}
|
||||
|
||||
if (pin->drive_strength != 0U) {
|
||||
ret = pfc_rcar_set_drive_strength(pin->pin,
|
||||
ret = pfc_rcar_set_drive_strength(pfc_base, pin->pin,
|
||||
pin->drive_strength);
|
||||
}
|
||||
|
||||
|
@ -218,10 +254,13 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
|
||||
__boot_func static int pfc_rcar_driver_init(void)
|
||||
{
|
||||
DEVICE_MMIO_TOPLEVEL_MAP(pfc, K_MEM_CACHE_NONE);
|
||||
reg_base[0] = DEVICE_MMIO_TOPLEVEL_GET(pfc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(pfc_rcar_driver_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||
#endif
|
||||
|
|
26
drivers/pinctrl/pfc_rcar.h
Normal file
26
drivers/pinctrl/pfc_rcar.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_PINCTRL_PFC_RCAR_H_
|
||||
#define ZEPHYR_DRIVERS_PINCTRL_PFC_RCAR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pinctrl_soc.h>
|
||||
|
||||
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void);
|
||||
const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void);
|
||||
|
||||
/**
|
||||
* @brief set the register index for a given pin
|
||||
*
|
||||
* @param the pin
|
||||
* @param pointer for the resulting register index
|
||||
* @return 0 if the register index is found, negative
|
||||
* errno otherwise.
|
||||
*/
|
||||
int pfc_rcar_get_reg_index(uint8_t pin, uint8_t *reg_index);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_PINCTRL_PFC_RCAR_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021 IoT.bzh
|
||||
* Copyright (c) 2021-2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -40,4 +40,36 @@
|
|||
*/
|
||||
#define RCAR_NOGP_PIN(pin) (PIN_NOGPSR_START + pin)
|
||||
|
||||
/* Renesas Gen4 has IPSR registers at different base address
|
||||
* reg is here an index for the base address.
|
||||
* Each base address has 4 IPSR banks.
|
||||
*/
|
||||
#define IPnSR(bank, reg, shift, func) \
|
||||
IPSR(((reg) << 4U) | (bank), shift, func)
|
||||
|
||||
#define IP0SR0(shift, func) IPnSR(0, 0, shift, func)
|
||||
#define IP1SR0(shift, func) IPnSR(1, 0, shift, func)
|
||||
#define IP2SR0(shift, func) IPnSR(2, 0, shift, func)
|
||||
#define IP3SR0(shift, func) IPnSR(3, 0, shift, func)
|
||||
#define IP0SR1(shift, func) IPnSR(0, 1, shift, func)
|
||||
#define IP1SR1(shift, func) IPnSR(1, 1, shift, func)
|
||||
#define IP2SR1(shift, func) IPnSR(2, 1, shift, func)
|
||||
#define IP3SR1(shift, func) IPnSR(3, 1, shift, func)
|
||||
#define IP0SR2(shift, func) IPnSR(0, 2, shift, func)
|
||||
#define IP1SR2(shift, func) IPnSR(1, 2, shift, func)
|
||||
#define IP2SR2(shift, func) IPnSR(2, 2, shift, func)
|
||||
#define IP3SR2(shift, func) IPnSR(3, 2, shift, func)
|
||||
#define IP0SR3(shift, func) IPnSR(0, 3, shift, func)
|
||||
#define IP1SR3(shift, func) IPnSR(1, 3, shift, func)
|
||||
#define IP2SR3(shift, func) IPnSR(2, 3, shift, func)
|
||||
#define IP3SR3(shift, func) IPnSR(3, 3, shift, func)
|
||||
#define IP0SR4(shift, func) IPnSR(0, 4, shift, func)
|
||||
#define IP1SR4(shift, func) IPnSR(1, 4, shift, func)
|
||||
#define IP2SR4(shift, func) IPnSR(2, 4, shift, func)
|
||||
#define IP3SR4(shift, func) IPnSR(3, 4, shift, func)
|
||||
#define IP0SR5(shift, func) IPnSR(0, 5, shift, func)
|
||||
#define IP1SR5(shift, func) IPnSR(1, 5, shift, func)
|
||||
#define IP2SR5(shift, func) IPnSR(2, 5, shift, func)
|
||||
#define IP3SR5(shift, func) IPnSR(3, 5, shift, func)
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RCAR_COMMON_H_ */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory(${SOC_SERIES})
|
||||
zephyr_include_directories(common)
|
||||
|
|
115
soc/arm/renesas_rcar/common/pinctrl_rcar.h
Normal file
115
soc/arm/renesas_rcar/common/pinctrl_rcar.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_ARM_RENESAS_RCAR_COMMON_PINCTRL_SOC_H_
|
||||
#define ZEPHYR_SOC_ARM_RENESAS_RCAR_COMMON_PINCTRL_SOC_H_
|
||||
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/renesas/pinctrl-rcar-common.h>
|
||||
#include <stdint.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
struct rcar_pin_func {
|
||||
uint8_t bank:5; /* bank number 0 - 18 */
|
||||
uint8_t shift:5; /* bit shift 0 - 28 */
|
||||
uint8_t func:4; /* choice from 0x0 to 0xF */
|
||||
};
|
||||
|
||||
/** Pull-up, pull-down, or bias disable is requested */
|
||||
#define RCAR_PIN_FLAGS_PULL_SET BIT(0)
|
||||
/** Performs on/off control of the pull resistors */
|
||||
#define RCAR_PIN_FLAGS_PUEN BIT(1)
|
||||
/** Select pull-up resistor if set pull-down otherwise */
|
||||
#define RCAR_PIN_FLAGS_PUD BIT(2)
|
||||
/** Alternate function for the pin is requested */
|
||||
#define RCAR_PIN_FLAGS_FUNC_SET BIT(3)
|
||||
|
||||
#define RCAR_PIN_PULL_UP (RCAR_PIN_FLAGS_PULL_SET | RCAR_PIN_FLAGS_PUEN | RCAR_PIN_FLAGS_PUD)
|
||||
#define RCAR_PIN_PULL_DOWN (RCAR_PIN_FLAGS_PULL_SET | RCAR_PIN_FLAGS_PUEN)
|
||||
#define RCAR_PIN_PULL_DISABLE RCAR_PIN_FLAGS_PULL_SET
|
||||
|
||||
/** Type for R-Car pin. */
|
||||
typedef struct pinctrl_soc_pin {
|
||||
uint16_t pin;
|
||||
struct rcar_pin_func func;
|
||||
uint8_t flags;
|
||||
uint8_t drive_strength;
|
||||
} pinctrl_soc_pin_t;
|
||||
|
||||
#define RCAR_IPSR(node_id) DT_PROP_BY_IDX(node_id, pin, 1)
|
||||
#define RCAR_HAS_IPSR(node_id) DT_PROP_HAS_IDX(node_id, pin, 1)
|
||||
|
||||
/* Offsets are defined in dt-bindings pinctrl-rcar-common.h */
|
||||
#define RCAR_PIN_FUNC(node_id) \
|
||||
{ \
|
||||
((RCAR_IPSR(node_id) >> 10U) & 0x1FU), \
|
||||
((RCAR_IPSR(node_id) >> 4U) & 0x1FU), \
|
||||
((RCAR_IPSR(node_id) & 0xFU)) \
|
||||
}
|
||||
|
||||
#define RCAR_PIN_FLAGS(node_id) \
|
||||
DT_PROP(node_id, bias_pull_up) * RCAR_PIN_PULL_UP | \
|
||||
DT_PROP(node_id, bias_pull_down) * RCAR_PIN_PULL_DOWN | \
|
||||
DT_PROP(node_id, bias_disable) * RCAR_PIN_PULL_DISABLE | \
|
||||
RCAR_HAS_IPSR(node_id) * RCAR_PIN_FLAGS_FUNC_SET
|
||||
|
||||
#define RCAR_DT_PIN(node_id) \
|
||||
{ \
|
||||
.pin = DT_PROP_BY_IDX(node_id, pin, 0), \
|
||||
.func = COND_CODE_1(RCAR_HAS_IPSR(node_id), \
|
||||
(RCAR_PIN_FUNC(node_id)), {0}), \
|
||||
.flags = RCAR_PIN_FLAGS(node_id), \
|
||||
.drive_strength = \
|
||||
COND_CODE_1(DT_NODE_HAS_PROP(node_id, drive_strength), \
|
||||
(DT_PROP(node_id, drive_strength)), (0)), \
|
||||
},
|
||||
|
||||
/**
|
||||
* @brief Utility macro to initialize each pin.
|
||||
*
|
||||
* @param node_id Node identifier.
|
||||
* @param state_prop State property name.
|
||||
* @param idx State property entry index.
|
||||
*/
|
||||
#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \
|
||||
RCAR_DT_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx))
|
||||
|
||||
/**
|
||||
* @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_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) }
|
||||
|
||||
struct pfc_drive_reg_field {
|
||||
uint16_t pin;
|
||||
uint8_t offset;
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
struct pfc_drive_reg {
|
||||
uint32_t reg;
|
||||
const struct pfc_drive_reg_field fields[8];
|
||||
};
|
||||
|
||||
struct pfc_bias_reg {
|
||||
uint32_t puen; /** Pull-enable or pull-up control register */
|
||||
uint32_t pud; /** Pull-up/down or pull-down control register */
|
||||
const uint16_t pins[32];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Utility macro to check if a pin is GPIO capable
|
||||
*
|
||||
* @param pin
|
||||
* @return true if pin is GPIO capable false otherwise
|
||||
*/
|
||||
#define RCAR_IS_GP_PIN(pin) (pin < PIN_NOGPSR_START)
|
||||
|
||||
#endif /* ZEPHYR_SOC_ARM_RENESAS_RCAR_COMMON_PINCTRL_SOC_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021 IoT.bzh
|
||||
* Copyright (c) 2021-2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -528,6 +528,7 @@ const struct pfc_bias_reg pfc_bias_regs[] = {
|
|||
} },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void)
|
||||
{
|
||||
return pfc_bias_regs;
|
||||
|
@ -536,3 +537,10 @@ const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void)
|
|||
{
|
||||
return pfc_drive_regs;
|
||||
}
|
||||
|
||||
int pfc_rcar_get_reg_index(uint8_t pin, uint8_t *reg_index)
|
||||
{
|
||||
/* There is only one register on Gen 3 */
|
||||
*reg_index = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021 IoT.bzh
|
||||
* Copyright (c) 2021-2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -7,111 +7,6 @@
|
|||
|
||||
#ifndef ZEPHYR_SOC_ARM_RENESAS_RCAR_GEN3_PINCTRL_SOC_H_
|
||||
#define ZEPHYR_SOC_ARM_RENESAS_RCAR_GEN3_PINCTRL_SOC_H_
|
||||
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/renesas/pinctrl-rcar-common.h>
|
||||
#include <stdint.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
struct rcar_pin_func {
|
||||
uint8_t bank:5; /* bank number 0 - 18 */
|
||||
uint8_t shift:5; /* bit shift 0 - 28 */
|
||||
uint8_t func:4; /* choice from 0x0 to 0xF */
|
||||
};
|
||||
/** Pull-up, pull-down, or bias disable is requested */
|
||||
#define RCAR_PIN_FLAGS_PULL_SET BIT(0)
|
||||
/** Performs on/off control of the pull resistors */
|
||||
#define RCAR_PIN_FLAGS_PUEN BIT(1)
|
||||
/** Select pull-up resistor if set pull-down otherwise */
|
||||
#define RCAR_PIN_FLAGS_PUD BIT(2)
|
||||
/** Alternate function for the pin is requested */
|
||||
#define RCAR_PIN_FLAGS_FUNC_SET BIT(3)
|
||||
|
||||
#define RCAR_PIN_PULL_UP (RCAR_PIN_FLAGS_PULL_SET | RCAR_PIN_FLAGS_PUEN | RCAR_PIN_FLAGS_PUD)
|
||||
#define RCAR_PIN_PULL_DOWN (RCAR_PIN_FLAGS_PULL_SET | RCAR_PIN_FLAGS_PUEN)
|
||||
#define RCAR_PIN_PULL_DISABLE RCAR_PIN_FLAGS_PULL_SET
|
||||
|
||||
/** Type for R-Car pin. */
|
||||
typedef struct pinctrl_soc_pin {
|
||||
uint16_t pin;
|
||||
struct rcar_pin_func func;
|
||||
uint8_t flags;
|
||||
uint8_t drive_strength;
|
||||
} pinctrl_soc_pin_t;
|
||||
|
||||
#define RCAR_IPSR(node_id) DT_PROP_BY_IDX(node_id, pin, 1)
|
||||
#define RCAR_HAS_IPSR(node_id) DT_PROP_HAS_IDX(node_id, pin, 1)
|
||||
|
||||
/* Offsets are defined in dt-bindings pinctrl-rcar-common.h */
|
||||
#define RCAR_PIN_FUNC(node_id) \
|
||||
{ \
|
||||
((RCAR_IPSR(node_id) >> 10U) & 0x1FU), \
|
||||
((RCAR_IPSR(node_id) >> 4U) & 0x1FU), \
|
||||
((RCAR_IPSR(node_id) & 0xFU)) \
|
||||
}
|
||||
|
||||
#define RCAR_PIN_FLAGS(node_id) \
|
||||
DT_PROP(node_id, bias_pull_up) * RCAR_PIN_PULL_UP | \
|
||||
DT_PROP(node_id, bias_pull_down) * RCAR_PIN_PULL_DOWN | \
|
||||
DT_PROP(node_id, bias_disable) * RCAR_PIN_PULL_DISABLE | \
|
||||
RCAR_HAS_IPSR(node_id) * RCAR_PIN_FLAGS_FUNC_SET
|
||||
|
||||
#define RCAR_DT_PIN(node_id) \
|
||||
{ \
|
||||
.pin = DT_PROP_BY_IDX(node_id, pin, 0), \
|
||||
.func = COND_CODE_1(RCAR_HAS_IPSR(node_id), \
|
||||
(RCAR_PIN_FUNC(node_id)), (0)), \
|
||||
.flags = RCAR_PIN_FLAGS(node_id), \
|
||||
.drive_strength = \
|
||||
COND_CODE_1(DT_NODE_HAS_PROP(node_id, drive_strength), \
|
||||
(DT_PROP(node_id, drive_strength)), (0)), \
|
||||
},
|
||||
|
||||
/**
|
||||
* @brief Utility macro to initialize each pin.
|
||||
*
|
||||
* @param node_id Node identifier.
|
||||
* @param state_prop State property name.
|
||||
* @param idx State property entry index.
|
||||
*/
|
||||
#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \
|
||||
RCAR_DT_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx))
|
||||
|
||||
/**
|
||||
* @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_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) }
|
||||
|
||||
struct pfc_drive_reg_field {
|
||||
uint16_t pin;
|
||||
uint8_t offset;
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
struct pfc_drive_reg {
|
||||
uint32_t reg;
|
||||
const struct pfc_drive_reg_field fields[8];
|
||||
};
|
||||
|
||||
struct pfc_bias_reg {
|
||||
uint32_t puen; /** Pull-enable or pull-up control register */
|
||||
uint32_t pud; /** Pull-up/down or pull-down control register */
|
||||
const uint16_t pins[32];
|
||||
};
|
||||
|
||||
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void);
|
||||
const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void);
|
||||
|
||||
/**
|
||||
* @brief Utility macro to check if a pin is GPIO capable
|
||||
*
|
||||
* @param pin
|
||||
* @return true if pin is GPIO capable false otherwise
|
||||
*/
|
||||
#define RCAR_IS_GP_PIN(pin) (pin < PIN_NOGPSR_START)
|
||||
#include <pinctrl_rcar.h>
|
||||
|
||||
#endif /* ZEPHYR_SOC_ARM_RENESAS_RCAR_GEN3_PINCTRL_SOC_H_ */
|
||||
|
|
2
soc/arm/renesas_rcar/gen4/CMakeLists.txt
Normal file
2
soc/arm/renesas_rcar/gen4/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Copyright (c) 2023 IoT.bzh
|
||||
# SPDX-License-Identifier: Apache-2.0
|
12
soc/arm/renesas_rcar/gen4/pinctrl_soc.h
Normal file
12
soc/arm/renesas_rcar/gen4/pinctrl_soc.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2023 IoT.bzh
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_ARM_RENESAS_RCAR_GEN4_PINCTRL_SOC_H_
|
||||
#define ZEPHYR_SOC_ARM_RENESAS_RCAR_GEN4_PINCTRL_SOC_H_
|
||||
#include <pinctrl_rcar.h>
|
||||
|
||||
#endif /* ZEPHYR_SOC_ARM_RENESAS_RCAR_GEN4_PINCTRL_SOC_H_ */
|
|
@ -536,3 +536,10 @@ const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void)
|
|||
{
|
||||
return pfc_drive_regs;
|
||||
}
|
||||
|
||||
int pfc_rcar_get_reg_index(uint8_t pin, uint8_t *reg_index)
|
||||
{
|
||||
/* There is only one register on Gen 3 */
|
||||
*reg_index = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -144,3 +144,10 @@ const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void)
|
|||
{
|
||||
return pfc_drive_regs;
|
||||
}
|
||||
|
||||
int pfc_rcar_get_reg_index(uint8_t pin, uint8_t *reg_index)
|
||||
{
|
||||
/* There is only one register on Gen 3 */
|
||||
*reg_index = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -103,9 +103,6 @@ struct pfc_bias_reg {
|
|||
const uint16_t pins[32];
|
||||
};
|
||||
|
||||
const struct pfc_bias_reg *pfc_rcar_get_bias_regs(void);
|
||||
const struct pfc_drive_reg *pfc_rcar_get_drive_regs(void);
|
||||
|
||||
/**
|
||||
* @brief Utility macro to check if a pin is GPIO capable
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue