goodix_cfg_bin.c 9.0 KB

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