dp_hpd.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  4. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  5. */
  6. #include <linux/slab.h>
  7. #include <linux/device.h>
  8. #include <linux/delay.h>
  9. #include <linux/err.h>
  10. #include "dp_hpd.h"
  11. #include "dp_altmode.h"
  12. #include "dp_usbpd.h"
  13. #include "dp_gpio_hpd.h"
  14. #include "dp_lphw_hpd.h"
  15. #include "dp_debug.h"
  16. #include "dp_bridge_hpd.h"
  17. #if defined(CONFIG_SECDP)
  18. #include "secdp.h"
  19. #endif
  20. static void dp_hpd_host_init(struct dp_hpd *dp_hpd,
  21. struct dp_catalog_hpd *catalog)
  22. {
  23. if (!catalog) {
  24. DP_ERR("invalid input\n");
  25. return;
  26. }
  27. catalog->config_hpd(catalog, true);
  28. }
  29. static void dp_hpd_host_deinit(struct dp_hpd *dp_hpd,
  30. struct dp_catalog_hpd *catalog)
  31. {
  32. if (!catalog) {
  33. DP_ERR("invalid input\n");
  34. return;
  35. }
  36. catalog->config_hpd(catalog, false);
  37. }
  38. static void dp_hpd_isr(struct dp_hpd *dp_hpd)
  39. {
  40. }
  41. struct dp_hpd *dp_hpd_get(struct device *dev, struct dp_parser *parser,
  42. struct dp_catalog_hpd *catalog,
  43. struct dp_aux_bridge *aux_bridge,
  44. struct dp_hpd_cb *cb)
  45. {
  46. struct dp_hpd *dp_hpd = NULL;
  47. if (aux_bridge && (aux_bridge->flag & DP_AUX_BRIDGE_HPD)) {
  48. dp_hpd = dp_bridge_hpd_get(dev, cb, aux_bridge);
  49. if (!IS_ERR(dp_hpd)) {
  50. dp_hpd->type = DP_HPD_BRIDGE;
  51. goto config;
  52. }
  53. }
  54. dp_hpd = dp_lphw_hpd_get(dev, parser, catalog, cb);
  55. if (!IS_ERR_OR_NULL(dp_hpd)) {
  56. dp_hpd->type = DP_HPD_LPHW;
  57. goto config;
  58. }
  59. dp_hpd = dp_gpio_hpd_get(dev, cb);
  60. if (!IS_ERR_OR_NULL(dp_hpd)) {
  61. dp_hpd->type = DP_HPD_GPIO;
  62. goto config;
  63. }
  64. dp_hpd = dp_altmode_get(dev, cb);
  65. if (!IS_ERR_OR_NULL(dp_hpd)) {
  66. dp_hpd->type = DP_HPD_ALTMODE;
  67. goto config;
  68. }
  69. dp_hpd = dp_usbpd_get(dev, cb);
  70. if (!IS_ERR_OR_NULL(dp_hpd)) {
  71. dp_hpd->type = DP_HPD_USBPD;
  72. goto config;
  73. }
  74. DP_ERR("Failed to detect HPD type\n");
  75. goto end;
  76. config:
  77. if (!dp_hpd->host_init)
  78. dp_hpd->host_init = dp_hpd_host_init;
  79. if (!dp_hpd->host_deinit)
  80. dp_hpd->host_deinit = dp_hpd_host_deinit;
  81. if (!dp_hpd->isr)
  82. dp_hpd->isr = dp_hpd_isr;
  83. end:
  84. return dp_hpd;
  85. }
  86. void dp_hpd_put(struct dp_hpd *dp_hpd)
  87. {
  88. if (!dp_hpd)
  89. return;
  90. switch (dp_hpd->type) {
  91. case DP_HPD_USBPD:
  92. dp_usbpd_put(dp_hpd);
  93. break;
  94. case DP_HPD_ALTMODE:
  95. dp_altmode_put(dp_hpd);
  96. break;
  97. case DP_HPD_GPIO:
  98. dp_gpio_hpd_put(dp_hpd);
  99. break;
  100. case DP_HPD_LPHW:
  101. dp_lphw_hpd_put(dp_hpd);
  102. break;
  103. case DP_HPD_BRIDGE:
  104. dp_bridge_hpd_put(dp_hpd);
  105. break;
  106. default:
  107. DP_ERR("unknown hpd type %d\n", dp_hpd->type);
  108. break;
  109. }
  110. }