Commit | Line | Data |
---|---|---|
aeec56e3 | 1 | /* |
c103de24 | 2 | * Generic driver for memory-mapped GPIO controllers. |
aeec56e3 AV |
3 | * |
4 | * Copyright 2008 MontaVista Software, Inc. | |
5 | * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2 of the License, or (at your | |
10 | * option) any later version. | |
11 | * | |
12 | * ....``.```~~~~````.`.`.`.`.```````'',,,.........`````......`....... | |
13 | * ...`` ```````.. | |
14 | * ..The simplest form of a GPIO controller that the driver supports is`` | |
15 | * `.just a single "data" register, where GPIO state can be read and/or ` | |
16 | * `,..written. ,,..``~~~~ .....``.`.`.~~.```.`.........``````.``````` | |
17 | * ````````` | |
18 | ___ | |
19 | _/~~|___/~| . ```~~~~~~ ___/___\___ ,~.`.`.`.`````.~~...,,,,... | |
20 | __________|~$@~~~ %~ /o*o*o*o*o*o\ .. Implementing such a GPIO . | |
21 | o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` | |
22 | `....trivial..'~`.```.``` | |
23 | * ``````` | |
24 | * .```````~~~~`..`.``.``. | |
25 | * . The driver supports `... ,..```.`~~~```````````````....````.``,, | |
26 | * . big-endian notation, just`. .. A bit more sophisticated controllers , | |
27 | * . register the device with -be`. .with a pair of set/clear-bit registers , | |
28 | * `.. suffix. ```~~`````....`.` . affecting the data register and the .` | |
29 | * ``.`.``...``` ```.. output pins are also supported.` | |
30 | * ^^ `````.`````````.,``~``~``~~`````` | |
31 | * . ^^ | |
32 | * ,..`.`.`...````````````......`.`.`.`.`.`..`.`.`.. | |
33 | * .. The expectation is that in at least some cases . ,-~~~-, | |
34 | * .this will be used with roll-your-own ASIC/FPGA .` \ / | |
35 | * .logic in Verilog or VHDL. ~~~`````````..`````~~` \ / | |
36 | * ..````````......``````````` \o_ | |
37 | * | | |
38 | * ^^ / \ | |
39 | * | |
40 | * ...`````~~`.....``.`..........``````.`.``.```........``. | |
41 | * ` 8, 16, 32 and 64 bits registers are supported, and``. | |
42 | * . the number of GPIOs is determined by the width of ~ | |
43 | * .. the registers. ,............```.`.`..`.`.~~~.`.`.`~ | |
44 | * `.......````.``` | |
45 | */ | |
46 | ||
47 | #include <linux/init.h> | |
280df6b3 | 48 | #include <linux/err.h> |
aeec56e3 AV |
49 | #include <linux/bug.h> |
50 | #include <linux/kernel.h> | |
51 | #include <linux/module.h> | |
52 | #include <linux/spinlock.h> | |
53 | #include <linux/compiler.h> | |
54 | #include <linux/types.h> | |
55 | #include <linux/errno.h> | |
56 | #include <linux/log2.h> | |
57 | #include <linux/ioport.h> | |
58 | #include <linux/io.h> | |
0f4630f3 | 59 | #include <linux/gpio/driver.h> |
aeec56e3 | 60 | #include <linux/slab.h> |
4b63739e | 61 | #include <linux/bitops.h> |
aeec56e3 AV |
62 | #include <linux/platform_device.h> |
63 | #include <linux/mod_devicetable.h> | |
e698613a ÁFR |
64 | #include <linux/of.h> |
65 | #include <linux/of_device.h> | |
aeec56e3 | 66 | |
8467afec | 67 | static void bgpio_write8(void __iomem *reg, unsigned long data) |
aeec56e3 | 68 | { |
fd996235 | 69 | writeb(data, reg); |
aeec56e3 AV |
70 | } |
71 | ||
8467afec | 72 | static unsigned long bgpio_read8(void __iomem *reg) |
aeec56e3 | 73 | { |
fd996235 | 74 | return readb(reg); |
8467afec JI |
75 | } |
76 | ||
77 | static void bgpio_write16(void __iomem *reg, unsigned long data) | |
78 | { | |
fd996235 | 79 | writew(data, reg); |
8467afec JI |
80 | } |
81 | ||
82 | static unsigned long bgpio_read16(void __iomem *reg) | |
83 | { | |
fd996235 | 84 | return readw(reg); |
8467afec JI |
85 | } |
86 | ||
87 | static void bgpio_write32(void __iomem *reg, unsigned long data) | |
88 | { | |
fd996235 | 89 | writel(data, reg); |
8467afec JI |
90 | } |
91 | ||
92 | static unsigned long bgpio_read32(void __iomem *reg) | |
93 | { | |
fd996235 | 94 | return readl(reg); |
8467afec JI |
95 | } |
96 | ||
aeec56e3 | 97 | #if BITS_PER_LONG >= 64 |
8467afec JI |
98 | static void bgpio_write64(void __iomem *reg, unsigned long data) |
99 | { | |
fd996235 | 100 | writeq(data, reg); |
8467afec JI |
101 | } |
102 | ||
103 | static unsigned long bgpio_read64(void __iomem *reg) | |
104 | { | |
fd996235 | 105 | return readq(reg); |
aeec56e3 | 106 | } |
8467afec | 107 | #endif /* BITS_PER_LONG >= 64 */ |
aeec56e3 | 108 | |
2b78f1e1 AL |
109 | static void bgpio_write16be(void __iomem *reg, unsigned long data) |
110 | { | |
111 | iowrite16be(data, reg); | |
112 | } | |
113 | ||
114 | static unsigned long bgpio_read16be(void __iomem *reg) | |
115 | { | |
116 | return ioread16be(reg); | |
117 | } | |
118 | ||
119 | static void bgpio_write32be(void __iomem *reg, unsigned long data) | |
120 | { | |
121 | iowrite32be(data, reg); | |
122 | } | |
123 | ||
124 | static unsigned long bgpio_read32be(void __iomem *reg) | |
125 | { | |
126 | return ioread32be(reg); | |
127 | } | |
128 | ||
24efd94b | 129 | static unsigned long bgpio_line2mask(struct gpio_chip *gc, unsigned int line) |
aeec56e3 | 130 | { |
24efd94b LW |
131 | if (gc->be_bits) |
132 | return BIT(gc->bgpio_bits - 1 - line); | |
133 | return BIT(line); | |
aeec56e3 AV |
134 | } |
135 | ||
b19e7f51 VZ |
136 | static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) |
137 | { | |
24efd94b | 138 | unsigned long pinmask = bgpio_line2mask(gc, gpio); |
b19e7f51 | 139 | |
0f4630f3 LW |
140 | if (gc->bgpio_dir & pinmask) |
141 | return !!(gc->read_reg(gc->reg_set) & pinmask); | |
b19e7f51 | 142 | else |
0f4630f3 | 143 | return !!(gc->read_reg(gc->reg_dat) & pinmask); |
b19e7f51 VZ |
144 | } |
145 | ||
80057cb4 LW |
146 | /* |
147 | * This assumes that the bits in the GPIO register are in native endianness. | |
148 | * We only assign the function pointer if we have that. | |
149 | */ | |
150 | static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, | |
151 | unsigned long *bits) | |
152 | { | |
153 | unsigned long get_mask = 0; | |
154 | unsigned long set_mask = 0; | |
80057cb4 | 155 | |
07c7b6a5 LW |
156 | /* Make sure we first clear any bits that are zero when we read the register */ |
157 | *bits &= ~*mask; | |
158 | ||
159 | /* Exploit the fact that we know which directions are set */ | |
160 | set_mask = *mask & gc->bgpio_dir; | |
161 | get_mask = *mask & ~gc->bgpio_dir; | |
80057cb4 LW |
162 | |
163 | if (set_mask) | |
164 | *bits |= gc->read_reg(gc->reg_set) & set_mask; | |
165 | if (get_mask) | |
166 | *bits |= gc->read_reg(gc->reg_dat) & get_mask; | |
167 | ||
168 | return 0; | |
169 | } | |
170 | ||
aeec56e3 AV |
171 | static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) |
172 | { | |
24efd94b | 173 | return !!(gc->read_reg(gc->reg_dat) & bgpio_line2mask(gc, gpio)); |
aeec56e3 AV |
174 | } |
175 | ||
80057cb4 LW |
176 | /* |
177 | * This only works if the bits in the GPIO register are in native endianness. | |
80057cb4 LW |
178 | */ |
179 | static int bgpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, | |
180 | unsigned long *bits) | |
181 | { | |
07c7b6a5 LW |
182 | /* Make sure we first clear any bits that are zero when we read the register */ |
183 | *bits &= ~*mask; | |
184 | *bits |= gc->read_reg(gc->reg_dat) & *mask; | |
80057cb4 LW |
185 | return 0; |
186 | } | |
187 | ||
188 | /* | |
189 | * With big endian mirrored bit order it becomes more tedious. | |
190 | */ | |
191 | static int bgpio_get_multiple_be(struct gpio_chip *gc, unsigned long *mask, | |
192 | unsigned long *bits) | |
193 | { | |
194 | unsigned long readmask = 0; | |
195 | unsigned long val; | |
196 | int bit; | |
197 | ||
07c7b6a5 LW |
198 | /* Make sure we first clear any bits that are zero when we read the register */ |
199 | *bits &= ~*mask; | |
200 | ||
80057cb4 | 201 | /* Create a mirrored mask */ |
07c7b6a5 LW |
202 | bit = -1; |
203 | while ((bit = find_next_bit(mask, gc->ngpio, bit + 1)) < gc->ngpio) | |
80057cb4 LW |
204 | readmask |= bgpio_line2mask(gc, bit); |
205 | ||
206 | /* Read the register */ | |
207 | val = gc->read_reg(gc->reg_dat) & readmask; | |
208 | ||
209 | /* | |
210 | * Mirror the result into the "bits" result, this will give line 0 | |
211 | * in bit 0 ... line 31 in bit 31 for a 32bit register. | |
212 | */ | |
07c7b6a5 LW |
213 | bit = -1; |
214 | while ((bit = find_next_bit(&val, gc->ngpio, bit + 1)) < gc->ngpio) | |
80057cb4 LW |
215 | *bits |= bgpio_line2mask(gc, bit); |
216 | ||
217 | return 0; | |
218 | } | |
219 | ||
91492a44 RV |
220 | static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val) |
221 | { | |
222 | } | |
223 | ||
aeec56e3 AV |
224 | static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) |
225 | { | |
24efd94b | 226 | unsigned long mask = bgpio_line2mask(gc, gpio); |
aeec56e3 AV |
227 | unsigned long flags; |
228 | ||
0f4630f3 | 229 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
aeec56e3 AV |
230 | |
231 | if (val) | |
0f4630f3 | 232 | gc->bgpio_data |= mask; |
aeec56e3 | 233 | else |
0f4630f3 | 234 | gc->bgpio_data &= ~mask; |
aeec56e3 | 235 | |
0f4630f3 | 236 | gc->write_reg(gc->reg_dat, gc->bgpio_data); |
aeec56e3 | 237 | |
0f4630f3 | 238 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
aeec56e3 AV |
239 | } |
240 | ||
e027d6f9 JI |
241 | static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, |
242 | int val) | |
243 | { | |
24efd94b | 244 | unsigned long mask = bgpio_line2mask(gc, gpio); |
e027d6f9 JI |
245 | |
246 | if (val) | |
0f4630f3 | 247 | gc->write_reg(gc->reg_set, mask); |
e027d6f9 | 248 | else |
0f4630f3 | 249 | gc->write_reg(gc->reg_clr, mask); |
e027d6f9 JI |
250 | } |
251 | ||
dd86a0cc JI |
252 | static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) |
253 | { | |
24efd94b | 254 | unsigned long mask = bgpio_line2mask(gc, gpio); |
dd86a0cc JI |
255 | unsigned long flags; |
256 | ||
0f4630f3 | 257 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
dd86a0cc JI |
258 | |
259 | if (val) | |
0f4630f3 | 260 | gc->bgpio_data |= mask; |
dd86a0cc | 261 | else |
0f4630f3 | 262 | gc->bgpio_data &= ~mask; |
dd86a0cc | 263 | |
0f4630f3 | 264 | gc->write_reg(gc->reg_set, gc->bgpio_data); |
dd86a0cc | 265 | |
0f4630f3 | 266 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
dd86a0cc JI |
267 | } |
268 | ||
0f4630f3 | 269 | static void bgpio_multiple_get_masks(struct gpio_chip *gc, |
73c4ceda RI |
270 | unsigned long *mask, unsigned long *bits, |
271 | unsigned long *set_mask, | |
272 | unsigned long *clear_mask) | |
273 | { | |
274 | int i; | |
275 | ||
276 | *set_mask = 0; | |
277 | *clear_mask = 0; | |
278 | ||
0f4630f3 | 279 | for (i = 0; i < gc->bgpio_bits; i++) { |
73c4ceda RI |
280 | if (*mask == 0) |
281 | break; | |
282 | if (__test_and_clear_bit(i, mask)) { | |
283 | if (test_bit(i, bits)) | |
24efd94b | 284 | *set_mask |= bgpio_line2mask(gc, i); |
73c4ceda | 285 | else |
24efd94b | 286 | *clear_mask |= bgpio_line2mask(gc, i); |
73c4ceda RI |
287 | } |
288 | } | |
289 | } | |
290 | ||
0f4630f3 | 291 | static void bgpio_set_multiple_single_reg(struct gpio_chip *gc, |
73c4ceda RI |
292 | unsigned long *mask, |
293 | unsigned long *bits, | |
294 | void __iomem *reg) | |
295 | { | |
296 | unsigned long flags; | |
297 | unsigned long set_mask, clear_mask; | |
298 | ||
0f4630f3 | 299 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
73c4ceda | 300 | |
0f4630f3 | 301 | bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask); |
73c4ceda | 302 | |
0f4630f3 LW |
303 | gc->bgpio_data |= set_mask; |
304 | gc->bgpio_data &= ~clear_mask; | |
73c4ceda | 305 | |
0f4630f3 | 306 | gc->write_reg(reg, gc->bgpio_data); |
73c4ceda | 307 | |
0f4630f3 | 308 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
73c4ceda RI |
309 | } |
310 | ||
311 | static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, | |
312 | unsigned long *bits) | |
313 | { | |
0f4630f3 | 314 | bgpio_set_multiple_single_reg(gc, mask, bits, gc->reg_dat); |
73c4ceda RI |
315 | } |
316 | ||
317 | static void bgpio_set_multiple_set(struct gpio_chip *gc, unsigned long *mask, | |
318 | unsigned long *bits) | |
319 | { | |
0f4630f3 | 320 | bgpio_set_multiple_single_reg(gc, mask, bits, gc->reg_set); |
73c4ceda RI |
321 | } |
322 | ||
323 | static void bgpio_set_multiple_with_clear(struct gpio_chip *gc, | |
324 | unsigned long *mask, | |
325 | unsigned long *bits) | |
326 | { | |
73c4ceda RI |
327 | unsigned long set_mask, clear_mask; |
328 | ||
0f4630f3 | 329 | bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask); |
73c4ceda RI |
330 | |
331 | if (set_mask) | |
0f4630f3 | 332 | gc->write_reg(gc->reg_set, set_mask); |
73c4ceda | 333 | if (clear_mask) |
0f4630f3 | 334 | gc->write_reg(gc->reg_clr, clear_mask); |
73c4ceda RI |
335 | } |
336 | ||
31029116 JI |
337 | static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio) |
338 | { | |
339 | return 0; | |
340 | } | |
341 | ||
91492a44 RV |
342 | static int bgpio_dir_out_err(struct gpio_chip *gc, unsigned int gpio, |
343 | int val) | |
344 | { | |
345 | return -EINVAL; | |
346 | } | |
347 | ||
31029116 JI |
348 | static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio, |
349 | int val) | |
350 | { | |
351 | gc->set(gc, gpio, val); | |
352 | ||
353 | return 0; | |
354 | } | |
355 | ||
aeec56e3 AV |
356 | static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) |
357 | { | |
31029116 JI |
358 | unsigned long flags; |
359 | ||
0f4630f3 | 360 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
31029116 | 361 | |
24efd94b | 362 | gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); |
0f4630f3 | 363 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); |
31029116 | 364 | |
0f4630f3 | 365 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
31029116 | 366 | |
aeec56e3 AV |
367 | return 0; |
368 | } | |
369 | ||
db3b0fcc PZ |
370 | static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) |
371 | { | |
0f4630f3 | 372 | /* Return 0 if output, 1 of input */ |
24efd94b | 373 | return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); |
db3b0fcc PZ |
374 | } |
375 | ||
aeec56e3 AV |
376 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) |
377 | { | |
31029116 JI |
378 | unsigned long flags; |
379 | ||
380 | gc->set(gc, gpio, val); | |
381 | ||
0f4630f3 | 382 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
31029116 | 383 | |
24efd94b | 384 | gc->bgpio_dir |= bgpio_line2mask(gc, gpio); |
0f4630f3 | 385 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); |
31029116 | 386 | |
0f4630f3 | 387 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
31029116 JI |
388 | |
389 | return 0; | |
390 | } | |
391 | ||
392 | static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio) | |
393 | { | |
31029116 JI |
394 | unsigned long flags; |
395 | ||
0f4630f3 | 396 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
31029116 | 397 | |
24efd94b | 398 | gc->bgpio_dir |= bgpio_line2mask(gc, gpio); |
0f4630f3 | 399 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); |
31029116 | 400 | |
0f4630f3 | 401 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
31029116 JI |
402 | |
403 | return 0; | |
404 | } | |
405 | ||
406 | static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) | |
407 | { | |
31029116 JI |
408 | unsigned long flags; |
409 | ||
e027d6f9 JI |
410 | gc->set(gc, gpio, val); |
411 | ||
0f4630f3 | 412 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
31029116 | 413 | |
24efd94b | 414 | gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); |
0f4630f3 | 415 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); |
31029116 | 416 | |
0f4630f3 | 417 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
31029116 | 418 | |
aeec56e3 AV |
419 | return 0; |
420 | } | |
421 | ||
db3b0fcc PZ |
422 | static int bgpio_get_dir_inv(struct gpio_chip *gc, unsigned int gpio) |
423 | { | |
0f4630f3 | 424 | /* Return 0 if output, 1 if input */ |
24efd94b | 425 | return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); |
db3b0fcc PZ |
426 | } |
427 | ||
280df6b3 | 428 | static int bgpio_setup_accessors(struct device *dev, |
0f4630f3 | 429 | struct gpio_chip *gc, |
2b78f1e1 | 430 | bool byte_be) |
aeec56e3 | 431 | { |
8467afec | 432 | |
0f4630f3 | 433 | switch (gc->bgpio_bits) { |
8467afec | 434 | case 8: |
0f4630f3 LW |
435 | gc->read_reg = bgpio_read8; |
436 | gc->write_reg = bgpio_write8; | |
8467afec JI |
437 | break; |
438 | case 16: | |
2b78f1e1 | 439 | if (byte_be) { |
0f4630f3 LW |
440 | gc->read_reg = bgpio_read16be; |
441 | gc->write_reg = bgpio_write16be; | |
2b78f1e1 | 442 | } else { |
0f4630f3 LW |
443 | gc->read_reg = bgpio_read16; |
444 | gc->write_reg = bgpio_write16; | |
2b78f1e1 | 445 | } |
8467afec JI |
446 | break; |
447 | case 32: | |
2b78f1e1 | 448 | if (byte_be) { |
0f4630f3 LW |
449 | gc->read_reg = bgpio_read32be; |
450 | gc->write_reg = bgpio_write32be; | |
2b78f1e1 | 451 | } else { |
0f4630f3 LW |
452 | gc->read_reg = bgpio_read32; |
453 | gc->write_reg = bgpio_write32; | |
2b78f1e1 | 454 | } |
8467afec JI |
455 | break; |
456 | #if BITS_PER_LONG >= 64 | |
457 | case 64: | |
2b78f1e1 AL |
458 | if (byte_be) { |
459 | dev_err(dev, | |
460 | "64 bit big endian byte order unsupported\n"); | |
461 | return -EINVAL; | |
462 | } else { | |
0f4630f3 LW |
463 | gc->read_reg = bgpio_read64; |
464 | gc->write_reg = bgpio_write64; | |
2b78f1e1 | 465 | } |
8467afec JI |
466 | break; |
467 | #endif /* BITS_PER_LONG >= 64 */ | |
468 | default: | |
0f4630f3 | 469 | dev_err(dev, "unsupported data width %u bits\n", gc->bgpio_bits); |
8467afec JI |
470 | return -EINVAL; |
471 | } | |
472 | ||
8467afec JI |
473 | return 0; |
474 | } | |
475 | ||
e027d6f9 JI |
476 | /* |
477 | * Create the device and allocate the resources. For setting GPIO's there are | |
dd86a0cc | 478 | * three supported configurations: |
e027d6f9 | 479 | * |
dd86a0cc | 480 | * - single input/output register resource (named "dat"). |
e027d6f9 | 481 | * - set/clear pair (named "set" and "clr"). |
dd86a0cc JI |
482 | * - single output register resource and single input resource ("set" and |
483 | * dat"). | |
e027d6f9 JI |
484 | * |
485 | * For the single output register, this drives a 1 by setting a bit and a zero | |
486 | * by clearing a bit. For the set clr pair, this drives a 1 by setting a bit | |
487 | * in the set register and clears it by setting a bit in the clear register. | |
488 | * The configuration is detected by which resources are present. | |
31029116 JI |
489 | * |
490 | * For setting the GPIO direction, there are three supported configurations: | |
491 | * | |
492 | * - simple bidirection GPIO that requires no configuration. | |
493 | * - an output direction register (named "dirout") where a 1 bit | |
494 | * indicates the GPIO is an output. | |
495 | * - an input direction register (named "dirin") where a 1 bit indicates | |
496 | * the GPIO is an input. | |
e027d6f9 | 497 | */ |
0f4630f3 | 498 | static int bgpio_setup_io(struct gpio_chip *gc, |
280df6b3 JI |
499 | void __iomem *dat, |
500 | void __iomem *set, | |
b19e7f51 VZ |
501 | void __iomem *clr, |
502 | unsigned long flags) | |
8467afec | 503 | { |
aeec56e3 | 504 | |
0f4630f3 LW |
505 | gc->reg_dat = dat; |
506 | if (!gc->reg_dat) | |
280df6b3 | 507 | return -EINVAL; |
e027d6f9 | 508 | |
280df6b3 | 509 | if (set && clr) { |
0f4630f3 LW |
510 | gc->reg_set = set; |
511 | gc->reg_clr = clr; | |
512 | gc->set = bgpio_set_with_clear; | |
513 | gc->set_multiple = bgpio_set_multiple_with_clear; | |
280df6b3 | 514 | } else if (set && !clr) { |
0f4630f3 LW |
515 | gc->reg_set = set; |
516 | gc->set = bgpio_set_set; | |
517 | gc->set_multiple = bgpio_set_multiple_set; | |
91492a44 | 518 | } else if (flags & BGPIOF_NO_OUTPUT) { |
0f4630f3 LW |
519 | gc->set = bgpio_set_none; |
520 | gc->set_multiple = NULL; | |
e027d6f9 | 521 | } else { |
0f4630f3 LW |
522 | gc->set = bgpio_set; |
523 | gc->set_multiple = bgpio_set_multiple; | |
aeec56e3 AV |
524 | } |
525 | ||
b19e7f51 | 526 | if (!(flags & BGPIOF_UNREADABLE_REG_SET) && |
80057cb4 | 527 | (flags & BGPIOF_READ_OUTPUT_REG_SET)) { |
0f4630f3 | 528 | gc->get = bgpio_get_set; |
80057cb4 LW |
529 | if (!gc->be_bits) |
530 | gc->get_multiple = bgpio_get_set_multiple; | |
531 | /* | |
532 | * We deliberately avoid assigning the ->get_multiple() call | |
533 | * for big endian mirrored registers which are ALSO reflecting | |
534 | * their value in the set register when used as output. It is | |
535 | * simply too much complexity, let the GPIO core fall back to | |
536 | * reading each line individually in that fringe case. | |
537 | */ | |
538 | } else { | |
0f4630f3 | 539 | gc->get = bgpio_get; |
80057cb4 LW |
540 | if (gc->be_bits) |
541 | gc->get_multiple = bgpio_get_multiple_be; | |
542 | else | |
543 | gc->get_multiple = bgpio_get_multiple; | |
544 | } | |
dd86a0cc | 545 | |
e027d6f9 JI |
546 | return 0; |
547 | } | |
548 | ||
0f4630f3 | 549 | static int bgpio_setup_direction(struct gpio_chip *gc, |
280df6b3 | 550 | void __iomem *dirout, |
91492a44 RV |
551 | void __iomem *dirin, |
552 | unsigned long flags) | |
31029116 | 553 | { |
280df6b3 | 554 | if (dirout && dirin) { |
31029116 | 555 | return -EINVAL; |
280df6b3 | 556 | } else if (dirout) { |
0f4630f3 LW |
557 | gc->reg_dir = dirout; |
558 | gc->direction_output = bgpio_dir_out; | |
559 | gc->direction_input = bgpio_dir_in; | |
560 | gc->get_direction = bgpio_get_dir; | |
280df6b3 | 561 | } else if (dirin) { |
0f4630f3 LW |
562 | gc->reg_dir = dirin; |
563 | gc->direction_output = bgpio_dir_out_inv; | |
564 | gc->direction_input = bgpio_dir_in_inv; | |
565 | gc->get_direction = bgpio_get_dir_inv; | |
31029116 | 566 | } else { |
91492a44 | 567 | if (flags & BGPIOF_NO_OUTPUT) |
0f4630f3 | 568 | gc->direction_output = bgpio_dir_out_err; |
91492a44 | 569 | else |
0f4630f3 LW |
570 | gc->direction_output = bgpio_simple_dir_out; |
571 | gc->direction_input = bgpio_simple_dir_in; | |
31029116 JI |
572 | } |
573 | ||
574 | return 0; | |
575 | } | |
576 | ||
7b42e3db AF |
577 | static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin) |
578 | { | |
579 | if (gpio_pin < chip->ngpio) | |
580 | return 0; | |
581 | ||
582 | return -EINVAL; | |
583 | } | |
584 | ||
0f4630f3 | 585 | int bgpio_init(struct gpio_chip *gc, struct device *dev, |
4f5b0480 RK |
586 | unsigned long sz, void __iomem *dat, void __iomem *set, |
587 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, | |
3e11f7b8 | 588 | unsigned long flags) |
e027d6f9 | 589 | { |
e027d6f9 | 590 | int ret; |
e027d6f9 | 591 | |
280df6b3 JI |
592 | if (!is_power_of_2(sz)) |
593 | return -EINVAL; | |
e027d6f9 | 594 | |
0f4630f3 LW |
595 | gc->bgpio_bits = sz * 8; |
596 | if (gc->bgpio_bits > BITS_PER_LONG) | |
280df6b3 JI |
597 | return -EINVAL; |
598 | ||
0f4630f3 LW |
599 | spin_lock_init(&gc->bgpio_lock); |
600 | gc->parent = dev; | |
601 | gc->label = dev_name(dev); | |
602 | gc->base = -1; | |
603 | gc->ngpio = gc->bgpio_bits; | |
604 | gc->request = bgpio_request; | |
80057cb4 | 605 | gc->be_bits = !!(flags & BGPIOF_BIG_ENDIAN); |
280df6b3 | 606 | |
0f4630f3 | 607 | ret = bgpio_setup_io(gc, dat, set, clr, flags); |
e027d6f9 JI |
608 | if (ret) |
609 | return ret; | |
aeec56e3 | 610 | |
24efd94b | 611 | ret = bgpio_setup_accessors(dev, gc, flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER); |
8467afec JI |
612 | if (ret) |
613 | return ret; | |
aeec56e3 | 614 | |
0f4630f3 | 615 | ret = bgpio_setup_direction(gc, dirout, dirin, flags); |
31029116 JI |
616 | if (ret) |
617 | return ret; | |
618 | ||
0f4630f3 LW |
619 | gc->bgpio_data = gc->read_reg(gc->reg_dat); |
620 | if (gc->set == bgpio_set_set && | |
3e11f7b8 | 621 | !(flags & BGPIOF_UNREADABLE_REG_SET)) |
0f4630f3 LW |
622 | gc->bgpio_data = gc->read_reg(gc->reg_set); |
623 | if (gc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR)) | |
624 | gc->bgpio_dir = gc->read_reg(gc->reg_dir); | |
924e7a9f | 625 | |
280df6b3 JI |
626 | return ret; |
627 | } | |
628 | EXPORT_SYMBOL_GPL(bgpio_init); | |
aeec56e3 | 629 | |
8f01c9d0 | 630 | #if IS_ENABLED(CONFIG_GPIO_GENERIC_PLATFORM) |
aeec56e3 | 631 | |
280df6b3 JI |
632 | static void __iomem *bgpio_map(struct platform_device *pdev, |
633 | const char *name, | |
8d240260 | 634 | resource_size_t sane_sz) |
280df6b3 | 635 | { |
280df6b3 | 636 | struct resource *r; |
280df6b3 | 637 | resource_size_t sz; |
280df6b3 JI |
638 | |
639 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); | |
8d240260 | 640 | if (!r) |
b2f68b63 | 641 | return NULL; |
280df6b3 JI |
642 | |
643 | sz = resource_size(r); | |
8d240260 HK |
644 | if (sz != sane_sz) |
645 | return IOMEM_ERR_PTR(-EINVAL); | |
280df6b3 | 646 | |
8d240260 | 647 | return devm_ioremap_resource(&pdev->dev, r); |
aeec56e3 AV |
648 | } |
649 | ||
e698613a ÁFR |
650 | #ifdef CONFIG_OF |
651 | static const struct of_device_id bgpio_of_match[] = { | |
05cc995f | 652 | { .compatible = "brcm,bcm6345-gpio" }, |
c0d30ecf | 653 | { .compatible = "wd,mbl-gpio" }, |
b8c90199 | 654 | { .compatible = "ni,169445-nand-gpio" }, |
e698613a ÁFR |
655 | { } |
656 | }; | |
657 | MODULE_DEVICE_TABLE(of, bgpio_of_match); | |
658 | ||
659 | static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev, | |
660 | unsigned long *flags) | |
661 | { | |
662 | struct bgpio_pdata *pdata; | |
663 | ||
664 | if (!of_match_device(bgpio_of_match, &pdev->dev)) | |
665 | return NULL; | |
666 | ||
667 | pdata = devm_kzalloc(&pdev->dev, sizeof(struct bgpio_pdata), | |
668 | GFP_KERNEL); | |
669 | if (!pdata) | |
670 | return ERR_PTR(-ENOMEM); | |
671 | ||
672 | pdata->base = -1; | |
673 | ||
05cc995f CL |
674 | if (of_device_is_big_endian(pdev->dev.of_node)) |
675 | *flags |= BGPIOF_BIG_ENDIAN_BYTE_ORDER; | |
676 | ||
c0d30ecf CL |
677 | if (of_property_read_bool(pdev->dev.of_node, "no-output")) |
678 | *flags |= BGPIOF_NO_OUTPUT; | |
679 | ||
e698613a ÁFR |
680 | return pdata; |
681 | } | |
682 | #else | |
683 | static struct bgpio_pdata *bgpio_parse_dt(struct platform_device *pdev, | |
684 | unsigned long *flags) | |
685 | { | |
686 | return NULL; | |
687 | } | |
688 | #endif /* CONFIG_OF */ | |
689 | ||
3836309d | 690 | static int bgpio_pdev_probe(struct platform_device *pdev) |
280df6b3 JI |
691 | { |
692 | struct device *dev = &pdev->dev; | |
693 | struct resource *r; | |
694 | void __iomem *dat; | |
695 | void __iomem *set; | |
696 | void __iomem *clr; | |
697 | void __iomem *dirout; | |
698 | void __iomem *dirin; | |
699 | unsigned long sz; | |
e698613a | 700 | unsigned long flags = 0; |
280df6b3 | 701 | int err; |
0f4630f3 | 702 | struct gpio_chip *gc; |
e698613a ÁFR |
703 | struct bgpio_pdata *pdata; |
704 | ||
705 | pdata = bgpio_parse_dt(pdev, &flags); | |
706 | if (IS_ERR(pdata)) | |
707 | return PTR_ERR(pdata); | |
708 | ||
709 | if (!pdata) { | |
710 | pdata = dev_get_platdata(dev); | |
711 | flags = pdev->id_entry->driver_data; | |
712 | } | |
280df6b3 JI |
713 | |
714 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); | |
715 | if (!r) | |
716 | return -EINVAL; | |
717 | ||
718 | sz = resource_size(r); | |
719 | ||
8d240260 HK |
720 | dat = bgpio_map(pdev, "dat", sz); |
721 | if (IS_ERR(dat)) | |
722 | return PTR_ERR(dat); | |
280df6b3 | 723 | |
8d240260 HK |
724 | set = bgpio_map(pdev, "set", sz); |
725 | if (IS_ERR(set)) | |
726 | return PTR_ERR(set); | |
280df6b3 | 727 | |
8d240260 HK |
728 | clr = bgpio_map(pdev, "clr", sz); |
729 | if (IS_ERR(clr)) | |
730 | return PTR_ERR(clr); | |
280df6b3 | 731 | |
8d240260 HK |
732 | dirout = bgpio_map(pdev, "dirout", sz); |
733 | if (IS_ERR(dirout)) | |
734 | return PTR_ERR(dirout); | |
280df6b3 | 735 | |
8d240260 HK |
736 | dirin = bgpio_map(pdev, "dirin", sz); |
737 | if (IS_ERR(dirin)) | |
738 | return PTR_ERR(dirin); | |
280df6b3 | 739 | |
0f4630f3 LW |
740 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); |
741 | if (!gc) | |
280df6b3 JI |
742 | return -ENOMEM; |
743 | ||
0f4630f3 | 744 | err = bgpio_init(gc, dev, sz, dat, set, clr, dirout, dirin, flags); |
280df6b3 JI |
745 | if (err) |
746 | return err; | |
747 | ||
748 | if (pdata) { | |
781f6d71 | 749 | if (pdata->label) |
0f4630f3 LW |
750 | gc->label = pdata->label; |
751 | gc->base = pdata->base; | |
280df6b3 | 752 | if (pdata->ngpio > 0) |
0f4630f3 | 753 | gc->ngpio = pdata->ngpio; |
280df6b3 JI |
754 | } |
755 | ||
0f4630f3 | 756 | platform_set_drvdata(pdev, gc); |
280df6b3 | 757 | |
c05f813b | 758 | return devm_gpiochip_add_data(&pdev->dev, gc, NULL); |
aeec56e3 AV |
759 | } |
760 | ||
761 | static const struct platform_device_id bgpio_id_table[] = { | |
19338530 AS |
762 | { |
763 | .name = "basic-mmio-gpio", | |
764 | .driver_data = 0, | |
765 | }, { | |
766 | .name = "basic-mmio-gpio-be", | |
767 | .driver_data = BGPIOF_BIG_ENDIAN, | |
768 | }, | |
769 | { } | |
aeec56e3 AV |
770 | }; |
771 | MODULE_DEVICE_TABLE(platform, bgpio_id_table); | |
772 | ||
773 | static struct platform_driver bgpio_driver = { | |
774 | .driver = { | |
775 | .name = "basic-mmio-gpio", | |
e698613a | 776 | .of_match_table = of_match_ptr(bgpio_of_match), |
aeec56e3 AV |
777 | }, |
778 | .id_table = bgpio_id_table, | |
280df6b3 | 779 | .probe = bgpio_pdev_probe, |
aeec56e3 AV |
780 | }; |
781 | ||
6f61415e | 782 | module_platform_driver(bgpio_driver); |
280df6b3 | 783 | |
c103de24 | 784 | #endif /* CONFIG_GPIO_GENERIC_PLATFORM */ |
aeec56e3 AV |
785 | |
786 | MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); | |
787 | MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); | |
788 | MODULE_LICENSE("GPL"); |