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
);