1 /* 2 * Xilinx Zynq GPIO device driver 3 * 4 * Copyright (C) 2015 DAVE Embedded Systems <devel@dave.eu> 5 * 6 * Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c) 7 * Copyright (C) 2009 - 2014 Xilinx, Inc. 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 #include <common.h> 13 #include <asm/gpio.h> 14 #include <asm/io.h> 15 #include <asm/errno.h> 16 17 /** 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 22 * pin 23 * @bank_pin_num: an output parameter used to return pin number within a bank 24 * for the given gpio pin 25 * 26 * Returns the bank number and pin offset within the bank. 27 */ 28 static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, 29 unsigned int *bank_num, 30 unsigned int *bank_pin_num) 31 { 32 switch (pin_num) { 33 case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX: 34 *bank_num = 0; 35 *bank_pin_num = pin_num; 36 break; 37 case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX: 38 *bank_num = 1; 39 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN; 40 break; 41 case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX: 42 *bank_num = 2; 43 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN; 44 break; 45 case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX: 46 *bank_num = 3; 47 *bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN; 48 break; 49 default: 50 printf("invalid GPIO pin number: %u\n", pin_num); 51 *bank_num = 0; 52 *bank_pin_num = 0; 53 break; 54 } 55 } 56 57 int gpio_is_valid(unsigned gpio) 58 { 59 return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS); 60 } 61 62 static int check_gpio(unsigned gpio) 63 { 64 if (!gpio_is_valid(gpio)) { 65 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); 66 return -1; 67 } 68 return 0; 69 } 70 71 /** 72 * gpio_get_value - Get the state of the specified pin of GPIO device 73 * @gpio: gpio pin number within the device 74 * 75 * This function reads the state of the specified pin of the GPIO device. 76 * 77 * Return: 0 if the pin is low, 1 if pin is high. 78 */ 79 int gpio_get_value(unsigned gpio) 80 { 81 u32 data; 82 unsigned int bank_num, bank_pin_num; 83 84 if (check_gpio(gpio) < 0) 85 return -1; 86 87 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); 88 89 data = readl(ZYNQ_GPIO_BASE_ADDRESS + 90 ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); 91 92 return (data >> bank_pin_num) & 1; 93 } 94 95 /** 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 99 * 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. 103 */ 104 int gpio_set_value(unsigned gpio, int value) 105 { 106 unsigned int reg_offset, bank_num, bank_pin_num; 107 108 if (check_gpio(gpio) < 0) 109 return -1; 110 111 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); 112 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); 117 } else { 118 reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); 119 } 120 121 /* 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 124 */ 125 value = !!value; 126 value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & 127 ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); 128 129 writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset); 130 131 return 0; 132 } 133 134 /** 135 * gpio_direction_input - Set the direction of the specified GPIO pin as input 136 * @gpio: gpio pin number within the device 137 * 138 * This function uses the read-modify-write sequence to set the direction of 139 * the gpio pin as input. 140 * 141 * Return: -1 if invalid gpio specified, 0 if successul 142 */ 143 int gpio_direction_input(unsigned gpio) 144 { 145 u32 reg; 146 unsigned int bank_num, bank_pin_num; 147 148 if (check_gpio(gpio) < 0) 149 return -1; 150 151 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); 152 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)) 155 return -1; 156 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)); 161 162 return 0; 163 } 164 165 /** 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 169 * 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. 173 * 174 * Return: 0 always 175 */ 176 int gpio_direction_output(unsigned gpio, int value) 177 { 178 u32 reg; 179 unsigned int bank_num, bank_pin_num; 180 181 if (check_gpio(gpio) < 0) 182 return -1; 183 184 zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); 185 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)); 190 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)); 195 196 /* set the state of the pin */ 197 gpio_set_value(gpio, value); 198 return 0; 199 } 200 201 /** 202 * Request a gpio before using it. 203 * 204 * NOTE: Argument 'label' is unused. 205 */ 206 int gpio_request(unsigned gpio, const char *label) 207 { 208 if (check_gpio(gpio) < 0) 209 return -1; 210 211 return 0; 212 } 213 214 /** 215 * Reset and free the gpio after using it. 216 */ 217 int gpio_free(unsigned gpio) 218 { 219 return 0; 220 } 221