import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / input / touchscreen / mediatek / synaptics_2202 / synaptics_ts_fw_upgrade.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 "synaptics_ts.h"
42
43
44 /* Variables for F34 functionality */
45 unsigned short SynaF34DataBase;
46 unsigned short SynaF34QueryBase;
47 unsigned short SynaF01DataBase;
48 unsigned short SynaF01CommandBase;
49 unsigned short SynaF01ControlBase;
50 unsigned short SynaF01QueryBase;
51
52 unsigned short SynaF34Reflash_BlockNum;
53 unsigned short SynaF34Reflash_BlockData;
54 unsigned short SynaF34ReflashQuery_BootID;
55 unsigned short SynaF34ReflashQuery_FlashPropertyQuery;
56 unsigned short SynaF34ReflashQuery_FirmwareBlockSize;
57 unsigned short SynaF34ReflashQuery_FirmwareBlockCount;
58 unsigned short SynaF34ReflashQuery_ConfigBlockSize;
59 unsigned short SynaF34ReflashQuery_ConfigBlockCount;
60
61 unsigned short SynaFirmwareBlockSize;
62 unsigned short SynaFirmwareBlockCount;
63 unsigned long SynaImageSize;
64
65 unsigned short SynaConfigBlockSize;
66 unsigned short SynaConfigBlockCount;
67 unsigned long SynaConfigImageSize;
68
69 unsigned short SynaBootloadID;
70
71 unsigned short SynaF34_FlashControl;
72
73 unsigned char *SynafirmwareImgData;
74 unsigned char *SynaconfigImgData;
75 unsigned char *SynalockImgData;
76 unsigned int SynafirmwareImgVersion;
77
78 unsigned char *my_image_bin;
79 unsigned long my_image_size;
80
81
82 int CompleteReflash(struct synaptics_ts_data *ts);
83 int ConfigBlockReflash(struct synaptics_ts_data *ts);
84 int CompleteReflash_Lockdown(struct synaptics_ts_data *ts);
85 void SynaInitialize(struct synaptics_ts_data *ts);
86 void SynaReadConfigInfo(struct synaptics_ts_data *ts);
87 void SynaReadFirmwareInfo(struct synaptics_ts_data *ts);
88 int SynaEnableFlashing(struct synaptics_ts_data *ts);
89 int SynaProgramFirmware(struct synaptics_ts_data *ts);
90 int SynaProgramConfiguration(struct synaptics_ts_data *ts);
91 int SynaFinalizeReflash(struct synaptics_ts_data *ts);
92 int SynaWaitForATTN(int time, struct synaptics_ts_data *ts);
93
94 extern int synaptics_ts_write(struct i2c_client *client, u8 reg, u8 * buf, int len);
95 extern int synaptics_ts_read(struct i2c_client *client, u8 reg, int num, u8 *buf);
96
97
98 int FirmwareUpgrade(struct synaptics_ts_data *ts, const char* fw_path)
99 {
100 int ret = 0;
101 int fd = -1;
102 mm_segment_t old_fs = 0;
103 struct stat fw_bin_stat;
104 unsigned long read_bytes;
105
106 if(unlikely(fw_path[0] != 0)) {
107 old_fs = get_fs();
108 set_fs(get_ds());
109
110 if ((fd = sys_open((const char __user *) fw_path, O_RDONLY, 0)) < 0) {
111 SYNAPTICS_ERR_MSG("Can not read FW binary from %s\n", fw_path);
112 ret = -EEXIST;
113 goto read_fail;
114 }
115
116 if ((ret = sys_newstat((char __user *) fw_path, (struct stat *)&fw_bin_stat)) < 0) {
117 SYNAPTICS_ERR_MSG("Can not read FW binary stat from %s\n", fw_path);
118 goto fw_mem_alloc_fail;
119 }
120
121 my_image_size = fw_bin_stat.st_size;
122 my_image_bin = kzalloc(sizeof(char) * (my_image_size+1), GFP_KERNEL);
123 if (my_image_bin == NULL) {
124 SYNAPTICS_ERR_MSG("Can not allocate memory\n");
125 ret = -ENOMEM;
126 goto fw_mem_alloc_fail;
127 }
128
129 read_bytes = sys_read(fd, (char __user *)my_image_bin, my_image_size);
130
131 /* for checksum */
132 *(my_image_bin+my_image_size) = 0xFF;
133
134 SYNAPTICS_INFO_MSG("Touch FW image read %ld bytes from %s\n", read_bytes, fw_path);
135
136 } else {
137 my_image_size = ts->fw_size-1;
138 my_image_bin = (unsigned char *)(&ts->fw_start[0]);
139 }
140
141 ret = CompleteReflash_Lockdown(ts);
142 if(ret < 0) {
143 SYNAPTICS_ERR_MSG("CompleteReflash_Lockdown fail\n");
144 }
145
146 if(unlikely(fw_path[0] != 0))
147 kfree(my_image_bin);
148
149 fw_mem_alloc_fail:
150 sys_close(fd);
151 read_fail:
152 set_fs(old_fs);
153
154 return ret;
155 }
156
157 static int writeRMI(struct i2c_client *client, u8 uRmiAddress, u8 *data, unsigned int length)
158 {
159 return synaptics_ts_write(client, uRmiAddress, data, length);
160 }
161
162 static int readRMI(struct i2c_client *client, u8 uRmiAddress, u8 *data, unsigned int length)
163 {
164 return synaptics_ts_read(client, uRmiAddress, length, data);
165 }
166
167 /* SynaSetup scans the Page Description Table (PDT) and sets up the necessary variables
168 * for the reflash process. This function is a "slim" version of the PDT scan function in
169 * in PDT.c, since only F34 and F01 are needed for reflash.
170 */
171 void SynaSetup(struct synaptics_ts_data *ts)
172 {
173 unsigned char address;
174 unsigned char buffer[6];
175 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
176
177 for (address = 0xe9; address > 0xd0; address = address - 6)
178 {
179 readRMI(ts->client, address, &buffer[0], 6);
180
181 if(!buffer[5]) break;
182
183 switch (buffer[5])
184 {
185 case 0x34:
186 SynaF34DataBase = buffer[3];
187 SynaF34QueryBase = buffer[0];
188 break;
189 case 0x01:
190 SynaF01DataBase = buffer[3];
191 SynaF01CommandBase = buffer[1];
192 SynaF01ControlBase = buffer[2];
193 SynaF01QueryBase = buffer[0];
194 break;
195 }
196 }
197
198 SynaF34Reflash_BlockNum = SynaF34DataBase;
199 SynaF34Reflash_BlockData = SynaF34DataBase + 2;
200 SynaF34ReflashQuery_BootID = SynaF34QueryBase;
201 SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 2;
202 SynaF34ReflashQuery_FirmwareBlockSize = SynaF34QueryBase + 3;
203 SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase +5;
204 SynaF34ReflashQuery_ConfigBlockSize = SynaF34QueryBase + 3;
205 SynaF34ReflashQuery_ConfigBlockCount = SynaF34QueryBase + 7;
206
207 SynafirmwareImgData = (unsigned char *)((&my_image_bin[0])+0x100);
208 SynaconfigImgData = (unsigned char *)(SynafirmwareImgData+SynaImageSize);
209 SynafirmwareImgVersion = (unsigned int)(my_image_bin[7]);
210
211 switch(SynafirmwareImgVersion)
212 {
213 case 2:
214 SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xD0);
215 break;
216 case 3:
217 case 4:
218 SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xC0);
219 break;
220 case 5:
221 SynalockImgData = (unsigned char *)((&my_image_bin[0]) + 0xB0);
222 break;
223 default: break;
224 }
225 }
226
227 /* SynaInitialize sets up the reflahs process
228 */
229 void SynaInitialize(struct synaptics_ts_data *ts)
230 {
231 unsigned char uData[2];
232
233 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
234
235 SYNAPTICS_INFO_MSG("Initializing Reflash Process...\n");
236 uData[0] = 0x00;
237 writeRMI(ts->client, 0xff, &uData[0], 1);
238
239 SynaSetup(ts);
240
241 //Set all interrupt enable
242 uData[0] = 0x0f;
243 writeRMI(ts->client, SynaF01ControlBase+1, &uData[0], 1);
244
245 readRMI(ts->client, SynaF34ReflashQuery_FirmwareBlockSize, &uData[0], 2);
246
247 SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);
248 }
249
250 /* SynaReadFirmwareInfo reads the F34 query registers and retrieves the block size and count
251 * of the firmware section of the image to be reflashed
252 */
253 void SynaReadFirmwareInfo(struct synaptics_ts_data *ts)
254 {
255 unsigned char uData[2];
256 uData[0] = 0;
257 uData[1] = 0;
258
259 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
260
261 SYNAPTICS_INFO_MSG("Read Firmware Info\n");
262
263 readRMI(ts->client, SynaF34ReflashQuery_FirmwareBlockSize, &uData[0], 2);
264 SynaFirmwareBlockSize = uData[0] | (uData[1] << 8);
265
266 readRMI(ts->client, SynaF34ReflashQuery_FirmwareBlockCount, &uData[0], 2);
267 SynaFirmwareBlockCount = uData[0] | (uData[1] << 8);
268 SynaImageSize = SynaFirmwareBlockCount * SynaFirmwareBlockSize;
269 }
270
271 /* SynaReadConfigInfo reads the F34 query registers and retrieves the block size and count
272 * of the configuration section of the image to be reflashed
273 */
274 void SynaReadConfigInfo(struct synaptics_ts_data *ts)
275 {
276 unsigned char uData[2];
277 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
278
279 SYNAPTICS_INFO_MSG("Read Config Info\n");
280
281 readRMI(ts->client, SynaF34ReflashQuery_ConfigBlockSize, &uData[0], 2);
282 SynaConfigBlockSize = uData[0] | (uData[1] << 8);
283
284 readRMI(ts->client, SynaF34ReflashQuery_ConfigBlockCount, &uData[0], 2);
285 SynaConfigBlockCount = uData[0] | (uData[1] << 8);
286 SynaConfigImageSize = SynaConfigBlockCount * SynaConfigBlockSize;
287 }
288
289 /* SynaReadBootloadID reads the F34 query registers and retrieves the bootloader ID of the firmware
290 */
291 void SynaReadBootloadID(struct synaptics_ts_data *ts)
292 {
293 unsigned char uData[2];
294 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
295
296 readRMI(ts->client, SynaF34ReflashQuery_BootID, &uData[0], 2);
297 SynaBootloadID = uData[0] + uData[1] * 0x100;
298 }
299
300 /* SynaWriteBootloadID writes the bootloader ID to the F34 data register to unlock the reflash process
301 */
302 void SynaWriteBootloadID(struct synaptics_ts_data *ts)
303 {
304 unsigned char uData[2];
305 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
306
307 uData[0] = SynaBootloadID % 0x100;
308 uData[1] = SynaBootloadID / 0x100;
309
310 writeRMI(ts->client, SynaF34Reflash_BlockData, &uData[0], 2);
311 }
312
313 /* SynaWaitForATTN waits for ATTN to be asserted within a certain time threshold.
314 */
315 int SynaWaitForATTN(int time, struct synaptics_ts_data *ts)
316 {
317 int trial_us=0;
318
319 while((mt_get_gpio_in(ts->pdata->int_gpio) != 0) && (trial_us < (time * 1000))) {
320 udelay(1);
321 trial_us++;
322 }
323
324 if (mt_get_gpio_in(ts->pdata->int_gpio) != 0)
325 return -EBUSY;
326 else
327 return 0;
328 }
329
330 /* SynaWaitATTN waits for ATTN to be asserted within a certain time threshold.
331 * The function also checks for the F34 "Program Enabled" bit and clear ATTN accordingly.
332 */
333 int SynaWaitATTN(struct synaptics_ts_data *ts)
334 {
335 int ret;
336 unsigned char uData;
337 unsigned char uStatus;
338
339 ret = SynaWaitForATTN(1000, ts);
340 if (ret < 0) {
341 SYNAPTICS_ERR_MSG("SynaWaitForATTN 1000ms timeout error\n");
342 return ret;
343 }
344
345 do {
346 readRMI(ts->client, SynaF34_FlashControl, &uData, 1);
347 readRMI(ts->client, (SynaF01DataBase + 1), &uStatus, 1);
348 } while (uData!= 0x80);
349
350 return 0;
351 }
352
353 /* SynaEnableFlashing kicks off the reflash process
354 */
355 int SynaEnableFlashing(struct synaptics_ts_data *ts)
356 {
357 int ret;
358 unsigned char uData;
359 unsigned char uStatus;
360 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
361
362 SYNAPTICS_INFO_MSG("Enable Reflash...\n");
363
364 // Reflash is enabled by first reading the bootloader ID from the firmware and write it back
365 SynaReadBootloadID(ts);
366 SynaWriteBootloadID(ts);
367
368 // Make sure Reflash is not already enabled
369 do {
370 readRMI(ts->client, SynaF34_FlashControl, &uData, 1);
371 } while (((uData & 0x0f) != 0x00));
372
373 // Clear ATTN
374 readRMI (ts->client, SynaF01DataBase, &uStatus, 1);
375
376 if ((uStatus &0x40) == 0)
377 {
378 // Write the "Enable Flash Programming command to F34 Control register
379 // Wait for ATTN and then clear the ATTN.
380 uData = 0x0f;
381 writeRMI(ts->client, SynaF34_FlashControl, &uData, 1);
382 ret = SynaWaitForATTN(100, ts);
383 if (ret < 0) {
384 SYNAPTICS_ERR_MSG("SynaWaitForATTN 100ms timeout error\n");
385 return ret;
386 }
387 readRMI(ts->client, (SynaF01DataBase + 1), &uStatus, 1);
388 // Scan the PDT again to ensure all register offsets are correct
389 SynaSetup(ts);
390 // Read the "Program Enabled" bit of the F34 Control register, and proceed only if the
391 // bit is set.
392 do{
393 readRMI(ts->client, SynaF34_FlashControl, &uData, 1);
394 // In practice, if uData!=0x80 happens for multiple counts, it indicates reflash
395 // is failed to be enabled, and program should quit
396 }while (uData != 0x80);
397 }
398
399 return 0;
400 }
401
402 /* SynaProgramConfiguration writes the configuration section of the image block by block
403 */
404 int SynaProgramConfiguration(struct synaptics_ts_data *ts)
405 {
406 unsigned char uData[2];
407 unsigned char *puData = (unsigned char *)&my_image_bin[0xb100];
408
409 unsigned short blockNum;
410 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
411
412 SYNAPTICS_INFO_MSG("Program Configuration Section...\n");
413
414 for (blockNum = 0; blockNum < SynaConfigBlockCount; blockNum++)
415 {
416 uData[0] = blockNum & 0xff;
417 uData[1] = (blockNum & 0xff00) >> 8;
418
419 //Block by blcok, write the block number and data to the corresponding F34 data registers
420 writeRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);
421 writeRMI(ts->client, SynaF34Reflash_BlockData, puData, SynaConfigBlockSize);
422 puData += SynaConfigBlockSize;
423
424 // Issue the "Write Configuration Block" command
425 uData[0] = 0x06;
426 writeRMI(ts->client, SynaF34_FlashControl, &uData[0], 1);
427 if(SynaWaitATTN(ts) < 0) return -1;
428 SYNAPTICS_INFO_MSG(".\n");
429 }
430 return 0;
431 }
432
433 /* SynaFinalizeReflash finalizes the reflash process
434 */
435 int SynaFinalizeReflash(struct synaptics_ts_data *ts)
436 {
437 int ret;
438 unsigned char uData;
439 unsigned char uStatus;
440 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
441
442 SYNAPTICS_INFO_MSG("Finalizing Reflash...\n");
443
444 // Issue the "Reset" command to F01 command register to reset the chip
445 // This command will also test the new firmware image and check if its is valid
446 uData = 1;
447 writeRMI(ts->client, SynaF01CommandBase, &uData, 1);
448
449 ret = SynaWaitForATTN(100, ts);
450 if (ret < 0) {
451 SYNAPTICS_ERR_MSG("SynaWaitForATTN 100ms timeout error\n");
452 return ret;
453 }
454 readRMI(ts->client, SynaF01DataBase, &uData, 1);
455
456 // Sanity check that the reflash process is still enabled
457 do {
458 readRMI(ts->client, SynaF34_FlashControl, &uStatus, 1);
459 } while ((uStatus & 0x0f) != 0x00);
460 readRMI(ts->client, (SynaF01DataBase + 1), &uStatus, 1);
461
462 SynaSetup(ts);
463 uData = 0;
464
465 // Check if the "Program Enabled" bit in F01 data register is cleared
466 // Reflash is completed, and the image passes testing when the bit is cleared
467 do {
468 readRMI(ts->client, SynaF01DataBase, &uData, 1);
469 } while ((uData & 0x40) != 0);
470
471 // Rescan PDT the update any changed register offsets
472 SynaSetup(ts);
473
474 SYNAPTICS_INFO_MSG("Reflash Completed. Please reboot.\n");
475
476 return 0;
477 }
478
479 /* SynaFlashFirmwareWrite writes the firmware section of the image block by block
480 */
481 int SynaFlashFirmwareWrite(struct synaptics_ts_data *ts)
482 {
483 unsigned char *puFirmwareData = (unsigned char *)&my_image_bin[0x100];
484 unsigned char uData[2];
485 unsigned short blockNum;
486 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
487
488 for (blockNum = 0; blockNum < SynaFirmwareBlockCount; ++blockNum)
489 {
490 if(blockNum%100 == 0)
491 SYNAPTICS_INFO_MSG("blockNum = [%d], (SynaFirmwareBlockCount=%d)\n", blockNum, SynaFirmwareBlockCount);
492 //Block by blcok, write the block number and data to the corresponding F34 data registers
493 uData[0] = blockNum & 0xff;
494 uData[1] = (blockNum & 0xff00) >> 8;
495 writeRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);
496
497 writeRMI(ts->client, SynaF34Reflash_BlockData, puFirmwareData, SynaFirmwareBlockSize);
498 puFirmwareData += SynaFirmwareBlockSize;
499
500 // Issue the "Write Firmware Block" command
501 uData[0] = 2;
502 writeRMI(ts->client, SynaF34_FlashControl, &uData[0], 1);
503
504 if(SynaWaitATTN(ts) < 0) return -1;
505 }
506 return 0;
507
508 }
509
510 /* SynaProgramFirmware prepares the firmware writing process
511 */
512 int SynaProgramFirmware(struct synaptics_ts_data *ts)
513 {
514 int ret;
515 unsigned char uData;
516 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
517
518 SYNAPTICS_INFO_MSG("Program Firmware Section...\n");
519
520 SynaWriteBootloadID(ts);
521
522 uData = 3;
523 writeRMI(ts->client, SynaF34_FlashControl, &uData, 1);
524
525 msleep(1000);
526
527 SynaWaitATTN(ts);
528
529 ret = SynaFlashFirmwareWrite(ts);
530 if(ret < 0){
531 SYNAPTICS_ERR_MSG("SynaFlashFirmwareWrite fail\n");
532 return ret;
533 }
534
535 return 0;
536 }
537
538
539 /* eraseConfigBlock erases the config block
540 */
541 int eraseConfigBlock(struct synaptics_ts_data *ts)
542 {
543 unsigned char uData;
544 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
545
546 // Erase of config block is done by first entering into bootloader mode
547 SynaReadBootloadID(ts);
548 SynaWriteBootloadID(ts);
549
550 // Command 7 to erase config block
551 uData = 7;
552 writeRMI(ts->client, SynaF34_FlashControl, &uData, 1);
553
554 if(SynaWaitATTN(ts) < 0) return -1;
555
556 return 0;
557 }
558
559 // CRC_Calculate illustates how to calculate a checksum from the config block data.
560 // With DS4, the config block checksum is calculated and applies towards the end of
561 // the config block data automatically
562 // Variable data to this function represents the data only portion of the config block
563 // Varaible len represents the length of the variable data.
564 void CRC_Calculate(unsigned short * data, unsigned short len)
565 {
566 short i;
567 unsigned long Data_CRC = 0xffffffff;
568 unsigned long sum1 = (unsigned long)(Data_CRC & 0xFFFF);
569 unsigned long sum2 = (unsigned long)(Data_CRC >> 16);
570 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
571
572 for (i = 0; i < len; i++)
573 {
574 unsigned long temp = data[i];
575 sum1 += temp;
576 sum2 += sum1;
577 sum1 = (unsigned long)((sum1 & 0xffff) + (sum1 >> 16));
578 sum2 = (unsigned long)((sum2 & 0xffff) + (sum2 >> 16));
579 }
580
581 Data_CRC = (unsigned long)(sum2 << 16 | sum1);
582 }
583
584 int SynaBootloaderLock(struct synaptics_ts_data *ts)
585 {
586 int ret;
587 unsigned short lockBlockCount;
588 unsigned char *puFirmwareData = SynalockImgData;
589 unsigned char uData[2];
590 unsigned short uBlockNum;
591
592 // Check if device is in unlocked state
593 readRMI(ts->client, (SynaF34QueryBase+ 2), &uData[0], 1);
594
595 //Device is unlocked
596 if (uData[0] & 0x02)
597 {
598 SYNAPTICS_INFO_MSG("Device unlocked. Lock it first...\n");
599 // Different bootloader version has different block count for the lockdown data
600 // Need to check the bootloader version from the image file being reflashed
601 switch (SynafirmwareImgVersion)
602 {
603 case 2:
604 lockBlockCount = 3;
605 break;
606 case 3:
607 case 4:
608 lockBlockCount = 4;
609 break;
610 case 5:
611 lockBlockCount = 5;
612 break;
613 default:
614 lockBlockCount = 0;
615 break;
616 }
617
618 // Write the lockdown info block by block
619 // This reference code of lockdown process does not check for bootloader version
620 // currently programmed on the ASIC against the bootloader version of the image to
621 // be reflashed. Such case should not happen in practice. Reflashing cross different
622 // bootloader versions is not supported.
623 for (uBlockNum = 0; uBlockNum < lockBlockCount; ++uBlockNum)
624 {
625 uData[0] = uBlockNum & 0xff;
626 uData[1] = (uBlockNum & 0xff00) >> 8;
627
628 /* Write Block Number */
629 readRMI(ts->client, SynaF34Reflash_BlockNum, &uData[0], 2);
630
631 /* Write Data Block */
632 writeRMI(ts->client, SynaF34Reflash_BlockData, puFirmwareData, SynaFirmwareBlockSize);
633
634 /* Move to next data block */
635 puFirmwareData += SynaFirmwareBlockSize;
636
637 /* Issue Write Lockdown Block command */
638 uData[0] = 4;
639 writeRMI(ts->client, SynaF34_FlashControl, &uData[0], 1);
640
641 /* Wait ATTN until device is done writing the block and is ready for the next. */
642 if(SynaWaitATTN(ts) < 0) return -1;
643 }
644 SYNAPTICS_INFO_MSG("Device locking done.\n");
645
646 // Enable reflash again to finish the lockdown process.
647 // Since this lockdown process is part of the reflash process, we are enabling
648 // reflash instead, rather than resetting the device to finish the unlock procedure.
649 ret = SynaEnableFlashing(ts);
650 if(ret < 0) {
651 SYNAPTICS_ERR_MSG("SynaEnableFlashing fail\n");
652 return ret;
653 }
654 }
655 else SYNAPTICS_INFO_MSG("Device already locked.\n");
656
657 return 0;
658 }
659
660 /* ConfigBlockReflash reflashes the config block only
661 */
662 int ConfigBlockReflash(struct synaptics_ts_data *ts)
663 {
664 int ret;
665 unsigned char uData[2];
666 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
667
668 SynaInitialize(ts);
669
670 SynaReadConfigInfo(ts);
671
672 SynaReadFirmwareInfo(ts);
673
674 SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
675
676 ret = SynaEnableFlashing(ts);
677 if(ret < 0) {
678 SYNAPTICS_ERR_MSG("SynaEnableFlashing fail\n");
679 return ret;
680 }
681
682 // Check if device is in unlocked state
683 readRMI(ts->client, (SynaF34QueryBase + 2), &uData[0], 1);
684
685 //Device is unlocked
686 if (uData[0] & 0x02)
687 {
688 ret = SynaFinalizeReflash(ts);
689 if(ret < 0) {
690 SYNAPTICS_ERR_MSG("SynaFinalizeReflash fail\n");
691 return ret;
692 }
693 return 0;
694 // Do not reflash config block if not locked.
695 }
696
697 ret = eraseConfigBlock(ts);
698 if(ret < 0) {
699 SYNAPTICS_ERR_MSG("eraseConfigBlock fail\n");
700 return ret;
701 }
702
703 ret = SynaProgramConfiguration(ts);
704 if(ret < 0) {
705 SYNAPTICS_ERR_MSG("SynaProgramConfiguration fail\n");
706 return ret;
707 }
708
709 ret = SynaFinalizeReflash(ts);
710 if(ret < 0) {
711 SYNAPTICS_ERR_MSG("SynaFinalizeReflash fail\n");
712 return ret;
713 }
714
715 return 0;
716 }
717
718 /* CompleteReflash reflashes the entire user image, including the configuration block and firmware
719 */
720 int CompleteReflash(struct synaptics_ts_data *ts)
721 {
722 int ret;
723 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
724 SynaInitialize(ts);
725
726 SynaReadConfigInfo(ts);
727
728 SynaReadFirmwareInfo(ts);
729
730 SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
731
732 ret = SynaEnableFlashing(ts);
733 if(ret < 0) {
734 SYNAPTICS_ERR_MSG("SynaEnableFlashing fail\n");
735 return ret;
736 }
737
738 ret = SynaProgramFirmware(ts);
739 if(ret < 0) {
740 SYNAPTICS_ERR_MSG("SynaProgramFirmware fail\n");
741 return ret;
742 }
743
744 ret = SynaProgramConfiguration(ts);
745 if(ret < 0) {
746 SYNAPTICS_ERR_MSG("SynaProgramConfiguration fail\n");
747 return ret;
748 }
749
750 ret = SynaFinalizeReflash(ts);
751 if(ret < 0) {
752 SYNAPTICS_ERR_MSG("SynaFinalizeReflash fail\n");
753 return ret;
754 }
755
756 return 0;
757 }
758
759 int CompleteReflash_Lockdown(struct synaptics_ts_data *ts)
760 {
761 int ret;
762 SYNAPTICS_INFO_MSG("%s\n", __FUNCTION__);
763
764 SynaInitialize(ts);
765
766 SynaReadConfigInfo(ts);
767
768 SynaReadFirmwareInfo(ts);
769
770 SynaF34_FlashControl = SynaF34DataBase + SynaFirmwareBlockSize + 2;
771
772 ret = SynaEnableFlashing(ts);
773 if(ret < 0) {
774 SYNAPTICS_ERR_MSG("SynaEnableFlashing fail\n");
775 return ret;
776 }
777
778 ret = SynaBootloaderLock(ts);
779 if(ret < 0) {
780 SYNAPTICS_ERR_MSG("SynaBootloaderLock fail\n");
781 return ret;
782 }
783
784 ret = SynaProgramFirmware(ts);
785 if(ret < 0) {
786 SYNAPTICS_ERR_MSG("SynaProgramFirmware fail\n");
787 return ret;
788 }
789
790 ret = SynaProgramConfiguration(ts);
791 if(ret < 0) {
792 SYNAPTICS_ERR_MSG("SynaProgramConfiguration fail\n");
793 return ret;
794 }
795
796 ret = SynaFinalizeReflash(ts);
797 if(ret < 0) {
798 SYNAPTICS_ERR_MSG("SynaFinalizeReflash fail\n");
799 return ret;
800 }
801
802 return 0;
803 }
804