linux/arch/arm/plat-s3c24xx/gpiolib.c
<<
>>
Prefs
   1/* linux/arch/arm/plat-s3c24xx/gpiolib.c
   2 *
   3 * Copyright (c) 2008-2010 Simtec Electronics
   4 *      http://armlinux.simtec.co.uk/
   5 *      Ben Dooks <ben@simtec.co.uk>
   6 *
   7 * S3C24XX GPIOlib support
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License.
  12*/
  13
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/module.h>
  17#include <linux/interrupt.h>
  18#include <linux/sysdev.h>
  19#include <linux/ioport.h>
  20#include <linux/io.h>
  21#include <linux/gpio.h>
  22
  23#include <plat/gpio-core.h>
  24#include <plat/gpio-cfg.h>
  25#include <plat/gpio-cfg-helpers.h>
  26#include <mach/hardware.h>
  27#include <asm/irq.h>
  28#include <plat/pm.h>
  29
  30#include <mach/regs-gpio.h>
  31
  32static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
  33{
  34        return -EINVAL;
  35}
  36
  37static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
  38                                        unsigned offset, int value)
  39{
  40        struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  41        void __iomem *base = ourchip->base;
  42        unsigned long flags;
  43        unsigned long dat;
  44        unsigned long con;
  45
  46        local_irq_save(flags);
  47
  48        con = __raw_readl(base + 0x00);
  49        dat = __raw_readl(base + 0x04);
  50
  51        dat &= ~(1 << offset);
  52        if (value)
  53                dat |= 1 << offset;
  54
  55        __raw_writel(dat, base + 0x04);
  56
  57        con &= ~(1 << offset);
  58
  59        __raw_writel(con, base + 0x00);
  60        __raw_writel(dat, base + 0x04);
  61
  62        local_irq_restore(flags);
  63        return 0;
  64}
  65
  66static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
  67{
  68        if (offset < 4)
  69                return IRQ_EINT0 + offset;
  70        
  71        if (offset < 8)
  72                return IRQ_EINT4 + offset - 4;
  73        
  74        return -EINVAL;
  75}
  76
  77static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
  78        .set_config     = s3c_gpio_setcfg_s3c24xx_a,
  79        .get_config     = s3c_gpio_getcfg_s3c24xx_a,
  80};
  81
  82struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
  83        .set_config     = s3c_gpio_setcfg_s3c24xx,
  84        .get_config     = s3c_gpio_getcfg_s3c24xx,
  85};
  86
  87struct s3c_gpio_chip s3c24xx_gpios[] = {
  88        [0] = {
  89                .base   = S3C2410_GPACON,
  90                .pm     = __gpio_pm(&s3c_gpio_pm_1bit),
  91                .config = &s3c24xx_gpiocfg_banka,
  92                .chip   = {
  93                        .base                   = S3C2410_GPA(0),
  94                        .owner                  = THIS_MODULE,
  95                        .label                  = "GPIOA",
  96                        .ngpio                  = 24,
  97                        .direction_input        = s3c24xx_gpiolib_banka_input,
  98                        .direction_output       = s3c24xx_gpiolib_banka_output,
  99                },
 100        },
 101        [1] = {
 102                .base   = S3C2410_GPBCON,
 103                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 104                .chip   = {
 105                        .base                   = S3C2410_GPB(0),
 106                        .owner                  = THIS_MODULE,
 107                        .label                  = "GPIOB",
 108                        .ngpio                  = 16,
 109                },
 110        },
 111        [2] = {
 112                .base   = S3C2410_GPCCON,
 113                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 114                .chip   = {
 115                        .base                   = S3C2410_GPC(0),
 116                        .owner                  = THIS_MODULE,
 117                        .label                  = "GPIOC",
 118                        .ngpio                  = 16,
 119                },
 120        },
 121        [3] = {
 122                .base   = S3C2410_GPDCON,
 123                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 124                .chip   = {
 125                        .base                   = S3C2410_GPD(0),
 126                        .owner                  = THIS_MODULE,
 127                        .label                  = "GPIOD",
 128                        .ngpio                  = 16,
 129                },
 130        },
 131        [4] = {
 132                .base   = S3C2410_GPECON,
 133                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 134                .chip   = {
 135                        .base                   = S3C2410_GPE(0),
 136                        .label                  = "GPIOE",
 137                        .owner                  = THIS_MODULE,
 138                        .ngpio                  = 16,
 139                },
 140        },
 141        [5] = {
 142                .base   = S3C2410_GPFCON,
 143                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 144                .chip   = {
 145                        .base                   = S3C2410_GPF(0),
 146                        .owner                  = THIS_MODULE,
 147                        .label                  = "GPIOF",
 148                        .ngpio                  = 8,
 149                        .to_irq                 = s3c24xx_gpiolib_bankf_toirq,
 150                },
 151        },
 152        [6] = {
 153                .base   = S3C2410_GPGCON,
 154                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 155                .irq_base = IRQ_EINT8,
 156                .chip   = {
 157                        .base                   = S3C2410_GPG(0),
 158                        .owner                  = THIS_MODULE,
 159                        .label                  = "GPIOG",
 160                        .ngpio                  = 16,
 161                        .to_irq                 = samsung_gpiolib_to_irq,
 162                },
 163        }, {
 164                .base   = S3C2410_GPHCON,
 165                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 166                .chip   = {
 167                        .base                   = S3C2410_GPH(0),
 168                        .owner                  = THIS_MODULE,
 169                        .label                  = "GPIOH",
 170                        .ngpio                  = 11,
 171                },
 172        },
 173                /* GPIOS for the S3C2443 and later devices. */
 174        {
 175                .base   = S3C2440_GPJCON,
 176                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 177                .chip   = {
 178                        .base                   = S3C2410_GPJ(0),
 179                        .owner                  = THIS_MODULE,
 180                        .label                  = "GPIOJ",
 181                        .ngpio                  = 16,
 182                },
 183        }, {
 184                .base   = S3C2443_GPKCON,
 185                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 186                .chip   = {
 187                        .base                   = S3C2410_GPK(0),
 188                        .owner                  = THIS_MODULE,
 189                        .label                  = "GPIOK",
 190                        .ngpio                  = 16,
 191                },
 192        }, {
 193                .base   = S3C2443_GPLCON,
 194                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 195                .chip   = {
 196                        .base                   = S3C2410_GPL(0),
 197                        .owner                  = THIS_MODULE,
 198                        .label                  = "GPIOL",
 199                        .ngpio                  = 15,
 200                },
 201        }, {
 202                .base   = S3C2443_GPMCON,
 203                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 204                .chip   = {
 205                        .base                   = S3C2410_GPM(0),
 206                        .owner                  = THIS_MODULE,
 207                        .label                  = "GPIOM",
 208                        .ngpio                  = 2,
 209                },
 210        },
 211};
 212
 213
 214static __init int s3c24xx_gpiolib_init(void)
 215{
 216        struct s3c_gpio_chip *chip = s3c24xx_gpios;
 217        int gpn;
 218
 219        for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
 220                if (!chip->config)
 221                        chip->config = &s3c24xx_gpiocfg_default;
 222
 223                s3c_gpiolib_add(chip);
 224        }
 225
 226        return 0;
 227}
 228
 229core_initcall(s3c24xx_gpiolib_init);
 230