xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/focaltech_touch_ft5436/focaltech_flash.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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, &reg_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, &reg_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