1 /* linux/arch/arm/mach-vt8500/gpio.c
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <linux/gpio.h>
17 #include <linux/init.h>
18 #include <linux/irq.h>
23 #define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
25 #define ENABLE_REGS 0x0
26 #define DIRECTION_REGS 0x20
27 #define OUTVALUE_REGS 0x40
28 #define INVALUE_REGS 0x60
30 #define EXT_REGOFF 0x1c
32 static void __iomem *regbase;
34 struct vt8500_gpio_chip {
35 struct gpio_chip chip;
40 static int gpio_to_irq_map[8];
42 static int vt8500_muxed_gpio_request(struct gpio_chip *chip,
45 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
46 unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
48 val |= (1 << vt8500_chip->shift << offset);
49 writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
54 static void vt8500_muxed_gpio_free(struct gpio_chip *chip,
57 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
58 unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
60 val &= ~(1 << vt8500_chip->shift << offset);
61 writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
64 static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip,
67 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
68 unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
70 val &= ~(1 << vt8500_chip->shift << offset);
71 writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
76 static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip,
77 unsigned offset, int value)
79 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
80 unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
82 val |= (1 << vt8500_chip->shift << offset);
83 writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
86 val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff);
87 val |= (1 << vt8500_chip->shift << offset);
88 writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff);
93 static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip,
96 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
98 return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff)
99 >> vt8500_chip->shift >> offset) & 1;
102 static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip,
103 unsigned offset, int value)
105 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
106 unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff);
109 val |= (1 << vt8500_chip->shift << offset);
111 val &= ~(1 << vt8500_chip->shift << offset);
113 writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff);
116 #define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num) \
120 .request = vt8500_muxed_gpio_request, \
121 .free = vt8500_muxed_gpio_free, \
122 .direction_input = vt8500_muxed_gpio_direction_input, \
123 .direction_output = vt8500_muxed_gpio_direction_output, \
124 .get = vt8500_muxed_gpio_get_value, \
125 .set = vt8500_muxed_gpio_set_value, \
134 static struct vt8500_gpio_chip vt8500_muxed_gpios[] = {
135 VT8500_GPIO_BANK("uart0", 0, 0x0, 8, 4),
136 VT8500_GPIO_BANK("uart1", 4, 0x0, 12, 4),
137 VT8500_GPIO_BANK("spi0", 8, 0x0, 16, 4),
138 VT8500_GPIO_BANK("spi1", 12, 0x0, 20, 4),
139 VT8500_GPIO_BANK("spi2", 16, 0x0, 24, 4),
140 VT8500_GPIO_BANK("pwmout", 24, 0x0, 28, 2),
142 VT8500_GPIO_BANK("sdmmc", 0, 0x4, 30, 11),
143 VT8500_GPIO_BANK("ms", 16, 0x4, 41, 7),
144 VT8500_GPIO_BANK("i2c0", 24, 0x4, 48, 2),
145 VT8500_GPIO_BANK("i2c1", 26, 0x4, 50, 2),
147 VT8500_GPIO_BANK("mii", 0, 0x8, 52, 20),
148 VT8500_GPIO_BANK("see", 20, 0x8, 72, 4),
149 VT8500_GPIO_BANK("ide", 24, 0x8, 76, 7),
151 VT8500_GPIO_BANK("ccir", 0, 0xc, 83, 19),
153 VT8500_GPIO_BANK("ts", 8, 0x10, 102, 11),
155 VT8500_GPIO_BANK("lcd", 0, 0x14, 113, 23),
158 static int vt8500_gpio_direction_input(struct gpio_chip *chip,
161 unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
163 val &= ~(1 << offset);
164 writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
168 static int vt8500_gpio_direction_output(struct gpio_chip *chip,
169 unsigned offset, int value)
171 unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
173 val |= (1 << offset);
174 writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
177 val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
178 val |= (1 << offset);
179 writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
184 static int vt8500_gpio_get_value(struct gpio_chip *chip,
187 return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1;
190 static void vt8500_gpio_set_value(struct gpio_chip *chip,
191 unsigned offset, int value)
193 unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
196 val |= (1 << offset);
198 val &= ~(1 << offset);
200 writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
203 static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
208 return gpio_to_irq_map[offset];
211 static struct gpio_chip vt8500_external_gpios = {
213 .direction_input = vt8500_gpio_direction_input,
214 .direction_output = vt8500_gpio_direction_output,
215 .get = vt8500_gpio_get_value,
216 .set = vt8500_gpio_set_value,
217 .to_irq = vt8500_gpio_to_irq,
223 void __init vt8500_gpio_init(void)
227 for (i = 0; i < 8; i++)
228 gpio_to_irq_map[i] = wmt_gpio_ext_irq[i];
230 regbase = ioremap(wmt_gpio_base, SZ_64K);
232 printk(KERN_ERR "Failed to map MMIO registers for GPIO\n");
236 gpiochip_add(&vt8500_external_gpios);
238 for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++)
239 gpiochip_add(&vt8500_muxed_gpios[i].chip);