/**************************** touch down / up *******************************/ static void tpd_down(int cx, int cy, int cd, int cp, int *px, int *py) { tpd_lpfx[tpd_lpfc]=cx; tpd_lpfy[tpd_lpfc]=cy; tpd_lpfc=(tpd_lpfc+4)%5; #ifdef TPD_HAVE_TREMBLE_ELIMINATION /*tremble elimination */ if(( (*px-cx)*(*px-cx)+(*py-cy)*(*py-cy)) < 17) cx=*px,cy=*py; else *px = cx, *py = cy; #endif //TPD_DEBUG("[DOWN] [x%4d y%4d d%1d p%6d)",cx, cy, cd, cp); #ifdef TPD_HAVE_BUTTON if(cy>=TPD_BUTTON_HEIGHT) { if(buf.count<5) tpd_button(cx,cy,1); return; } if(cy<TPD_BUTTON_HEIGHT && tpd->btn_state && cp<TPD_PRESSURE_MAX) tpd_button(cx,cy,0); #endif cp=(255*(TPD_PRESSURE_MAX-cp))/(TPD_PRESSURE_MAX-TPD_PRESSURE_MIN); do { input_report_abs(tpd->dev, ABS_X, cx); input_report_abs(tpd->dev, ABS_Y, cy); input_report_abs(tpd->dev, ABS_PRESSURE, cp); input_report_key(tpd->dev, BTN_TOUCH, 1); } while(0); input_sync(tpd->dev); buf.effective++; buf.last = buf.count+1; TPD_DEBUG_PRINT_DOWN; TPD_EM_PRINT(raw_x, raw_y, cx, cy, (raw_z1 << 16 | raw_z2), 1); //printk("f[%5d %5d %5d]", cx, cy, cp); }
static int tpd_up(tinno_ts_data *ts, int x, int y, int pressure, int trackID) { if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { CTP_DBG("x=%03d, y=%03d, ID=%03d", x, y, trackID); input_report_abs(tpd->dev, ABS_PRESSURE, 0); input_report_abs(tpd->dev, ABS_MT_PRESSURE, 0); input_report_key(tpd->dev, BTN_TOUCH, 0); input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); #ifdef FTS_SUPPORT_TRACK_ID input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, trackID); #endif input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 0); input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0);// This must be placed at the last one. input_mt_sync(tpd->dev); }else{//Android 4.0 don't need to report these up events. int i, have_down_cnt = 0; for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ if ( test_bit(i, &ts->fingers_flag) ){ ++have_down_cnt; } } if ( have_down_cnt < 2 ){ input_mt_sync(tpd->dev); } CTP_DBG("x=%03d, y=%03d, ID=%03d, have_down=%d", x, y, trackID, have_down_cnt); } __clear_bit(trackID, &ts->fingers_flag); TPD_UP_DEBUG_TRACK(x,y); if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { tpd_button(x, y, 0); } return 0; }
static int tpd_up(tinno_ts_data *ts, int x, int y, int pressure, int trackID) { if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { CTP_DBG("x=%03d, y=%03d, ID=%03d", x, y, trackID); input_report_abs(tpd->dev, ABS_PRESSURE, 0); input_report_abs(tpd->dev, ABS_MT_PRESSURE, 0); input_report_key(tpd->dev, BTN_TOUCH, 0); input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); #ifdef FTS_SUPPORT_TRACK_ID input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, trackID); #endif input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 0); input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0);// This must be placed at the last one. input_mt_sync(tpd->dev); }else{//Android 4.0 don't need to report these up events. int i, have_down_cnt = 0; for ( i=0; i < TINNO_TOUCH_TRACK_IDS; i++ ){ if ( test_bit(i, &ts->fingers_flag) ){ ++have_down_cnt; } } if ( have_down_cnt < 2 ){ input_mt_sync(tpd->dev); } CTP_DBG("x=%03d, y=%03d, ID=%03d, have_down=%d", x, y, trackID, have_down_cnt); } __clear_bit(trackID, &ts->fingers_flag); #ifdef CONFIG_TOUCHSCREEN_SWEEP2WAKE s2w_st_flag = 0; if (sweep2wake > 0) { //printk("[sweep2wake]:line : %d | func : %s\n", __LINE__, __func__); //printk("[SWEEP2WAKE]: resetin s2w param\n"); //printk("[sweep2wake]:line : %d | func : %s\n", __LINE__, __func__); exec_count = true; barrier[0] = false; barrier[1] = false; scr_on_touch = false; tripoff = 0; tripon = 0; triptime = 0; } if (doubletap2wake && scr_suspended) { printk("[SWEEP2WAKE]: detecting d2w\n"); doubletap2wake_func(x, y, jiffies); } #endif TPD_UP_DEBUG_TRACK(x,y); if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { tpd_button(x, y, 0); } return 0; }
static int tpd_up(tinno_ts_data *ts, int x, int y, int pressure, int trackID) { CTP_DBG("x=%03d, y=%03d, ID=%03d", x, y, trackID); //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); //input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, trackID); input_mt_sync(tpd->dev); //TPD_UP_DEBUG_TRACK(x,y); if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { tpd_button(x, y, 0); } return 0; }
static void tpd_down(tinno_ts_data *ts, int x, int y, int pressure, int trackID) { CTP_DBG("x=%03d, y=%03d, pressure=%03d, ID=%03d", x, y, pressure, trackID); input_report_key(tpd->dev, BTN_TOUCH, 1); input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 20); 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, trackID); input_mt_sync(tpd->dev); if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { tpd_button(x, y, 1); } //TPD_DOWN_DEBUG_TRACK(x,y); }
static void tpd_up(int cx, int cy, int cd, int cp) { int i, pending = 0; //TPD_DEBUG("[ UP ] [x%4d y%4d d%1d p%6d)\n",cx, cy, cd, cp); tpd_buffer_init(); #ifdef TPD_HAVE_BUTTON if(tpd->btn_state) tpd_button(cx,cy,0); else #endif do { input_report_abs(tpd->dev, ABS_X, cx); input_report_abs(tpd->dev, ABS_Y, cy); input_report_abs(tpd->dev, ABS_PRESSURE, 0); input_report_key(tpd->dev, BTN_TOUCH, 0); input_sync(tpd->dev); } while(0); for(i=0;i<5;i++) { tpd_lpfx[i]=0;tpd_lpfy[i]=0;tpd_lpfc=0; } TPD_DEBUG_PRINT_UP; TPD_EM_PRINT(raw_x, raw_y, cx, cy, (raw_z1 << 16 | raw_z2), 0); //printk("u[%5d %5d %5d]", cx, cy, cp); }
static void tpd_down(tinno_ts_data *ts, int x, int y, int pressure, int trackID) { CTP_DBG("x=%03d, y=%03d, pressure=%03d, ID=%03d", x, y, pressure, trackID); input_report_abs(tpd->dev, ABS_PRESSURE, pressure); input_report_abs(tpd->dev, ABS_MT_PRESSURE, pressure); input_report_key(tpd->dev, BTN_TOUCH, 1); input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); #ifdef FTS_SUPPORT_TRACK_ID input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, trackID); #endif input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, pressure*pressure/112); input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, pressure*pressure/112); input_mt_sync(tpd->dev); __set_bit(trackID, &ts->fingers_flag); ts->touch_point_pre[trackID].x=x; ts->touch_point_pre[trackID].y=y; if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { tpd_button(x, y, 1); } TPD_DOWN_DEBUG_TRACK(x,y); }
static void tpd_down(tinno_ts_data *ts, int x, int y, int pressure, int trackID) { int iPressure = pressure*pressure/110; if ( iPressure < 1 ){ iPressure = 1; } CTP_DBG("x=%03d, y=%03d, pressure=%03d, ID=%03d", x, y, pressure, trackID); input_report_abs(tpd->dev, ABS_PRESSURE, iPressure); input_report_abs(tpd->dev, ABS_MT_PRESSURE, iPressure); input_report_key(tpd->dev, BTN_TOUCH, 1); input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 20); input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); printk("[SWEEP2WAKE]: tpd down\n"); #ifdef CONFIG_TOUCHSCREEN_SWEEP2WAKE if (sweep2wake) { //printk("[SWEEP2WAKE]: detecting sweep\n"); detect_sweep2wake(x, y, jiffies, trackID); } #endif #ifdef FTS_SUPPORT_TRACK_ID input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, trackID); #endif input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, iPressure); input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, iPressure); input_mt_sync(tpd->dev); __set_bit(trackID, &ts->fingers_flag); ts->touch_point_pre[trackID].x=x; ts->touch_point_pre[trackID].y=y; if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode()) { tpd_button(x, y, 1); } TPD_DOWN_DEBUG_TRACK(x,y); }
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; }