linux/arch/mips/alchemy/common/gpiolib.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
   3 *      GPIOLIB support for Alchemy chips.
   4 *
   5 *  This program is free software; you can redistribute  it and/or modify it
   6 *  under  the terms of  the GNU General  Public License as published by the
   7 *  Free Software Foundation;  either version 2 of the  License, or (at your
   8 *  option) any later version.
   9 *
  10 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  11 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  12 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  13 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  14 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  15 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  16 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  17 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  18 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  19 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20 *
  21 *  You should have received a copy of the  GNU General Public License along
  22 *  with this program; if not, write  to the Free Software Foundation, Inc.,
  23 *  675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 *  Notes :
  26 *      This file must ONLY be built when CONFIG_GPIOLIB=y and
  27 *       CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail!
  28 *      au1000 SoC have only one GPIO block : GPIO1
  29 *      Au1100, Au15x0, Au12x0 have a second one : GPIO2
  30 *      Au1300 is totally different: 1 block with up to 128 GPIOs
  31 */
  32
  33#include <linux/init.h>
  34#include <linux/kernel.h>
  35#include <linux/module.h>
  36#include <linux/types.h>
  37#include <linux/gpio.h>
  38#include <asm/mach-au1x00/gpio-au1000.h>
  39#include <asm/mach-au1x00/gpio-au1300.h>
  40
  41static int gpio2_get(struct gpio_chip *chip, unsigned offset)
  42{
  43        return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
  44}
  45
  46static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
  47{
  48        alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value);
  49}
  50
  51static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
  52{
  53        return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE);
  54}
  55
  56static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset,
  57                                  int value)
  58{
  59        return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE,
  60                                                value);
  61}
  62
  63static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
  64{
  65        return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
  66}
  67
  68
  69static int gpio1_get(struct gpio_chip *chip, unsigned offset)
  70{
  71        return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
  72}
  73
  74static void gpio1_set(struct gpio_chip *chip,
  75                                unsigned offset, int value)
  76{
  77        alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value);
  78}
  79
  80static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
  81{
  82        return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE);
  83}
  84
  85static int gpio1_direction_output(struct gpio_chip *chip,
  86                                        unsigned offset, int value)
  87{
  88        return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE,
  89                                             value);
  90}
  91
  92static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset)
  93{
  94        return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
  95}
  96
  97struct gpio_chip alchemy_gpio_chip[] = {
  98        [0] = {
  99                .label                  = "alchemy-gpio1",
 100                .direction_input        = gpio1_direction_input,
 101                .direction_output       = gpio1_direction_output,
 102                .get                    = gpio1_get,
 103                .set                    = gpio1_set,
 104                .to_irq                 = gpio1_to_irq,
 105                .base                   = ALCHEMY_GPIO1_BASE,
 106                .ngpio                  = ALCHEMY_GPIO1_NUM,
 107        },
 108        [1] = {
 109                .label                  = "alchemy-gpio2",
 110                .direction_input        = gpio2_direction_input,
 111                .direction_output       = gpio2_direction_output,
 112                .get                    = gpio2_get,
 113                .set                    = gpio2_set,
 114                .to_irq                 = gpio2_to_irq,
 115                .base                   = ALCHEMY_GPIO2_BASE,
 116                .ngpio                  = ALCHEMY_GPIO2_NUM,
 117        },
 118};
 119
 120static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
 121{
 122        return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
 123}
 124
 125static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
 126{
 127        au1300_gpio_set_value(off + AU1300_GPIO_BASE, v);
 128}
 129
 130static int alchemy_gpic_dir_input(struct gpio_chip *chip, unsigned int off)
 131{
 132        return au1300_gpio_direction_input(off + AU1300_GPIO_BASE);
 133}
 134
 135static int alchemy_gpic_dir_output(struct gpio_chip *chip, unsigned int off,
 136                                   int v)
 137{
 138        return au1300_gpio_direction_output(off + AU1300_GPIO_BASE, v);
 139}
 140
 141static int alchemy_gpic_gpio_to_irq(struct gpio_chip *chip, unsigned int off)
 142{
 143        return au1300_gpio_to_irq(off + AU1300_GPIO_BASE);
 144}
 145
 146static struct gpio_chip au1300_gpiochip = {
 147        .label                  = "alchemy-gpic",
 148        .direction_input        = alchemy_gpic_dir_input,
 149        .direction_output       = alchemy_gpic_dir_output,
 150        .get                    = alchemy_gpic_get,
 151        .set                    = alchemy_gpic_set,
 152        .to_irq                 = alchemy_gpic_gpio_to_irq,
 153        .base                   = AU1300_GPIO_BASE,
 154        .ngpio                  = AU1300_GPIO_NUM,
 155};
 156
 157static int __init alchemy_gpiochip_init(void)
 158{
 159        int ret = 0;
 160
 161        switch (alchemy_get_cputype()) {
 162        case ALCHEMY_CPU_AU1000:
 163                ret = gpiochip_add(&alchemy_gpio_chip[0]);
 164                break;
 165        case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200:
 166                ret = gpiochip_add(&alchemy_gpio_chip[0]);
 167                ret |= gpiochip_add(&alchemy_gpio_chip[1]);
 168                break;
 169        case ALCHEMY_CPU_AU1300:
 170                ret = gpiochip_add(&au1300_gpiochip);
 171                break;
 172        }
 173        return ret;
 174}
 175arch_initcall(alchemy_gpiochip_init);
 176