sandbox.c 13 KB

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