ast_i2c.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Permission is hereby granted, free of charge, to any person obtaining a
  4. * copy of this software and associated documentation files (the
  5. * "Software"), to deal in the Software without restriction, including
  6. * without limitation the rights to use, copy, modify, merge, publish,
  7. * distribute, sub license, and/or sell copies of the Software, and to
  8. * permit persons to whom the Software is furnished to do so, subject to
  9. * the following conditions:
  10. *
  11. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  14. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  15. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  17. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. *
  19. * The above copyright notice and this permission notice (including the
  20. * next paragraph) shall be included in all copies or substantial portions
  21. * of the Software.
  22. */
  23. #include <drm/drm_managed.h>
  24. #include <drm/drm_print.h>
  25. #include "ast_drv.h"
  26. static void ast_i2c_setsda(void *i2c_priv, int data)
  27. {
  28. struct ast_i2c_chan *i2c = i2c_priv;
  29. struct ast_private *ast = to_ast_private(i2c->dev);
  30. int i;
  31. u8 ujcrb7, jtemp;
  32. for (i = 0; i < 0x10000; i++) {
  33. ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
  34. ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
  35. jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
  36. if (ujcrb7 == jtemp)
  37. break;
  38. }
  39. }
  40. static void ast_i2c_setscl(void *i2c_priv, int clock)
  41. {
  42. struct ast_i2c_chan *i2c = i2c_priv;
  43. struct ast_private *ast = to_ast_private(i2c->dev);
  44. int i;
  45. u8 ujcrb7, jtemp;
  46. for (i = 0; i < 0x10000; i++) {
  47. ujcrb7 = ((clock & 0x01) ? 0 : 1);
  48. ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
  49. jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
  50. if (ujcrb7 == jtemp)
  51. break;
  52. }
  53. }
  54. static int ast_i2c_getsda(void *i2c_priv)
  55. {
  56. struct ast_i2c_chan *i2c = i2c_priv;
  57. struct ast_private *ast = to_ast_private(i2c->dev);
  58. uint32_t val, val2, count, pass;
  59. count = 0;
  60. pass = 0;
  61. val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
  62. do {
  63. val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
  64. if (val == val2) {
  65. pass++;
  66. } else {
  67. pass = 0;
  68. val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
  69. }
  70. } while ((pass < 5) && (count++ < 0x10000));
  71. return val & 1 ? 1 : 0;
  72. }
  73. static int ast_i2c_getscl(void *i2c_priv)
  74. {
  75. struct ast_i2c_chan *i2c = i2c_priv;
  76. struct ast_private *ast = to_ast_private(i2c->dev);
  77. uint32_t val, val2, count, pass;
  78. count = 0;
  79. pass = 0;
  80. val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
  81. do {
  82. val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
  83. if (val == val2) {
  84. pass++;
  85. } else {
  86. pass = 0;
  87. val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
  88. }
  89. } while ((pass < 5) && (count++ < 0x10000));
  90. return val & 1 ? 1 : 0;
  91. }
  92. static void ast_i2c_release(struct drm_device *dev, void *res)
  93. {
  94. struct ast_i2c_chan *i2c = res;
  95. i2c_del_adapter(&i2c->adapter);
  96. kfree(i2c);
  97. }
  98. struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
  99. {
  100. struct ast_i2c_chan *i2c;
  101. int ret;
  102. i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
  103. if (!i2c)
  104. return NULL;
  105. i2c->adapter.owner = THIS_MODULE;
  106. i2c->adapter.class = I2C_CLASS_DDC;
  107. i2c->adapter.dev.parent = dev->dev;
  108. i2c->dev = dev;
  109. i2c_set_adapdata(&i2c->adapter, i2c);
  110. snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
  111. "AST i2c bit bus");
  112. i2c->adapter.algo_data = &i2c->bit;
  113. i2c->bit.udelay = 20;
  114. i2c->bit.timeout = 2;
  115. i2c->bit.data = i2c;
  116. i2c->bit.setsda = ast_i2c_setsda;
  117. i2c->bit.setscl = ast_i2c_setscl;
  118. i2c->bit.getsda = ast_i2c_getsda;
  119. i2c->bit.getscl = ast_i2c_getscl;
  120. ret = i2c_bit_add_bus(&i2c->adapter);
  121. if (ret) {
  122. drm_err(dev, "Failed to register bit i2c\n");
  123. goto out_kfree;
  124. }
  125. ret = drmm_add_action_or_reset(dev, ast_i2c_release, i2c);
  126. if (ret)
  127. return NULL;
  128. return i2c;
  129. out_kfree:
  130. kfree(i2c);
  131. return NULL;
  132. }