misc_sandbox.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2018
  4. * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <misc.h>
  9. struct misc_sandbox_priv {
  10. u8 mem[128];
  11. ulong last_ioctl;
  12. bool enabled;
  13. };
  14. int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size)
  15. {
  16. struct misc_sandbox_priv *priv = dev_get_priv(dev);
  17. memcpy(buf, priv->mem + offset, size);
  18. return size;
  19. }
  20. int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,
  21. int size)
  22. {
  23. struct misc_sandbox_priv *priv = dev_get_priv(dev);
  24. memcpy(priv->mem + offset, buf, size);
  25. return size;
  26. }
  27. int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf)
  28. {
  29. struct misc_sandbox_priv *priv = dev_get_priv(dev);
  30. priv->last_ioctl = request;
  31. return 0;
  32. }
  33. int misc_sandbox_call(struct udevice *dev, int msgid, void *tx_msg,
  34. int tx_size, void *rx_msg, int rx_size)
  35. {
  36. struct misc_sandbox_priv *priv = dev_get_priv(dev);
  37. if (msgid == 0) {
  38. int num = *(int *)tx_msg;
  39. switch (num) {
  40. case 0:
  41. strncpy(rx_msg, "Zero", rx_size);
  42. break;
  43. case 1:
  44. strncpy(rx_msg, "One", rx_size);
  45. break;
  46. case 2:
  47. strncpy(rx_msg, "Two", rx_size);
  48. break;
  49. default:
  50. return -EINVAL;
  51. }
  52. }
  53. if (msgid == 1) {
  54. int num = *(int *)tx_msg;
  55. switch (num) {
  56. case 0:
  57. strncpy(rx_msg, "Forty", rx_size);
  58. break;
  59. case 1:
  60. strncpy(rx_msg, "Forty-one", rx_size);
  61. break;
  62. case 2:
  63. strncpy(rx_msg, "Forty-two", rx_size);
  64. break;
  65. default:
  66. return -EINVAL;
  67. }
  68. }
  69. if (msgid == 2)
  70. memcpy(rx_msg, &priv->last_ioctl, sizeof(priv->last_ioctl));
  71. if (msgid == 3)
  72. memcpy(rx_msg, &priv->enabled, sizeof(priv->enabled));
  73. return 0;
  74. }
  75. int misc_sandbox_set_enabled(struct udevice *dev, bool val)
  76. {
  77. struct misc_sandbox_priv *priv = dev_get_priv(dev);
  78. priv->enabled = !priv->enabled;
  79. return 0;
  80. }
  81. static const struct misc_ops misc_sandbox_ops = {
  82. .read = misc_sandbox_read,
  83. .write = misc_sandbox_write,
  84. .ioctl = misc_sandbox_ioctl,
  85. .call = misc_sandbox_call,
  86. .set_enabled = misc_sandbox_set_enabled,
  87. };
  88. int misc_sandbox_probe(struct udevice *dev)
  89. {
  90. struct misc_sandbox_priv *priv = dev_get_priv(dev);
  91. priv->enabled = true;
  92. return 0;
  93. }
  94. static const struct udevice_id misc_sandbox_ids[] = {
  95. { .compatible = "sandbox,misc_sandbox" },
  96. { }
  97. };
  98. U_BOOT_DRIVER(misc_sandbox) = {
  99. .name = "misc_sandbox",
  100. .id = UCLASS_MISC,
  101. .ops = &misc_sandbox_ops,
  102. .of_match = misc_sandbox_ids,
  103. .probe = misc_sandbox_probe,
  104. .priv_auto_alloc_size = sizeof(struct misc_sandbox_priv),
  105. };