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