video-bridge-uclass.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #define LOG_CATEGORY UCLASS_VIDEO_BRIDGE
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <errno.h>
  10. #include <edid.h>
  11. #include <log.h>
  12. #include <video_bridge.h>
  13. #include <linux/delay.h>
  14. int video_bridge_set_backlight(struct udevice *dev, int percent)
  15. {
  16. struct video_bridge_ops *ops = video_bridge_get_ops(dev);
  17. if (!ops->set_backlight)
  18. return -ENOSYS;
  19. return ops->set_backlight(dev, percent);
  20. }
  21. int video_bridge_attach(struct udevice *dev)
  22. {
  23. struct video_bridge_ops *ops = video_bridge_get_ops(dev);
  24. if (!ops->attach)
  25. return -ENOSYS;
  26. return ops->attach(dev);
  27. }
  28. int video_bridge_check_attached(struct udevice *dev)
  29. {
  30. struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
  31. struct video_bridge_ops *ops = video_bridge_get_ops(dev);
  32. int ret;
  33. if (!ops->check_attached) {
  34. ret = dm_gpio_get_value(&uc_priv->hotplug);
  35. return ret > 0 ? 0 : ret == 0 ? -ENOTCONN : ret;
  36. }
  37. return ops->check_attached(dev);
  38. }
  39. int video_bridge_read_edid(struct udevice *dev, u8 *buf, int buf_size)
  40. {
  41. struct video_bridge_ops *ops = video_bridge_get_ops(dev);
  42. if (!ops || !ops->read_edid)
  43. return -ENOSYS;
  44. return ops->read_edid(dev, buf, buf_size);
  45. }
  46. static int video_bridge_pre_probe(struct udevice *dev)
  47. {
  48. struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
  49. int ret;
  50. debug("%s\n", __func__);
  51. ret = gpio_request_by_name(dev, "sleep-gpios", 0,
  52. &uc_priv->sleep, GPIOD_IS_OUT);
  53. if (ret) {
  54. debug("%s: Could not decode sleep-gpios (%d)\n", __func__, ret);
  55. if (ret != -ENOENT)
  56. return ret;
  57. }
  58. /*
  59. * Drop this for now as we do not have driver model pinctrl support
  60. *
  61. * ret = dm_gpio_set_pull(&uc_priv->sleep, GPIO_PULL_NONE);
  62. * if (ret) {
  63. * debug("%s: Could not set sleep pull value\n", __func__);
  64. * return ret;
  65. * }
  66. */
  67. ret = gpio_request_by_name(dev, "reset-gpios", 0, &uc_priv->reset,
  68. GPIOD_IS_OUT);
  69. if (ret) {
  70. debug("%s: Could not decode reset-gpios (%d)\n", __func__, ret);
  71. if (ret != -ENOENT)
  72. return ret;
  73. }
  74. /*
  75. * Drop this for now as we do not have driver model pinctrl support
  76. *
  77. * ret = dm_gpio_set_pull(&uc_priv->reset, GPIO_PULL_NONE);
  78. * if (ret) {
  79. * debug("%s: Could not set reset pull value\n", __func__);
  80. * return ret;
  81. * }
  82. */
  83. ret = gpio_request_by_name(dev, "hotplug-gpios", 0, &uc_priv->hotplug,
  84. GPIOD_IS_IN);
  85. if (ret) {
  86. debug("%s: Could not decode hotplug (%d)\n", __func__, ret);
  87. if (ret != -ENOENT)
  88. return ret;
  89. }
  90. return 0;
  91. }
  92. int video_bridge_set_active(struct udevice *dev, bool active)
  93. {
  94. struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
  95. int ret = 0;
  96. debug("%s: %d\n", __func__, active);
  97. if (uc_priv->sleep.dev) {
  98. ret = dm_gpio_set_value(&uc_priv->sleep, !active);
  99. if (ret)
  100. return ret;
  101. }
  102. if (!active)
  103. return 0;
  104. if (uc_priv->reset.dev) {
  105. ret = dm_gpio_set_value(&uc_priv->reset, true);
  106. if (ret)
  107. return ret;
  108. udelay(10);
  109. ret = dm_gpio_set_value(&uc_priv->reset, false);
  110. }
  111. return ret;
  112. }
  113. UCLASS_DRIVER(video_bridge) = {
  114. .id = UCLASS_VIDEO_BRIDGE,
  115. .name = "video_bridge",
  116. .per_device_auto = sizeof(struct video_bridge_priv),
  117. .pre_probe = video_bridge_pre_probe,
  118. };