linux/arch/arm/plat-s3c24xx/gpiolib.c
<<
>>
Prefs
   1/* linux/arch/arm/plat-s3c24xx/gpiolib.c
   2 *
   3 * Copyright (c) 2008 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 <mach/gpio-core.h>
  24#include <mach/hardware.h>
  25#include <asm/irq.h>
  26#include <plat/pm.h>
  27
  28#include <mach/regs-gpio.h>
  29
  30static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
  31{
  32        return -EINVAL;
  33}
  34
  35static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
  36                                        unsigned offset, int value)
  37{
  38        struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
  39        void __iomem *base = ourchip->base;
  40        unsigned long flags;
  41        unsigned long dat;
  42        unsigned long con;
  43
  44        local_irq_save(flags);
  45
  46        con = __raw_readl(base + 0x00);
  47        dat = __raw_readl(base + 0x04);
  48
  49        dat &= ~(1 << offset);
  50        if (value)
  51                dat |= 1 << offset;
  52
  53        __raw_writel(dat, base + 0x04);
  54
  55        con &= ~(1 << offset);
  56
  57        __raw_writel(con, base + 0x00);
  58        __raw_writel(dat, base + 0x04);
  59
  60        local_irq_restore(flags);
  61        return 0;
  62}
  63
  64static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
  65{
  66        if (offset < 4)
  67                return IRQ_EINT0 + offset;
  68        
  69        if (offset < 8)
  70                return IRQ_EINT4 + offset - 4;
  71        
  72        return -EINVAL;
  73}
  74
  75static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
  76{
  77        return IRQ_EINT8 + offset;
  78}
  79
  80struct s3c_gpio_chip s3c24xx_gpios[] = {
  81        [0] = {
  82                .base   = S3C2410_GPACON,
  83                .pm     = __gpio_pm(&s3c_gpio_pm_1bit),
  84                .chip   = {
  85                        .base                   = S3C2410_GPA(0),
  86                        .owner                  = THIS_MODULE,
  87                        .label                  = "GPIOA",
  88                        .ngpio                  = 24,
  89                        .direction_input        = s3c24xx_gpiolib_banka_input,
  90                        .direction_output       = s3c24xx_gpiolib_banka_output,
  91                },
  92        },
  93        [1] = {
  94                .base   = S3C2410_GPBCON,
  95                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
  96                .chip   = {
  97                        .base                   = S3C2410_GPB(0),
  98                        .owner                  = THIS_MODULE,
  99                        .label                  = "GPIOB",
 100                        .ngpio                  = 16,
 101                },
 102        },
 103        [2] = {
 104                .base   = S3C2410_GPCCON,
 105                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 106                .chip   = {
 107                        .base                   = S3C2410_GPC(0),
 108                        .owner                  = THIS_MODULE,
 109                        .label                  = "GPIOC",
 110                        .ngpio                  = 16,
 111                },
 112        },
 113        [3] = {
 114                .base   = S3C2410_GPDCON,
 115                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 116                .chip   = {
 117                        .base                   = S3C2410_GPD(0),
 118                        .owner                  = THIS_MODULE,
 119                        .label                  = "GPIOD",
 120                        .ngpio                  = 16,
 121                },
 122        },
 123        [4] = {
 124                .base   = S3C2410_GPECON,
 125                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 126                .chip   = {
 127                        .base                   = S3C2410_GPE(0),
 128                        .label                  = "GPIOE",
 129                        .owner                  = THIS_MODULE,
 130                        .ngpio                  = 16,
 131                },
 132        },
 133        [5] = {
 134                .base   = S3C2410_GPFCON,
 135                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 136                .chip   = {
 137                        .base                   = S3C2410_GPF(0),
 138                        .owner                  = THIS_MODULE,
 139                        .label                  = "GPIOF",
 140                        .ngpio                  = 8,
 141                        .to_irq                 = s3c24xx_gpiolib_bankf_toirq,
 142                },
 143        },
 144        [6] = {
 145                .base   = S3C2410_GPGCON,
 146                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 147                .chip   = {
 148                        .base                   = S3C2410_GPG(0),
 149                        .owner                  = THIS_MODULE,
 150                        .label                  = "GPIOG",
 151                        .ngpio                  = 16,
 152                        .to_irq                 = s3c24xx_gpiolib_bankg_toirq,
 153                },
 154        }, {
 155                .base   = S3C2410_GPHCON,
 156                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
 157                .chip   = {
 158                        .base                   = S3C2410_GPH(0),
 159                        .owner                  = THIS_MODULE,
 160                        .label                  = "GPIOH",
 161                        .ngpio                  = 11,
 162                },
 163        },
 164};
 165
 166static __init int s3c24xx_gpiolib_init(void)
 167{
 168        struct s3c_gpio_chip *chip = s3c24xx_gpios;
 169        int gpn;
 170
 171        for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
 172                s3c_gpiolib_add(chip);
 173
 174        return 0;
 175}
 176
 177core_initcall(s3c24xx_gpiolib_init);
 178