static int touch_event_handler(void *para) { int i; tinno_ts_point touch_point[TINNO_TOUCH_TRACK_IDS]; struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; tinno_ts_data *ts = (tinno_ts_data *)para; sched_setscheduler(current, SCHED_RR, ¶m); do { set_current_state(TASK_INTERRUPTIBLE); wait_event_interruptible(waiter, tpd_flag!=0); tpd_flag = 0; memset(touch_point, FTS_INVALID_DATA, sizeof(touch_point)); set_current_state(TASK_RUNNING); //LINE<JIRA_ID><DATE20130320><BUG_INFO>zenghaihui if(g_tp_charger_flag != g_pre_tp_charger_flag) { g_pre_tp_charger_flag = g_tp_charger_flag; g_need_refresh_tp_flag = 1; } if(g_need_refresh_tp_flag) { g_need_refresh_tp_flag = 0; fts_ft5316_switch_charger_status(g_tp_charger_flag); } if (!tpd_touchinfo(ts, &touch_point)) { if(ts->pcount > 0) { for ( i=0; i < ts->pcount; i++ ) { tpd_down(ts, touch_point[i].x, touch_point[i].y, touch_point[i].pressure, touch_point[i].touch_id);//<20120714><for multi-touch id>wangyanhui } input_sync(tpd->dev); } else { tpd_up(ts, touch_point[0].x, touch_point[0].y, touch_point[0].pressure, touch_point[0].touch_id); input_sync(tpd->dev); } } mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); }while(!kthread_should_stop()); mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); return 0; }
//Clear the unfinished touch event, simulate a up event if there this a pen down or move event. void ft6x06_complete_unfinished_event( void ) { int i = 0; for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ if ( test_bit(i, &g_pts->fingers_flag) ){ tpd_up(g_pts, g_pts->touch_point_pre[i].x, g_pts->touch_point_pre[i].y, g_pts->touch_point_pre[i].pressure, i); } } input_sync(tpd->dev); }
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, ¶m); 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; }
/* 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 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, ¶m); 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; }
static int touch_event_handler(void *para) { int i; tinno_ts_point touch_point[TINNO_TOUCH_TRACK_IDS]; struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; tinno_ts_data *ts = (tinno_ts_data *)para; sched_setscheduler(current, SCHED_RR, ¶m); //BEGIN <touch panel> <DATE20130831> <tp proximity> zhangxiaofei #if defined TPD_PROXIMITY int err; hwm_sensor_data sensor_data; u8 proximity_status; u8 state; #endif //END <touch panel> <DATE20130831> <tp proximity> zhangxiaofei do { set_current_state(TASK_INTERRUPTIBLE); wait_event_interruptible(waiter, tpd_flag!=0); tpd_flag = 0; memset(touch_point, FTS_INVALID_DATA, sizeof(touch_point)); set_current_state(TASK_RUNNING); //BEGIN <touch panel> <DATE20130831> <tp proximity> zhangxiaofei #if defined TPD_PROXIMITY if (tpd_proximity_flag == 1) { i2c_smbus_read_i2c_block_data(g_pts->client, TPD_PROXIMITY_ENABLE_REG, 1, &state); TPD_PROXIMITY_DBG("proxi_5206 0xB0 state value is 1131 0x%02X\n", state); if(!(state&0x01)) { tpd_enable_ps(1); } i2c_smbus_read_i2c_block_data(g_pts->client, 0x01, 1, &proximity_status); TPD_PROXIMITY_DBG("proxi_5206 0x01 value is 1139 0x%02X\n", proximity_status); if (proximity_status == TPD_PROXIMITY_CLOSE_VALUE) { tpd_proximity_detect = 0; } else if(proximity_status == TPD_PROXIMITY_FARAWAY_VALUE) { tpd_proximity_detect = 1; } TPD_PROXIMITY_DBG("tpd_proximity_detect 1149 = %d\n", tpd_proximity_detect); if ((err = tpd_read_ps())) { TPD_PROXIMITY_DBG("proxi_5206 read ps data 1156: %d\n", err); } sensor_data.values[0] = tpd_get_ps_value(); sensor_data.value_divide = 1; sensor_data.status = SENSOR_STATUS_ACCURACY_MEDIUM; if ((err = hwmsen_get_interrupt_data(ID_PROXIMITY, &sensor_data))) { TPD_PROXIMITY_DBG(" proxi_5206 call hwmsen_get_interrupt_data failed= %d\n", err); } } #endif //END <touch panel> <DATE20130831> <tp proximity> zhangxiaofei //BEGIN <add changing flag> <DATE20130330> <add changing flag> zhangxiaofei if(g_tp_charger_flag != g_pre_tp_charger_flag){ g_pre_tp_charger_flag = g_tp_charger_flag; fts_ft6x06_switch_charger_status(g_tp_charger_flag); } //END <add changing flag> <DATE20130330> <add changing flag> zhangxiaofei if (!tpd_touchinfo(ts, &touch_point)) { //report muti point then for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ if ( FTS_INVALID_DATA != touch_point[i].x ){ if ( FTS_EF_UP == touch_point[i].flag ){ if( test_bit(i, &ts->fingers_flag) ){ tpd_up(ts, ts->touch_point_pre[i].x, ts->touch_point_pre[i].y, touch_point[i].pressure, i); }else{ CTP_DBG("This is a invalid up event.(%d)", i); } }else{//FTS_EF_CONTACT or FTS_EF_DOWN if ( test_bit(i, &ts->fingers_flag) && (FTS_EF_DOWN == touch_point[i].flag) ){ CTP_DBG("Ignore a invalid down event.(%d)", i); continue; } tpd_down(ts, touch_point[i].x, touch_point[i].y, touch_point[i].pressure, i); } }else if ( test_bit(i, &ts->fingers_flag) ){ CTP_DBG("Complete a invalid down or move event.(%d)", i); tpd_up(ts, ts->touch_point_pre[i].x, ts->touch_point_pre[i].y, touch_point[i].pressure, i); } } input_sync(tpd->dev); } mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); }while(!kthread_should_stop()); mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); return 0; }
static int touch_event_handler(void *unused) { struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; int x1=0, y1=0, x2=0, y2=0, x3=0, y3=0, x4=0, y4=0, p1=0, p2=0, p3=0, p4=0, id1=0xf, id2=0xf, id3=0xf, id4 = 0xf, pre_id1 = 0xf, pre_id2 = 0xf, pre_id3 = 0xf, pre_id4 = 0xf, pre_tt_mode = 0, finger_num = 0, pre_num = 0; int raw_x1=0, raw_y1=0, raw_x2=0, raw_y2=0, raw_x3=0, raw_y3=0, raw_x4=0, raw_y4=0; static char toggle; static char buffer[32];//[16]; // int pending = 0; u32 temp; sched_setscheduler(current, SCHED_RR, ¶m); g_temptimerdiff=get_jiffies_64();//jiffies; do { if(tpd_debuglog==1) { TPD_DMESG("[mtk-tpd] %s\n", __FUNCTION__); } set_current_state(TASK_INTERRUPTIBLE); if(tpd_debuglog==1) TPD_DMESG("[mtk-tpd], %s, tpd_halt=%d\n", __FUNCTION__, tpd_halt); while (tpd_halt) {tpd_flag = 0; msleep(20);} #ifndef POLL_MODE wait_event_interruptible(waiter, tpd_flag != 0); tpd_flag = 0; #endif TPD_DEBUG_SET_TIME; set_current_state(TASK_RUNNING); // #ifndef CY8CTMA300_CHARGE #if 0 temp = *(volatile u32 *)CHR_CON0; temp &= (1<<13); if(temp!=0) { if(tpd_debuglog==1) TPD_DMESG("[mtk-tpd], write 0x01 to 0x1D register!!\n"); buffer[0] = 0x01; buffer[0] = 0x01; i2c_smbus_write_i2c_block_data(i2c_client, 0x1D, 1, &(buffer[0])); } else { if(tpd_debuglog==1) TPD_DMESG("[mtk-tpd], write 0x00 to 0x1D register!!\n"); buffer[0] = 0x00; i2c_smbus_write_i2c_block_data(i2c_client, 0x1D, 1, &(buffer[0])); } #endif #ifndef TPD_NO_GPIO // for mt6575T fpga early porting if (tpd_show_version) { tpd_show_version = 0; mt_set_gpio_mode(GPIO1, 0x00); mt_set_gpio_dir(GPIO1, GPIO_DIR_OUT); mt_set_gpio_pull_enable(GPIO1, GPIO_PULL_ENABLE); mt_set_gpio_pull_select(GPIO1, GPIO_PULL_UP); mt_set_gpio_out(GPIO1, GPIO_OUT_ZERO); msleep(100); buffer[0] = 0x01; // reset touch panel mode i2c_smbus_write_i2c_block_data(i2c_client, 0x00, 1, &(buffer[0])); msleep(200); buffer[0] = 0x10; // swith to system information mode i2c_smbus_write_i2c_block_data(i2c_client, 0x00, 1, &(buffer[0])); msleep(200); i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 8, &(buffer[0x0])); i2c_smbus_read_i2c_block_data(i2c_client, 0x08, 8, &(buffer[0x8])); i2c_smbus_read_i2c_block_data(i2c_client, 0x10, 8, &(buffer[0x10])); i2c_smbus_read_i2c_block_data(i2c_client, 0x18, 8, &(buffer[0x18])); printk("[mtk-tpd] Cypress Touch Panel ID %x.%x\n", buffer[0x07], buffer[0x08]); printk("[mtk-tpd] Cypress Touch Panel Firmware Version %x.%x\n", buffer[0x15], buffer[0x16]); buffer[0] = 0x04; // switch to operation mode i2c_smbus_write_i2c_block_data(i2c_client, 0x00, 1, &(buffer[0])); msleep(200); mt_set_gpio_out(GPIO1, GPIO_OUT_ONE); mt_set_gpio_mode(GPIO1, 0x01); mt_set_gpio_pull_enable(GPIO1, GPIO_PULL_ENABLE); mt_set_gpio_pull_select(GPIO1, GPIO_PULL_UP); continue; } #endif i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 8, &(buffer[0])); i2c_smbus_read_i2c_block_data(i2c_client, 0x08, 8, &(buffer[8])); i2c_smbus_read_i2c_block_data(i2c_client, 0x10, 8, &(buffer[16])); i2c_smbus_read_i2c_block_data(i2c_client, 0x18, 8, &(buffer[24])); if(tpd_debuglog==1) { TPD_DMESG("[mtk-tpd]HST_MODE : %x\n", buffer[0]); TPD_DMESG("[mtk-tpd]TT_MODE : %x\n", buffer[1]); TPD_DMESG("[mtk-tpd]TT_STAT : %x\n", buffer[2]); // TPD_DEBUG("[mtk-tpd]TOUCH_ID : %x\n", buffer[8]); TPD_DMESG("[mtk-tpd]TOUCH_12ID : %x\n", buffer[8]); TPD_DMESG("[mtk-tpd]TOUCH_34ID : %x\n", buffer[21]); } finger_num = buffer[2] & 0x0f; if (finger_num == 0 && pre_num ==0) { msleep(10); tpd_flag = 0; pre_tt_mode = buffer[1]; continue; } if (pre_tt_mode == buffer[1]) { msleep(5); tpd_flag = 0; pre_tt_mode = buffer[1]; continue; } if (buffer[1] & 0x20) { TPD_DEBUG("buffer not ready\n"); tpd_flag = 0; pre_tt_mode = buffer[1]; continue; // buffer is not ready for use } id1 = (buffer[8] & 0xf0) >> 4; id2 = (buffer[8] & 0x0f); id3 = (buffer[21] & 0xf0) >> 4; id4 = (buffer[21] & 0x0f); // if (id1 != 0xf) { if(finger_num>=1) { x1 = (((int)buffer[3]) << 8) + buffer[4]; y1 = (((int)buffer[5]) << 8) + buffer[6]; if(x1>2048 || y1>2048) { tpd_flag = 0; pre_tt_mode = buffer[1]; continue; } p1 = buffer[7]; raw_x1 = x1; raw_y1 = y1; tpd_calibrate(&x1, &y1); tpd_down(raw_x1, raw_y1, x1, y1, p1); if(counter_pointer==0) g_temptimerdiff=get_jiffies_64();//jiffies; if(x_min==0&&y_min==0&&x_max==0&&y_max==0) { x_min = x1; y_min = y1; x_max = x1; y_max = y1; } if(x1<x_min) x_min = x1; if(x1>x_max) x_max = x1; if(y1<y_min) y_min = y1; if(y1>y_max) y_max = y1; counter_pointer++; if (time_after(jiffies, g_temptimerdiff + 100)){ //1s TPD_DMESG("[mtk-tpd], x_min=%d, y_min=%d, x_max=%d, y_max=%d, counter_pointer=%d!!\n", x_min, y_min, x_max, y_max, counter_pointer); x_min=0; y_min=0; x_max=0; y_max=0; counter_pointer=0; } } // if (id2 != 0xf || finger_num==2) { if(finger_num>=2) { x2 = (((int)buffer[9]) << 8) + buffer[10]; y2 = (((int)buffer[11]) << 8) + buffer[12]; p2 = buffer[13]; raw_x2 = x2; raw_y2 = y2; tpd_calibrate(&x2, &y2); tpd_down(raw_x2, raw_y2, x2, y2, p2); } // if(id3 != 0xf || finger_num==3) { if(finger_num>=3) { x3 = (((int)buffer[16]) << 8) + buffer[17]; y3= (((int)buffer[18]) << 8) + buffer[19]; p3= buffer[20]; raw_x3 = x3; raw_y3 = y3; tpd_calibrate(&x3, &y3); tpd_down(raw_x3, raw_y3, x3, y3, p3); } // if(id4 != 0xf || finger_num==4) { if(finger_num>=4) { x4 = (((int)buffer[22]) << 8) + buffer[23]; y4= (((int)buffer[24]) << 8) + buffer[25]; p4= buffer[26]; raw_x4 = x4; raw_y4 = y4; tpd_calibrate(&x4, &y4); tpd_down(raw_x4, raw_y4, x4, y4, p4); } if(pre_num>=1 && pre_id1==0xf) { if(finger_num>=1 && id1==0xf) { if(tpd_debuglog==1) TPD_DMESG("finger1 is still down!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger1 is up!!\n"); tpd_up(raw_x1, raw_y1, x1, y1, p1); } } else if(pre_num>=1 && pre_id1 !=0xf) { if(id1==pre_id1) { if(tpd_debuglog==1) TPD_DMESG("finger1 is still down!!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger1 is up!\n"); tpd_up(raw_x1, raw_y1, x1, y1, p1); } } if(pre_num>=2 && pre_id2==0xf) { if((finger_num>=2 && id2==0xf) || (finger_num==1 && id1==0xf)) { if(tpd_debuglog==1) TPD_DMESG("finger2 is still down!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger2 is up!!\n"); tpd_up(raw_x2, raw_y2, x2, y2, p2); } } else if(pre_num>=2 && pre_id2 !=0xf) { if(id2==pre_id2 || id1==pre_id2) { if(tpd_debuglog==1) TPD_DMESG("finger2 is still down!!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger2 is up!\n"); tpd_up(raw_x2, raw_y2, x2, y2, p2); } } if(pre_num>=3 && pre_id3==0xf) { if((finger_num>=3 && id3==0xf) || (finger_num==2 && id2==0xf) || (finger_num==1 && id1==0xf)) { if(tpd_debuglog==1) TPD_DMESG("finger3 is still down!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger3 is up!!\n"); tpd_up(raw_x3, raw_y3, x3, y3, p3); } } else if(pre_num>=3 && pre_id3 !=0xf) { if(id3==pre_id3 || id2==pre_id3 || id1==pre_id3) { if(tpd_debuglog==1) TPD_DMESG("finger3 is still down!!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger3 is up!\n"); tpd_up(raw_x3, raw_y3, x3, y3, p3); } } if(pre_num==4 && pre_id4==0xf) { if((finger_num>=4 && id4==0xf) || (finger_num==3 && id3==0xf) || (finger_num==2 && id2==0xf) || (finger_num==1 && id1==0xf)) { if(tpd_debuglog==1) TPD_DMESG("finger4 is still down!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger4 is up!!\n"); tpd_up(raw_x4, raw_y4, x4, y4, p4); } } else if(pre_num==4 && pre_id4 !=0xf) { if(id4==pre_id4 || id3==pre_id4 || id2==pre_id4 || id1==pre_id4) { if(tpd_debuglog==1) TPD_DMESG("finger4 is still down!!\n"); } else { if(tpd_debuglog==1) TPD_DMESG("finger4 is up!\n"); tpd_up(raw_x4, raw_y4, x4, y4, p4); } } if(tpd_debuglog==1) TPD_DMESG("pre_id1=%d, pre_id2=%d, pre_id3=%d, pre_id4=%d, id1=%d, id2=%d, id3=%d, id4=%d\n", pre_id1, pre_id2, pre_id3, pre_id4, id1, id2, id3, id4); pre_id1 = id1; pre_id2 = id2; pre_id3 = id3; pre_id4 = id4; pre_tt_mode = buffer[1]; pre_num = finger_num; if(tpd && tpd->dev && tpd_register_flag==1) { input_sync(tpd->dev); } i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 1, &toggle); if((toggle & 0x80) == 0) toggle = toggle | 0x80; else toggle = toggle & (~0x80); i2c_smbus_write_i2c_block_data(i2c_client, 0x00, 1, &toggle); // switch the read toggle bit to do next sampling tpd_flag = 0; #ifndef POLL_MODE } while (!kthread_should_stop()); #else }while(1);
static int tpd_touchinfo(tinno_ts_data *ts, tinno_ts_point *touch_point) { int i = 0; int iInvalidTrackIDs = 0; int iTouchID, iSearchDeep; fts_report_data_t *pReportData = (fts_report_data_t *)ts->buffer; int ret; uint8_t start_reg = 0x00; #if 1 if ( tpd_read_touchinfo(ts) ){ CTP_DBG("Read touch information error. \n"); return -EAGAIN; } #else memset((void *)ts->buffer, FTS_INVALID_DATA, FTS_PROTOCOL_LEN); mutex_lock(&g_pts->mutex); start_reg = 0x02; ret = i2c_master_send(ts->client, &start_reg,1); ret = i2c_master_recv(ts->client, &ts->buffer[2], 5); if (ts->buffer[2] > 1) { start_reg = 9; ret = i2c_master_send(ts->client,&start_reg,1); ret = i2c_master_recv(ts->client, &ts->buffer[9], 4); } //edit by Magnum 2012-8-6 if (ts->buffer[9] > 1) { start_reg = 0x0f; ret = i2c_master_send(ts->client,&start_reg,1); ret = i2c_master_recv(ts->client, &ts->buffer[15], 4); } if (ts->buffer[15] > 1) { start_reg = 0x15; ret = i2c_master_send(ts->client,&start_reg,1); ret = i2c_master_recv(ts->client, &ts->buffer[21], 4); } if (ts->buffer[21] > 1) { start_reg = 0x1b; ret = i2c_master_send(ts->client,&start_reg,1); ret = i2c_master_recv(ts->client, &ts->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(&g_pts->mutex); if (ret < 0) { TPD_DEBUG("i2c_transfer failed"); return 1; //Error } #endif // tpd_dump_touchinfo( ts ); if ( 0 != pReportData->device_mode ){ CTP_DBG("device mode is %d\n", pReportData->device_mode); return -EPERM; } //We need only valid points... if ( pReportData->fingers > TINNO_TOUCH_TRACK_IDS ){ CTP_DBG("fingers is %d\n", pReportData->fingers); return -EAGAIN; } // For processing gestures. if (pReportData->gesture >= 0xF0 && pReportData->gesture <= 0xF3) { //fts_5x06_parase_keys(ts, pReportData); } iSearchDeep = 0; #ifdef FTS_SUPPORT_TRACK_ID for ( i = 0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ iSearchDeep += ((pReportData->xy_data[i].event_flag != FTS_EF_RESERVED)?1:0); } #else if (pReportData->fingers >= ts->last_fingers ){ iSearchDeep = pReportData->fingers; }else{ iSearchDeep = ts->last_fingers; } ts->last_fingers = pReportData->fingers; #endif if ( iSearchDeep ) { #ifdef FTS_SUPPORT_TRACK_ID for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ #else for ( i=0; i < iSearchDeep; i++ ){ #endif if (pReportData->xy_data[i].event_flag != FTS_EF_RESERVED) { #ifdef FTS_SUPPORT_TRACK_ID iTouchID = pReportData->xy_data[i].touch_id; if ( iTouchID >= TINNO_TOUCH_TRACK_IDS ) { CTP_DBG("i: Invalied Track ID(%d)\n!", i, iTouchID); iInvalidTrackIDs++; continue; } #else iTouchID = i; #endif touch_point[iTouchID].flag = pReportData->xy_data[i].event_flag; touch_point[iTouchID].x = pReportData->xy_data[i].x_h << 8 | pReportData->xy_data[i].x_l; touch_point[iTouchID].y = pReportData->xy_data[i].y_h << 8 | pReportData->xy_data[i].y_l; touch_point[iTouchID].pressure = pReportData->xy_data[i].pressure; #ifdef TPD_FIRST_FIRWARE ft_map_coordinate(&(touch_point[iTouchID].x), &(touch_point[iTouchID].y)); #endif }else{ //CTP_DBG("We got a invalied point, we take it the same as a up event!"); //CTP_DBG("As it has no valid track ID, we assume it's order is the same as it's layout in the memory!"); //touch_point[i].flag = FTS_EF_RESERVED; } } if ( TINNO_TOUCH_TRACK_IDS == iInvalidTrackIDs ){ CTP_DBG("All points are Invalied, Ignore the interrupt!\n"); return -EAGAIN; } } CTP_DBG("p0_flag=0x%x x0=0x%03x y0=0x%03x pressure0=0x%03x " "p1_flag=0x%x x1=0x%03x y1=0x%03x pressure1=0x%03x " "gesture = 0x%x fingers=0x%x", touch_point[0].flag, touch_point[0].x, touch_point[0].y, touch_point[0].pressure, touch_point[1].flag, touch_point[1].x, touch_point[1].y, touch_point[1].pressure, pReportData->gesture, pReportData->fingers); return 0; }; static int touch_event_handler(void *para) { int i; tinno_ts_point touch_point[TINNO_TOUCH_TRACK_IDS]; struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; tinno_ts_data *ts = (tinno_ts_data *)para; sched_setscheduler(current, SCHED_RR, ¶m); do { set_current_state(TASK_INTERRUPTIBLE); wait_event_interruptible(waiter, tpd_flag!=0); tpd_flag = 0; memset(touch_point, FTS_INVALID_DATA, sizeof(touch_point)); set_current_state(TASK_RUNNING); if (!tpd_touchinfo(ts, &touch_point)) { //report muti point then for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ if ( FTS_INVALID_DATA != touch_point[i].x ){ if ( FTS_EF_UP == touch_point[i].flag ){ if( test_bit(i, &ts->fingers_flag) ){ tpd_up(ts, ts->touch_point_pre[i].x, ts->touch_point_pre[i].y, touch_point[i].pressure, i); }else{ CTP_DBG("This is a invalid up event.(%d)", i); } }else{//FTS_EF_CONTACT or FTS_EF_DOWN if ( test_bit(i, &ts->fingers_flag) && (FTS_EF_DOWN == touch_point[i].flag) ){ CTP_DBG("Ignore a invalid down event.(%d)", i); continue; } tpd_down(ts, touch_point[i].x, touch_point[i].y, touch_point[i].pressure, i); } }else if ( test_bit(i, &ts->fingers_flag) ){ CTP_DBG("Complete a invalid down or move event.(%d)", i); tpd_up(ts, ts->touch_point_pre[i].x, ts->touch_point_pre[i].y, touch_point[i].pressure, i); } } input_sync(tpd->dev); } mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); }while(!kthread_should_stop()); mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); return 0; }
static int touch_event_handler(void *unused) { struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; char index; char buffer[14]; int i, pre_touch1 = 0, pre_touch2 = 0, touch = 0, finger_num = 0; int x1, y1, p1, x2, y2, p2, raw_x1, raw_y1, raw_x2, raw_y2; struct i2c_msg msg[2]; sched_setscheduler(current, SCHED_RR, ¶m); do { MT6516_EINTIRQUnmask(CUST_EINT_TOUCH_PANEL_NUM); // possibly to lose event? set_current_state(TASK_INTERRUPTIBLE); if (!kthread_should_stop()) { while (tpd_halt) {tpd_flag=0; msleep(20);} if (pre_touch1 || pre_touch2) wait_event_interruptible_timeout(waiter, tpd_flag!=0, HZ/8); else wait_event_interruptible_timeout(waiter, tpd_flag!=0, HZ*2); TPD_DEBUG_SET_TIME; } set_current_state(TASK_RUNNING); if (tpd_calibrate_en | tpd_show_version) { mt_set_gpio_mode(GPIO61, 0x00); mt_set_gpio_pull_enable(GPIO61, GPIO_PULL_ENABLE); mt_set_gpio_pull_select(GPIO61,GPIO_PULL_UP); mt_set_gpio_dir(GPIO61, GPIO_DIR_OUT); mt_set_gpio_out(GPIO61, GPIO_OUT_ZERO); hwPowerDown(TPD_POWER_SOURCE,"TP"); hwPowerOn(TPD_POWER_SOURCE,VOL_3300,"TP"); msleep(20); if (tpd_calibrate_en) { tpd_do_calibrate(); tpd_calibrate_en = 0; } else { tpd_print_version(); tpd_show_version = 0; } /* added in android 2.2, for configuring EINT2 to EINT mode */ mt_set_gpio_mode(GPIO61, 0x01); mt_set_gpio_pull_enable(GPIO61, GPIO_PULL_ENABLE); mt_set_gpio_pull_select(GPIO61,GPIO_PULL_UP); continue; } if (!tpd_flag) { if (pre_touch1==1) { tpd_up(raw_x1, raw_y1, x1,y1,p1); pre_touch1 = 0; } if (pre_touch2==1) { tpd_up(raw_x2, raw_y2, x2,y2,p2); pre_touch2 = 0; } input_sync(tpd->dev); continue; } else { tpd_flag = 0; } buffer[0] = 0x80; i2c_master_send(i2c_rs_client, &buffer[0], (1 << 8 | 1)); touch = (buffer[0] & 0x08) >> 3; // finger up or finger down //printk("buffer[0] = %d\n", buffer[0]); if (buffer[0]&0x80) { buffer[6] = 0xc0; i2c_master_send(i2c_rs_client, &buffer[6], (8 << 8 | 1)); buffer[0] = 0xe0; i2c_master_send(i2c_rs_client, &buffer[0], (6 << 8 | 1)); if (finger_num == 0x03 && buffer[0] == 0x00) { TPD_DEBUG("[mtk-tpd] firmware bug. hold one finger, hold another finger, and then tap the first finger, it will happen.\n"); continue; } if ((buffer[0] & 0xF0)) { TPD_DEBUG("[mtk-tpd] this is not a position information\n"); continue; } if (buffer[1] == 0x01) { TPD_DEBUG("[mtk-tpd] fat touch detect\n"); continue; } finger_num = buffer[0]&0x07; if (finger_num&1) { x1 = buffer[2]+((buffer[3]&0x0f)<<8); y1 = buffer[4]+((buffer[3]&0xf0)<<4); p1 = buffer[5]&0x0f; raw_x1 = x1; raw_y1 = y1; tpd_calibrate(&x1, &y1); tpd_down(raw_x1, raw_y1, x1, y1, p1); pre_touch1=1; } else { if (pre_touch1!=0) { tpd_up(raw_x1, raw_y1, x1, y1, p1); pre_touch1 = 0; } } if (finger_num&2) { x2 = buffer[6]+((buffer[7]&0x0f)<<8); y2 = buffer[8]+((buffer[7]&0xf0)<<4); p2 = buffer[9]&0x0f; raw_x2 = x2; raw_y2 = y2; tpd_calibrate(&x2, &y2); tpd_down(raw_x2, raw_y2, x2, y2, p2); pre_touch2=1; } else { if (pre_touch2!=0) { tpd_up(raw_x2, raw_y2, x2, y2, p2); pre_touch2 = 0; } } input_sync(tpd->dev); } else { msleep(10); } } while (!kthread_should_stop()); return 0; }
static int touch_event_handler(void *unused) { struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; static int x1, y1, raw_x1, raw_y1; int temp_x1, temp_y1, temp_raw_x1, temp_raw_y1, temp_touch_dir, temp_contact_id; int report_id, touch_valid, contact_id, touch_dir, touch_need_sync; char buffer[10]; int ret = -1; sched_setscheduler(current, SCHED_RR, ¶m); 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); TPD_DEBUG("[mtk-tpd] touch interrupt\n"); touch_need_sync = 0; temp_x1 = 0xFFFFFFFF; temp_y1 = 0xFFFFFFFF; temp_raw_x1 = 0xFFFFFFFF; temp_raw_y1 = 0xFFFFFFFF; temp_touch_dir = 0xFFFFFFFF; temp_contact_id = 0xFFFFFFFF; do { i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG | I2C_DMA_FLAG | I2C_ENEXT_FLAG; ret = tpd_i2c_read(i2c_client, buffer, 10); if (ret != sizeof(buffer)) { TPD_DEBUG("[mtk-tpd] i2c read communcate error: 0x%x\n", ret); continue; } i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG; report_id = buffer[0]; if (0x4 == report_id) { touch_valid = buffer[1]>>7; if (touch_valid) { contact_id = (buffer[1]&0x7C)>>2; touch_dir = buffer[1]&0x1; raw_x1 = x1 = ((buffer[3] << 8) | buffer[2]); raw_y1 = y1 = ((buffer[5] << 8) | buffer[4]); TPD_DEBUG("[mtk-tpd]:id:%d, raw_x1:%d, raw_y1:%d\n", contact_id, raw_x1, raw_y1); tpd_calibrate(&x1, &y1); if (((temp_x1 != x1) || (temp_y1 != y1) || (temp_contact_id != contact_id)) && (0xFFFFFFFF != temp_x1) && (0xFFFFFFFF != temp_y1)) { touch_need_sync = 1; if (temp_touch_dir) { tpd_down(temp_raw_y1, temp_raw_x1, temp_y1, temp_x1, 1); } else { tpd_up(temp_raw_y1, temp_raw_x1, temp_y1, temp_x1, 0); } } temp_x1 = x1; temp_y1 = y1; temp_raw_x1 = raw_x1; temp_raw_y1 = raw_y1; temp_touch_dir = touch_dir; temp_contact_id = contact_id; } else { TPD_DEBUG("[mtk-tpd]:Touch Invalid\n"); } } else { TPD_DEBUG("[mtk-tpd]:Invalid report ID:%d\n", buffer); } }while(!mt_get_gpio_in(GPIO_CTP_EINT_PIN));
static int touch_event_handler(void *unused) { struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; int i = 0,x1=0, y1=0, finger_num = 0; char buffer[32];//[16]; u32 temp; sched_setscheduler(current, SCHED_RR, ¶m); g_temptimerdiff=get_jiffies_64();//jiffies; do { if(tpd_debuglog==1) { TPD_DMESG("[mtk-tpd] %s\n", __FUNCTION__); } set_current_state(TASK_INTERRUPTIBLE); if(tpd_debuglog==1) TPD_DMESG("[mtk-tpd], %s, tpd_halt=%d\n", __FUNCTION__, tpd_halt); 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_smbus_read_i2c_block_data(i2c_client, 0x00, 8, &(buffer[0])); i2c_smbus_read_i2c_block_data(i2c_client, 0x08, 8, &(buffer[8])); i2c_smbus_read_i2c_block_data(i2c_client, 0x10, 8, &(buffer[16])); i2c_smbus_read_i2c_block_data(i2c_client, 0x18, 8, &(buffer[24])); if((buffer[1]&0x01) != (buffer[30]&0x01)) { i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 8, &(buffer[0])); i2c_smbus_read_i2c_block_data(i2c_client, 0x08, 8, &(buffer[8])); i2c_smbus_read_i2c_block_data(i2c_client, 0x10, 8, &(buffer[16])); i2c_smbus_read_i2c_block_data(i2c_client, 0x18, 8, &(buffer[24])); } if((buffer[1]&0xf0) != 0x10) { buffer[0] = 0x00; buffer[1] = 0x03; i2c_master_send(i2c_client,buffer,2); msleep(50); buffer[0] = 0x00; buffer[1] = 0x05; i2c_master_send(i2c_client,buffer,2); //status = i2c_master_recv(i2c_client, buffer, 3); msleep(50); buffer[0] = 0x00; buffer[1] = 0x21; buffer[2] = 0x07; buffer[3] = 0x01; buffer[4] = 0x00; i2c_master_send(i2c_client,buffer,5); msleep(50); continue; } if(tpd_debuglog==1) { TPD_DMESG("[mtk-tpd]HST_MODE : %x\n", buffer[0]); TPD_DMESG("[mtk-tpd]TT_MODE : %x\n", buffer[1]); TPD_DMESG("[mtk-tpd]TT_STAT : %x\n", buffer[2]); // TPD_DEBUG("[mtk-tpd]TOUCH_ID : %x\n", buffer[8]); TPD_DMESG("[mtk-tpd]TOUCH_12ID : %x\n", buffer[8]); TPD_DMESG("[mtk-tpd]TOUCH_34ID : %x\n", buffer[21]); } finger_num = 0; for(i = 0; i < 7;i++) { x1 = buffer[4*i + 2] | ((buffer[4*i+4]&0x0f) << 8) ; y1 = buffer[4*i + 3] | ((buffer[4*i+4]&0xf0) << 4) ; if(x1 != 0xfff){ tpd_down(x1, y1, x1, y1, 100); finger_num++; //printk("-----x:%d,y:%d-------down\n",x1,y1); } } //printk("-----finger_num = %d-------\n",finger_num); if(finger_num > 0) input_sync(tpd->dev); else { //printk("-----x:%d,y:%d-------up\n",x1,y1); tpd_up(x1, y1, x1, y1, 0); //input_mt_sync(tpd->dev); input_sync(tpd->dev); } tpd_flag = 0; } while (!kthread_should_stop()); return 0; }
/* handle touch panel interrupt for down / up event */ void tpd_tasklet(unsigned long unused) { static int x1,y1,p1;//,d1,round=0; int cx=0, cy=0, cp=0, cd=0; /* current point */ int fx=0, fy=0, fp=0, fd=0; /* foresee point */ int ni=0, i =0; /* index */ static int lx=0, ly=0; /* latest point */ static int px=0, py=0; static struct touch_info buf_kp[3]; static int buf_p=1, buf_c=2, buf_f=0, down = 0; int dx; TPD_DEBUG_SET_TIME; if (tpd_em_debounce_time != 0) { tpd_set_debounce_time(tpd_em_debounce_time); tpd_em_debounce_time = 0; } //struct timeval tv; //long t1, t2; //do_gettimeofday(&tv); //t1 = tv.tv_sec*1000000l+tv.tv_usec; //tpd_sampling(&cx, &cy, &cp, &cd); //tpd_calibrate(&cx, &cy); //printk("c [%5d %5d %5d %5d]\n", cx, cy, cp, cd); //mod_timer(&(tpd->timer),jiffies+TPD_DELAY); //return; tpd_sampling(&cx, &cy, &cp, &cd); tpd_calibrate(&cx, &cy); /* ============= boundary condition ============*/ if(cx<0) cx=0; if(cy<0) cy=0; if(cx>TPD_RES_X) cx=TPD_RES_X; #if defined(TPD_HAVE_BUTTON) || defined(TPD_HAVE_VIRTUAL_KEY) if(cy>TPD_RES_Y && cy<TPD_BUTTON_HEIGHT) cp=TPD_PRESSURE_MAX+1,cd=0; #else if(cy>TPD_RES_Y) cy=TPD_RES_Y; #endif if(tpd_mode==TPD_MODE_KEYPAD && ((cd==0 && down==1) || (tpd_mode_axis==0 && cy>=tpd_mode_min && cy<=tpd_mode_max) || (tpd_mode_axis==1 && cx>=tpd_mode_min && cx<=tpd_mode_max))) { /* this segment of code should be refactorized with following drift elimination */ #ifdef TPD_HAVE_DRIFT_ELIMINATION /* drift elimination */ if(buf.count==0 || (cp>=TPD_PRESSURE_NICE && cd)) { TPD_DEBUG("drift eliminated (0) or Pressure filtering\n"); #ifdef TPD_HAVE_ADV_DRIFT_ELIMINATION } else if (buf.count==1 && cp>TPD_ADE_P1) { TPD_DEBUG("drift eliminated (1)\n"); } else if (buf.count==1) { /* queue first good point, discard it if 2nd pt is bad */ TPD_BUF_QUEUE(cx,cy,cd,cp); } else if (buf.count==2 && cp>TPD_ADE_P2) { TPD_DEBUG("drift eliminated (2)\n"); TPD_BUF_UNQUEUE(fx,fy,fd,fp); #endif #else if(0) { #endif } else { buf_f = ((buf_f+1)%3); buf_c = ((buf_f+2)%3); buf_p = ((buf_f+1)%3); buf_kp[buf_f].x1 = (cd?cx:buf_kp[buf_c].x1); buf_kp[buf_f].y1 = (cd?cy:buf_kp[buf_c].y1); dx = buf_kp[buf_f].x1 - buf_kp[buf_c].x1; buf_kp[buf_f].count = (cd?(dx*dx<tpd_mode_keypad_tolerance?buf_kp[buf_c].count+1:1):0); if(buf_kp[buf_c].count<2) { if(down) { down=0; tpd_up(buf_kp[buf_p].x1, buf_kp[buf_p].y1,1,0); input_sync(tpd->dev); } } if(buf_kp[buf_c].count>1 || (buf_kp[buf_c].count==1 && ( buf_kp[buf_p].count==0 || buf_kp[buf_f].count==0 || (buf_kp[buf_f].x1-buf_kp[buf_c].x1)*(buf_kp[buf_c].x1-buf_kp[buf_p].x1)<=0))) { tpd_down(buf_kp[buf_c].x1, buf_kp[buf_c].y1,1,1, &px, &py); input_sync(tpd->dev); down = 1; } if(cd==0) { if(down) { down=0; tpd_up(buf_kp[buf_p].x1, buf_kp[buf_p].y1,1,0); input_sync(tpd->dev); buf.count = 0; }} else mod_timer(&(tpd->timer),jiffies+TPD_DELAY); } mod_timer(&(tpd->timer),jiffies+TPD_DELAY); buf.count++; } else { // to avoid miss of tpd down when press light to heavy if(tpd_sw_status==0) { if(tpd_hw_status==1) { if(cd==0) stop_timer(true); } else return; } tpd_sw_status = 1; /* ================= buffering =================*/ /* save new point in ni, get point from index */ ni=TPD_BUF_NP(); buf.x[ni]=cx; buf.y[ni]=cy; buf.d[ni]=cd; buf.p[ni]=cp; fx=(cx=buf.x[buf.index]); fy=(cy=buf.y[buf.index]); fd=(cp=buf.p[buf.index]); fp=(cd=buf.d[buf.index]); buf.index = ni; tpd_lpfx[tpd_lpfc]=cx; tpd_lpfy[tpd_lpfc]=cy; x1 = 0, y1 = 0, p1 = 0; for(i=tpd_lpfc;i<tpd_lpfc+5;i++) { x1 += (tpd_lpfx[i%5]*tpd_lpfw[i-tpd_lpfc]); y1 += (tpd_lpfy[i%5]*tpd_lpfw[i-tpd_lpfc]); if(tpd_lpfx[i%5]!=0 || tpd_lpfy[i%5]!=0) p1+=tpd_lpfw[i-tpd_lpfc]; } cx=x1/(p1?p1:1); cy=y1/(p1?p1:1); TPD_DEBUG(">%d [%8d %8d %8d %8d] - ",buf.count,cx,cy,cp,cd); /* pressure thresholding */ if(cp>TPD_PRESSURE_MAX || (cx==TPD_RES_X && cy==TPD_RES_Y)) cd=0,cp=TPD_PRESSURE_MAX+1; if(cd==1) { #ifdef TPD_HAVE_DRIFT_ELIMINATION /* drift elimination */ if(buf.count==0) { TPD_DEBUG("drift eliminated (0)\n"); #ifdef TPD_HAVE_ADV_DRIFT_ELIMINATION } else if (buf.count==1 && cp>TPD_ADE_P1) { TPD_DEBUG("drift eliminated (1)\n"); } else if (buf.count==1) { /* queue first good point, discard it if 2nd pt is bad */ TPD_BUF_QUEUE(cx,cy,cd,cp); } else if (buf.count==2 && cp>TPD_ADE_P2) { TPD_DEBUG("drift eliminated (2)\n"); TPD_BUF_UNQUEUE(fx,fy,fd,fp); #endif #else if(0) { #endif } else { /* if a point is already queued, pop and send it */ if(buf.queued) { TPD_BUF_UNQUEUE(fx,fy,fd,fp); /* if the queued point is a bad point.. */ #ifdef TPD_HAVE_BUTTON /* if point is for btn, don't process it */ if(cy>=TPD_BUTTON_HEIGHT) {} #else if(0) {} #endif else if(fp>TPD_PRESSURE_NICE && buf.avg_count<2) { /* average current point and queued point */ cx = (cx+fx)/2; cy = (cy+fy)/2; buf.avg_count++; } else { TPD_DEBUG("pop and down\n"); tpd_down(fx,fy,fd,fp, &px, &py); lx=fx,ly=fy; buf.avg_count=0; } } #ifdef TPD_HAVE_BUTTON /* queue points near bottom btns, to prevent mis-touch of menu */ if(cy>TPD_BUTTON_HEIGHT-20 && cy<TPD_BUTTON_HEIGHT) { TPD_DEBUG("queued\n"); TPD_BUF_QUEUE(cx,cy,cd,cp); } #else if(0) {} #endif /* discontinuity elimination - queueing */ /* also point averaging */ else if(buf.d[ni]==0 || cp>TPD_PRESSURE_NICE) { TPD_DEBUG("queued\n"); TPD_BUF_QUEUE(cx,cy,cd,cp); } else { TPD_DEBUG("down\n"); tpd_down(cx,cy,cd,cp, &px, &py); lx=cx,ly=cy; buf.effective++; buf.last = buf.count+1; } } buf.count++; mod_timer(&(tpd->timer),jiffies+TPD_DELAY); } else { if(buf.queued) { if(buf.count-buf.last>TPD_COUNT_TOLERANCE) { /* single point elimination */ TPD_BUF_UNQUEUE(cx,cy,cd,cp); TPD_DEBUG("unqueue : "); if(buf.effective==0) { TPD_DEBUG("sp eliminated.\n"); stop_timer(false); } else { /* track extension */ if(cp<TPD_PRESSURE_NICE) { /* only when end-point is good..*/ tpd_down(cx,cy,cd,cp, &px, &py); #ifdef TPD_HAVE_TRACK_EXTENSION if(buf.effective>0) { cx=cx+cx-px,cy=cy+cy-py; tpd_down(cx,cy,cd,cp, &px, &py); TPD_DEBUG("track extend.\n"); } lx=cx,ly=cy; #endif } else TPD_DEBUG("end point is not good, discard\n"); tpd_up(lx,ly,cd,cp); stop_timer(false); } } else { /* waiting for next down event */ TPD_DEBUG("delay handling.\n"); buf.count++; mod_timer(&(tpd->timer),jiffies+TPD_DELAY); } } else { TPD_DEBUG("no queue.\n"); /* since no queue and no touch, stop timer after specific times of trial */ /* only increase buf.count after real first down. */ //if(buf.effective) buf.count++; if(buf.count || !buf.last) buf.count++; if(buf.count-buf.last>TPD_COUNT_TOLERANCE || buf.count==0) { tpd_up(lx,ly,0,TPD_PRESSURE_MAX+1); stop_timer(true); } else mod_timer(&(tpd->timer),jiffies+TPD_DELAY); } } } //printk("\n"); //do_gettimeofday(&tv); //t2 = tv.tv_sec*1000000l+tv.tv_usec; //printk("%ld\n", t2-t1); return; } //#ifdef CONFIG_HAS_EARLYSUSPEND /* platform device functions */ void tpd_suspend(struct early_suspend *h) { /*MT6573_IRQClearInt(MT6573_WDT_IRQ_LINE); MT6573_IRQMask(MT6573_TOUCH_IRQ_LINE); if(hwDisableClock(MT6573_PDN_PERI_TP,"Touch")==FALSE) TPD_DMESG("entering suspend mode - hwDisableClock failed."); if(hwDisableClock(MT6573_PDN_PERI_ADC,"Touch")==FALSE) TPD_DMESG("entering suspend mode - hwDisableClock failed.");*/ tpd_hw_status = 0; } void tpd_resume(struct early_suspend *h) { /*if(hwEnableClock(MT6573_PDN_PERI_ADC,"Touch")==FALSE) TPD_DMESG("resume from suspend mode - hwEnableClock ADC failed."); if(hwEnableClock(MT6573_PDN_PERI_TP,"Touch")==FALSE) TPD_DMESG("resume from suspend mode - hwEnableClock TP failed.");*/ //MT6573_IRQUnmask(MT6573_TOUCH_IRQ_LINE); }
static int touch_event_handler(void *unused) { struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; struct touch_info cinfo, sinfo; int pending = 0, down = 0; struct touch_info buf[3]; int buf_p=1, buf_c=2, buf_f=0; int dx; cinfo.pending=0; sched_setscheduler(current, SCHED_RR, ¶m); do { MT6516_EINTIRQUnmask(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; } if(cinfo.count==-1) continue; if(tpd_mode==TPD_MODE_KEYPAD && ((tpd_mode_axis==0 && cinfo.y1>=tpd_mode_min && cinfo.y1<=tpd_mode_max) || (tpd_mode_axis==1 && cinfo.x1>=tpd_mode_min && cinfo.x1<=tpd_mode_max))) { buf_f = ((buf_f+1)%3); buf_c = ((buf_f+2)%3); buf_p = ((buf_f+1)%3); buf[buf_f].x1 = cinfo.x1; buf[buf_f].y1 = cinfo.y1; dx = cinfo.x1 - buf[buf_c].x1; buf[buf_f].count = (cinfo.count?(dx*dx<tpd_mode_keypad_tolerance?buf[buf_c].count+1:1):0); if(buf[buf_c].count<2) if(tpd_up(raw_x1, raw_y1, buf[buf_p].x1, buf[buf_p].y1,&down)) input_sync(tpd->dev); if(buf[buf_c].count>1 || (buf[buf_c].count==1 && ( buf[buf_p].count==0 || buf[buf_f].count==0 || (buf[buf_f].x1-buf[buf_c].x1)*(buf[buf_c].x1-buf[buf_p].x1)<=0))) { tpd_down(raw_x1, raw_y1, buf[buf_c].x1, buf[buf_c].y1, 1); input_sync(tpd->dev); down=1; } if(cinfo.count==0) if(tpd_up(raw_x1, raw_y1, buf[buf_p].x1, buf[buf_p].y1,&down)) input_sync(tpd->dev); } else { switch(cinfo.count) { case 0: if(cinfo.pending>0) pending+=cinfo.pending, cinfo.pending=0; else { if(sinfo.count>=2) { if(pending==0) pending+=1; else { if(tpd_up(raw_x1, raw_y1, sinfo.x1, sinfo.y1, &down) + tpd_up(raw_x2, raw_y2, sinfo.x2,sinfo.y2, &down)) input_sync(tpd->dev); sinfo.count = 0; pending = 0; } } else if(sinfo.count==1) { #ifdef TPD_HAVE_BUTTON if(boot_mode!=NORMAL_BOOT && tpd->btn_state) tpd_button(cinfo.x1, cinfo.y1,0); #endif if(tpd_up(raw_x1, raw_y1, cinfo.x1,cinfo.y1, &down)) input_sync(tpd->dev); sinfo.count = 0; pending=0; } else pending = 0; } TPD_DEBUG_PRINT_UP; break; case 1: if(sinfo.count>=3 || pending==1) { pending = 0; if(sinfo.count==3 && down>1) { if(tpd_up(raw_x1, raw_y1, sinfo.x1,sinfo.y1, &down)) input_sync(tpd->dev); /*tpd_down(cinfo.x1, cinfo.y1, 1); if( (cinfo.x1-sinfo.x1)*(cinfo.x1-sinfo.x1)+(cinfo.y1-sinfo.y1)*(cinfo.y1-sinfo.y1) > (cinfo.x1-sinfo.x2)*(cinfo.x1-sinfo.x2)+(cinfo.y1-sinfo.y2)*(cinfo.y1-sinfo.y2) ) { if(tpd_up(sinfo.x1,sinfo.y1, &down)) input_sync(tpd->dev); } else { if(tpd_up(sinfo.x2,sinfo.y2, &down)) input_sync(tpd->dev); }*/ } } else if(sinfo.count==2) { if(pending==0) pending=1; else { if(tpd_up(raw_x1, raw_y1, cinfo.x1,cinfo.y1, &down) + tpd_up(raw_x2, raw_y2, sinfo.x2,sinfo.y2, &down)) input_sync(tpd->dev); sinfo.x1 = cinfo.x1; sinfo.y1=cinfo.y1; } sinfo.count = 3; } else { #ifdef TPD_HAVE_BUTTON if(boot_mode!=NORMAL_BOOT && cinfo.y1>=TPD_RES_Y) { if(tpd_up(raw_x1, raw_y1, cinfo.x1, cinfo.y1, &down)) input_sync(tpd->dev); tpd_button(cinfo.x1, cinfo.y1, 1); sinfo.count = 1; } else #endif do { #ifdef TPD_HAVE_BUTTON if(boot_mode!=NORMAL_BOOT && tpd->btn_state) tpd_button(cinfo.x1,cinfo.y1,0); #endif tpd_down(raw_x1, raw_y1, cinfo.x1,cinfo.y1, cinfo.p); input_sync(tpd->dev); down = 1; sinfo.count = 1; } while(0); } TPD_DEBUG_PRINT_DOWN; break; case 2: // hold one finger, press another, this code will release both fingers if(sinfo.count==3) { if(tpd_up(raw_x1, raw_y1, sinfo.x1, sinfo.y1, &down) + tpd_up(raw_x2, raw_y2, sinfo.x2, sinfo.y2, &down)) input_sync(tpd->dev); } tpd_smoothing(&cinfo, &sinfo); tpd_down(raw_x1, raw_y1, sinfo.x1, sinfo.y1, 1); tpd_down(raw_x2, raw_y2, sinfo.x2, sinfo.y2, 1); down = 2; sinfo.count = 2; input_sync(tpd->dev); TPD_DEBUG_PRINT_DOWN; break; default: break; } } } while (!kthread_should_stop()); return 0; }
static int touch_event_handler(void *unused) { struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; int index; uint8_t Firmware_version[3] = {0x20,0x00,0x00}; sched_setscheduler(current, SCHED_RR, ¶m); do { set_current_state(TASK_INTERRUPTIBLE); if (!kthread_should_stop()) { TPD_DEBUG_CHECK_NO_RESPONSE; do { while (tpd_halt) {tpd_flag = 0;sinfo.TouchpointFlag=0; msleep(20);} wait_event_interruptible(waiter,tpd_flag!=0); tpd_flag = 0; } while(0); TPD_DEBUG_SET_TIME; } set_current_state(TASK_RUNNING); #if 0 if (tpd_show_version) { tpd_show_version = 0; if(tpd_i2c_master_rs_send(i2c_client,Firmware_version,3<<8|1) < 0) { TPD_DMESG("I2C transfer error, line: %d\n", __LINE__); } else { TPD_DMESG(" mcs6024 Hardware version is %x\n",Firmware_version[0]); TPD_DMESG(" mcs6024 Firmware version is %x\n",Firmware_version[1]); TPD_DMESG(" mcs6024 Panel Type is %x\n",Firmware_version[2]); } } if((tpd_gettouchinfo(&cinfo)) && (sinfo.TouchpointFlag==0) && ((sinfo.VirtualKeyFlag & 0x03) == 0)) continue; TPD_DEBUG("sinfo.TouchpointFlag = %d\n",sinfo.TouchpointFlag); TPD_DEBUG("cinfo.TouchpointFlag = %d\n",cinfo.TouchpointFlag); TPD_DEBUG("sinfo.VirtualKeyFlag = %d\n",sinfo.VirtualKeyFlag); TPD_DEBUG("cinfo.VirtualKeyFlag = %d\n",cinfo.VirtualKeyFlag); #ifdef TPD_HAVE_BUTTON int index = (cinfo.VirtualKeyFlag >> 2) & 0x03; if (index >= TPD_KEY_COUNT) continue; if ((cinfo.VirtualKeyFlag & 0x03) == 1) { if ((sinfo.VirtualKeyFlag & 0x03) == 0) { tpd_down(tpd_keys_dim_local[index][0],tpd_keys_dim_local[index][1], tpd_keys_dim_local[index][0],tpd_keys_dim_local[index][1], 128); if (boot_mode != NORMAL_BOOT) tpd_button(tpd_keys_dim_local[index][0],tpd_keys_dim_local[index][1], 1); } } else { if ((sinfo.VirtualKeyFlag & 0x03) == 1) { tpd_up(tpd_keys_dim_local[index][0],tpd_keys_dim_local[index][1], tpd_keys_dim_local[index][0],tpd_keys_dim_local[index][1]); if (boot_mode != NORMAL_BOOT) tpd_button(tpd_keys_dim_local[index][0],tpd_keys_dim_local[index][1], 0); } } #endif for(index = 0;index<MAX_POINT;index++) { if(cinfo.TouchpointFlag&(1<<index)) { raw_x[index] = cinfo.x[index]; raw_y[index] = cinfo.y[index]; tpd_down(raw_x[index], raw_y[index], cinfo.x[index],cinfo.y[index], 128); sinfo.x[index] = cinfo.x[index]; sinfo.y[index] = cinfo.y[index]; sinfo.TouchpointFlag |=(1<<index); } else { if(sinfo.TouchpointFlag&(1<<index)) { tpd_up(raw_x[index], raw_y[index], sinfo.x[index], sinfo.y[index]); sinfo.TouchpointFlag &=~(1<<index); } } } input_sync(tpd->dev); #endif msg21xx_data_disposal(); } while (!kthread_should_stop()); return 0; }