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>
19 DECLARE_GLOBAL_DATA_PTR;
21 struct zynq_gpio_privdata {
26 * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank
27 * for a given pin in the GPIO device
28 * @pin_num: gpio pin number within the device
29 * @bank_num: an output parameter used to return the bank number of the gpio
31 * @bank_pin_num: an output parameter used to return pin number within a bank
32 * for the given gpio pin
34 * Returns the bank number and pin offset within the bank.
36 static inline void zynq_gpio_get_bank_pin(unsigned int pin_num,
37 unsigned int *bank_num,
38 unsigned int *bank_pin_num)
41 case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX:
43 *bank_pin_num = pin_num;
45 case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX:
47 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN;
49 case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX:
51 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN;
53 case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX:
55 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN;
58 printf("invalid GPIO pin number: %u\n", pin_num);
65 static int gpio_is_valid(unsigned gpio)
67 return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS);
70 static int check_gpio(unsigned gpio)
72 if (!gpio_is_valid(gpio)) {
73 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
79 static int zynq_gpio_get_value(struct udevice *dev, unsigned gpio)
82 unsigned int bank_num, bank_pin_num;
83 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
85 if (check_gpio(gpio) < 0)
88 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
90 data = readl(priv->base +
91 ZYNQ_GPIO_DATA_RO_OFFSET(bank_num));
93 return (data >> bank_pin_num) & 1;
96 static int zynq_gpio_set_value(struct udevice *dev, unsigned gpio, int value)
98 unsigned int reg_offset, bank_num, bank_pin_num;
99 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
101 if (check_gpio(gpio) < 0)
104 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
106 if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) {
107 /* only 16 data bits in bit maskable reg */
108 bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM;
109 reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num);
111 reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num);
115 * get the 32 bit value to be written to the mask/data register where
116 * the upper 16 bits is the mask and lower 16 bits is the data
119 value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) &
120 ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK);
122 writel(value, priv->base + reg_offset);
127 static int zynq_gpio_direction_input(struct udevice *dev, unsigned gpio)
130 unsigned int bank_num, bank_pin_num;
131 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
133 if (check_gpio(gpio) < 0)
136 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
138 /* bank 0 pins 7 and 8 are special and cannot be used as inputs */
139 if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8))
142 /* clear the bit in direction mode reg to set the pin as input */
143 reg = readl(priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
144 reg &= ~BIT(bank_pin_num);
145 writel(reg, priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
150 static int zynq_gpio_direction_output(struct udevice *dev, unsigned gpio,
154 unsigned int bank_num, bank_pin_num;
155 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
157 if (check_gpio(gpio) < 0)
160 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
162 /* set the GPIO pin as output */
163 reg = readl(priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
164 reg |= BIT(bank_pin_num);
165 writel(reg, priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
167 /* configure the output enable reg for the pin */
168 reg = readl(priv->base + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
169 reg |= BIT(bank_pin_num);
170 writel(reg, priv->base + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
172 /* set the state of the pin */
173 gpio_set_value(gpio, value);
177 static const struct dm_gpio_ops gpio_zynq_ops = {
178 .direction_input = zynq_gpio_direction_input,
179 .direction_output = zynq_gpio_direction_output,
180 .get_value = zynq_gpio_get_value,
181 .set_value = zynq_gpio_set_value,
184 static int zynq_gpio_probe(struct udevice *dev)
186 struct zynq_gpio_privdata *priv = dev_get_priv(dev);
188 priv->base = dev_get_addr(dev);
193 static int zynq_gpio_ofdata_to_platdata(struct udevice *dev)
195 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
197 uc_priv->gpio_count = ZYNQ_GPIO_NR_GPIOS;
202 static const struct udevice_id zynq_gpio_ids[] = {
203 { .compatible = "xlnx,zynq-gpio-1.0" },
207 U_BOOT_DRIVER(gpio_zynq) = {
210 .ops = &gpio_zynq_ops,
211 .of_match = zynq_gpio_ids,
212 .ofdata_to_platdata = zynq_gpio_ofdata_to_platdata,
213 .probe = zynq_gpio_probe,
214 .priv_auto_alloc_size = sizeof(struct zynq_gpio_privdata),