blob: b53320a16fc8124b8ec38ee7debdd3bb554bb973 [file] [log] [blame]
Tony Prisk4e48b1c2012-08-08 13:05:55 +12001/* drivers/gpio/gpio-vt8500.c
2 *
3 * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
4 * Based on arch/arm/mach-vt8500/gpio.c:
5 * - Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/err.h>
20#include <linux/io.h>
21#include <linux/gpio.h>
22#include <linux/platform_device.h>
23#include <linux/bitops.h>
24#include <linux/of.h>
25#include <linux/of_address.h>
26#include <linux/of_irq.h>
27#include <linux/of_device.h>
28
29/*
30 We handle GPIOs by bank, each bank containing up to 32 GPIOs covered
31 by one set of registers (although not all may be valid).
32
33 Because different SoC's have different register offsets, we pass the
34 register offsets as data in vt8500_gpio_dt_ids[].
35
36 A value of NO_REG is used to indicate that this register is not
37 supported. Only used for ->en at the moment.
38*/
39
40#define NO_REG 0xFFFF
41
42/*
43 * struct vt8500_gpio_bank_regoffsets
44 * @en: offset to enable register of the bank
45 * @dir: offset to direction register of the bank
46 * @data_out: offset to the data out register of the bank
47 * @data_in: offset to the data in register of the bank
48 * @ngpio: highest valid pin in this bank
49 */
50
51struct vt8500_gpio_bank_regoffsets {
52 unsigned int en;
53 unsigned int dir;
54 unsigned int data_out;
55 unsigned int data_in;
56 unsigned char ngpio;
57};
58
59struct vt8500_gpio_data {
60 unsigned int num_banks;
61 struct vt8500_gpio_bank_regoffsets banks[];
62};
63
64#define VT8500_BANK(__en, __dir, __out, __in, __ngpio) \
65{ \
66 .en = __en, \
67 .dir = __dir, \
68 .data_out = __out, \
69 .data_in = __in, \
70 .ngpio = __ngpio, \
71}
72
73static struct vt8500_gpio_data vt8500_data = {
74 .num_banks = 7,
75 .banks = {
76 VT8500_BANK(0x00, 0x20, 0x40, 0x60, 26),
77 VT8500_BANK(0x04, 0x24, 0x44, 0x64, 28),
78 VT8500_BANK(0x08, 0x28, 0x48, 0x68, 31),
79 VT8500_BANK(0x0C, 0x2C, 0x4C, 0x6C, 19),
80 VT8500_BANK(0x10, 0x30, 0x50, 0x70, 19),
81 VT8500_BANK(0x14, 0x34, 0x54, 0x74, 23),
82 VT8500_BANK(NO_REG, 0x3C, 0x5C, 0x7C, 9),
83 },
84};
85
86static struct vt8500_gpio_data wm8505_data = {
87 .num_banks = 10,
88 .banks = {
89 VT8500_BANK(0x40, 0x68, 0x90, 0xB8, 8),
90 VT8500_BANK(0x44, 0x6C, 0x94, 0xBC, 32),
91 VT8500_BANK(0x48, 0x70, 0x98, 0xC0, 6),
92 VT8500_BANK(0x4C, 0x74, 0x9C, 0xC4, 16),
93 VT8500_BANK(0x50, 0x78, 0xA0, 0xC8, 25),
94 VT8500_BANK(0x54, 0x7C, 0xA4, 0xCC, 5),
95 VT8500_BANK(0x58, 0x80, 0xA8, 0xD0, 5),
96 VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12),
97 VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16),
98 VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22),
Tony Prisk67a0d492012-10-18 07:18:13 +130099 VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6),
Tony Prisk4e48b1c2012-08-08 13:05:55 +1200100 },
101};
102
103/*
104 * No information about which bits are valid so we just make
105 * them all available until its figured out.
106 */
107static struct vt8500_gpio_data wm8650_data = {
108 .num_banks = 9,
109 .banks = {
110 VT8500_BANK(0x40, 0x80, 0xC0, 0x00, 32),
111 VT8500_BANK(0x44, 0x84, 0xC4, 0x04, 32),
112 VT8500_BANK(0x48, 0x88, 0xC8, 0x08, 32),
113 VT8500_BANK(0x4C, 0x8C, 0xCC, 0x0C, 32),
114 VT8500_BANK(0x50, 0x90, 0xD0, 0x10, 32),
115 VT8500_BANK(0x54, 0x94, 0xD4, 0x14, 32),
116 VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32),
117 VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32),
118 VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32),
Tony Prisk67a0d492012-10-18 07:18:13 +1300119 VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6),
Tony Prisk4e48b1c2012-08-08 13:05:55 +1200120 },
121};
122
123struct vt8500_gpio_chip {
124 struct gpio_chip chip;
125
126 const struct vt8500_gpio_bank_regoffsets *regs;
127 void __iomem *base;
128};
129
130
131#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
132
133static int vt8500_gpio_request(struct gpio_chip *chip, unsigned offset)
134{
135 u32 val;
136 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
137
138 if (vt8500_chip->regs->en == NO_REG)
139 return 0;
140
141 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en);
142 val |= BIT(offset);
143 writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en);
144
145 return 0;
146}
147
148static void vt8500_gpio_free(struct gpio_chip *chip, unsigned offset)
149{
150 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
151 u32 val;
152
153 if (vt8500_chip->regs->en == NO_REG)
154 return;
155
156 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en);
157 val &= ~BIT(offset);
158 writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en);
159}
160
161static int vt8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
162{
163 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
164
165 u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir);
166 val &= ~BIT(offset);
167 writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir);
168
169 return 0;
170}
171
172static int vt8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
173 int value)
174{
175 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
176
177 u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir);
178 val |= BIT(offset);
179 writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir);
180
181 if (value) {
182 val = readl_relaxed(vt8500_chip->base +
183 vt8500_chip->regs->data_out);
184 val |= BIT(offset);
185 writel_relaxed(val, vt8500_chip->base +
186 vt8500_chip->regs->data_out);
187 }
188 return 0;
189}
190
191static int vt8500_gpio_get_value(struct gpio_chip *chip, unsigned offset)
192{
193 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
194
195 return (readl_relaxed(vt8500_chip->base + vt8500_chip->regs->data_in) >>
196 offset) & 1;
197}
198
199static void vt8500_gpio_set_value(struct gpio_chip *chip, unsigned offset,
200 int value)
201{
202 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
203
204 u32 val = readl_relaxed(vt8500_chip->base +
205 vt8500_chip->regs->data_out);
206 if (value)
207 val |= BIT(offset);
208 else
209 val &= ~BIT(offset);
210
211 writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->data_out);
212}
213
214static int vt8500_of_xlate(struct gpio_chip *gc,
215 const struct of_phandle_args *gpiospec, u32 *flags)
216{
217 /* bank if specificed in gpiospec->args[0] */
218 if (flags)
219 *flags = gpiospec->args[2];
220
221 return gpiospec->args[1];
222}
223
224static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base,
225 const struct vt8500_gpio_data *data)
226{
227 struct vt8500_gpio_chip *vtchip;
228 struct gpio_chip *chip;
229 int i;
230 int pin_cnt = 0;
231
232 vtchip = devm_kzalloc(&pdev->dev,
233 sizeof(struct vt8500_gpio_chip) * data->num_banks,
234 GFP_KERNEL);
235 if (!vtchip) {
236 pr_err("%s: failed to allocate chip memory\n", __func__);
237 return -ENOMEM;
238 }
239
240 for (i = 0; i < data->num_banks; i++) {
241 vtchip[i].base = base;
242 vtchip[i].regs = &data->banks[i];
243
244 chip = &vtchip[i].chip;
245
246 chip->of_xlate = vt8500_of_xlate;
247 chip->of_gpio_n_cells = 3;
248 chip->of_node = pdev->dev.of_node;
249
250 chip->request = vt8500_gpio_request;
251 chip->free = vt8500_gpio_free;
252 chip->direction_input = vt8500_gpio_direction_input;
253 chip->direction_output = vt8500_gpio_direction_output;
254 chip->get = vt8500_gpio_get_value;
255 chip->set = vt8500_gpio_set_value;
256 chip->can_sleep = 0;
257 chip->base = pin_cnt;
258 chip->ngpio = data->banks[i].ngpio;
259
260 pin_cnt += data->banks[i].ngpio;
261
262 gpiochip_add(chip);
263 }
264 return 0;
265}
266
267static struct of_device_id vt8500_gpio_dt_ids[] = {
268 { .compatible = "via,vt8500-gpio", .data = &vt8500_data, },
269 { .compatible = "wm,wm8505-gpio", .data = &wm8505_data, },
270 { .compatible = "wm,wm8650-gpio", .data = &wm8650_data, },
271 { /* Sentinel */ },
272};
273
Bill Pemberton38363092012-11-19 13:22:34 -0500274static int vt8500_gpio_probe(struct platform_device *pdev)
Tony Prisk4e48b1c2012-08-08 13:05:55 +1200275{
276 void __iomem *gpio_base;
277 struct device_node *np;
278 const struct of_device_id *of_id =
279 of_match_device(vt8500_gpio_dt_ids, &pdev->dev);
280
281 if (!of_id) {
282 dev_err(&pdev->dev, "Failed to find gpio controller\n");
283 return -ENODEV;
284 }
285
286 np = pdev->dev.of_node;
287 if (!np) {
288 dev_err(&pdev->dev, "Missing GPIO description in devicetree\n");
289 return -EFAULT;
290 }
291
292 gpio_base = of_iomap(np, 0);
293 if (!gpio_base) {
294 dev_err(&pdev->dev, "Unable to map GPIO registers\n");
295 of_node_put(np);
296 return -ENOMEM;
297 }
298
299 vt8500_add_chips(pdev, gpio_base, of_id->data);
300
301 return 0;
302}
303
304static struct platform_driver vt8500_gpio_driver = {
305 .probe = vt8500_gpio_probe,
306 .driver = {
307 .name = "vt8500-gpio",
308 .owner = THIS_MODULE,
309 .of_match_table = vt8500_gpio_dt_ids,
310 },
311};
312
313module_platform_driver(vt8500_gpio_driver);
314
315MODULE_DESCRIPTION("VT8500 GPIO Driver");
316MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
317MODULE_LICENSE("GPL v2");
318MODULE_DEVICE_TABLE(of, vt8500_gpio_dt_ids);