goodix_cfg_bin.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. #define TS_BIN_VERSION_START_INDEX 5
  19. #define TS_BIN_VERSION_LEN 4
  20. #define TS_CFG_BIN_HEAD_RESERVED_LEN 6
  21. #define TS_CFG_OFFSET_LEN 2
  22. #define TS_IC_TYPE_NAME_MAX_LEN 15
  23. #define TS_CFG_BIN_HEAD_LEN (sizeof(struct goodix_cfg_bin_head) + \
  24. TS_CFG_BIN_HEAD_RESERVED_LEN)
  25. #define TS_PKG_CONST_INFO_LEN (sizeof(struct goodix_cfg_pkg_const_info))
  26. #define TS_PKG_REG_INFO_LEN (sizeof(struct goodix_cfg_pkg_reg_info))
  27. #define TS_PKG_HEAD_LEN (TS_PKG_CONST_INFO_LEN + TS_PKG_REG_INFO_LEN)
  28. /*cfg block definitin*/
  29. #define TS_CFG_BLOCK_PID_LEN 8
  30. #define TS_CFG_BLOCK_VID_LEN 8
  31. #define TS_CFG_BLOCK_FW_MASK_LEN 9
  32. #define TS_CFG_BLOCK_FW_PATCH_LEN 4
  33. #define TS_CFG_BLOCK_RESERVED_LEN 9
  34. #define TS_NORMAL_CFG 0x01
  35. #define TS_HIGH_SENSE_CFG 0x03
  36. #define TS_RQST_FW_RETRY_TIMES 2
  37. #pragma pack(1)
  38. struct goodix_cfg_pkg_reg {
  39. u16 addr;
  40. u8 reserved1;
  41. u8 reserved2;
  42. };
  43. struct goodix_cfg_pkg_const_info {
  44. u32 pkg_len;
  45. u8 ic_type[TS_IC_TYPE_NAME_MAX_LEN];
  46. u8 cfg_type;
  47. u8 sensor_id;
  48. u8 hw_pid[TS_CFG_BLOCK_PID_LEN];
  49. u8 hw_vid[TS_CFG_BLOCK_VID_LEN];
  50. u8 fw_mask[TS_CFG_BLOCK_FW_MASK_LEN];
  51. u8 fw_patch[TS_CFG_BLOCK_FW_PATCH_LEN];
  52. u16 x_res_offset;
  53. u16 y_res_offset;
  54. u16 trigger_offset;
  55. };
  56. struct goodix_cfg_pkg_reg_info {
  57. struct goodix_cfg_pkg_reg cfg_send_flag;
  58. struct goodix_cfg_pkg_reg version_base;
  59. struct goodix_cfg_pkg_reg pid;
  60. struct goodix_cfg_pkg_reg vid;
  61. struct goodix_cfg_pkg_reg sensor_id;
  62. struct goodix_cfg_pkg_reg fw_mask;
  63. struct goodix_cfg_pkg_reg fw_status;
  64. struct goodix_cfg_pkg_reg cfg_addr;
  65. struct goodix_cfg_pkg_reg esd;
  66. struct goodix_cfg_pkg_reg command;
  67. struct goodix_cfg_pkg_reg coor;
  68. struct goodix_cfg_pkg_reg gesture;
  69. struct goodix_cfg_pkg_reg fw_request;
  70. struct goodix_cfg_pkg_reg proximity;
  71. u8 reserved[TS_CFG_BLOCK_RESERVED_LEN];
  72. };
  73. struct goodix_cfg_bin_head {
  74. u32 bin_len;
  75. u8 checksum;
  76. u8 bin_version[TS_BIN_VERSION_LEN];
  77. u8 pkg_num;
  78. };
  79. #pragma pack()
  80. struct goodix_cfg_package {
  81. struct goodix_cfg_pkg_const_info cnst_info;
  82. struct goodix_cfg_pkg_reg_info reg_info;
  83. const u8 *cfg;
  84. u32 pkg_len;
  85. };
  86. struct goodix_cfg_bin {
  87. unsigned char *bin_data;
  88. unsigned int bin_data_len;
  89. struct goodix_cfg_bin_head head;
  90. struct goodix_cfg_package *cfg_pkgs;
  91. };
  92. static int goodix_read_cfg_bin(struct device *dev, const char *cfg_name,
  93. struct goodix_cfg_bin *cfg_bin)
  94. {
  95. const struct firmware *firmware = NULL;
  96. int ret;
  97. int retry = GOODIX_RETRY_3;
  98. ts_info("cfg_bin_name:%s", cfg_name);
  99. while (retry--) {
  100. ret = request_firmware(&firmware, cfg_name, dev);
  101. if (!ret)
  102. break;
  103. ts_info("get cfg bin retry:[%d]", GOODIX_RETRY_3 - retry);
  104. msleep(200);
  105. }
  106. if (retry < 0) {
  107. ts_err("failed get cfg bin[%s] error:%d", cfg_name, ret);
  108. return ret;
  109. }
  110. if (firmware->size <= 0) {
  111. ts_err("request_firmware, cfg_bin length ERROR,len:%zu",
  112. firmware->size);
  113. ret = -EINVAL;
  114. goto exit;
  115. }
  116. cfg_bin->bin_data_len = firmware->size;
  117. /* allocate memory for cfg_bin->bin_data */
  118. cfg_bin->bin_data = kzalloc(cfg_bin->bin_data_len, GFP_KERNEL);
  119. if (!cfg_bin->bin_data) {
  120. ret = -ENOMEM;
  121. goto exit;
  122. }
  123. memcpy(cfg_bin->bin_data, firmware->data, cfg_bin->bin_data_len);
  124. exit:
  125. release_firmware(firmware);
  126. return ret;
  127. }
  128. static int goodix_parse_cfg_bin(struct goodix_cfg_bin *cfg_bin)
  129. {
  130. u16 offset1, offset2;
  131. u8 checksum;
  132. int i;
  133. /* copy cfg_bin head info */
  134. if (cfg_bin->bin_data_len < sizeof(struct goodix_cfg_bin_head)) {
  135. ts_err("Invalid cfg_bin size:%d", cfg_bin->bin_data_len);
  136. return -EINVAL;
  137. }
  138. memcpy(&cfg_bin->head, cfg_bin->bin_data,
  139. sizeof(struct goodix_cfg_bin_head));
  140. cfg_bin->head.bin_len = le32_to_cpu(cfg_bin->head.bin_len);
  141. /*check length*/
  142. if (cfg_bin->bin_data_len != cfg_bin->head.bin_len) {
  143. ts_err("cfg_bin len check failed,%d != %d",
  144. cfg_bin->head.bin_len, cfg_bin->bin_data_len);
  145. return -EINVAL;
  146. }
  147. /*check cfg_bin valid*/
  148. checksum = 0;
  149. for (i = TS_BIN_VERSION_START_INDEX; i < cfg_bin->bin_data_len; i++) {
  150. checksum += cfg_bin->bin_data[i];
  151. }
  152. if (checksum != cfg_bin->head.checksum) {
  153. ts_err("cfg_bin checksum check filed 0x%02x != 0x%02x",
  154. cfg_bin->head.checksum, checksum);
  155. return -EINVAL;
  156. }
  157. /*allocate memory for cfg packages*/
  158. cfg_bin->cfg_pkgs = kzalloc(sizeof(struct goodix_cfg_package) *
  159. cfg_bin->head.pkg_num, GFP_KERNEL);
  160. if (!cfg_bin->cfg_pkgs) {
  161. ts_err("cfg_pkgs, allocate memory ERROR");
  162. return -ENOMEM;
  163. }
  164. /*get cfg_pkg's info*/
  165. for (i = 0; i < cfg_bin->head.pkg_num; i++) {
  166. /*get cfg pkg length*/
  167. if (i == cfg_bin->head.pkg_num - 1) {
  168. offset1 = cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + i * TS_CFG_OFFSET_LEN] +
  169. (cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + i * TS_CFG_OFFSET_LEN + 1] << 8);
  170. cfg_bin->cfg_pkgs[i].pkg_len = cfg_bin->bin_data_len - offset1;
  171. } else {
  172. offset1 = cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + i * TS_CFG_OFFSET_LEN] +
  173. (cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + i * TS_CFG_OFFSET_LEN + 1] << 8);
  174. offset2 = cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + i * TS_CFG_OFFSET_LEN + 2] +
  175. (cfg_bin->bin_data[TS_CFG_BIN_HEAD_LEN + i * TS_CFG_OFFSET_LEN + 3] << 8);
  176. if (offset2 <= offset1) {
  177. ts_err("offset error,pkg:%d, offset1:%d, offset2:%d", i, offset1, offset2);
  178. goto exit;
  179. }
  180. cfg_bin->cfg_pkgs[i].pkg_len = offset2 - offset1;
  181. }
  182. /*get cfg pkg head*/
  183. memcpy(&cfg_bin->cfg_pkgs[i].cnst_info,
  184. &cfg_bin->bin_data[offset1], TS_PKG_CONST_INFO_LEN);
  185. memcpy(&cfg_bin->cfg_pkgs[i].reg_info,
  186. &cfg_bin->bin_data[offset1 + TS_PKG_CONST_INFO_LEN],
  187. TS_PKG_REG_INFO_LEN);
  188. /*get configuration data*/
  189. cfg_bin->cfg_pkgs[i].cfg = &cfg_bin->bin_data[offset1 + TS_PKG_HEAD_LEN];
  190. }
  191. /*debug, print pkg information*/
  192. ts_info("Driver bin info: ver %s, len %d, pkgs %d", cfg_bin->head.bin_version,
  193. cfg_bin->head.bin_len, cfg_bin->head.pkg_num);
  194. return 0;
  195. exit:
  196. kfree(cfg_bin->cfg_pkgs);
  197. return -EINVAL;
  198. }
  199. static int goodix_get_reg_and_cfg(struct goodix_ts_core *cd, u8 sensor_id,
  200. struct goodix_cfg_bin *cfg_bin)
  201. {
  202. int i;
  203. u8 cfg_type;
  204. u32 cfg_len;
  205. struct goodix_cfg_package *cfg_pkg;
  206. if (!cfg_bin->head.pkg_num || !cfg_bin->cfg_pkgs) {
  207. ts_err("there is none cfg package, pkg_num:%d",
  208. cfg_bin->head.pkg_num);
  209. return -EINVAL;
  210. }
  211. /* find cfg packages with same sensor_id */
  212. for (i = 0; i < cfg_bin->head.pkg_num; i++) {
  213. cfg_pkg = &cfg_bin->cfg_pkgs[i];
  214. if (sensor_id != cfg_pkg->cnst_info.sensor_id) {
  215. ts_info("pkg:%d, sensor id contrast FAILED, bin %d != %d",
  216. i, cfg_pkg->cnst_info.sensor_id, sensor_id);
  217. continue;
  218. }
  219. cfg_type = cfg_pkg->cnst_info.cfg_type;
  220. if (cfg_type >= GOODIX_MAX_CONFIG_GROUP) {
  221. ts_err("usupported config type %d",
  222. cfg_pkg->cnst_info.cfg_type);
  223. goto err_out;
  224. }
  225. cfg_len = cfg_pkg->pkg_len - TS_PKG_CONST_INFO_LEN -
  226. TS_PKG_REG_INFO_LEN;
  227. if (cfg_len > GOODIX_CFG_MAX_SIZE) {
  228. ts_err("config len exceed limit %d > %d",
  229. cfg_len, GOODIX_CFG_MAX_SIZE);
  230. goto err_out;
  231. }
  232. if (cd->ic_configs[cfg_type]) {
  233. ts_err("found same type config twice for sensor id %d, skiped",
  234. sensor_id);
  235. continue;
  236. }
  237. cd->ic_configs[cfg_type] = kzalloc(sizeof(struct goodix_ic_config), GFP_KERNEL);
  238. if (!cd->ic_configs[cfg_type])
  239. goto err_out;
  240. cd->ic_configs[cfg_type]->len = cfg_len;
  241. memcpy(cd->ic_configs[cfg_type]->data, cfg_pkg->cfg, cfg_len);
  242. ts_info("get config type %d, len %d, for sensor id %d",
  243. cfg_type, cfg_len, sensor_id);
  244. }
  245. return 0;
  246. err_out:
  247. /* parse config enter error, release memory alloced */
  248. for (i = 0; i < GOODIX_MAX_CONFIG_GROUP; i++) {
  249. if (cd->ic_configs[i])
  250. kfree(cd->ic_configs[i]);
  251. cd->ic_configs[i] = NULL;
  252. }
  253. return -EINVAL;
  254. }
  255. static int goodix_get_config_data(struct goodix_ts_core *cd, u8 sensor_id)
  256. {
  257. struct goodix_cfg_bin cfg_bin = {0};
  258. char *cfg_name = cd->board_data.cfg_bin_name;
  259. int ret;
  260. /*get cfg_bin from file system*/
  261. ret = goodix_read_cfg_bin(&cd->pdev->dev, cfg_name, &cfg_bin);
  262. if (ret) {
  263. ts_err("failed get valid config bin data");
  264. return ret;
  265. }
  266. /*parse cfg bin*/
  267. ret = goodix_parse_cfg_bin(&cfg_bin);
  268. if (ret) {
  269. ts_err("failed parse cfg bin");
  270. goto err_out;
  271. }
  272. /*get register address and configuration from cfg bin*/
  273. ret = goodix_get_reg_and_cfg(cd, sensor_id, &cfg_bin);
  274. if (!ret)
  275. ts_info("success get reg and cfg info from cfg bin");
  276. else
  277. ts_err("failed get cfg and reg info, update fw then retry");
  278. kfree(cfg_bin.cfg_pkgs);
  279. err_out:
  280. kfree(cfg_bin.bin_data);
  281. return ret;
  282. }
  283. int goodix_get_config_proc(struct goodix_ts_core *cd)
  284. {
  285. return goodix_get_config_data(cd, cd->fw_version.sensor_id);
  286. }