sandbox.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2011 The Chromium OS Authors.
  4. */
  5. #include <common.h>
  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_compat.h>
  14. #include <dm/lists.h>
  15. #include <dm/of.h>
  16. #include <dm/pinctrl.h>
  17. #include <dt-bindings/gpio/gpio.h>
  18. #include <dt-bindings/gpio/sandbox-gpio.h>
  19. struct gpio_state {
  20. const char *label; /* label given by requester */
  21. ulong dir_flags; /* dir_flags (GPIOD_...) */
  22. };
  23. /* Access routines for GPIO dir flags */
  24. static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
  25. {
  26. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  27. struct gpio_state *state = dev_get_priv(dev);
  28. if (offset >= uc_priv->gpio_count) {
  29. static ulong invalid_dir_flags;
  30. printf("sandbox_gpio: error: invalid gpio %u\n", offset);
  31. return &invalid_dir_flags;
  32. }
  33. return &state[offset].dir_flags;
  34. }
  35. static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
  36. {
  37. return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
  38. }
  39. static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
  40. int value)
  41. {
  42. ulong *gpio = get_gpio_dir_flags(dev, offset);
  43. if (value)
  44. *gpio |= flag;
  45. else
  46. *gpio &= ~flag;
  47. return 0;
  48. }
  49. /*
  50. * Back-channel sandbox-internal-only access to GPIO state
  51. */
  52. int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
  53. {
  54. if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
  55. debug("sandbox_gpio: get_value on output gpio %u\n", offset);
  56. return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE);
  57. }
  58. int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
  59. {
  60. return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
  61. }
  62. int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
  63. {
  64. return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
  65. }
  66. int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
  67. {
  68. set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
  69. set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
  70. return 0;
  71. }
  72. ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
  73. {
  74. return *get_gpio_dir_flags(dev, offset);
  75. }
  76. int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
  77. ulong flags)
  78. {
  79. *get_gpio_dir_flags(dev, offset) = flags;
  80. return 0;
  81. }
  82. /*
  83. * These functions implement the public interface within U-Boot
  84. */
  85. /* set GPIO port 'offset' as an input */
  86. static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
  87. {
  88. debug("%s: offset:%u\n", __func__, offset);
  89. return sandbox_gpio_set_direction(dev, offset, 0);
  90. }
  91. /* set GPIO port 'offset' as an output, with polarity 'value' */
  92. static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
  93. int value)
  94. {
  95. debug("%s: offset:%u, value = %d\n", __func__, offset, value);
  96. return sandbox_gpio_set_direction(dev, offset, 1) |
  97. sandbox_gpio_set_value(dev, offset, value);
  98. }
  99. /* read GPIO IN value of port 'offset' */
  100. static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
  101. {
  102. debug("%s: offset:%u\n", __func__, offset);
  103. return sandbox_gpio_get_value(dev, offset);
  104. }
  105. /* write GPIO OUT value to port 'offset' */
  106. static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
  107. {
  108. debug("%s: offset:%u, value = %d\n", __func__, offset, value);
  109. if (!sandbox_gpio_get_direction(dev, offset)) {
  110. printf("sandbox_gpio: error: set_value on input gpio %u\n",
  111. offset);
  112. return -1;
  113. }
  114. return sandbox_gpio_set_value(dev, offset, value);
  115. }
  116. static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
  117. {
  118. if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
  119. return GPIOF_OUTPUT;
  120. if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
  121. return GPIOF_INPUT;
  122. return GPIOF_INPUT; /*GPIO is not configurated */
  123. }
  124. static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
  125. struct ofnode_phandle_args *args)
  126. {
  127. desc->offset = args->args[0];
  128. if (args->args_count < 2)
  129. return 0;
  130. /* treat generic binding with gpio uclass */
  131. gpio_xlate_offs_flags(dev, desc, args);
  132. /* sandbox test specific, not defined in gpio.h */
  133. if (args->args[1] & GPIO_IN)
  134. desc->flags |= GPIOD_IS_IN;
  135. if (args->args[1] & GPIO_OUT)
  136. desc->flags |= GPIOD_IS_OUT;
  137. if (args->args[1] & GPIO_OUT_ACTIVE)
  138. desc->flags |= GPIOD_IS_OUT_ACTIVE;
  139. return 0;
  140. }
  141. static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
  142. ulong flags)
  143. {
  144. ulong *dir_flags;
  145. debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
  146. dir_flags = get_gpio_dir_flags(dev, offset);
  147. /*
  148. * For testing purposes keep the output value when switching to input.
  149. * This allows us to manipulate the input value via the gpio command.
  150. */
  151. if (flags & GPIOD_IS_IN)
  152. *dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
  153. (*dir_flags & GPIOD_IS_OUT_ACTIVE);
  154. else
  155. *dir_flags = flags;
  156. return 0;
  157. }
  158. static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
  159. ulong *flags)
  160. {
  161. debug("%s: offset:%u\n", __func__, offset);
  162. *flags = *get_gpio_dir_flags(dev, offset);
  163. return 0;
  164. }
  165. #if CONFIG_IS_ENABLED(ACPIGEN)
  166. static int sb_gpio_get_acpi(const struct gpio_desc *desc,
  167. struct acpi_gpio *gpio)
  168. {
  169. int ret;
  170. /* Note that gpio_get_acpi() zeroes *gpio before calling here */
  171. gpio->pin_count = 1;
  172. gpio->pins[0] = desc->offset;
  173. ret = acpi_device_scope(desc->dev, gpio->resource,
  174. sizeof(gpio->resource));
  175. if (ret)
  176. return log_ret(ret);
  177. /* All of these values are just used for testing */
  178. if (desc->flags & GPIOD_ACTIVE_LOW) {
  179. gpio->pin0_addr = 0x80012 + desc->offset;
  180. gpio->type = ACPI_GPIO_TYPE_INTERRUPT;
  181. gpio->pull = ACPI_GPIO_PULL_DOWN;
  182. gpio->interrupt_debounce_timeout = 4321;
  183. /* We use the GpioInt part */
  184. gpio->irq.pin = desc->offset;
  185. gpio->irq.polarity = ACPI_IRQ_ACTIVE_BOTH;
  186. gpio->irq.shared = ACPI_IRQ_SHARED;
  187. gpio->irq.wake = ACPI_IRQ_WAKE;
  188. /* The GpioIo part is only used for testing */
  189. gpio->polarity = ACPI_GPIO_ACTIVE_LOW;
  190. } else {
  191. gpio->pin0_addr = 0xc00dc + desc->offset;
  192. gpio->type = ACPI_GPIO_TYPE_IO;
  193. gpio->pull = ACPI_GPIO_PULL_UP;
  194. gpio->interrupt_debounce_timeout = 0;
  195. /* The GpioInt part is not used */
  196. /* We use the GpioIo part */
  197. gpio->output_drive_strength = 1234;
  198. gpio->io_shared = true;
  199. gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_INPUT;
  200. gpio->polarity = 0;
  201. }
  202. return 0;
  203. }
  204. static int sb_gpio_get_name(const struct udevice *dev, char *out_name)
  205. {
  206. return acpi_copy_name(out_name, "GPIO");
  207. }
  208. struct acpi_ops gpio_sandbox_acpi_ops = {
  209. .get_name = sb_gpio_get_name,
  210. };
  211. #endif /* ACPIGEN */
  212. static const struct dm_gpio_ops gpio_sandbox_ops = {
  213. .direction_input = sb_gpio_direction_input,
  214. .direction_output = sb_gpio_direction_output,
  215. .get_value = sb_gpio_get_value,
  216. .set_value = sb_gpio_set_value,
  217. .get_function = sb_gpio_get_function,
  218. .xlate = sb_gpio_xlate,
  219. .set_dir_flags = sb_gpio_set_dir_flags,
  220. .get_dir_flags = sb_gpio_get_dir_flags,
  221. #if CONFIG_IS_ENABLED(ACPIGEN)
  222. .get_acpi = sb_gpio_get_acpi,
  223. #endif
  224. };
  225. static int sandbox_gpio_of_to_plat(struct udevice *dev)
  226. {
  227. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  228. uc_priv->gpio_count = dev_read_u32_default(dev, "sandbox,gpio-count",
  229. 0);
  230. uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
  231. return 0;
  232. }
  233. static int gpio_sandbox_probe(struct udevice *dev)
  234. {
  235. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  236. if (!dev_of_valid(dev))
  237. /* Tell the uclass how many GPIOs we have */
  238. uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
  239. dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
  240. return 0;
  241. }
  242. static int gpio_sandbox_remove(struct udevice *dev)
  243. {
  244. free(dev->priv);
  245. return 0;
  246. }
  247. static const struct udevice_id sandbox_gpio_ids[] = {
  248. { .compatible = "sandbox,gpio" },
  249. { }
  250. };
  251. U_BOOT_DRIVER(sandbox_gpio) = {
  252. .name = "sandbox_gpio",
  253. .id = UCLASS_GPIO,
  254. .of_match = sandbox_gpio_ids,
  255. .of_to_plat = sandbox_gpio_of_to_plat,
  256. .probe = gpio_sandbox_probe,
  257. .remove = gpio_sandbox_remove,
  258. .ops = &gpio_sandbox_ops,
  259. ACPI_OPS_PTR(&gpio_sandbox_acpi_ops)
  260. };
  261. U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
  262. /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
  263. struct sb_pinctrl_priv {
  264. int pinctrl_ngpios;
  265. struct list_head gpio_dev;
  266. };
  267. struct sb_gpio_bank {
  268. struct udevice *gpio_dev;
  269. struct list_head list;
  270. };
  271. static int sb_populate_gpio_dev_list(struct udevice *dev)
  272. {
  273. struct sb_pinctrl_priv *priv = dev_get_priv(dev);
  274. struct udevice *gpio_dev;
  275. struct udevice *child;
  276. struct sb_gpio_bank *gpio_bank;
  277. int ret;
  278. /*
  279. * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
  280. * a list with all gpio device reference which belongs to the
  281. * current pin-controller. This list is used to find pin_name and
  282. * pin muxing
  283. */
  284. list_for_each_entry(child, &dev->child_head, sibling_node) {
  285. ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
  286. &gpio_dev);
  287. if (ret < 0)
  288. continue;
  289. gpio_bank = malloc(sizeof(*gpio_bank));
  290. if (!gpio_bank) {
  291. dev_err(dev, "Not enough memory\n");
  292. return -ENOMEM;
  293. }
  294. gpio_bank->gpio_dev = gpio_dev;
  295. list_add_tail(&gpio_bank->list, &priv->gpio_dev);
  296. }
  297. return 0;
  298. }
  299. static int sb_pinctrl_get_pins_count(struct udevice *dev)
  300. {
  301. struct sb_pinctrl_priv *priv = dev_get_priv(dev);
  302. struct gpio_dev_priv *uc_priv;
  303. struct sb_gpio_bank *gpio_bank;
  304. /*
  305. * if get_pins_count has already been executed once on this
  306. * pin-controller, no need to run it again
  307. */
  308. if (priv->pinctrl_ngpios)
  309. return priv->pinctrl_ngpios;
  310. if (list_empty(&priv->gpio_dev))
  311. sb_populate_gpio_dev_list(dev);
  312. /*
  313. * walk through all banks to retrieve the pin-controller
  314. * pins number
  315. */
  316. list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
  317. uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
  318. priv->pinctrl_ngpios += uc_priv->gpio_count;
  319. }
  320. return priv->pinctrl_ngpios;
  321. }
  322. static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
  323. unsigned int selector,
  324. unsigned int *idx)
  325. {
  326. struct sb_pinctrl_priv *priv = dev_get_priv(dev);
  327. struct sb_gpio_bank *gpio_bank;
  328. struct gpio_dev_priv *uc_priv;
  329. int pin_count = 0;
  330. if (list_empty(&priv->gpio_dev))
  331. sb_populate_gpio_dev_list(dev);
  332. /* look up for the bank which owns the requested pin */
  333. list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
  334. uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
  335. if (selector < (pin_count + uc_priv->gpio_count)) {
  336. /*
  337. * we found the bank, convert pin selector to
  338. * gpio bank index
  339. */
  340. *idx = selector - pin_count;
  341. return gpio_bank->gpio_dev;
  342. }
  343. pin_count += uc_priv->gpio_count;
  344. }
  345. return NULL;
  346. }
  347. static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
  348. unsigned int selector)
  349. {
  350. struct gpio_dev_priv *uc_priv;
  351. struct udevice *gpio_dev;
  352. unsigned int gpio_idx;
  353. static char pin_name[PINNAME_SIZE];
  354. /* look up for the bank which owns the requested pin */
  355. gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
  356. if (!gpio_dev) {
  357. snprintf(pin_name, PINNAME_SIZE, "Error");
  358. } else {
  359. uc_priv = dev_get_uclass_priv(gpio_dev);
  360. snprintf(pin_name, PINNAME_SIZE, "%s%d",
  361. uc_priv->bank_name,
  362. gpio_idx);
  363. }
  364. return pin_name;
  365. }
  366. static char *get_dir_flags_string(ulong flags)
  367. {
  368. if (flags & GPIOD_OPEN_DRAIN)
  369. return "drive-open-drain";
  370. if (flags & GPIOD_OPEN_SOURCE)
  371. return "drive-open-source";
  372. if (flags & GPIOD_PULL_UP)
  373. return "bias-pull-up";
  374. if (flags & GPIOD_PULL_DOWN)
  375. return "bias-pull-down";
  376. return ".";
  377. }
  378. static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
  379. unsigned int selector,
  380. char *buf, int size)
  381. {
  382. struct udevice *gpio_dev;
  383. unsigned int gpio_idx;
  384. ulong dir_flags;
  385. int function;
  386. /* look up for the bank which owns the requested pin */
  387. gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
  388. if (!gpio_dev) {
  389. snprintf(buf, size, "Error");
  390. } else {
  391. function = sb_gpio_get_function(gpio_dev, gpio_idx);
  392. dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
  393. snprintf(buf, size, "gpio %s %s",
  394. function == GPIOF_OUTPUT ? "output" : "input",
  395. get_dir_flags_string(dir_flags));
  396. }
  397. return 0;
  398. }
  399. #if CONFIG_IS_ENABLED(ACPIGEN)
  400. static int sb_pinctrl_get_name(const struct udevice *dev, char *out_name)
  401. {
  402. return acpi_copy_name(out_name, "PINC");
  403. }
  404. #endif
  405. static int sandbox_pinctrl_probe(struct udevice *dev)
  406. {
  407. struct sb_pinctrl_priv *priv = dev_get_priv(dev);
  408. INIT_LIST_HEAD(&priv->gpio_dev);
  409. return 0;
  410. }
  411. static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
  412. .get_pin_name = sb_pinctrl_get_pin_name,
  413. .get_pins_count = sb_pinctrl_get_pins_count,
  414. .get_pin_muxing = sb_pinctrl_get_pin_muxing,
  415. };
  416. #if CONFIG_IS_ENABLED(ACPIGEN)
  417. struct acpi_ops pinctrl_sandbox_acpi_ops = {
  418. .get_name = sb_pinctrl_get_name,
  419. };
  420. #endif
  421. static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
  422. { .compatible = "sandbox,pinctrl-gpio" },
  423. { /* sentinel */ }
  424. };
  425. U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
  426. .name = "sandbox_pinctrl_gpio",
  427. .id = UCLASS_PINCTRL,
  428. .of_match = sandbox_pinctrl_gpio_match,
  429. .ops = &sandbox_pinctrl_gpio_ops,
  430. .bind = dm_scan_fdt_dev,
  431. .probe = sandbox_pinctrl_probe,
  432. .priv_auto = sizeof(struct sb_pinctrl_priv),
  433. ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)
  434. };