diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-08-02 19:51:03 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-10-25 00:34:23 +0200 |
commit | ce1d43b9a9e8a3db8fe91696c0b0e3ac1a154e34 (patch) | |
tree | 7e47005c61e98f44005c17a636457c4398c73fdd /arch/mips/alchemy/common/gpiolib.c | |
parent | MIPS: Alchemy: Always build power code (diff) | |
download | linux-ce1d43b9a9e8a3db8fe91696c0b0e3ac1a154e34.tar.xz linux-ce1d43b9a9e8a3db8fe91696c0b0e3ac1a154e34.zip |
MIPS: Alchemy: support multiple GPIO styles in one kernel
For GPIOLIB=y decide at runtime which gpiochips to register;
in the GPIOLIB=n case, the gpio headers need to be reshuffled
a bit to make multiple implementations coexist peacefully.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
To: Linux-MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/2679/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/alchemy/common/gpiolib.c')
-rw-r--r-- | arch/mips/alchemy/common/gpiolib.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c new file mode 100644 index 000000000000..91fb4d9e30fd --- /dev/null +++ b/arch/mips/alchemy/common/gpiolib.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org> + * GPIOLIB support for Alchemy chips. + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Notes : + * This file must ONLY be built when CONFIG_GPIOLIB=y and + * CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail! + * au1000 SoC have only one GPIO block : GPIO1 + * Au1100, Au15x0, Au12x0 have a second one : GPIO2 + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/gpio.h> +#include <asm/mach-au1x00/gpio-au1000.h> + +static int gpio2_get(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); +} + +static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value) +{ + alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value); +} + +static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE); +} + +static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE, + value); +} + +static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE); +} + + +static int gpio1_get(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE); +} + +static void gpio1_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value); +} + +static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE); +} + +static int gpio1_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE, + value); +} + +static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset) +{ + return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE); +} + +struct gpio_chip alchemy_gpio_chip[] = { + [0] = { + .label = "alchemy-gpio1", + .direction_input = gpio1_direction_input, + .direction_output = gpio1_direction_output, + .get = gpio1_get, + .set = gpio1_set, + .to_irq = gpio1_to_irq, + .base = ALCHEMY_GPIO1_BASE, + .ngpio = ALCHEMY_GPIO1_NUM, + }, + [1] = { + .label = "alchemy-gpio2", + .direction_input = gpio2_direction_input, + .direction_output = gpio2_direction_output, + .get = gpio2_get, + .set = gpio2_set, + .to_irq = gpio2_to_irq, + .base = ALCHEMY_GPIO2_BASE, + .ngpio = ALCHEMY_GPIO2_NUM, + }, +}; + +static int __init alchemy_gpiochip_init(void) +{ + int ret = 0; + + switch (alchemy_get_cputype()) { + case ALCHEMY_CPU_AU1000: + ret = gpiochip_add(&alchemy_gpio_chip[0]); + break; + case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200: + ret = gpiochip_add(&alchemy_gpio_chip[0]); + ret |= gpiochip_add(&alchemy_gpio_chip[1]); + break; + } + return ret; +} +arch_initcall(alchemy_gpiochip_init); |