]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/gpio/zynq_gpio.c
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>
18 * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank
19 * for a given pin in the GPIO device
20 * @pin_num: gpio pin number within the device
21 * @bank_num: an output parameter used to return the bank number of the gpio
23 * @bank_pin_num: an output parameter used to return pin number within a bank
24 * for the given gpio pin
26 * Returns the bank number and pin offset within the bank.
28 static inline void zynq_gpio_get_bank_pin(unsigned int pin_num
,
29 unsigned int *bank_num
,
30 unsigned int *bank_pin_num
)
33 case ZYNQ_GPIO_BANK0_PIN_MIN
... ZYNQ_GPIO_BANK0_PIN_MAX
:
35 *bank_pin_num
= pin_num
;
37 case ZYNQ_GPIO_BANK1_PIN_MIN
... ZYNQ_GPIO_BANK1_PIN_MAX
:
39 *bank_pin_num
= pin_num
- ZYNQ_GPIO_BANK1_PIN_MIN
;
41 case ZYNQ_GPIO_BANK2_PIN_MIN
... ZYNQ_GPIO_BANK2_PIN_MAX
:
43 *bank_pin_num
= pin_num
- ZYNQ_GPIO_BANK2_PIN_MIN
;
45 case ZYNQ_GPIO_BANK3_PIN_MIN
... ZYNQ_GPIO_BANK3_PIN_MAX
:
47 *bank_pin_num
= pin_num
- ZYNQ_GPIO_BANK3_PIN_MIN
;
50 printf("invalid GPIO pin number: %u\n", pin_num
);
57 int gpio_is_valid(unsigned gpio
)
59 return (gpio
>= 0) && (gpio
< ZYNQ_GPIO_NR_GPIOS
);
62 static int check_gpio(unsigned gpio
)
64 if (!gpio_is_valid(gpio
)) {
65 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio
);
72 * gpio_get_value - Get the state of the specified pin of GPIO device
73 * @gpio: gpio pin number within the device
75 * This function reads the state of the specified pin of the GPIO device.
77 * Return: 0 if the pin is low, 1 if pin is high.
79 int gpio_get_value(unsigned gpio
)
82 unsigned int bank_num
, bank_pin_num
;
84 if (check_gpio(gpio
) < 0)
87 zynq_gpio_get_bank_pin(gpio
, &bank_num
, &bank_pin_num
);
89 data
= readl(ZYNQ_GPIO_BASE_ADDRESS
+
90 ZYNQ_GPIO_DATA_RO_OFFSET(bank_num
));
92 return (data
>> bank_pin_num
) & 1;
96 * gpio_set_value - Modify the value of the pin with specified value
97 * @gpio: gpio pin number within the device
98 * @value: value used to modify the value of the specified pin
100 * This function calculates the register offset (i.e to lower 16 bits or
101 * upper 16 bits) based on the given pin number and sets the value of a
102 * gpio pin to the specified value. The value is either 0 or non-zero.
104 int gpio_set_value(unsigned gpio
, int value
)
106 unsigned int reg_offset
, bank_num
, bank_pin_num
;
108 if (check_gpio(gpio
) < 0)
111 zynq_gpio_get_bank_pin(gpio
, &bank_num
, &bank_pin_num
);
113 if (bank_pin_num
>= ZYNQ_GPIO_MID_PIN_NUM
) {
114 /* only 16 data bits in bit maskable reg */
115 bank_pin_num
-= ZYNQ_GPIO_MID_PIN_NUM
;
116 reg_offset
= ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num
);
118 reg_offset
= ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num
);
122 * get the 32 bit value to be written to the mask/data register where
123 * the upper 16 bits is the mask and lower 16 bits is the data
126 value
= ~(1 << (bank_pin_num
+ ZYNQ_GPIO_MID_PIN_NUM
)) &
127 ((value
<< bank_pin_num
) | ZYNQ_GPIO_UPPER_MASK
);
129 writel(value
, ZYNQ_GPIO_BASE_ADDRESS
+ reg_offset
);
135 * gpio_direction_input - Set the direction of the specified GPIO pin as input
136 * @gpio: gpio pin number within the device
138 * This function uses the read-modify-write sequence to set the direction of
139 * the gpio pin as input.
141 * Return: -1 if invalid gpio specified, 0 if successul
143 int gpio_direction_input(unsigned gpio
)
146 unsigned int bank_num
, bank_pin_num
;
148 if (check_gpio(gpio
) < 0)
151 zynq_gpio_get_bank_pin(gpio
, &bank_num
, &bank_pin_num
);
153 /* bank 0 pins 7 and 8 are special and cannot be used as inputs */
154 if (bank_num
== 0 && (bank_pin_num
== 7 || bank_pin_num
== 8))
157 /* clear the bit in direction mode reg to set the pin as input */
158 reg
= readl(ZYNQ_GPIO_BASE_ADDRESS
+ ZYNQ_GPIO_DIRM_OFFSET(bank_num
));
159 reg
&= ~BIT(bank_pin_num
);
160 writel(reg
, ZYNQ_GPIO_BASE_ADDRESS
+ ZYNQ_GPIO_DIRM_OFFSET(bank_num
));
166 * gpio_direction_output - Set the direction of the specified GPIO pin as output
167 * @gpio: gpio pin number within the device
168 * @value: value to be written to specified pin
170 * This function sets the direction of specified GPIO pin as output, configures
171 * the Output Enable register for the pin and uses zynq_gpio_set to set
172 * the value of the pin to the value specified.
176 int gpio_direction_output(unsigned gpio
, int value
)
179 unsigned int bank_num
, bank_pin_num
;
181 if (check_gpio(gpio
) < 0)
184 zynq_gpio_get_bank_pin(gpio
, &bank_num
, &bank_pin_num
);
186 /* set the GPIO pin as output */
187 reg
= readl(ZYNQ_GPIO_BASE_ADDRESS
+ ZYNQ_GPIO_DIRM_OFFSET(bank_num
));
188 reg
|= BIT(bank_pin_num
);
189 writel(reg
, ZYNQ_GPIO_BASE_ADDRESS
+ ZYNQ_GPIO_DIRM_OFFSET(bank_num
));
191 /* configure the output enable reg for the pin */
192 reg
= readl(ZYNQ_GPIO_BASE_ADDRESS
+ ZYNQ_GPIO_OUTEN_OFFSET(bank_num
));
193 reg
|= BIT(bank_pin_num
);
194 writel(reg
, ZYNQ_GPIO_BASE_ADDRESS
+ ZYNQ_GPIO_OUTEN_OFFSET(bank_num
));
196 /* set the state of the pin */
197 gpio_set_value(gpio
, value
);
202 * Request a gpio before using it.
204 * NOTE: Argument 'label' is unused.
206 int gpio_request(unsigned gpio
, const char *label
)
208 if (check_gpio(gpio
) < 0)
215 * Reset and free the gpio after using it.
217 int gpio_free(unsigned gpio
)