diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 767cd30..445a879 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,10 +1,10 @@ -obj-y += clocksource.o -obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o gpio.o iomux-v1.o -obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o iomux-v3.o -obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o gpio.o imx21.o iomux-v1.o -obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o gpio.o imx27.o iomux-v1.o -obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o iomux-v2.o -obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o iomux-v3.o +obj-y += clocksource.o gpio.o +obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o imx1.o iomux-v1.o +obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o imx25.o iomux-v3.o +obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o imx21.o iomux-v1.o +obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o imx27.o iomux-v1.o +obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o imx31.o iomux-v2.o +obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o imx35.o iomux-v3.o obj-$(CONFIG_IMX_CLKO) += clko.o obj-$(CONFIG_NAND_IMX) += nand.o obj-y += speed.o diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c index eb095ec..6157bd1 100644 --- a/arch/arm/mach-imx/gpio.c +++ b/arch/arm/mach-imx/gpio.c @@ -24,28 +24,105 @@ */ #include +#include +#include #include +#if defined CONFIG_ARCH_IMX1 || defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27 +#define GPIO_DR 0x1c +#define GPIO_GDIR 0x00 +#define GPIO_PSR 0x24 +#define GPIO_ICR1 0x28 +#define GPIO_ICR2 0x2C +#define GPIO_IMR 0x30 +#define GPIO_ISR 0x34 +#else +#define GPIO_DR 0x00 +#define GPIO_GDIR 0x04 +#define GPIO_PSR 0x08 +#define GPIO_ICR1 0x0C +#define GPIO_ICR2 0x10 +#define GPIO_IMR 0x14 +#define GPIO_ISR 0x18 +#define GPIO_ISR 0x18 +#endif + +extern void *imx_gpio_base[]; +extern int imx_gpio_count; + +static void *gpio_get_base(unsigned gpio) +{ + if (gpio >= imx_gpio_count) + return 0; + + return imx_gpio_base[gpio / 32]; +} + void gpio_set_value(unsigned gpio, int value) { - if(value) - DR(gpio >> GPIO_PORT_SHIFT) |= (1 << (gpio & GPIO_PIN_MASK)); + void *base = gpio_get_base(gpio); + int shift = gpio % 32; + u32 val; + + if (!base) + return; + + val = readl(base + GPIO_DR); + + if (value) + val |= 1 << shift; else - DR(gpio >> GPIO_PORT_SHIFT) &= ~(1 << (gpio & GPIO_PIN_MASK)); + val &= ~(1 << shift); + + writel(val, base + GPIO_DR); } int gpio_direction_input(unsigned gpio) { - imx_gpio_mode(gpio | GPIO_IN | GPIO_GIUS | GPIO_GPIO); + void *base = gpio_get_base(gpio); + int shift = gpio % 32; + u32 val; + + if (!base) + return -EINVAL; + + val = readl(base + GPIO_GDIR); + val &= ~(1 << shift); + writel(val, base + GPIO_GDIR); + return 0; } int gpio_direction_output(unsigned gpio, int value) { + void *base = gpio_get_base(gpio); + int shift = gpio % 32; + u32 val; + + if (!base) + return -EINVAL; + gpio_set_value(gpio, value); - imx_gpio_mode(gpio | GPIO_OUT | GPIO_GIUS | GPIO_GPIO); + + val = readl(base + GPIO_GDIR); + val |= 1 << shift; + writel(val, base + GPIO_GDIR); + return 0; } +int gpio_get_value(unsigned gpio) +{ + void *base = gpio_get_base(gpio); + int shift = gpio % 32; + u32 val; + + if (!base) + return -EINVAL; + + val = readl(base + GPIO_DR); + + return val & (1 << shift) ? 1 : 0; +} diff --git a/arch/arm/mach-imx/gpio.h b/arch/arm/mach-imx/gpio.h new file mode 100644 index 0000000..545cebe --- /dev/null +++ b/arch/arm/mach-imx/gpio.h @@ -0,0 +1,4 @@ + +extern void *imx_gpio_base[]; +extern int imx_gpio_count; + diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c new file mode 100644 index 0000000..742a260 --- /dev/null +++ b/arch/arm/mach-imx/imx1.c @@ -0,0 +1,31 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include "gpio.h" + +void *imx_gpio_base[] = { + (void *)0x0021c000, + (void *)0x0021c100, + (void *)0x0021c200, + (void *)0x0021c300, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + + diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c index 0741f11..bbef33d 100644 --- a/arch/arm/mach-imx/imx21.c +++ b/arch/arm/mach-imx/imx21.c @@ -18,6 +18,8 @@ #include #include +#include "gpio.h" + int imx_silicon_revision(void) { // Known values: @@ -25,3 +27,15 @@ // 0x201D101D : mask set ID 1M55B or M55B return CID; } + +void *imx_gpio_base[] = { + (void *)0x10015000, + (void *)0x10015100, + (void *)0x10015200, + (void *)0x10015300, + (void *)0x10015400, + (void *)0x10015500, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c new file mode 100644 index 0000000..00a1e4e --- /dev/null +++ b/arch/arm/mach-imx/imx25.c @@ -0,0 +1,30 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include "gpio.h" + +void *imx_gpio_base[] = { + (void *)0x53fcc000, + (void *)0x53fd0000, + (void *)0x53fa4000, + (void *)0x53f9c000, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c index c33346a..04bdd5f 100644 --- a/arch/arm/mach-imx/imx27.c +++ b/arch/arm/mach-imx/imx27.c @@ -18,8 +18,21 @@ #include #include +#include "gpio.h" + int imx_silicon_revision(void) { - return CID >> 28; + return CID >> 28; } +void *imx_gpio_base[] = { + (void *)0x10015000, + (void *)0x10015100, + (void *)0x10015200, + (void *)0x10015300, + (void *)0x10015400, + (void *)0x10015500, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c new file mode 100644 index 0000000..f2fea4c --- /dev/null +++ b/arch/arm/mach-imx/imx31.c @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include "gpio.h" + +void *imx_gpio_base[] = { + (void *)0x53fcc000, + (void *)0x53fd0000, + (void *)0x53fa4000, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c new file mode 100644 index 0000000..f2fea4c --- /dev/null +++ b/arch/arm/mach-imx/imx35.c @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include "gpio.h" + +void *imx_gpio_base[] = { + (void *)0x53fcc000, + (void *)0x53fd0000, + (void *)0x53fa4000, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c new file mode 100644 index 0000000..8c4fc11 --- /dev/null +++ b/arch/arm/mach-imx/imx51.c @@ -0,0 +1,30 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#include "gpio.h" + +void *imx_gpio_base[] = { + (void *)0x87f84000, + (void *)0x73f88000, + (void *)0x73f8c000, + (void *)0x73f90000, +}; + +int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; + diff --git a/arch/arm/mach-imx/include/mach/gpio.h b/arch/arm/mach-imx/include/mach/gpio.h index 71298f4..0ebc3f9 100644 --- a/arch/arm/mach-imx/include/mach/gpio.h +++ b/arch/arm/mach-imx/include/mach/gpio.h @@ -3,6 +3,7 @@ void imx_gpio_mode(int gpio_mode); void gpio_set_value(unsigned gpio, int value); +int gpio_get_value(unsigned gpio); int gpio_direction_output(unsigned gpio, int value); int gpio_direction_input(unsigned gpio); diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h index 459714e..2cc49dd 100644 --- a/arch/arm/mach-imx/include/mach/imx-regs.h +++ b/arch/arm/mach-imx/include/mach/imx-regs.h @@ -55,31 +55,6 @@ # error "unknown i.MX soc type" #endif -/* - * 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(x) __REG2(IMX_GPIO_BASE + 0x00, ((x) & 7) << 8) -#define OCR1(x) __REG2(IMX_GPIO_BASE + 0x04, ((x) & 7) << 8) -#define OCR2(x) __REG2(IMX_GPIO_BASE + 0x08, ((x) & 7) << 8) -#define ICONFA1(x) __REG2(IMX_GPIO_BASE + 0x0c, ((x) & 7) << 8) -#define ICONFA2(x) __REG2(IMX_GPIO_BASE + 0x10, ((x) & 7) << 8) -#define ICONFB1(x) __REG2(IMX_GPIO_BASE + 0x14, ((x) & 7) << 8) -#define ICONFB2(x) __REG2(IMX_GPIO_BASE + 0x18, ((x) & 7) << 8) -#define DR(x) __REG2(IMX_GPIO_BASE + 0x1c, ((x) & 7) << 8) -#define GIUS(x) __REG2(IMX_GPIO_BASE + 0x20, ((x) & 7) << 8) -#define SSR(x) __REG2(IMX_GPIO_BASE + 0x24, ((x) & 7) << 8) -#define ICR1(x) __REG2(IMX_GPIO_BASE + 0x28, ((x) & 7) << 8) -#define ICR2(x) __REG2(IMX_GPIO_BASE + 0x2c, ((x) & 7) << 8) -#define IMR(x) __REG2(IMX_GPIO_BASE + 0x30, ((x) & 7) << 8) -#define ISR(x) __REG2(IMX_GPIO_BASE + 0x34, ((x) & 7) << 8) -#define GPR(x) __REG2(IMX_GPIO_BASE + 0x38, ((x) & 7) << 8) -#define SWR(x) __REG2(IMX_GPIO_BASE + 0x3c, ((x) & 7) << 8) -#define PUEN(x) __REG2(IMX_GPIO_BASE + 0x40, ((x) & 7) << 8) - #define GPIO_PIN_MASK 0x1f #define GPIO_PORT_SHIFT 5