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