static int synaptics_ts_probe(
		struct i2c_client *client, const struct i2c_device_id *id)
{
	struct synaptics_ts_data *ts;
	int ret = 0;
	struct vreg *vreg_touch;
	uint8_t i2c_addr = 0x1B;
	uint8_t buf_tmp[3]={0,};

	HW_ver = 0;
	SW_ver = 0;

	printk("[TSP] %s, %d\n", __func__, __LINE__ );

	vreg_touch = vreg_get(NULL, "ldo6");
	ret = vreg_set_level(vreg_touch, OUT3000mV);
	if (ret) {
		printk(KERN_ERR "%s: vreg set level failed (%d)\n",
				__func__, ret);
		return -EIO;
	}

	ret = vreg_enable(vreg_touch);
	if (ret) {
		printk(KERN_ERR "%s: vreg enable failed (%d)\n",
				__func__, ret);
		return -EIO;
	}

	msleep(700);

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	if (ts == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	INIT_WORK(&ts->work, synaptics_ts_work_func);
	INIT_DELAYED_WORK(&ts->work_check_ic, check_ic_work_func );
	schedule_delayed_work(&ts->work_check_ic, CHECK_TIME );

	ts->client = client;
	i2c_set_clientdata(client, ts);

	ts_global = ts;

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		ret = -ENOMEM;
			touch_present = 0;
		printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
		goto err_input_dev_alloc_failed;
	}
	ts->input_dev->name = "sec_touchscreen";
	set_bit(EV_SYN, ts->input_dev->evbit);
	set_bit(EV_KEY, ts->input_dev->evbit);
	set_bit(BTN_TOUCH, ts->input_dev->keybit);
	set_bit(EV_ABS, ts->input_dev->evbit);

	printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n");
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);	//0, MAX_X, 0, 0
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);	//0, MAX_Y, 0, 0
	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);

	/* ts->input_dev->name = ts->keypad_info->name; */
	ret = input_register_device(ts->input_dev);
	if (ret) {
			touch_present = 0;
		printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
		goto err_input_register_device_failed;
	}
	printk("[TSP] %s, irq=%d\n", __func__, client->irq );

	if (client->irq) {
		ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts);
		if (ret == 0) 
			ts->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = synaptics_ts_early_suspend;
	ts->early_suspend.resume = synaptics_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif

	printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");

	/* sys fs */
	touch_class = class_create(THIS_MODULE, "touch");
	if (IS_ERR(touch_class))
		pr_err("Failed to create class(touch)!\n");

	firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware");
	if (IS_ERR(firmware_dev))
		pr_err("Failed to create device(firmware)!\n");

	if (device_create_file(firmware_dev, &dev_attr_firmware) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name);
	if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name);
	/* sys fs */

	/* Check point - i2c check - start */
	ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp));
	HW_ver = buf_tmp[1];
	SW_ver = buf_tmp[2];

	if (ret <= 0) {
		printk(KERN_ERR "i2c_transfer failed\n");
		ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp));

		if (ret <= 0) 
		{
			disable_irq(ts_global->client->irq);
			cancel_delayed_work_sync(&ts_global->work_check_ic);
			touch_present = 0;
			printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret);
			goto err_check_functionality_failed;
		}
	}
	/* Check point - i2c check - end */
	printk("[TSP] %s, ver CY=%x\n", __func__ , buf_tmp[0] );
	printk("[TSP] %s, ver HW=%x\n", __func__ , buf_tmp[1] );
	printk("[TSP] %s, ver SW=%x\n", __func__ , buf_tmp[2] );

	touch_present = 1;
	/* Check point - Firmware */
	printk("[TSP] %s:%d, ver SW=%x, HW=%x\n", __func__, __LINE__,  SW_ver, HW_ver);

	printk("[TSP] Here - Deleted Firmware Check Routine \n");
#if 0
	switch( (HW_ver+1)/10 ){
		case 0:		//Degitech
			if(HW_ver < Digi_HEX_HW_VER){	//Firmware Update
				firm_update();
			}else if((SW_ver<Digi_HEX_SW_VER)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){
				printk("[TSP] firm_update START!!, ln=%d\n",__LINE__);
				firm_update();
			}else{
				printk("[TSP] Firmware Version(Digitech) is Up-to-date.\n");
			}break;	
		case 1:		//SMAC
			if(HW_ver < SMAC_HEX_HW_VER){	//Firmware Update
				firm_update();
			}else if((SW_ver<SMAC_HEX_SW_VER)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){
				printk("[TSP] firm_update START!!, ln=%d\n",__LINE__);
				firm_update();
			}else{
				printk("[TSP] Firmware Version(SMAC) is Up-to-date.\n");
			}break;	
		case 2:	;	//
	}
#endif

	printk(KERN_INFO "synaptics_ts_probe: Manufacturer ID: %x, HW ver=%x, SW ver=%x\n", buf_tmp[0], buf_tmp[1], buf_tmp[2]);

	/* Check point - Firmware */

	return 0;

err_input_register_device_failed:
	input_free_device(ts->input_dev);

err_input_dev_alloc_failed:
	kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
static void synaptics_ts_work_func(struct work_struct *work)
#endif
{
	int ret=0;
	uint8_t buf[12];// 02h ~ 0Dh
	uint8_t i2c_addr = 0x02;
	int i = 0;
	int finger = 0;

#if USE_THREADED_IRQ
	struct synaptics_ts_data *ts = dev_id;
#else
	struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);
#endif

	ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

	if (ret <= 0) {
		printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__);
		goto work_func_out;
	}

	finger = buf[0] & 0x07;	
	
	fingerInfo[0].x = (buf[1] << 8) |buf[2];
	fingerInfo[0].y = (buf[3] << 8) |buf[4];
	fingerInfo[0].z = buf[5];
	fingerInfo[0].id = buf[6] >>4;

	fingerInfo[1].x = (buf[7] << 8) |buf[8];
	fingerInfo[1].y = (buf[9] << 8) |buf[10];
	fingerInfo[1].z = buf[11];
	fingerInfo[1].id = buf[6] & 0xf;

/*********************hash
	if ( board_hw_revision >= 0x2 && HW_ver==1 )
	{

		fingerInfo[0].x = 240 - fingerInfo[0].x;
		fingerInfo[0].y = 320 - fingerInfo[0].y;
		fingerInfo[1].x = 240 - fingerInfo[1].x;
		fingerInfo[1].y = 320 - fingerInfo[1].y;
	
		//	fingerInfo[0].x = 320 - fingerInfo[0].x;
		//	fingerInfo[1].y = 480 - fingerInfo[1].y;
	}
************************/
	//	print message
//	for ( i= 0; i<MAX_USING_FINGER_NUM; i++ )
//		printk("[TSP] finger[%d].x = %d, finger[%d].y = %d, finger[%d].z = %x, finger[%d].id = %x\n", i, fingerInfo[i].x, i, fingerInfo[i].y, i, fingerInfo[i].z, i, fingerInfo[i].id);

	/* check key event*/
//	if(fingerInfo[0].status != 1 && fingerInfo[1].status != 1)	//
//		process_key_event(buf[0]);								//HASHTSK

	/* check touch event */
	for ( i= 0; i<MAX_USING_FINGER_NUM; i++ )
	{
		//////////////////////////////////////////////////IC
		if(fingerInfo[i].id >=1)
		{
			fingerInfo[i].status = 1;
		}
		else if(fingerInfo[i].id ==0 && fingerInfo[i].status == 1)
		{
			fingerInfo[i].status = 0;
		}
		else if(fingerInfo[i].id ==0 && fingerInfo[i].status == 0)
		{
			fingerInfo[i].status = -1;
		}

		if(fingerInfo[i].status == -1) continue;
		/////////////////////////////////////////////////IC

		input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[i].x);
		input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[i].y);
		input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, fingerInfo[i].id);
		input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[i].z);
		input_mt_sync(ts->input_dev);

     #if defined(__TOUCH_DEBUG__)
		printk("[TSP] i[%d] id[%d] xyz[%d, %d, %x] status[%x]\n", i, fingerInfo[i].id, fingerInfo[i].x, fingerInfo[i].y, fingerInfo[i].z, fingerInfo[i].status);	
    #endif
	}

	input_sync(ts->input_dev);

work_func_out:
	if (ts->use_irq)
	{
		#if USE_THREADED_IRQ

		#else
		enable_irq(ts->client->irq);
		#endif
	}
	
	#if USE_THREADED_IRQ
	return IRQ_HANDLED;
	#else

	#endif	
}
static void synaptics_ts_work_func(struct work_struct *work)
{
	int ret=0;
	uint8_t buf[12];// 02h ~ 0Dh
	uint8_t i2c_addr = 0x02;
	int i = 0;
	uint8_t finger = 0;

	struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);

	ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

	if (ret <= 0) {
		printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__);
		goto work_func_out;
	}

	finger = buf[0] & 0x07;	

	fingerInfo[0].x = (buf[1] << 8) |buf[2];
	fingerInfo[0].y = (buf[3] << 8) |buf[4];
	fingerInfo[0].z = buf[5]/2;
	fingerInfo[0].id = (buf[6] >>4)& 0x0f;

	fingerInfo[1].x = (buf[7] << 8) |buf[8];
	fingerInfo[1].y = (buf[9] << 8) |buf[10];
	fingerInfo[1].z = buf[11]/2;
	fingerInfo[1].id = buf[6] & 0x0f;

	/* check touch event */
	for ( i= 0; i<MAX_USING_FINGER_NUM; i++ )
	{
		if(fingerInfo[i].id >=1) // press interrupt
		{
			if(i==0 && fingerInfo[1].status != 1)
			{
				if((fingerInfo[2].id != fingerInfo[0].id)&&(fingerInfo[2].id != 0))// no release with finger id change
				{
					//			if(fingerInfo[1].id ==0)
					{
						input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[2].x);	
						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[2].y);
						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[2].z);
						input_mt_sync(ts->input_dev);
						input_sync(ts->input_dev);

						//printk("[TSP] [%d] 0 (%d, %d,	%x)\n", i, fingerInfo[2].x, fingerInfo[2].y, fingerInfo[2].z);
						fingerInfo[1].status = -1;
					}
				}
				else if(fingerInfo[2].id != 0) // check x or y jump with same finger id
				{

					if(ABS(fingerInfo[2].x,fingerInfo[0].x)>150)
					{
						input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[2].x);	
						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[2].y);
						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[2].z);
						input_mt_sync(ts->input_dev);
						input_sync(ts->input_dev);

						//printk("[TSP] [%d] 0 (%d, %d,	%x)\n", i, fingerInfo[2].x, fingerInfo[2].y, fingerInfo[2].z);
						fingerInfo[1].status = -1;	
					}
					else if(ABS(fingerInfo[2].y,fingerInfo[0].y)>150)
					{
						input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[2].x);	
						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[2].y);
						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[2].z);
						input_mt_sync(ts->input_dev);
						input_sync(ts->input_dev);

						//printk("[TSP] [%d] 0 (%d, %d,	%x)\n", i, fingerInfo[2].x, fingerInfo[2].y, fingerInfo[2].z);
						fingerInfo[1].status = -1;	
					}
					else // no jump
					{
						if(fingerInfo[i].status != -2) // force release
							fingerInfo[i].status = 1;
						else
							fingerInfo[i].status = -2;
					}
				}
				else // single touch with normal condition
				{
					if(fingerInfo[i].status != -2) // force release
						fingerInfo[i].status = 1;
					else
						fingerInfo[i].status = -2;
				}
			}
			else
			{
				if(fingerInfo[i].status != -2) // force release
					fingerInfo[i].status = 1;
				else
					fingerInfo[i].status = -2;
			}
		}
		else if(fingerInfo[i].id ==0) // release interrupt (only first finger)
		{
			if(fingerInfo[i].status == 1 || fingerInfo[i].status == -3) // prev status is press
				fingerInfo[i].status = 0;
			else if(fingerInfo[i].status == 0 || fingerInfo[i].status == -2) // release already or force release
				fingerInfo[i].status = -1;
		}

		if(fingerInfo[i].status < 0) continue;

		input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[i].x);
		input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[i].y);
		input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, fingerInfo[i].status);
		input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[i].z);
		input_mt_sync(ts->input_dev);

		//printk("[TSP] [%d] %d (%d, %d,	%x)		%x\n", i, fingerInfo[i].id, fingerInfo[i].x, fingerInfo[i].y, fingerInfo[i].z, fingerInfo[i].status);		
	}

	input_sync(ts->input_dev);

	fingerInfo[2].x = fingerInfo[0].x;
	fingerInfo[2].y = fingerInfo[0].y;
	fingerInfo[2].z = fingerInfo[0].z;
	fingerInfo[2].id = fingerInfo[0].id;	

work_func_out:
	if (ts->use_irq)
	{
		enable_irq(ts->client->irq);
	}
}
static void synaptics_ts_work_func(struct work_struct *work)
{
	int ret=0;
	uint8_t buf[11];
	uint8_t i2c_addr = 0x02;
	uint16_t x=0;
	uint16_t y=0;
	uint16_t z=1;
	int finger = 0;
       uint8_t i2c_reg_info;
        uint8_t InputType =0 ;
      int v_touch_pressed=0;
      int press;
#ifdef DEBUG_INPUT_REPORT
	static int prev_finger = 0;
#endif
	struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);

      #if defined(__TOUCH_DEBUG__)
	printk("[TSP] %s\n", __func__ );
      #endif
	ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

	if (ret <= 0) {
		printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__);
		goto work_func_out;
	}

     #if defined(__TOUCH_DEBUG__)
	printk("[TSP] buf[0]:%d, buf[1]:%d, buf[2]=%d, buf[3]=%d, buf[4]=%d, buf[5]=%d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
	printk("[TSP] buf[6]:%d, buf[7]:%d, buf[8]=%d, buf[9]=%d, buf[10]=%d, buf[11]=%d\n", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
    #endif
    
        i2c_reg_info = buf[3];
        x = buf[6]; 
        y = buf[4]; 

        if( i2c_reg_info == 1)	/* 6bit mask , 1이면 256이 넘은것을 의미*/
        	y  = y  + 256;

        InputType = i2c_reg_info&0x01;

        v_touch_pressed = (InputType == 0x01) ? TRUE:FALSE;  /*1 이면 pressed 0이면 released */

        press = buf[5];

        if(press)
		press= 1;//strength;
	else
		press = 0;

	input_report_abs(ts->input_dev, ABS_X, y);
	input_report_abs(ts->input_dev, ABS_Y, x);		
	input_report_abs(ts->input_dev, ABS_PRESSURE, 1);
	input_report_key(ts->input_dev, BTN_TOUCH, press);
	input_sync(ts->input_dev);    

     #if defined(__TOUCH_DEBUG__)
	printk("[TSP] x=%d, y=%d, press=%d\n", y, x, press );
    #endif
    
#ifdef DEBUG_INPUT_REPORT
	if ( finger ^ prev_finger )
	{
		printk("[TSP] x=%d, y=%d\n", x, y );
		prev_finger = finger;
	}
#endif

work_func_out:
	if (ts->use_irq)
	{
             #if defined(__TOUCH_DEBUG__)
        	printk("[TSP] synaptics_ts_work_func==>enable_irq\n");
            #endif
            enable_irq(ts->client->irq);
	}
}
static int synaptics_ts_probe(
		struct i2c_client *client, const struct i2c_device_id *id)
{
	struct synaptics_ts_data *ts;
	int ret = 0;
	uint8_t i2c_addr = 0x05;
	uint8_t buf[3];
	int ret_temp=0;
	uint8_t buf_temp[3];
	uint8_t i2c_addr_temp = 0x02;

	printk("[TSP] %s, %d\n", __func__, __LINE__ );

	touch_ctrl_regulator(TOUCH_ON);

	msleep(100);

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	if (ts == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	INIT_WORK(&ts->work, synaptics_ts_work_func);
	ts->client = client;
	i2c_set_clientdata(client, ts);

	ts_global = ts;

	/* Check point - i2c check - start */
	ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

	if (ret <= 0) {
		printk(KERN_ERR "i2c_transfer failed\n");
		ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

		if (ret <= 0) 
		{
			printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret);
			goto err_check_functionality_failed;
		}
	}
	/* Check point - i2c check - end */

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		ret = -ENOMEM;
		printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
		goto err_input_dev_alloc_failed;
	}
	ts->input_dev->name = "synaptics-rmi-touchscreen";
	set_bit(EV_SYN, ts->input_dev->evbit);
	set_bit(EV_KEY, ts->input_dev->evbit);
	set_bit(BTN_TOUCH, ts->input_dev->keybit);
	set_bit(EV_ABS, ts->input_dev->evbit);

	printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n");

       input_set_abs_params(ts->input_dev, ABS_X, 0, MAX_X, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_Y, 0, MAX_Y, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);

	/* ts->input_dev->name = ts->keypad_info->name; */
	ret = input_register_device(ts->input_dev);
	if (ret) {
		printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
		goto err_input_register_device_failed;
	}
	printk("[TSP] %s, irq=%d\n", __func__, client->irq );
	if (client->irq) {
		ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts);
		if (ret == 0) 
			ts->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}

	//	hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	//	ts->timer.function = synaptics_ts_timer_func;

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = synaptics_ts_early_suspend;
	ts->early_suspend.resume = synaptics_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif

	printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");

	/* sys fs */
	touch_class = class_create(THIS_MODULE, "touch");
	if (IS_ERR(touch_class))
		pr_err("Failed to create class(touch)!\n");

	firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware");
	if (IS_ERR(firmware_dev))
		pr_err("Failed to create device(firmware)!\n");

	if (device_create_file(firmware_dev, &dev_attr_firmware) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name);
	if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name);

	/* sys fs */

	/* Check point - Firmware */
	printk("[TSP] %s, ver CY=%x\n", __func__ , buf[0] );
	printk("[TSP] %s, ver HW=%x\n", __func__ , buf[1] );
	printk("[TSP] %s, ver SW=%x\n", __func__ , buf[2] );

	HW_ver = buf[1];
	printk(KERN_INFO "synaptics_ts_probe: Manufacturer ID: %x, HW ver=%d\n", buf[0], HW_ver);
    
	/* Check point - Firmware */

	ret_temp = tsp_i2c_read( i2c_addr_temp, buf_temp, sizeof(buf_temp));

	if (ret_temp <= 0) {
		printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret_temp, __LINE__);
		goto err_check_functionality_failed;
	}

	return 0;

err_input_register_device_failed:
	input_free_device(ts->input_dev);

err_input_dev_alloc_failed:
	kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
/* firmware - update */
static ssize_t firmware_store(
		struct device *dev, struct device_attribute *attr,
		const char *buf, size_t size)
{
	char *after;

	uint8_t i2c_addr = 0x00;
	uint8_t buf_tmp[11] = {0};

	unsigned long value = simple_strtoul(buf, &after, 10);	
	printk(KERN_INFO "[TSP] %s, %d\n", __func__, __LINE__);
	firmware_ret_val = -1;


	tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp));

	touch_vendor_id = buf_tmp[7];
	touch_hw_ver = buf_tmp[8];
	touch_sw_ver = buf_tmp[9];
	printk("[TSP] %s:%d, ver tsp=%x, HW=%x, SW=%x\n", __func__,__LINE__, touch_vendor_id, touch_hw_ver, touch_sw_ver);

	HW_ver = touch_hw_ver;

	if ( value == 1 )
	{
		printk("[TSP] Firmware update start!!\n" );

		now_tst200_update_luisa = 1;
		firm_update( );
		now_tst200_update_luisa = 0;
#if FIRM_TEST
		printk("[TSP] start update cypress touch firmware !!\n");
		g_FirmwareImageSize = CYPRESS_FIRMWARE_IMAGE_SIZE;

		if(g_pTouchFirmware == NULL)
		{
			printk("[TSP][ERROR] %s() kmalloc fail !! \n", __FUNCTION__);
			return -1;
		}


		/* ready for firmware code */
		size = issp_request_firmware("touch.hex");

		/* firmware update */
		//	issp_upgrade();

		g_FirmwareImageSize = 0;

		// step.1 power off/on

		// step.2 enable irq


#endif
		return size;
	}
	else if( value == 2 )
	{
		printk("[TSP] Special Firmware update start!!\n" );

		tsp_special_update = 1;

		now_tst200_update_luisa = 1;
		firm_update( );
		now_tst200_update_luisa = 0;	
	}

	return size;
}
static int synaptics_ts_resume(struct i2c_client *client)
{
	int ret;
	int key;
	struct vreg *vreg_touch;
	struct synaptics_ts_data *ts = i2c_get_clientdata(client);
	uint8_t i2c_addr = 0x1D;
	uint8_t buf[1];

	printk("[TSP] %s+\n", __func__ );

	gpio_set_value( TSP_SCL , 1 ); 
	gpio_set_value( TSP_SDA , 1 ); 
	gpio_set_value( TSP_INT , 1 ); 

	vreg_touch = vreg_get(NULL, "maxldo06");

	ret = vreg_enable(vreg_touch);
	if (ret) {
		printk(KERN_ERR "%s: vreg enable failed (%d)\n",
				__func__, ret);
		return -EIO;
	}
#ifdef KEY_LED_CONTROL
	if(!touchkey_led_on_off) {
		ret = key_led_power_control(TRUE);
		if (ret < 0) {
			printk(KERN_ERR "%s: vreg enable failed (%d)\n",__func__, ret);
		return -EIO;
		} else {
      			touchkey_led_on_off = 1;
		}
	}
#endif
	msleep(200);

	// for TSK
	for(key = 0; key < MAX_KEYS; key++)
		touchkey_status[key] = TK_STATUS_RELEASE;

	while (ts->use_irq)
	{
		msleep(20);

		ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));
		if (ret <= 0) {
//			printk("[TSP] %d : i2c_transfer failed\n", __LINE__);
		}
		else if	( buf[0] == 0 )
		{
			continue;
		}
		else
		{
			printk("[TSP] %s:%d, ver SW=%x\n", __func__,__LINE__, buf[0] );
			enable_irq(client->irq);
			break;
		}
		msleep(20);
	}

#ifdef TOUCH_VERIFY_WITH_TIMER
	if(board_hw_revision >= 0x3) {
	prev_wdog_val = -1;
	schedule_delayed_work(&ts->work_check_ic, CHECK_TIME );
	}
#endif
	printk("[TSP] %s-\n", __func__ );
	return 0;
}
static int synaptics_ts_probe(
		struct i2c_client *client, const struct i2c_device_id *id)
{
	struct synaptics_ts_data *ts;
	int ret = 0;
	int key = 0;
	struct vreg *vreg_touch;
	uint8_t i2c_addr = 0x1B;
	uint8_t buf_tmp[3]={0,};

	HW_ver = 0;
	SW_ver = 0;

	printk("[TSP] %s, %d\n", __func__, __LINE__ );

	vreg_touch = vreg_get(NULL, "maxldo06");
	ret = vreg_set_level(vreg_touch, OUT3000mV);
	if (ret) {
		printk(KERN_ERR "%s: vreg set level failed (%d)\n",
				__func__, ret);
		return -EIO;
	}

	ret = vreg_enable(vreg_touch);
	if (ret) {
		printk(KERN_ERR "%s: vreg enable failed (%d)\n",
				__func__, ret);
		return -EIO;
	}

	msleep(700);

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	if (ts == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	INIT_WORK(&ts->work, synaptics_ts_work_func);

#ifdef TOUCH_VERIFY_WITH_TIMER
	if(board_hw_revision >= 0x3) {
	INIT_DELAYED_WORK(&ts->work_check_ic, check_ic_work_func );
	schedule_delayed_work(&ts->work_check_ic, CHECK_TIME );
	}
#endif
	ts->client = client;
	i2c_set_clientdata(client, ts);

	ts_global = ts;

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		ret = -ENOMEM;
		printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
		goto err_input_dev_alloc_failed;
	}
	ts->input_dev->name = "synaptics-rmi-touchscreen";
	set_bit(EV_SYN, ts->input_dev->evbit);
	set_bit(EV_KEY, ts->input_dev->evbit);
	set_bit(BTN_TOUCH, ts->input_dev->keybit);
	set_bit(EV_ABS, ts->input_dev->evbit);

	printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n");
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);	//0, MAX_X, 0, 0
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);	//0, MAX_Y, 0, 0
	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);

	for(key = 0; key < MAX_KEYS ; key++)
		input_set_capability(ts->input_dev, EV_KEY, touchkey_keycodes[key]);

	// for TSK
	for(key = 0; key < MAX_KEYS ; key++)
		touchkey_status[key] = TK_STATUS_RELEASE;

	/* ts->input_dev->name = ts->keypad_info->name; */
	ret = input_register_device(ts->input_dev);
	if (ret) {
		printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
		goto err_input_register_device_failed;
	}
	printk("[TSP] %s, irq=%d\n", __func__, client->irq );

	if (client->irq) {
		ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts);
		if (ret == 0) 
			ts->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = synaptics_ts_early_suspend;
	ts->early_suspend.resume = synaptics_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif

	printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");

	/* sys fs */
	touch_class = class_create(THIS_MODULE, "touch");
	if (IS_ERR(touch_class))
		pr_err("Failed to create class(touch)!\n");

	firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware");
	if (IS_ERR(firmware_dev))
		pr_err("Failed to create device(firmware)!\n");

	if (device_create_file(firmware_dev, &dev_attr_firmware) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name);
	if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name);
	/* sys fs */

	if(board_hw_revision >= 0x3) {
		msleep(400);
	}

	/* Check point - i2c check - start */
	ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp));
	HW_ver = buf_tmp[1];
	SW_ver = buf_tmp[2];

	if (ret <= 0) {
		printk(KERN_ERR "i2c_transfer failed\n");
		ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp));
#ifdef EMERGENCY_FIRMWARE_UPDATE
		emergency_firm_update();
#endif
		if (ret <= 0) 
		{
			printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret);
			goto err_check_functionality_failed;
		}
	}
	/* Check point - i2c check - end */
	printk("[TSP] %s, ver CY=%x\n", __func__ , buf_tmp[0] );
	printk("[TSP] %s, ver HW=%x\n", __func__ , buf_tmp[1] );
	printk("[TSP] %s, ver SW=%x\n", __func__ , buf_tmp[2] );
	
	/* Check point - Firmware */
	printk("[TSP] %s: Board REV[%d], ver SW=%x, HW=%x\n", __func__, board_hw_revision, SW_ver, HW_ver );

	if(((HW_ver <= HEX_HW_VER ) || ( HW_ver < HEX_HW_VER && HW_ver > 0 )) && (board_hw_revision < 0x3)) {
		if((SW_ver<HEX_SW_VER)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){
			printk(KERN_INFO "[TSP] Firmware Update on REV01");
			firm_update();
		} else {
			printk(KERN_INFO "[TSP] Firmware version is up-to-date");
		}	
	} else if(((HW_ver <= HEX_HW_VER_REV03) || (HW_ver < HEX_HW_VER_REV03 && HW_ver>0)) && (board_hw_revision == 0x3)) {
		if((SW_ver < HEX_SW_VER_REV03)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){
			printk(KERN_INFO "[TSP] Firmware Update on REV03");
			firm_update();
		}else{
			printk(KERN_INFO "[TSP] Firmware version is up-to-date");
		}
	} else if(((HW_ver <= HEX_HW_VER_REV04) || (HW_ver < HEX_HW_VER_REV04 && HW_ver>0)) && (board_hw_revision >= 0x4)) {
		if((SW_ver < HEX_SW_VER_REV04)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){
			printk(KERN_INFO "[TSP] Firmware Update on REV06");
			firm_update();
		}else{
			printk(KERN_INFO "[TSP] Firmware version is up-to-date");
		}
	}

	printk(KERN_INFO "%s: Manufacturer ID: %x, HW ver=%x, SW ver=%x\n", __func__, buf_tmp[0], buf_tmp[1], buf_tmp[2]);

#ifdef KEY_LED_CONTROL
	init_timer(&g_led_timer);
	g_led_timer.expires= (jiffies + (HZ*KEY_LED_ON_TIME));
	g_led_timer.function = TouchKey_Led_TimerProc;
	add_timer(&g_led_timer);
#endif


	return 0;

err_input_register_device_failed:
	input_free_device(ts->input_dev);

err_input_dev_alloc_failed:
	kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
static void synaptics_ts_work_func(struct work_struct *work)
{
	int ret=0;
//	uint8_t buf[3];
	uint8_t buf[5];
	uint8_t temp;
	
	uint8_t i2c_addr = 0x02;
	uint16_t x=0;
	uint16_t y=0;
	uint16_t z=1;
	int finger = 0;
	static int prev_key = 0;
	static int curr_key = 0;
	static int key_report = 0;
	
#ifdef DEBUG_INPUT_REPORT
	static int prev_finger = 0;
#endif
	struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);

	ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

	if (ret <= 0) {
		printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__);
		goto work_func_out;
	}

//	x = buf[0];
//	y = buf[1] & 0x0F;
//	y = (y << 8) | (buf[2] );
//	finger = (buf[1] >> 7);

	x = buf[1];	//buf[0];
	y = buf[2];	//buf[0];
	if( buf[0] & 0x40 )
		x += 256;

	finger = buf[0] & 0x01;

	input_report_abs(ts->input_dev, ABS_X, x);
	input_report_abs(ts->input_dev, ABS_Y, y);		
	input_report_abs(ts->input_dev, ABS_PRESSURE, z);
	input_report_key(ts->input_dev, BTN_TOUCH, finger);
	input_sync(ts->input_dev);
	
//	printk("[TSP] buf[0]=%X, buf[1]=%X, buf[2]=%X, buf[3]=%X, buf[4]=%X\n",
//			 buf[0], buf[1], buf[2], buf[3], buf[4] );
//	printk("[TSP] temp=%X, key_report=%X, prev_key=%X\n", temp, key_report, prev_key );

	// Processing Key Btn 
	// 3 : MENU, 5 : HOME, 9 : PREV, 11 : SEARCH
	temp = buf[4];
	if(	temp )
	{
		if( !key_report )
		{
			key_report = 1;
			switch( temp )
			{
				case 0x03 : //MENU
					prev_key = 1;
#ifdef DEBUG_INPUT_REPORT
					printk("[TSP] MENU BTN Clicked!! \n" );
#endif
					input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1);
					break;
				case 0x05 : //HOME
					prev_key = 2;
#ifdef DEBUG_INPUT_REPORT
					printk("[TSP] HOME BTN Clicked!! \n" );
#endif
					input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1);
					break;
				case 0x09 : //PREV
					prev_key = 3;
#ifdef DEBUG_INPUT_REPORT
					printk("[TSP] PREV BTN Clicked!! \n" );
#endif
					input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1);
					break;
				case 0x11 : //SEARCH
					prev_key = 4;
#ifdef DEBUG_INPUT_REPORT
					printk("[TSP] SEARCH BTN Clicked!! \n" );
#endif
					input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1);
					break;
			}
		}
	}
	else if( prev_key )
	{
#ifdef DEBUG_INPUT_REPORT
		switch( prev_key )
		{
			case 1 : //MENU
				printk("[TSP] MENU BTN Released!! \n" );
				break;
			case 2 : //HOME
				printk("[TSP] HOME BTN Released!! \n" );
				break;
			case 3 : //PREV
				printk("[TSP] PREV BTN Released!! \n" );
				break;
			case 4 : //SEARCH
				printk("[TSP] SEARCH BTN Released!! \n" );
				break;
		}
#endif
		input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 0);
		prev_key =0;
		key_report = 0;
	}
/*	
	// TSP 칩에서 터치키 눌러질때 터치이벤트도 동시에 올라가서 불필요한 처리가 되게 됨.
	// TSP 펌웨어에서 추가적으로 처리될때까지 임시 루틴을 사용하여 불필요한 터치 이벤트를 올리지 않도록 할 필요가 있음.
//	if( !key_report && !prev_key )
	{
		key_report = 0;
		input_report_abs(ts->input_dev, ABS_X, x);
		input_report_abs(ts->input_dev, ABS_Y, y);		
		input_report_abs(ts->input_dev, ABS_PRESSURE, z);
		input_report_key(ts->input_dev, BTN_TOUCH, finger);
		input_sync(ts->input_dev);
	}
*/

#ifdef DEBUG_INPUT_REPORT
	if ( finger ^ prev_finger )
	{
		printk("[TSP] x=%d, y=%d\n", x, y );
		prev_finger = finger;
	}
#endif

work_func_out:
	if (ts->use_irq)
	{
		enable_irq(ts->client->irq);
	}
}
int tsp_reset( void )
{
	int ret=1;
#if 0	
	uint8_t i2c_addr = 0x07;
	uint8_t buf[1];
#endif
	struct vreg *vreg_touch;
	printk("[TSP] %s+\n", __func__ );

	vreg_touch = vreg_get(NULL, "ldo6");

	if (ts_global->use_irq)
	{
		disable_irq(ts_global->client->irq);
	}

	ret = vreg_disable(vreg_touch);
	if (ret) {
		printk(KERN_ERR "%s: vreg enable failed (%d)\n",
				__func__, ret);
		ret=-EIO;
		goto tsp_reset_out;
	}

	gpio_configure( TSP_SCL, GPIOF_DRIVE_OUTPUT );
	gpio_configure( TSP_SDA, GPIOF_DRIVE_OUTPUT );
	gpio_configure( TSP_INT, GPIOF_INPUT );
#if 0
	gpio_tlmm_config(GPIO_CFG( TSP_SCL, 0, GPIO_OUTPUT, GPIO_PULL_UP,GPIO_2MA), GPIO_ENABLE);
	gpio_tlmm_config(GPIO_CFG( TSP_SDA, 0, GPIO_OUTPUT, GPIO_PULL_UP,GPIO_2MA), GPIO_ENABLE);
	gpio_tlmm_config(GPIO_CFG( TSP_INT, 0, GPIO_OUTPUT, GPIO_PULL_UP,GPIO_2MA), GPIO_ENABLE);
#endif

	gpio_set_value( TSP_SCL , 0 ); 
	gpio_set_value( TSP_SDA , 0 ); 
	gpio_set_value( TSP_INT , 0 ); 

	msleep( 5 );

	gpio_set_value( TSP_SCL , 1 ); 
	gpio_set_value( TSP_SDA , 1 ); 
	gpio_set_value( TSP_INT , 1 ); 

	ret = vreg_enable(vreg_touch);
	if (ret) {
		printk(KERN_ERR "%s: vreg enable failed (%d)\n",
				__func__, ret);
		ret=-EIO;
		goto tsp_reset_out;
	}

	msleep(10);
#if 0
	while (ts_global->use_irq)
	{
		msleep(10);

		ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));
		if (ret <= 0) {
			printk("[TSP] %d : i2c_transfer failed\n", __LINE__);
		}
		else
		{
			printk("[TSP] %s:%d, ver SW=%x\n", __func__,__LINE__, buf[0] );
			ret=1;
			break;
		}
	}
#endif

tsp_reset_out:
	if (ts_global->use_irq)
	{
		enable_irq(ts_global->client->irq);
	}
	printk("[TSP] %s-\n", __func__ );

	return ret;
}