tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / input / touchscreen / ist30xx / ist30xx_sec.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
17 #include <linux/mutex.h>
18 #include <linux/i2c.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
21 #include <linux/input.h>
22 #include <linux/stat.h>
23 #include <linux/err.h>
24
25
26 #include "ist30xx.h"
27 #include "ist30xx_update.h"
28 #include "ist30xx_misc.h"
29
30
31
32 static char IsfwUpdate[20] = { 0 };
33
34 #define FW_DOWNLOADING "Downloading"
35 #define FW_DOWNLOAD_COMPLETE "Complete"
36 #define FW_DOWNLOAD_FAIL "FAIL"
37
38 #define FACTORY_BUF_SIZE    (1024)
39 #define BUILT_IN            (0)
40 #define UMS                 (1)
41
42 #define CMD_STATE_WAITING   (0)
43 #define CMD_STATE_RUNNING   (1)
44 #define CMD_STATE_OK        (2)
45 #define CMD_STATE_FAIL      (3)
46 #define CMD_STATE_NA        (4)
47
48 #define TSP_NODE_DEBUG      (1)
49
50 static u16 node_value[TSP_TOTAL_NUM];
51
52 extern struct ist30xx_data *ts_data;
53 extern TSP_INFO ist30xx_tsp_info;
54 extern TKEY_INFO ist30xx_tkey_info;
55
56
57 #define TSP_CMD(name, func) .cmd_name = name, .cmd_func = func
58 struct tsp_cmd {
59         struct list_head        list;
60         const char *            cmd_name;
61         void                    (*cmd_func)(void *dev_data);
62 };
63
64 u32 ist30xxb_get_fw_ver(struct ist30xx_data *data)
65 {
66         u32 addr = data->tags.cfg_addr + 4;
67         u32 len = 1;
68         u32 ver = 0;
69         int ret = -EPERM;
70
71         ist30xx_disable_irq(data);
72         ret = ist30xx_cmd_reg(data->client, CMD_ENTER_REG_ACCESS);
73         if (unlikely(ret)) goto get_fw_ver_fail;
74
75         ret = ist30xx_write_cmd(data->client, IST30XX_RX_CNT_ADDR, len);
76         if (unlikely(ret)) goto get_fw_ver_fail;
77
78         ret = ist30xx_read_cmd(data->client, addr, &ver);
79         if (unlikely(ret)) goto get_fw_ver_fail;
80
81         tsp_debug("Reg addr: %x, ver: %x\n", addr, ver);
82
83         ret = ist30xx_cmd_reg(data->client, CMD_EXIT_REG_ACCESS);
84         if (likely(ret == 0))
85                 goto get_fw_ver_end;
86
87 get_fw_ver_fail:
88         ist30xx_cmd_run_device(data->client, true);
89
90 get_fw_ver_end:
91         ist30xx_cmd_start_scan(data->client);
92         ist30xx_enable_irq(data);
93
94         return ver;
95 }
96
97 int ist30xxb_get_key_sensitivity(struct ist30xx_data *data, int id)
98 {
99         u32 addr = IST30XXB_MEM_COUNT + 4 * sizeof(u32);
100         u32 val = 0;
101         static u32 key_sensitivity = 0;
102         int ret = -EPERM;
103
104         if (unlikely(id >= ist30xx_tkey_info.key_num))
105                 return 0;
106
107         if (ist30xx_intr_wait(30) < 0) return 0;
108
109         ret = ist30xx_read_cmd(data->client, addr, &val);
110         if ((val & 0xFFF) == 0xFFF)
111                  return (key_sensitivity >> (16 * id)) & 0xFFFF;
112
113         key_sensitivity = val;
114
115         tsp_debug("Reg addr: %x, val: %8x\n", addr, val);
116
117         val >>= (16 * id);
118
119         return (int)(val & 0xFFFF);
120 }
121
122
123 /* Factory CMD function */
124 static void set_default_result(struct sec_factory *sec)
125 {
126         char delim = ':';
127
128         memset(sec->cmd_result, 0, ARRAY_SIZE(sec->cmd_result));
129         memcpy(sec->cmd_result, sec->cmd, strlen(sec->cmd));
130         strncat(sec->cmd_result, &delim, CMD_STATE_RUNNING);
131 }
132
133 static void set_cmd_result(struct sec_factory *sec, char *buf, int len)
134 {
135         strncat(sec->cmd_result, buf, len);
136 }
137
138 static void not_support_cmd(void *dev_data)
139 {
140         char buf[16] = { 0 };
141
142         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
143         struct sec_factory *sec = (struct sec_factory *)&data->sec;
144
145         set_default_result(sec);
146         snprintf(buf, sizeof(buf), "%s", "NA");
147         tsp_info("%s(), %s\n", __func__, buf);
148
149         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
150         sec->cmd_state = CMD_STATE_NA;
151         dev_info(&data->client->dev, "%s: \"%s(%d)\"\n", __func__,
152                  buf, strnlen(buf, sizeof(buf)));
153         return;
154 }
155
156 static void get_chip_vendor(void *dev_data)
157 {
158         char buf[16] = { 0 };
159
160         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
161         struct sec_factory *sec = (struct sec_factory *)&data->sec;
162
163         set_default_result(sec);
164         snprintf(buf, sizeof(buf), "%s", TSP_CHIP_VENDOR);
165         tsp_info("%s(), %s\n", __func__, buf);
166
167         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
168         sec->cmd_state = CMD_STATE_OK;
169         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
170                  buf, strnlen(buf, sizeof(buf)));
171 }
172
173 static void get_chip_name(void *dev_data)
174 {
175         char buf[16] = { 0 };
176
177         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
178         struct sec_factory *sec = (struct sec_factory *)&data->sec;
179
180         set_default_result(sec);
181         snprintf(buf, sizeof(buf), "%s", TSP_CHIP_NAME);
182         tsp_info("%s(), %s\n", __func__, buf);
183
184         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
185         sec->cmd_state = CMD_STATE_OK;
186         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
187                  buf, strnlen(buf, sizeof(buf)));
188 }
189
190 static void get_chip_id(void *dev_data)
191 {
192         char buf[16] = { 0 };
193
194         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
195         struct sec_factory *sec = (struct sec_factory *)&data->sec;
196
197         set_default_result(sec);
198         snprintf(buf, sizeof(buf), "%#02x", data->chip_id);
199         tsp_info("%s(), %s\n", __func__, buf);
200
201         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
202         sec->cmd_state = CMD_STATE_OK;
203         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
204                  buf, strnlen(buf, sizeof(buf)));
205 }
206 #include <linux/uaccess.h>
207 #define MAX_FW_PATH 255
208 static void fw_update(void *dev_data)
209 {
210         int ret;
211         char buf[16] = { 0 };
212         mm_segment_t old_fs = {0};
213         struct file *fp = NULL;
214         long fsize = 0, nread = 0;
215         u8 *fw;
216         char fw_path[MAX_FW_PATH+1];
217
218         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
219         struct sec_factory *sec = (struct sec_factory *)&data->sec;
220
221         set_default_result(sec);
222
223         tsp_info("%s(), %d\n", __func__, sec->cmd_param[0]);
224
225         switch (sec->cmd_param[0]) {
226         case BUILT_IN:
227                 sec->cmd_state = CMD_STATE_OK;
228                 ret = ist30xx_fw_recovery(data);
229                 if (ret < 0) {
230                         sec->cmd_state = CMD_STATE_FAIL;
231                 }
232                 break;
233         case UMS:
234                 sec->cmd_state = CMD_STATE_OK;
235                 old_fs = get_fs();
236                 set_fs(get_ds());
237
238                 snprintf(fw_path, MAX_FW_PATH, "/sdcard/%s", IST30XXB_FW_NAME);
239                 fp = filp_open(fw_path, O_RDONLY, 0);
240                 if (IS_ERR(fp)) {
241                         tsp_warn("[TSP] %s(), file %s open error:%d\n", __func__, fw_path, (s32)fp);
242                         sec->cmd_state= CMD_STATE_FAIL;
243                         set_fs(old_fs);
244                         break;
245                 }
246
247                 fsize = fp->f_path.dentry->d_inode->i_size;
248                 if(fsize != data->fw.buf_size) {
249                         tsp_warn("[TSP] %s(), invalid fw size!!\n", __func__);
250                         sec->cmd_state = CMD_STATE_FAIL;
251                         set_fs(old_fs);
252                         break;
253                 }
254                 fw = kzalloc((size_t)fsize, GFP_KERNEL);
255                 if (!fw) {
256                         tsp_warn("[TSP] failed to alloc buffer for fw\n");
257                         sec->cmd_state  = CMD_STATE_FAIL;
258                         filp_close(fp, NULL);
259                         set_fs(old_fs);
260                         break;
261                 }
262                 nread = vfs_read(fp, (char __user *)fw, fsize, &fp->f_pos);
263                 if (nread != fsize) {
264                         tsp_warn("[TSP] failed to read fw\n");
265                         sec->cmd_state = CMD_STATE_FAIL;
266                         filp_close(fp, NULL);
267                         set_fs(old_fs);
268                         break;
269                 }
270
271                 filp_close(fp, current->files);
272                 set_fs(old_fs);
273                 tsp_info("[TSP] %s(), ums fw is loaded!!\n", __func__);
274
275                 mutex_lock(&ist30xx_mutex);
276                 ist30xx_fw_update(data->client, fw, fsize, true);
277                 mutex_unlock(&ist30xx_mutex);
278
279                 ist30xx_calibrate(1);
280                 ist30xx_init_touch_driver(data);
281                 break;
282
283         default:
284                 tsp_warn("%s(), Invalid fw file type!\n", __func__);
285                 break;
286         }
287
288         if (sec->cmd_state == CMD_STATE_OK)
289                 snprintf(buf, sizeof(buf), "%s", "OK");
290         else
291                 snprintf(buf, sizeof(buf), "%s", "NG");
292
293         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
294 }
295
296
297 static void get_fw_ver_bin(void *dev_data)
298 {
299         u32 ver = 0;
300         char buf[16] = { 0 };
301
302         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
303         struct sec_factory *sec = (struct sec_factory *)&data->sec;
304
305         set_default_result(sec);
306
307         ver = ist30xx_parse_ver(FLAG_PARAM, data->fw.buf);
308         snprintf(buf, sizeof(buf), "IM00%04x", ver);
309         tsp_info("%s(), %s\n", __func__, buf);
310
311         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
312         sec->cmd_state = CMD_STATE_OK;
313         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
314                  buf, strnlen(buf, sizeof(buf)));
315 }
316
317 static void get_fw_ver_ic(void *dev_data)
318 {
319         u32 ver = 0;
320         char buf[16] = { 0 };
321
322         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
323         struct sec_factory *sec = (struct sec_factory *)&data->sec;
324
325         set_default_result(sec);
326
327         if (data->status.power == 1)
328                 ver = ist30xxb_get_fw_ver(ts_data);
329
330         snprintf(buf, sizeof(buf), "IM00%04x", ver & 0xFFFF);
331         tsp_info("%s(), %s\n", __func__, buf);
332
333         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
334         sec->cmd_state = CMD_STATE_OK;
335         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
336                  buf, strnlen(buf, sizeof(buf)));
337 }
338
339 static void get_threshold(void *dev_data)
340 {
341         char buf[16] = { 0 };
342         int threshold;
343         u32 *cfg_buf;
344
345         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
346         struct sec_factory *sec = (struct sec_factory *)&data->sec;
347
348         set_default_result(sec);
349
350         ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size);
351         cfg_buf = (u32 *)&data->fw.buf[data->tags.cfg_addr];
352
353         threshold = (int)(cfg_buf[0x108 / IST30XX_DATA_LEN] >> 16);
354
355         snprintf(buf, sizeof(buf), "%d", threshold);
356         tsp_info("%s(), %s\n", __func__, buf);
357
358         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
359         sec->cmd_state = CMD_STATE_OK;
360         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
361                  buf, strnlen(buf, sizeof(buf)));
362 }
363
364 static void get_x_num(void *dev_data)
365 {
366         int val = ist30xx_tsp_info.width;
367         char buf[16] = { 0 };
368
369         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
370         struct sec_factory *sec = (struct sec_factory *)&data->sec;
371
372         set_default_result(sec);
373
374         if (val >= 0) {
375                 snprintf(buf, sizeof(buf), "%u", val);
376                 sec->cmd_state = CMD_STATE_OK;
377                 dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
378                          strnlen(buf, sizeof(buf)));
379         } else {
380                 snprintf(buf, sizeof(buf), "%s", "NG");
381                 sec->cmd_state = CMD_STATE_FAIL;
382                 dev_info(&data->client->dev,
383                          "%s: fail to read num of x (%d).\n", __func__, val);
384         }
385         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
386         tsp_info("%s(), %s\n", __func__, buf);
387 }
388
389 static void get_y_num(void *dev_data)
390 {
391         int val = ist30xx_tsp_info.height;
392         char buf[16] = { 0 };
393
394         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
395         struct sec_factory *sec = (struct sec_factory *)&data->sec;
396
397         set_default_result(sec);
398
399         if (val >= 0) {
400                 snprintf(buf, sizeof(buf), "%u", val);
401                 sec->cmd_state = CMD_STATE_OK;
402                 dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
403                          strnlen(buf, sizeof(buf)));
404         } else {
405                 snprintf(buf, sizeof(buf), "%s", "NG");
406                 sec->cmd_state = CMD_STATE_FAIL;
407                 dev_info(&data->client->dev,
408                          "%s: fail to read num of x (%d).\n", __func__, val);
409         }
410         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
411         tsp_info("%s(), %s\n", __func__, buf);
412 }
413
414 int check_tsp_channel(void *dev_data)
415 {
416         int node = -EPERM;
417
418         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
419         struct sec_factory *sec = (struct sec_factory *)&data->sec;
420         TSP_INFO *tsp = &ist30xx_tsp_info;
421
422         if ((sec->cmd_param[0] < 0) || (sec->cmd_param[0] >= tsp->width) ||
423             (sec->cmd_param[1] < 0) || (sec->cmd_param[1] >= tsp->height)) {
424                 dev_info(&data->client->dev, "%s: parameter error: %u,%u\n",
425                          __func__, sec->cmd_param[0], sec->cmd_param[1]);
426         } else {
427                 node = sec->cmd_param[0] + sec->cmd_param[1] * tsp->width;
428                 dev_info(&data->client->dev, "%s: node = %d\n", __func__, node);
429         }
430
431         return node;
432 }
433
434
435 extern int parse_tsp_node(u8 flag, struct TSP_NODE_BUF *node, s16 *buf16);
436 void run_reference_read(void *dev_data)
437 {
438         int i, ret;
439         int min_val, max_val;
440         char buf[16] = { 0 };
441         u8 flag = NODE_FLAG_RAW;
442
443         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
444         struct sec_factory *sec = (struct sec_factory *)&data->sec;
445         TSP_INFO *tsp = &ist30xx_tsp_info;
446
447         set_default_result(sec);
448
449         ret = ist30xx_read_touch_node(flag, &tsp->node);
450         if (ret) {
451                 sec->cmd_state = CMD_STATE_FAIL;
452                 tsp_warn("%s(), tsp node read fail!\n", __func__);
453                 return;
454         }
455         ist30xx_parse_touch_node(flag, &tsp->node);
456
457         ret = parse_tsp_node(flag, &tsp->node, node_value);
458         if (ret) {
459                 sec->cmd_state = CMD_STATE_FAIL;
460                 tsp_warn("%s(), tsp node parse fail - flag: %d\n", __func__, flag);
461                 return;
462         }
463
464         min_val = max_val = node_value[0];
465         for (i = 0; i < tsp->width * tsp->height; i++) {
466 #if TSP_NODE_DEBUG
467                 if ((i % tsp->width) == 0)
468                         printk("\n%s %4d: ", IST30XX_DEBUG_TAG, i);
469
470                 printk("%4d ", node_value[i]);
471 #endif
472
473                 max_val = max(max_val, (int)node_value[i]);
474                 min_val = min(min_val, (int)node_value[i]);
475         }
476
477         snprintf(buf, sizeof(buf), "%d,%d", min_val, max_val);
478         tsp_info("%s(), %s\n", __func__, buf);
479
480         sec->cmd_state = CMD_STATE_OK;
481         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
482         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
483                  strnlen(buf, sizeof(buf)));
484 }
485
486 void get_reference(void *dev_data)
487 {
488         int idx = 0;
489         char buf[16] = { 0 };
490
491         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
492         struct sec_factory *sec = (struct sec_factory *)&data->sec;
493
494         set_default_result(sec);
495
496         idx = check_tsp_channel(data);
497         if (idx < 0) { // Parameter parsing fail
498                 snprintf(buf, sizeof(buf), "%s", "NG");
499                 sec->cmd_state = CMD_STATE_FAIL;
500         } else {
501                 snprintf(buf, sizeof(buf), "%d", node_value[idx]);
502                 sec->cmd_state = CMD_STATE_OK;
503         }
504
505         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
506         tsp_info("%s(), [%d][%d]: %s\n", __func__,
507                  sec->cmd_param[0], sec->cmd_param[1], buf);
508         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
509                  strnlen(buf, sizeof(buf)));
510 }
511
512
513
514 /* sysfs: /sys/class/sec/tsp/close_tsp_test */
515 static ssize_t show_close_tsp_test(struct device *dev,
516                                    struct device_attribute *attr, char *buf)
517 {
518         return snprintf(buf, FACTORY_BUF_SIZE, "%u\n", 0);
519 }
520
521 /* sysfs: /sys/class/sec/tsp/cmd */
522 static ssize_t store_cmd(struct device *dev, struct device_attribute
523                          *devattr, const char *buf, size_t count)
524 {
525         struct ist30xx_data *data = dev_get_drvdata(dev);
526         struct sec_factory *sec = (struct sec_factory *)&data->sec;
527         struct i2c_client *client = data->client;
528
529         char *cur, *start, *end;
530         char msg[SEC_CMD_STR_LEN] = { 0 };
531         int len, i;
532         struct tsp_cmd *tsp_cmd_ptr = NULL;
533         char delim = ',';
534         bool cmd_found = false;
535         int param_cnt = 0;
536         int ret;
537
538         if (sec->cmd_is_running == true) {
539                 dev_err(&client->dev, "tsp_cmd: other cmd is running.\n");
540                 tsp_err("tsp_cmd: other cmd is running.\n");
541                 goto err_out;
542         }
543
544         /* check lock  */
545         mutex_lock(&sec->cmd_lock);
546         sec->cmd_is_running = true;
547         mutex_unlock(&sec->cmd_lock);
548
549         sec->cmd_state = CMD_STATE_RUNNING;
550
551         for (i = 0; i < ARRAY_SIZE(sec->cmd_param); i++)
552                 sec->cmd_param[i] = 0;
553
554         len = (int)count;
555         if (*(buf + len - 1) == '\n')
556                 len--;
557         memset(sec->cmd, 0, ARRAY_SIZE(sec->cmd));
558         memcpy(sec->cmd, buf, len);
559
560         cur = strchr(buf, (int)delim);
561         if (cur)
562                 memcpy(msg, buf, cur - buf);
563         else
564                 memcpy(msg, buf, len);
565         /* find command */
566         list_for_each_entry(tsp_cmd_ptr, &sec->cmd_list_head, list) {
567                 if (!strcmp(msg, tsp_cmd_ptr->cmd_name)) {
568                         cmd_found = true;
569                         break;
570                 }
571         }
572
573         /* set not_support_cmd */
574         if (!cmd_found) {
575                 list_for_each_entry(tsp_cmd_ptr, &sec->cmd_list_head, list) {
576                         if (!strcmp("not_support_cmd", tsp_cmd_ptr->cmd_name))
577                                 break;
578                 }
579         }
580
581         /* parsing parameters */
582         if (cur && cmd_found) {
583                 cur++;
584                 start = cur;
585                 memset(msg, 0, ARRAY_SIZE(msg));
586                 do {
587                         if (*cur == delim || cur - buf == len) {
588                                 end = cur;
589                                 memcpy(msg, start, end - start);
590                                 *(msg + strlen(msg)) = '\0';
591                                 ret = kstrtoint(msg, 10, \
592                                                 sec->cmd_param + param_cnt);
593                                 start = cur + 1;
594                                 memset(msg, 0, ARRAY_SIZE(msg));
595                                 param_cnt++;
596                         }
597                         cur++;
598                 } while (cur - buf <= len);
599         }
600         dev_info(&client->dev, "cmd = %s\n", tsp_cmd_ptr->cmd_name);
601         tsp_info("SEC CMD = %s\n", tsp_cmd_ptr->cmd_name);
602
603         for (i = 0; i < param_cnt; i++)
604                 dev_info(&client->dev, "cmd param %d= %d\n", i, sec->cmd_param[i]);
605
606         tsp_cmd_ptr->cmd_func(data);
607
608 err_out:
609         return count;
610 }
611
612 /* sysfs: /sys/class/sec/tsp/cmd_status */
613 static ssize_t show_cmd_status(struct device *dev,
614                                struct device_attribute *devattr, char *buf)
615 {
616         struct ist30xx_data *data = dev_get_drvdata(dev);
617         struct sec_factory *sec = (struct sec_factory *)&data->sec;
618         char msg[16] = { 0 };
619
620         dev_info(&data->client->dev, "tsp cmd: status:%d\n", sec->cmd_state);
621
622         if (sec->cmd_state == CMD_STATE_WAITING)
623                 snprintf(msg, sizeof(msg), "WAITING");
624
625         else if (sec->cmd_state == CMD_STATE_RUNNING)
626                 snprintf(msg, sizeof(msg), "RUNNING");
627
628         else if (sec->cmd_state == CMD_STATE_OK)
629                 snprintf(msg, sizeof(msg), "OK");
630
631         else if (sec->cmd_state == CMD_STATE_FAIL)
632                 snprintf(msg, sizeof(msg), "FAIL");
633
634         else if (sec->cmd_state == CMD_STATE_NA)
635                 snprintf(msg, sizeof(msg), "NOT_APPLICABLE");
636
637         return snprintf(buf, FACTORY_BUF_SIZE, "%s\n", msg);
638 }
639
640 /* sysfs: /sys/class/sec/tsp/result */
641 static ssize_t show_cmd_result(struct device *dev, struct device_attribute
642                                *devattr, char *buf)
643 {
644         struct ist30xx_data *data = dev_get_drvdata(dev);
645         struct sec_factory *sec = (struct sec_factory *)&data->sec;
646
647         dev_info(&data->client->dev, "tsp cmd: result: %s\n", sec->cmd_result);
648
649         mutex_lock(&sec->cmd_lock);
650         sec->cmd_is_running = false;
651         mutex_unlock(&sec->cmd_lock);
652
653         sec->cmd_state = CMD_STATE_WAITING;
654
655         return snprintf(buf, FACTORY_BUF_SIZE, "%s\n", sec->cmd_result);
656 }
657
658
659
660 /* sysfs: /sys/class/sec/tsp/sec_touchscreen/tsp_firm_version_phone */
661 static ssize_t phone_firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
662 {
663         u32 ver = ist30xx_parse_ver(FLAG_PARAM, ts_data->fw.buf);
664
665         tsp_info("%s(), IM00%04x\n", __func__, ver);
666
667         return sprintf(buf, "IM00%04x", ver);
668 }
669
670 /* sysfs: /sys/class/sec/tsp/sec_touchscreen/tsp_firm_version_panel */
671 static ssize_t part_firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
672 {
673         u32 ver = 0;
674         
675         if (ts_data->status.power == 1)
676                 ver = ist30xxb_get_fw_ver(ts_data);
677
678         tsp_info("%s(), IM00%04x\n", __func__, ver);
679         
680         return sprintf(buf, "IM00%04x", ver);
681 }
682
683 /* sysfs: /sys/class/sec/tsp/sec_touchscreen/tsp_threshold */
684 static ssize_t threshold_firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
685 {
686         int threshold;
687         u32 *cfg_buf;
688         
689         ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size);
690         cfg_buf = (u32 *)&ts_data->fw.buf[ts_data->tags.cfg_addr];
691
692         threshold = (int)(cfg_buf[0x108 / IST30XX_DATA_LEN] >> 16);
693
694         tsp_info("%s(), %d\n", __func__, threshold);
695
696         return sprintf(buf, "%d", threshold);
697 }
698
699 /* sysfs: /sys/class/sec/tsp/sec_touchscreen/tsp_firm_update */
700 static ssize_t firmware_update(struct device *dev, struct device_attribute *attr, char *buf)
701 {
702         bool ret;
703
704         sprintf(IsfwUpdate, "%s\n", FW_DOWNLOADING);
705         tsp_info("%s(), %s\n", __func__, IsfwUpdate);
706
707         ret = ist30xx_fw_recovery(ts_data);
708         ret = (ret == 0 ? 1 : -1);
709
710         sprintf(IsfwUpdate, "%s\n",
711                 (ret > 0 ? FW_DOWNLOAD_COMPLETE : FW_DOWNLOAD_FAIL));
712         tsp_info("%s(), %s\n", __func__, IsfwUpdate);
713
714         return sprintf(buf, "%d", ret);
715 }
716
717 /* sysfs: /sys/class/sec/tsp/sec_touchscreen/tsp_firm_update_status */
718 static ssize_t firmware_update_status(struct device *dev, struct device_attribute *attr, char *buf)
719 {
720         tsp_info("%s(), %s\n", __func__, IsfwUpdate);
721
722         return sprintf(buf, "%s\n", IsfwUpdate);
723 }
724
725
726 /* sysfs: /sys/class/sec/tsp/sec_touchkey/touchkey_recent */
727 static ssize_t recent_sensitivity_show(struct device *dev, struct device_attribute *attr, char *buf)
728 {
729         int sensitivity = ist30xxb_get_key_sensitivity(ts_data, 0);
730
731         tsp_info("%s(), %d\n", __func__, sensitivity);
732
733         return sprintf(buf, "%d\n", sensitivity);
734 }
735
736 /* sysfs: /sys/class/sec/tsp/sec_touchkey/touchkey_back */
737 static ssize_t back_sensitivity_show(struct device *dev, struct device_attribute *attr, char *buf)
738 {
739         int sensitivity = ist30xxb_get_key_sensitivity(ts_data, 1);
740
741         tsp_info("%s(), %d\n", __func__, sensitivity);
742
743         return sprintf(buf, "%d\n", sensitivity);
744 }
745
746 /* sysfs: /sys/class/sec/tsp/sec_touchkey/touchkey_threshold */
747 static ssize_t touchkey_threshold_show(struct device *dev, struct device_attribute *attr, char *buf)
748 {
749         int threshold;
750         u32 *cfg_buf;
751
752         ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size);
753         cfg_buf = (u32 *)&ts_data->fw.buf[ts_data->tags.cfg_addr];
754
755         threshold = (int)(cfg_buf[0x134 / IST30XX_DATA_LEN] >> 16);
756
757         tsp_info("%s(), %d\n", __func__, threshold);
758
759         return snprintf(buf, sizeof(int), "%d\n", threshold);
760 }
761 /* sysfs: /sys/class/sec/tsp/sec_touchkey/touchkey_dummy_btn1 */
762 static ssize_t touchkey_dummy_btn1_show(struct device *dev, struct device_attribute *attr, char *buf)
763 {
764         printk("[TSP]Hidden btn 1 not supported\n");
765         return 0;
766 }
767 /* sysfs: /sys/class/sec/tsp/sec_touchkey/touchkey_dummy_btn3 */
768 static ssize_t touchkey_dummy_btn3_show(struct device *dev, struct device_attribute *attr, char *buf)
769 {
770         printk("[TSP]Hidden btn 3 not supported\n");
771         return 0;
772 }
773 struct tsp_cmd tsp_cmd[] = {
774         { TSP_CMD("get_chip_vendor", get_chip_vendor), },
775         { TSP_CMD("get_chip_name",   get_chip_name),   },
776         { TSP_CMD("get_chip_id",     get_chip_id),     },
777         { TSP_CMD("fw_update",       fw_update),       },
778         { TSP_CMD("get_fw_ver_bin",  get_fw_ver_bin),  },
779         { TSP_CMD("get_fw_ver_ic",   get_fw_ver_ic),   },
780         { TSP_CMD("get_threshold",   get_threshold),   },
781         { TSP_CMD("get_x_num",       get_x_num),       },
782         { TSP_CMD("get_y_num",       get_y_num),       },
783         { TSP_CMD("run_reference_read", run_reference_read),},
784         { TSP_CMD("get_reference",      get_reference),   },
785         { TSP_CMD("not_support_cmd", not_support_cmd), },
786 };
787
788 #define SEC_DEFAULT_ATTR    (S_IRUGO | S_IWUSR | S_IWGRP)
789 /* sysfs - touchscreen */
790 static DEVICE_ATTR(tsp_firm_version_phone, SEC_DEFAULT_ATTR,
791                    phone_firmware_show, NULL);
792 static DEVICE_ATTR(tsp_firm_version_panel, SEC_DEFAULT_ATTR,
793                    part_firmware_show, NULL);
794 static DEVICE_ATTR(tsp_threshold, SEC_DEFAULT_ATTR,
795                    threshold_firmware_show, NULL);
796 static DEVICE_ATTR(tsp_firm_update, SEC_DEFAULT_ATTR,
797                    firmware_update, NULL);
798 static DEVICE_ATTR(tsp_firm_update_status, SEC_DEFAULT_ATTR,
799                    firmware_update_status, NULL);
800
801 /* sysfs - touchkey */
802 static DEVICE_ATTR(touchkey_recent, SEC_DEFAULT_ATTR,
803                    recent_sensitivity_show, NULL);
804 static DEVICE_ATTR(touchkey_back, SEC_DEFAULT_ATTR,
805                    back_sensitivity_show, NULL);
806 static DEVICE_ATTR(touchkey_threshold, SEC_DEFAULT_ATTR,
807                    touchkey_threshold_show, NULL);
808 static DEVICE_ATTR(touchkey_dummy_btn1, SEC_DEFAULT_ATTR,
809                    touchkey_dummy_btn1_show,NULL);
810 static DEVICE_ATTR(touchkey_dummy_btn3, SEC_DEFAULT_ATTR,
811                    touchkey_dummy_btn3_show,NULL);
812                    
813 /* sysfs - tsp */
814 static DEVICE_ATTR(close_tsp_test, S_IRUGO, show_close_tsp_test, NULL);
815 static DEVICE_ATTR(cmd, S_IWUSR | S_IWGRP, NULL, store_cmd);
816 static DEVICE_ATTR(cmd_status, S_IRUGO, show_cmd_status, NULL);
817 static DEVICE_ATTR(cmd_result, S_IRUGO, show_cmd_result, NULL);
818
819 static struct attribute *sec_tsp_attributes[] = {
820         &dev_attr_tsp_firm_version_phone.attr,
821         &dev_attr_tsp_firm_version_panel.attr,
822         &dev_attr_tsp_threshold.attr,
823         &dev_attr_tsp_firm_update.attr,
824         &dev_attr_tsp_firm_update_status.attr,
825         NULL,
826 };
827
828 static struct attribute *sec_tkey_attributes[] = {
829         &dev_attr_touchkey_recent.attr,
830         &dev_attr_touchkey_back.attr,
831         &dev_attr_touchkey_threshold.attr,
832         &dev_attr_touchkey_dummy_btn1.attr,
833         &dev_attr_touchkey_dummy_btn3.attr,
834         NULL,
835 };
836
837 static struct attribute *sec_touch_facotry_attributes[] = {
838         &dev_attr_close_tsp_test.attr,
839         &dev_attr_cmd.attr,
840         &dev_attr_cmd_status.attr,
841         &dev_attr_cmd_result.attr,
842         NULL,
843 };
844
845 static struct attribute_group sec_tsp_attr_group = {
846         .attrs  = sec_tsp_attributes,
847 };
848
849 static struct attribute_group sec_tkey_attr_group = {
850         .attrs  = sec_tkey_attributes,
851 };
852
853 static struct attribute_group sec_touch_factory_attr_group = {
854         .attrs  = sec_touch_facotry_attributes,
855 };
856
857 extern struct class *sec_class;
858 struct device *sec_touchscreen;
859 EXPORT_SYMBOL(sec_touchscreen);
860 struct device *sec_touchkey;
861 EXPORT_SYMBOL(sec_touchkey);
862 struct device *sec_fac_dev;
863
864
865 int sec_touch_sysfs(struct ist30xx_data *data)
866 {
867         /* /sys/class/sec/sec_touchscreen */
868         sec_touchscreen = device_create(sec_class, NULL, 0, NULL, "sec_touchscreen");
869         if (IS_ERR(sec_touchscreen)) {
870                 tsp_err("Failed to create device (%s)!\n", "sec_touchscreen");
871                 return -ENODEV;
872         }
873         /* /sys/class/sec/sec_touchscreen/... */
874         if (sysfs_create_group(&sec_touchscreen->kobj, &sec_tsp_attr_group))
875                 tsp_err("Failed to create sysfs group(%s)!\n", "sec_touchscreen");
876
877         /* /sys/class/sec/sec_touchkey */
878         sec_touchkey = device_create(sec_class, NULL, 0, NULL, "sec_touchkey");
879         if (IS_ERR(sec_touchkey)) {
880                 tsp_err("Failed to create device (%s)!\n", "sec_touchkey");
881                 return -ENODEV;
882         }
883         /* /sys/class/sec/sec_touchkey/... */
884         if (sysfs_create_group(&sec_touchkey->kobj, &sec_tkey_attr_group))
885                 tsp_err("Failed to create sysfs group(%s)!\n", "sec_touchkey");
886
887         /* /sys/class/sec/tsp */
888         sec_fac_dev = device_create(sec_class, NULL, 0, data, "tsp");
889         if (IS_ERR(sec_fac_dev)) {
890                 tsp_err("Failed to create device (%s)!\n", "tsp");
891                 return -ENODEV;
892         }
893         /* /sys/class/sec/tsp/... */
894         if (sysfs_create_group(&sec_fac_dev->kobj, &sec_touch_factory_attr_group))
895                 tsp_err("Failed to create sysfs group(%s)!\n", "tsp");
896
897         return 0;
898 }
899
900 int sec_fac_cmd_init(struct ist30xx_data *data)
901 {
902         int i;
903         struct sec_factory *sec = (struct sec_factory *)&data->sec;
904
905         INIT_LIST_HEAD(&sec->cmd_list_head);
906         for (i = 0; i < ARRAY_SIZE(tsp_cmd); i++)
907                 list_add_tail(&tsp_cmd[i].list, &sec->cmd_list_head);
908
909         mutex_init(&sec->cmd_lock);
910         sec->cmd_is_running = false;
911
912         return 0;
913 }