goodix_ts_utils.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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) && (size < 2)) ||
  68. ((mode == CHECKSUM_MODE_U16_LE) && (size < 4)))
  69. return 1;
  70. if (mode == CHECKSUM_MODE_U8_LE) {
  71. for (i = 0; i < size - 2; i++)
  72. cal_checksum += data[i];
  73. r_checksum += data[i++];
  74. r_checksum += (data[i] << 8);
  75. return (cal_checksum & 0xFFFF) == r_checksum ? 0 : 1;
  76. }
  77. if (mode == CHECKSUM_MODE_U16_LE) {
  78. for (i = 0; i < size - 4; i += 2)
  79. cal_checksum += data[i] + (data[i + 1] << 8);
  80. r_checksum += data[i++];
  81. r_checksum += (data[i++] << 8);
  82. r_checksum += (data[i++] << 16);
  83. r_checksum += (data[i] << 24);
  84. return cal_checksum == r_checksum ? 0 : 1;
  85. }
  86. return 1;
  87. }
  88. /* return 1 if all data is zero or ff
  89. * else return 0
  90. */
  91. int is_risk_data(const u8 *data, int size)
  92. {
  93. int i;
  94. int zero_count = 0;
  95. int ff_count = 0;
  96. for (i = 0; i < size; i++) {
  97. if (data[i] == 0)
  98. zero_count++;
  99. else if (data[i] == 0xff)
  100. ff_count++;
  101. }
  102. if (zero_count == size || ff_count == size) {
  103. ts_info("warning data is all %s\n",
  104. zero_count == size ? "zero" : "0xff");
  105. return 1;
  106. }
  107. return 0;
  108. }
  109. /* get config id form config file */
  110. #define CONFIG_ID_OFFSET 30
  111. u32 goodix_get_file_config_id(u8 *ic_config)
  112. {
  113. if (!ic_config)
  114. return 0;
  115. return le32_to_cpup((__le32 *)&ic_config[CONFIG_ID_OFFSET]);
  116. }
  117. /* matrix transpose */
  118. void goodix_rotate_abcd2cbad(int tx, int rx, s16 *data)
  119. {
  120. s16 *temp_buf = NULL;
  121. int size = tx * rx;
  122. int i;
  123. int j;
  124. int col;
  125. temp_buf = kcalloc(size, sizeof(s16), GFP_KERNEL);
  126. if (!temp_buf) {
  127. ts_err("malloc failed");
  128. return;
  129. }
  130. for (i = 0, j = 0, col = 0; i < size; i++) {
  131. temp_buf[i] = data[j++ * rx + col];
  132. if (j == tx) {
  133. j = 0;
  134. col++;
  135. }
  136. }
  137. memcpy(data, temp_buf, size * sizeof(s16));
  138. kfree(temp_buf);
  139. }
  140. /* get ic type */
  141. int goodix_get_ic_type(struct device_node *node)
  142. {
  143. const char *name_tmp;
  144. int ret;
  145. ret = of_property_read_string(node, "compatible", &name_tmp);
  146. if (ret < 0) {
  147. ts_err("get compatible failed");
  148. return ret;
  149. }
  150. if (strstr(name_tmp, "9897")) {
  151. ts_info("ic type is BerlinA");
  152. ret = IC_TYPE_BERLIN_A;
  153. } else if (strstr(name_tmp, "9966") || strstr(name_tmp, "7986")) {
  154. ts_info("ic type is BerlinB");
  155. ret = IC_TYPE_BERLIN_B;
  156. } else if (strstr(name_tmp, "9916")) {
  157. ts_info("ic type is BerlinD");
  158. ret = IC_TYPE_BERLIN_D;
  159. } else {
  160. ts_info("can't find valid ic_type");
  161. ret = -EINVAL;
  162. }
  163. return ret;
  164. }