zephyr/drivers/pinctrl/pinctrl_imx.c

83 lines
2.5 KiB
C
Raw Normal View History

/*
* Copyright (c) 2022 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/arch/cpu.h>
#include <zephyr/drivers/pinctrl.h>
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
uintptr_t reg)
{
/* configure all pins */
for (uint8_t i = 0U; i < pin_cnt; i++) {
uint32_t mux_register = pins[i].pinmux.mux_register;
uint32_t mux_mode = pins[i].pinmux.mux_mode;
uint32_t input_register = pins[i].pinmux.input_register;
uint32_t input_daisy = pins[i].pinmux.input_daisy;
uint32_t config_register = pins[i].pinmux.config_register;
uint32_t pin_ctrl_flags = pins[i].pin_ctrl_flags;
#if defined(CONFIG_SOC_SERIES_IMX_RT10XX) || defined(CONFIG_SOC_SERIES_IMX_RT11XX)
volatile uint32_t *gpr_register =
(volatile uint32_t *)((uintptr_t)pins[i].pinmux.gpr_register);
if (gpr_register) {
/* Set or clear specified GPR bit for this mux */
if (pins[i].pinmux.gpr_val) {
*gpr_register |=
(pins[i].pinmux.gpr_val << pins[i].pinmux.gpr_shift);
} else {
*gpr_register &= ~(0x1 << pins[i].pinmux.gpr_shift);
}
}
#endif
#ifdef CONFIG_SOC_MIMX93_A55
sys_write32(IOMUXC1_SW_MUX_CTL_PAD_MUX_MODE(mux_mode) |
IOMUXC1_SW_MUX_CTL_PAD_SION(MCUX_IMX_INPUT_ENABLE(pin_ctrl_flags)),
(mem_addr_t)mux_register);
if (input_register) {
sys_write32(IOMUXC1_SELECT_INPUT_DAISY(input_daisy),
(mem_addr_t)input_register);
}
if (config_register) {
sys_write32(pin_ctrl_flags & (~(0x1 << MCUX_IMX_INPUT_ENABLE_SHIFT)),
(mem_addr_t)config_register);
}
#else
*((volatile uint32_t *)((uintptr_t)mux_register)) =
IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(mux_mode) |
IOMUXC_SW_MUX_CTL_PAD_SION(MCUX_IMX_INPUT_ENABLE(pin_ctrl_flags));
if (input_register) {
*((volatile uint32_t *)((uintptr_t)input_register)) =
IOMUXC_SELECT_INPUT_DAISY(input_daisy);
}
if (config_register) {
*((volatile uint32_t *)((uintptr_t)config_register)) =
pin_ctrl_flags & (~(0x1 << MCUX_IMX_INPUT_ENABLE_SHIFT));
}
#endif
}
return 0;
}
init: remove the need for a dummy device pointer in SYS_INIT functions The init infrastructure, found in `init.h`, is currently used by: - `SYS_INIT`: to call functions before `main` - `DEVICE_*`: to initialize devices They are all sorted according to an initialization level + a priority. `SYS_INIT` calls are really orthogonal to devices, however, the required function signature requires a `const struct device *dev` as a first argument. The only reason for that is because the same init machinery is used by devices, so we have something like: ```c struct init_entry { int (*init)(const struct device *dev); /* only set by DEVICE_*, otherwise NULL */ const struct device *dev; } ``` As a result, we end up with such weird/ugly pattern: ```c static int my_init(const struct device *dev) { /* always NULL! add ARG_UNUSED to avoid compiler warning */ ARG_UNUSED(dev); ... } ``` This is really a result of poor internals isolation. This patch proposes a to make init entries more flexible so that they can accept sytem initialization calls like this: ```c static int my_init(void) { ... } ``` This is achieved using a union: ```c union init_function { /* for SYS_INIT, used when init_entry.dev == NULL */ int (*sys)(void); /* for DEVICE*, used when init_entry.dev != NULL */ int (*dev)(const struct device *dev); }; struct init_entry { /* stores init function (either for SYS_INIT or DEVICE*) union init_function init_fn; /* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows * to know which union entry to call. */ const struct device *dev; } ``` This solution **does not increase ROM usage**, and allows to offer clean public APIs for both SYS_INIT and DEVICE*. Note that however, init machinery keeps a coupling with devices. **NOTE**: This is a breaking change! All `SYS_INIT` functions will need to be converted to the new signature. See the script offered in the following commit. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no> init: convert SYS_INIT functions to the new signature Conversion scripted using scripts/utils/migrate_sys_init.py. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no> manifest: update projects for SYS_INIT changes Update modules with updated SYS_INIT calls: - hal_ti - lvgl - sof - TraceRecorderSource Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no> tests: devicetree: devices: adjust test Adjust test according to the recently introduced SYS_INIT infrastructure. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no> tests: kernel: threads: adjust SYS_INIT call Adjust to the new signature: int (*init_fn)(void); Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-10-19 09:33:44 +02:00
static int imx_pinctrl_init(void)
{
#ifdef CONFIG_SOC_SERIES_IMX_RT
CLOCK_EnableClock(kCLOCK_Iomuxc);
#ifdef CONFIG_SOC_SERIES_IMX_RT10XX
CLOCK_EnableClock(kCLOCK_IomuxcSnvs);
CLOCK_EnableClock(kCLOCK_IomuxcGpr);
#elif defined(CONFIG_SOC_SERIES_IMX_RT11XX)
CLOCK_EnableClock(kCLOCK_Iomuxc_Lpsr);
#endif /* CONFIG_SOC_SERIES_IMX_RT10XX */
#elif defined(CONFIG_SOC_MIMX8MQ6)
CLOCK_EnableClock(kCLOCK_Iomux);
#endif /* CONFIG_SOC_SERIES_IMX_RT */
return 0;
}
SYS_INIT(imx_pinctrl_init, PRE_KERNEL_1, 0);