goodix_ts_utils.c 4.8 KB

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