import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / input / touchscreen / mediatek / synaptics_3528 / s3528_fw_update.c
1 /*
2 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 Copyright (c) 2011 Synaptics, Inc.
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of
6 this software and associated documentation files (the "Software"), to deal in
7 the Software without restriction, including without limitation the rights to use,
8 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
9 Software, and to permit persons to whom the Software is furnished to do so,
10 subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE.
22 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 */
24
25 #include <linux/module.h>
26 #include <linux/delay.h>
27 #include <linux/hrtimer.h>
28 #include <linux/i2c.h>
29 #include <linux/input.h>
30 #include <linux/interrupt.h>
31 #include <linux/io.h>
32 #include <linux/platform_device.h>
33 #include <linux/gpio.h>
34 #include <linux/slab.h>
35 #include <linux/jiffies.h>
36 #include <linux/syscalls.h>
37 #include <linux/uaccess.h>
38
39 #include <mach/mt_gpio.h>
40
41 #include "s3528_driver.h"
42
43 /* Variables for F34 functionality */
44 unsigned short SynaF34DataBase;
45 unsigned short SynaF34QueryBase;
46 unsigned short SynaF01DataBase;
47 unsigned short SynaF01CommandBase;
48 unsigned short SynaF01QueryBase;
49
50 unsigned short SynaF34Reflash_BlockNum;
51 unsigned short SynaF34Reflash_BlockData;
52 unsigned short SynaF34ReflashQuery_BootID;
53 unsigned short SynaF34ReflashQuery_FlashPropertyQuery;
54 unsigned short SynaF34ReflashQuery_BlockSize;
55 unsigned short SynaF34ReflashQuery_FirmwareBlockCount;
56 unsigned short SynaF34ReflashQuery_ConfigBlockCount;
57
58 unsigned char SynaF01Query43Length;
59
60 unsigned short SynaFirmwareBlockSize;
61 unsigned short SynaFirmwareBlockCount;
62 unsigned long SynaImageSize;
63
64 unsigned short SynaConfigBlockSize;
65 unsigned short SynaConfigBlockCount;
66 unsigned long SynaConfigImageSize;
67
68 unsigned short SynaBootloadID;
69
70 unsigned short SynaF34_FlashControl;
71 unsigned short SynaF34_FlashStatus;
72
73 unsigned char *SynafirmwareImgData;
74 unsigned char *SynaconfigImgData;
75 unsigned char *SynalockImgData;
76 unsigned int SynafirmwareImgVersion;
77
78 unsigned char * ConfigBlock;
79
80 enum FlashCommand
81 {
82 m_uF34ReflashCmd_FirmwareCrc = 0x01, // prior to V2 bootloaders
83 m_uF34ReflashCmd_FirmwareWrite = 0x02,
84 m_uF34ReflashCmd_EraseAll = 0x03,
85 m_uF34ReflashCmd_LockDown = 0x04, // V2 and later bootloaders
86 m_uF34ReflashCmd_ConfigRead = 0x05,
87 m_uF34ReflashCmd_ConfigWrite = 0x06,
88 m_uF34ReflashCmd_EraseUIConfig = 0x07,
89 m_uF34ReflashCmd_Enable = 0x0F,
90 m_uF34ReflashCmd_QuerySensorID = 0x08,
91 m_uF34ReflashCmd_EraseBLConfig = 0x09,
92 m_uF34ReflashCmd_EraseDisplayConfig = 0x0A,
93 };
94
95 char SynaFlashCommandStr[0x0C][0x20] =
96 {
97 "",
98 "FirmwareCrc",
99 "FirmwareWrite",
100 "EraseAll",
101 "LockDown",
102 "ConfigRead",
103 "ConfigWrite",
104 "EraseUIConfig",
105 "Enable",
106 "QuerySensorID",
107 "EraseBLConfig",
108 "EraseDisplayConfig",
109 };
110 /* Variables for F34 functionality */
111
112
113
114
115
116
117
118 unsigned char *my_image_bin;
119 unsigned long my_image_size;
120
121
122 int CompleteReflash(struct i2c_client *client);
123 //int ConfigBlockReflash(struct i2c_client *client);
124 //int CompleteReflash_Lockdown(struct i2c_client *client);
125 void SynaInitialize(struct i2c_client *client);
126 //void SynaReadConfigInfo(struct i2c_client *client);
127 void SynaReadFirmwareInfo(struct i2c_client *client);
128 void SynaEnableFlashing(struct i2c_client *client);
129 void SynaProgramFirmware(struct i2c_client *client);
130 //int SynaProgramConfiguration(struct i2c_client *client);
131 void SynaFinalizeReflash(struct i2c_client *client);
132 //int SynaWaitForATTN(int time);
133 unsigned int SynaWaitForATTN(int timeout, struct i2c_client *client);
134 void eraseAllBlock(struct i2c_client *client);
135 void EraseConfigBlock(struct i2c_client *client);
136 bool CheckTouchControllerType(struct i2c_client *client);
137
138 extern int synaptics_ts_write(struct i2c_client *client, u8 reg, u8 * buf, int len);
139 extern int synaptics_ts_read(struct i2c_client *client, u8 reg, int num, u8 *buf);
140
141
142 int FirmwareUpgrade(struct i2c_client *client, const char* fw_path, unsigned long fw_size, unsigned char* fw_start)
143 {
144 int ret = 0;
145 int fd = -1;
146 mm_segment_t old_fs = 0;
147 struct stat fw_bin_stat;
148 unsigned long read_bytes;
149
150 if(unlikely(fw_path[0] != 0)) {
151 old_fs = get_fs();
152 set_fs(get_ds());
153
154 if ((fd = sys_open((const char __user *) fw_path, O_RDONLY, 0)) < 0) {
155 TPD_ERR("Can not read FW binary from %s\n", fw_path);
156 ret = -EEXIST;
157 goto read_fail;
158 }
159
160 if ((ret = sys_newstat((char __user *) fw_path, (struct stat *)&fw_bin_stat)) < 0) {
161 TPD_ERR("Can not read FW binary stat from %s\n", fw_path);
162 goto fw_mem_alloc_fail;
163 }
164
165 my_image_size = fw_bin_stat.st_size;
166 my_image_bin = kzalloc(sizeof(char) * (my_image_size+1), GFP_KERNEL);
167 if (my_image_bin == NULL) {
168 TPD_ERR("Can not allocate memory\n");
169 ret = -ENOMEM;
170 goto fw_mem_alloc_fail;
171 }
172
173 read_bytes = sys_read(fd, (char __user *)my_image_bin, my_image_size);
174
175 /* for checksum */
176 *(my_image_bin+my_image_size) = 0xFF;
177
178 TPD_LOG("Touch FW image read %ld bytes from %s\n", read_bytes, fw_path);
179
180 } else {
181 my_image_size = fw_size-1;
182 my_image_bin = (unsigned char *)(&fw_start[0]);
183 }
184
185 #if 1//APK_TEST
186 ret = CompleteReflash(client);
187 if(ret < 0) {
188 TPD_ERR("CompleteReflash fail\n");
189 }
190 #else
191 ret = CompleteReflash_Lockdown(client);
192 if(ret < 0) {
193 TPD_ERR("CompleteReflash_Lockdown fail\n");
194 }
195 #endif
196
197 if(unlikely(fw_path[0] != 0))
198 kfree(my_image_bin);
199
200 fw_mem_alloc_fail:
201 sys_close(fd);
202 read_fail:
203 set_fs(old_fs);
204
205 return ret;
206 }
207
208 static int writeRMI(struct i2c_client *client, u8 uRmiAddress, u8 *data, unsigned int length)
209 {
210 return synaptics_ts_write(client, uRmiAddress, data, length);
211 }
212
213 static int readRMI(struct i2c_client *client, u8 uRmiAddress, u8 *data, unsigned int length)
214 {
215 return synaptics_ts_read(client, uRmiAddress, length, data);
216 }
217
218 bool CheckFlashStatus(enum FlashCommand command, struct i2c_client *client)
219 {
220 unsigned char uData = 0;
221 // Read the "Program Enabled" bit of the F34 Control register, and proceed only if the
222 // bit is set.
223 readRMI(client, SynaF34_FlashStatus, &uData, 1);
224
225 //if ((uData & 0x3F) != 0)
226 //printf("Command %s failed.\n\tFlash status : 0x%X\n", SynaFlashCommandStr[command], uData & 0x3F);
227
228 return !(uData & 0x3F);
229 }
230
231 void SynaImageParser(struct i2c_client *client)
232 {
233 TPD_LOG("%s\n", __FUNCTION__);
234 // img file parsing
235 SynaImageSize = ( (unsigned int)my_image_bin[0x08] |
236 (unsigned int)my_image_bin[0x09] <<8 |
237 (unsigned int)my_image_bin[0x0A] <<16|
238 (unsigned int)my_image_bin[0x0B] <<24);
239 SynafirmwareImgData = (unsigned char *)((&my_image_bin[0]) + 0x100);
240 SynaconfigImgData = (unsigned char *)(SynafirmwareImgData + SynaImageSize);
241 SynafirmwareImgVersion = (unsigned int)(my_image_bin[7]);
242
243 switch (SynafirmwareImgVersion)
244 {
245 case 2:
246 SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xD0);
247 break;
248 case 3:
249 case 4:
250 SynalockImgData = (unsigned char *)((&my_image_bin[0])+ 0xC0);
251 break;
252 case 5:
253 case 6:
254 SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xB0);
255 default: break;
256 }
257 }
258
259 void SynaBootloaderLock(struct i2c_client *client)
260 {
261 unsigned short lockBlockCount = 0;
262 unsigned char uData[2] = {0,};
263 unsigned short uBlockNum = 0;
264 enum FlashCommand cmd;
265
266 TPD_LOG("%s\n", __FUNCTION__);
267
268 if (my_image_bin[0x1E] == 0)
269 {
270 TPD_LOG("Skip lockdown process with this .img\n");
271 return;
272 }
273 // Check if device is in unlocked state
274 readRMI(client, (SynaF34QueryBase+ 1), &uData[0], 1);
275
276 //Device is unlocked
277 if (uData[0] & 0x02)
278 {
279 TPD_LOG("Device unlocked. Lock it first...\n");
280 // Different bootloader version has different block count for the lockdown data
281 // Need to check the bootloader version from the image file being reflashed
282 switch (SynafirmwareImgVersion)
283 {
284 case 2:
285 lockBlockCount = 3;
286 break;
287 case 3:
288 case 4:
289 lockBlockCount = 4;
290 break;
291 case 5:
292 case 6:
293 lockBlockCount = 5;
294 break;
295 default:
296 lockBlockCount = 0;
297 break;
298 }
299
300 // Write the lockdown info block by block
301 // This reference code of lockdown process does not check for bootloader version
302 // currently programmed on the ASIC against the bootloader version of the image to
303 // be reflashed. Such case should not happen in practice. Reflashing cross different
304 // bootloader versions is not supported.
305 for (uBlockNum = 0; uBlockNum < lockBlockCount; ++uBlockNum)
306 {
307 uData[0] = uBlockNum & 0xff;
308 uData[1] = (uBlockNum & 0xff00) >> 8;
309
310 /* Write Block Number */
311 writeRMI(client, SynaF34Reflash_BlockNum, &uData[0], 2);
312
313 /* Write Data Block */
314 writeRMI(client, SynaF34Reflash_BlockData, SynalockImgData, SynaFirmwareBlockSize);
315
316 /* Move to next data block */
317 SynalockImgData += SynaFirmwareBlockSize;
318
319 /* Issue Write Lockdown Block command */
320 cmd = m_uF34ReflashCmd_LockDown;
321 writeRMI(client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);
322
323 /* Wait ATTN until device is done writing the block and is ready for the next. */
324 SynaWaitForATTN(1000, client);
325 CheckFlashStatus(cmd, client);
326 }
327
328 // Enable reflash again to finish the lockdown process.
329 // Since this lockdown process is part of the reflash process, we are enabling
330 // reflash instead, rather than resetting the device to finish the unlock procedure.
331 SynaEnableFlashing(client);
332 }
333 else TPD_LOG("Device already locked.\n");
334 }
335
336
337 /* SynaScanPDT scans the Page Description Table (PDT) and sets up the necessary variables
338 * for the reflash process. This function is a "slim" version of the PDT scan function in
339 * in PDT.c, since only F34 and F01 are needed for reflash.
340 */
341 void SynaScanPDT(struct i2c_client *client)
342 {
343 unsigned char address=0;
344 unsigned char uData[2]={0,};
345 unsigned char buffer[6]={0,};
346 TPD_LOG("%s\n", __FUNCTION__);
347
348 for (address = 0xe9; address > 0xc0; address = address - 6)
349 {
350 readRMI(client, address, buffer, 6);
351
352 switch (buffer[5])
353 {
354 case 0x34:
355 SynaF34DataBase = buffer[3];
356 SynaF34QueryBase = buffer[0];
357 break;
358 case 0x01:
359 SynaF01DataBase = buffer[3];
360 SynaF01CommandBase = buffer[1];
361 SynaF01QueryBase = buffer[0];
362 break;
363 }
364 }
365
366 SynaF34Reflash_BlockNum = SynaF34DataBase;
367 SynaF34Reflash_BlockData = SynaF34DataBase + 1;
368 SynaF34ReflashQuery_BootID = SynaF34QueryBase;
369 SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 1;
370 SynaF34ReflashQuery_BlockSize = SynaF34QueryBase + 2;
371 SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase + 3;
372 SynaF34_FlashControl = SynaF34DataBase + 2;
373 SynaF34_FlashStatus = SynaF34DataBase + 3;
374
375 readRMI(client, SynaF34ReflashQuery_FirmwareBlockCount, buffer, 4);
376 SynaFirmwareBlockCount = buffer[0] | (buffer[1] << 8);
377 SynaConfigBlockCount = buffer[2] | (buffer[3] << 8);
378
379 readRMI(client, SynaF34ReflashQuery_BlockSize, &uData[0], 2);
380 SynaConfigBlockSize = SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);
381
382 //cleat ATTN
383 readRMI(client, (SynaF01DataBase + 1), buffer, 1);
384 }
385 /* SynaSetup scans the Page Description Table (PDT) and sets up the necessary variables
386 * for the reflash process. This function is a "slim" version of the PDT scan function in
387 * in PDT.c, since only F34 and F01 are needed for reflash.
388 */
389
390
391
392
393
394
395
396
397 /* SynaInitialize sets up the reflahs process
398 */
399 void SynaInitialize(struct i2c_client *client)
400 {
401 u8 data;
402
403 TPD_LOG("%s\n", __FUNCTION__);
404 TPD_LOG("\nInitializing Reflash Process...\n");
405
406 data = 0x00;
407 writeRMI(client, 0xff, &data, 1);
408
409 SynaImageParser(client);
410
411 SynaScanPDT(client);
412 }
413 /* SynaInitialize sets up the reflahs process
414 */
415
416
417
418
419
420 //Set all interrupt enable
421
422
423
424 /* SynaReadFirmwareInfo reads the F34 query registers and retrieves the block size and count
425 * of the firmware section of the image to be reflashed
426 */
427 void SynaReadFirmwareInfo(struct i2c_client *client)
428 {
429 unsigned char uData[3] = {0,};
430 unsigned char product_id[11] = {0,};
431 int firmware_version = 0;
432 TPD_LOG("%s\n", __FUNCTION__);
433
434 readRMI(client, SynaF01QueryBase + 11, product_id, 10);
435 product_id[10] = '\0';
436 TPD_LOG("Read Product ID %s\n", product_id);
437
438 readRMI(client, SynaF01QueryBase + 18, uData, 3);
439 firmware_version = uData[2] << 16 | uData[1] << 8 | uData[0];
440 TPD_LOG("Read Firmware Info %d\n", firmware_version);
441
442 CheckTouchControllerType(client);
443 //CheckFimrwareRevision();//APK_TEST
444 }
445
446 /* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader ID of the firmware
447 */
448 void SynaReadBootloadID(struct i2c_client *client)
449 {
450 unsigned char uData[2] = {0,};
451 TPD_LOG("%s\n", __FUNCTION__);
452
453 readRMI(client, SynaF34ReflashQuery_BootID, &uData[0], 2);
454 SynaBootloadID = uData[0] | (uData[1] << 8);
455 }
456
457 /* SynaWriteBootloadID writes the bootloader ID to the F34 data register to unlock the reflash process
458 */
459 void SynaWriteBootloadID(struct i2c_client *client)
460 {
461 unsigned char uData[2];
462 TPD_LOG("%s\n", __FUNCTION__);
463
464 uData[0] = SynaBootloadID % 0x100;
465 uData[1] = SynaBootloadID / 0x100;
466
467 writeRMI(client, SynaF34Reflash_BlockData, &uData[0], 2);
468 }
469
470 /* SynaReadFirmwareInfo reads the F34 query registers and retrieves the block size and count
471 * of the firmware section of the image to be reflashed
472 */
473
474
475
476
477
478 /* SynaReadConfigInfo reads the F34 query registers and retrieves the block size and count
479 * of the configuration section of the image to be reflashed
480 */
481
482
483
484
485 /* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader ID of the firmware
486 */
487
488
489 /* SynaWriteBootloadID writes the bootloader ID to the F34 data register to unlock the reflash process
490 */
491
492
493
494 /* SynaEnableFlashing kicks off the reflash process
495 */
496 void SynaEnableFlashing(struct i2c_client *client)
497 {
498 unsigned char uStatus = 0;
499 enum FlashCommand cmd;
500 TPD_LOG("%s\n", __FUNCTION__);
501 TPD_LOG("Enable Reflash...\n");
502
503 readRMI (client, SynaF01DataBase, &uStatus, 1);
504
505 //APK_TEST
506 TPD_LOG("APK_TEST uStatus= 0x%02x\n", uStatus);
507
508 if ((uStatus &0x40) == 0 /*|| force*/)
509 {
510 // Reflash is enabled by first reading the bootloader ID from the firmware and write it back
511 SynaReadBootloadID(client);
512 SynaWriteBootloadID(client);
513
514 // Write the "Enable Flash Programming command to F34 Control register
515 // Wait for ATTN and then clear the ATTN.
516 cmd = m_uF34ReflashCmd_Enable;
517 writeRMI(client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);
518 SynaWaitForATTN(1000,client);
519
520 //I2C addrss may change
521 //ConfigCommunication();//APK_TEST
522
523 // Scan the PDT again to ensure all register offsets are correct
524 SynaScanPDT(client);
525
526 // Read the "Program Enabled" bit of the F34 Control register, and proceed only if the
527 // bit is set.
528 CheckFlashStatus(cmd,client);
529 }
530 }
531
532 /* SynaWaitForATTN waits for ATTN to be asserted within a certain time threshold.
533 */
534 unsigned int SynaWaitForATTN(int timeout, struct i2c_client *client)
535 {
536 unsigned char uStatus;
537 //int duration = 50;
538 //int retry = timeout/duration;
539 //int times = 0;
540 #ifdef POLLING
541 do {
542 uStatus = 0x00;
543 readRMI((SynaF01DataBase + 1), &uStatus, 1);
544 if (uStatus != 0)
545 break;
546 Sleep(duration);
547 times++;
548 } while (times < retry);
549
550 if (times == retry)
551 return -1;
552 #else
553 //if (Line_WaitForAttention(timeout) == EErrorTimeout)
554 //{
555 //return -1;
556 //}
557 int trial_us=0;
558
559 while((mt_get_gpio_in(GPIO_CTP_EINT_PIN) != 0) && (trial_us < (timeout * 1000))) {
560 udelay(1);
561 trial_us++;
562 }
563
564 if (mt_get_gpio_in(GPIO_CTP_EINT_PIN) != 0){
565 TPD_LOG("interrupt pin is busy...");
566 return -EBUSY;
567 }
568
569 readRMI(client, (SynaF01DataBase + 1), &uStatus, 1);
570 #endif
571 return 0;
572 }
573 /* SynaWaitForATTN waits for ATTN to be asserted within a certain time threshold.
574 */
575
576
577
578
579 /* SynaWaitATTN waits for ATTN to be asserted within a certain time threshold.
580 * The function also checks for the F34 "Program Enabled" bit and clear ATTN accordingly.
581 */
582
583
584
585
586 /* SynaEnableFlashing kicks off the reflash process
587 */
588
589
590 // Reflash is enabled by first reading the bootloader ID from the firmware and write it back
591
592 // Make sure Reflash is not already enabled
593
594 // Clear ATTN
595
596 //APK_TEST
597
598 // Write the "Enable Flash Programming command to F34 Control register
599 // Wait for ATTN and then clear the ATTN.
600 // Scan the PDT again to ensure all register offsets are correct
601 // Read the "Program Enabled" bit of the F34 Control register, and proceed only if the
602 // bit is set.
603 // In practice, if uData!=0x80 happens for multiple counts, it indicates reflash
604 // is failed to be enabled, and program should quit
605 //APK_TEST
606 //TPD_LOG("APK_TEST uData= 0x%02x\n", uData);
607
608
609 /* SynaFinalizeReflash finalizes the reflash process
610 */
611 void SynaFinalizeReflash(struct i2c_client *client)
612 {
613 unsigned char uData;
614
615 char deviceStatusStr[7][20] = {
616 "0x00",
617 "0x01",
618 "0x02",
619 "0x03",
620 "config CRC failed",
621 "firmware CRC failed",
622 "CRC in progress\n"
623 };
624
625 TPD_LOG("%s\n", __FUNCTION__);
626 TPD_LOG("\nFinalizing Reflash...\n");
627
628 // Issue the "Reset" command to F01 command register to reset the chip
629 // This command will also test the new firmware image and check if its is valid
630 uData = 1;
631 writeRMI(client, SynaF01CommandBase, &uData, 1);
632
633 // After command reset, there will be 2 interrupt to be asserted
634 // Simply sleep 150 ms to skip first attention
635 msleep(150);
636 SynaWaitForATTN(1000, client);
637
638 SynaScanPDT(client);
639
640 readRMI(client, SynaF01DataBase, &uData, 1);
641
642 if ((uData & 0x40) != 0)
643 {
644 TPD_LOG("\nDevice is in bootloader mode (status: %s).\n", deviceStatusStr[uData & 0xF]);
645 }
646 else
647 {
648 TPD_LOG("\nReflash Completed and Succeed.\n");
649 }
650 }
651
652 /* SynaFlashFirmwareWrite writes the firmware section of the image block by block
653 */
654 void SynaFlashFirmwareWrite(struct i2c_client *client)
655 {
656 unsigned char *puFirmwareData = SynafirmwareImgData;
657 unsigned char uData[2];
658 unsigned short blockNum;
659 enum FlashCommand cmd;
660
661 TPD_LOG("%s\n", __FUNCTION__);
662 for (blockNum = 0; blockNum < SynaFirmwareBlockCount; ++blockNum)
663 {
664 if (blockNum == 0)
665 {
666 //Block by blcok, write the block number and data to the corresponding F34 data registers
667 uData[0] = blockNum & 0xff;
668 uData[1] = (blockNum & 0xff00) >> 8;
669 writeRMI(client, SynaF34Reflash_BlockNum, &uData[0], 2);
670 }
671
672 writeRMI(client, SynaF34Reflash_BlockData, puFirmwareData, SynaFirmwareBlockSize);
673 puFirmwareData += SynaFirmwareBlockSize;
674
675 // Issue the "Write Firmware Block" command
676 cmd = m_uF34ReflashCmd_FirmwareWrite;
677 writeRMI(client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);
678
679 SynaWaitForATTN(1000, client);
680 CheckFlashStatus(cmd, client);
681 //#ifdef SHOW_PROGRESS
682 #if 1//APK_TEST
683 if (blockNum % 100 == 0)
684 TPD_LOG("blk %d / %d\n", blockNum, SynaFirmwareBlockCount);
685 #endif
686 }
687 //#ifdef SHOW_PROGRESS
688 #if 1//APK_TEST
689 TPD_LOG("blk %d / %d\n", SynaFirmwareBlockCount, SynaFirmwareBlockCount);
690 #endif
691 }
692
693 /* SynaFlashFirmwareWrite writes the firmware section of the image block by block
694 */
695 void SynaFlashConfigWrite(struct i2c_client *client)
696 {
697 unsigned char *puConfigData = SynaconfigImgData;
698 unsigned char uData[2];
699 unsigned short blockNum;
700 enum FlashCommand cmd;
701
702 TPD_LOG("%s\n", __FUNCTION__);
703 for (blockNum = 0; blockNum < SynaConfigBlockCount; ++blockNum)
704 {
705 //Block by blcok, write the block number and data to the corresponding F34 data registers
706 uData[0] = blockNum & 0xff;
707 uData[1] = (blockNum & 0xff00) >> 8;
708 writeRMI(client, SynaF34Reflash_BlockNum, &uData[0], 2);
709
710 writeRMI(client, SynaF34Reflash_BlockData, puConfigData, SynaConfigBlockSize);
711 puConfigData += SynaConfigBlockSize;
712
713 // Issue the "Write Config Block" command
714 cmd = m_uF34ReflashCmd_ConfigWrite;
715 writeRMI(client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);
716
717 SynaWaitForATTN(1000, client);
718 CheckFlashStatus(cmd, client);
719 #ifdef SHOW_PROGRESS
720 if (blockNum % 100 == 0)
721 TPD_LOG("blk %d / %d\n", blockNum, SynaConfigBlockCount);
722 #endif
723 }
724 #ifdef SHOW_PROGRESS
725 TPD_LOG("blk %d / %d\n", SynaConfigBlockCount, SynaConfigBlockCount);
726 #endif
727 }
728
729 /* SynaProgramFirmware prepares the firmware writing process
730 */
731 void SynaProgramFirmware(struct i2c_client *client)
732 {
733 TPD_LOG("%s\n", __FUNCTION__);
734 TPD_LOG("\nProgram Firmware Section...\n");
735
736 eraseAllBlock(client);
737
738 SynaFlashFirmwareWrite(client);
739
740 SynaFlashConfigWrite(client);
741 }
742
743 /* SynaProgramFirmware prepares the firmware writing process
744 */
745 void SynaUpdateConfig(struct i2c_client *client)
746 {
747 TPD_LOG("%s\n", __FUNCTION__);
748 TPD_LOG("\nUpdate Config Section...\n");
749
750 EraseConfigBlock(client);
751
752 SynaFlashConfigWrite(client);
753 }
754
755 /* EraseConfigBlock erases the config block
756 */
757 void eraseAllBlock(struct i2c_client *client)
758 {
759 enum FlashCommand cmd;
760
761 TPD_LOG("%s\n", __FUNCTION__);
762 // Erase of config block is done by first entering into bootloader mode
763 SynaReadBootloadID(client);
764 SynaWriteBootloadID(client);
765
766 // Command 7 to erase config block
767 cmd = m_uF34ReflashCmd_EraseAll;
768 writeRMI(client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);
769
770 SynaWaitForATTN(6000, client);
771 CheckFlashStatus(cmd, client);
772 }
773
774 /* EraseConfigBlock erases the config block
775 */
776 void EraseConfigBlock(struct i2c_client *client)
777 {
778 enum FlashCommand cmd;
779
780 TPD_LOG("%s\n", __FUNCTION__);
781 // Erase of config block is done by first entering into bootloader mode
782 SynaReadBootloadID(client);
783 SynaWriteBootloadID(client);
784
785 // Command 7 to erase config block
786 cmd = m_uF34ReflashCmd_EraseUIConfig;
787 writeRMI(client, SynaF34_FlashControl, (unsigned char*)&cmd, 1);
788
789 SynaWaitForATTN(2000, client);
790 CheckFlashStatus(cmd, client);
791 }
792
793 // This function is to check the touch controller type of the touch controller matches with the firmware image
794 bool CheckTouchControllerType(struct i2c_client *client)
795 {
796 int ID=0;
797 char buffer[5]={0,};
798 char controllerType[20]={0,};
799 unsigned char uData[4]={0,};
800
801 TPD_LOG("%s\n", __FUNCTION__);
802 readRMI(client, (SynaF01QueryBase + 22), &SynaF01Query43Length, 1); //43
803
804 if ((SynaF01Query43Length & 0x0f) > 0)
805 {
806 readRMI(client, (SynaF01QueryBase + 23), &uData[0], 1);
807 if (uData[0] & 0x01)
808 {
809 readRMI(client, (SynaF01QueryBase + 17), &uData[0], 2);
810
811 ID = ((int)uData[0] | ((int)uData[1] << 8));
812 //sprintf_s(buffer, "%d\0", ID);//APK_TEST
813
814 if (strstr(controllerType, buffer) != 0) return true;
815 return false;
816 }
817 else return false;
818 }
819 else return false;
820 }
821
822 #if 0//APK_TEST
823 bool CheckFimrwareRevision(struct i2c_client *client)
824 {
825 unsigned char uData[16];
826 char revision[106];
827
828 TPD_LOG("%s\n", __FUNCTION__);
829 readRMI((SynaF01QueryBase + 28 + SynaF01Query43Length), &uData[0], 16);
830
831 for (int i = 0; i < 0; i++)
832 {
833 while (uData[i] != NULL)
834 {
835 revision[i] = char(uData[0]);
836 }
837 }
838
839 if (strcmp(revision, FW_REVISION) == 0) return true;
840 return false;
841 }
842 #endif
843
844 /* SynaProgramConfiguration writes the configuration section of the image block by block
845 */
846
847
848
849
850 //Block by blcok, write the block number and data to the corresponding F34 data registers
851
852 // Issue the "Write Configuration Block" command
853
854 /* SynaFinalizeReflash finalizes the reflash process
855 */
856
857
858 // Issue the "Reset" command to F01 command register to reset the chip
859 // This command will also test the new firmware image and check if its is valid
860
861
862 // Sanity check that the reflash process is still enabled
863
864
865 // Check if the "Program Enabled" bit in F01 data register is cleared
866 // Reflash is completed, and the image passes testing when the bit is cleared
867
868 // Rescan PDT the update any changed register offsets
869
870
871
872 /* SynaFlashFirmwareWrite writes the firmware section of the image block by block
873 */
874
875 //Block by blcok, write the block number and data to the corresponding F34 data registers
876
877
878 // Issue the "Write Firmware Block" command
879
880
881
882 /* SynaProgramFirmware prepares the firmware writing process
883 */
884
885
886
887
888
889
890
891
892
893 /* eraseConfigBlock erases the config block
894 */
895
896 // Erase of config block is done by first entering into bootloader mode
897
898 // Command 7 to erase config block
899
900
901
902 // CRC_Calculate illustates how to calculate a checksum from the config block data.
903 // With DS4, the config block checksum is calculated and applies towards the end of
904 // the config block data automatically
905 // Variable data to this function represents the data only portion of the config block
906 // Varaible len represents the length of the variable data.
907
908
909
910
911
912 // Check if device is in unlocked state
913
914 //Device is unlocked
915 // Different bootloader version has different block count for the lockdown data
916 // Need to check the bootloader version from the image file being reflashed
917
918 // Write the lockdown info block by block
919 // This reference code of lockdown process does not check for bootloader version
920 // currently programmed on the ASIC against the bootloader version of the image to
921 // be reflashed. Such case should not happen in practice. Reflashing cross different
922 // bootloader versions is not supported.
923
924 /* Write Block Number */
925
926 /* Write Data Block */
927
928 /* Move to next data block */
929
930 /* Issue Write Lockdown Block command */
931
932 /* Wait ATTN until device is done writing the block and is ready for the next. */
933
934 // Enable reflash again to finish the lockdown process.
935 // Since this lockdown process is part of the reflash process, we are enabling
936 // reflash instead, rather than resetting the device to finish the unlock procedure.
937
938
939 /* ConfigBlockReflash reflashes the config block only
940 */
941
942
943
944
945
946
947
948 // Check if device is in unlocked state
949
950 //Device is unlocked
951 // Do not reflash config block if not locked.
952
953
954
955
956
957 /* CompleteReflash reflashes the entire user image, including the configuration block and firmware
958 */
959 int CompleteReflash(struct i2c_client *client)
960 {
961 bool bFlashAll = true;
962
963 SynaInitialize(client);
964
965 SynaReadFirmwareInfo(client);
966
967 SynaEnableFlashing(client);
968
969 SynaBootloaderLock(client);
970
971 if (bFlashAll)
972 SynaProgramFirmware(client);
973 else
974 SynaUpdateConfig(client);
975
976 SynaFinalizeReflash(client);
977
978 return 0;
979 }
980
981 /* CompleteReflash reflashes the entire user image, including the configuration block and firmware
982 */
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001