simple_panel.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2016 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #include <common.h>
  7. #include <backlight.h>
  8. #include <dm.h>
  9. #include <log.h>
  10. #include <mipi_dsi.h>
  11. #include <panel.h>
  12. #include <asm/gpio.h>
  13. #include <power/regulator.h>
  14. struct simple_panel_priv {
  15. struct udevice *reg;
  16. struct udevice *backlight;
  17. struct gpio_desc enable;
  18. };
  19. /* List of supported DSI panels */
  20. enum {
  21. PANEL_NON_DSI,
  22. PANASONIC_VVX10F004B00,
  23. };
  24. static const struct mipi_dsi_panel_plat panasonic_vvx10f004b00 = {
  25. .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
  26. MIPI_DSI_CLOCK_NON_CONTINUOUS,
  27. .format = MIPI_DSI_FMT_RGB888,
  28. .lanes = 4,
  29. };
  30. static int simple_panel_enable_backlight(struct udevice *dev)
  31. {
  32. struct simple_panel_priv *priv = dev_get_priv(dev);
  33. int ret;
  34. debug("%s: start, backlight = '%s'\n", __func__, priv->backlight->name);
  35. dm_gpio_set_value(&priv->enable, 1);
  36. ret = backlight_enable(priv->backlight);
  37. debug("%s: done, ret = %d\n", __func__, ret);
  38. if (ret)
  39. return ret;
  40. return 0;
  41. }
  42. static int simple_panel_set_backlight(struct udevice *dev, int percent)
  43. {
  44. struct simple_panel_priv *priv = dev_get_priv(dev);
  45. int ret;
  46. debug("%s: start, backlight = '%s'\n", __func__, priv->backlight->name);
  47. dm_gpio_set_value(&priv->enable, 1);
  48. ret = backlight_set_brightness(priv->backlight, percent);
  49. debug("%s: done, ret = %d\n", __func__, ret);
  50. if (ret)
  51. return ret;
  52. return 0;
  53. }
  54. static int simple_panel_get_display_timing(struct udevice *dev,
  55. struct display_timing *timings)
  56. {
  57. const void *blob = gd->fdt_blob;
  58. return fdtdec_decode_display_timing(blob, dev_of_offset(dev),
  59. 0, timings);
  60. }
  61. static int simple_panel_of_to_plat(struct udevice *dev)
  62. {
  63. struct simple_panel_priv *priv = dev_get_priv(dev);
  64. int ret;
  65. if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
  66. ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
  67. "power-supply", &priv->reg);
  68. if (ret) {
  69. debug("%s: Warning: cannot get power supply: ret=%d\n",
  70. __func__, ret);
  71. if (ret != -ENOENT)
  72. return ret;
  73. }
  74. }
  75. ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
  76. "backlight", &priv->backlight);
  77. if (ret) {
  78. debug("%s: Cannot get backlight: ret=%d\n", __func__, ret);
  79. if (ret != -ENOENT)
  80. return log_ret(ret);
  81. }
  82. ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable,
  83. GPIOD_IS_OUT);
  84. if (ret) {
  85. debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
  86. __func__, ret);
  87. if (ret != -ENOENT)
  88. return log_ret(ret);
  89. }
  90. return 0;
  91. }
  92. static int simple_panel_probe(struct udevice *dev)
  93. {
  94. struct simple_panel_priv *priv = dev_get_priv(dev);
  95. struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
  96. const u32 dsi_data = dev_get_driver_data(dev);
  97. int ret;
  98. if (CONFIG_IS_ENABLED(DM_REGULATOR) && priv->reg) {
  99. debug("%s: Enable regulator '%s'\n", __func__, priv->reg->name);
  100. ret = regulator_set_enable(priv->reg, true);
  101. if (ret)
  102. return ret;
  103. }
  104. switch (dsi_data) {
  105. case PANASONIC_VVX10F004B00:
  106. memcpy(plat, &panasonic_vvx10f004b00,
  107. sizeof(panasonic_vvx10f004b00));
  108. break;
  109. case PANEL_NON_DSI:
  110. default:
  111. break;
  112. }
  113. return 0;
  114. }
  115. static const struct panel_ops simple_panel_ops = {
  116. .enable_backlight = simple_panel_enable_backlight,
  117. .set_backlight = simple_panel_set_backlight,
  118. .get_display_timing = simple_panel_get_display_timing,
  119. };
  120. static const struct udevice_id simple_panel_ids[] = {
  121. { .compatible = "simple-panel" },
  122. { .compatible = "auo,b133xtn01" },
  123. { .compatible = "auo,b116xw03" },
  124. { .compatible = "auo,b133htn01" },
  125. { .compatible = "boe,nv140fhmn49" },
  126. { .compatible = "lg,lb070wv8" },
  127. { .compatible = "sharp,lq123p1jx31" },
  128. { .compatible = "boe,nv101wxmn51" },
  129. { .compatible = "panasonic,vvx10f004b00",
  130. .data = PANASONIC_VVX10F004B00 },
  131. { }
  132. };
  133. U_BOOT_DRIVER(simple_panel) = {
  134. .name = "simple_panel",
  135. .id = UCLASS_PANEL,
  136. .of_match = simple_panel_ids,
  137. .ops = &simple_panel_ops,
  138. .of_to_plat = simple_panel_of_to_plat,
  139. .probe = simple_panel_probe,
  140. .priv_auto = sizeof(struct simple_panel_priv),
  141. .plat_auto = sizeof(struct mipi_dsi_panel_plat),
  142. };