diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d76732b..977fea5 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -165,10 +165,12 @@ config ARCH_IMX1 bool "i.MX1" select CPU_ARM920T + select PINCTRL_IMX_IOMUX_V1 config ARCH_IMX21 bool "i.MX21" select CPU_ARM926T + select PINCTRL_IMX_IOMUX_V1 config ARCH_IMX25 bool "i.MX25" @@ -180,6 +182,7 @@ bool "i.MX27" select CPU_ARM926T select ARCH_HAS_FEC_IMX + select PINCTRL_IMX_IOMUX_V1 config ARCH_IMX31 select CPU_V6 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 0b156aa..339b6a1 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,8 +1,8 @@ obj-y += clocksource.o gpio.o -obj-$(CONFIG_ARCH_IMX1) += imx1.o iomux-v1.o clk-imx1.o +obj-$(CONFIG_ARCH_IMX1) += imx1.o clk-imx1.o obj-$(CONFIG_ARCH_IMX25) += imx25.o clk-imx25.o -obj-$(CONFIG_ARCH_IMX21) += imx21.o iomux-v1.o clk-imx21.o -obj-$(CONFIG_ARCH_IMX27) += imx27.o iomux-v1.o clk-imx27.o +obj-$(CONFIG_ARCH_IMX21) += imx21.o clk-imx21.o +obj-$(CONFIG_ARCH_IMX27) += imx27.o clk-imx27.o obj-$(CONFIG_ARCH_IMX31) += imx31.o clk-imx31.o obj-$(CONFIG_ARCH_IMX35) += imx35.o clk-imx35.o obj-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o clk-imx5.o diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c deleted file mode 100644 index f8f9061..0000000 --- a/arch/arm/mach-imx/iomux-v1.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include - -/* - * GPIO Module and I/O Multiplexer - * x = 0..3 for reg_A, reg_B, reg_C, reg_D - * - * i.MX1 and i.MXL: 0 <= x <= 3 - * i.MX27 : 0 <= x <= 5 - */ -#define DDIR 0x00 -#define OCR1 0x04 -#define OCR2 0x08 -#define ICONFA1 0x0c -#define ICONFA2 0x10 -#define ICONFB1 0x14 -#define ICONFB2 0x18 -#define DR 0x1c -#define GIUS 0x20 -#define SSR 0x24 -#define ICR1 0x28 -#define ICR2 0x2c -#define IMR 0x30 -#define ISR 0x34 -#define GPR 0x38 -#define SWR 0x3c -#define PUEN 0x40 - -static void __iomem *iomuxv1_base; - -void imx_gpio_mode(int gpio_mode) -{ - unsigned int pin = gpio_mode & GPIO_PIN_MASK; - unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; - unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT; - unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT; - void __iomem *portbase = iomuxv1_base + port * 0x100; - uint32_t val; - - if (!iomuxv1_base) - return; - - /* Pullup enable */ - val = readl(portbase + PUEN); - if (gpio_mode & GPIO_PUEN) - val |= (1 << pin); - else - val &= ~(1 << pin); - writel(val, portbase + PUEN); - - /* Data direction */ - val = readl(portbase + DDIR); - if (gpio_mode & GPIO_OUT) - val |= 1 << pin; - else - val &= ~(1 << pin); - writel(val, portbase + DDIR); - - /* Primary / alternate function */ - val = readl(portbase + GPR); - if (gpio_mode & GPIO_AF) - val |= (1 << pin); - else - val &= ~(1 << pin); - writel(val, portbase + GPR); - - /* use as gpio? */ - val = readl(portbase + GIUS); - if (!(gpio_mode & (GPIO_PF | GPIO_AF))) - val |= (1 << pin); - else - val &= ~(1 << pin); - writel(val, portbase + GIUS); - - /* Output / input configuration */ - if (pin < 16) { - val = readl(portbase + OCR1); - val &= ~(3 << (pin * 2)); - val |= (ocr << (pin * 2)); - writel(val, portbase + OCR1); - - val = readl(portbase + ICONFA1); - val &= ~(3 << (pin * 2)); - val |= aout << (pin * 2); - writel(val, portbase + ICONFA1); - - val = readl(portbase + ICONFB1); - val &= ~(3 << (pin * 2)); - val |= bout << (pin * 2); - writel(val, portbase + ICONFB1); - } else { - pin -= 16; - - val = readl(portbase + OCR2); - val &= ~(3 << (pin * 2)); - val |= (ocr << (pin * 2)); - writel(val, portbase + OCR2); - - val = readl(portbase + ICONFA2); - val &= ~(3 << (pin * 2)); - val |= aout << (pin * 2); - writel(val, portbase + ICONFA2); - - val = readl(portbase + ICONFB2); - val &= ~(3 << (pin * 2)); - val |= bout << (pin * 2); - writel(val, portbase + ICONFB2); - } -} - -void imx_iomuxv1_init(void __iomem *base) -{ - iomuxv1_base = base; -} diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 6b73d7b..e6aee50 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -9,6 +9,11 @@ from the devicetree. Legacy drivers here may not need this core support but instead provide their own SoC specific APIs +config PINCTRL_IMX_IOMUX_V1 + bool "i.MX iomux v1" + help + This iomux controller is found on i.MX1,21,27. + config PINCTRL_IMX_IOMUX_V2 bool "i.MX iomux v2" help diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index b03a20f..e9272d0 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o +obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o diff --git a/drivers/pinctrl/imx-iomux-v1.c b/drivers/pinctrl/imx-iomux-v1.c new file mode 100644 index 0000000..f8f9061 --- /dev/null +++ b/drivers/pinctrl/imx-iomux-v1.c @@ -0,0 +1,116 @@ +#include +#include +#include + +/* + * GPIO Module and I/O Multiplexer + * x = 0..3 for reg_A, reg_B, reg_C, reg_D + * + * i.MX1 and i.MXL: 0 <= x <= 3 + * i.MX27 : 0 <= x <= 5 + */ +#define DDIR 0x00 +#define OCR1 0x04 +#define OCR2 0x08 +#define ICONFA1 0x0c +#define ICONFA2 0x10 +#define ICONFB1 0x14 +#define ICONFB2 0x18 +#define DR 0x1c +#define GIUS 0x20 +#define SSR 0x24 +#define ICR1 0x28 +#define ICR2 0x2c +#define IMR 0x30 +#define ISR 0x34 +#define GPR 0x38 +#define SWR 0x3c +#define PUEN 0x40 + +static void __iomem *iomuxv1_base; + +void imx_gpio_mode(int gpio_mode) +{ + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; + unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT; + unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT; + void __iomem *portbase = iomuxv1_base + port * 0x100; + uint32_t val; + + if (!iomuxv1_base) + return; + + /* Pullup enable */ + val = readl(portbase + PUEN); + if (gpio_mode & GPIO_PUEN) + val |= (1 << pin); + else + val &= ~(1 << pin); + writel(val, portbase + PUEN); + + /* Data direction */ + val = readl(portbase + DDIR); + if (gpio_mode & GPIO_OUT) + val |= 1 << pin; + else + val &= ~(1 << pin); + writel(val, portbase + DDIR); + + /* Primary / alternate function */ + val = readl(portbase + GPR); + if (gpio_mode & GPIO_AF) + val |= (1 << pin); + else + val &= ~(1 << pin); + writel(val, portbase + GPR); + + /* use as gpio? */ + val = readl(portbase + GIUS); + if (!(gpio_mode & (GPIO_PF | GPIO_AF))) + val |= (1 << pin); + else + val &= ~(1 << pin); + writel(val, portbase + GIUS); + + /* Output / input configuration */ + if (pin < 16) { + val = readl(portbase + OCR1); + val &= ~(3 << (pin * 2)); + val |= (ocr << (pin * 2)); + writel(val, portbase + OCR1); + + val = readl(portbase + ICONFA1); + val &= ~(3 << (pin * 2)); + val |= aout << (pin * 2); + writel(val, portbase + ICONFA1); + + val = readl(portbase + ICONFB1); + val &= ~(3 << (pin * 2)); + val |= bout << (pin * 2); + writel(val, portbase + ICONFB1); + } else { + pin -= 16; + + val = readl(portbase + OCR2); + val &= ~(3 << (pin * 2)); + val |= (ocr << (pin * 2)); + writel(val, portbase + OCR2); + + val = readl(portbase + ICONFA2); + val &= ~(3 << (pin * 2)); + val |= aout << (pin * 2); + writel(val, portbase + ICONFA2); + + val = readl(portbase + ICONFB2); + val &= ~(3 << (pin * 2)); + val |= bout << (pin * 2); + writel(val, portbase + ICONFB2); + } +} + +void imx_iomuxv1_init(void __iomem *base) +{ + iomuxv1_base = base; +}