From 5e2e95f520538e095d10456acd28d9107317aa32 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 15 Feb 2010 09:42:59 +0100 Subject: arm/imx/iomux-v1: rename source file and reorganize Kconfig stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König --- arch/arm/plat-mxc/iomux-v1.c | 156 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 arch/arm/plat-mxc/iomux-v1.c (limited to 'arch/arm/plat-mxc/iomux-v1.c') diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c new file mode 100644 index 00000000000..0b745686b37 --- /dev/null +++ b/arch/arm/plat-mxc/iomux-v1.c @@ -0,0 +1,156 @@ +/* + * arch/arm/plat-mxc/iomux-v1.c + * + * author: Sascha Hauer + * Created: april 20th, 2004 + * Copyright: Synertronixx GmbH + * + * Common code for i.MX1, i.MX21 and i.MX27 + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +void mxc_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 tmp; + + /* Pullup enable */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port)); + if (gpio_mode & GPIO_PUEN) + tmp |= (1 << pin); + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port)); + + /* Data direction */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port)); + if (gpio_mode & GPIO_OUT) + tmp |= 1 << pin; + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port)); + + /* Primary / alternate function */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port)); + if (gpio_mode & GPIO_AF) + tmp |= (1 << pin); + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port)); + + /* use as gpio? */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port)); + if (gpio_mode & (GPIO_PF | GPIO_AF)) + tmp &= ~(1 << pin); + else + tmp |= (1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); + + if (pin < 16) { + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); + } else { + pin -= 16; + + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port)); + } +} +EXPORT_SYMBOL(mxc_gpio_mode); + +int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, + const char *label) +{ + const int *p = pin_list; + int i; + unsigned gpio; + unsigned mode; + int ret = -EINVAL; + + for (i = 0; i < count; i++) { + gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); + mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK); + + if (gpio >= (GPIO_PORT_MAX + 1) * 32) + goto setup_error; + + ret = gpio_request(gpio, label); + if (ret) + goto setup_error; + + mxc_gpio_mode(gpio | mode); + + p++; + } + return 0; + +setup_error: + mxc_gpio_release_multiple_pins(pin_list, i); + return ret; +} +EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins); + +void mxc_gpio_release_multiple_pins(const int *pin_list, int count) +{ + const int *p = pin_list; + int i; + + for (i = 0; i < count; i++) { + unsigned gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); + gpio_free(gpio); + p++; + } + +} +EXPORT_SYMBOL(mxc_gpio_release_multiple_pins); -- cgit v1.2.3-70-g09d2 From f021b5a1ef1b229ddc8c5cf3f2c5da308d974a5a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 15 Feb 2010 16:57:09 +0100 Subject: arm/imx/iomux-v1: make base address a runtime choice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While at it move register modification to static inlines and so make the relevant code more readable. Signed-off-by: Uwe Kleine-König --- arch/arm/plat-mxc/include/mach/iomux.h | 1 - arch/arm/plat-mxc/iomux-v1.c | 193 ++++++++++++++++++++++----------- 2 files changed, 127 insertions(+), 67 deletions(-) (limited to 'arch/arm/plat-mxc/iomux-v1.c') diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h index 011cfcd8b82..e15d28aaab8 100644 --- a/arch/arm/plat-mxc/include/mach/iomux.h +++ b/arch/arm/plat-mxc/include/mach/iomux.h @@ -24,7 +24,6 @@ * GPIO Module and I/O Multiplexer * x = 0..3 for reg_A, reg_B, reg_C, reg_D */ -#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) #define MXC_DDIR(x) (0x00 + ((x) << 8)) #define MXC_OCR1(x) (0x04 + ((x) << 8)) #define MXC_OCR2(x) (0x08 + ((x) << 8)) diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c index 0b745686b37..aeaf2951579 100644 --- a/arch/arm/plat-mxc/iomux-v1.c +++ b/arch/arm/plat-mxc/iomux-v1.c @@ -1,9 +1,8 @@ /* * arch/arm/plat-mxc/iomux-v1.c * - * author: Sascha Hauer - * Created: april 20th, 2004 - * Copyright: Synertronixx GmbH + * Copyright (C) 2004 Sascha Hauer, Synertronixx GmbH + * Copyright (C) 2009 Uwe Kleine-Koenig, Pengutronix * * Common code for i.MX1, i.MX21 and i.MX27 * @@ -18,9 +17,8 @@ * 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 - * + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -34,78 +32,119 @@ #include #include +static void __iomem *imx_iomuxv1_baseaddr; + +static inline unsigned long imx_iomuxv1_readl(unsigned offset) +{ + return __raw_readl(imx_iomuxv1_baseaddr + offset); +} + +static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset) +{ + __raw_writel(val, imx_iomuxv1_baseaddr + offset); +} + +static inline void imx_iomuxv1_rmwl(unsigned offset, + unsigned long mask, unsigned long value) +{ + unsigned long reg = imx_iomuxv1_readl(offset); + + reg &= ~mask; + reg |= value; + + imx_iomuxv1_writel(reg, offset); +} + +static inline void imx_iomuxv1_set_puen( + unsigned int port, unsigned int pin, int on) +{ + unsigned long mask = 1 << pin; + + imx_iomuxv1_rmwl(MXC_PUEN(port), mask, on ? mask : 0); +} + +static inline void imx_iomuxv1_set_ddir( + unsigned int port, unsigned int pin, int out) +{ + unsigned long mask = 1 << pin; + + imx_iomuxv1_rmwl(MXC_DDIR(port), mask, out ? mask : 0); +} + +static inline void imx_iomuxv1_set_gpr( + unsigned int port, unsigned int pin, int af) +{ + unsigned long mask = 1 << pin; + + imx_iomuxv1_rmwl(MXC_GPR(port), mask, af ? mask : 0); +} + +static inline void imx_iomuxv1_set_gius( + unsigned int port, unsigned int pin, int inuse) +{ + unsigned long mask = 1 << pin; + + imx_iomuxv1_rmwl(MXC_GIUS(port), mask, inuse ? mask : 0); +} + +static inline void imx_iomuxv1_set_ocr( + unsigned int port, unsigned int pin, unsigned int ocr) +{ + unsigned long shift = (pin & 0xf) << 1; + unsigned long mask = 3 << shift; + unsigned long value = ocr << shift; + unsigned long offset = pin < 16 ? MXC_OCR1(port) : MXC_OCR2(port); + + imx_iomuxv1_rmwl(offset, mask, value); +} + +static inline void imx_iomuxv1_set_iconfa( + unsigned int port, unsigned int pin, unsigned int aout) +{ + unsigned long shift = (pin & 0xf) << 1; + unsigned long mask = 3 << shift; + unsigned long value = aout << shift; + unsigned long offset = pin < 16 ? MXC_ICONFA1(port) : MXC_ICONFA2(port); + + imx_iomuxv1_rmwl(offset, mask, value); +} + +static inline void imx_iomuxv1_set_iconfb( + unsigned int port, unsigned int pin, unsigned int bout) +{ + unsigned long shift = (pin & 0xf) << 1; + unsigned long mask = 3 << shift; + unsigned long value = bout << shift; + unsigned long offset = pin < 16 ? MXC_ICONFB1(port) : MXC_ICONFB2(port); + + imx_iomuxv1_rmwl(offset, mask, value); +} + void mxc_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 tmp; + unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3; + unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3; /* Pullup enable */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port)); - if (gpio_mode & GPIO_PUEN) - tmp |= (1 << pin); - else - tmp &= ~(1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port)); + imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN); /* Data direction */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port)); - if (gpio_mode & GPIO_OUT) - tmp |= 1 << pin; - else - tmp &= ~(1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port)); + imx_iomuxv1_set_ddir(port, pin, gpio_mode & GPIO_OUT); /* Primary / alternate function */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port)); - if (gpio_mode & GPIO_AF) - tmp |= (1 << pin); - else - tmp &= ~(1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port)); + imx_iomuxv1_set_gpr(port, pin, gpio_mode & GPIO_AF); /* use as gpio? */ - tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port)); - if (gpio_mode & (GPIO_PF | GPIO_AF)) - tmp &= ~(1 << pin); - else - tmp |= (1 << pin); - __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); - - if (pin < 16) { - tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); - } else { - pin -= 16; - - tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port)); - - tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port)); - tmp &= ~(3 << (pin * 2)); - tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); - __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port)); - } + imx_iomuxv1_set_gius(port, pin, !(gpio_mode & (GPIO_PF | GPIO_AF))); + + imx_iomuxv1_set_ocr(port, pin, ocr); + + imx_iomuxv1_set_iconfa(port, pin, aout); + + imx_iomuxv1_set_iconfb(port, pin, bout); } EXPORT_SYMBOL(mxc_gpio_mode); @@ -151,6 +190,28 @@ void mxc_gpio_release_multiple_pins(const int *pin_list, int count) gpio_free(gpio); p++; } - } EXPORT_SYMBOL(mxc_gpio_release_multiple_pins); + +static int imx_iomuxv1_init(void) +{ +#ifdef CONFIG_ARCH_MX1 + if (cpu_is_mx1()) + imx_iomuxv1_baseaddr = MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR); + else +#endif +#ifdef CONFIG_MACH_MX21 + if (cpu_is_mx21()) + imx_iomuxv1_baseaddr = MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR); + else +#endif +#ifdef CONFIG_MACH_MX27 + if (cpu_is_mx27()) + imx_iomuxv1_baseaddr = MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR); + else +#endif + return -ENODEV; + + return 0; +} +pure_initcall(imx_iomuxv1_init); -- cgit v1.2.3-70-g09d2 From 111588f8304b7e13f107bd4c590e8d3939ad907d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 15 Feb 2010 21:52:34 +0100 Subject: arm/imx/iomux-v1: rename header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addionally make iomux-mx*.h headers stand-alone and similar to iomux-v3 platform files should include their platform iomux header from now on. For now iomux.h simply includes all iomux-v1 platform headers and so provides compatibility until all files are converted. Signed-off-by: Uwe Kleine-König --- arch/arm/plat-mxc/include/mach/iomux-mx1.h | 4 +- arch/arm/plat-mxc/include/mach/iomux-mx21.h | 5 +- arch/arm/plat-mxc/include/mach/iomux-mx27.h | 5 +- arch/arm/plat-mxc/include/mach/iomux-mx2x.h | 4 - arch/arm/plat-mxc/include/mach/iomux-v1.h | 110 +++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/iomux.h | 123 +++------------------------- arch/arm/plat-mxc/iomux-v1.c | 2 +- 7 files changed, 126 insertions(+), 127 deletions(-) create mode 100644 arch/arm/plat-mxc/include/mach/iomux-v1.h (limited to 'arch/arm/plat-mxc/iomux-v1.c') diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1.h b/arch/arm/plat-mxc/include/mach/iomux-mx1.h index d29a7b38975..6b1507cf378 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx1.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx1.h @@ -18,9 +18,7 @@ #ifndef __MACH_IOMUX_MX1_H__ #define __MACH_IOMUX_MX1_H__ -#ifndef GPIO_PORTA -#error Please include mach/iomux.h -#endif +#include #define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0) #define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx21.h b/arch/arm/plat-mxc/include/mach/iomux-mx21.h index 4cede3220be..1495dfda783 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx21.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx21.h @@ -18,9 +18,8 @@ #ifndef __MACH_IOMUX_MX21_H__ #define __MACH_IOMUX_MX21_H__ -#ifndef GPIO_PORTA -#error Please include mach/iomux.h -#endif +#include +#include /* Primary GPIO pin functions */ diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx27.h b/arch/arm/plat-mxc/include/mach/iomux-mx27.h index abec94d3f21..d9f9a6e32d8 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx27.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx27.h @@ -19,9 +19,8 @@ #ifndef __MACH_IOMUX_MX27_H__ #define __MACH_IOMUX_MX27_H__ -#ifndef GPIO_PORTA -#error Please include mach/iomux.h -#endif +#include +#include /* Primary GPIO pin functions */ diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h index 522e83a570f..c4f116d214f 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h @@ -19,10 +19,6 @@ #ifndef __MACH_IOMUX_MX2x_H__ #define __MACH_IOMUX_MX2x_H__ -#ifndef GPIO_PORTA -#error Please include mach/iomux.h -#endif - /* Primary GPIO pin functions */ #define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5) diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h new file mode 100644 index 00000000000..54abfc051b7 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * Copyright (C) 2009 by Holger Schurig + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef __MACH_IOMUX_V1_H__ +#define __MACH_IOMUX_V1_H__ + +/* +* GPIO Module and I/O Multiplexer +* x = 0..3 for reg_A, reg_B, reg_C, reg_D +*/ +#define MXC_DDIR(x) (0x00 + ((x) << 8)) +#define MXC_OCR1(x) (0x04 + ((x) << 8)) +#define MXC_OCR2(x) (0x08 + ((x) << 8)) +#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) +#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) +#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) +#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) +#define MXC_DR(x) (0x1c + ((x) << 8)) +#define MXC_GIUS(x) (0x20 + ((x) << 8)) +#define MXC_SSR(x) (0x24 + ((x) << 8)) +#define MXC_ICR1(x) (0x28 + ((x) << 8)) +#define MXC_ICR2(x) (0x2c + ((x) << 8)) +#define MXC_IMR(x) (0x30 + ((x) << 8)) +#define MXC_ISR(x) (0x34 + ((x) << 8)) +#define MXC_GPR(x) (0x38 + ((x) << 8)) +#define MXC_SWR(x) (0x3c + ((x) << 8)) +#define MXC_PUEN(x) (0x40 + ((x) << 8)) + +#ifdef CONFIG_ARCH_MX1 +# define GPIO_PORT_MAX 3 +#endif +#ifdef CONFIG_ARCH_MX2 +# define GPIO_PORT_MAX 5 +#endif + +#ifndef GPIO_PORT_MAX +# error "GPIO config port count unknown!" +#endif + +#define GPIO_PIN_MASK 0x1f + +#define GPIO_PORT_SHIFT 5 +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) + +#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) + +#define GPIO_OUT (1 << 8) +#define GPIO_IN (0 << 8) +#define GPIO_PUEN (1 << 9) + +#define GPIO_PF (1 << 10) +#define GPIO_AF (1 << 11) + +#define GPIO_OCR_SHIFT 12 +#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) +#define GPIO_AIN (0 << GPIO_OCR_SHIFT) +#define GPIO_BIN (1 << GPIO_OCR_SHIFT) +#define GPIO_CIN (2 << GPIO_OCR_SHIFT) +#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) + +#define GPIO_AOUT_SHIFT 14 +#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) + +#define GPIO_BOUT_SHIFT 16 +#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) + +/* decode irq number to use with IMR(x), ISR(x) and friends */ +#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5) + +#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x) +#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) +#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) +#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) +#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) +#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x) + +extern void mxc_gpio_mode(int gpio_mode); +extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, + const char *label); +extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count); + +#endif /* __MACH_IOMUX_V1_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h index 8b2467f300b..3d226d7e7be 100644 --- a/arch/arm/plat-mxc/include/mach/iomux.h +++ b/arch/arm/plat-mxc/include/mach/iomux.h @@ -1,101 +1,14 @@ /* -* Copyright (C) 2008 by Sascha Hauer -* Copyright (C) 2009 by Holger Schurig -* -* 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., 51 Franklin Street, Fifth Floor, Boston, -* MA 02110-1301, USA. -*/ - -#ifndef _MXC_IOMUX_H -#define _MXC_IOMUX_H - -/* -* GPIO Module and I/O Multiplexer -* x = 0..3 for reg_A, reg_B, reg_C, reg_D -*/ -#define MXC_DDIR(x) (0x00 + ((x) << 8)) -#define MXC_OCR1(x) (0x04 + ((x) << 8)) -#define MXC_OCR2(x) (0x08 + ((x) << 8)) -#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) -#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) -#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) -#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) -#define MXC_DR(x) (0x1c + ((x) << 8)) -#define MXC_GIUS(x) (0x20 + ((x) << 8)) -#define MXC_SSR(x) (0x24 + ((x) << 8)) -#define MXC_ICR1(x) (0x28 + ((x) << 8)) -#define MXC_ICR2(x) (0x2c + ((x) << 8)) -#define MXC_IMR(x) (0x30 + ((x) << 8)) -#define MXC_ISR(x) (0x34 + ((x) << 8)) -#define MXC_GPR(x) (0x38 + ((x) << 8)) -#define MXC_SWR(x) (0x3c + ((x) << 8)) -#define MXC_PUEN(x) (0x40 + ((x) << 8)) - -#ifdef CONFIG_ARCH_MX1 -# define GPIO_PORT_MAX 3 -#endif -#ifdef CONFIG_ARCH_MX2 -# define GPIO_PORT_MAX 5 -#endif -#ifdef CONFIG_ARCH_MX25 -# define GPIO_PORT_MAX 3 -#endif - -#ifndef GPIO_PORT_MAX -# error "GPIO config port count unknown!" -#endif - -#define GPIO_PIN_MASK 0x1f - -#define GPIO_PORT_SHIFT 5 -#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) - -#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) -#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) -#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) -#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) -#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) -#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) - -#define GPIO_OUT (1 << 8) -#define GPIO_IN (0 << 8) -#define GPIO_PUEN (1 << 9) - -#define GPIO_PF (1 << 10) -#define GPIO_AF (1 << 11) - -#define GPIO_OCR_SHIFT 12 -#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) -#define GPIO_AIN (0 << GPIO_OCR_SHIFT) -#define GPIO_BIN (1 << GPIO_OCR_SHIFT) -#define GPIO_CIN (2 << GPIO_OCR_SHIFT) -#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) - -#define GPIO_AOUT_SHIFT 14 -#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) - -#define GPIO_BOUT_SHIFT 16 -#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) + * Copyright (C) 2010 Uwe Kleine-Koenig, Pengutronix + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef __MACH_IOMUX_H__ +#define __MACH_IOMUX_H__ +/* This file will go away, please include mach/iomux-mx... directly */ #ifdef CONFIG_ARCH_MX1 #include @@ -110,20 +23,4 @@ #endif #endif -/* decode irq number to use with IMR(x), ISR(x) and friends */ -#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5) - -#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x) -#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) -#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) -#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) -#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) -#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x) - - -extern void mxc_gpio_mode(int gpio_mode); -extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, - const char *label); -extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count); - -#endif +#endif /* __MACH_IOMUX_H__ */ diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c index aeaf2951579..5798b35b6cb 100644 --- a/arch/arm/plat-mxc/iomux-v1.c +++ b/arch/arm/plat-mxc/iomux-v1.c @@ -30,7 +30,7 @@ #include #include -#include +#include static void __iomem *imx_iomuxv1_baseaddr; -- cgit v1.2.3-70-g09d2 From bac3fcfad565c9bbceeed8b607f140c29df97355 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 15 Feb 2010 09:47:55 +0100 Subject: arm/imx/iomux-v1: check for invalid modes in mxc_gpio_mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mxc_gpio_mode checks for invalid pins and so it returns zero for success, -EINVAL for invalid pins. While at it, remove definitions of GPIO_PORT_MAX removed as they are unused now. Signed-off-by: Uwe Kleine-König --- arch/arm/plat-mxc/Makefile | 1 - arch/arm/plat-mxc/include/mach/iomux-mx3.h | 5 -- arch/arm/plat-mxc/include/mach/iomux-v1.h | 17 ++----- arch/arm/plat-mxc/iomux-v1.c | 77 +++++++++++++++++++----------- 4 files changed, 54 insertions(+), 46 deletions(-) (limited to 'arch/arm/plat-mxc/iomux-v1.c') diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 41d31762bca..9465a01b3f5 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -8,7 +8,6 @@ obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o obj-$(CONFIG_ARCH_MX1) += dma-mx1-mx2.o obj-$(CONFIG_ARCH_MX2) += dma-mx1-mx2.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o -CFLAGS_iomux-v1.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o obj-$(CONFIG_MXC_PWM) += pwm.o obj-$(CONFIG_USB_EHCI_MXC) += ehci.o diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index e5e5861cbbe..e51465d7b22 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -164,11 +164,6 @@ int mxc_iomux_mode(unsigned int pin_mode); (((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \ MXC_GPIO_IRQ_START) -/* - * The number of gpio devices among the pads - */ -#define GPIO_PORT_MAX 3 - /* * This enumeration is constructed based on the Section * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h index 54abfc051b7..884f5753f27 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-v1.h +++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h @@ -41,16 +41,9 @@ #define MXC_SWR(x) (0x3c + ((x) << 8)) #define MXC_PUEN(x) (0x40 + ((x) << 8)) -#ifdef CONFIG_ARCH_MX1 -# define GPIO_PORT_MAX 3 -#endif -#ifdef CONFIG_ARCH_MX2 -# define GPIO_PORT_MAX 5 -#endif - -#ifndef GPIO_PORT_MAX -# error "GPIO config port count unknown!" -#endif +#define MX1_NUM_GPIO_PORT 4 +#define MX21_NUM_GPIO_PORT 6 +#define MX27_NUM_GPIO_PORT 6 #define GPIO_PIN_MASK 0x1f @@ -102,9 +95,9 @@ #define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) #define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x) -extern void mxc_gpio_mode(int gpio_mode); +extern int mxc_gpio_mode(int gpio_mode); extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, - const char *label); + const char *label); extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count); #endif /* __MACH_IOMUX_V1_H__ */ diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c index 5798b35b6cb..960a02cbcba 100644 --- a/arch/arm/plat-mxc/iomux-v1.c +++ b/arch/arm/plat-mxc/iomux-v1.c @@ -33,6 +33,7 @@ #include static void __iomem *imx_iomuxv1_baseaddr; +static unsigned imx_iomuxv1_numports; static inline unsigned long imx_iomuxv1_readl(unsigned offset) { @@ -120,7 +121,7 @@ static inline void imx_iomuxv1_set_iconfb( imx_iomuxv1_rmwl(offset, mask, value); } -void mxc_gpio_mode(int gpio_mode) +int mxc_gpio_mode(int gpio_mode) { unsigned int pin = gpio_mode & GPIO_PIN_MASK; unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; @@ -128,6 +129,9 @@ void mxc_gpio_mode(int gpio_mode) unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3; unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3; + if (port >= imx_iomuxv1_numports) + return -EINVAL; + /* Pullup enable */ imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN); @@ -145,50 +149,64 @@ void mxc_gpio_mode(int gpio_mode) imx_iomuxv1_set_iconfa(port, pin, aout); imx_iomuxv1_set_iconfb(port, pin, bout); + + return 0; } EXPORT_SYMBOL(mxc_gpio_mode); +static int imx_iomuxv1_setup_multiple(const int *list, unsigned count) +{ + size_t i; + int ret; + + for (i = 0; i < count; ++i) { + ret = mxc_gpio_mode(list[i]); + + if (ret) + return ret; + } + + return ret; +} + int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, const char *label) { - const int *p = pin_list; - int i; - unsigned gpio; - unsigned mode; - int ret = -EINVAL; + size_t i; + int ret; - for (i = 0; i < count; i++) { - gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); - mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK); - - if (gpio >= (GPIO_PORT_MAX + 1) * 32) - goto setup_error; + for (i = 0; i < count; ++i) { + unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK); ret = gpio_request(gpio, label); if (ret) - goto setup_error; + goto err_gpio_request; + } - mxc_gpio_mode(gpio | mode); + ret = imx_iomuxv1_setup_multiple(pin_list, count); + if (ret) + goto err_setup; - p++; - } return 0; -setup_error: +err_setup: + BUG_ON(i != count); + +err_gpio_request: mxc_gpio_release_multiple_pins(pin_list, i); + return ret; } EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins); void mxc_gpio_release_multiple_pins(const int *pin_list, int count) { - const int *p = pin_list; - int i; + size_t i; + + for (i = 0; i < count; ++i) { + unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK); - for (i = 0; i < count; i++) { - unsigned gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); gpio_free(gpio); - p++; } } EXPORT_SYMBOL(mxc_gpio_release_multiple_pins); @@ -196,19 +214,22 @@ EXPORT_SYMBOL(mxc_gpio_release_multiple_pins); static int imx_iomuxv1_init(void) { #ifdef CONFIG_ARCH_MX1 - if (cpu_is_mx1()) + if (cpu_is_mx1()) { imx_iomuxv1_baseaddr = MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR); - else + imx_iomuxv1_numports = MX1_NUM_GPIO_PORT; + } else #endif #ifdef CONFIG_MACH_MX21 - if (cpu_is_mx21()) + if (cpu_is_mx21()) { imx_iomuxv1_baseaddr = MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR); - else + imx_iomuxv1_numports = MX21_NUM_GPIO_PORT; + } else #endif #ifdef CONFIG_MACH_MX27 - if (cpu_is_mx27()) + if (cpu_is_mx27()) { imx_iomuxv1_baseaddr = MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR); - else + imx_iomuxv1_numports = MX27_NUM_GPIO_PORT; + } else #endif return -ENODEV; -- cgit v1.2.3-70-g09d2