]>
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 | |
74600ee0 MS |
46 | * gpio_lock: Lock used for synchronization |
47 | */ | |
0bcb6069 JL |
48 | struct xgpio_instance { |
49 | struct of_mm_gpio_chip mmchip; | |
74600ee0 MS |
50 | u32 gpio_state; |
51 | u32 gpio_dir; | |
74600ee0 | 52 | spinlock_t gpio_lock; |
0bcb6069 JL |
53 | }; |
54 | ||
55 | /** | |
56 | * xgpio_get - Read the specified signal of the GPIO device. | |
57 | * @gc: Pointer to gpio_chip device structure. | |
58 | * @gpio: GPIO signal number. | |
59 | * | |
60 | * This function reads the specified signal of the GPIO device. It returns 0 if | |
61 | * the signal clear, 1 if signal is set or negative value on error. | |
62 | */ | |
63 | static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) | |
64 | { | |
65 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
66 | ||
bc2f3dc3 | 67 | return !!(xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET) & BIT(gpio)); |
0bcb6069 JL |
68 | } |
69 | ||
70 | /** | |
71 | * xgpio_set - Write the specified signal of the GPIO device. | |
72 | * @gc: Pointer to gpio_chip device structure. | |
73 | * @gpio: GPIO signal number. | |
74 | * @val: Value to be written to specified signal. | |
75 | * | |
76 | * This function writes the specified value in to the specified signal of the | |
77 | * GPIO device. | |
78 | */ | |
79 | static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | |
80 | { | |
81 | unsigned long flags; | |
82 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
83 | struct xgpio_instance *chip = | |
84 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
85 | ||
86 | spin_lock_irqsave(&chip->gpio_lock, flags); | |
87 | ||
88 | /* Write to GPIO signal and set its direction to output */ | |
89 | if (val) | |
9f7f0b2b | 90 | chip->gpio_state |= BIT(gpio); |
0bcb6069 | 91 | else |
9f7f0b2b | 92 | chip->gpio_state &= ~BIT(gpio); |
74600ee0 | 93 | |
bc2f3dc3 | 94 | xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); |
0bcb6069 JL |
95 | |
96 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | |
97 | } | |
98 | ||
99 | /** | |
100 | * xgpio_dir_in - Set the direction of the specified GPIO signal as input. | |
101 | * @gc: Pointer to gpio_chip device structure. | |
102 | * @gpio: GPIO signal number. | |
103 | * | |
104 | * This function sets the direction of specified GPIO signal as input. | |
105 | * It returns 0 if direction of GPIO signals is set as input otherwise it | |
106 | * returns negative error value. | |
107 | */ | |
108 | static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | |
109 | { | |
110 | unsigned long flags; | |
111 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
112 | struct xgpio_instance *chip = | |
113 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
114 | ||
115 | spin_lock_irqsave(&chip->gpio_lock, flags); | |
116 | ||
117 | /* Set the GPIO bit in shadow register and set direction as input */ | |
9f7f0b2b | 118 | chip->gpio_dir |= BIT(gpio); |
bc2f3dc3 | 119 | xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); |
0bcb6069 JL |
120 | |
121 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | |
122 | ||
123 | return 0; | |
124 | } | |
125 | ||
126 | /** | |
127 | * xgpio_dir_out - Set the direction of the specified GPIO signal as output. | |
128 | * @gc: Pointer to gpio_chip device structure. | |
129 | * @gpio: GPIO signal number. | |
130 | * @val: Value to be written to specified signal. | |
131 | * | |
132 | * This function sets the direction of specified GPIO signal as output. If all | |
133 | * GPIO signals of GPIO chip is configured as input then it returns | |
134 | * error otherwise it returns 0. | |
135 | */ | |
136 | static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |
137 | { | |
138 | unsigned long flags; | |
139 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | |
140 | struct xgpio_instance *chip = | |
141 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
142 | ||
143 | spin_lock_irqsave(&chip->gpio_lock, flags); | |
144 | ||
145 | /* Write state of GPIO signal */ | |
146 | if (val) | |
9f7f0b2b | 147 | chip->gpio_state |= BIT(gpio); |
0bcb6069 | 148 | else |
9f7f0b2b | 149 | chip->gpio_state &= ~BIT(gpio); |
bc2f3dc3 | 150 | xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); |
0bcb6069 JL |
151 | |
152 | /* Clear the GPIO bit in shadow register and set direction as output */ | |
9f7f0b2b | 153 | chip->gpio_dir &= ~BIT(gpio); |
bc2f3dc3 | 154 | xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); |
0bcb6069 JL |
155 | |
156 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | |
157 | ||
158 | return 0; | |
159 | } | |
160 | ||
161 | /** | |
162 | * xgpio_save_regs - Set initial values of GPIO pins | |
163 | * @mm_gc: pointer to memory mapped GPIO chip structure | |
164 | */ | |
165 | static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) | |
166 | { | |
167 | struct xgpio_instance *chip = | |
168 | container_of(mm_gc, struct xgpio_instance, mmchip); | |
169 | ||
bc2f3dc3 RRD |
170 | xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); |
171 | xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | |
0bcb6069 JL |
172 | } |
173 | ||
174 | /** | |
175 | * xgpio_of_probe - Probe method for the GPIO device. | |
176 | * @np: pointer to device tree node | |
177 | * | |
178 | * This function probes the GPIO device in the device tree. It initializes the | |
179 | * driver data structure. It returns 0, if the driver is bound to the GPIO | |
180 | * device, or a negative value if there is an error. | |
181 | */ | |
3836309d | 182 | static int xgpio_of_probe(struct device_node *np) |
0bcb6069 JL |
183 | { |
184 | struct xgpio_instance *chip; | |
0bcb6069 JL |
185 | int status = 0; |
186 | const u32 *tree_info; | |
1b4c5a6e | 187 | u32 ngpio; |
0bcb6069 JL |
188 | |
189 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | |
190 | if (!chip) | |
191 | return -ENOMEM; | |
0bcb6069 JL |
192 | |
193 | /* Update GPIO state shadow register with default value */ | |
6f8bf500 MS |
194 | of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state); |
195 | ||
196 | /* By default, all pins are inputs */ | |
197 | chip->gpio_dir = 0xFFFFFFFF; | |
0bcb6069 JL |
198 | |
199 | /* Update GPIO direction shadow register with default value */ | |
6f8bf500 MS |
200 | of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir); |
201 | ||
1b4c5a6e GV |
202 | /* |
203 | * Check device node and parent device node for device width | |
204 | * and assume default width of 32 | |
205 | */ | |
206 | if (of_property_read_u32(np, "xlnx,gpio-width", &ngpio)) | |
207 | ngpio = 32; | |
208 | chip->mmchip.gc.ngpio = (u16)ngpio; | |
0bcb6069 JL |
209 | |
210 | spin_lock_init(&chip->gpio_lock); | |
211 | ||
a19e3da5 AV |
212 | chip->mmchip.gc.direction_input = xgpio_dir_in; |
213 | chip->mmchip.gc.direction_output = xgpio_dir_out; | |
214 | chip->mmchip.gc.get = xgpio_get; | |
215 | chip->mmchip.gc.set = xgpio_set; | |
0bcb6069 JL |
216 | |
217 | chip->mmchip.save_regs = xgpio_save_regs; | |
218 | ||
219 | /* Call the OF gpio helper to setup and register the GPIO device */ | |
220 | status = of_mm_gpiochip_add(np, &chip->mmchip); | |
221 | if (status) { | |
222 | kfree(chip); | |
223 | pr_err("%s: error in probe function with status %d\n", | |
224 | np->full_name, status); | |
225 | return status; | |
226 | } | |
74600ee0 MS |
227 | |
228 | pr_info("XGpio: %s: registered, base is %d\n", np->full_name, | |
229 | chip->mmchip.gc.base); | |
230 | ||
231 | tree_info = of_get_property(np, "xlnx,is-dual", NULL); | |
232 | if (tree_info && be32_to_cpup(tree_info)) { | |
233 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | |
234 | if (!chip) | |
235 | return -ENOMEM; | |
236 | ||
74600ee0 MS |
237 | /* Update GPIO state shadow register with default value */ |
238 | of_property_read_u32(np, "xlnx,dout-default-2", | |
239 | &chip->gpio_state); | |
240 | ||
241 | /* By default, all pins are inputs */ | |
242 | chip->gpio_dir = 0xFFFFFFFF; | |
243 | ||
244 | /* Update GPIO direction shadow register with default value */ | |
245 | of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir); | |
246 | ||
1b4c5a6e GV |
247 | /* |
248 | * Check device node and parent device node for device width | |
249 | * and assume default width of 32 | |
250 | */ | |
251 | if (of_property_read_u32(np, "xlnx,gpio2-width", &ngpio)) | |
252 | ngpio = 32; | |
253 | chip->mmchip.gc.ngpio = (u16)ngpio; | |
74600ee0 MS |
254 | |
255 | spin_lock_init(&chip->gpio_lock); | |
256 | ||
257 | chip->mmchip.gc.direction_input = xgpio_dir_in; | |
258 | chip->mmchip.gc.direction_output = xgpio_dir_out; | |
259 | chip->mmchip.gc.get = xgpio_get; | |
260 | chip->mmchip.gc.set = xgpio_set; | |
261 | ||
262 | chip->mmchip.save_regs = xgpio_save_regs; | |
263 | ||
264 | /* Call the OF gpio helper to setup and register the GPIO dev */ | |
265 | status = of_mm_gpiochip_add(np, &chip->mmchip); | |
266 | if (status) { | |
267 | kfree(chip); | |
268 | pr_err("%s: error in probe function with status %d\n", | |
269 | np->full_name, status); | |
270 | return status; | |
271 | } | |
bc2f3dc3 RRD |
272 | |
273 | /* Add dual channel offset */ | |
274 | chip->mmchip.regs += XGPIO_CHANNEL_OFFSET; | |
275 | ||
74600ee0 MS |
276 | pr_info("XGpio: %s: dual channel registered, base is %d\n", |
277 | np->full_name, chip->mmchip.gc.base); | |
278 | } | |
279 | ||
0bcb6069 JL |
280 | return 0; |
281 | } | |
282 | ||
9992bc95 | 283 | static const struct of_device_id xgpio_of_match[] = { |
0bcb6069 JL |
284 | { .compatible = "xlnx,xps-gpio-1.00.a", }, |
285 | { /* end of list */ }, | |
286 | }; | |
287 | ||
288 | static int __init xgpio_init(void) | |
289 | { | |
290 | struct device_node *np; | |
291 | ||
292 | for_each_matching_node(np, xgpio_of_match) | |
293 | xgpio_of_probe(np); | |
294 | ||
295 | return 0; | |
296 | } | |
297 | ||
298 | /* Make sure we get initialized before anyone else tries to use us */ | |
299 | subsys_initcall(xgpio_init); | |
300 | /* No exit call at the moment as we cannot unregister of GPIO chips */ | |
301 | ||
302 | MODULE_AUTHOR("Xilinx, Inc."); | |
303 | MODULE_DESCRIPTION("Xilinx GPIO driver"); | |
304 | MODULE_LICENSE("GPL"); |