Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * linux/arch/arm/mach-w90p910/gpio.c
  3  *
  4  * Generic w90p910 GPIO handling
  5  *
  6  *  Wan ZongShun <mcuos.com@gmail.com>
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License version 2 as
 10  * published by the Free Software Foundation.
 11  */
 12 
 13 #include <linux/clk.h>
 14 #include <linux/errno.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/irq.h>
 17 #include <linux/debugfs.h>
 18 #include <linux/seq_file.h>
 19 #include <linux/kernel.h>
 20 #include <linux/list.h>
 21 #include <linux/module.h>
 22 #include <linux/io.h>
 23 #include <linux/gpio.h>
 24 
 25 #include <mach/hardware.h>
 26 
 27 #define GPIO_BASE               (W90X900_VA_GPIO)
 28 #define GPIO_DIR                (0x04)
 29 #define GPIO_OUT                (0x08)
 30 #define GPIO_IN                 (0x0C)
 31 #define GROUPINERV              (0x10)
 32 #define GPIO_GPIO(Nb)           (0x00000001 << (Nb))
 33 #define to_w90p910_gpio_chip(c) container_of(c, struct w90p910_gpio_chip, chip)
 34 
 35 #define W90P910_GPIO_CHIP(name, base_gpio, nr_gpio)                     \
 36         {                                                               \
 37                 .chip = {                                               \
 38                         .label            = name,                       \
 39                         .direction_input  = w90p910_dir_input,          \
 40                         .direction_output = w90p910_dir_output,         \
 41                         .get              = w90p910_gpio_get,           \
 42                         .set              = w90p910_gpio_set,           \
 43                         .base             = base_gpio,                  \
 44                         .ngpio            = nr_gpio,                    \
 45                 }                                                       \
 46         }
 47 
 48 struct w90p910_gpio_chip {
 49         struct gpio_chip        chip;
 50         void __iomem            *regbase;       /* Base of group register*/
 51         spinlock_t              gpio_lock;
 52 };
 53 
 54 static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset)
 55 {
 56         struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
 57         void __iomem *pio = w90p910_gpio->regbase + GPIO_IN;
 58         unsigned int regval;
 59 
 60         regval = __raw_readl(pio);
 61         regval &= GPIO_GPIO(offset);
 62 
 63         return (regval != 0);
 64 }
 65 
 66 static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
 67 {
 68         struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
 69         void __iomem *pio = w90p910_gpio->regbase + GPIO_OUT;
 70         unsigned int regval;
 71         unsigned long flags;
 72 
 73         spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
 74 
 75         regval = __raw_readl(pio);
 76 
 77         if (val)
 78                 regval |= GPIO_GPIO(offset);
 79         else
 80                 regval &= ~GPIO_GPIO(offset);
 81 
 82         __raw_writel(regval, pio);
 83 
 84         spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
 85 }
 86 
 87 static int w90p910_dir_input(struct gpio_chip *chip, unsigned offset)
 88 {
 89         struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
 90         void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR;
 91         unsigned int regval;
 92         unsigned long flags;
 93 
 94         spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
 95 
 96         regval = __raw_readl(pio);
 97         regval &= ~GPIO_GPIO(offset);
 98         __raw_writel(regval, pio);
 99 
100         spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
101 
102         return 0;
103 }
104 
105 static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val)
106 {
107         struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
108         void __iomem *outreg = w90p910_gpio->regbase + GPIO_OUT;
109         void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR;
110         unsigned int regval;
111         unsigned long flags;
112 
113         spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
114 
115         regval = __raw_readl(pio);
116         regval |= GPIO_GPIO(offset);
117         __raw_writel(regval, pio);
118 
119         regval = __raw_readl(outreg);
120 
121         if (val)
122                 regval |= GPIO_GPIO(offset);
123         else
124                 regval &= ~GPIO_GPIO(offset);
125 
126         __raw_writel(regval, outreg);
127 
128         spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
129 
130         return 0;
131 }
132 
133 static struct w90p910_gpio_chip w90p910_gpio[] = {
134         W90P910_GPIO_CHIP("GROUPC", 0, 16),
135         W90P910_GPIO_CHIP("GROUPD", 16, 10),
136         W90P910_GPIO_CHIP("GROUPE", 26, 14),
137         W90P910_GPIO_CHIP("GROUPF", 40, 10),
138         W90P910_GPIO_CHIP("GROUPG", 50, 17),
139         W90P910_GPIO_CHIP("GROUPH", 67, 8),
140         W90P910_GPIO_CHIP("GROUPI", 75, 17),
141 };
142 
143 void __init w90p910_init_gpio(int nr_group)
144 {
145         unsigned        i;
146         struct w90p910_gpio_chip *gpio_chip;
147 
148         for (i = 0; i < nr_group; i++) {
149                 gpio_chip = &w90p910_gpio[i];
150                 spin_lock_init(&gpio_chip->gpio_lock);
151                 gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
152                 gpiochip_add(&gpio_chip->chip);
153         }
154 }
155 
  This page was automatically generated by the LXR engine.