static void tpd_down(int x, int y, int id) {
    if(tpd_status)
    {
		TPD_DEBUG("tpd_down!\n");
	 if(RECOVERY_BOOT != get_boot_mode())
	   {
		    input_report_key(tpd->dev, BTN_TOUCH, 1);
		    input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 128);
		    input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
		    input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
		    input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, id-1); 
		    input_mt_sync(tpd->dev);
		    tpd_down_state=1;
		    down_x=x;
		    down_y=y;
	     }
	    if (FACTORY_BOOT == get_boot_mode()|| RECOVERY_BOOT == get_boot_mode())
	    {   
	        //tpd_button(x, y, 1); 
		     int i ;
		     for(i=0;i< TPD_KEY_COUNT;i++) 
			{
	            if( (x >= (tpd_keys_dim_local[i][0] - tpd_keys_dim_local[i][2]/2)) && (x <=(tpd_keys_dim_local[i][0]+tpd_keys_dim_local[i][2]/2))
					&&(y >=	(tpd_keys_dim_local[i][1]-tpd_keys_dim_local[i][3]/2)) &&(y <=(tpd_keys_dim_local[i][1]+tpd_keys_dim_local[i][3]/2)) )
	            {
	            	
	            	TPD_DEBUG("tpd down value ==%d \n",tpd_keys_local[i]);
					input_report_key(tpd->dev, tpd_keys_local[i], 1);
				}
		    }  
		}
    }
}
void tpd_resume(struct early_suspend *h) 
{
	TPD_DEBUG("TP tpd_resume\n");
	if (ft5316_i2c_client == NULL)
		return;

	//    if (atomic_read( &g_pts->isp_opened ))
	//	return;

	TPD_DEBUG("[mtk-tpd] Resume++.\n");
	tinno_tp_power_on();
	int err = 0;
    	int i=0;
	for(i=0;i<5;i++){
	   err = tinno_check_focaltech();
	   if(err)
	        break;
	    tinno_tp_power_off();
	    tinno_tp_power_on();
	}
	if (err ==0)
	    TPD_DEBUG("tinno_init_panel ****************************************************power on failed.\n");

	tpd_init_skip = 1;
	tpd_status = 1;
	//Ivan 6573    MT6516_IRQUnmask(MT6516_TOUCH_IRQ_LINE); 
	mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);  
	TPD_DEBUG("[mtk-tpd] Resume--.\n");  
}
static void tpd_up(int x, int y,int *count) {
    if(tpd_status){
	    TPD_DEBUG("tpd_up!\n");
	   if(RECOVERY_BOOT != get_boot_mode())
	   {
		    input_report_key(tpd->dev, BTN_TOUCH, 0);
		    input_mt_sync(tpd->dev);	    
	             tpd_down_state=0;
	             down_x=0;
	             down_y=0;
	   	}
		 if (FACTORY_BOOT == get_boot_mode()|| RECOVERY_BOOT == get_boot_mode())
		{   
		     	 int i ;
			     for(i=0;i< TPD_KEY_COUNT;i++) 
				{
		          if( (x >= (tpd_keys_dim_local[i][0] - tpd_keys_dim_local[i][2]/2)) && (x <=(tpd_keys_dim_local[i][0]+tpd_keys_dim_local[i][2]/2))
					&&(y >=	(tpd_keys_dim_local[i][1]-tpd_keys_dim_local[i][3]/2)) &&(y <=(tpd_keys_dim_local[i][1]+tpd_keys_dim_local[i][3]/2)) )
		            {
		            	TPD_DEBUG("tpd up value ==%d \n",tpd_keys_local[i]);
						input_report_key(tpd->dev, tpd_keys_local[i], 0);
					}
			    }  
		    }  
       }
}
void tpd_button(unsigned int x, unsigned int y, unsigned int down) {
    int i;
    if(down) {
        for(i=0;i<tpd_keycnt;i++) 
		{
            if(x>=tpd_keys_dim[i][0]-(tpd_keys_dim[i][2]/2) &&
               x<=tpd_keys_dim[i][0]+(tpd_keys_dim[i][2]/2) &&
               y>=tpd_keys_dim[i][1]-(tpd_keys_dim[i][3]/2) &&
               y<=tpd_keys_dim[i][1]+(tpd_keys_dim[i][3]/2) &&
               !(tpd->btn_state&(1<<i))) 
            {
                input_report_key(tpd->kpd, tpd_keys[i], 1);
				input_sync(tpd->kpd);
                tpd->btn_state|=(1<<i);
                TPD_DEBUG("[mtk-tpd] press key %d (%d)\n",i, tpd_keys[i]);
				printk("[mtk-tpd] press key %d (%d)\n",i, tpd_keys[i]);
            }
        }
    } else {
        for(i=0;i<tpd_keycnt;i++) {
            if(tpd->btn_state&(1<<i)) {
                input_report_key(tpd->kpd, tpd_keys[i], 0);
				input_sync(tpd->kpd);
                TPD_DEBUG("[mtk-tpd] release key %d (%d)\n",i, tpd_keys[i]);
				printk("[mtk-tpd] release key %d (%d)\n",i, tpd_keys[i]);
            }
        }
        tpd->btn_state=0;
    }
}
Exemple #5
0
int tpd_gettouchinfo(struct touch_info *cinfo) {
	uint8_t status = 0x10;
	uint8_t  address_p1[4] = {0x11,0x00,0x00,0x00};
	uint8_t  address_p2[4] = {0x19,0x00,0x00,0x00};
	uint8_t i;

    sinfo.VirtualKeyFlag = cinfo->VirtualKeyFlag;
	cinfo->TouchpointFlag = 0;
    cinfo->VirtualKeyFlag= 0;
		
	tpd_i2c_master_rs_send(i2c_client,&status,(1<<8)|1);
	cinfo->TouchpointFlag = status&0x03;   //For multi-touch(three point)
	TPD_DEBUG("TouchpointFlag = %x\n",status);

    status = 0x18;
    tpd_i2c_master_rs_send(i2c_client,&status,(1<<8)|1);
    cinfo->VirtualKeyFlag = status&0x0F;
    TPD_DEBUG("VirtualKeyFlag = %x\n",status);
    
	if((cinfo->TouchpointFlag == 0) && ((cinfo->VirtualKeyFlag & 0x03) == 0))
		return 1;  //No touch

	if(cinfo->TouchpointFlag == 0x01) // 1 point
	{
		tpd_i2c_master_rs_send(i2c_client,address_p1,(4<<8)|1);
		cinfo->x[0] =address_p1[1]|((address_p1[0]&0x3)<<8);
		cinfo->y[0]= address_p1[3]|((address_p1[2]&0x3)<<8);
	}
	if(cinfo->TouchpointFlag == 0x02) 
	{
		tpd_i2c_master_rs_send(i2c_client,address_p2,(4<<8)|1);
		cinfo->x[1] =address_p2[1]|((address_p2[0]&0x3)<<8);
		cinfo->y[1]= address_p2[3]|((address_p2[2]&0x3)<<8);
	}
	if(cinfo->TouchpointFlag == 0x03) 
	{

		tpd_i2c_master_rs_send(i2c_client,address_p1,(4<<8)|1);
		tpd_i2c_master_rs_send(i2c_client,address_p2,(4<<8)|1);
		cinfo->x[0] =address_p1[1]|((address_p1[0]&0x3)<<8);
		cinfo->y[0]= address_p1[3]|((address_p1[2]&0x3)<<8);
		cinfo->x[1] =address_p2[1]|((address_p2[0]&0x3)<<8);
		cinfo->y[1]= address_p2[3]|((address_p2[2]&0x3)<<8);

	}

	//if(tpd_debuglog==1) {
		//TPD_DMESG("point data [%d %d %d  %d]\n",cinfo->x[0],cinfo->y[0],cinfo->x[1],cinfo->y[1]);
	//}
	
	TPD_DEBUG("point data [%d %d %d  %d]\n",address_p1[0],address_p1[1],address_p1[2],address_p1[3]);	
	TPD_DEBUG("point data [%d %d %d  %d]\n",cinfo->x[0],cinfo->y[0],cinfo->x[1],cinfo->y[1]);
		
	return 0;	
}
static int touch_event_handler(void *unused) {
    struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
    struct touch_info cinfo, sinfo;
    int pending = 0;
    struct i2c_client * i2c_client  =  ft5316_i2c_client ;
    TPD_DEBUG("touch_event_handler\n");
	
    cinfo.pending=0;
    sched_setscheduler(current, SCHED_RR, &param);
    do {
//Ivan added for testing
		if (tpd_status == 1){
		    mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); // possibly to lose event?
         	 }
	        set_current_state(TASK_INTERRUPTIBLE);
	        if (!kthread_should_stop()) 
		{
	        //    TPD_DEBUG_CHECK_NO_RESPONSE;
	            do {
	                if(pending) wait_event_interruptible_timeout(waiter, tpd_flag!=0, HZ/10);
	                else wait_event_interruptible_timeout(waiter,tpd_flag!=0, HZ*2);
	            } while(0);
	            if(tpd_flag==0 && !pending) continue; // if timeout for no touch, then re-wait.
	            if(tpd_flag!=0 && pending>0)  pending=0;
	            tpd_flag=0;
	            TPD_DEBUG_SET_TIME;
	        }
	        set_current_state(TASK_RUNNING);
	        
	        if(!pending) if(tpd_gettouchinfo(&cinfo, &sinfo)) continue; 
	        if(pending>1) { pending--; continue; }
		//Ivan ++
		if (tpd_init_skip) {tpd_init_skip = 0; continue; }
		TPD_DEBUG("cinfo->count == %d!\n", cinfo.count);
		if(cinfo.count > 0)
		{
			int i;
			for ( i=0; i < cinfo.count; i++ )
			{
				TPD_DEBUG("cinfo->count == %d!\n", cinfo.count);
				TPD_DEBUG("Point ID == %d, x == %d , y == %d ,z ==%d\n!",cinfo.pt[i].id,cinfo.pt[i].x,cinfo.pt[i].y,cinfo.pt[i].z );
				tpd_down(cinfo.pt[i].x, cinfo.pt[i].y, cinfo.pt[i].id);
			}
			input_sync(tpd->dev);
		}
		else
		{
			TPD_DEBUG("TPD up x == %d , y == %d\n!",x_history[cinfo.count], y_history[cinfo.count]);
			tpd_up(x_history[cinfo.count], y_history[cinfo.count], 0);		
			input_sync(tpd->dev);
		}    
    } while (!kthread_should_stop());
    return 0;
}
/* called when loaded into kernel */
static int __init tpd_driver_init(void) {
	TPD_DEBUG("MediaTek FT5316 touch panel driver init\n");
	i2c_register_board_info(TPD_I2C_NUMBER, &ft5316_i2c_tpd, 1);    
	if(tpd_driver_add(&tpd_device_driver) < 0)
	TPD_DMESG("add generic driver failed\n");
	return 0;
}
void tpd_open_gpio(void)
{
    TPD_DEBUG("GT827 open gpio - lenovo..\n");
    
    mt_set_gpio_mode(GPIO70, GPIO_MODE_00);
    mt_set_gpio_dir(GPIO70, GPIO_DIR_OUT);
    mt_set_gpio_out(GPIO70, GPIO_OUT_ONE);
}
void tpd_close_gpio(void)
{
    TPD_DEBUG("GT827 close gpio - lenovo..\n");
    
    mt_set_gpio_mode(GPIO70, GPIO_MODE_00);
    mt_set_gpio_dir(GPIO70, GPIO_DIR_OUT);
    mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO);
}
Exemple #10
0
void tpd_down(int raw_x, int raw_y, int x, int y, int p) {
    input_report_abs(tpd->dev, ABS_PRESSURE, 128);
    input_report_key(tpd->dev, BTN_TOUCH, 1);
    input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 128);
    input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 128);
    input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
    input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
    input_mt_sync(tpd->dev);
    TPD_DEBUG("D[%4d %4d %4d]\n", x, y, p);
    TPD_EM_PRINT(raw_x, raw_y, x, y, p, 1);
}
Exemple #11
0
void tpd_up(int raw_x, int raw_y, int x, int y, int p) {
    //input_report_abs(tpd->dev, ABS_PRESSURE, 0);
    input_report_key(tpd->dev, BTN_TOUCH, 0);
    //input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0);
    //input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 0);
    //input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
    //input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
    input_mt_sync(tpd->dev);
    TPD_DEBUG("U[%4d %4d %4d]\n", x, y, 0);
    TPD_EM_PRINT(raw_x, raw_y, x, y, p, 0);
}
int tpd_local_init(void) 
{
	int i;
	tp_boot_mode = get_boot_mode();
	// Software reset mode will be treated as normal boot
	if(tp_boot_mode==3) tp_boot_mode = NORMAL_BOOT;
	TPD_DEBUG("tpd_local_init boot mode = %d\n",tp_boot_mode);  
	if(i2c_add_driver(&tpd_i2c_driver)!=0)
	    TPD_DEBUG("unable to add i2c driver.\n");

	if(tpd_load_status == 0) 
	{
		TPD_DMESG("ft5206 add error touch panel driver.\n");
		i2c_del_driver(&tpd_i2c_driver);
		return -1;
	}
	
#ifdef TPD_HAVE_BUTTON     
	if (FACTORY_BOOT == tp_boot_mode)
	{
	for (i = 0; i < TPD_KEY_COUNT ; i++)
	    tpd_keys_local[i] = TPD_KEYSFACTORY[i];
	}

	tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data
#endif   
	 
#if (defined(TPD_WARP_START) && defined(TPD_WARP_END))    
	TPD_DO_WARP = 1;
	memcpy(tpd_wb_start, tpd_wb_start_local, TPD_WARP_CNT*4);
	memcpy(tpd_wb_end, tpd_wb_start_local, TPD_WARP_CNT*4);
#endif 

#if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION))
	memcpy(tpd_calmat, tpd_calmat_local, 8*4);
	memcpy(tpd_def_calmat, tpd_def_calmat_local, 8*4);	
#endif  
	TPD_DMESG("end %s, %d\n", __FUNCTION__, __LINE__);  
	tpd_type_cap = 1;	
	return 0;
}
/* platform device functions */
void tpd_suspend(struct early_suspend *h)
{
	TPD_DEBUG("[mtk-tpd] Suspend++.\n");
	if(isUpgrade ==1)
	{
	    TPD_DEBUG("Magnum tp is Upgrading.....\r\n");
		return;
	}
	mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
	if(tpd_down_state){
	    tpd_up(down_x,down_y,NULL);
	//Ivan        input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, 0);
	    input_sync(tpd->dev);
	    msleep(200);
	}
	tpd_status = 0;
	tinno_tp_power_off();
	TPD_DEBUG("[mtk-tpd] Suspend--.tpd_down_state=%d\n",tpd_down_state);
	if (ft5316_i2c_client == NULL)
		return;
}
static int tpd_i2c_remove(struct i2c_client *client) {
	i2c_unregister_device(client);
	TPD_DEBUG("[mtk-tpd] touch panel i2c device is removed.\n");
	input_unregister_device(tpd->dev);
	input_unregister_device(tpd->kpd);

#ifdef CONFIG_TOUCHSCREEN_FT5X05_SUPPORT_ISP
	fts_isp_deregister(ft5316_i2c_client);//misc_deregister(&fts_isp_device);
	
#endif		
	return 0;
}
Exemple #15
0
int tpd_up(int raw_x, int raw_y, int x, int y) {
        input_report_abs(tpd->dev, ABS_PRESSURE, 0);
        input_report_key(tpd->dev, BTN_TOUCH, 0);
        input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0);
        input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
        input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
        TPD_DEBUG("U[%4d %4d %4d] ", x, y, 0);
        input_mt_sync(tpd->dev);
        TPD_UP_DEBUG_TRACK(x,y);
        TPD_EM_PRINT(raw_x, raw_y, x, y, 0, 0);
        return 1;
}
//edit by Magnum 2012-12-17  check ic work state 
//return value :  <0  :  // I2c commiucatie  fail
// 			   = 0 :  // IC has been upgraded fail.
//			   > 0 :  // IC work well.
 int tinno_check_focaltech(void)
{
	char readbyte[2] = {0xA3};
   	char fw_version;
    	int err;

	// Read FW Version.
//	fw_version = i2c_smbus_read_byte_data(ft5316_i2c_client, 0xA6);
	readbyte[0] = 0xA3;
	i2c_master_send(ft5316_i2c_client,&readbyte[0],1);
	err = i2c_master_recv(ft5316_i2c_client, &fw_version, 1);
	TPD_DEBUG("fw_version=0x%X \n", fw_version);
	if(err<0)   // I2c commiucatie  fail
		return err;
	if (fw_version == 0x0a){
		return 1;
	}
	TPD_DEBUG("i2c_smbus_write_byte_data failed.\n");
	 return 0;
	
}
void tpd_down(int raw_x, int raw_y, int x, int y, int p) {
	if(tpd && tpd->dev && tpd_register_flag==1) {
    input_report_abs(tpd->dev, ABS_PRESSURE, p/PRESSURE_FACTOR);
    input_report_key(tpd->dev, BTN_TOUCH, 1);
    input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, p/PRESSURE_FACTOR);
    input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, p/PRESSURE_FACTOR);
    input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
    input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
    input_mt_sync(tpd->dev);
    TPD_DEBUG("D[%4d %4d %4d]\n", x, y, p);
    TPD_EM_PRINT(raw_x, raw_y, x, y, p, 1);
  }  
}
Exemple #18
0
static void tpd_print_version(void) {
    char buffer[10];
    struct i2c_msg msg[2];
      
    buffer[0] = 0x80;
    while (1) {
        i2c_master_send(i2c_rs_client, &buffer[0], (1 << 8 | 1));
        TPD_DEBUG("[mtk-tpd] buffer: %x\n", buffer[0]);
        if (buffer[0] == 0x00) break;
        msleep(10);
    }
        
    buffer[0] = 0x20;
    buffer[1] = 0xE1;
    buffer[2] = 0x08;
    buffer[3] = 0x01;
    buffer[4] = 0x08;
    buffer[5] = 0x00;    
    buffer[6] = 0x00;
    buffer[7] = 0xd0;
    i2c_master_send(i2c_client, buffer, 8);

    msleep(20);
    
    buffer[0] = 0x80;
    while (1) {
        i2c_master_send(i2c_rs_client, &buffer[0], (1 << 8 | 1));
        TPD_DEBUG("[mtk-tpd] buffer: %x\n", buffer[0]);
        if (buffer[0] == 0x00) break;
        msleep(10);
    }
    
    buffer[0] = 0xa0;
    i2c_master_send(i2c_rs_client, &buffer[0], (8 << 8 | 1));
    
    printk("[mtk-tpd] ITE Touch Panel Firmware Version %d.%d Subversion %02x.%02x\n", 
                buffer[0], buffer[1], buffer[2], buffer[3]);  
}
Exemple #19
0
//void tpd_resume(struct i2c_client *client)
static void tpd_resume( struct early_suspend *h )
{   
    int ret = 0;
    unsigned char Wrbuf[2] = {0x14, 0x00};
    
    i2c_client->addr = ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
    ret = i2c_master_send(i2c_client, Wrbuf, 2);
    if(ret != sizeof(Wrbuf))
    {
        TPD_DEBUG("[mtk-tpd] i2c write communcate error during resume: 0x%x\n", ret);
    }
    mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); 
    tpd_halt = 0;
}
void tpd_up(int raw_x, int raw_y, int x, int y, int p) {
	if(tpd && tpd->dev && tpd_register_flag==1) {
    input_report_abs(tpd->dev, ABS_PRESSURE, 0);
    input_report_key(tpd->dev, BTN_TOUCH, 0);
    input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0);
    input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 0);
    input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
    input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
    input_mt_sync(tpd->dev);
    TPD_DEBUG("U[%4d %4d %4d]\n", x, y, 0);
    printk("mtk-tpd:U[%4d %4d %4d]\n", x, y, 0);
    TPD_EM_PRINT(raw_x, raw_y, x, y, p, 0);
  }  
}
// get the report frequent 
int tinno_ts_set_period_active(void)
{
    char readbyte[2] = {0x88};	
	char rdata;
	int ret = 0;
	ret = i2c_smbus_write_byte_data(ft5316_i2c_client, 0x88, 6);/*6X10HZ*/
	readbyte[0] = 0x88;
	i2c_master_send(ft5316_i2c_client,&readbyte[0],1);
	i2c_master_recv(ft5316_i2c_client, &rdata, 1);
	if (rdata < 0) {
		TPD_DEBUG("get period active failed");
		goto err;
	}
	TPD_DEBUG("active period is %d \n", rdata);

	if (ret < 0) {
		TPD_DEBUG("set period active failed");
		goto err;
	}
	return 0;
err:
	return ret;
}
ssize_t tp_write_m_byte(u8 cmd, u8 *writeData,U16 len)
{
//	TPD_DEBUG("tp_write_m_byte!! \n");
    char    write_data[8] = {0};
    int   i, ret=0;
    struct i2c_client * i2c_client = ft5316_i2c_client;
    if(len == 0) {
        TPD_DEBUG("[Error]TP Write Len should not be zero!! \n");
        return 0;
    }
    //Driver does not allow (single write length > 8)
    while(len > 8)
    {
        for (i = 0; i<7; i++){
            write_data[i] = *(writeData+i);    
        }
        ret = i2c_master_send(ft5316_i2c_client, write_data, 8);
        if (ret < 0) {
            TPD_DEBUG("[Error]TP reads data error!! \n");
            return 0;
        }
        writeData+=8;
        len -= 8;
    }
    if (len > 0){
        for (i = 0; i<len; i++){
            write_data[i] = *(writeData+i);    
        }
        ret = i2c_master_send(ft5316_i2c_client, write_data, len);
        if (ret < 0) {
            TPD_DEBUG("[Error]TP reads data error!! \n");
            return 0;
        }
    }

    return 1;
}
//return value:   2013-1-15
// <0  :  // the driver do not match the IC
// = 0 :  // IC has been upgraded fail.
// > 0 :  // IC work well.
//ABC
 int tinno_ts_get_fw_version()
{
	char readbyte[2] = {0xA6};
	char fw_version;
	int err;
	char vendor_id;
	readbyte[0] = 0xA8;
	TPD_DEBUG("ft5316_i2c_client addr ==== %X \n", ft5316_i2c_client->addr);
	 i2c_master_send(ft5316_i2c_client,&readbyte[0],1);
	 err = i2c_master_recv(ft5316_i2c_client, &vendor_id, 1);
	 TPD_DEBUG("++++++++++++Check IC return %d\n",err);
	 if(err<0)   // the driver do not match the IC
		return err;   
	 vendor_version = vendor_id;
	  TPD_DEBUG("Magnum vendor_id=0x%X \n", vendor_id);   
	 if (vendor_id == 0 || vendor_id == 0xa8 ){
	    TPD_DEBUG("i2c_read vendor version failed.\n");
	     return 0;
	  }
	  
	// Read FW Version.
	//	fw_version = i2c_smbus_read_byte_data(ft5316_i2c_client, 0xA6);
	readbyte[0] = 0xA6;
	i2c_master_send(ft5316_i2c_client,&readbyte[0],1);
	err = i2c_master_recv(ft5316_i2c_client, &fw_version, 1);
	if(err<0)   // the driver do not match the IC
		return err;   
	TPD_DEBUG("fw_version=0x%X \n", fw_version);
	panel_version = fw_version;
	if (fw_version == 0 ||fw_version == 0xa6 ){
		TPD_DEBUG("i2c_read panel version failed.\n");
	    return 0;
	}

	TPD_DEBUG("tpd_local_init boot mode = %d \n", tp_boot_mode);    
	return 1;
}
Exemple #24
0
static int touch_event_handler(void *unused)
{
    struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; 
    static int x1, y1, x2, y2, raw_x1, raw_y1, raw_x2, raw_y2;
    int temp_x1 = x1, temp_y1 = y1, temp_raw_x1 = raw_x1, temp_raw_y1 = raw_y1;
    int lastUp_x = 0, lastUp_y = 0;
    char buffer[10];
    int ret = -1, touching, oldtouching;//int pending = 0
    unsigned char Wrbuf[1] = {0};
    
    sched_setscheduler(current, SCHED_RR, &param); 
    do{
        set_current_state(TASK_INTERRUPTIBLE);
        while (tpd_halt) {tpd_flag = 0; msleep(20);}
        wait_event_interruptible(waiter, tpd_flag != 0);
        tpd_flag = 0;
        TPD_DEBUG_SET_TIME;
        set_current_state(TASK_RUNNING); 

        i2c_client->addr = ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
        ret = i2c_master_send(i2c_client, Wrbuf, 1);
        if(ret != sizeof(Wrbuf))
        {
            TPD_DEBUG("[mtk-tpd] i2c write communcate error: 0x%x\n", ret);
            continue;
        }
        i2c_client->addr = ( ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_DMA_FLAG ) | I2C_ENEXT_FLAG;
        ret = tpd_i2c_read(i2c_client, buffer, 7);
        buffer[7] = buffer[8] = buffer[9] = 0;
        if (ret != 7)//sizeof(buffer)
        {
            TPD_DEBUG("[mtk-tpd] i2c read communcate error: 0x%x\n", ret);
            continue;
        }
        i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG;

        touching = buffer[0];
        if(touching > 0) 
        {
            raw_x1 = x1 = ((buffer[3] << 8) | buffer[2]);
            raw_y1 = y1 = ((buffer[5] << 8) | buffer[4]);
        }
        if(touching > 1)
        {
            raw_x2 = x2 = ((buffer[7] << 8) | buffer[6]);
            raw_y2 = y2 = ((buffer[9] << 8) | buffer[8]);
        }
        oldtouching = buffer[1]; 
        TPD_DEBUG("[mtk-tpd]:raw_x1:%d, raw_y1:%d, raw_x2:%d, raw_y2:%d\n", raw_x1, raw_y1, raw_x2, raw_y2);
        TPD_DEBUG("[mtk-tpd]:touch:%d, old_touch:%d\n", touching, oldtouching);
        switch(touching)
        {
        case 0:
            /* touching=0, oldtouching 0 is invalid */
            if(oldtouching > 0)
            {
                //tpd_up(raw_y1, raw_x1, y1, x1, 0);	
                //tpd_up(raw_x1, raw_y1, x1, y1, 0);
                lastUp_x = x1;
                lastUp_y = y1;
            }
            if(oldtouching > 1)
            {
                //tpd_up(raw_y2, raw_x2, y2, x2, 0);	
                //tpd_up(raw_x2, raw_y2, x2, y2, 0);
                //lastUp_x = x1;
                //lastUp_y = y1;
            }
            tpd_up(lastUp_x, lastUp_y, lastUp_x, lastUp_y, 0);
            break;
        case 1:
            tpd_calibrate(&x1, &y1);
            //tpd_down(raw_y1, raw_x1, y1, x1, 1);
            tpd_down(raw_x1, raw_y1, x1, y1, 1);
            if(oldtouching == 2)
            {
                if(abs(x1 - x2) < 2 && abs(y1 - y2) < 2) // need to adjust.
                {
                    //tpd_up(temp_raw_y1, temp_raw_x1, temp_y1, temp_x1, 0);
                    
                    //For ICS
                    //tpd_up(temp_raw_x1, temp_raw_y1, temp_x1, temp_y1, 0);
                }
                else
                {
                    //tpd_up(raw_y2, raw_x2, y2, x2, 0);
                    
                    //For ICS
                    //tpd_up(raw_x2, raw_y2, x2, y2, 0);
                }
            }
            break;
        case 2:
            tpd_calibrate(&x1, &y1);
            //tpd_down(raw_y1, raw_x1, y1, x1, 1);
            tpd_down(raw_x1, raw_y1, x1, y1, 1);
            //tpd_calibrate(&x2, &y2);
            //tpd_down(raw_y2, raw_x2, y2, x2, 1);
            //tpd_down(raw_x2, raw_y2, x2, y2, 1);
            break;
        default:
            TPD_DEBUG("[mtk-tpd] invalid touch num: 0x%x\n", touching);
            continue;
        }
        temp_x1 = x1;
        temp_y1 = y1;      
        temp_raw_x1 = raw_x1;
        temp_raw_y1 = raw_y1;
        input_sync(tpd->dev);
        
    } while (!kthread_should_stop()); 
    return 0;
}
int tpd_ps_operate(void* self, uint32_t command, void* buff_in, int size_in,
		void* buff_out, int size_out, int* actualout)
{
	int err = 0;
	int value;
	
	hwm_sensor_data *sensor_data;
	TPD_DEBUG("[proxi_5206]command = 0x%02X\n", command);		
	switch (command)
	{
		case SENSOR_DELAY:
			if((buff_in == NULL) || (size_in < sizeof(int)))
			{
				APS_ERR("Set delay parameter error!\n");
				err = -EINVAL;
			}
			// Do nothing
			break;

		case SENSOR_ENABLE:
			if((buff_in == NULL) || (size_in < sizeof(int)))
			{
				APS_ERR("Enable sensor parameter error!\n");
				err = -EINVAL;
			}
			else
			{				
				value = *(int *)buff_in;
				if(value)
				{		
					if((tpd_enable_ps(1) != 0))
					{
						APS_ERR("enable ps fail: %d\n", err); 
						return -1;
					}
				}
				else
				{
					if((tpd_enable_ps(0) != 0))
					{
						APS_ERR("disable ps fail: %d\n", err); 
						return -1;
					}
				}
			}
			break;

		case SENSOR_GET_DATA:
			if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
			{
				APS_ERR("get sensor data parameter error!\n");
				err = -EINVAL;
			}
			else
			{
				
				sensor_data = (hwm_sensor_data *)buff_out;				
				
				if((err = tpd_read_ps()))
				{
					err = -1;;
				}
				else
				{
					sensor_data->values[0] = tpd_get_ps_value();
					TPD_PROXIMITY_DBG("huang sensor_data->values[0] 1082 = %d\n", sensor_data->values[0]);
					sensor_data->value_divide = 1;
					sensor_data->status = SENSOR_STATUS_ACCURACY_MEDIUM;
				}	
				
			}
			break;
		default:
			APS_ERR("proxmy sensor operate function no this parameter %d!\n", command);
			err = -1;
			break;
	}
	
	return err;	
}
static int __devexit tpd_remove(struct i2c_client *client) 
{
	TPD_DEBUG("TPD removed\n");
	return 0;
}
static int tpd_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
{
	TPD_DEBUG("tpd_i2c_detect\n");
	strcpy(info->type, "ft5316");
	return 0;
}
static int tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) 
{
	int err = 0;
	TPD_DEBUG("ft5316 tpd_i2c_probe\n");
	if (ft5316_i2c_client != NULL)
	return 1;

	ft5316_i2c_client = client;
	TPD_DEBUG("ft5316_i2c_client addr ==== %X \n", ft5316_i2c_client->addr);
	tinno_tp_power_off();
	tinno_tp_power_on();

	int i = 0;
	while(i++ <5){
		err=tinno_ts_get_fw_version();
		TPD_DEBUG("Product  version ==== %X \n", panel_version);
		if(err > 0)
			break;
		else
			continue;
	}
	if ( err < 0 ){
	    TPD_DEBUG("Product  version %X is invalid.\n", panel_version);
	    goto err_detect_failed;
	}

	tpd_load_status = 1;
	
	  

    /* added in android 2.2, for configuring EINT2 */
    mt_set_gpio_mode(TPIO_EINT, GPIO_CTP_EINT_PIN_M_EINT);
    mt_set_gpio_pull_enable(TPIO_EINT, GPIO_PULL_ENABLE);
    mt_set_gpio_pull_select(TPIO_EINT,GPIO_PULL_UP);
    mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_SENSITIVE);
    mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
    mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_TOUCH_PANEL_POLARITY, tpd_eint_interrupt_handler, 1);    
    mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);

    mutex_init(&tp_mutex);	
#ifdef CONFIG_TOUCHSCREEN_FT5X05_SUPPORT_ISP
	magnum_fts_isp_register(ft5316_i2c_client);

#endif/*CONFIG_TOUCHSCREEN_FT5X05_SUPPORT_ISP*/
    tpd_status = 1;
  thread = kthread_run(touch_event_handler, 0, TPD_DEVICE);
	    if (IS_ERR(thread)) { 
	        err = PTR_ERR(thread);
	        TPD_DEBUG(TPD_DEVICE " failed to create kernel thread: %d\n", err);
    }

    //edit by Magnum 2012-12-25
#ifdef  TP_AUTO_UPGRADE
		focaltech_auto_upgrade();
#endif

    TPD_DEBUG("tpd_i2c_probe OK\n");	
   
    return 0;

err_detect_failed:
    TPD_DEBUG("tpd_i2c_probe ERROR\n");
    ft5316_i2c_client = NULL;
    tinno_tp_power_off();
   return 1;
}
int tinno_ts_parse_data(struct touch_info *cinfo, struct touch_info *sinfo, uint8_t buffer[])
{
	int iInvalidTrackIDs = 0;
	fts_report_data_t report_data = {0};
	tinno_ts_point touch_point[TINNO_TOUCH_TRACK_IDS];
	int iTouchID, i,iKeyCode;

	memset(touch_point, FTS_INVALID_DATA, sizeof(touch_point));
	memcpy(&report_data, buffer, FTS_PROTOCOL_LEN);

	cinfo->count = 0;

	cinfo->pt[0].z = FTS_EF_RESERVED;
	cinfo->pt[1].z = FTS_EF_RESERVED;
	//edit by Magnum 2012-8-6
	cinfo->pt[2].z = FTS_EF_RESERVED;
	cinfo->pt[3].z = FTS_EF_RESERVED;
	cinfo->pt[4].z = FTS_EF_RESERVED;

#ifdef TPD_USE_VIRTUAL_KEY
    if (tp_boot_mode == RECOVERY_BOOT || tp_boot_mode == FACTORY_BOOT)
    {
    	//edit by Magnum 2012-9-20: make only one point in Recovery & Factory mode.
    	if (report_data.fingers > 0 && report_data.fingers < 2 )
		    tpd_dcount = 1;
		else
		    tpd_dcount = 0;
    }
    else
    {
		 tpd_dcount=((report_data.xy_data[0].event_flag  != FTS_EF_RESERVED)?1:0)+
               ((report_data.xy_data[1].event_flag  != FTS_EF_RESERVED)?1:0);	
    }
#else
       tpd_dcount=((report_data.xy_data[0].event_flag  != FTS_EF_RESERVED)?1:0)+
               ((report_data.xy_data[1].event_flag  != FTS_EF_RESERVED)?1:0);
#endif
       if(tpd_dcount){		
		for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){
			if (report_data.xy_data[i].event_flag != FTS_EF_RESERVED) {
				iTouchID = report_data.xy_data[i].touch_id;
				if ( iTouchID >= TINNO_TOUCH_TRACK_IDS )
				{
					TPD_DEBUG("Invalied Track ID(%d)!\n", iTouchID);
					iInvalidTrackIDs++;
					continue;
				}
				cinfo->pt[i].x = report_data.xy_data[i].x_h << 8 | report_data.xy_data[i].x_l;
				cinfo->pt[i].y = report_data.xy_data[i].y_h << 8 | report_data.xy_data[i].y_l;
				cinfo->pt[i].z = report_data.xy_data[i].event_flag;	
				cinfo->pt[i].id = report_data.xy_data[i].touch_id;		
				TPD_DEBUG("iTpuchID ==%d, Point ID == %d, x == %d , y == %d ,z ==%d\n!",iTouchID, cinfo->pt[iTouchID].id,cinfo->pt[iTouchID].x,cinfo->pt[iTouchID].y,cinfo->pt[iTouchID].z );
				cinfo->count++;						//Two fingers touched

				//edit by Magnum 2012-8-31 ctp up question
				x_history[i] = cinfo->pt[iTouchID].x;
               			y_history[i] = cinfo->pt[iTouchID].y;
				
			}
		}
//		cinfo->count = 	i;						//Two fingers touched		
		if ( TINNO_TOUCH_TRACK_IDS == iInvalidTrackIDs ){
			TPD_DEBUG("All points are Invalied, Ignore the interrupt!");
			return 1; 
		}
	}

	if (1==report_data.fingers)
	{
        if (cinfo->pt[0].y > TPD_BUTTON_HEIGHT)
        {
              // cinfo->count = 3;
              inTouchKey = 1;
        } 
		else 
			 inTouchKey = 0;  
     }
    if (0==report_data.fingers)
        cinfo->count = 0 ; //0xFF;		//Release
	    
	return 0;
}
int tpd_gettouchinfo(struct touch_info *cinfo, struct touch_info *sinfo) 
{
	int ret;
	uint8_t start_reg = 0x00;
	char buffer[40];
	//	memset(buffer, 0xFF, 16);
	memset(buffer, 0xFF, FTS_PROTOCOL_LEN);
	TPD_DEBUG("Magnum FTS_PROTOCOL_LEN ===%d\n",FTS_PROTOCOL_LEN);

	mutex_lock(&tp_mutex);

	start_reg = 0x02;
	ret = i2c_master_send(ft5316_i2c_client,&start_reg,1);
	ret = i2c_master_recv(ft5316_i2c_client, &buffer[2], 5);
	
	if (buffer[2] > 1)
	{
	    start_reg = 9;
	    ret = i2c_master_send(ft5316_i2c_client,&start_reg,1);
	    ret = i2c_master_recv(ft5316_i2c_client, &buffer[9], 4);
	} 
	//edit by Magnum 2012-8-6
	if (buffer[9] > 1)
	{
	    start_reg = 0x0f;
	    ret = i2c_master_send(ft5316_i2c_client,&start_reg,1);
	    ret = i2c_master_recv(ft5316_i2c_client, &buffer[15], 4);
	} 
	if (buffer[15] > 1)
	{
	    start_reg = 0x15;
	    ret = i2c_master_send(ft5316_i2c_client,&start_reg,1);
	    ret = i2c_master_recv(ft5316_i2c_client, &buffer[21], 4);
	} 
	if (buffer[21] > 1)
	{
	    start_reg = 0x1b;
	    ret = i2c_master_send(ft5316_i2c_client,&start_reg,1);
	    ret = i2c_master_recv(ft5316_i2c_client, &buffer[27], 4);
	} 
//	ret = i2c_master_recv(i2c_client, &buffer[0],8 );
	//ret = i2c_master_recv(i2c_client, &buffer[8],8 );	
	//ret = i2c_master_recv(i2c_client, &buffer[16],8 );	
	//ret = i2c_master_recv(i2c_client, &buffer[24],8 );	
	//ret = i2c_master_recv(i2c_client, &buffer[32],1 );	
	

	mutex_unlock(&tp_mutex);

	if (ret < 0) {
	    TPD_DEBUG("i2c_transfer failed");
		return 1;							//Error
	}

	TPD_DEBUG("[%x %x %x ]\n",buffer[0],buffer[1],buffer[2]);			
    	int i = 0;int j =3;
	for(i;i<4;i++){
      		 TPD_DEBUG("[%x %x %x %x ]\n",buffer[j],buffer[j+1],buffer[j+2],buffer[j+3],buffer[j+4]);
	   	j = j+6;
	}
				
    	ret = tinno_ts_parse_data(cinfo, sinfo, buffer);
	return ret;
}