Commit | Line | Data |
---|---|---|
0bcb6069 | 1 | /* |
74600ee0 | 2 | * Xilinx gpio driver for xps/axi_gpio IP. |
0bcb6069 | 3 | * |
74600ee0 | 4 | * Copyright 2008 - 2013 Xilinx, Inc. |
0bcb6069 JL |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * You should have received a copy of the GNU General Public License | |
11 | * along with this program; if not, write to the Free Software | |
12 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
13 | */ | |
14 | ||
74600ee0 | 15 | #include <linux/bitops.h> |
0bcb6069 JL |
16 | #include <linux/init.h> |
17 | #include <linux/errno.h> | |
bb207ef1 | 18 | #include <linux/module.h> |
0bcb6069 JL |
19 | #include <linux/of_device.h> |
20 | #include <linux/of_platform.h> | |
21 | #include <linux/of_gpio.h> | |
22 | #include <linux/io.h> | |
23 | #include <linux/gpio.h> | |
5a0e3ad6 | 24 | #include <linux/slab.h> |
0bcb6069 JL |
25 | |
26 | /* Register Offset Definitions */ | |
27 | #define XGPIO_DATA_OFFSET (0x0) /* Data register */ | |
28 | #define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ | |
29 | ||
74600ee0 MS |
30 | #define XGPIO_CHANNEL_OFFSET 0x8 |
31 | ||
32 | /* Read/Write access to the GPIO registers */ | |
cc090d61 MS |
33 | #ifdef CONFIG_ARCH_ZYNQ |
34 | # define xgpio_readreg(offset) readl(offset) | |
35 | # define xgpio_writereg(offset, val) writel(val, offset) | |
36 | #else | |
37 | # define xgpio_readreg(offset) __raw_readl(offset) | |
38 | # define xgpio_writereg(offset, val) __raw_writel(val, offset) | |
39 | #endif | |
74600ee0 MS |
40 | |
41 | /** | |
42 | * struct xgpio_instance - Stores information about GPIO device | |
43 | * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks | |
44 | * gpio_state: GPIO state shadow register | |
45 | * gpio_dir: GPIO direction shadow register | |
46 | * offset: GPIO channel offset | |
47 | * gpio_lock: Lock used for synchronization | |
48 | */ | |
0bcb6069 JL |
49 | struct xgpio_instance { |
50 | struct of_mm_gpio_chip mmchip; | |
74600ee0 MS |
51 | u32 gpio_state; |
52 | u32 gpio_dir; | |
53 | u32 offset; | |
54 | spinlock_t gpio_lock; | |
0bcb6069 JL |
55 | }; |
56 | ||
57 | /** | |
58 | * xgpio_get - Read the specified signal of the GPIO device. | |
59 | * @gc: Pointer to gpio_chip device structure. | |
60 | * @gpio: GPIO signal number. | |
61 | * | |
62 | * This function reads the specified signal of the GPIO device. It returns 0 if | |
63 | * the signal clear, 1 if signal is set or negative value on error. | |
64 | */ | |
65 | static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) | |
66 | { | |
67 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
74600ee0 MS |
68 | struct xgpio_instance *chip = |
69 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
0bcb6069 | 70 | |
74600ee0 MS |
71 | void __iomem *regs = mm_gc->regs + chip->offset; |
72 | ||
73 | return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio)); | |
0bcb6069 JL |
74 | } |
75 | ||
76 | /** | |
77 | * xgpio_set - Write the specified signal of the GPIO device. | |
78 | * @gc: Pointer to gpio_chip device structure. | |
79 | * @gpio: GPIO signal number. | |
80 | * @val: Value to be written to specified signal. | |
81 | * | |
82 | * This function writes the specified value in to the specified signal of the | |
83 | * GPIO device. | |
84 | */ | |
85 | static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | |
86 | { | |
87 | unsigned long flags; | |
88 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
89 | struct xgpio_instance *chip = | |
90 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
74600ee0 | 91 | void __iomem *regs = mm_gc->regs; |
0bcb6069 JL |
92 | |
93 | spin_lock_irqsave(&chip->gpio_lock, flags); | |
94 | ||
95 | /* Write to GPIO signal and set its direction to output */ | |
96 | if (val) | |
9f7f0b2b | 97 | chip->gpio_state |= BIT(gpio); |
0bcb6069 | 98 | else |
9f7f0b2b | 99 | chip->gpio_state &= ~BIT(gpio); |
74600ee0 MS |
100 | |
101 | xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, | |
102 | chip->gpio_state); | |
0bcb6069 JL |
103 | |
104 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | |
105 | } | |
106 | ||
107 | /** | |
108 | * xgpio_dir_in - Set the direction of the specified GPIO signal as input. | |
109 | * @gc: Pointer to gpio_chip device structure. | |
110 | * @gpio: GPIO signal number. | |
111 | * | |
112 | * This function sets the direction of specified GPIO signal as input. | |
113 | * It returns 0 if direction of GPIO signals is set as input otherwise it | |
114 | * returns negative error value. | |
115 | */ | |
116 | static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | |
117 | { | |
118 | unsigned long flags; | |
119 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
120 | struct xgpio_instance *chip = | |
121 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
74600ee0 | 122 | void __iomem *regs = mm_gc->regs; |
0bcb6069 JL |
123 | |
124 | spin_lock_irqsave(&chip->gpio_lock, flags); | |
125 | ||
126 | /* Set the GPIO bit in shadow register and set direction as input */ | |
9f7f0b2b | 127 | chip->gpio_dir |= BIT(gpio); |
74600ee0 | 128 | xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir); |
0bcb6069 JL |
129 | |
130 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | |
131 | ||
132 | return 0; | |
133 | } | |
134 | ||
135 | /** | |
136 | * xgpio_dir_out - Set the direction of the specified GPIO signal as output. | |
137 | * @gc: Pointer to gpio_chip device structure. | |
138 | * @gpio: GPIO signal number. | |
139 | * @val: Value to be written to specified signal. | |
140 | * | |
141 | * This function sets the direction of specified GPIO signal as output. If all | |
142 | * GPIO signals of GPIO chip is configured as input then it returns | |
143 | * error otherwise it returns 0. | |
144 | */ | |
145 | static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |
146 | { | |
147 | unsigned long flags; | |
148 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
149 | struct xgpio_instance *chip = | |
150 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
74600ee0 | 151 | void __iomem *regs = mm_gc->regs; |
0bcb6069 JL |
152 | |
153 | spin_lock_irqsave(&chip->gpio_lock, flags); | |
154 | ||
155 | /* Write state of GPIO signal */ | |
156 | if (val) | |
9f7f0b2b | 157 | chip->gpio_state |= BIT(gpio); |
0bcb6069 | 158 | else |
9f7f0b2b | 159 | chip->gpio_state &= ~BIT(gpio); |
74600ee0 MS |
160 | xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, |
161 | chip->gpio_state); | |
0bcb6069 JL |
162 | |
163 | /* Clear the GPIO bit in shadow register and set direction as output */ | |
9f7f0b2b | 164 | chip->gpio_dir &= ~BIT(gpio); |
74600ee0 | 165 | xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir); |
0bcb6069 JL |
166 | |
167 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | |
168 | ||
169 | return 0; | |
170 | } | |
171 | ||
172 | /** | |
173 | * xgpio_save_regs - Set initial values of GPIO pins | |
174 | * @mm_gc: pointer to memory mapped GPIO chip structure | |
175 | */ | |
176 | static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) | |
177 | { | |
178 | struct xgpio_instance *chip = | |
179 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
180 | ||
74600ee0 MS |
181 | xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET, |
182 | chip->gpio_state); | |
183 | xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_TRI_OFFSET, | |
184 | chip->gpio_dir); | |
0bcb6069 JL |
185 | } |
186 | ||
187 | /** | |
188 | * xgpio_of_probe - Probe method for the GPIO device. | |
189 | * @np: pointer to device tree node | |
190 | * | |
191 | * This function probes the GPIO device in the device tree. It initializes the | |
192 | * driver data structure. It returns 0, if the driver is bound to the GPIO | |
193 | * device, or a negative value if there is an error. | |
194 | */ | |
3836309d | 195 | static int xgpio_of_probe(struct device_node *np) |
0bcb6069 JL |
196 | { |
197 | struct xgpio_instance *chip; | |
0bcb6069 JL |
198 | int status = 0; |
199 | const u32 *tree_info; | |
200 | ||
201 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | |
202 | if (!chip) | |
203 | return -ENOMEM; | |
0bcb6069 JL |
204 | |
205 | /* Update GPIO state shadow register with default value */ | |
6f8bf500 MS |
206 | of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state); |
207 | ||
208 | /* By default, all pins are inputs */ | |
209 | chip->gpio_dir = 0xFFFFFFFF; | |
0bcb6069 JL |
210 | |
211 | /* Update GPIO direction shadow register with default value */ | |
6f8bf500 MS |
212 | of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir); |
213 | ||
214 | /* By default assume full GPIO controller */ | |
215 | chip->mmchip.gc.ngpio = 32; | |
0bcb6069 JL |
216 | |
217 | /* Check device node and parent device node for device width */ | |
6f8bf500 MS |
218 | of_property_read_u32(np, "xlnx,gpio-width", |
219 | (u32 *)&chip->mmchip.gc.ngpio); | |
0bcb6069 JL |
220 | |
221 | spin_lock_init(&chip->gpio_lock); | |
222 | ||
a19e3da5 AV |
223 | chip->mmchip.gc.direction_input = xgpio_dir_in; |
224 | chip->mmchip.gc.direction_output = xgpio_dir_out; | |
225 | chip->mmchip.gc.get = xgpio_get; | |
226 | chip->mmchip.gc.set = xgpio_set; | |
0bcb6069 JL |
227 | |
228 | chip->mmchip.save_regs = xgpio_save_regs; | |
229 | ||
230 | /* Call the OF gpio helper to setup and register the GPIO device */ | |
231 | status = of_mm_gpiochip_add(np, &chip->mmchip); | |
232 | if (status) { | |
233 | kfree(chip); | |
234 | pr_err("%s: error in probe function with status %d\n", | |
235 | np->full_name, status); | |
236 | return status; | |
237 | } | |
74600ee0 MS |
238 | |
239 | pr_info("XGpio: %s: registered, base is %d\n", np->full_name, | |
240 | chip->mmchip.gc.base); | |
241 | ||
242 | tree_info = of_get_property(np, "xlnx,is-dual", NULL); | |
243 | if (tree_info && be32_to_cpup(tree_info)) { | |
244 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | |
245 | if (!chip) | |
246 | return -ENOMEM; | |
247 | ||
248 | /* Add dual channel offset */ | |
249 | chip->offset = XGPIO_CHANNEL_OFFSET; | |
250 | ||
251 | /* Update GPIO state shadow register with default value */ | |
252 | of_property_read_u32(np, "xlnx,dout-default-2", | |
253 | &chip->gpio_state); | |
254 | ||
255 | /* By default, all pins are inputs */ | |
256 | chip->gpio_dir = 0xFFFFFFFF; | |
257 | ||
258 | /* Update GPIO direction shadow register with default value */ | |
259 | of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir); | |
260 | ||
261 | /* By default assume full GPIO controller */ | |
262 | chip->mmchip.gc.ngpio = 32; | |
263 | ||
264 | /* Check device node and parent device node for device width */ | |
265 | of_property_read_u32(np, "xlnx,gpio2-width", | |
266 | (u32 *)&chip->mmchip.gc.ngpio); | |
267 | ||
268 | spin_lock_init(&chip->gpio_lock); | |
269 | ||
270 | chip->mmchip.gc.direction_input = xgpio_dir_in; | |
271 | chip->mmchip.gc.direction_output = xgpio_dir_out; | |
272 | chip->mmchip.gc.get = xgpio_get; | |
273 | chip->mmchip.gc.set = xgpio_set; | |
274 | ||
275 | chip->mmchip.save_regs = xgpio_save_regs; | |
276 | ||
277 | /* Call the OF gpio helper to setup and register the GPIO dev */ | |
278 | status = of_mm_gpiochip_add(np, &chip->mmchip); | |
279 | if (status) { | |
280 | kfree(chip); | |
281 | pr_err("%s: error in probe function with status %d\n", | |
282 | np->full_name, status); | |
283 | return status; | |
284 | } | |
285 | pr_info("XGpio: %s: dual channel registered, base is %d\n", | |
286 | np->full_name, chip->mmchip.gc.base); | |
287 | } | |
288 | ||
0bcb6069 JL |
289 | return 0; |
290 | } | |
291 | ||
aeca8ad1 | 292 | static struct of_device_id xgpio_of_match[] = { |
0bcb6069 JL |
293 | { .compatible = "xlnx,xps-gpio-1.00.a", }, |
294 | { /* end of list */ }, | |
295 | }; | |
296 | ||
297 | static int __init xgpio_init(void) | |
298 | { | |
299 | struct device_node *np; | |
300 | ||
301 | for_each_matching_node(np, xgpio_of_match) | |
302 | xgpio_of_probe(np); | |
303 | ||
304 | return 0; | |
305 | } | |
306 | ||
307 | /* Make sure we get initialized before anyone else tries to use us */ | |
308 | subsys_initcall(xgpio_init); | |
309 | /* No exit call at the moment as we cannot unregister of GPIO chips */ | |
310 | ||
311 | MODULE_AUTHOR("Xilinx, Inc."); | |
312 | MODULE_DESCRIPTION("Xilinx GPIO driver"); | |
313 | MODULE_LICENSE("GPL"); |