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