1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2011 The Chromium OS Authors. 4 */ 5 6#include <dm.h> 7#include <fdtdec.h> 8#include <log.h> 9#include <malloc.h> 10#include <acpi/acpi_device.h> 11#include <asm/gpio.h> 12#include <dm/acpi.h> 13#include <dm/device-internal.h> 14#include <dm/device_compat.h> 15#include <dm/lists.h> 16#include <dm/of.h> 17#include <dm/pinctrl.h> 18#include <dt-bindings/gpio/gpio.h> 19#include <dt-bindings/gpio/sandbox-gpio.h> 20 21struct gpio_state { 22 const char *label; /* label given by requester */ 23 ulong flags; /* flags (GPIOD_...) */ 24}; 25 26/* Access routines for GPIO info */ 27static struct gpio_state *get_gpio_state(struct udevice *dev, uint offset) 28{ 29 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 30 struct gpio_state *state = dev_get_priv(dev); 31 32 if (offset >= uc_priv->gpio_count) { 33 printf("sandbox_gpio: error: invalid gpio %u\n", offset); 34 return NULL; 35 } 36 37 return &state[offset]; 38} 39 40/* Access routines for GPIO flags */ 41static ulong *get_gpio_flags(struct udevice *dev, unsigned int offset) 42{ 43 struct gpio_state *state = get_gpio_state(dev, offset); 44 45 if (!state) 46 return NULL; 47 48 return &state->flags; 49 50} 51 52static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag) 53{ 54 return (*get_gpio_flags(dev, offset) & flag) != 0; 55} 56 57static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag, 58 int value) 59{ 60 struct gpio_state *state = get_gpio_state(dev, offset); 61 62 if (value) 63 state->flags |= flag; 64 else 65 state->flags &= ~flag; 66 67 return 0; 68} 69 70/* 71 * Back-channel sandbox-internal-only access to GPIO state 72 */ 73 74int sandbox_gpio_get_value(struct udevice *dev, unsigned offset) 75{ 76 struct gpio_state *state = get_gpio_state(dev, offset); 77 bool val; 78 79 if (get_gpio_flag(dev, offset, GPIOD_IS_OUT)) 80 debug("sandbox_gpio: get_value on output gpio %u\n", offset); 81 82 if (state->flags & GPIOD_EXT_DRIVEN) { 83 val = state->flags & GPIOD_EXT_HIGH; 84 } else { 85 if (state->flags & GPIOD_EXT_PULL_UP) 86 val = true; 87 else if (state->flags & GPIOD_EXT_PULL_DOWN) 88 val = false; 89 else 90 val = state->flags & GPIOD_PULL_UP; 91 } 92 93 return val; 94} 95 96int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value) 97{ 98 set_gpio_flag(dev, offset, GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value); 99 100 return 0; 101} 102 103int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset) 104{ 105 return get_gpio_flag(dev, offset, GPIOD_IS_OUT); 106} 107 108int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output) 109{ 110 set_gpio_flag(dev, offset, GPIOD_IS_OUT, output); 111 set_gpio_flag(dev, offset, GPIOD_IS_IN, !output); 112 113 return 0; 114} 115 116ulong sandbox_gpio_get_flags(struct udevice *dev, uint offset) 117{ 118 ulong flags = *get_gpio_flags(dev, offset); 119 120 return flags & ~GPIOD_SANDBOX_MASK; 121} 122 123int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags) 124{ 125 struct gpio_state *state = get_gpio_state(dev, offset); 126 127 state->flags = flags; 128 129 return 0; 130} 131 132/* 133 * These functions implement the public interface within U-Boot 134 */ 135 136/* set GPIO port 'offset' as an input */ 137static int sb_gpio_direction_input(struct udevice *dev, unsigned offset) 138{ 139 debug("%s: offset:%u\n", __func__, offset); 140 141 return sandbox_gpio_set_direction(dev, offset, 0); 142} 143 144/* set GPIO port 'offset' as an output, with polarity 'value' */ 145static int sb_gpio_direction_output(struct udevice *dev, unsigned offset, 146 int value) 147{ 148 int ret; 149 150 debug("%s: offset:%u, value = %d\n", __func__, offset, value); 151 152 ret = sandbox_gpio_set_direction(dev, offset, 1); 153 if (ret) 154 return ret; 155 ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | 156 GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value); 157 if (ret) 158 return ret; 159 160 return 0; 161} 162 163/* read GPIO IN value of port 'offset' */ 164static int sb_gpio_get_value(struct udevice *dev, unsigned offset) 165{ 166 debug("%s: offset:%u\n", __func__, offset); 167 168 return sandbox_gpio_get_value(dev, offset); 169} 170 171/* write GPIO OUT value to port 'offset' */ 172static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value) 173{ 174 int ret; 175 176 debug("%s: offset:%u, value = %d\n", __func__, offset, value); 177 178 if (!sandbox_gpio_get_direction(dev, offset)) { 179 printf("sandbox_gpio: error: set_value on input gpio %u\n", 180 offset); 181 return -1; 182 } 183 184 ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | 185 GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value); 186 if (ret) 187 return ret; 188 189 return 0; 190} 191 192static int sb_gpio_get_function(struct udevice *dev, unsigned offset) 193{ 194 if (get_gpio_flag(dev, offset, GPIOD_IS_OUT)) 195 return GPIOF_OUTPUT; 196 if (get_gpio_flag(dev, offset, GPIOD_IS_IN)) 197 return GPIOF_INPUT; 198 if (get_gpio_flag(dev, offset, GPIOD_IS_AF)) 199 return GPIOF_FUNC; 200 201 return GPIOF_INPUT; /*GPIO is not configurated */ 202} 203 204static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, 205 struct ofnode_phandle_args *args) 206{ 207 desc->offset = args->args[0]; 208 if (args->args_count < 2) 209 return 0; 210 /* treat generic binding with gpio uclass */ 211 gpio_xlate_offs_flags(dev, desc, args); 212 213 /* sandbox test specific, not defined in gpio.h */ 214 if (args->args[1] & GPIO_IN) 215 desc->flags |= GPIOD_IS_IN; 216 217 if (args->args[1] & GPIO_OUT) 218 desc->flags |= GPIOD_IS_OUT; 219 220 if (args->args[1] & GPIO_OUT_ACTIVE) 221 desc->flags |= GPIOD_IS_OUT_ACTIVE; 222 223 if (args->args[1] & GPIO_AF) 224 desc->flags |= GPIOD_IS_AF; 225 226 return 0; 227} 228 229static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset, 230 ulong flags) 231{ 232 debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags); 233 struct gpio_state *state = get_gpio_state(dev, offset); 234 235 if (flags & GPIOD_IS_OUT) { 236 flags |= GPIOD_EXT_DRIVEN; 237 if (flags & GPIOD_IS_OUT_ACTIVE) 238 flags |= GPIOD_EXT_HIGH; 239 else 240 flags &= ~GPIOD_EXT_HIGH; 241 } else { 242 flags |= state->flags & GPIOD_SANDBOX_MASK; 243 } 244 state->flags = flags; 245 246 return 0; 247} 248 249static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp) 250{ 251 debug("%s: offset:%u\n", __func__, offset); 252 *flagsp = *get_gpio_flags(dev, offset) & ~GPIOD_SANDBOX_MASK; 253 254 return 0; 255} 256 257#if CONFIG_IS_ENABLED(ACPIGEN) 258static int sb_gpio_get_acpi(const struct gpio_desc *desc, 259 struct acpi_gpio *gpio) 260{ 261 int ret; 262 263 /* Note that gpio_get_acpi() zeroes *gpio before calling here */ 264 gpio->pin_count = 1; 265 gpio->pins[0] = desc->offset; 266 ret = acpi_device_scope(desc->dev, gpio->resource, 267 sizeof(gpio->resource)); 268 if (ret) 269 return log_ret(ret); 270 271 /* All of these values are just used for testing */ 272 if (desc->flags & GPIOD_ACTIVE_LOW) { 273 gpio->pin0_addr = 0x80012 + desc->offset; 274 gpio->type = ACPI_GPIO_TYPE_INTERRUPT; 275 gpio->pull = ACPI_GPIO_PULL_DOWN; 276 gpio->interrupt_debounce_timeout = 4321; 277 278 /* We use the GpioInt part */ 279 gpio->irq.pin = desc->offset; 280 gpio->irq.polarity = ACPI_IRQ_ACTIVE_BOTH; 281 gpio->irq.shared = ACPI_IRQ_SHARED; 282 gpio->irq.wake = ACPI_IRQ_WAKE; 283 284 /* The GpioIo part is only used for testing */ 285 gpio->polarity = ACPI_GPIO_ACTIVE_LOW; 286 } else { 287 gpio->pin0_addr = 0xc00dc + desc->offset; 288 gpio->type = ACPI_GPIO_TYPE_IO; 289 gpio->pull = ACPI_GPIO_PULL_UP; 290 gpio->interrupt_debounce_timeout = 0; 291 292 /* The GpioInt part is not used */ 293 294 /* We use the GpioIo part */ 295 gpio->output_drive_strength = 1234; 296 gpio->io_shared = true; 297 gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_INPUT; 298 gpio->polarity = 0; 299 } 300 301 return 0; 302} 303 304static int sb_gpio_get_name(const struct udevice *dev, char *out_name) 305{ 306 return acpi_copy_name(out_name, "GPIO"); 307} 308 309struct acpi_ops gpio_sandbox_acpi_ops = { 310 .get_name = sb_gpio_get_name, 311}; 312#endif /* ACPIGEN */ 313 314static const struct dm_gpio_ops gpio_sandbox_ops = { 315 .direction_input = sb_gpio_direction_input, 316 .direction_output = sb_gpio_direction_output, 317 .get_value = sb_gpio_get_value, 318 .set_value = sb_gpio_set_value, 319 .get_function = sb_gpio_get_function, 320 .xlate = sb_gpio_xlate, 321 .set_flags = sb_gpio_set_flags, 322 .get_flags = sb_gpio_get_flags, 323#if CONFIG_IS_ENABLED(ACPIGEN) 324 .get_acpi = sb_gpio_get_acpi, 325#endif 326}; 327 328static int sandbox_gpio_of_to_plat(struct udevice *dev) 329{ 330 if (CONFIG_IS_ENABLED(OF_REAL)) { 331 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 332 333 uc_priv->gpio_count = 334 dev_read_u32_default(dev, "sandbox,gpio-count", 0); 335 uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); 336 } 337 338 return 0; 339} 340 341static int gpio_sandbox_probe(struct udevice *dev) 342{ 343 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 344 345 if (!dev_has_ofnode(dev)) 346 /* Tell the uclass how many GPIOs we have */ 347 uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT; 348 349 dev_set_priv(dev, 350 calloc(sizeof(struct gpio_state), uc_priv->gpio_count)); 351 352 return 0; 353} 354 355static int gpio_sandbox_remove(struct udevice *dev) 356{ 357 free(dev_get_priv(dev)); 358 359 return 0; 360} 361 362static const struct udevice_id sandbox_gpio_ids[] = { 363 { .compatible = "sandbox,gpio" }, 364 { } 365}; 366 367U_BOOT_DRIVER(sandbox_gpio) = { 368 .name = "sandbox_gpio", 369 .id = UCLASS_GPIO, 370 .of_match = sandbox_gpio_ids, 371 .of_to_plat = sandbox_gpio_of_to_plat, 372 .probe = gpio_sandbox_probe, 373 .remove = gpio_sandbox_remove, 374 .ops = &gpio_sandbox_ops, 375 ACPI_OPS_PTR(&gpio_sandbox_acpi_ops) 376}; 377 378DM_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias) 379 380#if CONFIG_IS_ENABLED(PINCTRL) 381 382/* pincontrol: used only to check GPIO pin configuration (pinmux command) */ 383 384struct sb_pinctrl_priv { 385 int pinctrl_ngpios; 386 struct list_head gpio_dev; 387}; 388 389struct sb_gpio_bank { 390 struct udevice *gpio_dev; 391 struct list_head list; 392}; 393 394static int sb_populate_gpio_dev_list(struct udevice *dev) 395{ 396 struct sb_pinctrl_priv *priv = dev_get_priv(dev); 397 struct udevice *gpio_dev; 398 struct udevice *child; 399 struct sb_gpio_bank *gpio_bank; 400 int ret; 401 402 /* 403 * parse pin-controller sub-nodes (ie gpio bank nodes) and fill 404 * a list with all gpio device reference which belongs to the 405 * current pin-controller. This list is used to find pin_name and 406 * pin muxing 407 */ 408 list_for_each_entry(child, &dev->child_head, sibling_node) { 409 ret = uclass_get_device_by_name(UCLASS_GPIO, child->name, 410 &gpio_dev); 411 if (ret < 0) 412 continue; 413 414 gpio_bank = malloc(sizeof(*gpio_bank)); 415 if (!gpio_bank) { 416 dev_err(dev, "Not enough memory\n"); 417 return -ENOMEM; 418 } 419 420 gpio_bank->gpio_dev = gpio_dev; 421 list_add_tail(&gpio_bank->list, &priv->gpio_dev); 422 } 423 424 return 0; 425} 426 427static int sb_pinctrl_get_pins_count(struct udevice *dev) 428{ 429 struct sb_pinctrl_priv *priv = dev_get_priv(dev); 430 struct gpio_dev_priv *uc_priv; 431 struct sb_gpio_bank *gpio_bank; 432 433 /* 434 * if get_pins_count has already been executed once on this 435 * pin-controller, no need to run it again 436 */ 437 if (priv->pinctrl_ngpios) 438 return priv->pinctrl_ngpios; 439 440 if (list_empty(&priv->gpio_dev)) 441 sb_populate_gpio_dev_list(dev); 442 /* 443 * walk through all banks to retrieve the pin-controller 444 * pins number 445 */ 446 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { 447 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); 448 449 priv->pinctrl_ngpios += uc_priv->gpio_count; 450 } 451 452 return priv->pinctrl_ngpios; 453} 454 455static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev, 456 unsigned int selector, 457 unsigned int *idx) 458{ 459 struct sb_pinctrl_priv *priv = dev_get_priv(dev); 460 struct sb_gpio_bank *gpio_bank; 461 struct gpio_dev_priv *uc_priv; 462 int pin_count = 0; 463 464 if (list_empty(&priv->gpio_dev)) 465 sb_populate_gpio_dev_list(dev); 466 467 /* look up for the bank which owns the requested pin */ 468 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { 469 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); 470 471 if (selector < (pin_count + uc_priv->gpio_count)) { 472 /* 473 * we found the bank, convert pin selector to 474 * gpio bank index 475 */ 476 *idx = selector - pin_count; 477 478 return gpio_bank->gpio_dev; 479 } 480 pin_count += uc_priv->gpio_count; 481 } 482 483 return NULL; 484} 485 486static const char *sb_pinctrl_get_pin_name(struct udevice *dev, 487 unsigned int selector) 488{ 489 struct gpio_dev_priv *uc_priv; 490 struct udevice *gpio_dev; 491 unsigned int gpio_idx; 492 static char pin_name[PINNAME_SIZE]; 493 494 /* look up for the bank which owns the requested pin */ 495 gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); 496 if (!gpio_dev) { 497 snprintf(pin_name, PINNAME_SIZE, "Error"); 498 } else { 499 uc_priv = dev_get_uclass_priv(gpio_dev); 500 501 snprintf(pin_name, PINNAME_SIZE, "%s%d", 502 uc_priv->bank_name, 503 gpio_idx); 504 } 505 506 return pin_name; 507} 508 509static char *get_flags_string(ulong flags) 510{ 511 if (flags & GPIOD_OPEN_DRAIN) 512 return "drive-open-drain"; 513 if (flags & GPIOD_OPEN_SOURCE) 514 return "drive-open-source"; 515 if (flags & GPIOD_PULL_UP) 516 return "bias-pull-up"; 517 if (flags & GPIOD_PULL_DOWN) 518 return "bias-pull-down"; 519 return "."; 520} 521 522static int sb_pinctrl_get_pin_muxing(struct udevice *dev, 523 unsigned int selector, 524 char *buf, int size) 525{ 526 struct udevice *gpio_dev; 527 unsigned int gpio_idx; 528 ulong flags; 529 int function; 530 531 /* look up for the bank which owns the requested pin */ 532 gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); 533 if (!gpio_dev) { 534 snprintf(buf, size, "Error"); 535 } else { 536 function = sb_gpio_get_function(gpio_dev, gpio_idx); 537 flags = *get_gpio_flags(gpio_dev, gpio_idx); 538 539 snprintf(buf, size, "gpio %s %s", 540 function == GPIOF_OUTPUT ? "output" : "input", 541 get_flags_string(flags)); 542 } 543 544 return 0; 545} 546 547#if CONFIG_IS_ENABLED(ACPIGEN) 548static int sb_pinctrl_get_name(const struct udevice *dev, char *out_name) 549{ 550 return acpi_copy_name(out_name, "PINC"); 551} 552#endif 553 554static int sandbox_pinctrl_probe(struct udevice *dev) 555{ 556 struct sb_pinctrl_priv *priv = dev_get_priv(dev); 557 558 INIT_LIST_HEAD(&priv->gpio_dev); 559 560 return 0; 561} 562 563static struct pinctrl_ops sandbox_pinctrl_gpio_ops = { 564 .get_pin_name = sb_pinctrl_get_pin_name, 565 .get_pins_count = sb_pinctrl_get_pins_count, 566 .get_pin_muxing = sb_pinctrl_get_pin_muxing, 567}; 568 569#if CONFIG_IS_ENABLED(ACPIGEN) 570struct acpi_ops pinctrl_sandbox_acpi_ops = { 571 .get_name = sb_pinctrl_get_name, 572}; 573#endif 574 575static const struct udevice_id sandbox_pinctrl_gpio_match[] = { 576 { .compatible = "sandbox,pinctrl-gpio" }, 577 { /* sentinel */ } 578}; 579 580U_BOOT_DRIVER(sandbox_pinctrl_gpio) = { 581 .name = "sandbox_pinctrl_gpio", 582 .id = UCLASS_PINCTRL, 583 .of_match = sandbox_pinctrl_gpio_match, 584 .ops = &sandbox_pinctrl_gpio_ops, 585 .bind = dm_scan_fdt_dev, 586 .probe = sandbox_pinctrl_probe, 587 .priv_auto = sizeof(struct sb_pinctrl_priv), 588 ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops) 589}; 590 591#endif /* PINCTRL */ 592