// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2021 NXP */ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/pinctrl/pinctrl.h> #include <linux/platform_device.h> #include "pinctrl-imx.h" enum imx8ulp_pads { IMX8ULP_PAD_PTD0 = 0, IMX8ULP_PAD_PTD1, IMX8ULP_PAD_PTD2, IMX8ULP_PAD_PTD3, IMX8ULP_PAD_PTD4, IMX8ULP_PAD_PTD5, IMX8ULP_PAD_PTD6, IMX8ULP_PAD_PTD7, IMX8ULP_PAD_PTD8, IMX8ULP_PAD_PTD9, IMX8ULP_PAD_PTD10, IMX8ULP_PAD_PTD11, IMX8ULP_PAD_PTD12, IMX8ULP_PAD_PTD13, IMX8ULP_PAD_PTD14, IMX8ULP_PAD_PTD15, IMX8ULP_PAD_PTD16, IMX8ULP_PAD_PTD17, IMX8ULP_PAD_PTD18, IMX8ULP_PAD_PTD19, IMX8ULP_PAD_PTD20, IMX8ULP_PAD_PTD21, IMX8ULP_PAD_PTD22, IMX8ULP_PAD_PTD23, IMX8ULP_PAD_RESERVE0, IMX8ULP_PAD_RESERVE1, IMX8ULP_PAD_RESERVE2, IMX8ULP_PAD_RESERVE3, IMX8ULP_PAD_RESERVE4, IMX8ULP_PAD_RESERVE5, IMX8ULP_PAD_RESERVE6, IMX8ULP_PAD_RESERVE7, IMX8ULP_PAD_PTE0, IMX8ULP_PAD_PTE1, IMX8ULP_PAD_PTE2, IMX8ULP_PAD_PTE3, IMX8ULP_PAD_PTE4, IMX8ULP_PAD_PTE5, IMX8ULP_PAD_PTE6, IMX8ULP_PAD_PTE7, IMX8ULP_PAD_PTE8, IMX8ULP_PAD_PTE9, IMX8ULP_PAD_PTE10, IMX8ULP_PAD_PTE11, IMX8ULP_PAD_PTE12, IMX8ULP_PAD_PTE13, IMX8ULP_PAD_PTE14, IMX8ULP_PAD_PTE15, IMX8ULP_PAD_PTE16, IMX8ULP_PAD_PTE17, IMX8ULP_PAD_PTE18, IMX8ULP_PAD_PTE19, IMX8ULP_PAD_PTE20, IMX8ULP_PAD_PTE21, IMX8ULP_PAD_PTE22, IMX8ULP_PAD_PTE23, IMX8ULP_PAD_RESERVE8, IMX8ULP_PAD_RESERVE9, IMX8ULP_PAD_RESERVE10, IMX8ULP_PAD_RESERVE11, IMX8ULP_PAD_RESERVE12, IMX8ULP_PAD_RESERVE13, IMX8ULP_PAD_RESERVE14, IMX8ULP_PAD_RESERVE15, IMX8ULP_PAD_PTF0, IMX8ULP_PAD_PTF1, IMX8ULP_PAD_PTF2, IMX8ULP_PAD_PTF3, IMX8ULP_PAD_PTF4, IMX8ULP_PAD_PTF5, IMX8ULP_PAD_PTF6, IMX8ULP_PAD_PTF7, IMX8ULP_PAD_PTF8, IMX8ULP_PAD_PTF9, IMX8ULP_PAD_PTF10, IMX8ULP_PAD_PTF11, IMX8ULP_PAD_PTF12, IMX8ULP_PAD_PTF13, IMX8ULP_PAD_PTF14, IMX8ULP_PAD_PTF15, IMX8ULP_PAD_PTF16, IMX8ULP_PAD_PTF17, IMX8ULP_PAD_PTF18, IMX8ULP_PAD_PTF19, IMX8ULP_PAD_PTF20, IMX8ULP_PAD_PTF21, IMX8ULP_PAD_PTF22, IMX8ULP_PAD_PTF23, IMX8ULP_PAD_PTF24, IMX8ULP_PAD_PTF25, IMX8ULP_PAD_PTF26, IMX8ULP_PAD_PTF27, IMX8ULP_PAD_PTF28, IMX8ULP_PAD_PTF29, IMX8ULP_PAD_PTF30, IMX8ULP_PAD_PTF31, }; /* Pad names for the pinmux subsystem */ static const struct pinctrl_pin_desc imx8ulp_pinctrl_pads[] = { IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD0), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD1), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD2), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD3), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD4), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD5), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD6), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD7), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD8), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD9), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD10), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD11), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD12), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD13), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD14), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD15), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD16), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD17), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD18), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD19), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD20), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD21), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD22), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD23), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE0), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE1), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE2), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE3), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE4), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE5), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE6), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE7), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE0), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE1), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE2), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE3), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE4), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE5), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE6), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE7), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE8), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE9), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE10), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE11), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE12), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE13), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE14), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE15), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE16), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE17), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE18), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE19), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE20), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE21), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE22), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE23), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE8), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE9), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE10), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE11), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE12), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE13), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE14), IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE15), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF0), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF1), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF2), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF3), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF4), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF5), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF6), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF7), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF8), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF9), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF10), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF11), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF12), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF13), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF14), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF15), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF16), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF17), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF18), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF19), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF20), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF21), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF22), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF23), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF24), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF25), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF26), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF27), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF28), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF29), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF30), IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF31), }; #define BM_OBE_ENABLED BIT(17) #define BM_IBE_ENABLED BIT(16) #define BM_MUX_MODE 0xf00 #define BP_MUX_MODE 8 static int imx8ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset, bool input) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx_pin_reg *pin_reg; u32 reg; pin_reg = &ipctl->pin_regs[offset]; if (pin_reg->mux_reg == -1) return -EINVAL; reg = readl(ipctl->base + pin_reg->mux_reg); if (input) reg = (reg & ~BM_OBE_ENABLED) | BM_IBE_ENABLED; else reg = (reg & ~BM_IBE_ENABLED) | BM_OBE_ENABLED; writel(reg, ipctl->base + pin_reg->mux_reg); return 0; } static const struct imx_pinctrl_soc_info imx8ulp_pinctrl_info = { .pins = imx8ulp_pinctrl_pads, .npins = ARRAY_SIZE(imx8ulp_pinctrl_pads), .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG, .gpio_set_direction = imx8ulp_pmx_gpio_set_direction, .mux_mask = BM_MUX_MODE, .mux_shift = BP_MUX_MODE, }; static const struct of_device_id imx8ulp_pinctrl_of_match[] = { { .compatible = "fsl,imx8ulp-iomuxc1", }, { /* sentinel */ } }; static int imx8ulp_pinctrl_probe(struct platform_device *pdev) { return imx_pinctrl_probe(pdev, &imx8ulp_pinctrl_info); } static struct platform_driver imx8ulp_pinctrl_driver = { .driver = { .name = "imx8ulp-pinctrl", .of_match_table = imx8ulp_pinctrl_of_match, .suppress_bind_attrs = true, }, .probe = imx8ulp_pinctrl_probe, }; static int __init imx8ulp_pinctrl_init(void) { return platform_driver_register(&imx8ulp_pinctrl_driver); } arch_initcall(imx8ulp_pinctrl_init); MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>"); MODULE_DESCRIPTION("NXP i.MX8ULP pinctrl driver"); MODULE_LICENSE("GPL v2");