blob: 32944eb886c1c4a5b0900ea71477e6d3281d2750 [file] [log] [blame]
Thomas Gleixner6e75fc02019-05-27 08:55:22 +02001// SPDX-License-Identifier: GPL-2.0-only
John Linn0bcb6062008-11-12 13:25:38 -08002/*
Michal Simek74600ee2013-06-03 14:31:17 +02003 * Xilinx gpio driver for xps/axi_gpio IP.
John Linn0bcb6062008-11-12 13:25:38 -08004 *
Michal Simek74600ee2013-06-03 14:31:17 +02005 * Copyright 2008 - 2013 Xilinx, Inc.
John Linn0bcb6062008-11-12 13:25:38 -08006 */
7
Michal Simek74600ee2013-06-03 14:31:17 +02008#include <linux/bitops.h>
John Linn0bcb6062008-11-12 13:25:38 -08009#include <linux/init.h>
10#include <linux/errno.h>
Paul Gortmakerbb207ef2011-07-03 13:38:09 -040011#include <linux/module.h>
John Linn0bcb6062008-11-12 13:25:38 -080012#include <linux/of_device.h>
13#include <linux/of_platform.h>
14#include <linux/of_gpio.h>
15#include <linux/io.h>
Linus Walleij516df4e2018-08-06 18:39:59 +020016#include <linux/gpio/driver.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090017#include <linux/slab.h>
John Linn0bcb6062008-11-12 13:25:38 -080018
19/* Register Offset Definitions */
20#define XGPIO_DATA_OFFSET (0x0) /* Data register */
21#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */
22
Michal Simek74600ee2013-06-03 14:31:17 +020023#define XGPIO_CHANNEL_OFFSET 0x8
24
25/* Read/Write access to the GPIO registers */
Ricardo Ribalda Delgadoc54c58b2014-12-17 16:51:10 +010026#if defined(CONFIG_ARCH_ZYNQ) || defined(CONFIG_X86)
Michal Simekcc090d62013-06-03 14:31:18 +020027# define xgpio_readreg(offset) readl(offset)
28# define xgpio_writereg(offset, val) writel(val, offset)
29#else
30# define xgpio_readreg(offset) __raw_readl(offset)
31# define xgpio_writereg(offset, val) __raw_writel(val, offset)
32#endif
Michal Simek74600ee2013-06-03 14:31:17 +020033
34/**
35 * struct xgpio_instance - Stores information about GPIO device
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +010036 * @mmchip: OF GPIO chip for memory mapped banks
Michal Simek3c1b5c9b2015-05-04 16:37:16 +020037 * @gpio_width: GPIO width for every channel
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +010038 * @gpio_state: GPIO state shadow register
39 * @gpio_dir: GPIO direction shadow register
40 * @gpio_lock: Lock used for synchronization
Michal Simek74600ee2013-06-03 14:31:17 +020041 */
John Linn0bcb6062008-11-12 13:25:38 -080042struct xgpio_instance {
43 struct of_mm_gpio_chip mmchip;
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +010044 unsigned int gpio_width[2];
45 u32 gpio_state[2];
46 u32 gpio_dir[2];
47 spinlock_t gpio_lock[2];
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +010048};
49
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +010050static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
51{
52 if (gpio >= chip->gpio_width[0])
53 return 1;
54
55 return 0;
56}
57
58static inline int xgpio_regoffset(struct xgpio_instance *chip, int gpio)
59{
60 if (xgpio_index(chip, gpio))
61 return XGPIO_CHANNEL_OFFSET;
62
63 return 0;
64}
65
66static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
67{
68 if (xgpio_index(chip, gpio))
69 return gpio - chip->gpio_width[0];
70
71 return gpio;
72}
John Linn0bcb6062008-11-12 13:25:38 -080073
74/**
75 * xgpio_get - Read the specified signal of the GPIO device.
76 * @gc: Pointer to gpio_chip device structure.
77 * @gpio: GPIO signal number.
78 *
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +010079 * This function reads the specified signal of the GPIO device.
80 *
81 * Return:
82 * 0 if direction of GPIO signals is set as input otherwise it
83 * returns negative error value.
John Linn0bcb6062008-11-12 13:25:38 -080084 */
85static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
86{
87 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
Linus Walleij097d88e2015-12-07 15:20:17 +010088 struct xgpio_instance *chip = gpiochip_get_data(gc);
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +010089 u32 val;
John Linn0bcb6062008-11-12 13:25:38 -080090
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +010091 val = xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET +
92 xgpio_regoffset(chip, gpio));
93
94 return !!(val & BIT(xgpio_offset(chip, gpio)));
John Linn0bcb6062008-11-12 13:25:38 -080095}
96
97/**
98 * xgpio_set - Write the specified signal of the GPIO device.
99 * @gc: Pointer to gpio_chip device structure.
100 * @gpio: GPIO signal number.
101 * @val: Value to be written to specified signal.
102 *
103 * This function writes the specified value in to the specified signal of the
104 * GPIO device.
105 */
106static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
107{
108 unsigned long flags;
109 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
Linus Walleij097d88e2015-12-07 15:20:17 +0100110 struct xgpio_instance *chip = gpiochip_get_data(gc);
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100111 int index = xgpio_index(chip, gpio);
112 int offset = xgpio_offset(chip, gpio);
John Linn0bcb6062008-11-12 13:25:38 -0800113
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100114 spin_lock_irqsave(&chip->gpio_lock[index], flags);
John Linn0bcb6062008-11-12 13:25:38 -0800115
116 /* Write to GPIO signal and set its direction to output */
117 if (val)
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100118 chip->gpio_state[index] |= BIT(offset);
John Linn0bcb6062008-11-12 13:25:38 -0800119 else
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100120 chip->gpio_state[index] &= ~BIT(offset);
Michal Simek74600ee2013-06-03 14:31:17 +0200121
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100122 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
123 xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
John Linn0bcb6062008-11-12 13:25:38 -0800124
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100125 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
John Linn0bcb6062008-11-12 13:25:38 -0800126}
127
128/**
Iban Rodriguez8e7c1b802016-06-03 14:54:41 +0200129 * xgpio_set_multiple - Write the specified signals of the GPIO device.
130 * @gc: Pointer to gpio_chip device structure.
131 * @mask: Mask of the GPIOS to modify.
132 * @bits: Value to be wrote on each GPIO
133 *
134 * This function writes the specified values into the specified signals of the
135 * GPIO devices.
136 */
137static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
138 unsigned long *bits)
139{
140 unsigned long flags;
141 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
142 struct xgpio_instance *chip = gpiochip_get_data(gc);
143 int index = xgpio_index(chip, 0);
144 int offset, i;
145
146 spin_lock_irqsave(&chip->gpio_lock[index], flags);
147
148 /* Write to GPIO signals */
149 for (i = 0; i < gc->ngpio; i++) {
150 if (*mask == 0)
151 break;
152 if (index != xgpio_index(chip, i)) {
153 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
154 xgpio_regoffset(chip, i),
155 chip->gpio_state[index]);
156 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
157 index = xgpio_index(chip, i);
158 spin_lock_irqsave(&chip->gpio_lock[index], flags);
159 }
160 if (__test_and_clear_bit(i, mask)) {
161 offset = xgpio_offset(chip, i);
162 if (test_bit(i, bits))
163 chip->gpio_state[index] |= BIT(offset);
164 else
165 chip->gpio_state[index] &= ~BIT(offset);
166 }
167 }
168
169 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
170 xgpio_regoffset(chip, i), chip->gpio_state[index]);
171
172 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
173}
174
175/**
John Linn0bcb6062008-11-12 13:25:38 -0800176 * xgpio_dir_in - Set the direction of the specified GPIO signal as input.
177 * @gc: Pointer to gpio_chip device structure.
178 * @gpio: GPIO signal number.
179 *
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +0100180 * Return:
181 * 0 - if direction of GPIO signals is set as input
182 * otherwise it returns negative error value.
John Linn0bcb6062008-11-12 13:25:38 -0800183 */
184static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
185{
186 unsigned long flags;
187 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
Linus Walleij097d88e2015-12-07 15:20:17 +0100188 struct xgpio_instance *chip = gpiochip_get_data(gc);
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100189 int index = xgpio_index(chip, gpio);
190 int offset = xgpio_offset(chip, gpio);
John Linn0bcb6062008-11-12 13:25:38 -0800191
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100192 spin_lock_irqsave(&chip->gpio_lock[index], flags);
John Linn0bcb6062008-11-12 13:25:38 -0800193
194 /* Set the GPIO bit in shadow register and set direction as input */
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100195 chip->gpio_dir[index] |= BIT(offset);
196 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
197 xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
John Linn0bcb6062008-11-12 13:25:38 -0800198
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100199 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
John Linn0bcb6062008-11-12 13:25:38 -0800200
201 return 0;
202}
203
204/**
205 * xgpio_dir_out - Set the direction of the specified GPIO signal as output.
206 * @gc: Pointer to gpio_chip device structure.
207 * @gpio: GPIO signal number.
208 * @val: Value to be written to specified signal.
209 *
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +0100210 * This function sets the direction of specified GPIO signal as output.
211 *
212 * Return:
213 * If all GPIO signals of GPIO chip is configured as input then it returns
John Linn0bcb6062008-11-12 13:25:38 -0800214 * error otherwise it returns 0.
215 */
216static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
217{
218 unsigned long flags;
219 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
Linus Walleij097d88e2015-12-07 15:20:17 +0100220 struct xgpio_instance *chip = gpiochip_get_data(gc);
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100221 int index = xgpio_index(chip, gpio);
222 int offset = xgpio_offset(chip, gpio);
John Linn0bcb6062008-11-12 13:25:38 -0800223
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100224 spin_lock_irqsave(&chip->gpio_lock[index], flags);
John Linn0bcb6062008-11-12 13:25:38 -0800225
226 /* Write state of GPIO signal */
227 if (val)
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100228 chip->gpio_state[index] |= BIT(offset);
John Linn0bcb6062008-11-12 13:25:38 -0800229 else
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100230 chip->gpio_state[index] &= ~BIT(offset);
231 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
232 xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
John Linn0bcb6062008-11-12 13:25:38 -0800233
234 /* Clear the GPIO bit in shadow register and set direction as output */
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100235 chip->gpio_dir[index] &= ~BIT(offset);
236 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
237 xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
John Linn0bcb6062008-11-12 13:25:38 -0800238
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100239 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
John Linn0bcb6062008-11-12 13:25:38 -0800240
241 return 0;
242}
243
244/**
245 * xgpio_save_regs - Set initial values of GPIO pins
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +0100246 * @mm_gc: Pointer to memory mapped GPIO chip structure
John Linn0bcb6062008-11-12 13:25:38 -0800247 */
248static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
249{
Guenter Roeckde06c1d2016-01-06 16:20:10 -0800250 struct xgpio_instance *chip =
251 container_of(mm_gc, struct xgpio_instance, mmchip);
John Linn0bcb6062008-11-12 13:25:38 -0800252
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100253 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
254 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
255
256 if (!chip->gpio_width[1])
257 return;
258
Raphaël Teysseyre5b2c9122015-06-24 09:19:45 +0200259 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100260 chip->gpio_state[1]);
Raphaël Teysseyre5b2c9122015-06-24 09:19:45 +0200261 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100262 chip->gpio_dir[1]);
John Linn0bcb6062008-11-12 13:25:38 -0800263}
264
265/**
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100266 * xgpio_remove - Remove method for the GPIO device.
267 * @pdev: pointer to the platform device
268 *
269 * This function remove gpiochips and frees all the allocated resources.
Michal Simek3c1b5c9b2015-05-04 16:37:16 +0200270 *
271 * Return: 0 always
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100272 */
273static int xgpio_remove(struct platform_device *pdev)
274{
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100275 struct xgpio_instance *chip = platform_get_drvdata(pdev);
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100276
Ricardo Ribalda Delgadoc458e452014-12-17 16:51:14 +0100277 of_mm_gpiochip_remove(&chip->mmchip);
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100278
279 return 0;
280}
281
282/**
John Linn0bcb6062008-11-12 13:25:38 -0800283 * xgpio_of_probe - Probe method for the GPIO device.
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100284 * @pdev: pointer to the platform device
John Linn0bcb6062008-11-12 13:25:38 -0800285 *
Ricardo Ribalda Delgado4ae798f2014-12-17 16:51:11 +0100286 * Return:
287 * It returns 0, if the driver is bound to the GPIO device, or
288 * a negative value if there is an error.
John Linn0bcb6062008-11-12 13:25:38 -0800289 */
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100290static int xgpio_probe(struct platform_device *pdev)
John Linn0bcb6062008-11-12 13:25:38 -0800291{
292 struct xgpio_instance *chip;
John Linn0bcb6062008-11-12 13:25:38 -0800293 int status = 0;
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100294 struct device_node *np = pdev->dev.of_node;
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100295 u32 is_dual;
John Linn0bcb6062008-11-12 13:25:38 -0800296
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100297 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
298 if (!chip)
John Linn0bcb6062008-11-12 13:25:38 -0800299 return -ENOMEM;
John Linn0bcb6062008-11-12 13:25:38 -0800300
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100301 platform_set_drvdata(pdev, chip);
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100302
John Linn0bcb6062008-11-12 13:25:38 -0800303 /* Update GPIO state shadow register with default value */
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100304 of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0]);
John Linn0bcb6062008-11-12 13:25:38 -0800305
306 /* Update GPIO direction shadow register with default value */
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100307 if (of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir[0]))
308 chip->gpio_dir[0] = 0xFFFFFFFF;
Michal Simek6f8bf502013-06-03 14:31:16 +0200309
Gernot Vormayr1b4c5a62014-09-24 00:58:45 +0200310 /*
311 * Check device node and parent device node for device width
312 * and assume default width of 32
313 */
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100314 if (of_property_read_u32(np, "xlnx,gpio-width", &chip->gpio_width[0]))
315 chip->gpio_width[0] = 32;
John Linn0bcb6062008-11-12 13:25:38 -0800316
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100317 spin_lock_init(&chip->gpio_lock[0]);
John Linn0bcb6062008-11-12 13:25:38 -0800318
Ricardo Ribalda Delgado1d6902d2014-12-17 16:51:12 +0100319 if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
320 is_dual = 0;
321
322 if (is_dual) {
323 /* Update GPIO state shadow register with default value */
324 of_property_read_u32(np, "xlnx,dout-default-2",
325 &chip->gpio_state[1]);
326
327 /* Update GPIO direction shadow register with default value */
328 if (of_property_read_u32(np, "xlnx,tri-default-2",
329 &chip->gpio_dir[1]))
330 chip->gpio_dir[1] = 0xFFFFFFFF;
331
332 /*
333 * Check device node and parent device node for device width
334 * and assume default width of 32
335 */
336 if (of_property_read_u32(np, "xlnx,gpio2-width",
337 &chip->gpio_width[1]))
338 chip->gpio_width[1] = 32;
339
340 spin_lock_init(&chip->gpio_lock[1]);
341 }
342
343 chip->mmchip.gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
Linus Walleij58383c782015-11-04 09:56:26 +0100344 chip->mmchip.gc.parent = &pdev->dev;
Anton Vorontsova19e3da2010-06-08 07:48:16 -0600345 chip->mmchip.gc.direction_input = xgpio_dir_in;
346 chip->mmchip.gc.direction_output = xgpio_dir_out;
347 chip->mmchip.gc.get = xgpio_get;
348 chip->mmchip.gc.set = xgpio_set;
Iban Rodriguez8e7c1b802016-06-03 14:54:41 +0200349 chip->mmchip.gc.set_multiple = xgpio_set_multiple;
John Linn0bcb6062008-11-12 13:25:38 -0800350
351 chip->mmchip.save_regs = xgpio_save_regs;
352
353 /* Call the OF gpio helper to setup and register the GPIO device */
Linus Walleij097d88e2015-12-07 15:20:17 +0100354 status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip);
John Linn0bcb6062008-11-12 13:25:38 -0800355 if (status) {
Rob Herring7eb6ce22017-07-18 16:43:03 -0500356 pr_err("%pOF: error in probe function with status %d\n",
357 np, status);
John Linn0bcb6062008-11-12 13:25:38 -0800358 return status;
359 }
Michal Simek74600ee2013-06-03 14:31:17 +0200360
John Linn0bcb6062008-11-12 13:25:38 -0800361 return 0;
362}
363
Jingoo Han9992bc92014-05-07 18:08:20 +0900364static const struct of_device_id xgpio_of_match[] = {
John Linn0bcb6062008-11-12 13:25:38 -0800365 { .compatible = "xlnx,xps-gpio-1.00.a", },
366 { /* end of list */ },
367};
368
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100369MODULE_DEVICE_TABLE(of, xgpio_of_match);
370
371static struct platform_driver xgpio_plat_driver = {
372 .probe = xgpio_probe,
373 .remove = xgpio_remove,
374 .driver = {
375 .name = "gpio-xilinx",
376 .of_match_table = xgpio_of_match,
377 },
378};
379
John Linn0bcb6062008-11-12 13:25:38 -0800380static int __init xgpio_init(void)
381{
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100382 return platform_driver_register(&xgpio_plat_driver);
John Linn0bcb6062008-11-12 13:25:38 -0800383}
384
John Linn0bcb6062008-11-12 13:25:38 -0800385subsys_initcall(xgpio_init);
Ricardo Ribalda Delgado749564f2014-12-17 16:51:09 +0100386
387static void __exit xgpio_exit(void)
388{
389 platform_driver_unregister(&xgpio_plat_driver);
390}
391module_exit(xgpio_exit);
John Linn0bcb6062008-11-12 13:25:38 -0800392
393MODULE_AUTHOR("Xilinx, Inc.");
394MODULE_DESCRIPTION("Xilinx GPIO driver");
395MODULE_LICENSE("GPL");