xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/hyn_cst2xx/hyn_cst2xx.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * drivers/input/touchscreen/hyn_cst2xx.c
3  *
4  * hynitron TouchScreen driver.
5  *
6  * Copyright (c) 2015  hynitron
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * VERSION      	DATE			AUTHOR
18  *  1.0		    2015-10-12		    Tim
19  *
20  * note: only support mulititouch
21  */
22 
23 #include <linux/module.h>
24 #include <linux/delay.h>
25 //#include <linux/earlysuspend.h>
26 #include <linux/device.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/async.h>
34 //#include <mach/iomux.h>
35 #include <linux/irq.h>
36 //#include <mach/board.h>
37 #include <linux/uaccess.h>
38 #include <linux/workqueue.h>
39 #include <linux/proc_fs.h>
40 #include <linux/uaccess.h>
41 #include <linux/input/mt.h>
42 #include <linux/gpio.h>
43 #include <linux/version.h>
44 #include <linux/slab.h>
45 #include <linux/of_gpio.h>
46 #include "../tp_suspend.h"
47 
48 #define HYN_DEBUG
49 #if defined (CONFIG_KP_AXP)
50         extern int axp_gpio_set_value(int gpio, int io_state);
51         extern int axp_gpio_set_io(int , int );
52 #if defined(CONFIG_BOARD_TYPE_ZM726CE_V12)
53         #define PMU_GPIO_NUM    3
54 #endif
55 #endif
56 
57 #if defined(CONFIG_TP_1680E_726_SD)
58     //#define Y_POL
59 	//#define X_POL
60 	#define SWAP_X_Y
61 	#define SCREEN_MAX_X 		1024
62 	#define SCREEN_MAX_Y 		600
63     //#include "CST21680_F_WGJ10276.h"
64 
65 #else
66     #define Y_POL
67 	//#define X_POL
68 	#define SWAP_X_Y
69 	#define SCREEN_MAX_X 		1280
70 	#define SCREEN_MAX_Y 		800
71     #include "CST21680SE_S126_D863_7.h"
72 #endif
73 
74 #define ICS_SLOT_REPORT
75 //#define HAVE_TOUCH_KEY
76 #define SLEEP_CLEAR_POINT
77 
78 #define CST2XX_I2C_NAME 	"cst2xxse"
79 #define CST2XX_I2C_ADDR 	0x5A
80 
81 //#define IRQ_PORT			RK2928_PIN1_PB0//RK30_PIN1_PB7
82 //#define WAKE_PORT			RK30_PIN0_PA1//RK30_PIN0_PB6
83 
84 //#define TPD_PROC_DEBUG
85 #ifdef TPD_PROC_DEBUG
86 #include <linux/proc_fs.h>
87 #include <linux/uaccess.h>
88 //static struct proc_dir_entry *hyn_config_proc = NULL;
89 #define HYN_CONFIG_PROC_FILE "hyn_config"
90 #define CONFIG_LEN 31
91 //static char hyn_read[CONFIG_LEN];
92 static u8 hyn_data_proc[8] = {0};
93 static u8 hyn_proc_flag = 0;
94 //static struct i2c_client *ts->client = NULL;
95 #endif
96 
97 #define TRANSACTION_LENGTH_LIMITED
98 //#define HYN_MONITOR
99 #define PRESS_MAX    		255
100 #define MAX_FINGERS 		5
101 #define MAX_CONTACTS 		10
102 #define DMA_TRANS_LEN		0x20
103 
104 #ifdef HYN_MONITOR
105 static struct workqueue_struct *hyn_monitor_workqueue = NULL;
106 static u8 int_1st[4] = {0};
107 static u8 int_2nd[4] = {0};
108 //static char dac_counter = 0;
109 static char b0_counter = 0;
110 static char bc_counter = 0;
111 static char i2c_lock_flag = 0;
112 #endif
113 
114 //#define HYN_GESTURE	// if define enable this function
115 #ifdef HYN_GESTURE
116 	extern void rk_send_wakeup_key(void);
117 	static int gsl_lcd_flag = -1;
118 	static int gsl_gesture_flag = -1;
119 #endif
120 
121 #ifdef HAVE_TOUCH_KEY
122 static u16 key = 0;
123 static int key_state_flag = 0;
124 struct key_data {
125 	u16 key;
126 	u16 x_min;
127 	u16 x_max;
128 	u16 y_min;
129 	u16 y_max;
130 };
131 
132 static const u16 key_array[] = {
133 			KEY_BACK,
134 			KEY_HOME,
135 			KEY_MENU,
136 			KEY_SEARCH,
137 };
138 #define MAX_KEY_NUM     (sizeof(key_array)/sizeof(key_array[0]))
139 
140 struct key_data hyn_key_data[MAX_KEY_NUM] = {
141 	{KEY_BACK, 2048, 2048, 2048, 2048},
142 	{KEY_HOME, 2048, 2048, 2048, 2048},
143 	{KEY_MENU, 2048, 2048, 2048, 2048},
144 	{KEY_SEARCH, 2048, 2048, 2048, 2048},
145 };
146 #endif
147 
148 struct hyn_ts {
149 	struct i2c_client *client;
150 	struct input_dev *input;
151 	struct work_struct work;
152 	struct workqueue_struct *wq;
153 	struct hyn_ts_data *dd;
154 	u8 *touch_data;
155 	u8 device_id;
156 	int irq;
157 	int rst_pin;
158 	int irq_pin;
159     struct delayed_work hyn_monitor_work;
160 
161 #if defined(CONFIG_HAS_EARLYSUSPEND)
162 	struct early_suspend early_suspend;
163 #endif
164 	struct  tp_device  tp;
165 };
166 int h_wake_pin = 0;
167 
168 #ifdef HYN_DEBUG
169 #define print_info(fmt, args...)   \
170         do{                              \
171                 printk(fmt, ##args);     \
172         }while(0)
173 #else
174 #define print_info(fmt, args...)
175 #endif
176 
177 #define ANDROID_TOOL_SURPORT
178 
179 #ifdef ANDROID_TOOL_SURPORT
180 
181 static int cst2xx_update_firmware(struct i2c_client * client, struct hyn_ts *ts,
182  	unsigned char *pdata, int data_len);
183 
184 static unsigned short g_unnormal_mode = 0;
185 static unsigned short g_cst2xx_tx = 15;
186 static unsigned short g_cst2xx_rx = 10;
187 static struct hyn_ts *hyn_global_ts=NULL;
188 
189 #endif
190 
cst2xx_i2c_read(struct i2c_client * client,unsigned char * buf,int len)191 static int cst2xx_i2c_read(struct i2c_client *client, unsigned char *buf, int len)
192 {
193 	int ret = -1;
194 	int retries = 0;
195 
196     //client->timing  = 370;
197     //client->addr   |= I2C_ENEXT_FLAG;
198 
199 	while(retries < 2) {
200 		ret = i2c_master_recv(client, buf, len);
201 		if(ret<=0)
202 		    retries++;
203         else
204             break;
205 	}
206 
207 	return ret;
208 }
209 
cst2xx_i2c_write(struct i2c_client * client,unsigned char * buf,int len)210 static int cst2xx_i2c_write(struct i2c_client *client, unsigned char *buf, int len)
211 {
212 	int ret = -1;
213 	int retries = 0;
214 
215 	while(retries < 2) {
216 		ret = i2c_master_send(client, buf, len);
217 		if(ret<=0)
218 			retries++;
219 		else
220 			break;
221 	}
222 	return ret;
223 }
224 
cst2xx_i2c_read_register(struct i2c_client * client,unsigned char * buf,int len)225 static int cst2xx_i2c_read_register(struct i2c_client *client, unsigned char *buf, int len)
226 {
227 	int ret = -1;
228 
229 	ret = cst2xx_i2c_write(client, buf, 2);
230 	ret = cst2xx_i2c_read(client, buf, len);
231 	return ret;
232 }
233 
cst2xx_test_i2c(struct i2c_client * client)234 static int cst2xx_test_i2c(struct i2c_client *client)
235 {
236 	u8 retry = 0;
237 	u8 ret;
238 	u8 buf[4];
239 
240 	buf[0] = 0xD0;
241 	buf[1] = 0x00;
242 	while(retry++ < 5) {
243 		ret = cst2xx_i2c_write(client, buf, 2);
244 		if (ret > 0)
245 			return ret;
246 		msleep(2);
247 	}
248 
249 	if(retry==5) printk("hyn iic test error.ret:%d.\n", ret);
250 
251 	return ret;
252 }
253 
254 
hard_reset_chip(struct hyn_ts * ts,u16 ms)255 static void hard_reset_chip(struct hyn_ts *ts, u16 ms)
256 {
257 	int ret=0;
258 	int retry=0;
259 	unsigned char buf[4];
260 
261 	buf[0] = 0xD1;
262 	buf[1] = 0x0e;
263 	while(retry++ < 3) {
264 		ret = cst2xx_i2c_write(ts->client, buf, 2);
265 		if (ret > 0) break;
266 		msleep(2);
267 	}
268 
269 	msleep(ms);
270 }
271 
272 #ifdef TPD_PROC_DEBUG
char_to_int(char ch)273 static int char_to_int(char ch)
274 {
275 	if(ch>='0' && ch<='9')
276 		return (ch-'0');
277 	else
278 		return (ch-'a'+10);
279 }
280 
281 #endif
282 
283 #define  CST2XX_BASE_ADDR		(0x00000000)
284 
cst2xx_enter_download_mode(struct hyn_ts * ts)285 static int cst2xx_enter_download_mode(struct hyn_ts *ts)
286 {
287 	int ret;
288 	int i;
289 	unsigned char buf[3];
290 
291 	hard_reset_chip(ts, 5);
292 
293 	for(i=0; i<30; i++)
294 	{
295 
296 		buf[0] = 0xA0;
297 		buf[1] = 0x01;
298 		buf[2] = 0xAA;
299 		ret = cst2xx_i2c_write(ts->client, buf, 3);
300 		if (ret < 0)
301 		{
302 			msleep(1);
303 			continue;
304 		}
305 
306 		msleep(6); //wait enter download mode
307 
308 		buf[0] = 0xA0;
309 		buf[1] = 0x03; //check whether into program mode
310 		ret = cst2xx_i2c_read_register(ts->client, buf, 1);
311 		if(ret < 0)
312 		{
313 			msleep(1);
314 			continue;
315 		}
316 
317 		if (buf[0] == 0x55)
318 		{
319 			break;
320 
321 		}
322 
323 	}
324 
325 	if(buf[0] != 0x55)
326 	{
327 		printk("hyn reciev 0x55 failed.\n");
328 		return -1;
329 	}
330 	else
331 	{
332 	    buf[0] = 0xA0;
333 		buf[1] = 0x06;
334 		buf[2] = 0x00;
335 		ret = cst2xx_i2c_write(ts->client, buf, 3);
336 
337 	}
338 
339 	return 0;
340 }
341 
cst2xx_download_program(unsigned char * pdata,int len,struct hyn_ts * ts)342 static int cst2xx_download_program(unsigned char *pdata, int len, struct hyn_ts *ts)
343 {
344 	int i, ret, j,retry;
345 	unsigned char *i2c_buf;
346 	unsigned char temp_buf[8];
347 	unsigned short eep_addr, iic_addr;
348 	int total_kbyte;
349 
350 	i2c_buf = kmalloc(sizeof(unsigned char)*(512 + 2), GFP_KERNEL);
351 	if (i2c_buf == NULL)
352 	{
353 		return -1;
354 	}
355 
356 	//make sure fwbin len is N*1K
357 
358 	total_kbyte = len / 512;
359 
360 	for (i=0; i<total_kbyte; i++) {
361 		i2c_buf[0] = 0xA0;
362 		i2c_buf[1] = 0x14;
363 		eep_addr = i << 9;		//i * 512
364 		i2c_buf[2] = eep_addr;
365 		i2c_buf[3] = eep_addr>>8;
366 		ret = cst2xx_i2c_write(ts->client, i2c_buf, 4);
367 		if (ret < 0)
368 			goto error_out;
369 
370 	#if 0
371 		i2c_buf[0] = 0xA0;
372 		i2c_buf[1] = 0x18;
373 		memcpy(i2c_buf + 2, pdata + eep_addr, 512);
374 		ret = cst2xx_i2c_write(ts->client, i2c_buf, 514);
375 		if (ret < 0)
376 			goto error_out;
377 	#else
378 
379 		memcpy(i2c_buf, pdata + eep_addr, 512);
380 		for(j=0; j<128; j++) {
381 			iic_addr = (j<<2);
382 			temp_buf[0] = (iic_addr+0xA018)>>8;
383 			temp_buf[1] = (iic_addr+0xA018)&0xFF;
384 			temp_buf[2] = i2c_buf[iic_addr+0];
385 			temp_buf[3] = i2c_buf[iic_addr+1];
386 			temp_buf[4] = i2c_buf[iic_addr+2];
387 			temp_buf[5] = i2c_buf[iic_addr+3];
388     			ret = cst2xx_i2c_write(ts->client, temp_buf, 6);
389     			if (ret < 0)
390     				goto error_out;
391 			}
392 	#endif
393 
394 		i2c_buf[0] = 0xA0;
395 		i2c_buf[1] = 0x04;
396 		i2c_buf[2] = 0xEE;
397 		ret = cst2xx_i2c_write(ts->client, i2c_buf, 3);
398 		if (ret < 0)
399 			goto error_out;
400 
401 		msleep(600);
402 
403 		for(retry=0;retry<10;retry++)
404 		{
405 			i2c_buf[0] = 0xA0;
406 			i2c_buf[1] = 0x05;
407 			ret = cst2xx_i2c_read_register(ts->client, i2c_buf, 1);
408 
409 			if (ret < 0){
410 
411 				msleep(100);
412 				continue;
413 			}
414 			else
415 			{
416 				if (i2c_buf[0] != 0x55){
417 					msleep(100);
418 					continue;
419 				}else{
420 	 				break;
421 				}
422 
423 			}
424 
425 		}
426 		if(retry==10)
427 		{
428 			goto error_out;
429 		}
430 	}
431 
432 	i2c_buf[0] = 0xA0;
433 	i2c_buf[1] = 0x01;
434 	i2c_buf[2] = 0x00;
435 	ret = cst2xx_i2c_write(ts->client, i2c_buf, 3);
436 	if (ret < 0)
437 	goto error_out;
438 
439 	i2c_buf[0] = 0xA0;
440 	i2c_buf[1] = 0x03;
441 	i2c_buf[2] = 0x00;
442 	ret = cst2xx_i2c_write(ts->client, i2c_buf, 3);
443 
444 	if (i2c_buf != NULL) {
445 		kfree(i2c_buf);
446 		i2c_buf = NULL;
447 	}
448 
449 	return 0;
450 
451 error_out:
452 	if (i2c_buf != NULL) {
453 		kfree(i2c_buf);
454 		i2c_buf = NULL;
455 	}
456 	return -1;
457 }
458 
cst2xx_read_checksum(struct hyn_ts * ts)459 static int cst2xx_read_checksum(struct hyn_ts *ts)
460 {
461 	int ret;
462 	int i;
463 	unsigned int  checksum;
464 	unsigned int  bin_checksum;
465 	unsigned char buf[4];
466 	const unsigned char *pData;
467 
468 	for(i=0; i<10; i++)
469 	{
470 		buf[0] = 0xA0;
471 		buf[1] = 0x00;
472 		ret = cst2xx_i2c_read_register(ts->client, buf, 1);
473 		if(ret < 0)
474 		{
475 			msleep(2);
476 			continue;
477 		}
478 
479 		if(buf[0]!=0)
480 			break;
481 		else
482 		msleep(2);
483 	}
484 	msleep(4);
485 
486 	if(buf[0]==0x01)
487 	{
488 		buf[0] = 0xA0;
489 		buf[1] = 0x08;
490 		ret = cst2xx_i2c_read_register(ts->client, buf, 4);
491 
492 		if(ret < 0)	return -1;
493 
494 		//handle read data  --> checksum
495 		checksum = buf[0] + (buf[1]<<8) + (buf[2]<<16) + (buf[3]<<24);
496 
497         pData=(unsigned char  *)fwbin +7680-4;   //7*1024 +512
498 		bin_checksum = pData[0] + (pData[1]<<8) + (pData[2]<<16) + (pData[3]<<24);
499 
500 	printk("hyn checksum ic:0x%x. bin:0x%x------\n", checksum, bin_checksum);
501 
502 	if(checksum!=bin_checksum)
503 		{
504 			printk("hyn check sum error.\n");
505 			return -1;
506 
507 		}
508 
509 	}
510 	else
511 	{
512 		printk("hyn No checksum. buf[0]:%d.\n", buf[0]);
513 		return -1;
514 	}
515 
516 	return 0;
517 }
518 
cst2xx_update_firmware(struct i2c_client * client,struct hyn_ts * ts,unsigned char * pdata,int data_len)519 static int cst2xx_update_firmware(struct i2c_client * client, struct hyn_ts *ts,
520 	unsigned char *pdata, int data_len)
521 {
522 	int ret;
523 	int retry;
524 	unsigned char buf[4];
525 
526 	retry = 0;
527 
528 start_flow:
529 
530 	printk("hyn enter the update firmware.\n");
531 
532 	disable_irq(ts->irq);
533 
534 	msleep(20);
535 	ret = cst2xx_enter_download_mode(ts);
536 	if (ret < 0)
537 	{
538 		printk("hyn enter download mode failed.\n");
539 		goto fail_retry;
540 	}
541 
542 	ret = cst2xx_download_program(pdata, data_len,ts);
543 	if (ret < 0)
544 	{
545 		printk("hyn download program failed.\n");
546 		goto fail_retry;
547 	}
548 
549 	msleep(10);
550 
551 	ret = cst2xx_read_checksum(ts);
552 	if(ret < 0){
553 		printk("hyn check the updating checksum error.\n");
554 		return ret;
555 	}
556 	else
557 	{
558 		buf[0] = 0xA0;  //exit program
559 		buf[1] = 0x06;
560 		buf[2] = 0xEE;
561 		ret = cst2xx_i2c_write(client, buf, 3);
562 
563 		if(ret < 0)
564 			goto fail_retry;
565 
566 	}
567 
568 	printk("hyn download firmware succesfully.\n");
569 
570 	msleep(100);
571 
572 	hard_reset_chip(ts, 30);
573 
574 	enable_irq(ts->irq);
575 
576 	return 0;
577 
578 fail_retry:
579 	if (retry < 4)
580 	{
581 		retry++;
582 		goto start_flow;
583 	}
584 
585 	return -1;
586 }
587 
cst2xx_boot_update_fw(struct i2c_client * client,struct hyn_ts * ts)588 static int cst2xx_boot_update_fw(struct i2c_client * client, struct hyn_ts *ts)
589 {
590 	return cst2xx_update_firmware(client, ts, fwbin, FW_BIN_SIZE);
591 }
592 
cst2xx_check_code(struct hyn_ts * ts)593 static int cst2xx_check_code(struct hyn_ts *ts)
594 {
595 	int retry = 0;
596 	int ret;
597 	unsigned char buf[4];
598 	unsigned int fw_checksum,fw_version,fw_customer_id;
599 	unsigned int  bin_checksum,bin_version;
600 	const unsigned char *pData;
601 
602 	buf[0] = 0xD0;
603 	buf[1] = 0x4C;
604 	while(retry++ < 3) {
605 		ret = cst2xx_i2c_read_register(ts->client, buf, 1);
606 		if (ret > 0) break;
607 		msleep(2);
608 	}
609 	if((buf[0]==226)||(buf[0]==237)||(buf[0]==240))
610 	{
611 		//checksum
612 		return 0;
613 	}
614 	else if(buf[0]==168)
615 	{
616 	    buf[0] = 0xD0;
617 		buf[1] = 0x49;
618 		while(retry++ < 3) {
619 			ret = cst2xx_i2c_read_register(ts->client, buf, 2);
620 			if (ret > 0) break;
621 			msleep(2);
622 		}
623 		fw_customer_id=(buf[0]<<8)+buf[1];
624 		printk("hyn fw_customer_id:%d. \r\n",fw_customer_id);
625 
626 		//checksum
627 		buf[0] = 0xD2;
628 		buf[1] = 0x0C;
629 		while(retry++ < 5) {
630 			ret = cst2xx_i2c_read_register(ts->client, buf, 4);
631 			if (ret > 0) break;
632 			msleep(2);
633 		}
634 
635 		fw_checksum = buf[3];
636 		fw_checksum <<= 8;
637 		fw_checksum |= buf[2];
638 		fw_checksum <<= 8;
639 		fw_checksum |= buf[1];
640 		fw_checksum <<= 8;
641 		fw_checksum |= buf[0];
642 
643 		pData=(unsigned char  *)fwbin +7680-4;   //7*1024 +512
644 		bin_checksum = pData[0] + (pData[1]<<8) + (pData[2]<<16) + (pData[3]<<24);
645 
646  		if(fw_checksum!=bin_checksum)
647 		{
648 			 printk("hyn checksum is different******bin_checksum:0x%x, fw_checksum:0x%x. \r\n",bin_checksum,fw_checksum);
649 
650 			//chip version
651 			buf[0] = 0xD2;
652 			buf[1] = 0x08;
653 			while(retry++ < 5) {
654 				ret = cst2xx_i2c_read_register(ts->client, buf, 4);
655 				if (ret > 0) break;
656 				msleep(2);
657 			}
658 
659 			fw_version = buf[3];
660 			fw_version <<= 8;
661 			fw_version |= buf[2];
662 			fw_version <<= 8;
663 			fw_version |= buf[1];
664 			fw_version <<= 8;
665 			fw_version |= buf[0];
666 
667 			pData=(unsigned char  *)fwbin +7680-8;   //7*1024 +512
668 			bin_version = pData[0] + (pData[1]<<8) + (pData[2]<<16) + (pData[3]<<24);
669 
670 			printk("hyn bin_version is different******bin_version:0x%x, fw_version:0x%x. \r\n",bin_version,fw_version);
671 
672 			if(bin_version>=fw_version)
673 			{
674 				ret = cst2xx_boot_update_fw(ts->client, ts);
675 				if(ret<0)
676 				{
677 					printk("hyn update firmware fail  . \r\n");
678                     hard_reset_chip(ts, 20);
679 					return -2;
680 				}
681 				else   return  0;
682 			}
683 			else
684 			{
685 		    	printk("hyn bin_version is lower ,no need to update firmware.\n");
686 			return 0;
687 			}
688 
689 		}
690 		else
691 		{
692 			printk("hyn checksum :0x%x is same,no need to update firmware.\n",fw_checksum);
693 			return 0;
694 		}
695 
696 	}
697 	else
698 	{
699 		printk("hyn check code error. buf[0]:%d.\n", buf[0]);
700 		ret = cst2xx_boot_update_fw(ts->client, ts);
701 		if(ret<0) return -2;
702 		else      return  0;
703 	}
704 }
705 
706 #ifdef HAVE_TOUCH_KEY
report_key(struct hyn_ts * ts,u16 x,u16 y)707 static void report_key(struct hyn_ts *ts, u16 x, u16 y)
708 {
709 	u16 i = 0;
710 
711 	for(i = 0; i < MAX_KEY_NUM; i++) {
712 		if((hyn_key_data[i].x_min < x) && (x < hyn_key_data[i].x_max)&&(hyn_key_data[i].y_min < y) && (y < hyn_key_data[i].y_max)){
713 			key = hyn_key_data[i].key;
714 			input_report_key(ts->input, key, 1);
715 			input_sync(ts->input);
716 			key_state_flag = 1;
717 			break;
718 		}
719 	}
720 }
721 #endif
722 
cst2xx_touch_down(struct input_dev * input_dev,s32 id,s32 x,s32 y,s32 w)723 static void cst2xx_touch_down(struct input_dev *input_dev, s32 id,s32 x,s32 y,s32 w)
724 {
725 	s32 temp_w = (w>>1);
726 
727 #ifdef ICS_SLOT_REPORT
728 	input_mt_slot(input_dev, id);
729 	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
730 	input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
731 	input_report_abs(input_dev, ABS_MT_POSITION_X, x);
732 	input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
733 	input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, temp_w);
734 	input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, temp_w);
735 	input_report_abs(input_dev, ABS_MT_PRESSURE, temp_w);
736 #else
737     input_report_key(input_dev, BTN_TOUCH, 1);
738     input_report_abs(input_dev, ABS_MT_POSITION_X, x);
739     input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
740     input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, temp_w);
741     input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, temp_w);
742     input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
743     input_mt_sync(input_dev);
744 #endif
745 
746 }
747 
cst2xx_touch_up(struct input_dev * input_dev,int id)748 static void cst2xx_touch_up(struct input_dev *input_dev, int id)
749 {
750 
751 #ifdef ICS_SLOT_REPORT
752 	input_mt_slot(input_dev, id);
753 	//input_report_abs(input_dev, ABS_MT_TRACKING_ID, -1);
754 	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
755 #else
756 	input_report_key(input_dev, BTN_TOUCH, 0);
757 	input_mt_sync(input_dev);
758 #endif
759 
760 }
761 
762 #ifdef ANDROID_TOOL_SURPORT   //debug tool support
763 
764 #define CST2XX_PROC_DIR_NAME	"cst1xx_ts"
765 #define CST2XX_PROC_FILE_NAME	"cst1xx-update"
766 
767 static struct proc_dir_entry *g_proc_dir, *g_update_file;
768 static int CMDIndex = 0;
769 
770 #if 1
cst2xx_open_fw_file(char * path)771 static struct file *cst2xx_open_fw_file(char *path)
772 {
773 	struct file * filp = NULL;
774 	int ret;
775 
776 	//*old_fs_p = get_fs();
777 	//set_fs(KERNEL_DS);
778 	filp = filp_open(path, O_RDONLY, 0);
779 	if (IS_ERR(filp))
780 	{
781 		ret = PTR_ERR(filp);
782 		return NULL;
783 	}
784 	filp->f_op->llseek(filp, 0, 0);
785     return filp;
786 }
787 
cst2xx_close_fw_file(struct file * filp)788 static void cst2xx_close_fw_file(struct file * filp)
789 {
790 //	set_fs(old_fs);
791 	if(filp)
792 	    filp_close(filp,NULL);
793 }
794 
cst2xx_read_fw_file(unsigned char * filename,unsigned char * pdata,int * plen)795 static int cst2xx_read_fw_file(unsigned char *filename, unsigned char *pdata, int *plen)
796 {
797 	struct file *fp;
798 //	mm_segment_t old_fs;
799 	int size;
800 	int length;
801 	int ret = -1;
802 
803 	if((pdata == NULL) || (strlen(filename) == 0))
804 	{
805 		printk("file name is null.\n");
806 		return ret;
807 	}
808 	fp = cst2xx_open_fw_file(filename);
809 	if(fp == NULL)
810 	{
811         printk("Open bin file faild.path:%s.\n", filename);
812 		goto clean;
813 	}
814 
815 	length = fp->f_op->llseek(fp, 0, SEEK_END);
816 	fp->f_op->llseek(fp, 0, 0);
817 	size = fp->f_op->read(fp, pdata, length, &fp->f_pos);
818 	if(size == length)
819 	{
820 		ret = 0;
821 		*plen = length;
822 	} else {
823 		printk("read bin file length fail****size:%d*******length:%d .\n", size,length);
824 
825 	}
826 
827 clean:
828 	cst2xx_close_fw_file(fp);
829 	return ret;
830 }
831 #else
cst2xx_open_fw_file(char * path,mm_segment_t * old_fs_p)832 static struct file *cst2xx_open_fw_file(char *path, mm_segment_t * old_fs_p)
833 {
834 	struct file * filp;
835 	int ret;
836 
837 	*old_fs_p = get_fs();
838 	set_fs(KERNEL_DS);
839 	filp = filp_open(path, O_RDONLY, 0);
840 	if (IS_ERR(filp))
841 	{
842 		ret = PTR_ERR(filp);
843 		return NULL;
844 	}
845 	filp->f_op->llseek(filp, 0, 0);
846 
847 	return filp;
848 }
849 
cst2xx_close_fw_file(struct file * filp,mm_segment_t old_fs)850 static void cst2xx_close_fw_file(struct file * filp,mm_segment_t old_fs)
851 {
852 	set_fs(old_fs);
853 	if(filp)
854 	    filp_close(filp,NULL);
855 }
856 
cst2xx_read_fw_file(unsigned char * filename,unsigned char * pdata,int * plen)857 static int cst2xx_read_fw_file(unsigned char *filename, unsigned char *pdata, int *plen)
858 {
859 	struct file *fp;
860 	mm_segment_t old_fs;
861 	int size;
862 	int length;
863 	int ret = -1;
864 
865 	if((pdata == NULL) || (strlen(filename) == 0))
866 		return ret;
867 	fp = cst2xx_open_fw_file(filename, &old_fs);
868 	if(fp == NULL)
869 	{
870         printk("Open bin file faild.path:%s.\n", filename);
871 		goto clean;
872 	}
873 
874 	length = fp->f_op->llseek(fp, 0, SEEK_END);
875 	fp->f_op->llseek(fp, 0, 0);
876 	size = fp->f_op->read(fp, pdata, length, &fp->f_pos);
877 	if(size == length)
878 	{
879 		ret = 0;
880 		*plen = length;
881 	} else {
882 		printk("read bin file length fail****size:%d*******length:%d .\n", size,length);
883 
884 	}
885 
886 clean:
887 	cst2xx_close_fw_file(fp, old_fs);
888 	return ret;
889 }
890 
891 #endif
cst2xx_apk_fw_dowmload(struct i2c_client * client,unsigned char * pdata,int length)892 static int cst2xx_apk_fw_dowmload(struct i2c_client *client,
893 		unsigned char *pdata, int length)
894 {
895 	int ret;
896 
897 	ret = cst2xx_update_firmware(client, hyn_global_ts, pdata, FW_BIN_SIZE);
898 	if (ret < 0)
899 	{
900 		printk("online update fw failed.\n");
901 		return -1;
902 	}
903 
904 	return 0;
905 }
906 
cst2xx_proc_read_foobar(struct file * page,char __user * user_buf,size_t count,loff_t * data)907 static ssize_t cst2xx_proc_read_foobar(struct file *page,char __user *user_buf, size_t count, loff_t *data)
908 {
909 	unsigned char buf[512];
910 	int len = 0;
911 	int ret;
912 
913 	printk("cst2xx_proc_read_foobar********CMDIndex:%d. \n",CMDIndex);
914 
915 	disable_irq(hyn_global_ts->irq);
916 
917 	if (CMDIndex == 0) {
918 		sprintf(buf,"Hynitron touchscreen driver 1.0.\n");
919 		//strcpy(page,buf);
920 		len = strlen(buf);
921 		ret = copy_to_user(user_buf,buf,len);
922 
923 	}
924 	else if (CMDIndex == 1)
925 	{
926 		buf[0] = g_cst2xx_rx;
927 		buf[1] = g_cst2xx_tx;
928 		ret = copy_to_user(user_buf,buf,2);
929 		len = 2;
930 	}
931 	if(CMDIndex == 2 || CMDIndex == 3)
932 	{
933 		unsigned short rx,tx;
934 		int data_len;
935 
936 		rx = g_cst2xx_rx;
937 		tx = g_cst2xx_tx;
938 		data_len = rx*tx*2 + 4 + (tx+rx)*2 + rx + rx; //374
939 
940 		if(CMDIndex == 2)  //read diff
941 		{
942 			buf[0] = 0xD1;
943 			buf[1] = 0x0D;
944 		}
945 		else          //rawdata
946 		{
947 			buf[0] = 0xD1;
948 			buf[1] = 0x0A;
949 		}
950 
951 		ret = cst2xx_i2c_write(hyn_global_ts->client, buf, 2);
952 		if(ret < 0)
953 		{
954 			printk("Write command raw/diff mode failed.error:%d.\n", ret);
955 			goto END;
956 		}
957 
958 		g_unnormal_mode = 1;
959 		msleep(14);
960 
961  		while(!gpio_get_value(hyn_global_ts->irq_pin ));
962 
963 		buf[0] = 0x80;
964 		buf[1] = 0x01;
965 		ret = cst2xx_i2c_write(hyn_global_ts->client, buf, 2);
966 		if(ret < 0)
967 		{
968 			printk("Write command(0x8001) failed.error:%d.\n", ret);
969 			goto END;
970 		}
971 		ret = cst2xx_i2c_read(hyn_global_ts->client, &buf[2], data_len);
972 		if(ret < 0)
973 		{
974 			printk("Read raw/diff data failed.error:%d.\n", ret);
975 			goto END;
976 		}
977 
978 		msleep(2);
979 
980 		buf[0] = 0xD1;
981 		buf[1] = 0x08;
982 		ret = cst2xx_i2c_write(hyn_global_ts->client, buf, 2);
983 		if(ret < 0)
984 		{
985 			printk("Write command normal mode failed.error:%d.\n", ret);
986 			goto END;
987 		}
988 
989 		buf[0] = rx;
990 		buf[1] = tx;
991     	ret = copy_to_user(user_buf,buf,data_len + 2);
992     	len = data_len + 2;
993 
994 		msleep(2);
995 	}
996 
997 END:
998 	g_unnormal_mode = 0;
999 
1000 	CMDIndex = 0;
1001 	enable_irq(hyn_global_ts->irq);
1002 
1003 	return len;
1004 }
1005 
cst2xx_proc_write_foobar(struct file * file,const char __user * buffer,size_t count,loff_t * data)1006 static ssize_t cst2xx_proc_write_foobar(struct file *file, const char __user *buffer,size_t count, loff_t *data)
1007 {
1008 	unsigned char cmd[128];
1009 	unsigned char *pdata = NULL;
1010 	int len;
1011 	int ret;
1012 	int length = 6*1024;
1013 
1014 	if (count > 128)
1015 		len = 128;
1016 	else
1017 		len = count;
1018 
1019 	if (copy_from_user(cmd, buffer, len))
1020 	{
1021 		printk("copy data from user space failed.\n");
1022 		return -EFAULT;
1023 	}
1024 
1025 	printk("cst2xx_proc_write_foobar*********cmd:%d*****%d******len:%d .\r\n", cmd[0], cmd[1], len);
1026 
1027 	if (cmd[0] == 0)
1028 	{
1029 		 pdata = kzalloc(sizeof(char)*length, GFP_KERNEL);
1030 		if(pdata == NULL)
1031 		{
1032 			printk("zalloc GFP_KERNEL memory fail.\n");
1033 			return -ENOMEM;
1034 		}
1035 		ret = cst2xx_read_fw_file(&cmd[1], pdata, &length);
1036 		if(ret < 0)
1037 	  	{
1038 			printk("cst2xx_read_fw_file fail.\n");
1039 			if(pdata != NULL)
1040 			{
1041 				kfree(pdata);
1042 				pdata = NULL;
1043 			}
1044 			return -EPERM;
1045 	  	}
1046 
1047 		ret = cst2xx_apk_fw_dowmload(hyn_global_ts->client, pdata, length);
1048 	  	if(ret < 0)
1049 	  	{
1050 	        printk("update firmware failed.\n");
1051 			if(pdata != NULL)
1052 			{
1053 				kfree(pdata);
1054 				pdata = NULL;
1055 			}
1056 	        return -EPERM;
1057 		}
1058 
1059 	}
1060 	else if (cmd[0] == 2)
1061 	{
1062 		//cst2xx_touch_release();
1063 		CMDIndex = cmd[1];
1064 	}
1065 	else if (cmd[0] == 3)
1066 	{
1067 		CMDIndex = 0;
1068 	}
1069 
1070 	return count;
1071 }
1072 
1073 
1074 static const struct file_operations proc_tool_debug_fops = {
1075 
1076 	.owner		= THIS_MODULE,
1077 	.read	    = cst2xx_proc_read_foobar,
1078 	.write		= cst2xx_proc_write_foobar,
1079 
1080 };
cst2xx_proc_fs_init(void)1081 static int  cst2xx_proc_fs_init(void)
1082 {
1083 	int ret;
1084 
1085 	g_proc_dir = proc_mkdir(CST2XX_PROC_DIR_NAME, NULL);
1086 	if (g_proc_dir == NULL)
1087 	{
1088 		ret = -ENOMEM;
1089 		goto out;
1090 	}
1091 
1092 	g_update_file = proc_create(CST2XX_PROC_FILE_NAME, 0777, g_proc_dir,&proc_tool_debug_fops);
1093 
1094 	if (g_update_file == NULL)
1095 	{
1096 		ret = -ENOMEM;
1097 		printk("proc_create CST2XX_PROC_FILE_NAME failed.\n");
1098 		goto no_foo;
1099 	}
1100 /**************************************
1101 	g_update_file = create_proc_entry(CST2XX_PROC_FILE_NAME, 0666, g_proc_dir);
1102 	if (g_update_file == NULL)
1103 	{
1104 		ret = -ENOMEM;
1105 		goto no_foo;
1106 	}
1107 
1108 	g_update_file->read_proc = cst2xx_proc_read_foobar;
1109 	g_update_file->write_proc = cst2xx_proc_write_foobar;
1110 
1111 ************************************************/
1112 	return 0;
1113 
1114 no_foo:
1115 	remove_proc_entry(CST2XX_PROC_FILE_NAME, g_proc_dir);
1116 out:
1117 	return ret;
1118 }
1119 #endif
1120 
1121 
1122 static int report_flag = 0;
cst2xx_ts_worker(struct work_struct * work)1123 static void cst2xx_ts_worker(struct work_struct *work)
1124 {
1125 	//int rc, i;
1126 	//u8 id, touches;
1127 	//u16 x, y;
1128 	u8 buf[60];//30
1129 	u8 i2c_buf[8];
1130 	u8 key_status;
1131 	u8 key_id, finger_id, sw;
1132 	int  input_x = 0;
1133 	int  input_y = 0;
1134 	int  input_w = 0;
1135 	int  temp;
1136 	u8   i, cnt_up, cnt_down;
1137 	int  ret, idx;
1138 	int  cnt, i2c_len, len_1, len_2;
1139 
1140 
1141 #ifdef HYN_NOID_VERSION
1142 	u32 tmp1;
1143 	u8 buf[4] = {0};
1144 	struct hyn_touch_info cinfo;
1145 #endif
1146 
1147 	struct hyn_ts *ts = container_of(work, struct hyn_ts,work);
1148 
1149 	//print_info("=====cst2xx_ts_worker=====\n");
1150 
1151 #ifdef TPD_PROC_DEBUG
1152 	if(hyn_proc_flag == 1)
1153 		goto schedule;
1154 #endif
1155 
1156 	//buf[0] = 0xD1;
1157 	//buf[1] = 0x08;
1158 	//ret = cst2xx_i2c_write(g_i2c_client, buf, 2);
1159 	//if (ret < 0)
1160 	//{
1161 	//	printk("send get finger point cmd failed.\r\n");
1162 	//	goto END;
1163 	//}
1164 
1165 	buf[0] = 0xD0;
1166 	buf[1] = 0x00;
1167 	ret = cst2xx_i2c_read_register(ts->client, buf, 7);
1168 	if(ret < 0) {
1169 		printk("hyn iic read touch point data failed.\n");
1170 		goto OUT_PROCESS;
1171 	}
1172 
1173 	key_status = buf[0];
1174 
1175 	if(buf[6] != 0xAB) {
1176 		//printk("data is not valid..\r\n");
1177 		goto OUT_PROCESS;
1178 	}
1179 
1180 	cnt = buf[5] & 0x7F;
1181 	if(cnt>MAX_FINGERS) goto OUT_PROCESS;
1182 	else if(cnt==0)     goto CLR_POINT;
1183 
1184 	if(buf[5] == 0x80) {
1185 		key_status = buf[0];
1186 		key_id = buf[1];
1187 		goto KEY_PROCESS;
1188 	}
1189 	else if(cnt == 0x01) {
1190 		goto FINGER_PROCESS;
1191 	}
1192 	else {
1193 		#ifdef TRANSACTION_LENGTH_LIMITED
1194 		if((buf[5]&0x80) == 0x80) { //key
1195 			i2c_len = (cnt - 1)*5 + 3;
1196 			len_1   = i2c_len;
1197 			for(idx=0; idx<i2c_len; idx+=6) {
1198 			    i2c_buf[0] = 0xD0;
1199 				i2c_buf[1] = 0x07+idx;
1200 
1201 				if(len_1>=6) {
1202 					len_2  = 6;
1203 					len_1 -= 6;
1204 				}
1205 				else {
1206 					len_2 = len_1;
1207 					len_1 = 0;
1208 				}
1209 
1210     			ret = cst2xx_i2c_read_register(ts->client, i2c_buf, len_2);
1211     			if(ret < 0) goto OUT_PROCESS;
1212 
1213 				for(i=0; i<len_2; i++) {
1214 					buf[5+idx+i] = i2c_buf[i];
1215 				}
1216 			}
1217 
1218 			i2c_len   += 5;
1219 			key_status = buf[i2c_len - 3];
1220 			key_id     = buf[i2c_len - 2];
1221 		}
1222 		else {
1223 			i2c_len = (cnt - 1)*5 + 1;
1224 			len_1   = i2c_len;
1225 
1226 			for(idx=0; idx<i2c_len; idx+=6) {
1227 				i2c_buf[0] = 0xD0;
1228 				i2c_buf[1] = 0x07+idx;
1229 
1230 				if(len_1>=6) {
1231 					len_2  = 6;
1232 					len_1 -= 6;
1233 				}
1234 				else {
1235 					len_2 = len_1;
1236 					len_1 = 0;
1237 				}
1238 
1239 				ret = cst2xx_i2c_read_register(ts->client, i2c_buf, len_2);
1240 				if (ret < 0) goto OUT_PROCESS;
1241 
1242 				for(i=0; i<len_2; i++) {
1243 					buf[5+idx+i] = i2c_buf[i];
1244 				}
1245 			}
1246 			i2c_len += 5;
1247 		}
1248 		#else
1249 		if ((buf[5]&0x80) == 0x80) {
1250 			buf[5] = 0xD0;
1251 			buf[6] = 0x07;
1252 			i2c_len = (cnt - 1)*5 + 3;
1253 			ret = cst2xx_i2c_read_register(ts->client, &buf[5], i2c_len);
1254 			if (ret < 0)
1255 				goto OUT_PROCESS;
1256 			i2c_len += 5;
1257 			key_status = buf[i2c_len - 3];
1258 			key_id = buf[i2c_len - 2];
1259 		}
1260 		else {
1261 			buf[5] = 0xD0;
1262 			buf[6] = 0x07;
1263 			i2c_len = (cnt - 1)*5 + 1;
1264 			ret = cst2xx_i2c_read_register(ts->client, &buf[5], i2c_len);
1265 			if (ret < 0)
1266 				goto OUT_PROCESS;
1267 			i2c_len += 5;
1268 		}
1269 		#endif
1270 
1271 		if (buf[i2c_len - 1] != 0xAB) {
1272 			goto OUT_PROCESS;
1273 		}
1274 	}
1275 
1276 	if((cnt > 0) && (key_status & 0x80))  //both key and point
1277 	{
1278         	if(report_flag==0xA5) goto KEY_PROCESS;
1279 	}
1280 
1281 FINGER_PROCESS:
1282 
1283 	i2c_buf[0] = 0xD0;
1284 	i2c_buf[1] = 0x00;
1285 	i2c_buf[2] = 0xAB;
1286 	ret = cst2xx_i2c_write(ts->client, i2c_buf, 3);
1287 	if (ret < 0) {
1288 		printk("hyn send read touch info ending failed.\r\n");
1289 		hard_reset_chip(ts, 20);
1290 	}
1291 
1292 	idx = 0;
1293 	cnt_up = 0;
1294 	cnt_down = 0;
1295 	for (i = 0; i < cnt; i++) {
1296 		input_x = (unsigned int)((buf[idx + 1] << 4) | ((buf[idx + 3] >> 4) & 0x0F));
1297 		input_y = (unsigned int)((buf[idx + 2] << 4) | (buf[idx + 3] & 0x0F));
1298 		input_w = (unsigned int)(buf[idx + 4]);
1299 		sw = (buf[idx] & 0x0F) >> 1;
1300 		finger_id = (buf[idx] >> 4) & 0x0F;
1301 
1302 	#ifdef SWAP_X_Y
1303 		temp    = input_x;
1304 		input_x = input_y;
1305 		input_y = temp;
1306 	#endif
1307 
1308 	#ifdef X_POL
1309 		input_x = SCREEN_MAX_X - input_x;
1310 	#endif
1311 
1312 	#ifdef Y_POL
1313 		input_y = SCREEN_MAX_Y - input_y;
1314 	#endif
1315 
1316 	//printk("Point x:%d, y:%d, id:%d, sw:%d.\r\n", input_x, input_y, finger_id, sw);
1317 
1318 		if (sw == 0x03) {
1319 			cst2xx_touch_down(ts->input, finger_id, input_x, input_y, input_w);
1320 			cnt_down++;
1321 
1322 #ifdef HYN_GESTURE
1323 			print_info("\n gsl_lcd_flag = %d ---- gsl_gesture_flag = %d .\n\n", gsl_lcd_flag, gsl_gesture_flag);
1324 			if(1 == gsl_lcd_flag && 1 == gsl_gesture_flag){
1325 				print_info("auto wake up lcd\n");
1326 				rk_send_wakeup_key();
1327 			}else{
1328 				gsl_gesture_flag = 0;
1329 			}
1330 #endif
1331 
1332 		}
1333 		else {
1334 		cnt_up++;
1335 		#ifdef ICS_SLOT_REPORT
1336 			cst2xx_touch_up(ts->input, finger_id);
1337 		#endif
1338 	}
1339 		idx += 5;
1340 	}
1341 
1342 	#ifndef ICS_SLOT_REPORT
1343 	if((cnt_up>0) && (cnt_down==0))
1344 		cst2xx_touch_up(ts->input, 0);
1345 	#endif
1346 
1347 	if(cnt_down==0)  report_flag = 0;
1348 	else report_flag = 0xCA;
1349 
1350 	input_sync(ts->input);
1351 
1352 	goto END;
1353 
1354 KEY_PROCESS:
1355 	i2c_buf[0] = 0xD0;
1356 	i2c_buf[1] = 0x00;
1357 	i2c_buf[2] = 0xAB;
1358 	ret = cst2xx_i2c_write(ts->client, i2c_buf, 3);
1359 	if (ret < 0) {
1360 		printk("hyn send read touch info ending failed.\r\n");
1361 	}
1362 
1363     #ifdef HAVE_TOUCH_KEY
1364 	if(key_status&0x80) {
1365 		if((key_status&0x7F)==0x03) {
1366 			i = (key_id>>4)-1;
1367 			key = hyn_key_data[i].key;
1368 			input_report_key(ts->input, key, 1);
1369 
1370 			report_flag = 0xA5;
1371 		}
1372 		else {
1373 			input_report_key(ts->input, key, 0);
1374 			report_flag = 0;
1375 		}
1376 	}
1377 	#endif
1378 
1379 	input_sync(ts->input);
1380 
1381 	goto END;
1382 
1383 CLR_POINT:
1384 #ifdef SLEEP_CLEAR_POINT
1385 	#ifdef ICS_SLOT_REPORT
1386 		for(i=0; i<=MAX_CONTACTS; i++) {
1387 			input_mt_slot(ts->input, i);
1388 			input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
1389 			input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false);
1390 		}
1391 	#else
1392 		input_mt_sync(ts->input);
1393 	#endif
1394 		input_sync(ts->input);
1395 #endif
1396 
1397 OUT_PROCESS:
1398 	i2c_buf[0] = 0xD0;
1399 	i2c_buf[1] = 0x00;
1400 	i2c_buf[2] = 0xAB;
1401 	ret = cst2xx_i2c_write(ts->client, i2c_buf, 3);
1402 	if (ret < 0) {
1403 		printk("send read touch info ending failed.\n");
1404 		hard_reset_chip(ts, 20);
1405 	}
1406 
1407 END:
1408 #ifdef HYN_MONITOR
1409 	if(i2c_lock_flag != 0)
1410 		goto i2c_lock_schedule;
1411 	else
1412 		i2c_lock_flag = 1;
1413 #endif
1414 
1415 #ifdef TPD_PROC_DEBUG
1416 schedule:
1417 #endif
1418 
1419 #ifdef HYN_MONITOR
1420 	i2c_lock_flag = 0;
1421 i2c_lock_schedule:
1422 #endif
1423 	//enable_irq(ts->irq);
1424 	cnt=0;
1425 	//printk("========cst2xx_ts_worker end=========\n");
1426 }
1427 
1428 #ifdef HYN_MONITOR
hyn_monitor_worker(struct work_struct * work)1429 static void hyn_monitor_worker(struct work_struct *work)
1430 {
1431 	//u8 write_buf[4] = {0};
1432 	u8 read_buf[4]  = {0};
1433 	char init_chip_flag = 0;
1434 
1435 //	print_info("----------------hyn_monitor_worker-----------------\n");
1436    struct hyn_ts *ts = container_of(work, struct hyn_ts,hyn_monitor_work.work);
1437 	if(i2c_lock_flag != 0) {
1438 	    //i2c_lock_flag=1;
1439 	    goto queue_monitor_work;
1440 	}
1441 	else
1442 		i2c_lock_flag = 1;
1443 
1444 	//hyn_ts_read(ts->client, 0x80, read_buf, 4);
1445 	//printk("======read 0x80: %x %x %x %x ======tony0geshu\n",read_buf[3], read_buf[2], read_buf[1], read_buf[0]);
1446 
1447 	hyn_ts_read(ts->client, 0xb0, read_buf, 4);
1448 	if(read_buf[3] != 0x5a || read_buf[2] != 0x5a || read_buf[1] != 0x5a || read_buf[0] != 0x5a)
1449 		b0_counter ++;
1450 	else
1451 		b0_counter = 0;
1452 
1453 	if(b0_counter > 1) {
1454 		printk("======read 0xb0: %x %x %x %x ======\n",read_buf[3], read_buf[2], read_buf[1], read_buf[0]);
1455 		init_chip_flag = 1;
1456 		b0_counter = 0;
1457 		goto queue_monitor_init_chip;
1458 	}
1459 
1460 	hyn_ts_read(ts->client, 0xb4, read_buf, 4);
1461 	int_2nd[3] = int_1st[3];
1462 	int_2nd[2] = int_1st[2];
1463 	int_2nd[1] = int_1st[1];
1464 	int_2nd[0] = int_1st[0];
1465 	int_1st[3] = read_buf[3];
1466 	int_1st[2] = read_buf[2];
1467 	int_1st[1] = read_buf[1];
1468 	int_1st[0] = read_buf[0];
1469 
1470 	//printk("======int_1st: %x %x %x %x , int_2nd: %x %x %x %x ======\n",int_1st[3], int_1st[2], int_1st[1], int_1st[0], int_2nd[3], int_2nd[2],int_2nd[1],int_2nd[0]);
1471 
1472 	if(int_1st[3] == int_2nd[3] && int_1st[2] == int_2nd[2] &&int_1st[1] == int_2nd[1] && int_1st[0] == int_2nd[0])  {
1473 		printk("======int_1st: %x %x %x %x , int_2nd: %x %x %x %x ======\n",int_1st[3], int_1st[2], int_1st[1], int_1st[0], int_2nd[3], int_2nd[2],int_2nd[1],int_2nd[0]);
1474 		init_chip_flag = 1;
1475 		goto queue_monitor_init_chip;
1476 	}
1477 
1478 
1479 	hyn_ts_read(ts->client, 0xbc, read_buf, 4);
1480 	if(read_buf[3] != 0 || read_buf[2] != 0 || read_buf[1] != 0 || read_buf[0] != 0)
1481 		bc_counter++;
1482 	else
1483 		bc_counter = 0;
1484 	if(bc_counter > 1) {
1485 		printk("======read 0xbc: %x %x %x %x======\n",read_buf[3], read_buf[2], read_buf[1], read_buf[0]);
1486 		init_chip_flag = 1;
1487 		bc_counter = 0;
1488 	}
1489 
1490 
1491 /*
1492 	write_buf[3] = 0x01;
1493 	write_buf[2] = 0xfe;
1494 	write_buf[1] = 0x10;
1495 	write_buf[0] = 0x00;
1496 	hyn_ts_write(ts->client, 0xf0, write_buf, 4);
1497 	hyn_ts_read(ts->client, 0x10, read_buf, 4);
1498 	hyn_ts_read(ts->client, 0x10, read_buf, 4);
1499 
1500 	if(read_buf[3] < 10 && read_buf[2] < 10 && read_buf[1] < 10 && read_buf[0] < 10)
1501 		dac_counter ++;
1502 	else
1503 		dac_counter = 0;
1504 
1505 	if(dac_counter > 1)
1506 	{
1507 		printk("======read DAC1_0: %x %x %x %x ======\n",read_buf[3], read_buf[2], read_buf[1], read_buf[0]);
1508 		init_chip_flag = 1;
1509 		dac_counter = 0;
1510 	}
1511 */
1512 queue_monitor_init_chip:
1513 	if(init_chip_flag)
1514 		init_chip(ts->client,ts);
1515 
1516 	i2c_lock_flag = 0;
1517 
1518 queue_monitor_work:
1519 	queue_delayed_work(hyn_monitor_workqueue, &ts->hyn_monitor_work, 100);
1520 }
1521 #endif
1522 
hyn_ts_irq(int irq,void * dev_id)1523 static irqreturn_t hyn_ts_irq(int irq, void *dev_id)
1524 {
1525 	///struct hyn_ts *ts = dev_id;
1526     struct hyn_ts *ts = (struct hyn_ts*)dev_id;
1527 	//printk("========cst2xx Interrupt=========\n");
1528 
1529 #ifdef HYN_GESTURE
1530 	if(1 == gsl_lcd_flag)
1531 		gsl_gesture_flag = 1;
1532 #endif
1533 
1534 	//disable_irq_nosync(ts->irq);
1535 
1536 	if (!work_pending(&ts->work))
1537 	{
1538 		queue_work(ts->wq, &ts->work);
1539 	}
1540 
1541 	return IRQ_HANDLED;
1542 }
1543 
cst2xx_ts_init(struct i2c_client * client,struct hyn_ts * ts)1544 static int cst2xx_ts_init(struct i2c_client *client, struct hyn_ts *ts)
1545 {
1546 	struct input_dev *input_device;
1547 	int rc = 0;
1548 
1549 	printk("hyn cst2xx Enter %s\n", __func__);
1550 
1551 	//input_device = devm_input_allocate_device(&ts->client->dev);
1552 	input_device = input_allocate_device();
1553 	if (!input_device) {
1554 		rc = -ENOMEM;
1555 		goto error_alloc_dev;
1556 	}
1557 
1558 	ts->input = input_device;
1559 	input_device->name = CST2XX_I2C_NAME;
1560 	input_device->id.bustype = BUS_I2C;
1561 	input_device->dev.parent = &client->dev;
1562 	input_set_drvdata(input_device, ts);
1563 
1564 #ifdef ICS_SLOT_REPORT
1565 	__set_bit(EV_ABS, input_device->evbit);
1566 	__set_bit(EV_KEY, input_device->evbit);
1567 	__set_bit(EV_REP, input_device->evbit);
1568 	__set_bit(INPUT_PROP_DIRECT, input_device->propbit);
1569 	input_mt_init_slots(input_device, (MAX_CONTACTS+1), 0);
1570 #else
1571 	input_set_abs_params(input_device,ABS_MT_TRACKING_ID, 0, (MAX_CONTACTS+1), 0, 0);
1572 	set_bit(EV_ABS, input_device->evbit);
1573 	set_bit(EV_KEY, input_device->evbit);
1574 	__set_bit(INPUT_PROP_DIRECT, input_device->propbit);
1575 	input_device->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
1576 #endif
1577 
1578 #ifdef HAVE_TOUCH_KEY
1579 	input_device->evbit[0] = BIT_MASK(EV_KEY);
1580 	//input_device->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1581 	for (i = 0; i < MAX_KEY_NUM; i++)
1582 		set_bit(key_array[i], input_device->keybit);
1583 #endif
1584 
1585 	set_bit(ABS_MT_POSITION_X, input_device->absbit);
1586 	set_bit(ABS_MT_POSITION_Y, input_device->absbit);
1587 	set_bit(ABS_MT_TOUCH_MAJOR, input_device->absbit);
1588 	set_bit(ABS_MT_WIDTH_MAJOR, input_device->absbit);
1589 
1590 	input_set_abs_params(input_device,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
1591 	input_set_abs_params(input_device,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
1592 	input_set_abs_params(input_device,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
1593 	input_set_abs_params(input_device,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
1594 
1595 	//client->irq = IRQ_PORT;
1596 	//ts->irq = client->irq;
1597 	//create_workqueue
1598 
1599 	ts->wq = create_singlethread_workqueue("kworkqueue_ts");
1600 	if (!ts->wq) {
1601 		dev_err(&client->dev, "hyn Could not create workqueue\n");
1602 		goto error_wq_create;
1603 	}
1604 	flush_workqueue(ts->wq);
1605 
1606 	INIT_WORK(&ts->work, cst2xx_ts_worker);
1607 
1608 	rc = input_register_device(input_device);
1609 	if (rc)
1610 		goto error_unreg_device;
1611 
1612 	return 0;
1613 
1614 error_unreg_device:
1615 	destroy_workqueue(ts->wq);
1616 error_wq_create:
1617 	input_free_device(input_device);
1618 error_alloc_dev:
1619 	//kfree(ts->touch_data);
1620 	return rc;
1621 }
1622 
hyn_ts_suspend(struct device * dev)1623 static int hyn_ts_suspend(struct device *dev)
1624 {
1625 	struct hyn_ts *ts = dev_get_drvdata(dev);
1626 	int i;
1627 
1628 	printk("I'am in hyn_ts_suspend() start\n");
1629 
1630 #ifdef HYN_MONITOR
1631 	printk( "hyn_ts_suspend () : cancel hyn_monitor_work\n");
1632 	cancel_delayed_work_sync(&ts->hyn_monitor_work);
1633 #endif
1634 
1635 #ifdef HYN_GESTURE
1636 //	disable_irq_nosync(ts->irq);
1637 #else
1638 	disable_irq_nosync(ts->irq);
1639 
1640 	if(h_wake_pin != 0) {
1641 	    gpio_direction_output(ts->rst_pin, 0);
1642 	}
1643 #endif
1644 
1645 #ifdef SLEEP_CLEAR_POINT
1646 	msleep(10);
1647 	#ifdef ICS_SLOT_REPORT
1648 	for(i=1; i<=MAX_CONTACTS; i++) {
1649 		input_mt_slot(ts->input, i);
1650 		input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
1651 		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false);
1652 	}
1653 	#else
1654 	input_mt_sync(ts->input);
1655 	#endif
1656 	input_sync(ts->input);
1657 
1658 #endif
1659 
1660 	return 0;
1661 }
1662 
hyn_ts_resume(struct device * dev)1663 static int hyn_ts_resume(struct device *dev)
1664 {
1665 	struct hyn_ts *ts = dev_get_drvdata(dev);
1666 	int i, rc;
1667 
1668 	printk("I'am in hyn_ts_resume() start\n");
1669 
1670 	hard_reset_chip(ts, 30);
1671 
1672 #ifdef SLEEP_CLEAR_POINT
1673 	#ifdef ICS_SLOT_REPORT
1674 	for(i=1; i<=MAX_CONTACTS; i++) {
1675 		input_mt_slot(ts->input, i);
1676 		input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
1677 		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false);
1678 	}
1679 	#else
1680 	input_mt_sync(ts->input);
1681 	#endif
1682 	input_sync(ts->input);
1683 #endif
1684 
1685 #ifdef HYN_MONITOR
1686 	printk( "hyn_ts_resume () : queue hyn_monitor_work\n");
1687 	queue_delayed_work(hyn_monitor_workqueue, &ts->hyn_monitor_work, 300);
1688 #endif
1689 
1690 
1691 #ifdef HYN_GESTURE
1692 //	enable_irq(ts->irq);
1693 #else
1694 	enable_irq(ts->irq);
1695 #endif
1696 
1697 	msleep(200);
1698 
1699 	rc = cst2xx_check_code(ts);
1700 	if(rc < 0){
1701 		printk("hyn check code error.\n");
1702 		return rc;
1703 	}
1704 	return 0;
1705 }
1706 
hyn_ts_early_suspend(struct tp_device * tp_d)1707 static int hyn_ts_early_suspend(struct tp_device *tp_d)
1708 {
1709 	struct hyn_ts *ts = container_of(tp_d, struct hyn_ts, tp);
1710 
1711 #ifdef HYN_GESTURE
1712 	gsl_lcd_flag = 1;
1713 #endif
1714 
1715 	printk("[CST2XX] Enter %s\n", __func__);
1716 	hyn_ts_suspend(&ts->client->dev);
1717 	return 0;
1718 }
1719 
hyn_ts_late_resume(struct tp_device * tp_d)1720 static int hyn_ts_late_resume(struct tp_device *tp_d)
1721 {
1722 	struct hyn_ts *ts = container_of(tp_d, struct hyn_ts, tp);
1723 
1724 #ifdef HYN_GESTURE
1725 	gsl_lcd_flag = 0;
1726 	gsl_gesture_flag = 0;
1727 #endif
1728 
1729 	printk("[CST2XX] Enter %s\n", __func__);
1730 	hyn_ts_resume(&ts->client->dev);
1731 	return 0;
1732 }
1733 
1734 
hyn_ts_probe(struct i2c_client * client,const struct i2c_device_id * id)1735 static int  hyn_ts_probe(struct i2c_client *client,
1736 			const struct i2c_device_id *id)
1737 {
1738 
1739 	int rc;
1740 	struct hyn_ts *ts=NULL;
1741 	struct device_node *np = client->dev.of_node;
1742 	enum of_gpio_flags wake_flags;
1743 	unsigned long irq_flags;
1744 
1745 	printk("cst2xx enter %s\n", __func__);
1746 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1747 		dev_err(&client->dev, "hyn I2C functionality not supported\n");
1748 		return -ENODEV;
1749 	}
1750 
1751 	ts = devm_kzalloc(&client->dev,sizeof(*ts), GFP_KERNEL);
1752 	//ts = kzalloc(sizeof(*ts), GFP_KERNEL);
1753 	if (!ts)
1754 		return -ENOMEM;
1755 	printk("==kzalloc success=\n");
1756 
1757 	ts->client = client;
1758 
1759 	i2c_set_clientdata(client, ts);
1760 	ts->device_id = id->driver_data;
1761 
1762     //×¢ÒâÖжϵÄÃû×Ö irq
1763 	ts->irq_pin = of_get_named_gpio_flags(np, "irq-gpio", 0, (enum of_gpio_flags *)&irq_flags);
1764 	ts->rst_pin = of_get_named_gpio_flags(np, "wake-gpio", 0, &wake_flags);
1765 
1766 	if (gpio_is_valid(ts->rst_pin)) {
1767 		rc = devm_gpio_request_one(&client->dev, ts->rst_pin, (wake_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, "cst21680 wake pin");
1768 		if (rc != 0) {
1769 			dev_err(&client->dev, "cst21680 wake pin error\n");
1770 			//return -EIO;
1771 		}
1772 		else
1773 		{
1774 		    h_wake_pin = ts->rst_pin;
1775 		}
1776 		//msleep(100);
1777 	} else {
1778 		dev_info(&client->dev, "wake pin invalid\n");
1779 	}
1780 
1781 	if (gpio_is_valid(ts->irq_pin)) {
1782 		rc = 0x00;
1783 		//rc = devm_gpio_request_one(&client->dev, ts->irq_pin, IRQF_TRIGGER_RISING, "gslX680 irq pin");
1784 			//printk("huang-GPIOF_OUT_INIT_LOW=%d\n\n",GPIOF_OUT_INIT_LOW);
1785 			//	printk("huang-GPIOF_OUT_INIT_LOW=%d\n\n",IRQF_TRIGGER_RISING);
1786 			//rc = request_irq(client->irq,gsl_ts_irq,IRQF_TRIGGER_RISING,client->name,ts);
1787 			//printk("huang-GPIOF_OUT_INIT_LOW=%d\n\n",IRQF_TRIGGER_RISING);
1788 		if (rc != 0) {
1789 			dev_err(&client->dev, "cst21680 irq pin error\n");
1790 			return -EIO;
1791 		}
1792 	} else {
1793 		dev_info(&client->dev, "irq pin invalid\n");
1794 	}
1795 
1796 
1797 	msleep(40);	 //runing
1798 
1799 	rc = cst2xx_test_i2c(client);
1800 	if (rc < 0) {
1801 		dev_err(&client->dev, "hyn cst2xx test iic error.\n");
1802 		return rc;
1803 	}
1804 
1805 	msleep(20);
1806 	rc = cst2xx_check_code(ts);
1807 	if(rc < 0){
1808 		printk("hyn check code error.\n");
1809 		return rc;
1810 	}
1811 
1812 	rc = cst2xx_ts_init(client, ts);
1813 	if (rc < 0) {
1814 		printk("hyn CST2XX init failed\n");
1815 		goto error_mutex_destroy;
1816 	}
1817 
1818 	ts->irq = gpio_to_irq(ts->irq_pin);
1819 
1820 	printk("cst2xx request ts->irq is :%d\n", ts->irq);
1821 	#if 0
1822 	rc = request_irq(client->irq, hyn_ts_irq, IRQF_TRIGGER_RISING, client->name, ts);
1823 	if (rc < 0) {
1824 		printk( "hyn_probe: request irq failed\n");
1825 		goto error_mutex_destroy;
1826 	}
1827 	#endif
1828 	if(ts->irq)
1829 	{
1830 		rc = devm_request_threaded_irq(&client->dev, ts->irq, NULL, hyn_ts_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, client->name, ts);
1831 		if (rc != 0) {
1832 			printk(KERN_ALERT "Cannot allocate ts INT!ERRNO:%d\n", rc);
1833 			goto error_mutex_destroy;
1834 		}
1835 		disable_irq(ts->irq);
1836 	}
1837 	else
1838 	{
1839 		printk("cst21680 irq req fail\n");
1840 		goto error_mutex_destroy;
1841 	}
1842 
1843 	/* create debug attribute */
1844 	//rc = device_create_file(&ts->input->dev, &dev_attr_debug_enable);
1845 	ts->tp.tp_suspend = hyn_ts_early_suspend;
1846 	ts->tp.tp_resume = hyn_ts_late_resume;
1847 	tp_register_fb(&ts->tp);
1848 
1849 #ifdef CONFIG_HAS_EARLYSUSPEND
1850 	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
1851 	//ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;
1852 	ts->early_suspend.suspend = hyn_ts_early_suspend;
1853 	ts->early_suspend.resume = hyn_ts_late_resume;
1854 	register_early_suspend(&ts->early_suspend);
1855 #endif
1856 
1857 #ifdef HYN_MONITOR
1858 	printk( "hyn_ts_probe () : queue hyn_monitor_workqueue\n");
1859 
1860 	INIT_DELAYED_WORK(&ts->hyn_monitor_work, hyn_monitor_worker);
1861 	hyn_monitor_workqueue = create_singlethread_workqueue("hyn_monitor_workqueue");
1862 	queue_delayed_work(hyn_monitor_workqueue, &ts->hyn_monitor_work, 1000);
1863 #endif
1864 
1865 #ifdef ANDROID_TOOL_SURPORT
1866 	cst2xx_proc_fs_init();
1867 	hyn_global_ts=ts;
1868 #endif
1869 
1870 #ifdef TPD_PROC_DEBUG
1871 
1872 	hyn_config_proc = create_proc_entry(HYN_CONFIG_PROC_FILE, 0666, NULL);
1873 	printk("[tp-hyn] [%s] hyn_config_proc = %x \n",__func__,hyn_config_proc);
1874 	if (hyn_config_proc == NULL)
1875 	{
1876 		print_info("create_proc_entry %s failed\n", HYN_CONFIG_PROC_FILE);
1877 	}
1878 	else
1879 	{
1880 		hyn_config_proc->read_proc = hyn_config_read_proc;
1881 		hyn_config_proc->write_proc = hyn_config_write_proc;
1882 	}
1883 #endif
1884 
1885 	enable_irq(ts->irq);
1886 	printk("[CST2XX] End %s\n", __func__);
1887 	return 0;
1888 
1889 error_mutex_destroy:
1890 	input_free_device(ts->input);
1891 	return rc;
1892 }
1893 
hyn_ts_remove(struct i2c_client * client)1894 static int hyn_ts_remove(struct i2c_client *client)
1895 {
1896 	struct hyn_ts *ts = i2c_get_clientdata(client);
1897 	printk("==hyn_ts_remove=\n");
1898 
1899 #ifdef CONFIG_HAS_EARLYSUSPEND
1900 	unregister_early_suspend(&ts->early_suspend);
1901 #endif
1902 
1903 #ifdef HYN_MONITOR
1904 	cancel_delayed_work_sync(&ts->hyn_monitor_work);
1905 	destroy_workqueue(hyn_monitor_workqueue);
1906 #endif
1907 
1908 	device_init_wakeup(&client->dev, 0);
1909 	cancel_work_sync(&ts->work);
1910 	destroy_workqueue(ts->wq);
1911 	input_unregister_device(ts->input);
1912 	//device_remove_file(&ts->input->dev, &dev_attr_debug_enable);
1913 
1914 	//kfree(ts->touch_data);
1915 	return 0;
1916 }
1917 
1918 #if 1
1919 static struct of_device_id hyn_ts_ids[] = {
1920 	{ .compatible = "cst2xx" },
1921 	{ }
1922 };
1923 #endif
1924 
1925 static const struct i2c_device_id hyn_ts_id[] = {
1926 	{CST2XX_I2C_NAME, 0},
1927 	{}
1928 };
1929 
1930 MODULE_DEVICE_TABLE(i2c, hyn_ts_id);
1931 
1932 static struct i2c_driver hyn_ts_driver = {
1933 	.driver = {
1934 		.name = CST2XX_I2C_NAME,
1935 		.owner = THIS_MODULE,
1936         .of_match_table = of_match_ptr(hyn_ts_ids),
1937 	},
1938 
1939 #ifndef CONFIG_HAS_EARLYSUSPEND
1940   //  .suspend	= hyn_ts_suspend,
1941   //  .resume	= hyn_ts_resume,
1942 #endif
1943 	.probe		= hyn_ts_probe,
1944 	.remove		= hyn_ts_remove,
1945 	.id_table	= hyn_ts_id,
1946 };
1947 
hyn_ts_init(void)1948 static int __init hyn_ts_init(void)
1949 {
1950     int ret;
1951 	//printk("==hyn_ts_init==\n");
1952 	ret = i2c_add_driver(&hyn_ts_driver);
1953 	//printk("ret=%d\n",ret);
1954 	return ret;
1955 }
hyn_ts_exit(void)1956 static void __exit hyn_ts_exit(void)
1957 {
1958 	//printk("==hyn_ts_exit==\n");
1959 	i2c_del_driver(&hyn_ts_driver);
1960 	return;
1961 }
1962 
1963 module_init(hyn_ts_init);
1964 module_exit(hyn_ts_exit);
1965 
1966 MODULE_LICENSE("GPL");
1967 MODULE_DESCRIPTION("HYNCST2XX touchscreen controller driver");
1968 MODULE_AUTHOR("Tim.Tan");
1969 MODULE_ALIAS("platform:hyn_ts");
1970 
1971