1 /*
2 *
3 * FocalTech fts TouchScreen driver.
4 *
5 * Copyright (c) 2012-2018, Focaltech Ltd. All rights reserved.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18 /*****************************************************************************
19 *
20 * File Name: focaltech_flash.c
21 *
22 * Author: Focaltech Driver Team
23 *
24 * Created: 2016-08-08
25 *
26 * Abstract:
27 *
28 * Reference:
29 *
30 *****************************************************************************/
31
32 /*****************************************************************************
33 * 1.Included header files
34 *****************************************************************************/
35 #include "focaltech_core.h"
36 #include "focaltech_flash.h"
37
38 #define vfs_read(fp, buf, len, pos) kernel_read(fp, buf, len, pos)
39 /*****************************************************************************
40 * Static variables
41 *****************************************************************************/
42
43 /*****************************************************************************
44 * Global variable or extern global variabls/functions
45 *****************************************************************************/
46 /* Upgrade FW/PRAMBOOT/LCD CFG */
47 u8 fw_file[] = {
48 #include FTS_UPGRADE_FW_FILE
49 };
50
51 u8 fw_file2[] = {
52 #include FTS_UPGRADE_FW2_FILE
53 };
54
55 u8 fw_file3[] = {
56 #include FTS_UPGRADE_FW3_FILE
57 };
58
59 struct upgrade_fw fw_list[] = {
60 {FTS_VENDOR_ID, fw_file, sizeof(fw_file)},
61 {FTS_VENDOR_ID2, fw_file2, sizeof(fw_file2)},
62 {FTS_VENDOR_ID3, fw_file3, sizeof(fw_file3)},
63 };
64
65 struct upgrade_func *upgrade_func_list[] = {
66 &upgrade_func_ft8006m,
67 };
68
69 struct fts_upgrade *fwupgrade = NULL;
70
71 /*****************************************************************************
72 * Static function prototypes
73 *****************************************************************************/
fts_crc16_calc_host(u8 * pbuf,u16 length)74 u16 fts_crc16_calc_host(u8 *pbuf, u16 length)
75 {
76 u16 ecc = 0;
77 u16 i = 0;
78 u16 j = 0;
79
80 for ( i = 0; i < length; i += 2 ) {
81 ecc ^= ((pbuf[i] << 8) | (pbuf[i + 1]));
82 for (j = 0; j < 16; j ++) {
83 if (ecc & 0x01)
84 ecc = (u16)((ecc >> 1) ^ AL2_FCS_COEF);
85 else
86 ecc >>= 1;
87 }
88 }
89
90 return ecc;
91 }
92
fts_pram_ecc_calc_host(u8 * pbuf,u16 length)93 static u16 fts_pram_ecc_calc_host(u8 *pbuf, u16 length)
94 {
95 return fts_crc16_calc_host(pbuf, length);
96 }
97
98
99 /************************************************************************
100 * fts_pram_ecc_cal - Calculate and get pramboot ecc
101 *
102 * return pramboot ecc of tp if success, otherwise return error code
103 ***********************************************************************/
fts_pram_ecc_cal_algo(struct i2c_client * client,u32 start_addr,u32 ecc_length)104 static int fts_pram_ecc_cal_algo(
105 struct i2c_client *client,
106 u32 start_addr,
107 u32 ecc_length)
108 {
109 int ret = 0;
110 int i = 0;
111 int ecc = 0;
112 u8 val[2] = { 0 };
113 u8 cmd[FTS_ROMBOOT_CMD_ECC_NEW_LEN] = { 0 };
114
115 FTS_INFO("read out pramboot checksum");
116 cmd[0] = FTS_ROMBOOT_CMD_ECC;
117 cmd[1] = BYTE_OFF_16(start_addr);
118 cmd[2] = BYTE_OFF_8(start_addr);
119 cmd[3] = BYTE_OFF_0(start_addr);
120 cmd[4] = BYTE_OFF_16(ecc_length);
121 cmd[5] = BYTE_OFF_8(ecc_length);
122 cmd[6] = BYTE_OFF_0(ecc_length);
123 ret = fts_i2c_write(client, cmd, FTS_ROMBOOT_CMD_ECC_NEW_LEN);
124 if (ret < 0) {
125 FTS_ERROR("write pramboot ecc cal cmd fail");
126 return ret;
127 }
128
129 cmd[0] = FTS_ROMBOOT_CMD_ECC_FINISH;
130 for (i = 0; i < 100; i++) {
131 msleep(1);
132 ret = fts_i2c_read(client, cmd, 1, val, 1);
133 if (ret < 0) {
134 FTS_ERROR("ecc_finish read cmd fail");
135 return ret;
136 }
137 if (0 == val[0])
138 break;
139 }
140 if (i >= 100) {
141 FTS_ERROR("wait ecc finish fail");
142 return -EIO;
143 }
144
145 cmd[0] = FTS_CMD_READ_ECC;
146 ret = fts_i2c_read(client, cmd, 1, val, 2);
147 if (ret < 0) {
148 FTS_ERROR("read pramboot ecc fail");
149 return ret;
150 }
151
152 ecc = ((u16)(val[0] << 8) + val[1]) & 0x0000FFFF;
153 return ecc;
154 }
155
fts_pram_ecc_cal_xor(struct i2c_client * client)156 static int fts_pram_ecc_cal_xor(struct i2c_client *client)
157 {
158 int ret = 0;
159 u8 reg_val = 0;
160
161 FTS_INFO("read out pramboot checksum");
162
163 ret = fts_i2c_read_reg(client, FTS_ROMBOOT_CMD_ECC, ®_val);
164 if (ret < 0) {
165 FTS_ERROR("read pramboot ecc fail");
166 return ret;
167 }
168
169 return (int)reg_val;
170 }
171
fts_pram_ecc_cal(struct i2c_client * client,u32 saddr,u32 len)172 static int fts_pram_ecc_cal(struct i2c_client *client, u32 saddr, u32 len)
173 {
174 if ((NULL == fwupgrade) || (NULL == fwupgrade->func)) {
175 FTS_ERROR("fwupgrade/func is null");
176 return -EINVAL;
177 }
178
179 if (fwupgrade->func->newmode) {
180 return fts_pram_ecc_cal_algo(client, saddr, len);
181 } else {
182 return fts_pram_ecc_cal_xor(client);
183 }
184 }
185
186 /************************************************************************
187 * fts_pram_write_buf - write pramboot data and calculate ecc
188 *
189 * return pramboot ecc of host if success, otherwise return error code
190 ***********************************************************************/
fts_pram_write_buf(struct i2c_client * client,u8 * buf,u32 len)191 static int fts_pram_write_buf(struct i2c_client *client, u8 *buf, u32 len)
192 {
193 int ret = 0;
194 u32 i = 0;
195 u32 j = 0;
196 u32 offset = 0;
197 u32 remainder = 0;
198 u32 packet_number;
199 u32 packet_len = 0;
200 u8 packet_buf[FTS_FLASH_PACKET_LENGTH + FTS_CMD_WRITE_LEN] = { 0 };
201 u8 ecc_tmp = 0;
202 int ecc_in_host = 0;
203
204 FTS_INFO("write pramboot to pram");
205 if ((NULL == fwupgrade) || (NULL == fwupgrade->func)) {
206 FTS_ERROR("fwupgrade/func is null");
207 return -EINVAL;
208 }
209
210 if (NULL == buf) {
211 FTS_ERROR("pramboot buf is null");
212 return -EINVAL;
213 }
214
215 FTS_INFO("pramboot len=%d", len);
216 if ((len < PRAMBOOT_MIN_SIZE) || (len > PRAMBOOT_MAX_SIZE)) {
217 FTS_ERROR("pramboot length(%d) fail", len);
218 return -EINVAL;
219 }
220
221 packet_number = len / FTS_FLASH_PACKET_LENGTH;
222 remainder = len % FTS_FLASH_PACKET_LENGTH;
223 if (remainder > 0)
224 packet_number++;
225 packet_len = FTS_FLASH_PACKET_LENGTH;
226
227 packet_buf[0] = FTS_ROMBOOT_CMD_WRITE;
228 for (i = 0; i < packet_number; i++) {
229 offset = i * FTS_FLASH_PACKET_LENGTH;
230 packet_buf[1] = BYTE_OFF_16(offset);
231 packet_buf[2] = BYTE_OFF_8(offset);
232 packet_buf[3] = BYTE_OFF_0(offset);
233
234 /* last packet */
235 if ((i == (packet_number - 1)) && remainder)
236 packet_len = remainder;
237
238 packet_buf[4] = BYTE_OFF_8(packet_len);
239 packet_buf[5] = BYTE_OFF_0(packet_len);
240
241 for (j = 0; j < packet_len; j++) {
242 packet_buf[FTS_CMD_WRITE_LEN + j] = buf[offset + j];
243 if (!fwupgrade->func->newmode) {
244 ecc_tmp ^= packet_buf[FTS_CMD_WRITE_LEN + j];
245 }
246 }
247
248 ret = fts_i2c_write(client, packet_buf, packet_len + FTS_CMD_WRITE_LEN);
249 if (ret < 0) {
250 FTS_ERROR("pramboot write data(%d) fail", i);
251 return ret;
252 }
253 }
254
255 if (fwupgrade->func->newmode) {
256 ecc_in_host = (int)fts_pram_ecc_calc_host(buf, len);
257 } else {
258 ecc_in_host = (int)ecc_tmp;
259 }
260
261 return ecc_in_host;
262 }
263
264 /************************************************************************
265 * fts_pram_start - remap to start pramboot
266 *
267 * return 0 if success, otherwise return error code
268 ***********************************************************************/
fts_pram_start(struct i2c_client * client)269 static int fts_pram_start(struct i2c_client *client)
270 {
271 u8 cmd = FTS_ROMBOOT_CMD_START_APP;
272 int ret = 0;
273
274 FTS_INFO("remap to start pramboot");
275
276 ret = fts_i2c_write(client, &cmd, 1);
277 if (ret < 0) {
278 FTS_ERROR("write start pram cmd fail");
279 return ret;
280 }
281 msleep(FTS_DELAY_PRAMBOOT_START);
282
283 return 0;
284 }
285
286 /************************************************************************
287 * fts_pram_write_remap - write pramboot to pram and start pramboot
288 *
289 * return 0 if success, otherwise return error code
290 ***********************************************************************/
fts_pram_write_remap(struct i2c_client * client)291 static int fts_pram_write_remap(struct i2c_client *client)
292 {
293 int ret = 0;
294 int ecc_in_host = 0;
295 int ecc_in_tp = 0;
296 u8 *pb_buf = NULL;
297 u32 pb_len = 0;
298 struct fts_upgrade *upg = fwupgrade;
299
300 FTS_INFO("write pram and remap");
301
302 if (!upg || !upg->func || !upg->func->pramboot) {
303 FTS_ERROR("upgrade/pramboot is null");
304 return -EINVAL;
305 }
306
307 if (upg->func->pb_length < FTS_MIN_LEN) {
308 FTS_ERROR("pramboot length(%d) fail", upg->func->pb_length);
309 return -EINVAL;
310 }
311
312 pb_buf = upg->func->pramboot;
313 pb_len = upg->func->pb_length;
314
315 /* write pramboot to pram */
316 ecc_in_host = fts_pram_write_buf(client, pb_buf, pb_len);
317 if (ecc_in_host < 0) {
318 FTS_ERROR( "write pramboot fail");
319 return ecc_in_host;
320 }
321
322 /* read out checksum */
323 ecc_in_tp = fts_pram_ecc_cal(client, 0, pb_len);
324 if (ecc_in_tp < 0) {
325 FTS_ERROR( "read pramboot ecc fail");
326 return ecc_in_tp;
327 }
328
329 FTS_INFO("pram ecc in tp:%x, host:%x", ecc_in_tp, ecc_in_host);
330 /* pramboot checksum != fw checksum, upgrade fail */
331 if (ecc_in_host != ecc_in_tp) {
332 FTS_ERROR("pramboot ecc check fail");
333 return -EIO;
334 }
335
336 /*start pram*/
337 ret = fts_pram_start(client);
338 if (ret < 0) {
339 FTS_ERROR("pram start fail");
340 return ret;
341 }
342
343 return 0;
344 }
345
346 /************************************************************************
347 * fts_pram_init - initialize pramboot
348 *
349 * return 0 if success, otherwise return error code
350 ***********************************************************************/
fts_pram_init(struct i2c_client * client)351 static int fts_pram_init(struct i2c_client *client)
352 {
353 int ret = 0;
354 u8 reg_val = 0;
355 u8 wbuf[3] = { 0 };
356
357 FTS_INFO("pramboot initialization");
358
359 /* read flash ID */
360 wbuf[0] = FTS_CMD_FLASH_TYPE;
361 ret = fts_i2c_read(client, wbuf, 1, ®_val, 1);
362 if (ret < 0) {
363 FTS_ERROR("read flash type fail");
364 return ret;
365 }
366
367 /* set flash clk */
368 wbuf[0] = FTS_CMD_FLASH_TYPE;
369 wbuf[1] = reg_val;
370 wbuf[2] = 0x00;
371 ret = fts_i2c_write(client, wbuf, 3);
372 if (ret < 0) {
373 FTS_ERROR("write flash type fail");
374 return ret;
375 }
376
377 return 0;
378 }
379
380 /************************************************************************
381 * Name: fts_pram_write_init
382 * Brief: wirte pramboot to pram and initialize
383 * Input:
384 * Output:
385 * Return: return 0 if success, otherwise return error code
386 ***********************************************************************/
fts_pram_write_init(struct i2c_client * client)387 static int fts_pram_write_init(struct i2c_client *client)
388 {
389 int ret = 0;
390 bool state = 0;
391 enum FW_STATUS status = FTS_RUN_IN_ERROR;
392 struct fts_upgrade *upg = fwupgrade;
393
394 FTS_INFO("**********pram write and init**********");
395 if ((NULL == upg) || (NULL == upg->func)) {
396 FTS_ERROR("upgrade/func is null");
397 return -EINVAL;
398 }
399
400 if (!upg->func->pramboot_supported) {
401 FTS_ERROR("ic not support pram");
402 return -EINVAL;
403 }
404
405 FTS_DEBUG("check whether tp is in romboot or not ");
406 /* need reset to romboot when non-romboot state */
407 fts_fwupg_get_boot_state(client, &status);
408 if (status != FTS_RUN_IN_ROM) {
409 if (FTS_RUN_IN_PRAM == status) {
410 FTS_INFO("tp is in pramboot, need send reset cmd before upgrade");
411 ret = fts_pram_init(client);
412 if (ret < 0) {
413 FTS_ERROR("pramboot(before) init fail");
414 return ret;
415 }
416 }
417
418 FTS_INFO("tp isn't in romboot, need send reset to romboot");
419 ret = fts_fwupg_reset_to_romboot(client);
420 if (ret < 0) {
421 FTS_ERROR("reset to romboot fail");
422 return ret;
423 }
424 }
425
426 /* check the length of the pramboot */
427 ret = fts_pram_write_remap(client);
428 if (ret < 0) {
429 FTS_ERROR("pram write fail, ret=%d", ret);
430 return ret;
431 }
432
433 FTS_DEBUG("after write pramboot, confirm run in pramboot");
434 state = fts_fwupg_check_state(client, FTS_RUN_IN_PRAM);
435 if (!state) {
436 FTS_ERROR("not in pramboot");
437 return -EIO;
438 }
439
440 ret = fts_pram_init(client);
441 if (ret < 0) {
442 FTS_ERROR("pramboot init fail");
443 return ret;
444 }
445
446 return 0;
447 }
448
449 /************************************************************************
450 * Name: fts_fwupg_check_fw_valid
451 * Brief: check fw in tp is valid or not
452 * Input:
453 * Output:
454 * Return: return true if fw is valid, otherwise return false
455 ***********************************************************************/
fts_fwupg_check_fw_valid(struct i2c_client * client)456 bool fts_fwupg_check_fw_valid(struct i2c_client *client)
457 {
458 int ret = 0;
459
460 ret = fts_wait_tp_to_valid(client);
461 if (ret < 0) {
462 FTS_INFO("tp fw invaild");
463 return false;
464 }
465
466 FTS_INFO("tp fw vaild");
467 return true;
468 }
469
470 /************************************************************************
471 * Name: fts_fwupg_get_boot_state
472 * Brief: read boot id(rom/pram/bootloader), confirm boot environment
473 * Input:
474 * Output:
475 * Return: return 0 if success, otherwise return error code
476 ***********************************************************************/
fts_fwupg_get_boot_state(struct i2c_client * client,enum FW_STATUS * fw_sts)477 int fts_fwupg_get_boot_state(struct i2c_client *client, enum FW_STATUS *fw_sts)
478 {
479 int ret = 0;
480 u8 cmd[4] = { 0 };
481 u32 cmd_len = 0;
482 u8 val[2] = { 0 };
483 struct ft_chip_t ids = fts_data->ic_info.ids;
484 struct fts_upgrade *upg = fwupgrade;
485
486 FTS_INFO("**********read boot id**********");
487 if ((NULL == fw_sts) || (NULL == upg) || (NULL == upg->func)) {
488 FTS_ERROR("upgrade/func/fw_sts is null");
489 return -EINVAL;
490 }
491
492 if (upg->func->hid_supported)
493 fts_i2c_hid2std(client);
494
495 cmd[0] = FTS_CMD_START1;
496 cmd[1] = FTS_CMD_START2;
497 ret = fts_i2c_write(client, cmd, 2);
498 if (ret < 0) {
499 FTS_ERROR("write 55 aa cmd fail");
500 return ret;
501 }
502
503 msleep(FTS_CMD_START_DELAY);
504 cmd[0] = FTS_CMD_READ_ID;
505 cmd[1] = cmd[2] = cmd[3] = 0x00;
506 if (fts_data->ic_info.is_incell)
507 cmd_len = FTS_CMD_READ_ID_LEN_INCELL;
508 else
509 cmd_len = FTS_CMD_READ_ID_LEN;
510 ret = fts_i2c_read(client, cmd, cmd_len, val, 2);
511 if (ret < 0) {
512 FTS_ERROR("write 90 cmd fail");
513 return ret;
514 }
515
516 FTS_INFO("read boot id:0x%02x%02x", val[0], val[1]);
517 if ((val[0] == ids.rom_idh) && (val[1] == ids.rom_idl)) {
518 FTS_INFO("tp run in romboot");
519 *fw_sts = FTS_RUN_IN_ROM;
520 } else if ((val[0] == ids.pb_idh) && (val[1] == ids.pb_idl)) {
521 FTS_INFO("tp run in pramboot");
522 *fw_sts = FTS_RUN_IN_PRAM;
523 } else if ((val[0] == ids.bl_idh) && (val[1] == ids.bl_idl)) {
524 FTS_INFO("tp run in bootloader");
525 *fw_sts = FTS_RUN_IN_BOOTLOADER;
526 }
527
528 return 0;
529 }
530
531 /************************************************************************
532 * Name: fts_fwupg_check_state
533 * Brief: confirm tp run in romboot/pramboot/bootloader
534 * Input:
535 * Output:
536 * Return: return true if state is match, otherwise return false
537 ***********************************************************************/
fts_fwupg_check_state(struct i2c_client * client,enum FW_STATUS rstate)538 bool fts_fwupg_check_state(struct i2c_client *client, enum FW_STATUS rstate)
539 {
540 int i = 0;
541 enum FW_STATUS cstate = FTS_RUN_IN_ERROR;
542
543 for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
544 fts_fwupg_get_boot_state(client, &cstate);
545 /* FTS_DEBUG("fw state=%d, retries=%d", cstate, i); */
546 if (cstate == rstate)
547 return true;
548 msleep(FTS_DELAY_READ_ID);
549 }
550
551 return false;
552 }
553
554 /************************************************************************
555 * Name: fts_fwupg_reset_in_boot
556 * Brief: RST CMD(07), reset to romboot(bootloader) in boot environment
557 * Input:
558 * Output:
559 * Return: return 0 if success, otherwise return error code
560 ***********************************************************************/
fts_fwupg_reset_in_boot(struct i2c_client * client)561 int fts_fwupg_reset_in_boot(struct i2c_client *client)
562 {
563 int ret = 0;
564 u8 cmd = FTS_CMD_RESET;
565
566 FTS_INFO("reset in boot environment");
567 ret = fts_i2c_write(client, &cmd, 1);
568 if (ret < 0) {
569 FTS_ERROR("pram/rom/bootloader reset cmd write fail");
570 return ret;
571 }
572
573 msleep(FTS_DELAY_UPGRADE_RESET);
574 return 0;
575 }
576
577 /************************************************************************
578 * Name: fts_fwupg_reset_to_boot
579 * Brief: reset to boot environment
580 * Input:
581 * Output:
582 * Return: return 0 if success, otherwise return error code
583 ***********************************************************************/
fts_fwupg_reset_to_boot(struct i2c_client * client)584 int fts_fwupg_reset_to_boot(struct i2c_client *client)
585 {
586 int ret = 0;
587
588 FTS_INFO("send 0xAA and 0x55 to FW, reset to boot environment");
589
590 ret = fts_i2c_write_reg(client, FTS_REG_UPGRADE, FTS_UPGRADE_AA);
591 if (ret < 0) {
592 FTS_ERROR("write FC=0xAA fail");
593 return ret;
594 }
595 msleep(FTS_DELAY_FC_AA);
596
597 ret = fts_i2c_write_reg(client, FTS_REG_UPGRADE, FTS_UPGRADE_55);
598 if (ret < 0) {
599 FTS_ERROR("write FC=0x55 fail");
600 return ret;
601 }
602
603 msleep(FTS_DELAY_UPGRADE_RESET);
604 return 0;
605 }
606
607 /************************************************************************
608 * Name: fts_fwupg_reset_to_romboot
609 * Brief: reset to romboot, to load pramboot
610 * Input:
611 * Output:
612 * Return: return 0 if success, otherwise return error code
613 ***********************************************************************/
fts_fwupg_reset_to_romboot(struct i2c_client * client)614 int fts_fwupg_reset_to_romboot(struct i2c_client *client)
615 {
616 int ret = 0;
617 int i = 0;
618 u8 cmd = FTS_CMD_RESET;
619 enum FW_STATUS state = FTS_RUN_IN_ERROR;
620
621 ret = fts_i2c_write(client, &cmd, 1);
622 if (ret < 0) {
623 FTS_ERROR("pram/rom/bootloader reset cmd write fail");
624 return ret;
625 }
626 mdelay(10);
627
628 for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
629 fts_fwupg_get_boot_state(client, &state);
630 if (FTS_RUN_IN_ROM == state)
631 break;
632 mdelay(5);
633 }
634 if (i >= FTS_UPGRADE_LOOP) {
635 FTS_ERROR("reset to romboot fail");
636 return -EIO;
637 }
638
639 return 0;
640 }
641
642 /************************************************************************
643 * Name: fts_fwupg_enter_into_boot
644 * Brief: enter into boot environment, ready for upgrade
645 * Input:
646 * Output:
647 * Return: return 0 if success, otherwise return error code
648 ***********************************************************************/
fts_fwupg_enter_into_boot(struct i2c_client * client)649 int fts_fwupg_enter_into_boot(struct i2c_client *client)
650 {
651 int ret = 0;
652 bool fwvalid = false;
653 bool state = false;
654 struct fts_upgrade *upg = fwupgrade;
655
656 FTS_INFO("***********enter into pramboot/bootloader***********");
657 if ((NULL == upg) || (NULL == upg->func)) {
658 FTS_ERROR("upgrade/func is null");
659 return -EINVAL;
660 }
661
662 fwvalid = fts_fwupg_check_fw_valid(client);
663 if (fwvalid) {
664 ret = fts_fwupg_reset_to_boot(client);
665 if (ret < 0) {
666 FTS_ERROR("enter into romboot/bootloader fail");
667 return ret;
668 }
669 } else if (upg->func->read_boot_id_need_reset) {
670 ret = fts_fwupg_reset_in_boot(client);
671 if (ret < 0) {
672 FTS_ERROR("reset before read boot id when fw invalid fail");
673 return ret;
674 }
675 }
676
677 if (upg->func->pramboot_supported) {
678 FTS_INFO("pram supported, write pramboot and init");
679 /* pramboot */
680 ret = fts_pram_write_init(client);
681 if (ret < 0) {
682 FTS_ERROR("pram write_init fail");
683 return ret;
684 }
685 } else {
686 FTS_DEBUG("pram not supported, confirm in bootloader");
687 /* bootloader */
688 state = fts_fwupg_check_state(client, FTS_RUN_IN_BOOTLOADER);
689 if (!state) {
690 FTS_ERROR("fw not in bootloader, fail");
691 return -EIO;
692 }
693 }
694
695 return 0;
696 }
697
698 /************************************************************************
699 * Name: fts_fwupg_check_flash_status
700 * Brief: read status from tp
701 * Input: flash_status: correct value from tp
702 * retries: read retry times
703 * retries_delay: retry delay
704 * Output:
705 * Return: return true if flash status check pass, otherwise return false
706 ***********************************************************************/
fts_fwupg_check_flash_status(struct i2c_client * client,u16 flash_status,int retries,int retries_delay)707 static bool fts_fwupg_check_flash_status(
708 struct i2c_client *client,
709 u16 flash_status,
710 int retries,
711 int retries_delay)
712 {
713 int i = 0;
714 u8 cmd = 0;
715 u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
716 u16 read_status = 0;
717
718 for (i = 0; i < retries; i++) {
719 cmd = FTS_CMD_FLASH_STATUS;
720 fts_i2c_read(client, &cmd , 1, val, FTS_CMD_FLASH_STATUS_LEN);
721 read_status = (((u16)val[0]) << 8) + val[1];
722 if (flash_status == read_status) {
723 /* FTS_DEBUG("[UPGRADE]flash status ok"); */
724 return true;
725 }
726 /* FTS_DEBUG("flash status fail,ok:%04x read:%04x, retries:%d", flash_status, read_status, i); */
727 msleep(retries_delay);
728 }
729
730 return false;
731 }
732
733 /************************************************************************
734 * Name: fts_fwupg_erase
735 * Brief: erase flash area
736 * Input: delay - delay after erase
737 * Output:
738 * Return: return 0 if success, otherwise return error code
739 ***********************************************************************/
fts_fwupg_erase(struct i2c_client * client,u32 delay)740 int fts_fwupg_erase(struct i2c_client *client, u32 delay)
741 {
742 int ret = 0;
743 u8 cmd = 0;
744 bool flag = false;
745
746 FTS_INFO("**********erase now**********");
747
748 /*send to erase flash*/
749 cmd = FTS_CMD_ERASE_APP;
750 ret = fts_i2c_write(client, &cmd, 1);
751 if (ret < 0) {
752 FTS_ERROR("erase cmd fail");
753 return ret;
754 }
755 msleep(delay);
756
757 /* read status 0xF0AA: success */
758 flag = fts_fwupg_check_flash_status(client, FTS_CMD_FLASH_STATUS_ERASE_OK,
759 FTS_RETRIES_REASE, FTS_RETRIES_DELAY_REASE);
760 if (!flag) {
761 FTS_ERROR("ecc flash status check fail");
762 return -EIO;
763 }
764
765 return 0;
766 }
767
768 /************************************************************************
769 * Name: fts_fwupg_ecc_cal
770 * Brief: calculate and get ecc from tp
771 * Input: saddr - start address need calculate ecc
772 * len - length need calculate ecc
773 * Output:
774 * Return: return data ecc of tp if success, otherwise return error code
775 ***********************************************************************/
fts_fwupg_ecc_cal(struct i2c_client * client,u32 saddr,u32 len)776 int fts_fwupg_ecc_cal(struct i2c_client *client, u32 saddr, u32 len)
777 {
778 int ret = 0;
779 u32 i = 0;
780 u8 wbuf[FTS_CMD_ECC_CAL_LEN] = { 0 };
781 u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
782 int ecc = 0;
783 int ecc_len = 0;
784 u32 packet_num = 0;
785 u32 packet_len = 0;
786 u32 remainder = 0;
787 u32 addr = 0;
788 u32 offset = 0;
789 struct fts_upgrade *upg = fwupgrade;
790
791 FTS_INFO( "**********read out checksum**********");
792 if ((NULL == upg) || (NULL == upg->func)) {
793 FTS_ERROR("upgrade/func is null");
794 return -EINVAL;
795 }
796
797 /* check sum init */
798 wbuf[0] = FTS_CMD_ECC_INIT;
799 ret = fts_i2c_write(client, wbuf, 1);
800 if (ret < 0) {
801 FTS_ERROR("ecc init cmd write fail");
802 return ret;
803 }
804
805 packet_num = len / FTS_MAX_LEN_ECC_CALC;
806 remainder = len % FTS_MAX_LEN_ECC_CALC;
807 if (remainder)
808 packet_num++;
809 packet_len = FTS_MAX_LEN_ECC_CALC;
810 FTS_INFO("ecc calc num:%d, remainder:%d", packet_num, remainder);
811
812 /* send commond to start checksum */
813 wbuf[0] = FTS_CMD_ECC_CAL;
814 for (i = 0; i < packet_num; i++) {
815 offset = FTS_MAX_LEN_ECC_CALC * i;
816 addr = saddr + offset;
817 wbuf[1] = BYTE_OFF_16(addr);
818 wbuf[2] = BYTE_OFF_8(addr);
819 wbuf[3] = BYTE_OFF_0(addr);
820
821 if ((i == (packet_num - 1)) && remainder)
822 packet_len = remainder;
823 wbuf[4] = BYTE_OFF_8(packet_len);
824 wbuf[5] = BYTE_OFF_0(packet_len);
825
826 FTS_DEBUG("ecc calc startaddr:0x%04x, len:%d", addr, packet_len);
827 ret = fts_i2c_write(client, wbuf, FTS_CMD_ECC_CAL_LEN);
828 if (ret < 0) {
829 FTS_ERROR("ecc calc cmd write fail");
830 return ret;
831 }
832
833 msleep(packet_len / 256);
834
835 /* read status if check sum is finished */
836 ret = fts_fwupg_check_flash_status(client, FTS_CMD_FLASH_STATUS_ECC_OK,
837 FTS_RETRIES_ECC_CAL, FTS_RETRIES_DELAY_ECC_CAL);
838 if (ret < 0) {
839 FTS_ERROR("ecc flash status read fail");
840 return ret;
841 }
842 }
843
844 ecc_len = 1;
845 if (ECC_CHECK_MODE_CRC16 == upg->func->ecc_check_mode) {
846 ecc_len = 2;
847 }
848
849 /* read out check sum */
850 wbuf[0] = FTS_CMD_ECC_READ;
851 ret = fts_i2c_read(client, wbuf, 1, val, ecc_len);
852 if (ret < 0) {
853 FTS_ERROR( "ecc read cmd write fail");
854 return ret;
855 }
856
857 if (ECC_CHECK_MODE_CRC16 == upg->func->ecc_check_mode) {
858 ecc = (int)((u16)(val[0] << 8) + val[1]);
859 } else {
860 ecc = (int)val[0];
861 }
862
863 return ecc;
864 }
865
866 /************************************************************************
867 * Name: fts_flash_write_buf
868 * Brief: write buf data to flash address
869 * Input: saddr - start address data write to flash
870 * buf - data buffer
871 * len - data length
872 * delay - delay after write
873 * Output:
874 * Return: return data ecc of host if success, otherwise return error code
875 ***********************************************************************/
fts_flash_write_buf(struct i2c_client * client,u32 saddr,u8 * buf,u32 len,u32 delay)876 int fts_flash_write_buf(
877 struct i2c_client *client,
878 u32 saddr,
879 u8 *buf,
880 u32 len,
881 u32 delay)
882 {
883 int ret = 0;
884 u32 i = 0;
885 u32 j = 0;
886 u32 packet_number = 0;
887 u32 packet_len = 0;
888 u32 addr = 0;
889 u32 offset = 0;
890 u32 remainder = 0;
891 u8 packet_buf[FTS_FLASH_PACKET_LENGTH + FTS_CMD_WRITE_LEN] = { 0 };
892 u8 ecc_in_host = 0;
893 u8 cmd = 0;
894 u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
895 u16 read_status = 0;
896 u16 wr_ok = 0;
897
898 FTS_INFO( "**********write data to flash**********");
899
900 if ((NULL == buf) || (0 == len)) {
901 FTS_ERROR("buf is NULL or len is 0");
902 return -EINVAL;
903 }
904
905 FTS_INFO("data buf start addr=0x%x, len=0x%x", saddr, len);
906 packet_number = len / FTS_FLASH_PACKET_LENGTH;
907 remainder = len % FTS_FLASH_PACKET_LENGTH;
908 if (remainder > 0)
909 packet_number++;
910 packet_len = FTS_FLASH_PACKET_LENGTH;
911 FTS_INFO("write data, num:%d remainder:%d", packet_number, remainder);
912
913 packet_buf[0] = FTS_CMD_WRITE;
914 for (i = 0; i < packet_number; i++) {
915 offset = i * FTS_FLASH_PACKET_LENGTH;
916 addr = saddr + offset;
917 packet_buf[1] = BYTE_OFF_16(addr);
918 packet_buf[2] = BYTE_OFF_8(addr);
919 packet_buf[3] = BYTE_OFF_0(addr);
920
921 /* last packet */
922 if ((i == (packet_number - 1)) && remainder)
923 packet_len = remainder;
924
925 packet_buf[4] = BYTE_OFF_8(packet_len);
926 packet_buf[5] = BYTE_OFF_0(packet_len);
927
928 for (j = 0; j < packet_len; j++) {
929 packet_buf[FTS_CMD_WRITE_LEN + j] = buf[offset + j];
930 ecc_in_host ^= packet_buf[FTS_CMD_WRITE_LEN + j];
931 }
932
933 ret = fts_i2c_write(client, packet_buf, packet_len + FTS_CMD_WRITE_LEN);
934 if (ret < 0) {
935 FTS_ERROR("app write fail");
936 return ret;
937 }
938 mdelay(delay);
939
940 /* read status */
941 wr_ok = FTS_CMD_FLASH_STATUS_WRITE_OK + addr / packet_len;
942 for (j = 0; j < FTS_RETRIES_WRITE; j++) {
943 cmd = FTS_CMD_FLASH_STATUS;
944 fts_i2c_read(client, &cmd , 1, val, FTS_CMD_FLASH_STATUS_LEN);
945 read_status = (((u16)val[0]) << 8) + val[1];
946 /* FTS_INFO("%x %x", wr_ok, read_status); */
947 if (wr_ok == read_status) {
948 break;
949 }
950 mdelay(FTS_RETRIES_DELAY_WRITE);
951 }
952 }
953
954 return (int)ecc_in_host;
955 }
956
957 #if FTS_AUTO_UPGRADE_EN
958 /************************************************************************
959 * Name: fts_flash_read_buf
960 * Brief: read data from flash
961 * Input: saddr - start address data write to flash
962 * buf - buffer to store data read from flash
963 * len - read length
964 * Output:
965 * Return: return 0 if success, otherwise return error code
966 *
967 * Warning: can't call this function directly, need call in boot environment
968 ***********************************************************************/
fts_flash_read_buf(struct i2c_client * client,u32 saddr,u8 * buf,u32 len)969 static int fts_flash_read_buf(struct i2c_client *client, u32 saddr, u8 *buf, u32 len)
970 {
971 int ret = 0;
972 u32 i = 0;
973 u32 packet_number = 0;
974 u32 packet_len = 0;
975 u32 addr = 0;
976 u32 offset = 0;
977 u32 remainder = 0;
978 u8 wbuf[FTS_CMD_READ_LEN];
979
980 if ((NULL == buf) || (0 == len)) {
981 FTS_ERROR("buf is NULL or len is 0");
982 return -EINVAL;
983 }
984
985 packet_number = len / FTS_FLASH_PACKET_LENGTH;
986 remainder = len % FTS_FLASH_PACKET_LENGTH;
987 if (remainder > 0) {
988 packet_number++;
989 }
990 packet_len = FTS_FLASH_PACKET_LENGTH;
991 FTS_INFO("read packet_number:%d, remainder:%d", packet_number, remainder);
992
993 wbuf[0] = FTS_CMD_READ;
994 for (i = 0; i < packet_number; i++) {
995 offset = i * FTS_FLASH_PACKET_LENGTH;
996 addr = saddr + offset;
997 wbuf[1] = BYTE_OFF_16(addr);
998 wbuf[2] = BYTE_OFF_8(addr);
999 wbuf[3] = BYTE_OFF_0(addr);
1000
1001 /* last packet */
1002 if ((i == (packet_number - 1)) && remainder)
1003 packet_len = remainder;
1004
1005 ret = fts_i2c_write(client, wbuf, FTS_CMD_READ_LEN);
1006 if (ret < 0) {
1007 FTS_ERROR("pram/bootloader write 03 command fail");
1008 return ret;
1009 }
1010
1011 msleep(FTS_CMD_READ_DELAY); /* must wait, otherwise read wrong data */
1012 ret = fts_i2c_read(client, NULL, 0, buf + offset, packet_len);
1013 if (ret < 0) {
1014 FTS_ERROR("pram/bootloader read 03 command fail");
1015 return ret;
1016 }
1017 }
1018
1019 return 0;
1020 }
1021
1022 /************************************************************************
1023 * Name: fts_flash_read
1024 * Brief:
1025 * Input: addr - address of flash
1026 * len - length of read
1027 * Output: buf - data read from flash
1028 * Return: return 0 if success, otherwise return error code
1029 ***********************************************************************/
fts_flash_read(struct i2c_client * client,u32 addr,u8 * buf,u32 len)1030 static int fts_flash_read(struct i2c_client *client, u32 addr, u8 *buf, u32 len)
1031 {
1032 int ret = 0;
1033
1034 FTS_INFO("***********read flash***********");
1035
1036 if ((NULL == buf) || (0 == len)) {
1037 FTS_ERROR("buf is NULL or len is 0");
1038 return -EINVAL;
1039 }
1040
1041 ret = fts_fwupg_enter_into_boot(client);
1042 if (ret < 0) {
1043 FTS_ERROR("enter into pramboot/bootloader fail");
1044 goto read_flash_err;
1045 }
1046
1047 ret = fts_flash_read_buf(client, addr, buf, len);
1048 if (ret < 0) {
1049 FTS_ERROR("read flash fail");
1050 goto read_flash_err;
1051 }
1052
1053 read_flash_err:
1054 /* reset to normal boot */
1055 ret = fts_fwupg_reset_in_boot(client);
1056 if (ret < 0) {
1057 FTS_ERROR("reset to normal boot fail");
1058 }
1059 return ret;
1060 }
1061 #endif /* FTS_AUTO_UPGRADE_EN */
1062
1063 /************************************************************************
1064 * Name: fts_read_file
1065 * Brief: read file
1066 * Input: file name
1067 * Output:
1068 * Return: return file len if succuss, otherwise return error code
1069 ***********************************************************************/
fts_read_file(char * file_name,u8 ** file_buf)1070 static int fts_read_file(char *file_name, u8 **file_buf)
1071 {
1072 int ret = 0;
1073 char file_path[FILE_NAME_LENGTH] = { 0 };
1074 struct file *filp = NULL;
1075 struct inode *inode;
1076 mm_segment_t old_fs;
1077 loff_t pos;
1078 loff_t file_len = 0;
1079
1080 if ((NULL == file_name) || (NULL == file_buf)) {
1081 FTS_ERROR("filename/filebuf is NULL");
1082 return -EINVAL;
1083 }
1084
1085 snprintf(file_path, FILE_NAME_LENGTH, "%s%s", FTS_FW_BIN_FILEPATH, file_name);
1086 filp = filp_open(file_path, O_RDONLY, 0);
1087 if (IS_ERR(filp)) {
1088 FTS_ERROR("open %s file fail", file_path);
1089 return -ENOENT;
1090 }
1091
1092 #if 1
1093 inode = filp->f_inode;
1094 #else
1095 /* reserved for linux earlier verion */
1096 inode = filp->f_dentry->d_inode;
1097 #endif
1098
1099 file_len = inode->i_size;
1100 *file_buf = (u8 *)vmalloc(file_len);
1101 if (NULL == *file_buf) {
1102 FTS_ERROR("file buf malloc fail");
1103 filp_close(filp, NULL);
1104 return -ENOMEM;
1105 }
1106 old_fs = get_fs();
1107 set_fs(KERNEL_DS);
1108 pos = 0;
1109 ret = vfs_read(filp, *file_buf, file_len , &pos);
1110 if (ret < 0)
1111 FTS_ERROR("read file fail");
1112 FTS_INFO("file len:%d read len:%d pos:%d", (u32)file_len, ret, (u32)pos);
1113 filp_close(filp, NULL);
1114 set_fs(old_fs);
1115
1116 return ret;
1117 }
1118
1119 /************************************************************************
1120 * Name: fts_upgrade_bin
1121 * Brief:
1122 * Input:
1123 * Output:
1124 * Return: return 0 if success, otherwise return error code
1125 ***********************************************************************/
fts_upgrade_bin(struct i2c_client * client,char * fw_name,bool force)1126 int fts_upgrade_bin(struct i2c_client *client, char *fw_name, bool force)
1127 {
1128 int ret = 0;
1129 u32 fw_file_len = 0;
1130 u8 *fw_file_buf = NULL;
1131 struct fts_upgrade *upg = fwupgrade;
1132
1133 FTS_INFO("start upgrade with fw bin");
1134 if ((NULL == upg) || (NULL == upg->func)) {
1135 FTS_ERROR("upgrade/func is null");
1136 return -EINVAL;
1137 }
1138
1139 ret = fts_read_file(fw_name, &fw_file_buf);
1140 if ((ret < 0) || (ret < FTS_MIN_LEN) || (ret > FTS_MAX_LEN_FILE)) {
1141 FTS_ERROR("read fw bin file(sdcard) fail, len:%d", ret);
1142 goto err_bin;
1143 }
1144
1145 fw_file_len = ret;
1146 FTS_INFO("fw bin file len:%d", fw_file_len);
1147 if (force) {
1148 if (upg->func->force_upgrade) {
1149 ret = upg->func->force_upgrade(client, fw_file_buf, fw_file_len);
1150 } else {
1151 FTS_INFO("force_upgrade function is null, no upgrade");
1152 goto err_bin;
1153 }
1154 } else {
1155 #if FTS_AUTO_LIC_UPGRADE_EN
1156 if (upg->func->lic_upgrade) {
1157 ret = upg->func->lic_upgrade(client, fw_file_buf, fw_file_len);
1158 } else {
1159 FTS_INFO("lic_upgrade function is null, no upgrade");
1160 }
1161 #endif
1162 if (upg->func->upgrade) {
1163 ret = upg->func->upgrade(client, fw_file_buf, fw_file_len);
1164 } else {
1165 FTS_INFO("upgrade function is null, no upgrade");
1166 }
1167 }
1168
1169 if (ret < 0) {
1170 FTS_ERROR("upgrade fw bin failed");
1171 fts_fwupg_reset_in_boot(client);
1172 goto err_bin;
1173 }
1174
1175 FTS_INFO("upgrade fw bin success");
1176
1177 err_bin:
1178 if (fw_file_buf) {
1179 vfree(fw_file_buf);
1180 fw_file_buf = NULL;
1181 }
1182 return ret;
1183 }
1184
1185 #if (FTS_AUTO_LIC_UPGRADE_EN && FTS_AUTO_UPGRADE_EN)
fts_lic_get_vid_in_tp(struct i2c_client * client,u16 * vid)1186 static int fts_lic_get_vid_in_tp(struct i2c_client *client, u16 *vid)
1187 {
1188 int ret = 0;
1189 u8 val[2] = { 0 };
1190
1191 if (NULL == vid) {
1192 FTS_ERROR("vid is NULL");
1193 return -EINVAL;
1194 }
1195
1196 ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &val[0]);
1197 if (fts_data->ic_info.is_incell)
1198 ret = fts_i2c_read_reg(client, FTS_REG_MODULE_ID, &val[1]);
1199 if (ret < 0) {
1200 FTS_ERROR("read vid from tp fail");
1201 return ret;
1202 }
1203
1204 *vid = *(u16 *)val;
1205 return 0;
1206 }
1207
fts_lic_get_vid_in_host(u16 * vid)1208 static int fts_lic_get_vid_in_host(u16 *vid)
1209 {
1210 u8 val[2] = { 0 };
1211 u8 *licbuf = NULL;
1212 u32 conf_saddr = 0;
1213 struct fts_upgrade *upg = fwupgrade;
1214
1215 if (!upg || !upg->func || !upg->lic || !vid) {
1216 FTS_ERROR("upgrade/func/get_hlic_ver/lic/vid is null");
1217 return -EINVAL;
1218 }
1219
1220 if (upg->lic_length < FTS_MAX_LEN_SECTOR) {
1221 FTS_ERROR("lic length(%x) fail", upg->lic_length);
1222 return -EINVAL;
1223 }
1224
1225 licbuf = upg->lic;
1226 conf_saddr = upg->func->fwcfgoff;
1227 val[0] = licbuf[conf_saddr + FTS_CONIFG_VENDORID_OFF];
1228 if (fts_data->ic_info.is_incell)
1229 val[1] = licbuf[conf_saddr + FTS_CONIFG_MODULEID_OFF];
1230
1231 *vid = *(u16 *)val;
1232 return 0;
1233 }
1234
fts_lic_get_ver_in_tp(struct i2c_client * client,u8 * ver)1235 static int fts_lic_get_ver_in_tp(struct i2c_client *client, u8 *ver)
1236 {
1237 int ret = 0;
1238
1239 if (NULL == ver) {
1240 FTS_ERROR("ver is NULL");
1241 return -EINVAL;
1242 }
1243
1244 ret = fts_i2c_read_reg(client, FTS_REG_LIC_VER, ver);
1245 if (ret < 0) {
1246 FTS_ERROR("read lcd initcode ver from tp fail");
1247 return ret;
1248 }
1249
1250 return 0;
1251 }
1252
fts_lic_get_ver_in_host(u8 * ver)1253 static int fts_lic_get_ver_in_host(u8 *ver)
1254 {
1255 int ret = 0;
1256 struct fts_upgrade *upg = fwupgrade;
1257
1258 if (!upg || !upg->func || !upg->func->get_hlic_ver || !upg->lic) {
1259 FTS_ERROR("upgrade/func/get_hlic_ver/lic is null");
1260 return -EINVAL;
1261 }
1262
1263 ret = upg->func->get_hlic_ver(upg->lic);
1264 if (ret < 0) {
1265 FTS_ERROR("get host lcd initial code version fail");
1266 return ret;
1267 }
1268
1269 *ver = (u8)ret;
1270 return ret;
1271 }
1272
1273 /* check if lcd init code need upgrade
1274 * true-need false-no need
1275 */
fts_lic_need_upgrade(struct i2c_client * client)1276 static bool fts_lic_need_upgrade(struct i2c_client *client)
1277 {
1278 int ret = 0;
1279 u8 initcode_ver_in_tp = 0;
1280 u8 initcode_ver_in_host = 0;
1281 u16 vid_in_tp = 0;
1282 u16 vid_in_host = 0;
1283 bool fwvalid = false;
1284
1285 fwvalid = fts_fwupg_check_fw_valid(client);
1286 if ( !fwvalid) {
1287 FTS_INFO("fw is invalid, no upgrade lcd init code");
1288 return false;
1289 }
1290
1291 ret = fts_lic_get_vid_in_host(&vid_in_host);
1292 if (ret < 0) {
1293 FTS_ERROR("vendor id in host invalid");
1294 return false;
1295 }
1296
1297 ret = fts_lic_get_vid_in_tp(client, &vid_in_tp);
1298 if (ret < 0) {
1299 FTS_ERROR("vendor id in tp invalid");
1300 return false;
1301 }
1302
1303 FTS_DEBUG("vid in tp:0x%04x, host:0x%04x", vid_in_tp, vid_in_host);
1304 if (vid_in_tp != vid_in_host) {
1305 FTS_INFO("vendor id in tp&host are different, no upgrade lic");
1306 return false;
1307 }
1308
1309 ret = fts_lic_get_ver_in_host(&initcode_ver_in_host);
1310 if (ret < 0) {
1311 FTS_ERROR("init code in host invalid");
1312 return false;
1313 }
1314
1315 ret = fts_lic_get_ver_in_tp(client, &initcode_ver_in_tp);
1316 if (ret < 0) {
1317 FTS_ERROR("read reg0xE4 fail");
1318 return false;
1319 }
1320
1321 FTS_DEBUG("lcd initial code version in tp:%x, host:%x",
1322 initcode_ver_in_tp, initcode_ver_in_host);
1323 if (0xA5 == initcode_ver_in_tp) {
1324 FTS_INFO("lcd init code ver is 0xA5, don't upgade init code");
1325 return false;
1326 } else if (0xFF == initcode_ver_in_tp) {
1327 FTS_DEBUG("lcd init code in tp is invalid, need upgrade init code");
1328 return true;
1329 } else if (initcode_ver_in_tp < initcode_ver_in_host)
1330 return true;
1331 else
1332 return false;
1333 }
1334
fts_lic_upgrade(struct i2c_client * client,struct fts_upgrade * upg)1335 static int fts_lic_upgrade(struct i2c_client *client, struct fts_upgrade *upg)
1336 {
1337 int ret = 0;
1338 bool hlic_upgrade = false;
1339 int upgrade_count = 0;
1340 u8 ver = 0;
1341
1342 FTS_INFO("lcd initial code auto upgrade function");
1343 if ((!upg) || (!upg->func) || (!upg->func->lic_upgrade)) {
1344 FTS_ERROR("lcd upgrade function is null");
1345 return -EINVAL;
1346 }
1347
1348 hlic_upgrade = fts_lic_need_upgrade(client);
1349 FTS_INFO("lcd init code upgrade flag:%d", hlic_upgrade);
1350 if (hlic_upgrade) {
1351 FTS_INFO("lcd initial code need upgrade, upgrade begin...");
1352 do {
1353 FTS_INFO("lcd initial code upgrade times:%d", upgrade_count);
1354 upgrade_count++;
1355
1356 ret = upg->func->lic_upgrade(client, upg->lic, upg->lic_length);
1357 if (ret < 0) {
1358 fts_fwupg_reset_in_boot(client);
1359 } else {
1360 fts_lic_get_ver_in_tp(client, &ver);
1361 FTS_INFO("success upgrade to lcd initcode ver:%02x", ver);
1362 break;
1363 }
1364 } while (upgrade_count < 2);
1365 } else {
1366 FTS_INFO("lcd initial code don't need upgrade");
1367 }
1368
1369 return ret;
1370 }
1371 #endif /* FTS_AUTO_LIC_UPGRADE_EN && FTS_AUTO_UPGRADE_EN */
1372
1373
fts_param_get_ver_in_tp(struct i2c_client * client,u8 * ver)1374 static int fts_param_get_ver_in_tp(struct i2c_client *client, u8 *ver)
1375 {
1376 int ret = 0;
1377
1378 if (NULL == ver) {
1379 FTS_ERROR("ver is NULL");
1380 return -EINVAL;
1381 }
1382
1383 ret = fts_i2c_read_reg(client, FTS_REG_IDE_PARA_VER_ID, ver);
1384 if (ret < 0) {
1385 FTS_ERROR("read fw param ver from tp fail");
1386 return ret;
1387 }
1388
1389 if ((0x00 == *ver) || (0xFF == *ver)) {
1390 FTS_INFO("param version in tp invalid");
1391 return -EIO;
1392 }
1393
1394 return 0;
1395 }
1396
fts_param_get_ver_in_host(u8 * ver)1397 static int fts_param_get_ver_in_host(u8 *ver)
1398 {
1399 struct fts_upgrade *upg = fwupgrade;
1400
1401 if ((!upg) || (!upg->func) || (!upg->fw) || (!ver)) {
1402 FTS_ERROR("fts_data/upgrade/func/fw/ver is NULL");
1403 return -EINVAL;
1404 }
1405
1406 if (upg->fw_length < upg->func->paramcfgveroff) {
1407 FTS_ERROR("fw len(%x) < paramcfg ver offset(%x)",
1408 upg->fw_length, upg->func->paramcfgveroff);
1409 return -EINVAL;
1410 }
1411
1412 FTS_INFO("fw paramcfg version offset:%x", upg->func->paramcfgveroff);
1413 *ver = upg->fw[upg->func->paramcfgveroff];
1414
1415 if ((0x00 == *ver) || (0xFF == *ver)) {
1416 FTS_INFO("param version in host invalid");
1417 return -EIO;
1418 }
1419
1420 return 0;
1421 }
1422
1423 /*
1424 * return: < 0 : error
1425 * == 0: no ide
1426 * == 1: ide
1427 */
fts_param_ide_in_host(void)1428 static int fts_param_ide_in_host(void)
1429 {
1430 u32 off = 0;
1431 struct fts_upgrade *upg = fwupgrade;
1432
1433 if ((!upg) || (!upg->func) || (!upg->fw)) {
1434 FTS_ERROR("fts_data/upgrade/func/fw is NULL");
1435 return -EINVAL;
1436 }
1437
1438 if (upg->fw_length < upg->func->paramcfgoff + FTS_FW_IDE_SIG_LEN) {
1439 FTS_INFO("fw len(%x) < paramcfg offset(%x), no IDE",
1440 upg->fw_length, upg->func->paramcfgoff + FTS_FW_IDE_SIG_LEN);
1441 return 0;
1442 }
1443
1444 off = upg->func->paramcfgoff;
1445 if (0 == memcmp(&upg->fw[off], FTS_FW_IDE_SIG, FTS_FW_IDE_SIG_LEN)) {
1446 FTS_INFO("fw in host is IDE version");
1447 return 1;
1448 }
1449
1450 FTS_INFO("fw in host isn't IDE version");
1451 return 0;
1452 }
1453
1454 /*
1455 * return: < 0 : error
1456 * 0 : no ide
1457 * 1 : ide
1458 */
fts_param_ide_in_tp(struct i2c_client * client,u8 * val)1459 static int fts_param_ide_in_tp(struct i2c_client *client, u8 *val)
1460 {
1461 int ret = 0;
1462
1463 ret = fts_i2c_read_reg(client, FTS_REG_IDE_PARA_STATUS, val);
1464 if (ret < 0) {
1465 FTS_ERROR("read IDE PARAM STATUS in tp fail");
1466 return ret;
1467 }
1468
1469 if ((*val != 0xFF) && ((*val & 0x80) == 0x80)) {
1470 FTS_INFO("fw in tp is IDE version");
1471 return 1;
1472 }
1473
1474 FTS_INFO("fw in tp isn't IDE version");
1475 return 0;
1476 }
1477
1478 /************************************************************************
1479 * fts_param_need_upgrade - check fw paramcfg need upgrade or not
1480 *
1481 * Return: < 0 : error if paramcfg need upgrade
1482 * 0 : no need upgrade
1483 * 1 : need upgrade app + param
1484 * 2 : need upgrade param
1485 ***********************************************************************/
fts_param_need_upgrade(struct i2c_client * client)1486 static int fts_param_need_upgrade(struct i2c_client *client)
1487 {
1488 int ret = 0;
1489 u8 val = 0;
1490 int ide_in_host = 0;
1491 int ide_in_tp = 0;
1492 u8 ver_in_host = 0;
1493 u8 ver_in_tp = 0;
1494 bool fwvalid = false;
1495
1496 fwvalid = fts_fwupg_check_fw_valid(client);
1497 if ( !fwvalid) {
1498 FTS_INFO("fw is invalid, upgrade app+param");
1499 return 1;
1500 }
1501
1502 ide_in_host = fts_param_ide_in_host();
1503 if (ide_in_host < 0) {
1504 FTS_INFO("fts_param_ide_in_host fail");
1505 return ide_in_host;
1506 }
1507
1508 ide_in_tp = fts_param_ide_in_tp(client, &val);
1509 if (ide_in_tp < 0) {
1510 FTS_INFO("fts_param_ide_in_tp fail");
1511 return ide_in_tp;
1512 }
1513
1514 if ((0 == ide_in_host) && (0 == ide_in_tp)) {
1515 FTS_INFO("fw in host&tp are both no ide");
1516 return 0;
1517 } else if (ide_in_host != ide_in_tp) {
1518 FTS_INFO("fw in host&tp not equal, need upgrade app+param");
1519 return 1;
1520 } else if ((1 == ide_in_host) && (1 == ide_in_tp)) {
1521 FTS_INFO("fw in host&tp are both ide");
1522 if ((val & 0x7F) != 0x00) {
1523 FTS_INFO("param invalid, need upgrade param");
1524 return 2;
1525 }
1526
1527 ret = fts_param_get_ver_in_host(&ver_in_host);
1528 if (ret < 0) {
1529 FTS_ERROR("param version in host invalid");
1530 return ret;
1531 }
1532
1533 ret = fts_param_get_ver_in_tp(client, &ver_in_tp);
1534 if (ret < 0) {
1535 FTS_ERROR("get IDE param ver in tp fail");
1536 return ret;
1537 }
1538
1539 FTS_INFO("fw paramcfg version in tp:%x, host:%x", ver_in_tp, ver_in_host);
1540 if (ver_in_tp != ver_in_host) {
1541 return 2;
1542 }
1543 }
1544
1545 return 0;
1546 }
1547
1548 /************************************************************************
1549 * fts_fwupg_get_ver_in_tp - read fw ver from tp register
1550 *
1551 * return 0 if success, otherwise return error code
1552 ***********************************************************************/
fts_fwupg_get_ver_in_tp(struct i2c_client * client,u8 * ver)1553 static int fts_fwupg_get_ver_in_tp(struct i2c_client *client, u8 *ver)
1554 {
1555 int ret = 0;
1556
1557 if (NULL == ver) {
1558 FTS_ERROR("ver is NULL");
1559 return -EINVAL;
1560 }
1561
1562 ret = fts_i2c_read_reg(client, FTS_REG_FW_VER, ver);
1563 if (ret < 0) {
1564 FTS_ERROR("read fw ver from tp fail");
1565 return ret;
1566 }
1567
1568 return 0;
1569 }
1570
1571 /************************************************************************
1572 * fts_fwupg_get_ver_in_host - read fw ver in host fw image
1573 *
1574 * return 0 if success, otherwise return error code
1575 ***********************************************************************/
fts_fwupg_get_ver_in_host(u8 * ver)1576 static int fts_fwupg_get_ver_in_host(u8 *ver)
1577 {
1578 struct fts_upgrade *upg = fwupgrade;
1579
1580 if ((!upg) || (!upg->func) || (!upg->fw) || (!ver)) {
1581 FTS_ERROR("fts_data/upgrade/func/fw/ver is NULL");
1582 return -EINVAL;
1583 }
1584
1585 if (upg->fw_length < upg->func->fwveroff) {
1586 FTS_ERROR("fw len(0x%0x) < fw ver offset(0x%x)",
1587 upg->fw_length, upg->func->fwveroff);
1588 return -EINVAL;
1589 }
1590
1591 FTS_INFO("fw version offset:0x%x", upg->func->fwveroff);
1592 *ver = upg->fw[upg->func->fwveroff];
1593 return 0;
1594 }
1595
1596 /************************************************************************
1597 * fts_fwupg_need_upgrade - check fw need upgrade or not
1598 *
1599 * Return: return true if fw need upgrade
1600 ***********************************************************************/
fts_fwupg_need_upgrade(struct i2c_client * client)1601 static bool fts_fwupg_need_upgrade(struct i2c_client *client)
1602 {
1603 int ret = 0;
1604 bool fwvalid = false;
1605 u8 fw_ver_in_host = 0;
1606 u8 fw_ver_in_tp = 0;
1607
1608 fwvalid = fts_fwupg_check_fw_valid(client);
1609 if (fwvalid) {
1610 ret = fts_fwupg_get_ver_in_host(&fw_ver_in_host);
1611 if (ret < 0) {
1612 FTS_ERROR("get fw ver in host fail");
1613 return false;
1614 }
1615
1616 ret = fts_fwupg_get_ver_in_tp(client, &fw_ver_in_tp);
1617 if (ret < 0) {
1618 FTS_ERROR("get fw ver in tp fail");
1619 return false;
1620 }
1621
1622 FTS_INFO("fw version in tp:%x, host:%x", fw_ver_in_tp, fw_ver_in_host);
1623 if (fw_ver_in_tp != fw_ver_in_host) {
1624 return true;
1625 }
1626 } else {
1627 FTS_INFO("fw invalid, need upgrade fw");
1628 return true;
1629 }
1630
1631 return false;
1632 }
1633
1634 /************************************************************************
1635 * Name: fts_fw_upgrade
1636 * Brief: fw upgrade main entry
1637 * Input:
1638 * Output:
1639 * Return: return 0 if success, otherwise return error code
1640 ***********************************************************************/
fts_fwupg_upgrade(struct i2c_client * client,struct fts_upgrade * upg)1641 int fts_fwupg_upgrade(struct i2c_client *client, struct fts_upgrade *upg)
1642 {
1643 int ret = 0;
1644 bool upgrade_flag = false;
1645 int upgrade_count = 0;
1646 u8 ver = 0;
1647
1648 FTS_INFO("fw auto upgrade function");
1649 if ((NULL == upg) || (NULL == upg->func)) {
1650 FTS_ERROR("upg/upg->func is null");
1651 return -EINVAL;
1652 }
1653
1654 upgrade_flag = fts_fwupg_need_upgrade(client);
1655 FTS_INFO("fw upgrade flag:%d", upgrade_flag);
1656 do {
1657 upgrade_count++;
1658 if (upgrade_flag) {
1659 FTS_INFO("upgrade fw app(times:%d)", upgrade_count);
1660 if (upg->func->upgrade) {
1661 ret = upg->func->upgrade(client, upg->fw, upg->fw_length);
1662 if (ret < 0) {
1663 fts_fwupg_reset_in_boot(client);
1664 } else {
1665 fts_fwupg_get_ver_in_tp(client, &ver);
1666 FTS_INFO("success upgrade to fw version %02x", ver);
1667 break;
1668 }
1669 } else {
1670 FTS_ERROR("upgrade func/upgrade is null, return immediately");
1671 ret = -ENODATA;
1672 break;
1673 }
1674 } else {
1675 if (upg->func->param_upgrade) {
1676 ret = fts_param_need_upgrade(client);
1677 if (ret <= 0) {
1678 FTS_INFO("param don't need upgrade");
1679 break;
1680 } else if (1 == ret) {
1681 FTS_INFO("force upgrade fw app(times:%d)", upgrade_count);
1682 if (upg->func->upgrade) {
1683 ret = upg->func->upgrade(client, upg->fw, upg->fw_length);
1684 if (ret < 0) {
1685 fts_fwupg_reset_in_boot(client);
1686 } else {
1687 break;
1688 }
1689 }
1690 } else if (2 == ret) {
1691 FTS_INFO("upgrade param area(times:%d)", upgrade_count);
1692 ret = upg->func->param_upgrade(client, upg->fw, upg->fw_length);
1693 if (ret < 0) {
1694 fts_fwupg_reset_in_boot(client);
1695 } else {
1696 fts_param_get_ver_in_tp(client, &ver);
1697 FTS_INFO("success upgrade to fw param version %02x", ver);
1698 break;
1699 }
1700 } else
1701 break;
1702 } else {
1703 break;
1704 }
1705 }
1706 } while (upgrade_count < 2);
1707
1708 return ret;
1709 }
1710
1711 #if FTS_AUTO_UPGRADE_EN
1712 /************************************************************************
1713 * fts_fwupg_auto_upgrade - upgrade main entry
1714 ***********************************************************************/
fts_fwupg_auto_upgrade(struct fts_ts_data * ts_data)1715 void fts_fwupg_auto_upgrade(struct fts_ts_data *ts_data)
1716 {
1717 int ret = 0;
1718 struct i2c_client *client = ts_data->client;
1719 struct fts_upgrade *upg = fwupgrade;
1720
1721 FTS_INFO("********************FTS enter upgrade********************");
1722
1723 ret = fts_fwupg_upgrade(client, upg);
1724 if (ret < 0)
1725 FTS_ERROR("**********tp fw(app/param) upgrade failed**********");
1726 else
1727 FTS_INFO("**********tp fw(app/param) no upgrade/upgrade success**********");
1728
1729 #if FTS_AUTO_LIC_UPGRADE_EN
1730 ret = fts_lic_upgrade(client, upg);
1731 if (ret < 0)
1732 FTS_ERROR("**********lcd init code upgrade failed**********");
1733 else
1734 FTS_INFO("**********lcd init code no upgrade/upgrade success**********");
1735 #endif
1736
1737 FTS_INFO("********************FTS exit upgrade********************");
1738 }
1739
1740 /*
1741 * fts_fwupg_work - fw upgrade work function, handle upgrade
1742 * @vid - u16 consit of module id and panel id
1743 *
1744 * return 0 if success, otherwise return error code
1745 */
fts_fwupg_get_vendorid(struct fts_ts_data * ts_data,u16 * vid)1746 int fts_fwupg_get_vendorid(struct fts_ts_data *ts_data, u16 *vid)
1747 {
1748 int ret = 0;
1749 bool fwvalid = false;
1750 u8 vendor_id = 0;
1751 u8 module_id = 0;
1752 u32 fwcfg_addr = 0;
1753 u8 cfgbuf[FTS_HEADER_LEN] = { 0 };
1754 struct i2c_client *client = ts_data->client;
1755 struct fts_upgrade *upg = fwupgrade;
1756
1757 FTS_INFO("read vendor id from tp");
1758 if ((!upg) || (!upg->func) || (!vid)) {
1759 FTS_ERROR("upgrade/func/vid is null");
1760 return -EINVAL;
1761 }
1762
1763 fwvalid = fts_fwupg_check_fw_valid(client);
1764 if (fwvalid) {
1765 ret = fts_i2c_read_reg(client, FTS_REG_VENDOR_ID, &vendor_id);
1766 if (ts_data->ic_info.is_incell)
1767 ret = fts_i2c_read_reg(client, FTS_REG_MODULE_ID, &module_id);
1768 } else {
1769 fwcfg_addr = upg->func->fwcfgoff;
1770 ret = fts_flash_read(client, fwcfg_addr, cfgbuf, FTS_HEADER_LEN);
1771 vendor_id = cfgbuf[FTS_CONIFG_VENDORID_OFF];
1772 if (ts_data->ic_info.is_incell) {
1773 if ((cfgbuf[FTS_CONIFG_MODULEID_OFF] +
1774 cfgbuf[FTS_CONIFG_MODULEID_OFF + 1]) == 0xFF)
1775 module_id = cfgbuf[FTS_CONIFG_MODULEID_OFF];
1776 }
1777 }
1778
1779 if (ret < 0) {
1780 FTS_ERROR("fail to get vendor id from tp");
1781 return ret;
1782 }
1783
1784 *vid = ((u16)module_id << 8) + vendor_id;
1785 return 0;
1786 }
1787
1788 /*
1789 * fts_fwupg_get_fw_file - get upgrade fw file in host driver
1790 *
1791 * return 0 if success, otherwise return error code
1792 *
1793 * call it to get upgrade file which include in host driver
1794 * warning:
1795 * 1. if more fw files, please modify FTS_GET_VENDOR_ID_NUM&
1796 * FTS_VENDOR_ID
1797 * 2. For incell ICs, vendor id = module id << 8 + panel id
1798 * For others, vendor id = 0x0000 + panel id
1799 * 3. get fw file from reques_firmware(), this function unactive
1800 */
fts_fwupg_get_fw_file(struct fts_ts_data * ts_data)1801 static int fts_fwupg_get_fw_file(struct fts_ts_data *ts_data)
1802 {
1803 struct upgrade_fw *fw = &fw_list[0];
1804 struct fts_upgrade *upg = fwupgrade;
1805
1806 #if (FTS_GET_VENDOR_ID_NUM > 1)
1807 int ret = 0;
1808 int i = 0;
1809 u16 vendor_id = 0;
1810
1811 /* support multi vendor, must read correct vendor id */
1812 ret = fts_fwupg_get_vendorid(ts_data, &vendor_id);
1813 if (ret < 0) {
1814 FTS_ERROR("get vendor id failed");
1815 return ret;
1816 }
1817 FTS_INFO("success to read vendor id:%04x", vendor_id);
1818 for (i = 0; i < FTS_GET_VENDOR_ID_NUM; i++) {
1819 fw = &fw_list[i];
1820 if (vendor_id == fw->vendor_id) {
1821 FTS_INFO("vendor id match, get fw file successfully");
1822 break;
1823 }
1824 }
1825 if (i >= FTS_GET_VENDOR_ID_NUM) {
1826 FTS_ERROR("no vendor id match, don't get file");
1827 return -ENODATA;
1828 }
1829 #endif
1830
1831 if (upg) {
1832 upg->fw = fw->fw_file;
1833 upg->fw_length = fw->fw_len;
1834 upg->lic = fw->fw_file;
1835 upg->lic_length = fw->fw_len;
1836
1837 FTS_INFO("upgrade fw file len:%d", upg->fw_length);
1838 if ((upg->fw_length < FTS_MIN_LEN)
1839 || (upg->fw_length > FTS_MAX_LEN_FILE)) {
1840 FTS_ERROR("fw file len(%d) fail", upg->fw_length);
1841 return -ENODATA;
1842 }
1843 }
1844 return 0;
1845 }
1846
1847 /*
1848 * fts_fwupg_init_ic_detail - for ic detail initialaztion
1849 */
fts_fwupg_init_ic_detail(void)1850 static void fts_fwupg_init_ic_detail(void)
1851 {
1852 struct fts_upgrade *upg = fwupgrade;
1853
1854 if (upg && upg->func && upg->func->init) {
1855 upg->func->init();
1856 }
1857 }
1858
1859 /*
1860 * fts_fwupg_work - fw upgrade work function
1861 * 1. get fw image/file
1862 * 2. call upgrade main function(fts_fwupg_auto_upgrade)
1863 */
fts_fwupg_work(struct work_struct * work)1864 static void fts_fwupg_work(struct work_struct *work)
1865 {
1866 int ret = 0;
1867 struct fts_ts_data *ts_data = container_of(work,
1868 struct fts_ts_data, fwupg_work);
1869
1870 FTS_INFO("fw upgrade work function");
1871 ts_data->fw_loading = 1;
1872 fts_irq_disable();
1873 #if FTS_ESDCHECK_EN
1874 fts_esdcheck_switch(DISABLE);
1875 #endif
1876
1877 FTS_INFO("get upgrade fw file");
1878 ret = fts_fwupg_get_fw_file(ts_data);
1879 fts_fwupg_init_ic_detail();
1880 if (ret < 0) {
1881 FTS_ERROR("get file fail, can't upgrade");
1882 } else {
1883 /* run auto upgrade */
1884 fts_fwupg_auto_upgrade(ts_data);
1885 }
1886
1887 #if FTS_ESDCHECK_EN
1888 fts_esdcheck_switch(ENABLE);
1889 #endif
1890 fts_irq_enable();
1891 ts_data->fw_loading = 0;
1892 }
1893
1894 /*****************************************************************************
1895 * Name: fts_fwupg_init
1896 * Brief: upgrade function initialization
1897 * Input:
1898 * Output:
1899 * Return: return 0 if success, otherwise return error code
1900 *****************************************************************************/
fts_fwupg_init(struct fts_ts_data * ts_data)1901 int fts_fwupg_init(struct fts_ts_data *ts_data)
1902 {
1903 int i = 0;
1904 int j = 0;
1905 int ic_stype = ts_data->ic_info.ids.type;
1906 struct upgrade_func *func = upgrade_func_list[0];
1907 int func_count = sizeof(upgrade_func_list) / sizeof(upgrade_func_list[0]);
1908
1909 FTS_INFO("fw upgrade init function");
1910
1911 if (NULL == ts_data->ts_workqueue) {
1912 FTS_ERROR("fts workqueue is NULL, can't run upgrade function");
1913 return -EINVAL;
1914 }
1915
1916 if (0 == func_count) {
1917 FTS_ERROR("no upgrade function in tp driver");
1918 return -ENODATA;
1919 }
1920
1921 fwupgrade = (struct fts_upgrade *)kzalloc(sizeof(*fwupgrade), GFP_KERNEL);
1922 if (NULL == fwupgrade) {
1923 FTS_ERROR("malloc memory for upgrade fail");
1924 return -ENOMEM;
1925 }
1926
1927 if (1 == func_count) {
1928 fwupgrade->func = func;
1929 } else {
1930 for (i = 0; i < func_count; i++) {
1931 func = upgrade_func_list[i];
1932 for (j = 0; j < FTX_MAX_COMPATIBLE_TYPE; j++) {
1933 if (0 == func->ctype[j])
1934 break;
1935 else if (func->ctype[j] == ic_stype) {
1936 FTS_INFO("match upgrade function,type:%x", (int)func->ctype[j]);
1937 fwupgrade->func = func;
1938 }
1939 }
1940 }
1941 }
1942
1943 if (NULL == fwupgrade->func) {
1944 FTS_ERROR("no upgrade function match, can't upgrade");
1945 return -ENODATA;
1946 }
1947
1948 INIT_WORK(&ts_data->fwupg_work, fts_fwupg_work);
1949 queue_work(ts_data->ts_workqueue, &ts_data->fwupg_work);
1950
1951 return 0;
1952 }
1953
1954 /*****************************************************************************
1955 * Name: fts_fwupg_exit
1956 * Brief:
1957 * Input:
1958 * Output:
1959 * Return:
1960 *****************************************************************************/
fts_fwupg_exit(struct fts_ts_data * ts_data)1961 int fts_fwupg_exit(struct fts_ts_data *ts_data)
1962 {
1963 FTS_FUNC_ENTER();
1964 if (fwupgrade) {
1965 kfree(fwupgrade);
1966 }
1967 FTS_FUNC_EXIT();
1968
1969 return 0;
1970 }
1971
1972 #endif /* #if FTS_AUTO_UPGRADE_EN */
1973