goodix_ts_utils.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Goodix Touchscreen Driver
  3. * Copyright (C) 2020 - 2021 Goodix, Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be a reference
  11. * to you, when you are integrating the GOODiX's CTP IC into your system,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. */
  17. #include "goodix_ts_core.h"
  18. bool debug_log_flag = false;
  19. /*****************************************************************************
  20. * goodix_append_checksum
  21. * @summary
  22. * Calcualte data checksum with the specified mode.
  23. *
  24. * @param data
  25. * data need to be calculate
  26. * @param len
  27. * data length
  28. * @param mode
  29. * calculate for u8 or u16 checksum
  30. * @return
  31. * return the data checksum value.
  32. *
  33. *****************************************************************************/
  34. u32 goodix_append_checksum(u8 *data, int len, int mode)
  35. {
  36. u32 checksum = 0;
  37. int i;
  38. checksum = 0;
  39. if (mode == CHECKSUM_MODE_U8_LE) {
  40. for (i = 0; i < len; i++)
  41. checksum += data[i];
  42. } else {
  43. for (i = 0; i < len; i+=2)
  44. checksum += (data[i] + (data[i+1] << 8));
  45. }
  46. if (mode == CHECKSUM_MODE_U8_LE) {
  47. data[len] = checksum & 0xff;
  48. data[len + 1] = (checksum >> 8) & 0xff;
  49. return 0xFFFF & checksum;
  50. }
  51. data[len] = checksum & 0xff;
  52. data[len + 1] = (checksum >> 8) & 0xff;
  53. data[len + 2] = (checksum >> 16) & 0xff;
  54. data[len + 3] = (checksum >> 24) & 0xff;
  55. return checksum;
  56. }
  57. /* checksum_cmp: check data valid or not
  58. * @data: data need to be check
  59. * @size: data length need to be check(include the checksum bytes)
  60. * @mode: compare with U8 or U16 mode
  61. * */
  62. int checksum_cmp(const u8 *data, int size, int mode)
  63. {
  64. u32 cal_checksum = 0;
  65. u32 r_checksum = 0;
  66. u32 i;
  67. if (mode == CHECKSUM_MODE_U8_LE) {
  68. if (size < 2)
  69. return 1;
  70. for (i = 0; i < size - 2; i++)
  71. cal_checksum += data[i];
  72. r_checksum = data[size - 2] + (data[size - 1] << 8);
  73. return (cal_checksum & 0xFFFF) == r_checksum ? 0 : 1;
  74. }
  75. if (size < 4)
  76. return 1;
  77. for (i = 0; i < size - 4; i += 2)
  78. cal_checksum += data[i] + (data[i + 1] << 8);
  79. r_checksum = data[size - 4] + (data[size - 3] << 8) +
  80. (data[size - 2] << 16) + (data[size - 1] << 24);
  81. return cal_checksum == r_checksum ? 0 : 1;
  82. }
  83. /* return 1 if all data is zero or ff
  84. * else return 0
  85. */
  86. int is_risk_data(const u8 *data, int size)
  87. {
  88. int i;
  89. int zero_count = 0;
  90. int ff_count = 0;
  91. for (i = 0; i < size; i++) {
  92. if (data[i] == 0)
  93. zero_count++;
  94. else if (data[i] == 0xff)
  95. ff_count++;
  96. }
  97. if (zero_count == size || ff_count == size) {
  98. ts_info("warning data is all %s\n",
  99. zero_count == size ? "zero" : "0xff");
  100. return 1;
  101. }
  102. return 0;
  103. }
  104. /* get config id form config file */
  105. #define CONFIG_ID_OFFSET 30
  106. u32 goodix_get_file_config_id(u8 *ic_config)
  107. {
  108. if (!ic_config)
  109. return 0;
  110. return le32_to_cpup((__le32 *)&ic_config[CONFIG_ID_OFFSET]);
  111. }
  112. /* matrix transpose */
  113. void goodix_rotate_abcd2cbad(int tx, int rx, s16 *data)
  114. {
  115. s16 *temp_buf = NULL;
  116. int size = tx * rx;
  117. int i;
  118. int j;
  119. int col;
  120. temp_buf = kcalloc(size, sizeof(s16), GFP_KERNEL);
  121. if (!temp_buf) {
  122. ts_err("malloc failed");
  123. return;
  124. }
  125. for (i = 0, j = 0, col = 0; i < size; i++) {
  126. temp_buf[i] = data[j++ * rx + col];
  127. if (j == tx) {
  128. j = 0;
  129. col++;
  130. }
  131. }
  132. memcpy(data, temp_buf, size * sizeof(s16));
  133. kfree(temp_buf);
  134. }
  135. /* get ic type */
  136. int goodix_get_ic_type(struct device_node *node)
  137. {
  138. const char *name_tmp;
  139. int ret;
  140. ret = of_property_read_string(node, "compatible", &name_tmp);
  141. if (ret < 0) {
  142. ts_err("get compatible failed");
  143. return ret;
  144. }
  145. if (strstr(name_tmp, "9897")) {
  146. ts_info("ic type is BerlinA");
  147. ret = IC_TYPE_BERLIN_A;
  148. } else if (strstr(name_tmp, "9966") || strstr(name_tmp, "7986")) {
  149. ts_info("ic type is BerlinB");
  150. ret = IC_TYPE_BERLIN_B;
  151. } else if (strstr(name_tmp, "9916")) {
  152. ts_info("ic type is BerlinD");
  153. ret = IC_TYPE_BERLIN_D;
  154. } else {
  155. ts_info("can't find valid ic_type");
  156. ret = -EINVAL;
  157. }
  158. return ret;
  159. }