1 /* 2 * Copyright (c) 2013 Google, Inc 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <asm/gpio.h> 11 #include <linux/ctype.h> 12 13 /** 14 * gpio_to_device() - Convert global GPIO number to device, number 15 * gpio: The numeric representation of the GPIO 16 * 17 * Convert the GPIO number to an entry in the list of GPIOs 18 * or GPIO blocks registered with the GPIO controller. Returns 19 * entry on success, NULL on error. 20 */ 21 static int gpio_to_device(unsigned int gpio, struct udevice **devp, 22 unsigned int *offset) 23 { 24 struct gpio_dev_priv *uc_priv; 25 struct udevice *dev; 26 int ret; 27 28 for (ret = uclass_first_device(UCLASS_GPIO, &dev); 29 dev; 30 ret = uclass_next_device(&dev)) { 31 uc_priv = dev->uclass_priv; 32 if (gpio >= uc_priv->gpio_base && 33 gpio < uc_priv->gpio_base + uc_priv->gpio_count) { 34 *devp = dev; 35 *offset = gpio - uc_priv->gpio_base; 36 return 0; 37 } 38 } 39 40 /* No such GPIO */ 41 return ret ? ret : -EINVAL; 42 } 43 44 int gpio_lookup_name(const char *name, struct udevice **devp, 45 unsigned int *offsetp, unsigned int *gpiop) 46 { 47 struct gpio_dev_priv *uc_priv = NULL; 48 struct udevice *dev; 49 ulong offset; 50 int numeric; 51 int ret; 52 53 if (devp) 54 *devp = NULL; 55 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1; 56 for (ret = uclass_first_device(UCLASS_GPIO, &dev); 57 dev; 58 ret = uclass_next_device(&dev)) { 59 int len; 60 61 uc_priv = dev->uclass_priv; 62 if (numeric != -1) { 63 offset = numeric - uc_priv->gpio_base; 64 /* Allow GPIOs to be numbered from 0 */ 65 if (offset >= 0 && offset < uc_priv->gpio_count) 66 break; 67 } 68 69 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0; 70 71 if (!strncasecmp(name, uc_priv->bank_name, len)) { 72 if (!strict_strtoul(name + len, 10, &offset)) 73 break; 74 } 75 } 76 77 if (!dev) 78 return ret ? ret : -EINVAL; 79 80 if (devp) 81 *devp = dev; 82 if (offsetp) 83 *offsetp = offset; 84 if (gpiop) 85 *gpiop = uc_priv->gpio_base + offset; 86 87 return 0; 88 } 89 90 /** 91 * gpio_request() - [COMPAT] Request GPIO 92 * gpio: GPIO number 93 * label: Name for the requested GPIO 94 * 95 * This function implements the API that's compatible with current 96 * GPIO API used in U-Boot. The request is forwarded to particular 97 * GPIO driver. Returns 0 on success, negative value on error. 98 */ 99 int gpio_request(unsigned gpio, const char *label) 100 { 101 unsigned int offset; 102 struct udevice *dev; 103 int ret; 104 105 ret = gpio_to_device(gpio, &dev, &offset); 106 if (ret) 107 return ret; 108 109 if (!gpio_get_ops(dev)->request) 110 return 0; 111 112 return gpio_get_ops(dev)->request(dev, offset, label); 113 } 114 115 /** 116 * gpio_free() - [COMPAT] Relinquish GPIO 117 * gpio: GPIO number 118 * 119 * This function implements the API that's compatible with current 120 * GPIO API used in U-Boot. The request is forwarded to particular 121 * GPIO driver. Returns 0 on success, negative value on error. 122 */ 123 int gpio_free(unsigned gpio) 124 { 125 unsigned int offset; 126 struct udevice *dev; 127 int ret; 128 129 ret = gpio_to_device(gpio, &dev, &offset); 130 if (ret) 131 return ret; 132 133 if (!gpio_get_ops(dev)->free) 134 return 0; 135 return gpio_get_ops(dev)->free(dev, offset); 136 } 137 138 /** 139 * gpio_direction_input() - [COMPAT] Set GPIO direction to input 140 * gpio: GPIO number 141 * 142 * This function implements the API that's compatible with current 143 * GPIO API used in U-Boot. The request is forwarded to particular 144 * GPIO driver. Returns 0 on success, negative value on error. 145 */ 146 int gpio_direction_input(unsigned gpio) 147 { 148 unsigned int offset; 149 struct udevice *dev; 150 int ret; 151 152 ret = gpio_to_device(gpio, &dev, &offset); 153 if (ret) 154 return ret; 155 156 return gpio_get_ops(dev)->direction_input(dev, offset); 157 } 158 159 /** 160 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value 161 * gpio: GPIO number 162 * value: Logical value to be set on the GPIO pin 163 * 164 * This function implements the API that's compatible with current 165 * GPIO API used in U-Boot. The request is forwarded to particular 166 * GPIO driver. Returns 0 on success, negative value on error. 167 */ 168 int gpio_direction_output(unsigned gpio, int value) 169 { 170 unsigned int offset; 171 struct udevice *dev; 172 int ret; 173 174 ret = gpio_to_device(gpio, &dev, &offset); 175 if (ret) 176 return ret; 177 178 return gpio_get_ops(dev)->direction_output(dev, offset, value); 179 } 180 181 /** 182 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value 183 * gpio: GPIO number 184 * 185 * This function implements the API that's compatible with current 186 * GPIO API used in U-Boot. The request is forwarded to particular 187 * GPIO driver. Returns the value of the GPIO pin, or negative value 188 * on error. 189 */ 190 int gpio_get_value(unsigned gpio) 191 { 192 unsigned int offset; 193 struct udevice *dev; 194 int ret; 195 196 ret = gpio_to_device(gpio, &dev, &offset); 197 if (ret) 198 return ret; 199 200 return gpio_get_ops(dev)->get_value(dev, offset); 201 } 202 203 /** 204 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin 205 * gpio: GPIO number 206 * value: Logical value to be set on the GPIO pin. 207 * 208 * This function implements the API that's compatible with current 209 * GPIO API used in U-Boot. The request is forwarded to particular 210 * GPIO driver. Returns 0 on success, negative value on error. 211 */ 212 int gpio_set_value(unsigned gpio, int value) 213 { 214 unsigned int offset; 215 struct udevice *dev; 216 int ret; 217 218 ret = gpio_to_device(gpio, &dev, &offset); 219 if (ret) 220 return ret; 221 222 return gpio_get_ops(dev)->set_value(dev, offset, value); 223 } 224 225 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) 226 { 227 struct gpio_dev_priv *priv; 228 229 /* Must be called on an active device */ 230 priv = dev->uclass_priv; 231 assert(priv); 232 233 *bit_count = priv->gpio_count; 234 return priv->bank_name; 235 } 236 237 /* We need to renumber the GPIOs when any driver is probed/removed */ 238 static int gpio_renumber(void) 239 { 240 struct gpio_dev_priv *uc_priv; 241 struct udevice *dev; 242 struct uclass *uc; 243 unsigned base; 244 int ret; 245 246 ret = uclass_get(UCLASS_GPIO, &uc); 247 if (ret) 248 return ret; 249 250 /* Ensure that we have a base for each bank */ 251 base = 0; 252 uclass_foreach_dev(dev, uc) { 253 if (device_active(dev)) { 254 uc_priv = dev->uclass_priv; 255 uc_priv->gpio_base = base; 256 base += uc_priv->gpio_count; 257 } 258 } 259 260 return 0; 261 } 262 263 static int gpio_post_probe(struct udevice *dev) 264 { 265 return gpio_renumber(); 266 } 267 268 static int gpio_pre_remove(struct udevice *dev) 269 { 270 return gpio_renumber(); 271 } 272 273 UCLASS_DRIVER(gpio) = { 274 .id = UCLASS_GPIO, 275 .name = "gpio", 276 .post_probe = gpio_post_probe, 277 .pre_remove = gpio_pre_remove, 278 .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv), 279 }; 280