goodix_tool.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /* drivers/input/touchscreen/goodix_tool.c
  2. *
  3. * 2010 - 2012 Goodix Technology.
  4. * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be a reference
  12. * to you, when you are integrating the GOODiX's CTP IC into your system,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * Version:1.6
  18. * V1.0:2012/05/01,create file.
  19. * V1.2:2012/06/08,modify some warning.
  20. * V1.4:2012/08/28,modified to support GT9XX
  21. * V1.6:new proc name
  22. */
  23. #include "gt9xx.h"
  24. #include <linux/mutex.h>
  25. #include <linux/proc_fs.h>
  26. #include <linux/debugfs.h>
  27. #define DATA_LENGTH_UINT 512
  28. #define CMD_HEAD_LENGTH (sizeof(struct st_cmd_head) - sizeof(u8 *))
  29. static char procname[20] = {0};
  30. struct st_cmd_head {
  31. u8 wr; /* write read flag 0:R 1:W 2:PID 3: */
  32. u8 flag; /* 0:no need flag/int 1: need flag 2:need int */
  33. u8 flag_addr[2];/* flag address */
  34. u8 flag_val; /* flag val */
  35. u8 flag_relation; /* flag_val:flag 0:not equal 1:equal 2:> 3:< */
  36. u16 circle; /* polling cycle */
  37. u8 times; /* plling times */
  38. u8 retry; /* I2C retry times */
  39. u16 delay; /* delay befor read or after write */
  40. u16 data_len; /* data length */
  41. u8 addr_len; /* address length */
  42. u8 addr[2]; /* address */
  43. u8 res[3]; /* reserved */
  44. u8 *data; /* data pointer */
  45. } __packed;
  46. static struct st_cmd_head cmd_head;
  47. static struct i2c_client *gt_client;
  48. static struct proc_dir_entry *goodix_proc_entry;
  49. static struct mutex lock;
  50. static s32 (*tool_i2c_read)(u8 *, u16);
  51. static s32 (*tool_i2c_write)(u8 *, u16);
  52. s32 data_length;
  53. s8 ic_type[16] = {0};
  54. static void tool_set_proc_name(char *procname)
  55. {
  56. char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May",
  57. "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  58. char date[20] = {0};
  59. char month[4] = {0};
  60. int i = 0, n_month = 1, n_day = 0, n_year = 0;
  61. snprintf(date, 20, "%s", __DATE__);
  62. /* pr_debug("compile date: %s", date); */
  63. sscanf(date, "%s %d %d", month, &n_day, &n_year);
  64. for (i = 0; i < 12; ++i) {
  65. if (!memcmp(months[i], month, 3)) {
  66. n_month = i+1;
  67. break;
  68. }
  69. }
  70. snprintf(procname, 20, "gmnode%04d%02d%02d", n_year, n_month, n_day);
  71. /* pr_debug("procname = %s", procname); */
  72. }
  73. static s32 tool_i2c_read_no_extra(u8 *buf, u16 len)
  74. {
  75. s32 ret = -1;
  76. u8 i = 0;
  77. struct i2c_msg msgs[2] = {
  78. {
  79. .flags = !I2C_M_RD,
  80. .addr = gt_client->addr,
  81. .len = cmd_head.addr_len,
  82. .buf = &buf[0],
  83. },
  84. {
  85. .flags = I2C_M_RD,
  86. .addr = gt_client->addr,
  87. .len = len,
  88. .buf = &buf[GTP_ADDR_LENGTH],
  89. },
  90. };
  91. for (i = 0; i < cmd_head.retry; i++) {
  92. ret = i2c_transfer(gt_client->adapter, msgs, 2);
  93. if (ret > 0)
  94. break;
  95. }
  96. if (i == cmd_head.retry) {
  97. dev_err(&gt_client->dev, "I2C read retry limit over.\n");
  98. ret = -EIO;
  99. }
  100. return ret;
  101. }
  102. static s32 tool_i2c_write_no_extra(u8 *buf, u16 len)
  103. {
  104. s32 ret = -1;
  105. u8 i = 0;
  106. struct i2c_msg msg = {
  107. .flags = !I2C_M_RD,
  108. .addr = gt_client->addr,
  109. .len = len,
  110. .buf = buf,
  111. };
  112. for (i = 0; i < cmd_head.retry; i++) {
  113. ret = i2c_transfer(gt_client->adapter, &msg, 1);
  114. if (ret > 0)
  115. break;
  116. }
  117. if (i == cmd_head.retry) {
  118. dev_err(&gt_client->dev, "I2C write retry limit over.\n");
  119. ret = -EIO;
  120. }
  121. return ret;
  122. }
  123. static s32 tool_i2c_read_with_extra(u8 *buf, u16 len)
  124. {
  125. s32 ret = -1;
  126. u8 pre[2] = {0x0f, 0xff};
  127. u8 end[2] = {0x80, 0x00};
  128. tool_i2c_write_no_extra(pre, 2);
  129. ret = tool_i2c_read_no_extra(buf, len);
  130. tool_i2c_write_no_extra(end, 2);
  131. return ret;
  132. }
  133. static s32 tool_i2c_write_with_extra(u8 *buf, u16 len)
  134. {
  135. s32 ret = -1;
  136. u8 pre[2] = {0x0f, 0xff};
  137. u8 end[2] = {0x80, 0x00};
  138. tool_i2c_write_no_extra(pre, 2);
  139. ret = tool_i2c_write_no_extra(buf, len);
  140. tool_i2c_write_no_extra(end, 2);
  141. return ret;
  142. }
  143. static void register_i2c_func(void)
  144. {
  145. if (strcmp(ic_type, "GT8110") && strcmp(ic_type, "GT8105")
  146. && strcmp(ic_type, "GT801") && strcmp(ic_type, "GT800")
  147. && strcmp(ic_type, "GT801PLUS") && strcmp(ic_type, "GT811")
  148. && strcmp(ic_type, "GTxxx")) {
  149. tool_i2c_read = tool_i2c_read_with_extra;
  150. tool_i2c_write = tool_i2c_write_with_extra;
  151. pr_debug("I2C function: with pre and end cmd!");
  152. } else {
  153. tool_i2c_read = tool_i2c_read_no_extra;
  154. tool_i2c_write = tool_i2c_write_no_extra;
  155. pr_info("I2C function: without pre and end cmd!");
  156. }
  157. }
  158. static void unregister_i2c_func(void)
  159. {
  160. tool_i2c_read = NULL;
  161. tool_i2c_write = NULL;
  162. pr_info("I2C function: unregister i2c transfer function!");
  163. }
  164. void uninit_wr_node(void)
  165. {
  166. cmd_head.data = NULL;
  167. unregister_i2c_func();
  168. remove_proc_entry(procname, NULL);
  169. }
  170. static u8 relation(u8 src, u8 dst, u8 rlt)
  171. {
  172. u8 ret = 0;
  173. switch (rlt) {
  174. case 0:
  175. ret = (src != dst) ? true : false;
  176. break;
  177. case 1:
  178. ret = (src == dst) ? true : false;
  179. pr_debug("equal:src:0x%02x dst:0x%02x ret:%d.",
  180. src, dst, (s32)ret);
  181. break;
  182. case 2:
  183. ret = (src > dst) ? true : false;
  184. break;
  185. case 3:
  186. ret = (src < dst) ? true : false;
  187. break;
  188. case 4:
  189. ret = (src & dst) ? true : false;
  190. break;
  191. case 5:
  192. ret = (!(src | dst)) ? true : false;
  193. break;
  194. default:
  195. ret = false;
  196. break;
  197. }
  198. return ret;
  199. }
  200. /*******************************************************
  201. Function:
  202. Comfirm function.
  203. Input:
  204. None.
  205. Output:
  206. Return write length.
  207. ********************************************************/
  208. static u8 comfirm(void)
  209. {
  210. s32 i = 0;
  211. u8 buf[32];
  212. memcpy(buf, cmd_head.flag_addr, cmd_head.addr_len);
  213. for (i = 0; i < cmd_head.times; i++) {
  214. if (tool_i2c_read(buf, 1) <= 0) {
  215. dev_err(&gt_client->dev, "Read flag data failed!");
  216. return FAIL;
  217. }
  218. if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val,
  219. cmd_head.flag_relation)) {
  220. pr_debug("value at flag addr:0x%02x.",
  221. buf[GTP_ADDR_LENGTH]);
  222. pr_debug("flag value:0x%02x.", cmd_head.flag_val);
  223. break;
  224. }
  225. msleep(cmd_head.circle);
  226. }
  227. if (i >= cmd_head.times) {
  228. dev_err(&gt_client->dev, "Didn't get the flag to continue!");
  229. return FAIL;
  230. }
  231. return SUCCESS;
  232. }
  233. #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
  234. static s32 fill_update_info(char __user *user_buf,
  235. size_t count, loff_t *ppos)
  236. {
  237. u8 buf[4];
  238. buf[0] = show_len >> 8;
  239. buf[1] = show_len & 0xff;
  240. buf[2] = total_len >> 8;
  241. buf[3] = total_len & 0xff;
  242. return simple_read_from_buffer(user_buf, count, ppos,
  243. buf, sizeof(buf));
  244. }
  245. #else
  246. static s32 fill_update_info(char __user *user_buf,
  247. size_t count, loff_t *ppos)
  248. {
  249. return -ENODEV;
  250. }
  251. #endif
  252. /********************************************************
  253. Function:
  254. Goodix tool write function.
  255. nput:
  256. standard proc write function param.
  257. Output:
  258. Return write length.
  259. ********************************************************/
  260. static s32 goodix_tool_write(struct file *filp, const char __user *userbuf,
  261. size_t count, loff_t *ppos)
  262. {
  263. s32 ret = 0;
  264. u8 *dataptr = NULL;
  265. mutex_lock(&lock);
  266. ret = copy_from_user(&cmd_head, userbuf, CMD_HEAD_LENGTH);
  267. if (ret) {
  268. dev_err(&gt_client->dev, "copy_from_user failed.");
  269. ret = -EACCES;
  270. goto exit;
  271. }
  272. dev_dbg(&gt_client->dev, "wr:0x%02x, flag:0x%02x, flag addr:0x%02x%02x, flag val:0x%02x, flag rel:0x%02x, circle:%d, times:%d, retry:%d, delay:%d, data len:%d, addr len:%d, addr:0x%02x%02x, write len: %d.",
  273. cmd_head.wr, cmd_head.flag, cmd_head.flag_addr[0],
  274. cmd_head.flag_addr[1], cmd_head.flag_val,
  275. cmd_head.flag_relation, (s32)cmd_head.circle,
  276. (s32)cmd_head.times, (s32)cmd_head.retry, (s32)cmd_head.delay,
  277. (s32)cmd_head.data_len, (s32)cmd_head.addr_len,
  278. cmd_head.addr[0], cmd_head.addr[1], (s32)count);
  279. if (cmd_head.data_len > (data_length - GTP_ADDR_LENGTH)) {
  280. dev_err(&gt_client->dev, "data len %d > data buff %d, rejected!\n",
  281. cmd_head.data_len, (data_length - GTP_ADDR_LENGTH));
  282. ret = -EINVAL;
  283. goto exit;
  284. }
  285. if (cmd_head.addr_len > GTP_ADDR_LENGTH) {
  286. dev_err(&gt_client->dev, "addr len %d > data buff %d, rejected!\n",
  287. cmd_head.addr_len, GTP_ADDR_LENGTH);
  288. ret = -EINVAL;
  289. goto exit;
  290. }
  291. if (cmd_head.wr == GTP_RW_WRITE) {
  292. ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
  293. &userbuf[CMD_HEAD_LENGTH], cmd_head.data_len);
  294. if (ret) {
  295. dev_err(&gt_client->dev, "copy_from_user failed.");
  296. goto exit;
  297. }
  298. memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
  299. cmd_head.addr, cmd_head.addr_len);
  300. if (cmd_head.flag == GTP_NEED_FLAG) {
  301. if (comfirm() == FAIL) {
  302. dev_err(&gt_client->dev, "Comfirm fail!");
  303. ret = -EINVAL;
  304. goto exit;
  305. }
  306. } else if (cmd_head.flag == GTP_NEED_INTERRUPT) {
  307. /* Need interrupt! */
  308. }
  309. if (tool_i2c_write(
  310. &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
  311. cmd_head.data_len + cmd_head.addr_len) <= 0) {
  312. dev_err(&gt_client->dev, "Write data failed!");
  313. ret = -EIO;
  314. goto exit;
  315. }
  316. if (cmd_head.delay)
  317. msleep(cmd_head.delay);
  318. ret = cmd_head.data_len + CMD_HEAD_LENGTH;
  319. goto exit;
  320. } else if (cmd_head.wr == GTP_RW_WRITE_IC_TYPE) { /* Write ic type */
  321. ret = copy_from_user(&cmd_head.data[0],
  322. &userbuf[CMD_HEAD_LENGTH],
  323. cmd_head.data_len);
  324. if (ret) {
  325. dev_err(&gt_client->dev, "copy_from_user failed.");
  326. goto exit;
  327. }
  328. if (cmd_head.data_len > sizeof(ic_type)) {
  329. dev_err(&gt_client->dev,
  330. "data len %d > data buff %d, rejected!\n",
  331. cmd_head.data_len, sizeof(ic_type));
  332. ret = -EINVAL;
  333. goto exit;
  334. }
  335. memcpy(ic_type, cmd_head.data, cmd_head.data_len);
  336. register_i2c_func();
  337. ret = cmd_head.data_len + CMD_HEAD_LENGTH;
  338. goto exit;
  339. } else if (cmd_head.wr == GTP_RW_NO_WRITE) {
  340. ret = cmd_head.data_len + CMD_HEAD_LENGTH;
  341. goto exit;
  342. } else if (cmd_head.wr == GTP_RW_DISABLE_IRQ) { /* disable irq! */
  343. gtp_irq_disable(i2c_get_clientdata(gt_client));
  344. #if GTP_ESD_PROTECT
  345. gtp_esd_switch(gt_client, SWITCH_OFF);
  346. #endif
  347. ret = CMD_HEAD_LENGTH;
  348. goto exit;
  349. } else if (cmd_head.wr == GTP_RW_ENABLE_IRQ) { /* enable irq! */
  350. gtp_irq_enable(i2c_get_clientdata(gt_client));
  351. #if GTP_ESD_PROTECT
  352. gtp_esd_switch(gt_client, SWITCH_ON);
  353. #endif
  354. ret = CMD_HEAD_LENGTH;
  355. goto exit;
  356. } else if (cmd_head.wr == GTP_RW_CHECK_RAWDIFF_MODE) {
  357. struct goodix_ts_data *ts = i2c_get_clientdata(gt_client);
  358. ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
  359. &userbuf[CMD_HEAD_LENGTH], cmd_head.data_len);
  360. if (ret) {
  361. pr_debug("copy_from_user failed.");
  362. goto exit;
  363. }
  364. if (cmd_head.data[GTP_ADDR_LENGTH]) {
  365. pr_debug("gtp enter rawdiff.");
  366. ts->gtp_rawdiff_mode = true;
  367. } else {
  368. ts->gtp_rawdiff_mode = false;
  369. pr_debug("gtp leave rawdiff.");
  370. }
  371. ret = CMD_HEAD_LENGTH;
  372. goto exit;
  373. } else if (cmd_head.wr == GTP_RW_ENTER_UPDATE_MODE) {
  374. /* Enter update mode! */
  375. if (gup_enter_update_mode(gt_client) == FAIL) {
  376. ret = -EBUSY;
  377. goto exit;
  378. }
  379. } else if (cmd_head.wr == GTP_RW_LEAVE_UPDATE_MODE) {
  380. /* Leave update mode! */
  381. gup_leave_update_mode(gt_client);
  382. } else if (cmd_head.wr == GTP_RW_UPDATE_FW) {
  383. /* Update firmware! */
  384. show_len = 0;
  385. total_len = 0;
  386. if (cmd_head.data_len + 1 > data_length) {
  387. dev_err(&gt_client->dev, "data len %d > data buff %d, rejected!\n",
  388. cmd_head.data_len + 1, data_length);
  389. ret = -EINVAL;
  390. goto exit;
  391. }
  392. memset(cmd_head.data, 0, cmd_head.data_len + 1);
  393. memcpy(cmd_head.data, &userbuf[CMD_HEAD_LENGTH],
  394. cmd_head.data_len);
  395. if (gup_update_proc((void *)cmd_head.data) == FAIL) {
  396. ret = -EBUSY;
  397. goto exit;
  398. }
  399. }
  400. ret = CMD_HEAD_LENGTH;
  401. exit:
  402. dataptr = cmd_head.data;
  403. memset(&cmd_head, 0, sizeof(cmd_head));
  404. cmd_head.wr = 0xFF;
  405. cmd_head.data = dataptr;
  406. mutex_unlock(&lock);
  407. return ret;
  408. }
  409. /*******************************************************
  410. Function:
  411. Goodix tool read function.
  412. Input:
  413. standard seq file read function param.
  414. Output:
  415. Return read length.
  416. ********************************************************/
  417. static s32 goodix_tool_read(struct file *file, char __user *user_buf,
  418. size_t count, loff_t *ppos)
  419. {
  420. u16 data_len = 0;
  421. s32 ret;
  422. u8 buf[32];
  423. mutex_lock(&lock);
  424. if (cmd_head.wr & 0x1) {
  425. dev_err(&gt_client->dev, "command head wrong\n");
  426. ret = -EINVAL;
  427. goto exit;
  428. }
  429. switch (cmd_head.wr) {
  430. case GTP_RW_READ:
  431. if (cmd_head.flag == GTP_NEED_FLAG) {
  432. if (comfirm() == FAIL) {
  433. dev_err(&gt_client->dev, "Comfirm fail!");
  434. ret = -EINVAL;
  435. goto exit;
  436. }
  437. } else if (cmd_head.flag == GTP_NEED_INTERRUPT) {
  438. /* Need interrupt! */
  439. }
  440. memcpy(cmd_head.data, cmd_head.addr, cmd_head.addr_len);
  441. pr_debug("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head.data[0],
  442. cmd_head.data[1]);
  443. pr_debug("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head.addr[0],
  444. cmd_head.addr[1]);
  445. if (cmd_head.delay)
  446. msleep(cmd_head.delay);
  447. data_len = cmd_head.data_len;
  448. if (data_len <= 0 || (data_len > data_length)) {
  449. dev_err(&gt_client->dev, "Invalid data length %d\n",
  450. data_len);
  451. ret = -EINVAL;
  452. goto exit;
  453. }
  454. if (data_len > count)
  455. data_len = count;
  456. if (tool_i2c_read(cmd_head.data, data_len) <= 0) {
  457. dev_err(&gt_client->dev, "Read data failed!\n");
  458. ret = -EIO;
  459. goto exit;
  460. }
  461. ret = simple_read_from_buffer(user_buf, count, ppos,
  462. &cmd_head.data[GTP_ADDR_LENGTH], data_len);
  463. break;
  464. case GTP_RW_FILL_INFO:
  465. ret = fill_update_info(user_buf, count, ppos);
  466. break;
  467. case GTP_RW_READ_VERSION:
  468. /* Read driver version */
  469. data_len = scnprintf(buf, sizeof(buf), "%s\n",
  470. GTP_DRIVER_VERSION);
  471. ret = simple_read_from_buffer(user_buf, count, ppos,
  472. buf, data_len);
  473. break;
  474. default:
  475. ret = -EINVAL;
  476. break;
  477. }
  478. exit:
  479. mutex_unlock(&lock);
  480. return ret;
  481. }
  482. static const struct file_operations goodix_proc_fops = {
  483. .write = goodix_tool_write,
  484. .read = goodix_tool_read,
  485. .open = simple_open,
  486. .owner = THIS_MODULE,
  487. };
  488. s32 init_wr_node(struct i2c_client *client)
  489. {
  490. u8 i;
  491. gt_client = client;
  492. memset(&cmd_head, 0, sizeof(cmd_head));
  493. cmd_head.data = NULL;
  494. i = GTP_I2C_RETRY_5;
  495. while ((!cmd_head.data) && i) {
  496. cmd_head.data = devm_kzalloc(&client->dev,
  497. i * DATA_LENGTH_UINT, GFP_KERNEL);
  498. if (cmd_head.data)
  499. break;
  500. i--;
  501. }
  502. if (i) {
  503. data_length = i * DATA_LENGTH_UINT;
  504. dev_dbg(&client->dev, "Applied memory size:%d.", data_length);
  505. } else {
  506. dev_err(&client->dev, "Apply for memory failed.");
  507. return FAIL;
  508. }
  509. cmd_head.addr_len = 2;
  510. cmd_head.retry = GTP_I2C_RETRY_5;
  511. register_i2c_func();
  512. mutex_init(&lock);
  513. tool_set_proc_name(procname);
  514. goodix_proc_entry = proc_create(procname,
  515. S_IWUSR | S_IWGRP | S_IRUSR | S_IRGRP,
  516. goodix_proc_entry,
  517. &goodix_proc_fops);
  518. if (goodix_proc_entry == NULL) {
  519. dev_err(&client->dev, "Couldn't create proc entry!");
  520. return FAIL;
  521. }
  522. return SUCCESS;
  523. }