17379061ca4834bec22a0b51c16c0a8406d57c9a
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / input / touchscreen / ist30xx / ist30xx_update.c
1 /*
2  *  Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/i2c.h>
17 #include <linux/delay.h>
18 #include <linux/slab.h>
19 #include <linux/firmware.h>
20 #include <asm/unaligned.h>
21
22 /* Including the definition of S_IRWXUGO */
23 // Can use S_IRUGO for better security. Verify the same.
24 #include <linux/stat.h>
25
26 #include "ist30xx.h"
27 #include "ist30xx_update.h"
28 #include "ist30xx_tracking.h"
29
30 #if IST30XX_DEBUG
31 #include "ist30xx_misc.h"
32 #endif
33
34 #if IST30XX_INTERNAL_BIN
35 #if defined(CONFIG_MACH_KANAS)
36 #include "./firmware/IST3038_FW_KANAS.h"
37 #elif defined(CONFIG_MACH_TSHARKWSAMSUNG)
38 #include "./firmware/ist3038_fw_tshark_ver0007.h"
39 #elif defined(CONFIG_MACH_CORE3)
40 #include "./firmware/ist3038_fw_kanas_ver0006_20140401.h"
41 #else
42 #include "./firmware/ist3038_fw_kanas_ver0006_20140401.h"
43 #endif
44 # if IST30XX_MULTIPLE_TSP
45 #  include "./firmware/ist3038_fw_kanas_ver0001_20140225.h"     //Not proper file
46 #  include "./firmware/ist3038_fw_kanas_ver0001_20140225.h"     //Not proper file
47 # endif
48 #endif // IST30XX_INTERNAL_BIN
49
50 struct ist30xx_tags *ts_tags;
51
52 u32 ist30xx_fw_ver = 0;
53 u32 ist30xx_param_ver = 0;
54 u32 ist30xx_sub_ver = 0;
55
56 extern struct ist30xx_data *ts_data;
57
58 extern void ist30xx_disable_irq(struct ist30xx_data *data);
59 extern void ist30xx_enable_irq(struct ist30xx_data *data);
60
61
62 int ist30xx_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
63                          int msg_num, u8 *cmd_buf)
64 {
65         int ret = 0;
66         int idx = msg_num - 1;
67         int size = msgs[idx].len;
68         u8 *msg_buf = NULL;
69         u8 *pbuf = NULL;
70         int max_size = 0;
71
72         if (msg_num == WRITE_CMD_MSG_LEN)
73                 max_size = I2C_MAX_WRITE_SIZE;
74         else if (msg_num == READ_CMD_MSG_LEN)
75                 max_size = I2C_MAX_READ_SIZE;
76
77         if (unlikely(max_size == 0)) {
78                 tsp_err("%s() : transaction size(%d)\n", __func__, max_size);
79                 return -EINVAL;
80         }
81
82         if (msg_num == WRITE_CMD_MSG_LEN) {
83                 msg_buf = kmalloc(max_size + IST30XX_ADDR_LEN, GFP_KERNEL);
84                 if (!msg_buf)
85                         return -ENOMEM;
86                 memcpy(msg_buf, cmd_buf, IST30XX_ADDR_LEN);
87                 pbuf = msgs[idx].buf;
88         }
89
90         while (size > 0) {
91                 int trans_size = (size >= max_size ? max_size : size);
92
93                 msgs[idx].len = trans_size;
94                 if (msg_num == WRITE_CMD_MSG_LEN) {
95                         memcpy(&msg_buf[IST30XX_ADDR_LEN], pbuf, trans_size);
96                         msgs[idx].buf = msg_buf;
97                         msgs[idx].len += IST30XX_ADDR_LEN;
98                 }
99                 ret = i2c_transfer(adap, msgs, msg_num);
100                 if (unlikely(ret != msg_num)) {
101                         tsp_err("%s() : i2c_transfer failed(%d), num=%d\n",
102                                 __func__, ret, msg_num);
103                         break;
104                 }
105
106                 if (msg_num == WRITE_CMD_MSG_LEN)
107                         pbuf += trans_size;
108                 else
109                         msgs[idx].buf += trans_size;
110
111                 size -= trans_size;
112         }
113
114         if (msg_num == WRITE_CMD_MSG_LEN)
115                 kfree(msg_buf);
116
117         return ret;
118 }
119
120 int ist30xx_read_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len)
121 {
122         int ret, i;
123         u32 le_reg = cpu_to_be32(cmd);
124
125         struct i2c_msg msg[READ_CMD_MSG_LEN] = {
126                 {
127                         .addr = client->addr,
128                         .flags = 0,
129                         .len = IST30XX_ADDR_LEN,
130                         .buf = (u8 *)&le_reg,
131                 },
132                 {
133                         .addr = client->addr,
134                         .flags = I2C_M_RD,
135                         .len = len * IST30XX_DATA_LEN,
136                         .buf = (u8 *)buf,
137                 },
138         };
139
140         ret = ist30xx_i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN, NULL);
141         if (unlikely(ret != READ_CMD_MSG_LEN))
142                 return -EIO;
143
144         for (i = 0; i < len; i++)
145                 buf[i] = cpu_to_be32(buf[i]);
146
147         return 0;
148 }
149
150 int ist30xx_write_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len)
151 {
152         int ret;
153         struct i2c_msg msg;
154         u8 cmd_buf[IST30XX_ADDR_LEN];
155         u8 msg_buf[IST30XX_DATA_LEN * (len + 1)];
156
157         put_unaligned_be32(cmd, cmd_buf);
158
159         if (likely(len > 0)) {
160                 int i;
161                 for (i = 0; i < len; i++)
162                         put_unaligned_be32(buf[i], msg_buf + (i * IST30XX_DATA_LEN));
163         } else {
164                 /* then add dummy data(4byte) */
165                 put_unaligned_be32(0, msg_buf);
166                 len = 1;
167         }
168
169         msg.addr = client->addr;
170         msg.flags = 0;
171         msg.len = IST30XX_DATA_LEN * len;
172         msg.buf = msg_buf;
173
174         ret = ist30xx_i2c_transfer(client->adapter, &msg, WRITE_CMD_MSG_LEN, cmd_buf);
175         if (unlikely(ret != WRITE_CMD_MSG_LEN))
176                 return -EIO;
177
178         return 0;
179 }
180
181 int ist30xxb_burst_read(struct i2c_client *client, u32 addr,
182                         u32 *buf32, int len)
183 {
184         int i;
185         int max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN;
186
187         addr |= IST30XXB_BURST_ACCESS;
188
189         for (i = 0; i < len; i += max_len) {
190                 int ret = 0;
191                 if (len < max_len) max_len = len;
192
193                 ret = ist30xx_read_buf(client, addr, buf32, max_len);
194                 if (unlikely(ret)) {
195                         tsp_err("Burst fail, addr: %x\n", __func__, addr);
196                         return ret;
197                 }
198
199                 addr += max_len * IST30XX_DATA_LEN;
200                 buf32 += max_len;
201         }
202
203         return 0;
204 }
205
206 #define IST30XXB_ISP_READ       (1)
207 #define IST30XXB_ISP_WRITE      (2)
208 #define IST30XXB_ISP_ERASE_ALL  (3)
209 #define IST30XXB_ISP_ERASE_PAGE (4)
210
211 int ist30xxb_isp_reset(void)
212 {
213         int ret = 0;
214
215         ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPPWRCTRL, 0xB200);
216         if (unlikely(ret)) return ret;
217
218         ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPPWRCTRL, 0x9200);
219         if (unlikely(ret)) return ret;
220
221         msleep(1);
222
223         return ret;
224 }
225
226 int ist30xxb_isp_enable(bool enable)
227 {
228         int ret = 0;
229
230         if (enable) {
231                 ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPISPEN, 0x3);
232                 if (unlikely(ret)) return ret;
233
234                 ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_LDOOSC, 0xF4C8);
235                 if (unlikely(ret)) return ret;
236
237                 ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_CLKDIV, 0x3);
238                 if (unlikely(ret)) return ret;
239
240                 msleep(5);
241         } else {
242                 ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPISPEN, 0x2);
243                 if (unlikely(ret)) return ret;
244
245                 msleep(1);
246         }
247
248         return 0;
249 }
250
251 int ist30xxb_isp_mode(int mode)
252 {
253         int ret = 0;
254         u32 val = 0;
255
256         switch (mode) {
257         case IST30XXB_ISP_READ:
258                 val = 0x1C0;
259                 break;
260         case IST30XXB_ISP_WRITE:
261                 val = 0x1A8;
262                 break;
263         case IST30XXB_ISP_ERASE_ALL:
264                 val = 0x1A7;
265                 break;
266         case IST30XXB_ISP_ERASE_PAGE:
267                 val = 0x1A3;
268                 break;
269         default:
270                 tsp_err("ISP fail, unknown mode\n");
271                 return -EINVAL;
272         }
273
274         ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPMODE, val);
275         if (unlikely(ret)) {
276                 tsp_err("ISP fail, IST30XXB_REG_EEPMODE\n");
277                 return ret;
278         }
279
280         return 0;
281 }
282
283 int ist30xxb_isp_erase(struct i2c_client *client, int mode, u32 addr)
284 {
285         int ret = 0;
286         u32 val = 0x1A0;
287         u8 buf[EEPROM_PAGE_SIZE] = { 0, };
288
289         ret = ist30xxb_isp_mode(mode);
290         if (unlikely(ret)) return ret;
291
292         ret = ist30xx_write_cmd(client, IST30XXB_REG_EEPADDR, addr);
293         if (unlikely(ret)) {
294                 tsp_err("ISP fail, IST30XXB_REG_EEPADDR\n");
295                 return ret;
296         }
297
298         val = (EEPROM_PAGE_SIZE / IST30XX_DATA_LEN);
299         ret = ist30xx_write_buf(client, IST30XXB_REG_EEPWDAT, (u32 *)buf, val);
300         if (unlikely(ret)) {
301                 tsp_err("ISP fail, IST30XXB_REG_EEPWDAT\n");
302                 return ret;
303         }
304
305         msleep(30);
306
307         ist30xxb_isp_reset();
308
309         return 0;
310 }
311
312 int ist30xxb_isp_write(struct i2c_client *client, u32 addr,
313                        const u32 *buf32, int len)
314 {
315         int ret = 0;
316
317         ret = ist30xx_write_cmd(client, IST30XXB_REG_EEPADDR, addr);
318         if (unlikely(ret)) {
319                 tsp_err("ISP fail, IST30XXB_REG_EEPADDR\n");
320                 return ret;
321         }
322
323         ret = ist30xx_write_buf(client, IST30XXB_REG_EEPWDAT, (u32 *)buf32, len);
324         if (unlikely(ret)) {
325                 tsp_err("ISP fail, IST30XXB_REG_EEPWDAT\n");
326                 return ret;
327         }
328
329         return 0;
330 }
331
332 int ist30xxb_isp_read(struct i2c_client *client, u32 addr,
333                       u32 *buf32, int len)
334 {
335         int i;
336         int max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN;
337
338         for (i = 0; i < len; i += max_len) {
339                 int ret = 0;
340                 if (len < max_len) max_len = len;
341
342                 /* IST30xxB ISP read mode */
343                 ret = ist30xxb_isp_mode(IST30XXB_ISP_READ);
344                 if (unlikely(ret)) return ret;
345
346                 ret = ist30xx_write_cmd(client, IST30XXB_REG_EEPADDR, addr);
347                 if (unlikely(ret)) {
348                         tsp_err("ISP fail, IST30XXB_REG_EEPADDR\n");
349                         return ret;
350                 }
351
352                 ret = ist30xx_read_buf(client, IST30XXB_REG_EEPRDAT, buf32, max_len);
353                 if (unlikely(ret)) {
354                         tsp_err("ISP fail, IST30XXB_REG_EEPWDAT\n");
355                         return ret;
356                 }
357
358                 addr += max_len * IST30XX_DATA_LEN;
359                 buf32 += max_len;
360         }
361
362         return 0;
363 }
364
365 int ist30xxb_cmd_read_chksum(struct i2c_client *client,
366                              u32 start_addr, u32 end_addr, u32 *chksum)
367 {
368         int ret = 0;
369         u32 val = (1 << 31); // Chkecksum enable
370
371         val |= start_addr;
372         val |= (end_addr / IST30XX_DATA_LEN - 1) << 16;
373
374         ret = ist30xx_write_cmd(client, IST30XXB_REG_CHKSMOD, val);
375         if (unlikely(ret)) {
376                 tsp_err("ISP fail, IST30XXB_REG_CHKSMOD (%x)\n", val);
377                 return ret;
378         }
379
380         msleep(10);
381
382         ret = ist30xx_read_cmd(client, IST30XXB_REG_CHKSDAT, chksum);
383         if (unlikely(ret)) {
384                 tsp_err("ISP fail, IST30XXB_REG_CHKSDAT (%x)\n", chksum);
385                 return ret;
386         }
387
388         tsp_verb("chksum: %x (%x~%x)\n", *chksum, start_addr, end_addr);
389
390         return 0;
391 }
392
393 int ist30xxb_read_chksum(struct i2c_client *client, u32 *chksum)
394 {
395         int ret = 0;
396         u32 start_addr, end_addr;
397         u32 chksum1 = 0, chksum2 = 0;
398
399         start_addr = 0;
400         end_addr = ts_data->tags.flag_addr;
401         ret = ist30xxb_cmd_read_chksum(client, start_addr, end_addr, &chksum1);
402         if (unlikely(ret)) return ret;
403
404         start_addr = ts_data->tags.flag_addr + ts_data->tags.flag_size;
405         end_addr = ts_data->tags.sensor2_addr + ts_data->tags.sensor2_size;
406         ret = ist30xxb_cmd_read_chksum(client, start_addr, end_addr, &chksum2);
407         if (unlikely(ret)) return ret;
408
409         *chksum = chksum1 | (chksum2 << 16);
410
411         tsp_info("Chksum: %x(%x~%x, %x~%x)\n", *chksum, 0, ts_data->tags.flag_addr,
412                  start_addr, end_addr);
413
414         return 0;
415 }
416
417
418 int ist30xxb_isp_fw_read(struct i2c_client *client, u32 *buf32)
419 {
420         int ret = 0;
421         int i;
422
423         u16 addr = EEPROM_BASE_ADDR;
424         int len = EEPROM_PAGE_SIZE / IST30XX_DATA_LEN;
425
426         ist30xx_reset();
427
428         /* IST30xxB ISP enable */
429         ret = ist30xxb_isp_enable(true);
430         if (unlikely(ret)) return ret;
431
432         for (i = 0; i < IST30XX_EEPROM_SIZE; i += EEPROM_PAGE_SIZE) {
433                 ret = ist30xxb_isp_read(client, addr, buf32, len);
434                 if (unlikely(ret)) goto isp_fw_read_end;
435
436                 addr += EEPROM_PAGE_SIZE;
437                 buf32 += len;
438         }
439
440 isp_fw_read_end:
441         /* IST30xxB ISP disable */
442         ist30xxb_isp_enable(false);
443         return ret;
444 }
445
446 int ist30xxb_isp_fw_update(struct i2c_client *client, const u8 *buf, u32 *chksum)
447 {
448         int ret = 0;
449         int i;
450         u32 page_cnt = IST30XX_EEPROM_SIZE / EEPROM_PAGE_SIZE;
451         u16 addr = EEPROM_BASE_ADDR;
452         int len = EEPROM_PAGE_SIZE / IST30XX_DATA_LEN;
453
454         ist30xx_tracking(TRACK_CMD_FWUPDATE);
455
456         /* IST30xxB ISP enable */
457         ret = ist30xxb_isp_enable(true);
458         if (unlikely(ret)) goto isp_fw_update_end;
459
460         ret = ist30xxb_isp_erase(client, IST30XXB_ISP_ERASE_ALL, 0);
461         if (unlikely(ret)) goto isp_fw_update_end;
462
463         for (i = 0; i < page_cnt; i++) {
464                 /* IST30xxB ISP write mode */
465                 ret = ist30xxb_isp_mode(IST30XXB_ISP_WRITE);
466                 if (unlikely(ret)) goto isp_fw_update_end;
467
468                 ret = ist30xxb_isp_write(client, addr, (u32 *)buf, len);
469                 if (unlikely(ret)) goto isp_fw_update_end;
470
471                 addr += EEPROM_PAGE_SIZE;
472                 buf += EEPROM_PAGE_SIZE;
473
474                 msleep(5);
475
476                 ist30xxb_isp_reset();
477         }
478
479 isp_fw_update_end:
480         /* IST30xxB ISP disable */
481         ist30xxb_isp_enable(false);
482         return ret;
483 }
484
485 int ist30xxb_isp_bootloader(struct i2c_client *client, const u8 *buf)
486 {
487         int ret = 0;
488         int i;
489         u16 addr = EEPROM_BASE_ADDR;
490         u32 page_cnt = (ts_data->fw.index) / EEPROM_PAGE_SIZE;
491         int buf_cnt = EEPROM_PAGE_SIZE / IST30XX_DATA_LEN;
492
493         tsp_info("*** Bootloader update (0x%x~0x%x) ***\n",
494                  EEPROM_BASE_ADDR, ts_data->fw.index);
495
496         /* IST30xxB ISP enable */
497         ret = ist30xxb_isp_enable(true);
498         if (unlikely(ret)) goto isp_bootldr_end;
499
500         ret = ist30xxb_isp_erase(client, IST30XXB_ISP_ERASE_ALL, 0);
501         if (unlikely(ret)) goto isp_bootldr_end;
502
503         for (i = 0; i < page_cnt; i++) {
504                 /* IST30xxB ISP write mode */
505                 ret = ist30xxb_isp_mode(IST30XXB_ISP_WRITE);
506                 if (unlikely(ret)) goto isp_bootldr_end;
507
508                 ret = ist30xxb_isp_write(client, addr, (u32 *)buf, buf_cnt);
509                 if (unlikely(ret)) goto isp_bootldr_end;
510
511                 addr += EEPROM_PAGE_SIZE;
512                 buf += EEPROM_PAGE_SIZE;
513
514                 msleep(5);
515
516                 ist30xxb_isp_reset();
517         }
518
519 isp_bootldr_end:
520         /* IST30xxB ISP disable */
521         ist30xxb_isp_enable(false);
522         return ret;
523 }
524
525
526 int ist30xx_fw_write(struct i2c_client *client, const u8 *buf)
527 {
528         u32 *buf32 = (u32 *)(buf + ts_data->fw.index);
529         u32 size = ts_data->fw.size;
530
531         if (unlikely(size == 0 || size > IST30XX_EEPROM_SIZE))
532                 return -ENOEXEC;
533
534         while (size > 0) {
535                 int len = (size >= EEPROM_PAGE_SIZE ? EEPROM_PAGE_SIZE : size);
536
537                 int ret = ist30xx_write_buf(client, CMD_ENTER_FW_UPDATE, buf32, (len >> 2));
538                 if (unlikely(ret))
539                         return ret;
540
541                 buf32 += (len >> 2);
542                 size -= len;
543
544                 msleep(5);
545         }
546         return 0;
547 }
548
549
550 u32 ist30xx_parse_ver(int flag, const u8 *buf)
551 {
552         u32 ver = 0;
553         u32 *buf32 = (u32 *)buf;
554
555         if (flag == FLAG_FW)
556                 ver = (u32)buf32[(ts_data->tags.flag_addr + 4) >> 2];
557         else if (flag == FLAG_SUB)
558                 ver = (u32)buf32[(ts_data->tags.flag_addr + 8) >> 2];
559         else if (flag == FLAG_PARAM)
560                 ver = (u32)(buf32[(ts_data->tags.cfg_addr + 4) >> 2] & 0xFFFF);
561         else
562                 tsp_warn("Parsing ver's flag is not corrent!\n");
563
564         return ver;
565 }
566
567
568 int calib_ms_delay = WAIT_CALIB_CNT;
569 int ist30xx_calib_wait(void)
570 {
571         int cnt = calib_ms_delay;
572
573         ts_data->status.calib_msg = 0;
574         while (cnt-- > 0) {
575                 msleep(100);
576
577                 if (ts_data->status.calib_msg) {
578                         tsp_info("Calibration status : %d, Max raw gap : %d - (%08x)\n",
579                                  CALIB_TO_STATUS(ts_data->status.calib_msg),
580                                  CALIB_TO_GAP(ts_data->status.calib_msg),
581                                  ts_data->status.calib_msg);
582
583                         if (CALIB_TO_OS_VALUE(ts_data->status.calib_msg) == 0xFFFF)
584                                 return 1;
585                         else if (CALIB_TO_STATUS(ts_data->status.calib_msg) == 0)
586                                 return 0;  // Calibrate success
587                         else
588                                 return -EAGAIN;
589                 }
590         }
591         tsp_warn("Calibration time out\n");
592
593         return -EPERM;
594 }
595
596 int ist30xx_calibrate(int wait_cnt)
597 {
598         int ret = -ENOEXEC;
599
600         tsp_info("*** Calibrate %ds ***\n", calib_ms_delay / 10);
601
602         ts_data->status.update = 1;
603         while (wait_cnt--) {
604                 ist30xx_disable_irq(ts_data);
605                 ret = ist30xx_cmd_run_device(ts_data->client, true);
606                 if (unlikely(ret)) continue;
607
608                 ret = ist30xx_cmd_calibrate(ts_data->client);
609                 if (unlikely(ret)) continue;
610
611                 ist30xx_enable_irq(ts_data);
612                 ret = ist30xx_calib_wait();
613                 if (likely(ret == 0)) break;
614         }
615
616         ist30xx_disable_irq(ts_data);
617         ist30xx_cmd_run_device(ts_data->client, true);
618
619         ts_data->status.update = 2;
620
621         ist30xx_enable_irq(ts_data);
622
623         return ret;
624 }
625
626
627 int ist30xx_parse_tags(struct ist30xx_data *data, const u8 *buf, const u32 size)
628 {
629         int ret = -EPERM;
630
631         ts_tags = (struct ist30xx_tags *)(&buf[size - sizeof(struct ist30xx_tags)]);
632
633                 if (!strncmp(ts_tags->magic1, IST30XX_TAG_MAGIC, sizeof(ts_tags->magic1))
634                     && !strncmp(ts_tags->magic2, IST30XX_TAG_MAGIC, sizeof(ts_tags->magic2))) {
635                         data->fw.index = ts_tags->fw_addr;
636                         data->fw.size = ts_tags->flag_addr - ts_tags->fw_addr +
637                                         ts_tags->flag_size;
638                         data->fw.chksum = ts_tags->chksum;
639                         data->tags = *ts_tags;
640
641                         ret = 0;
642                 }
643
644         tsp_verb("Tagts magic1: %s, magic2: %s\n",
645                          ts_tags->magic1, ts_tags->magic2);
646                 tsp_verb(" fw: %x(%x)\n", ts_tags->fw_addr, ts_tags->fw_size);
647                 tsp_verb(" flag: %x(%x)\n", ts_tags->flag_addr, ts_tags->flag_size);
648                 tsp_verb(" cfg: %x(%x)\n", ts_tags->cfg_addr, ts_tags->cfg_size);
649                 tsp_verb(" sensor1: %x(%x)\n", ts_tags->sensor1_addr, ts_tags->sensor1_size);
650                 tsp_verb(" sensor2: %x(%x)\n", ts_tags->sensor2_addr, ts_tags->sensor2_size);
651                 tsp_verb(" sensor3: %x(%x)\n", ts_tags->sensor3_addr, ts_tags->sensor3_size);
652                 tsp_verb(" chksum: %x\n", ts_tags->chksum);
653
654         return ret;
655 }
656
657 void ist30xx_get_update_info(struct ist30xx_data *data, const u8 *buf, const u32 size)
658 {
659         int ret;
660
661         ret = ist30xx_parse_tags(data, buf, size);
662         if (unlikely(ret != TAGS_PARSE_OK))
663                 tsp_warn("Cannot find tags of F/W, make a tags by 'tagts.exe'\n");
664 }
665
666 #if (IST30XX_DEBUG) && (IST30XX_INTERNAL_BIN)
667 extern TSP_INFO ist30xx_tsp_info;
668 extern TKEY_INFO ist30xx_tkey_info;
669 int ist30xx_get_tkey_info(struct ist30xx_data *data)
670 {
671         int ret = 0;
672         TSP_INFO *tsp = &ist30xx_tsp_info;
673         TKEY_INFO *tkey = &ist30xx_tkey_info;
674         u8 *cfg_buf;
675
676         ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size);
677         cfg_buf = (u8 *)&data->fw.buf[data->tags.cfg_addr];
678
679         tkey->enable = (bool)(cfg_buf[0x14] & 1);
680         tkey->axis_rx = (bool)((cfg_buf[0x14] >> 1) & 1);
681         tkey->key_num = (u8)cfg_buf[0x15];
682         tkey->ch_num[0] = (u8)cfg_buf[0x16];
683         tkey->ch_num[1] = (u8)cfg_buf[0x17];
684         tkey->ch_num[2] = (u8)cfg_buf[0x18];
685         tkey->ch_num[3] = (u8)cfg_buf[0x19];
686         tkey->ch_num[4] = (u8)cfg_buf[0x1A];
687
688         if (tkey->axis_rx) {
689                 if (tsp->dir.swap_xy) tsp->height -= 1;
690                 else tsp->width -= 1;
691         } else {
692                 if (tsp->dir.swap_xy) tsp->width -= 1;
693                 else tsp->height -= 1;
694         }
695
696         return ret;
697 }
698
699 #define TSP_INFO_SWAP_XY    (1 << 0)
700 #define TSP_INFO_FLIP_X     (1 << 1)
701 #define TSP_INFO_FLIP_Y     (1 << 2)
702 int ist30xx_get_tsp_info(struct ist30xx_data *data)
703 {
704         int ret = 0;
705         TSP_INFO *tsp = &ist30xx_tsp_info;
706         u8 *cfg_buf, *sensor_buf;
707
708         ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size);
709         cfg_buf = (u8 *)&data->fw.buf[data->tags.cfg_addr];
710         sensor_buf = (u8 *)&data->fw.buf[data->tags.sensor1_addr];
711
712         tsp->finger_num = (u8)cfg_buf[0x0E];
713         tsp->dir.swap_xy = (bool)(cfg_buf[0xF] & TSP_INFO_SWAP_XY ? true : false);
714         tsp->dir.flip_x = (bool)(cfg_buf[0xF] & TSP_INFO_FLIP_X ? true : false);
715         tsp->dir.flip_y = (bool)(cfg_buf[0xF] & TSP_INFO_FLIP_Y ? true : false);
716
717         tsp->ch_num.tx = (u8)sensor_buf[0x40];
718         tsp->ch_num.rx = (u8)sensor_buf[0x41];
719
720         tsp->node.len = tsp->ch_num.tx * tsp->ch_num.rx;
721         tsp->height = (tsp->dir.swap_xy ? tsp->ch_num.rx : tsp->ch_num.tx);
722         tsp->width = (tsp->dir.swap_xy ? tsp->ch_num.tx : tsp->ch_num.rx);
723
724         return ret;
725 }
726 #endif // (IST30XX_DEBUG) && (IST30XX_INTERNAL_BIN)
727
728
729 #define update_next_step(ret)   { if (unlikely(ret)) goto end; }
730 int ist30xx_fw_update(struct i2c_client *client, const u8 *buf, int size, bool mode)
731 {
732         int ret = 0;
733         u32 chksum = 0;
734         struct ist30xx_fw *fw = &ts_data->fw;
735
736         tsp_info("*** Firmware update ***\n");
737         tsp_info(" core: %x, param: %x, sub: %x (addr: 0x%x ~ 0x%x)\n",
738                  ist30xx_fw_ver, ist30xx_param_ver, ist30xx_sub_ver,
739                  fw->index, (fw->index + fw->size));
740
741         ts_data->status.update = 1;
742
743         ist30xx_disable_irq(ts_data);
744
745         ist30xx_reset();
746
747         if (mode) { /* ISP Mode */
748                 ret = ist30xxb_isp_fw_update(client, buf, &chksum);
749                 update_next_step(ret);
750         } else { /* I2C SW Mode */
751                 ret = ist30xx_cmd_update(client, CMD_ENTER_FW_UPDATE);
752                 update_next_step(ret);
753
754                 ret = ist30xx_fw_write(client, buf);
755                 update_next_step(ret);
756         }
757         msleep(50);
758
759         buf += IST30XX_EEPROM_SIZE;
760         size -= IST30XX_EEPROM_SIZE;
761
762         ret = ist30xx_cmd_run_device(client, true);
763         update_next_step(ret);
764
765         ret = ist30xx_read_cmd(client, CMD_GET_CHECKSUM, &chksum);
766         if (unlikely((ret) || (chksum != fw->chksum)))
767                 goto end;
768
769         ret = ist30xx_get_ver_info(ts_data);
770         update_next_step(ret);
771
772 end:
773         if (unlikely(ret)) {
774                 tsp_warn("Firmware update Fail!, ret=%d\n", ret);
775         } else if (unlikely(chksum != fw->chksum)) {
776                 tsp_warn("Error CheckSum: %x(%x)\n", chksum, fw->chksum);
777                 ret = -ENOEXEC;
778         }
779
780         ist30xx_enable_irq(ts_data);
781
782         ts_data->status.update = 2;
783
784         return ret;
785 }
786
787 int ist30xx_fw_recovery(struct ist30xx_data *data)
788 {
789         int ret;
790         u8 *fw = data->fw.buf;
791         int fw_size = data->fw.buf_size;
792
793         ist30xx_get_update_info(data, fw, fw_size);
794         ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw);
795         ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw);
796         ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw);
797
798         mutex_lock(&ist30xx_mutex);
799         ret = ist30xx_fw_update(data->client, fw, fw_size, true);
800         mutex_unlock(&ist30xx_mutex);
801
802         ist30xx_calibrate(1);
803
804         ist30xx_init_touch_driver(data);
805
806         return ret;
807 }
808
809
810 #define fw_update_next_step(ret)   { if (unlikely(ret)) \
811                                      { step = 1; goto end; } }
812 #define param_update_next_step(ret)   { if (unlikely(ret)) \
813                                         { step = 2; goto end; } }
814 int ist30xx_fw_param_update(struct i2c_client *client, const u8 *buf)
815 {
816         int ret = 0;
817         int step = 0;
818         u16 len = 0;
819         int size = IST30XX_EEPROM_SIZE;
820         u32 chksum = 0, ver = 0;
821         u32 *param = (u32 *)buf;
822         struct ist30xx_fw *fw = &ts_data->fw;
823
824         tsp_info("*** FW param update ***\n");
825         tsp_info(" core: %x, param: %x, sub: %x (addr: 0x%x ~ 0x%x)\n",
826                  ist30xx_fw_ver, ist30xx_param_ver, ist30xx_sub_ver,
827                  fw->index, (fw->index + fw->size));
828
829         ts_data->status.update = 1;
830
831         ist30xx_disable_irq(ts_data);
832         ist30xx_reset();
833
834         /* FW update by SW */
835         ret = ist30xx_cmd_update(client, CMD_ENTER_FW_UPDATE);
836         fw_update_next_step(ret);
837
838         ret = ist30xx_fw_write(client, buf);
839         fw_update_next_step(ret);
840
841         msleep(50);
842
843         param = (u32 *)(buf + (fw->index + fw->size));
844         size -= fw->size;
845
846         ret = ist30xx_cmd_run_device(client, true);
847         fw_update_next_step(ret);
848
849         ret = ist30xx_read_cmd(client, CMD_GET_CHECKSUM, &chksum);
850         if (unlikely((ret) || (chksum != fw->chksum)))
851                 goto end;
852
853         ret = ist30xx_read_cmd(client, CMD_GET_FW_VER, &ver);
854         update_next_step(ret);
855         fw->prev_core_ver = fw->core_ver;
856         fw->core_ver = ver;
857         tsp_info("F/W core version : %x\n", fw->core_ver);
858
859         /* update parameters */
860         ret = ist30xx_cmd_update(client, CMD_ENTER_UPDATE);
861         param_update_next_step(ret);
862
863         /* config */
864         len = (ts_data->tags.cfg_size >> 2);
865         ret = ist30xx_write_buf(client, CMD_UPDATE_CONFIG, param, len);
866         param_update_next_step(ret);
867         msleep(10);
868
869         param += len;
870         size -= (len << 2);
871
872         /* sensor */
873         len = ((ts_data->tags.sensor1_size + ts_data->tags.sensor2_size) >> 2);
874         ret = ist30xx_write_buf(client, CMD_UPDATE_SENSOR, param, len);
875         param_update_next_step(ret);
876         msleep(10);
877
878         param += len;
879         size -= (len << 2);
880
881         ret = ist30xx_cmd_update(client, CMD_EXIT_UPDATE);
882         param_update_next_step(ret);
883         msleep(120);
884
885         ret = ist30xx_cmd_run_device(client, true);
886         update_next_step(ret);
887
888         ret = ist30xx_read_cmd(client, CMD_GET_PARAM_VER, &ver);
889         update_next_step(ret);
890         fw->prev_param_ver = fw->param_ver;
891         fw->param_ver = ver;
892
893         ret = ist30xx_read_cmd(client, CMD_GET_SUB_VER, &ver);
894         update_next_step(ret);
895         fw->sub_ver = ver;
896
897         tsp_info("Param version : %x, (sub: %x)\n", fw->param_ver, fw->sub_ver);
898
899 end:
900         if (unlikely(ret)) {
901                 if (unlikely(step == 1))
902                         tsp_warn("Firmware update Fail!, ret=%d", ret);
903                 else if (unlikely(step == 2))
904                         tsp_warn("Parameters update Fail!, ret=%d", ret);
905         } else if (unlikely(chksum != fw->chksum)) {
906                 tsp_warn("Error CheckSum: %08x(%08x)\n", chksum, fw->chksum);
907                 ret = -ENOEXEC;
908         }
909
910         ist30xx_enable_irq(ts_data);
911         ts_data->status.update = 2;
912
913         return ret;
914 }
915
916
917 #if IST30XX_INTERNAL_BIN
918 int ist30xx_check_fw(struct ist30xx_data *data, const u8 *buf)
919 {
920         int ret;
921         u32 chksum;
922
923         ret = ist30xx_read_cmd(data->client, CMD_GET_CHECKSUM, &chksum);
924         if (unlikely(ret)) return ret;
925
926         if (unlikely(chksum != data->fw.chksum)) {
927                 tsp_warn("Checksum compare error, (IC: %08x, Bin: %08x)\n",
928                          chksum, data->fw.chksum);
929                 return -EPERM;
930         }
931
932         return 0;
933 }
934
935 bool ist30xx_check_valid_vendor(u32 tsp_vendor)
936 {
937         switch (tsp_vendor) {
938         case TSP_TYPE_ALPS:
939         case TSP_TYPE_EELY:
940         case TSP_TYPE_TOP:
941         case TSP_TYPE_MELFAS:
942         case TSP_TYPE_ILJIN:
943         case TSP_TYPE_SYNOPEX:
944         case TSP_TYPE_SMAC:
945         case TSP_TYPE_OTHERS:
946                 return true;
947         default:
948                 return false;
949         }
950
951         return false;
952 }
953
954 #if IST30XX_MULTIPLE_TSP
955 void ist30xx_set_tsp_fw(struct ist30xx_data *data)
956 {
957         char *str;
958         struct ist30xx_fw *fw = &data->fw;
959
960         switch (data->tsp_type) {
961         case TSP_TYPE_ALPS:
962         case TSP_TYPE_ILJIN:
963                 str = "ALPS/ILJIN";
964                 fw->buf = (u8 *)ist30xxb_fw;
965                 fw->buf_size = sizeof(ist30xxb_fw);
966                 break;
967         case TSP_TYPE_EELY:
968                 str = "EELY";
969                 fw->buf = (u8 *)ist30xxb_fw2;
970                 fw->buf_size = sizeof(ist30xxb_fw2);
971                 break;
972         case TSP_TYPE_TOP:
973                 str = "TopTouch";
974                 fw->buf = (u8 *)ist30xxb_fw1;
975                 fw->buf_size = sizeof(ist30xxb_fw1);
976                 break;
977         case TSP_TYPE_UNKNOWN:
978         default:
979                 str = "Unknown";
980                 tsp_warn("Unknown TSP vendor(0x%x)\n", data->tsp_type);
981                 break;
982         }
983         tsp_info("TSP vendor : %s(%x)\n", str, data->tsp_type);
984
985         ist30xx_get_update_info(ts_data, fw->buf, fw->buf_size);
986         ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw->buf);
987         ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw->buf);
988         ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw->buf);
989 }
990 #endif  // IST30XX_MULTIPLE_TSP
991
992
993 int ist30xx_check_auto_update(struct ist30xx_data *data)
994 {
995         int ret = 0;
996         int retry = IST30XX_FW_UPDATE_RETRY;
997         u32 tsp_type = TSP_TYPE_UNKNOWN;
998         u32 chksum;
999         bool tsp_check = false;
1000         struct ist30xx_fw *fw = &data->fw;
1001
1002         while (retry--) {
1003                 ret = ist30xx_read_cmd(data->client,
1004                                        CMD_GET_TSP_PANNEL_TYPE, &tsp_type);
1005                 if (likely(ret == 0)) {
1006                         if (likely(ist30xx_check_valid_vendor(tsp_type) == true))
1007                                 tsp_check = true;
1008                         break;
1009                 }
1010         }
1011
1012         retry = IST30XX_FW_UPDATE_RETRY;
1013
1014         if (unlikely(!tsp_check)) {
1015                 while (retry--) {
1016                         /* FW recovery */
1017                         tsp_info("tsp type: %x\n", tsp_type);
1018                         ret = ist30xxb_isp_bootloader(data->client, fw->buf);
1019                         if (likely(ret == 0)) {
1020                                 ist30xx_reset();
1021                                 ret = ist30xx_read_cmd(data->client,
1022                                                        CMD_GET_TSP_PANNEL_TYPE, &tsp_type);
1023                                 tsp_info("tsp type: %x\n", tsp_type);
1024                                 if (likely(ret == 0)) // recovery OK
1025                                         if (ist30xx_check_valid_vendor(tsp_type) == true) {
1026                                                 data->tsp_type = tsp_type;
1027 #if IST30XX_MULTIPLE_TSP
1028                                                 ist30xx_set_tsp_fw(data);
1029 #endif
1030                                                 break;
1031                                         }
1032                         }
1033
1034                         if (retry == 0) return 1;  /* TSP is not connected */
1035                 }
1036         }
1037
1038         ist30xx_cmd_run_device(data->client, false);
1039
1040         ist30xx_get_ver_info(data);
1041
1042         if (likely((fw->param_ver > 0) && (fw->param_ver < 0xFFFFFFFF))) {
1043                 if (unlikely(((fw->core_ver & MASK_FW_VER) != IST30XX_FW_VER3) &&
1044                              ((fw->core_ver & MASK_FW_VER) != IST30XX_FW_VER4)))
1045                         goto fw_check_end;
1046
1047                 tsp_info("Version compare IC: %x(%x), BIN: %x(%x)\n",
1048                          fw->param_ver, fw->core_ver, ist30xx_param_ver, ist30xx_fw_ver);
1049
1050                 /* If FW version is same, check FW checksum */
1051                 if (likely((fw->core_ver == ist30xx_fw_ver) &&
1052                            (fw->param_ver == ist30xx_param_ver))) {
1053                         ret = ist30xx_read_cmd(data->client, CMD_GET_CHECKSUM, &chksum);
1054                         if (unlikely((ret) || (chksum != fw->chksum))) {
1055                                 tsp_warn("Checksum error, IC: %x, Bin: %x (ret: %d)\n",
1056                                          chksum, fw->chksum, ret);
1057                                 goto fw_check_end;
1058                         }
1059                 }
1060
1061                 /*
1062                  *  fw->core_ver : FW core version in TSP IC
1063                  *  fw->param_ver : FW version if TSP IC
1064                  *  ist30xx_fw_ver : FW core version in FW Binary
1065                  *  ist30xx_fw_ver : FW version in FW Binary
1066                  */
1067                 /* If the ver of binary is higher than ver of IC, FW update operate. */
1068
1069                 if (likely((fw->core_ver >= ist30xx_fw_ver) &&
1070                            (fw->param_ver >= ist30xx_param_ver)))
1071                         return 0;
1072         }
1073
1074 fw_check_end:
1075         return -EAGAIN;
1076 }
1077
1078 int ist30xx_auto_bin_update(struct ist30xx_data *data)
1079 {
1080         int ret = 0;
1081         int retry = IST30XX_FW_UPDATE_RETRY;
1082         struct ist30xx_fw *fw = &data->fw;
1083
1084         fw->buf = (u8 *)ist30xxb_fw;
1085         fw->buf_size = sizeof(ist30xxb_fw);
1086
1087 #if IST30XX_MULTIPLE_TSP
1088         ist30xx_set_tsp_fw(data);
1089 #else
1090         ist30xx_get_update_info(data, fw->buf, fw->buf_size);
1091         ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw->buf);
1092         ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw->buf);
1093         ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw->buf);
1094 #endif
1095
1096         tsp_info("IC: %x, Binary ver core: %x, param: %x, sub: %x\n",
1097                  data->chip_id, ist30xx_fw_ver, ist30xx_param_ver, ist30xx_sub_ver);
1098         
1099         mutex_lock(&ist30xx_mutex);
1100         ret = ist30xx_check_auto_update(data);
1101         mutex_unlock(&ist30xx_mutex);
1102         if (likely(ret >= 0))
1103                 return ret;
1104
1105 update_bin:   // TSP is not ready / FW update
1106         tsp_info("Update version. param(core): %x(%x, %x) -> %x(%x, %x)\n",
1107                  fw->param_ver, fw->core_ver, fw->sub_ver,
1108                  ist30xx_param_ver, ist30xx_fw_ver, ist30xx_sub_ver);
1109
1110         mutex_lock(&ist30xx_mutex);
1111         while (retry--) {
1112                 ret = ist30xx_fw_update(data->client, fw->buf, fw->buf_size, true);
1113                 if (unlikely(!ret)) break;
1114         }
1115         mutex_unlock(&ist30xx_mutex);
1116
1117         if (unlikely(ret))
1118                 return ret;
1119
1120         if (unlikely(retry > 0 && ist30xx_check_fw(data, fw->buf)))
1121                 goto update_bin;
1122
1123         ist30xx_calibrate(IST30XX_FW_UPDATE_RETRY);
1124         
1125         return ret;
1126 }
1127 #endif // IST30XX_INTERNAL_BIN
1128
1129
1130 /* sysfs: /sys/class/touch/firmware/boot */
1131 ssize_t ist30xx_boot_store(struct device *dev, struct device_attribute *attr,
1132                            const char *buf, size_t size)
1133 {
1134         int fw_size = 0;
1135         u8 *fw = NULL;
1136         char *tmp;
1137         const struct firmware *request_fw = NULL;
1138
1139         unsigned long mode = simple_strtoul(buf, &tmp, 10);
1140
1141         if (mode == MASK_UPDATE_ISP || mode == MASK_UPDATE_FW) {
1142                 int ret = request_firmware(&request_fw, IST30XXB_FW_NAME, &ts_data->client->dev);
1143                 if (ret) {
1144                         tsp_warn("File not found, %s\n", IST30XXB_FW_NAME);
1145                         return size;
1146                 }
1147                 fw = (u8 *)request_fw->data;
1148                 fw_size = (u32)request_fw->size;
1149         } else {
1150 #if IST30XX_INTERNAL_BIN
1151                 fw = ts_data->fw.buf;
1152                 fw_size = ts_data->fw.buf_size;
1153 #else
1154                 return size;
1155 #endif          // IST30XX_INTERNAL_BIN
1156         }
1157
1158         if (mode == 3) {
1159                 tsp_info("EEPROM all erase test\n");
1160                 ist30xx_disable_irq(ts_data);
1161                 mutex_lock(&ist30xx_mutex);
1162
1163                 ist30xxb_isp_enable(true);
1164                 ist30xxb_isp_erase(ts_data->client, IST30XXB_ISP_ERASE_ALL, 0);
1165                 ist30xxb_isp_enable(false);
1166
1167                 mutex_unlock(&ist30xx_mutex);
1168                 ist30xx_enable_irq(ts_data);
1169         } else {
1170                 ist30xx_get_update_info(ts_data, fw, fw_size);
1171                 ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw);
1172
1173                 ist30xx_disable_irq(ts_data);
1174
1175                 mutex_lock(&ist30xx_mutex);
1176                 ist30xxb_isp_bootloader(ts_data->client, fw);
1177                 mutex_unlock(&ist30xx_mutex);
1178
1179                 if (mode == MASK_UPDATE_ISP || mode == MASK_UPDATE_FW)
1180                         release_firmware(request_fw);
1181         }
1182
1183         return size;
1184 }
1185
1186 u32 buf32_eeprom[IST30XX_EEPROM_SIZE / IST30XX_DATA_LEN];
1187 ssize_t ist30xx_fw_show(struct device *dev, struct device_attribute *attr,
1188                         char *buf)
1189 {
1190         int i;
1191         u8 *buf8 = (u8 *)buf32_eeprom;;
1192
1193         mutex_lock(&ist30xx_mutex);
1194         ist30xx_disable_irq(ts_data);
1195
1196         ist30xxb_isp_fw_read(ts_data->client, buf32_eeprom);
1197         for (i = 0; i < IST30XX_EEPROM_SIZE; i += 16) {
1198                 tsp_debug("%07x: %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\n", i,
1199                           buf8[i], buf8[i + 1], buf8[i + 2], buf8[i + 3],
1200                           buf8[i + 4], buf8[i + 5], buf8[i + 6], buf8[i + 7],
1201                           buf8[i + 8], buf8[i + 9], buf8[i + 10], buf8[i + 11],
1202                           buf8[i + 12], buf8[i + 13], buf8[i + 14], buf8[i + 15]);
1203         }
1204
1205         ist30xx_enable_irq(ts_data);
1206         mutex_unlock(&ist30xx_mutex);
1207
1208         return 0;
1209 }
1210
1211 /* sysfs: /sys/class/touch/firmware/fw_only */
1212 ssize_t ist30xx_fw_only_store(struct device *dev, struct device_attribute *attr,
1213                               const char *buf, size_t size)
1214 {
1215         int ret;
1216         bool isp_mode = false;
1217         int fw_size = 0;
1218         u8 *fw = NULL;
1219         char *tmp;
1220         const struct firmware *request_fw = NULL;
1221
1222         unsigned long mode = simple_strtoul(buf, &tmp, 10);
1223
1224         if (mode == MASK_UPDATE_ISP || mode == MASK_UPDATE_FW) {
1225                 ret = request_firmware(&request_fw, IST30XXB_FW_NAME, &ts_data->client->dev);
1226                 if (ret) {
1227                         tsp_warn("File not found, %s\n", IST30XXB_FW_NAME);
1228                         return size;
1229                 }
1230                 fw = (u8 *)request_fw->data;
1231                 fw_size = (u32)request_fw->size;
1232                 isp_mode = (mode == MASK_UPDATE_ISP ? true : false);
1233         } else {
1234 #if IST30XX_INTERNAL_BIN
1235                 fw = ts_data->fw.buf;
1236                 fw_size = ts_data->fw.buf_size;
1237 #else
1238                 return size;
1239 #endif          // IST30XX_INTERNAL_BIN
1240         }
1241
1242         ist30xx_get_update_info(ts_data, fw, fw_size);
1243         ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw);
1244         ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw);
1245         ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw);
1246
1247         mutex_lock(&ist30xx_mutex);
1248         ist30xx_fw_update(ts_data->client, fw, fw_size, isp_mode);
1249         mutex_unlock(&ist30xx_mutex);
1250
1251         ist30xx_init_touch_driver(ts_data);
1252
1253         if (mode == MASK_UPDATE_ISP || mode == MASK_UPDATE_FW)
1254                 release_firmware(request_fw);
1255
1256         return size;
1257 }
1258
1259 /* sysfs: /sys/class/touch/firmware/firmware */
1260 ssize_t ist30xx_fw_store(struct device *dev, struct device_attribute *attr,
1261                          const char *buf, size_t size)
1262 {
1263         bool isp_mode = false;
1264         int fw_size = 0;
1265         u8 *fw = NULL;
1266         char *tmp;
1267         const struct firmware *request_fw = NULL;
1268
1269         unsigned long mode = simple_strtoul(buf, &tmp, 10);
1270
1271         if (mode == MASK_UPDATE_ISP || mode == MASK_UPDATE_FW) {
1272                 int ret = request_firmware(&request_fw, IST30XXB_FW_NAME, &ts_data->client->dev);
1273                 if (ret) {
1274                         tsp_warn("File not found, %s\n", IST30XXB_FW_NAME);
1275                         return size;
1276                 }
1277                 fw = (u8 *)request_fw->data;
1278                 fw_size = (u32)request_fw->size;
1279                 isp_mode = (mode == MASK_UPDATE_ISP ? true : false);
1280         } else {
1281 #if IST30XX_INTERNAL_BIN
1282                 fw = ts_data->fw.buf;
1283                 fw_size = ts_data->fw.buf_size;
1284 #else
1285                 return size;
1286 #endif          // IST30XX_INTERNAL_BIN
1287         }
1288
1289         ist30xx_get_update_info(ts_data, fw, fw_size);
1290         ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw);
1291         ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw);
1292         ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw);
1293
1294         mutex_lock(&ist30xx_mutex);
1295         ist30xx_fw_update(ts_data->client, fw, fw_size, isp_mode);
1296         mutex_unlock(&ist30xx_mutex);
1297
1298         ist30xx_calibrate(1);
1299
1300         ist30xx_init_touch_driver(ts_data);
1301
1302         if (mode == MASK_UPDATE_ISP || mode == MASK_UPDATE_FW)
1303                 release_firmware(request_fw);
1304
1305         return size;
1306 }
1307
1308 ssize_t ist30xx_fw_status(struct device *dev, struct device_attribute *attr,
1309                           char *buf)
1310 {
1311         int count;
1312
1313         switch (ts_data->status.update) {
1314         case 1:
1315                 count = sprintf(buf, "Downloading\n");
1316                 break;
1317         case 2:
1318                 count = sprintf(buf, "Update success, ver %x(%x) -> %x(%x, %x), status : %d, gap : %d\n",
1319                                 ts_data->fw.prev_param_ver, ts_data->fw.prev_core_ver,
1320                                 ts_data->fw.param_ver, ts_data->fw.core_ver, ts_data->fw.sub_ver,
1321                                 CALIB_TO_STATUS(ts_data->status.calib_msg),
1322                                 CALIB_TO_GAP(ts_data->status.calib_msg));
1323                 break;
1324         default:
1325                 count = sprintf(buf, "Pass\n");
1326         }
1327
1328         return count;
1329 }
1330
1331
1332 /* sysfs: /sys/class/touch/firmware/fwparam */
1333 ssize_t ist30xx_fwparam_store(struct device *dev, struct device_attribute *attr,
1334                               const char *buf, size_t size)
1335 {
1336         int fw_size = 0;
1337         u8 *fw = NULL;
1338         char *tmp;
1339         const struct firmware *request_fw = NULL;
1340
1341         unsigned long mode = simple_strtoul(buf, &tmp, 10);
1342
1343         if (mode == MASK_UPDATE_FW) {
1344                 int ret = request_firmware(&request_fw, IST30XXB_FW_NAME, &ts_data->client->dev);
1345                 if (unlikely(ret)) {
1346                         tsp_warn("File not found, %s\n", IST30XXB_FW_NAME);
1347                         return size;
1348                 }
1349                 fw = (u8 *)request_fw->data;
1350                 fw_size = (u32)request_fw->size;
1351         } else {
1352 #if IST30XX_INTERNAL_BIN
1353                 fw = ts_data->fw.buf;
1354                 fw_size = ts_data->fw.buf_size;
1355 #else
1356                 return size;
1357 #endif          // IST30XX_INTERNAL_BIN
1358         }
1359
1360         ist30xx_get_update_info(ts_data, fw, fw_size);
1361         ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw);
1362         ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw);
1363         ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw);
1364
1365         mutex_lock(&ist30xx_mutex);
1366         ist30xx_fw_param_update(ts_data->client, fw);
1367         mutex_unlock(&ist30xx_mutex);
1368
1369         ist30xx_calibrate(1);
1370
1371         ist30xx_init_touch_driver(ts_data);
1372
1373         if (mode == MASK_UPDATE_FW)
1374                 release_firmware(request_fw);
1375
1376         return size;
1377 }
1378
1379
1380 /* sysfs: /sys/class/touch/firmware/viersion */
1381 ssize_t ist30xx_fw_version(struct device *dev, struct device_attribute *attr,
1382                            char *buf)
1383 {
1384         int count;
1385
1386         count = sprintf(buf, "ID: %x, f/w core: %x, param: %x, sub: %x\n",
1387                         ts_data->chip_id, ts_data->fw.core_ver,
1388                         ts_data->fw.param_ver, ts_data->fw.sub_ver);
1389
1390 #if IST30XX_INTERNAL_BIN
1391         {
1392                 char msg[128];
1393
1394                 ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size);
1395
1396                 count += snprintf(msg, sizeof(msg),
1397                                   " Header - f/w ver: %x, param: %x, sub: %x\r\n",
1398                                   ist30xx_parse_ver(FLAG_FW, ts_data->fw.buf),
1399                                   ist30xx_parse_ver(FLAG_PARAM, ts_data->fw.buf),
1400                                   ist30xx_parse_ver(FLAG_SUB, ts_data->fw.buf));
1401                 strncat(buf, msg, sizeof(msg));
1402         }
1403 #endif
1404
1405         return count;
1406 }
1407
1408
1409 /* sysfs  */
1410 static DEVICE_ATTR(fw_only, S_IWUSR | S_IWGRP | S_IRUGO, ist30xx_fw_status, ist30xx_fw_only_store);
1411 static DEVICE_ATTR(firmware, S_IWUSR | S_IWGRP | S_IRUGO, ist30xx_fw_status, ist30xx_fw_store);
1412 static DEVICE_ATTR(fwparam, S_IWUSR | S_IWGRP, NULL, ist30xx_fwparam_store);
1413 static DEVICE_ATTR(boot, S_IWUSR | S_IWGRP | S_IRUGO, ist30xx_fw_show, ist30xx_boot_store);
1414 static DEVICE_ATTR(version, S_IRUGO, ist30xx_fw_version, NULL);
1415
1416 struct class *ist30xx_class;
1417 struct device *ist30xx_fw_dev;
1418
1419 static struct attribute *fw_attributes[] = {
1420         &dev_attr_fw_only.attr,
1421         &dev_attr_firmware.attr,
1422         &dev_attr_fwparam.attr,
1423         &dev_attr_boot.attr,
1424         &dev_attr_version.attr,
1425         NULL,
1426 };
1427
1428 static struct attribute_group fw_attr_group = {
1429         .attrs  = fw_attributes,
1430 };
1431
1432 int ist30xx_init_update_sysfs(void)
1433 {
1434         /* /sys/class/touch */
1435         ist30xx_class = class_create(THIS_MODULE, "touch");
1436
1437         /* /sys/class/touch/firmware */
1438         ist30xx_fw_dev = device_create(ist30xx_class, NULL, 0, NULL, "firmware");
1439
1440         /* /sys/class/touch/firmware/... */
1441         if (unlikely(sysfs_create_group(&ist30xx_fw_dev->kobj,
1442                                         &fw_attr_group)))
1443                 tsp_err("Failed to create sysfs group(%s)!\n", "firmware");
1444
1445         ts_data->status.update = 0;
1446         ts_data->status.calib = 0;
1447
1448         return 0;
1449 }