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
),