demo-shape.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright (c) 2013 Google, Inc
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <fdtdec.h>
  10. #include <malloc.h>
  11. #include <dm-demo.h>
  12. #include <asm/io.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. /* Shape size */
  15. #define WIDTH 8
  16. #define HEIGHT 6
  17. struct shape_data {
  18. int num_chars; /* Number of non-space characters output so far */
  19. };
  20. /* Crazy little function to draw shapes on the console */
  21. static int shape_hello(struct udevice *dev, int ch)
  22. {
  23. const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
  24. struct shape_data *data = dev_get_priv(dev);
  25. static const struct shape {
  26. int start;
  27. int end;
  28. int dstart;
  29. int dend;
  30. } shapes[3] = {
  31. { 0, 1, 0, 1 },
  32. { 0, WIDTH, 0, 0 },
  33. { HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
  34. };
  35. struct shape shape;
  36. unsigned int index;
  37. int line, pos, inside;
  38. const char *colour = pdata->colour;
  39. int first = 0;
  40. if (!ch)
  41. ch = pdata->default_char;
  42. if (!ch)
  43. ch = '@';
  44. index = (pdata->sides / 2) - 1;
  45. if (index >= ARRAY_SIZE(shapes))
  46. return -EIO;
  47. shape = shapes[index];
  48. for (line = 0; line < HEIGHT; line++) {
  49. first = 1;
  50. for (pos = 0; pos < WIDTH; pos++) {
  51. inside = pos >= shape.start && pos < shape.end;
  52. if (inside) {
  53. putc(first ? *colour++ : ch);
  54. data->num_chars++;
  55. first = 0;
  56. if (!*colour)
  57. colour = pdata->colour;
  58. } else {
  59. putc(' ');
  60. }
  61. }
  62. putc('\n');
  63. shape.start += shape.dstart;
  64. shape.end += shape.dend;
  65. if (shape.start < 0) {
  66. shape.dstart = -shape.dstart;
  67. shape.dend = -shape.dend;
  68. shape.start += shape.dstart;
  69. shape.end += shape.dend;
  70. }
  71. }
  72. return 0;
  73. }
  74. static int shape_status(struct udevice *dev, int *status)
  75. {
  76. struct shape_data *data = dev_get_priv(dev);
  77. *status = data->num_chars;
  78. return 0;
  79. }
  80. static const struct demo_ops shape_ops = {
  81. .hello = shape_hello,
  82. .status = shape_status,
  83. };
  84. static int shape_ofdata_to_platdata(struct udevice *dev)
  85. {
  86. struct dm_demo_pdata *pdata = dev_get_platdata(dev);
  87. int ret;
  88. /* Parse the data that is common with all demo devices */
  89. ret = demo_parse_dt(dev);
  90. if (ret)
  91. return ret;
  92. /* Parse the data that only we need */
  93. pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
  94. "character", '@');
  95. return 0;
  96. }
  97. static const struct udevice_id demo_shape_id[] = {
  98. { "demo-shape", 0 },
  99. { },
  100. };
  101. U_BOOT_DRIVER(demo_shape_drv) = {
  102. .name = "demo_shape_drv",
  103. .of_match = demo_shape_id,
  104. .id = UCLASS_DEMO,
  105. .ofdata_to_platdata = shape_ofdata_to_platdata,
  106. .ops = &shape_ops,
  107. .priv_auto_alloc_size = sizeof(struct shape_data),
  108. .platdata_auto_alloc_size = sizeof(struct dm_demo_pdata),
  109. };