1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2013 Xilinx, Michal Simek 4 */ 5 6 #include <common.h> 7 #include <errno.h> 8 #include <malloc.h> 9 #include <linux/list.h> 10 #include <asm/io.h> 11 #include <asm/gpio.h> 12 13 static LIST_HEAD(gpio_list); 14 15 enum gpio_direction { 16 GPIO_DIRECTION_OUT = 0, 17 GPIO_DIRECTION_IN = 1, 18 }; 19 20 /* Gpio simple map */ 21 struct gpio_regs { 22 u32 gpiodata; 23 u32 gpiodir; 24 }; 25 26 #define GPIO_NAME_SIZE 10 27 28 struct gpio_names { 29 char name[GPIO_NAME_SIZE]; 30 }; 31 32 /* Initialized, rxbd_current, rx_first_buf must be 0 after init */ 33 struct xilinx_gpio_priv { 34 struct gpio_regs *regs; 35 u32 gpio_min; 36 u32 gpio_max; 37 u32 gpiodata_store; 38 char name[GPIO_NAME_SIZE]; 39 struct list_head list; 40 struct gpio_names *gpio_name; 41 }; 42 43 /* Store number of allocated gpio pins */ 44 static u32 xilinx_gpio_max; 45 46 /* Get associated gpio controller */ 47 static struct xilinx_gpio_priv *gpio_get_controller(unsigned gpio) 48 { 49 struct list_head *entry; 50 struct xilinx_gpio_priv *priv = NULL; 51 52 list_for_each(entry, &gpio_list) { 53 priv = list_entry(entry, struct xilinx_gpio_priv, list); 54 if (gpio >= priv->gpio_min && gpio <= priv->gpio_max) { 55 debug("%s: reg: %x, min-max: %d-%d\n", __func__, 56 (u32)priv->regs, priv->gpio_min, priv->gpio_max); 57 return priv; 58 } 59 } 60 puts("!!!Can't get gpio controller!!!\n"); 61 return NULL; 62 } 63 64 /* Get gpio pin name if used/setup */ 65 static char *get_name(unsigned gpio) 66 { 67 u32 gpio_priv; 68 struct xilinx_gpio_priv *priv; 69 70 debug("%s\n", __func__); 71 72 priv = gpio_get_controller(gpio); 73 if (priv) { 74 gpio_priv = gpio - priv->gpio_min; 75 76 return *priv->gpio_name[gpio_priv].name ? 77 priv->gpio_name[gpio_priv].name : "UNKNOWN"; 78 } 79 return "UNKNOWN"; 80 } 81 82 /* Get output value */ 83 static int gpio_get_output_value(unsigned gpio) 84 { 85 u32 val, gpio_priv; 86 struct xilinx_gpio_priv *priv = gpio_get_controller(gpio); 87 88 if (priv) { 89 gpio_priv = gpio - priv->gpio_min; 90 val = !!(priv->gpiodata_store & (1 << gpio_priv)); 91 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__, 92 (u32)priv->regs, gpio_priv, val); 93 94 return val; 95 } 96 return -1; 97 } 98 99 /* Get input value */ 100 static int gpio_get_input_value(unsigned gpio) 101 { 102 u32 val, gpio_priv; 103 struct gpio_regs *regs; 104 struct xilinx_gpio_priv *priv = gpio_get_controller(gpio); 105 106 if (priv) { 107 regs = priv->regs; 108 gpio_priv = gpio - priv->gpio_min; 109 val = readl(®s->gpiodata); 110 val = !!(val & (1 << gpio_priv)); 111 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__, 112 (u32)priv->regs, gpio_priv, val); 113 114 return val; 115 } 116 return -1; 117 } 118 119 /* Set gpio direction */ 120 static int gpio_set_direction(unsigned gpio, enum gpio_direction direction) 121 { 122 u32 val, gpio_priv; 123 struct gpio_regs *regs; 124 struct xilinx_gpio_priv *priv = gpio_get_controller(gpio); 125 126 if (priv) { 127 regs = priv->regs; 128 val = readl(®s->gpiodir); 129 130 gpio_priv = gpio - priv->gpio_min; 131 if (direction == GPIO_DIRECTION_OUT) 132 val &= ~(1 << gpio_priv); 133 else 134 val |= 1 << gpio_priv; 135 136 writel(val, ®s->gpiodir); 137 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__, 138 (u32)priv->regs, gpio_priv, val); 139 140 return 0; 141 } 142 143 return -1; 144 } 145 146 /* Get gpio direction */ 147 static int gpio_get_direction(unsigned gpio) 148 { 149 u32 val, gpio_priv; 150 struct gpio_regs *regs; 151 struct xilinx_gpio_priv *priv = gpio_get_controller(gpio); 152 153 if (priv) { 154 regs = priv->regs; 155 gpio_priv = gpio - priv->gpio_min; 156 val = readl(®s->gpiodir); 157 val = !!(val & (1 << gpio_priv)); 158 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__, 159 (u32)priv->regs, gpio_priv, val); 160 161 return val; 162 } 163 164 return -1; 165 } 166 167 /* 168 * Get input value 169 * for example gpio setup to output only can't get input value 170 * which is breaking gpio toggle command 171 */ 172 int gpio_get_value(unsigned gpio) 173 { 174 u32 val; 175 176 if (gpio_get_direction(gpio) == GPIO_DIRECTION_OUT) 177 val = gpio_get_output_value(gpio); 178 else 179 val = gpio_get_input_value(gpio); 180 181 return val; 182 } 183 184 /* Set output value */ 185 static int gpio_set_output_value(unsigned gpio, int value) 186 { 187 u32 val, gpio_priv; 188 struct gpio_regs *regs; 189 struct xilinx_gpio_priv *priv = gpio_get_controller(gpio); 190 191 if (priv) { 192 regs = priv->regs; 193 gpio_priv = gpio - priv->gpio_min; 194 val = priv->gpiodata_store; 195 if (value) 196 val |= 1 << gpio_priv; 197 else 198 val &= ~(1 << gpio_priv); 199 200 writel(val, ®s->gpiodata); 201 debug("%s: reg: %x, gpio_no: %d, output_val: %d\n", __func__, 202 (u32)priv->regs, gpio_priv, val); 203 priv->gpiodata_store = val; 204 205 return 0; 206 } 207 208 return -1; 209 } 210 211 int gpio_set_value(unsigned gpio, int value) 212 { 213 if (gpio_get_direction(gpio) == GPIO_DIRECTION_OUT) 214 return gpio_set_output_value(gpio, value); 215 216 return -1; 217 } 218 219 /* Set GPIO as input */ 220 int gpio_direction_input(unsigned gpio) 221 { 222 debug("%s\n", __func__); 223 return gpio_set_direction(gpio, GPIO_DIRECTION_IN); 224 } 225 226 /* Setup GPIO as output and set output value */ 227 int gpio_direction_output(unsigned gpio, int value) 228 { 229 int ret = gpio_set_direction(gpio, GPIO_DIRECTION_OUT); 230 231 debug("%s\n", __func__); 232 233 if (ret < 0) 234 return ret; 235 236 return gpio_set_output_value(gpio, value); 237 } 238 239 /* Show gpio status */ 240 void gpio_info(void) 241 { 242 unsigned gpio; 243 244 struct list_head *entry; 245 struct xilinx_gpio_priv *priv = NULL; 246 247 list_for_each(entry, &gpio_list) { 248 priv = list_entry(entry, struct xilinx_gpio_priv, list); 249 printf("\n%s: %s/%x (%d-%d)\n", __func__, priv->name, 250 (u32)priv->regs, priv->gpio_min, priv->gpio_max); 251 252 for (gpio = priv->gpio_min; gpio <= priv->gpio_max; gpio++) { 253 printf("GPIO_%d:\t%s is an ", gpio, get_name(gpio)); 254 if (gpio_get_direction(gpio) == GPIO_DIRECTION_OUT) 255 printf("OUTPUT value = %d\n", 256 gpio_get_output_value(gpio)); 257 else 258 printf("INPUT value = %d\n", 259 gpio_get_input_value(gpio)); 260 } 261 } 262 } 263 264 int gpio_request(unsigned gpio, const char *label) 265 { 266 u32 gpio_priv; 267 struct xilinx_gpio_priv *priv; 268 269 if (gpio >= xilinx_gpio_max) 270 return -EINVAL; 271 272 priv = gpio_get_controller(gpio); 273 if (priv) { 274 gpio_priv = gpio - priv->gpio_min; 275 276 if (label != NULL) { 277 strncpy(priv->gpio_name[gpio_priv].name, label, 278 GPIO_NAME_SIZE); 279 priv->gpio_name[gpio_priv].name[GPIO_NAME_SIZE - 1] = 280 '\0'; 281 } 282 return 0; 283 } 284 285 return -1; 286 } 287 288 int gpio_free(unsigned gpio) 289 { 290 u32 gpio_priv; 291 struct xilinx_gpio_priv *priv; 292 293 if (gpio >= xilinx_gpio_max) 294 return -EINVAL; 295 296 priv = gpio_get_controller(gpio); 297 if (priv) { 298 gpio_priv = gpio - priv->gpio_min; 299 priv->gpio_name[gpio_priv].name[0] = '\0'; 300 301 /* Do nothing here */ 302 return 0; 303 } 304 305 return -1; 306 } 307 308 int gpio_alloc(u32 baseaddr, const char *name, u32 gpio_no) 309 { 310 struct xilinx_gpio_priv *priv; 311 312 priv = calloc(1, sizeof(struct xilinx_gpio_priv)); 313 314 /* Setup gpio name */ 315 if (name != NULL) { 316 strncpy(priv->name, name, GPIO_NAME_SIZE); 317 priv->name[GPIO_NAME_SIZE - 1] = '\0'; 318 } 319 priv->regs = (struct gpio_regs *)baseaddr; 320 321 priv->gpio_min = xilinx_gpio_max; 322 xilinx_gpio_max = priv->gpio_min + gpio_no; 323 priv->gpio_max = xilinx_gpio_max - 1; 324 325 priv->gpio_name = calloc(gpio_no, sizeof(struct gpio_names)); 326 327 INIT_LIST_HEAD(&priv->list); 328 list_add_tail(&priv->list, &gpio_list); 329 330 printf("%s: Add %s (%d-%d)\n", __func__, name, 331 priv->gpio_min, priv->gpio_max); 332 333 /* Return the first gpio allocated for this device */ 334 return priv->gpio_min; 335 } 336 337 /* Dual channel gpio is one IP with two independent channels */ 338 int gpio_alloc_dual(u32 baseaddr, const char *name, u32 gpio_no0, u32 gpio_no1) 339 { 340 int ret; 341 342 ret = gpio_alloc(baseaddr, name, gpio_no0); 343 gpio_alloc(baseaddr + 8, strcat((char *)name, "_1"), gpio_no1); 344 345 /* Return the first gpio allocated for this device */ 346 return ret; 347 } 348