2 * Xilinx Zynq GPIO device driver
4 * Copyright (C) 2015 DAVE Embedded Systems <devel@dave.eu>
6 * Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c)
7 * Copyright (C) 2009 - 2014 Xilinx, Inc.
9 * SPDX-License-Identifier: GPL-2.0+
15 #include <asm/errno.h>
21 DECLARE_GLOBAL_DATA_PTR;
23 struct zynq_gpio_privdata {
29 * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank
30 * for a given pin in the GPIO device
31 * @pin_num: gpio pin number within the device
32 * @bank_num: an output parameter used to return the bank number of the gpio
34 * @bank_pin_num: an output parameter used to return pin number within a bank
35 * for the given gpio pin
37 * Returns the bank number and pin offset within the bank.
39 static inline void zynq_gpio_get_bank_pin(unsigned int pin_num,
40 unsigned int *bank_num,
41 unsigned int *bank_pin_num)
44 case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX:
46 *bank_pin_num = pin_num;
48 case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX:
50 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN;
52 case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX:
54 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN;
56 case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX:
58 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN;
61 printf("invalid GPIO pin number: %u\n", pin_num);
68 int gpio_is_valid(unsigned gpio)
70 return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS);
73 static int check_gpio(unsigned gpio)
75 if (!gpio_is_valid(gpio)) {
76 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
82 #ifndef CONFIG_DM_GPIO
84 * gpio_get_value - Get the state of the specified pin of GPIO device
85 * @gpio: gpio pin number within the device
87 * This function reads the state of the specified pin of the GPIO device.
89 * Return: 0 if the pin is low, 1 if pin is high.
91 int gpio_get_value(unsigned gpio)
94 unsigned int bank_num, bank_pin_num;
96 if (check_gpio(gpio) < 0)
99 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
101 data = readl(ZYNQ_GPIO_BASE_ADDRESS +
102 ZYNQ_GPIO_DATA_RO_OFFSET(bank_num));
104 return (data >> bank_pin_num) & 1;
108 * gpio_set_value - Modify the value of the pin with specified value
109 * @gpio: gpio pin number within the device
110 * @value: value used to modify the value of the specified pin
112 * This function calculates the register offset (i.e to lower 16 bits or
113 * upper 16 bits) based on the given pin number and sets the value of a
114 * gpio pin to the specified value. The value is either 0 or non-zero.
116 int gpio_set_value(unsigned gpio, int value)
118 unsigned int reg_offset, bank_num, bank_pin_num;
120 if (check_gpio(gpio) < 0)
123 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
125 if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) {
126 /* only 16 data bits in bit maskable reg */
127 bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM;
128 reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num);
130 reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num);
134 * get the 32 bit value to be written to the mask/data register where
135 * the upper 16 bits is the mask and lower 16 bits is the data
138 value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) &
139 ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK);
141 writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset);
147 * gpio_direction_input - Set the direction of the specified GPIO pin as input
148 * @gpio: gpio pin number within the device
150 * This function uses the read-modify-write sequence to set the direction of
151 * the gpio pin as input.
153 * Return: -1 if invalid gpio specified, 0 if successul
155 int gpio_direction_input(unsigned gpio)
158 unsigned int bank_num, bank_pin_num;
160 if (check_gpio(gpio) < 0)
163 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
165 /* bank 0 pins 7 and 8 are special and cannot be used as inputs */
166 if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8))
169 /* clear the bit in direction mode reg to set the pin as input */
170 reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
171 reg &= ~BIT(bank_pin_num);
172 writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
178 * gpio_direction_output - Set the direction of the specified GPIO pin as output
179 * @gpio: gpio pin number within the device
180 * @value: value to be written to specified pin
182 * This function sets the direction of specified GPIO pin as output, configures
183 * the Output Enable register for the pin and uses zynq_gpio_set to set
184 * the value of the pin to the value specified.
188 int gpio_direction_output(unsigned gpio, int value)
191 unsigned int bank_num, bank_pin_num;
193 if (check_gpio(gpio) < 0)
196 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
198 /* set the GPIO pin as output */
199 reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
200 reg |= BIT(bank_pin_num);
201 writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
203 /* configure the output enable reg for the pin */
204 reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
205 reg |= BIT(bank_pin_num);
206 writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
208 /* set the state of the pin */
209 gpio_set_value(gpio, value);
214 * Request a gpio before using it.
216 * NOTE: Argument 'label' is unused.
218 int gpio_request(unsigned gpio, const char *label)
220 if (check_gpio(gpio) < 0)
227 * Reset and free the gpio after using it.
229 int gpio_free(unsigned gpio)
234 static int zynq_gpio_get_value(struct udevice *dev, unsigned gpio)
237 unsigned int bank_num, bank_pin_num;
238 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
240 if (check_gpio(gpio) < 0)
243 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
245 data = readl(priv->base +
246 ZYNQ_GPIO_DATA_RO_OFFSET(bank_num));
248 return (data >> bank_pin_num) & 1;
251 static int zynq_gpio_set_value(struct udevice *dev, unsigned gpio, int value)
253 unsigned int reg_offset, bank_num, bank_pin_num;
254 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
256 if (check_gpio(gpio) < 0)
259 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
261 if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) {
262 /* only 16 data bits in bit maskable reg */
263 bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM;
264 reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num);
266 reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num);
270 * get the 32 bit value to be written to the mask/data register where
271 * the upper 16 bits is the mask and lower 16 bits is the data
274 value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) &
275 ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK);
277 writel(value, priv->base + reg_offset);
282 static int zynq_gpio_direction_input(struct udevice *dev, unsigned gpio)
285 unsigned int bank_num, bank_pin_num;
286 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
288 if (check_gpio(gpio) < 0)
291 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
293 /* bank 0 pins 7 and 8 are special and cannot be used as inputs */
294 if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8))
297 /* clear the bit in direction mode reg to set the pin as input */
298 reg = readl(priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
299 reg &= ~BIT(bank_pin_num);
300 writel(reg, priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
305 static int zynq_gpio_direction_output(struct udevice *dev, unsigned gpio,
309 unsigned int bank_num, bank_pin_num;
310 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
312 if (check_gpio(gpio) < 0)
315 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
317 /* set the GPIO pin as output */
318 reg = readl(priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
319 reg |= BIT(bank_pin_num);
320 writel(reg, priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
322 /* configure the output enable reg for the pin */
323 reg = readl(priv->base + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
324 reg |= BIT(bank_pin_num);
325 writel(reg, priv->base + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
327 /* set the state of the pin */
328 gpio_set_value(gpio, value);
332 static const struct dm_gpio_ops gpio_zynq_ops = {
333 .direction_input = zynq_gpio_direction_input,
334 .direction_output = zynq_gpio_direction_output,
335 .get_value = zynq_gpio_get_value,
336 .set_value = zynq_gpio_set_value,
339 static int zynq_gpio_probe(struct udevice *dev)
341 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
343 priv->base = dev_get_addr(dev);
348 static int zynq_gpio_ofdata_to_platdata(struct udevice *dev)
350 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
352 uc_priv->gpio_count = ZYNQ_GPIO_NR_GPIOS;
357 static const struct udevice_id zynq_gpio_ids[] = {
358 { .compatible = "xlnx,zynq-gpio-1.0" },
362 U_BOOT_DRIVER(gpio_zynq) = {
365 .ops = &gpio_zynq_ops,
366 .of_match = zynq_gpio_ids,
367 .ofdata_to_platdata = zynq_gpio_ofdata_to_platdata,
368 .probe = zynq_gpio_probe,
369 .priv_auto_alloc_size = sizeof(struct zynq_gpio_privdata),