Hi, On 03/28/2014 08:49 PM, Dimitar Penev wrote: > Hi Hans, > > I plan to use sun4i-ts drivers. > How well is the mainstream version working?
AFAIK it works well. > Do you have useful updates after your clean up? Nope. Regards, Hans > > Thanks > Dimitar > > 22 декември 2013, неделя, 18:48:12 UTC+2, Hans de Goede написа: >> >> The sun4i-ts controller is capable of detecting a second touch, but when a >> second touch is present then the accuracy becomes so bad the reported >> touch >> location is not useable. >> >> The android driver contains some complicated heuristics using the aprox. >> distance between the 2 touches to see if the user is making a pinch open / >> close movement, and then reports emulated multi-touch events around the >> last >> single touch coordinate (as the dual-touch coordinates are worthless). >> >> Note that this pinch emulation has never worked as the implementation of >> the evdev mt protocol inside the android code is wrong, more over it is >> wrong because there is a lot more to multi-touch then just pinch >> detection, >> and reporting being mt capable when we're really not will confuse apps. >> >> I'm currently writing a new rtp driver from scratch for upstream, I've >> decided >> to start with gutting all the heuristics from the 3.4 driver making it >> work >> the same way as I intend the upstream driver to work, so I can test things >> on a kernel where I have a working lcd driver. >> >> So this commit removes all the broken heuristics. As a bonus after this >> patch >> the tslib.patch people have been using also is no longer needed: >> >> https://raw.github.com/webconn/OLINUXINO/master/SOFTWARE/A13/TOUCHSCREEN/tslib.patch >> >> >> Signed-off-by: Hans de Goede <[email protected] <javascript:>> >> --- >> drivers/input/touchscreen/sun4i-ts.c | 1448 >> ++-------------------------------- >> 1 file changed, 45 insertions(+), 1403 deletions(-) >> >> diff --git a/drivers/input/touchscreen/sun4i-ts.c >> b/drivers/input/touchscreen/sun4i-ts.c >> index c74b2a9..5637a6f 100644 >> --- a/drivers/input/touchscreen/sun4i-ts.c >> +++ b/drivers/input/touchscreen/sun4i-ts.c >> @@ -48,37 +48,6 @@ >> #include <linux/earlysuspend.h> >> #endif >> >> -//#undef CONFIG_HAS_EARLYSUSPEND >> - >> -static int tp_flag = 0; >> - >> -//tp status value >> -#define TP_INITIAL (-1) >> -#define TP_DOWN (0) >> -#define TP_UP (1) >> -#define TP_DATA_VA (2) >> -//? >> -#define DUAL_TOUCH (dual_touch_distance) >> -#define TOUCH_CHANGE (3) >> -#define TP_DATA_AV_NO (0x3) >> - >> -//#define PRINT_INT_INFO >> -//#define PRINT_FILTER_INFO >> -//#define PRINT_REPORT_STATUS_INFO >> -//#define PRINT_REPORT_DATA_INFO >> -//#define PRINT_TASKLET_INFO >> -#define CONFIG_TOUCHSCREEN_SUN4I_DEBUG >> -#define PRINT_SUSPEND_INFO >> -//#define PRINT_FILTER_DOUBLE_POINT_STATUS_INFO >> -//#define PRINT_ORIENTATION_INFO >> -//#define FIX_ORIENTATION >> -#define ORIENTATION_DEFAULT_VAL (-1) >> -//#define TP_INT_PERIOD_TEST >> -//#define TP_TEMP_DEBUG >> -//#define TP_FREQ_DEBUG >> -//#define PRINT_UP_SEPARATOR >> -#define TP_FIX_CENTER >> - >> #define IRQ_TP (29) >> #define TP_BASSADDRESS (0xf1c25000) >> #define TP_CTRL0 (0x00) >> @@ -103,17 +72,16 @@ static int tp_flag = 0; >> #define ACQ (0x3f) >> #define T_ACQ (ACQ) >> >> -#define STYLUS_UP_DEBOUNCE (0<<12) >> -#define STYLUS_UP_DEBOUCE_EN (0<<9) >> +#define STYLUS_UP_DEBOUNCE (5<<12) >> +#define STYLUS_UP_DEBOUCE_EN (1<<9) >> #define TOUCH_PAN_CALI_EN (1<<6) >> #define TP_DUAL_EN (1<<5) >> #define TP_MODE_EN (1<<4) >> #define TP_ADC_SELECT (0<<3) >> #define ADC_CHAN_SELECT (0) >> >> -//#define TP_SENSITIVE_ADJUST (0xf<<28) >> #define TP_SENSITIVE_ADJUST (tp_sensitive_level<<28) //mark by >> young for test angda 5" 0xc >> -#define TP_MODE_SELECT (0x1<<26) >> +#define TP_MODE_SELECT (0x0<<26) >> #define PRE_MEA_EN (0x1<<24) >> #define PRE_MEA_THRE_CNT (tp_press_threshold<<0) //0x1f40 >> >> @@ -123,7 +91,7 @@ static int tp_flag = 0; >> >> #define TP_DATA_IRQ_EN (1<<16) >> #define TP_DATA_XY_CHANGE (tp_exchange_x_y<<13) >> //tp_exchange_x_y >> -#define TP_FIFO_TRIG_LEVEL (3<<8) >> +#define TP_FIFO_TRIG_LEVEL (1<<8) >> #define TP_FIFO_FLUSH (1<<4) >> #define TP_UP_IRQ_EN (1<<1) >> #define TP_DOWN_IRQ_EN (1<<0) >> @@ -132,213 +100,24 @@ static int tp_flag = 0; >> #define TP_UP_PENDING (1<<1) >> #define TP_DOWN_PENDING (1<<0) >> >> -#define SINGLE_TOUCH_MODE (1) >> -#define CHANGING_TO_DOUBLE_TOUCH_MODE (2) >> -#define DOUBLE_TOUCH_MODE (3) >> -#define UP_TOUCH_MODE (4) >> - >> -#define SINGLE_CNT_LIMIT (40) >> -#define DOUBLE_CNT_LIMIT (2) >> -#define UP_TO_SINGLE_CNT_LIMIT (10) >> - >> -#define TPDATA_MASK (0xfff) >> -#define FILTER_NOISE_LOWER_LIMIT (2) >> -#define MAX_DELTA_X (700-100) // avoid excursion >> -#define MAX_DELTA_Y (1200-200) >> -#define X_TURN_POINT (330) // x1 < (1647 - >> MAX_DELTA_X) /3 >> -#define X_COMPENSATE (4*X_TURN_POINT) >> -#define Y_TURN_POINT (260) // y1 < (1468 -MAX_DELTA_Y >> ) >> -#define Y_COMPENSATE (2*Y_TURN_POINT) >> - >> -#ifdef TP_FIX_CENTER >> -#define X_CENTER_COORDINATE (2048) //for construct two point >> -#define Y_CENTER_COORDINATE (2048) >> -#else >> -#define X_CENTER_COORDINATE (sample_data->x) >> -#define Y_CENTER_COORDINATE (sample_data->y) >> -#endif >> - >> -#define CYCLE_BUFFER_SIZE (64) //must be 2^n >> -#define DELAY_PERIOD (6) //delay 60 ms, unit is 10ms >> -#define DELAY_COMPENSTAE_PEROID (3) //the os is busy, can not process >> the data in time. >> - >> -#define ZOOM_CHANGE_LIMIT_CNT (3) >> -#define ZOOM_IN (1) >> -#define ZOOM_OUT (2) >> -#define ZOOM_INIT_STATE (3) >> -#define ZOOM_STATIC (4) >> - >> -#define SAMPLE_TIME (9.6) >> //unit is ms. ??? >> -#define SAMPLE_TIME_FACTOR (9.6/SAMPLE_TIME) >> - >> -#ifndef TRUE >> -#define TRUE 1 >> -#define FALSE 0 >> -#endif >> - >> -#ifdef PRINT_INT_INFO >> -#define print_int_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_int_info(fmt, args...) // >> -#endif >> - >> -#ifdef PRINT_FILTER_INFO >> -#define print_filter_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_filter_info(fmt, args...) // >> -#endif >> - >> -#ifdef PRINT_REPORT_STATUS_INFO >> -#define print_report_status_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_report_status_info(fmt, args...) // >> -#endif >> - >> -#ifdef PRINT_REPORT_DATA_INFO >> -#define print_report_data_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_report_data_info(fmt, args...) // >> -#endif >> - >> -#ifdef PRINT_TASKLET_INFO >> -#define print_tasklet_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_tasklet_info(fmt, args...) // >> -#endif >> - >> -#ifdef PRINT_FILTER_DOUBLE_POINT_STATUS_INFO >> -#define print_filter_double_point_status_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_filter_double_point_status_info(fmt, args...) // >> -#endif >> - >> -#ifdef PRINT_ORIENTATION_INFO >> -#define print_orientation_info(fmt, args...) \ >> - do{ \ >> - printk(fmt, ##args); \ >> - }while(0) >> -#else >> -#define print_orientation_info(fmt, args...) // >> -#endif >> - >> struct sun4i_ts_data { >> struct resource *res; >> struct input_dev *input; >> void __iomem *base_addr; >> int irq; >> char phys[32]; >> - unsigned int count; //for report threshold & touchmod(double to >> single touch mode) change >> - unsigned long buffer_head; //for cycle buffer >> - unsigned long buffer_tail; >> - int ts_sample_status; //for touchscreen status >> when sampling >> - int ts_process_status; //for record touchscreen >> status when process data >> - int double_point_cnt; //for noise reduction when in >> double_touch_mode >> - int single_touch_cnt; //for noise reduction when >> change to double_touch_mode >> - int ts_delay_period; //will determine responding >> sensitivity >> - int touchflag; >> + int ignore_fifo_data; >> #ifdef CONFIG_HAS_EARLYSUSPEND >> struct early_suspend early_suspend; >> #endif >> }; >> >> -struct ts_sample_data{ >> - unsigned int x1; >> - unsigned int y1; >> - unsigned int x; >> - unsigned int y; >> - unsigned int dx; >> - unsigned int dy; >> - unsigned int z1; >> - unsigned int z2; >> - int sample_status; //record the sample >> point status when sampling >> - unsigned int sample_time; >> -}; >> - >> -struct sun4i_ts_data * mtTsData =NULL; >> -static int touch_mode = UP_TOUCH_MODE; >> -static int change_mode = TRUE; >> -static int tp_irq_state = TRUE; >> - >> -#ifdef PRINT_INT_INFO >> -static cputime64_t cur_wall_time = 0L; >> -#endif >> - >> -//static cputime64_t cur_idle_time = 0L; >> - >> -static struct ts_sample_data cycle_buffer[CYCLE_BUFFER_SIZE] = {{0},}; >> -static struct ts_sample_data *prev_sample; >> -static struct ts_sample_data *prev_data_sample; >> -static struct timer_list data_timer; >> -static int data_timer_status = 0; //when 1, mean tp driver have >> recervied data, and begin to report data, and start timer to reduce up&down >> signal >> -static struct ts_sample_data prev_single_sample; >> -static struct ts_sample_data prev_double_sample_data; >> -static struct ts_sample_data prev_report_samp; >> -static int orientation_flag = 0; >> -static int zoom_flag = 0; >> -static int accmulate_zoom_out_ds = 0; >> -static int accmulate_zoom_in_ds = 0; >> -static int zoom_in_count = 0; >> -static int zoom_out_count = 0; >> -static int zoom_change_cnt = 0; >> -static int hold_cnt = 0; >> //config from sysconfig files. >> -static int glide_delta_ds_max_limit = 0; >> -static int tp_regidity_level = 0; >> static int tp_press_threshold_enable = 0; >> static int tp_press_threshold = 0; //usded to adjust sensitivity of touch >> static int tp_sensitive_level = 0; //used to adjust sensitivity of pen >> down detection >> static int tp_exchange_x_y = 0; >> >> -#define ZOOM_IN_OUT_BUFFER_SIZE_TIMES (2) >> -#define ZOOM_IN_OUT_BUFFER_SIZE (1<<ZOOM_IN_OUT_BUFFER_SIZE_TIMES) >> -#define TRANSFER_DATA_BUFFER_SIZE (4) >> - >> -static struct ts_sample_data zoom_in_data_buffer[ZOOM_IN_OUT_BUFFER_SIZE] >> = {{0},}; >> -static struct ts_sample_data >> zoom_out_data_buffer[ZOOM_IN_OUT_BUFFER_SIZE] = {{0},}; >> -static struct ts_sample_data >> transfer_data_buffer[TRANSFER_DATA_BUFFER_SIZE] = {{0},}; >> - >> -static int zoom_in_buffer_cnt = 0; >> -static int zoom_out_buffer_cnt = 0; >> - >> -static spinlock_t tp_do_tasklet_sync; >> -static int tp_do_tasklet_running = 0; >> -//for test >> -//static int tp_irq = 0; >> -static int dual_touch_distance = 0; >> - >> -#ifdef PRINT_UP_SEPARATOR >> - static int separator_flag = 0; >> -#endif >> - >> -static int reported_single_point_cnt = 0; >> -static int reported_data_start_time = 0; >> - >> -static atomic_t report_up_event_implement_sync = ATOMIC_INIT(1); >> -static int report_up_event_implement_running = 0; >> - >> -static int reference_point_flag = 1; >> - >> -void tp_do_tasklet(unsigned long data); >> -DECLARE_TASKLET(tp_tasklet,tp_do_tasklet,0); >> - >> //停用设备 >> #ifdef CONFIG_HAS_EARLYSUSPEND >> static void sun4i_ts_suspend(struct early_suspend *h) >> @@ -362,7 +141,7 @@ static void sun4i_ts_resume(struct early_suspend *h) >> #ifdef PRINT_SUSPEND_INFO >> printk("enter laterresume: sun4i_ts_resume. \n"); >> #endif >> - >> >> writel(STYLUS_UP_DEBOUNCE|STYLUS_UP_DEBOUCE_EN|TP_DUAL_EN|TP_MODE_EN,TP_BASSADDRESS >> >> + TP_CTRL1); >> + >> writel(STYLUS_UP_DEBOUNCE|STYLUS_UP_DEBOUCE_EN|TP_MODE_EN,TP_BASSADDRESS + >> TP_CTRL1); >> return ; >> } >> #else >> @@ -384,7 +163,7 @@ static int sun4i_ts_resume(struct platform_device >> *pdev) >> printk("enter: sun4i_ts_resume. \n"); >> #endif >> >> - >> >> writel(STYLUS_UP_DEBOUNCE|STYLUS_UP_DEBOUCE_EN|TP_DUAL_EN|TP_MODE_EN,TP_BASSADDRESS >> >> + TP_CTRL1); >> + >> writel(STYLUS_UP_DEBOUNCE|STYLUS_UP_DEBOUCE_EN|TP_MODE_EN,TP_BASSADDRESS + >> TP_CTRL1); >> return 0; >> } >> #endif >> @@ -394,14 +173,10 @@ static int sun4i_ts_resume(struct platform_device >> *pdev) >> >> static int tp_init(void) >> { >> - //struct sun4i_ts_data *ts_data = (struct sun4i_ts_data >> *)platform_get_drvdata(pdev); >> -// struct sun4i_ts_data *ts_data = mtTsData; >> - //TP_CTRL0: 0x0027003f >> - #ifdef TP_FREQ_DEBUG >> - writel(0x0028001f, TP_BASSADDRESS + TP_CTRL0); >> - #else >> + // Hosc clk | clkin: clk/6 | adc sample freq: clkin / 8192 | >> t_acq clkin / (16 * 48) >> + // 0x0<<22 | 0x2<<20 | 7<<16 | 0x3f >> writel(ADC_CLK_DIVIDER|FS_DIV|T_ACQ, TP_BASSADDRESS + TP_CTRL0); >> - #endif >> + >> //TP_CTRL2: 0xc4000000 >> if(1 == tp_press_threshold_enable){ >> writel(TP_SENSITIVE_ADJUST |TP_MODE_SELECT | PRE_MEA_EN | >> PRE_MEA_THRE_CNT, TP_BASSADDRESS + TP_CTRL2); >> @@ -412,1130 +187,62 @@ static int tp_init(void) >> >> >> //TP_CTRL3: 0x05 >> - #ifdef TP_FREQ_DEBUG >> - writel(0x06, TP_BASSADDRESS + TP_CTRL3); >> - #else >> writel(FILTER_EN|FILTER_TYPE,TP_BASSADDRESS + TP_CTRL3); >> - #endif >> >> #ifdef TP_TEMP_DEBUG >> //TP_INT_FIFOC: 0x00010313 >> - >> >> writel(TP_DATA_IRQ_EN|TP_FIFO_TRIG_LEVEL|TP_FIFO_FLUSH|TP_UP_IRQ_EN|TP_DOWN_IRQ_EN|0x40000, >> >> TP_BASSADDRESS + TP_INT_FIFOC); >> + >> >> writel(TP_DATA_IRQ_EN|TP_FIFO_TRIG_LEVEL|TP_FIFO_FLUSH|TP_UP_IRQ_EN|0x40000, >> TP_BASSADDRESS + TP_INT_FIFOC); >> writel(0x10fff, TP_BASSADDRESS + TP_TPR); >> #else >> //TP_INT_FIFOC: 0x00010313 >> - >> >> writel(TP_DATA_IRQ_EN|TP_FIFO_TRIG_LEVEL|TP_FIFO_FLUSH|TP_UP_IRQ_EN|TP_DOWN_IRQ_EN, >> >> TP_BASSADDRESS + TP_INT_FIFOC); >> + >> writel(TP_DATA_IRQ_EN|TP_FIFO_TRIG_LEVEL|TP_FIFO_FLUSH|TP_UP_IRQ_EN, >> TP_BASSADDRESS + TP_INT_FIFOC); >> #endif >> //TP_CTRL1: 0x00000070 -> 0x00000030 >> - >> >> writel(TP_DATA_XY_CHANGE|STYLUS_UP_DEBOUNCE|STYLUS_UP_DEBOUCE_EN|TP_DUAL_EN|TP_MODE_EN,TP_BASSADDRESS >> >> + TP_CTRL1); >> - >> - >> - /* >> - //put_wvalue(TP_CTRL0 ,0x02a6007f); //512us TACQ 4ms FS 60 point >> - //put_wvalue(TP_CTRL0 ,0x0aa7003f); >> - put_wvalue(TP_CTRL0 ,0x00a7003f); //100 point >> - put_wvalue(TP_CTRL1 ,0x00000030); >> - //put_wvalue(TP_INT_FIFOC,0x12f13); >> - put_wvalue(TP_INT_FIFOC,0x10313); >> - //put_wvalue(TP_CTRL2,0x90003e8); >> - //put_wvalue(TP_CTRL2,0x9002710); >> - put_wvalue(TP_CTRL2,0xc4002710); >> - put_wvalue(TP_CTRL3,0x00000005); >> - */ >> - >> - /* >> - writel(0x00b70100,TP_BASSADDRESS + TP_CTRL0); >> - writel(0xfd000000,TP_BASSADDRESS + TP_CTRL2); >> - writel(0x4,TP_BASSADDRESS + TP_CTRL3); >> - writel(0x10513,TP_BASSADDRESS +TP_INT_FIFOC); >> - writel(0x00005230,TP_BASSADDRESS + TP_CTRL1);*/ >> - return (0); >> -} >> -static void change_to_single_touch_mode(void) >> -{ >> - touch_mode = SINGLE_TOUCH_MODE; >> - reported_single_point_cnt = 0; >> - return; >> -} >> >> -static void backup_transfered_data(struct ts_sample_data *sample_data) >> -{ >> - static int index = 0; >> - >> - index = reported_single_point_cnt%TRANSFER_DATA_BUFFER_SIZE; >> - transfer_data_buffer[index].dx = sample_data->dx; >> - transfer_data_buffer[index].dy = sample_data->dy; >> - transfer_data_buffer[index].x = sample_data->x; >> - transfer_data_buffer[index].y = sample_data->y; >> - >> - if(reported_single_point_cnt > (TRANSFER_DATA_BUFFER_SIZE<<10)){ >> - reported_single_point_cnt -= (TRANSFER_DATA_BUFFER_SIZE<<9); >> - } >> - reported_single_point_cnt++; >> - >> - return; >> -} >> - >> -static void report_single_point_implement(struct sun4i_ts_data *ts_data, >> struct ts_sample_data *sample_data) >> -{ >> - input_report_abs(ts_data->input, ABS_MT_TOUCH_MAJOR,800); >> - input_report_abs(ts_data->input, ABS_MT_POSITION_X, sample_data->x); >> - input_report_abs(ts_data->input, ABS_MT_POSITION_Y, sample_data->y); >> -/* >> - print_report_data_info("report single point: x = %d, y = %d\n >> \ >> - sample_data->dx = %d, sample_data->dy = %d. \n", \ >> - sample_data->x, sample_data->y, sample_data->dx, >> sample_data->dy); >> - */ >> - print_report_data_info("report single point: x = %d,sample_data->y = >> %d. \n", sample_data->x, sample_data->y); >> - >> - input_mt_sync(ts_data->input); >> - input_sync(ts_data->input); >> - >> - return; >> -} >> - >> -static void report_single_point(struct sun4i_ts_data *ts_data, struct >> ts_sample_data *sample_data) >> -{ >> - backup_transfered_data(sample_data); >> - report_single_point_implement(ts_data, sample_data); >> - return; >> -} >> - >> -static void report_slide_data(struct sun4i_ts_data *ts_data) >> -{ >> - int start = 0; >> - int end = 0; >> -#define MIN_DX (DUAL_TOUCH*20) >> -#define MIN_DY (DUAL_TOUCH*20) >> -#define MAX_DX (DUAL_TOUCH*40) >> -#define MAX_DY (DUAL_TOUCH*40) >> - int dx = 0; >> - int dy = 0; >> - int ds_times = 4; >> - //index = reported_single_point_cnt%TRANSFER_DATA_BUFFER_SIZE; >> - struct ts_sample_data sample_data; >> - >> - //printk("reported_single_point_cnt = %d. \n", >> reported_single_point_cnt); >> - if(reported_single_point_cnt <= 1){ >> - //only one reference point, can not judge direction >> - dx = -MIN_DX; >> - dy = MIN_DY; >> - //dy = 0; >> - end = (reported_single_point_cnt-1)%TRANSFER_DATA_BUFFER_SIZE; >> - sample_data.x = max(0, min(4096, >> (int)(transfer_data_buffer[end].x + dx))); >> - sample_data.y = max(0, min(4096, >> (int)(transfer_data_buffer[end].y + dy))); >> - //printk("sample_data.x = %d. sample_data.y = %d. \n", >> sample_data.x, sample_data.y); >> - report_single_point_implement(ts_data, &sample_data); >> - >> - sample_data.x = transfer_data_buffer[end].x; >> - sample_data.y = transfer_data_buffer[end].y; >> - //printk("sample_data.x = %d. sample_data.y = %d. \n", >> sample_data.x, sample_data.y); >> - //report_single_point_implement(ts_data, &sample_data); >> - >> - }else{ >> - if(reported_single_point_cnt <=TRANSFER_DATA_BUFFER_SIZE){ >> - start = 0; >> - }else{ >> - start = reported_single_point_cnt - >> TRANSFER_DATA_BUFFER_SIZE; >> - } >> - start = start%TRANSFER_DATA_BUFFER_SIZE; >> - end = (reported_single_point_cnt-1)%TRANSFER_DATA_BUFFER_SIZE; >> - >> - dx = transfer_data_buffer[end].x -transfer_data_buffer[start].x; >> - dy = transfer_data_buffer[end].y -transfer_data_buffer[start].y; >> - //printk("dx = %d, dy = %d. \n", dx, dy); >> - if(dx < 0){ >> - dx = -dx; >> - dx = min(MAX_DX, max(MIN_DX, dx*ds_times/(end - start))); >> - dx = -dx; >> - }else{ >> - dx = min(MAX_DX, max(MIN_DX, dx*ds_times/(end - start))); >> - } >> - >> - if(dy < 0){ >> - dy = -dy; >> - dy = min(MAX_DY, max(MIN_DY, dy*ds_times/(end - start))); >> - dy = -dy; >> - }else{ >> - dy = min(MAX_DY, max(MIN_DY, dy*ds_times/(end - start))); >> - } >> - >> - //printk("dx = %d, dy = %d. \n", dx, dy); >> - sample_data.x = max(0, min(4096, >> (int)(transfer_data_buffer[end].x + dx))); >> - sample_data.y = max(0, min(4096, >> (int)(transfer_data_buffer[end].y + dy))); >> - >> - //printk("sample_data.x = %d. sample_data.y = %d. \n", >> sample_data.x, sample_data.y); >> - report_single_point_implement(ts_data, &sample_data); >> - } >> - } >> - >> -static void report_up_event_implement(struct sun4i_ts_data *ts_data) >> -{ >> - static const int UP_EVENT_DELAY_TIME = 3; >> - static const int SLIDE_MIN_CNT = 3; >> - if(atomic_sub_and_test(1, &report_up_event_implement_sync)){ >> - //get the resource >> - if(1 == report_up_event_implement_running){ >> - atomic_inc(&report_up_event_implement_sync); >> - printk("other thread is running the rountine. \n"); >> - return; >> - }else{ >> - report_up_event_implement_running = 1; >> - atomic_inc(&report_up_event_implement_sync); >> - } >> - }else{ >> - printk("failed to get the lock. other thread is using the lock. >> \n"); >> - return; >> - } >> - >> - if(0 == data_timer_status){ >> - printk("report_up_event_implement have been called. \n"); >> - goto report_up_event_implement_out; >> - return; >> - } >> - >> - print_report_status_info("enter report_up_event_implement. jiffies == >> %lu. \n", jiffies); >> - >> - //printk("prev_sample->sample_time =%d, prev_data_sample->sample_time >> = %d. \n", prev_sample->sample_time, prev_data_sample->sample_time); >> - //printk("touch_mode = %d. reported_single_point_cnt = %d. \n", >> touch_mode, reported_single_point_cnt); >> - if( (SINGLE_TOUCH_MODE == touch_mode) && \ >> - (reported_single_point_cnt<SLIDE_MIN_CNT) && >> (reported_single_point_cnt>0) && \ >> - (prev_sample->sample_time >= (prev_data_sample->sample_time + >> UP_EVENT_DELAY_TIME))){ >> - //obvious, a slide, how to compenstate? >> - //printk("report_up_event_implement: obvious, a slide. \n"); >> - report_slide_data(ts_data); >> - } >> - >> - //note: below operation may be interfere by intterrupt, but it does >> not matter >> - input_report_abs(ts_data->input, ABS_MT_TOUCH_MAJOR,0); >> - input_sync(ts_data->input); >> - del_timer(&data_timer); >> - data_timer_status = 0; >> - ts_data->ts_process_status = TP_UP; >> - ts_data->double_point_cnt = 0; >> - //ts_data->buffer_head = 0; >> - //ts_data->buffer_tail = 0; >> - ts_data->touchflag = 0; >> - //ts_data->count = 0; >> - touch_mode = UP_TOUCH_MODE; >> - change_mode = TRUE; >> - reported_single_point_cnt = 0; >> - reported_data_start_time = 0; >> - >> -report_up_event_implement_out: >> - report_up_event_implement_running = 0; >> - >> -#ifdef PRINT_UP_SEPARATOR >> - printk("separator: #######%d, %d, %d###########. \n\n\n\n\n\n\n", >> separator_flag, separator_flag, separator_flag); >> - separator_flag++; >> -#endif >> - >> - return; >> -} >> - >> -static int judge_zoom_orientation(struct ts_sample_data *sample_data) >> -{ >> - int dx,dy; >> - int ret = 0; >> - if(1 == reference_point_flag){ >> - dx = sample_data->x - prev_single_sample.x; >> - dy = sample_data->y - prev_single_sample.y; >> - if(dx*dy > 0){ >> - ret = -1; >> - }else if(dx*dy < 0){ >> - ret = 1; >> - } >> - }else{ >> - print_orientation_info("judge_zoom_orientation: lack >> reference point .\n"); >> - } >> - >> - print_orientation_info("sun4i-ts: orientation_flag == %d . \n", >> ret); >> - return ret; >> -} >> -static void filter_double_point_init(struct ts_sample_data *sample_data, >> int backup_samp_flag) >> -{ >> - //backup prev_double_sample_data >> - zoom_flag = ZOOM_INIT_STATE; >> - accmulate_zoom_out_ds = 0; >> - zoom_out_count = 0; >> - accmulate_zoom_in_ds = 0; >> - zoom_in_count = 0; >> - //printk("sample_data->x = %d, sample_data-> y = %d. \n", >> sample_data->x, sample_data->y); >> - if(1 == backup_samp_flag){ >> - memcpy((void*)(&prev_double_sample_data), >> (void*)sample_data, sizeof(*sample_data)); >> - } >> - >> - hold_cnt = 0; >> - //when report two point, the first two point will be reserved for >> reference purpose. >> - return; >> -} >> - >> -static void change_to_double_mode(struct sun4i_ts_data *ts_data) >> -{ >> - if((CHANGING_TO_DOUBLE_TOUCH_MODE != touch_mode) && \ >> - (DOUBLE_TOUCH_MODE != touch_mode)&& \ >> - (UP_TOUCH_MODE != touch_mode)){ >> - printk("change_to_double_mode: err, not the expected state. >> touch_mode = %d. \n", touch_mode); >> - } >> - touch_mode = DOUBLE_TOUCH_MODE; >> - change_mode = FALSE; >> - ts_data->single_touch_cnt = 0; //according this counter, change >> to single touch mode >> - return; >> -} >> - >> -static void change_to_zoom_in(struct sun4i_ts_data *ts_data, struct >> ts_sample_data *sample_data) >> -{ >> - zoom_flag = ZOOM_IN; >> - zoom_change_cnt = 0; >> - accmulate_zoom_out_ds = 0; >> - zoom_out_count = 0; >> - //orientation_flag = judge_zoom_orientation(sample_data); >> - change_to_double_mode(ts_data); >> - return; >> -} >> - >> -static void change_to_zoom_out(struct sun4i_ts_data *ts_data, struct >> ts_sample_data *sample_data) >> -{ >> - zoom_flag = ZOOM_OUT; >> - zoom_change_cnt = 0; >> - accmulate_zoom_in_ds = 0; >> - zoom_in_count = 0; >> - //orientation_flag = judge_zoom_orientation(sample_data); >> - change_to_double_mode(ts_data); >> - return; >> -} >> - >> -static void filter_zoom_in_data_init(void) >> -{ >> - zoom_in_buffer_cnt = 0; >> - // zoom_out_buffer_cnt = 0; >> - return; >> -} >> - >> -static void filter_zoom_out_data_init(void) >> -{ >> -// zoom_in_buffer_cnt = 0; >> - zoom_out_buffer_cnt = 0; >> - return; >> -} >> -static void filter_zoom_in_data(struct ts_sample_data * report_data, >> struct ts_sample_data *sample_data) >> -{ >> - static int i = 0; >> - static int index = 0; >> - static int count = 0; >> - //backup data to filter noise, only when ds < 40, need this >> operation. >> - >> - //printk("before filter zoom in: sample_data->dx = %d, >> sample_data->dy = %d. \n", sample_data->dx, sample_data->dy); >> - index = zoom_in_buffer_cnt%ZOOM_IN_OUT_BUFFER_SIZE; >> - zoom_in_data_buffer[index].dx = sample_data->dx; >> - zoom_in_data_buffer[index].dy = sample_data->dy; >> - zoom_in_data_buffer[index].x = sample_data->x; >> - zoom_in_data_buffer[index].y = sample_data->y; >> - >> - //printk("zoom_in_buffer_cnt quyu ZOOM_IN_OUT_BUFFER_SIZE = %d. >> \n", index); >> - if(zoom_in_buffer_cnt > (ZOOM_IN_OUT_BUFFER_SIZE<<10)){ >> - zoom_in_buffer_cnt -= (ZOOM_IN_OUT_BUFFER_SIZE<<9); >> - } >> - >> - if(zoom_in_buffer_cnt >= ZOOM_IN_OUT_BUFFER_SIZE){ >> - index = ZOOM_IN_OUT_BUFFER_SIZE - 1; >> - } >> - //index mean the real count. >> - sample_data->dx = 0; >> - sample_data->dy = 0; >> - sample_data->x = 0; >> - sample_data->y = 0; >> - count = 0; >> - for(i = 0; i <= index; i++){ >> - sample_data->dx += zoom_in_data_buffer[i].dx; >> - sample_data->dy += zoom_in_data_buffer[i].dy; >> - sample_data->x += zoom_in_data_buffer[i].x; >> - sample_data->y += zoom_in_data_buffer[i].y; >> - count++; >> - //printk("i = %d. \n", i); >> - } >> - >> - sample_data->dx /= count; >> - sample_data->dy /= count; >> - sample_data->x /= count; >> - sample_data->y /= count; >> - >> - report_data->x = sample_data->x; >> - report_data->y = sample_data->y; >> - report_data->dx = sample_data->dx; >> - report_data->dy = sample_data->dy; >> - >> - //printk("after filter zoom in: sample_data->dx = %d, >> sample_data->dy = %d. \n", sample_data->dx, sample_data->dy); >> - zoom_in_buffer_cnt++; >> - //printk("using mean value for nosie reduction: >> zoom_in_buffer_cnt = %d. \n", zoom_in_buffer_cnt); >> - >> - return; >> -} >> - >> -static void filter_zoom_out_data(struct ts_sample_data * report_data, >> struct ts_sample_data *sample_data) >> -{ >> - static int i = 0; >> - static int index = 0; >> - static int count = 0; >> - //backup data to filter noise, only when ds < 40, need this >> operation. >> - >> - //printk("before filter zoom out: sample_data->dx = %d, >> sample_data->dy = %d. \n", sample_data->dx, sample_data->dy); >> - index = zoom_out_buffer_cnt%ZOOM_IN_OUT_BUFFER_SIZE; >> - zoom_out_data_buffer[index].dx = sample_data->dx; >> - zoom_out_data_buffer[index].dy = sample_data->dy; >> - zoom_out_data_buffer[index].x = sample_data->x; >> - zoom_out_data_buffer[index].y = sample_data->y; >> - >> - //printk("zoom_out_buffer_cnt quyu ZOOM_IN_OUT_BUFFER_SIZE = %d. >> \n", index); >> - if(zoom_out_buffer_cnt > (ZOOM_IN_OUT_BUFFER_SIZE<<10)){ >> - zoom_out_buffer_cnt -= (ZOOM_IN_OUT_BUFFER_SIZE<<9); >> - } >> - >> - if(zoom_out_buffer_cnt >= ZOOM_IN_OUT_BUFFER_SIZE){ >> - index = ZOOM_IN_OUT_BUFFER_SIZE - 1; >> - } >> - //index mean the real count. >> - sample_data->dx = 0; >> - sample_data->dy = 0; >> - sample_data->x = 0; >> - sample_data->y = 0; >> - count = 0; >> - >> - for(i = 0; i <= index; i++){ >> - sample_data->dx += zoom_out_data_buffer[i].dx; >> - sample_data->dy += zoom_out_data_buffer[i].dy; >> - sample_data->x += zoom_out_data_buffer[i].x; >> - sample_data->y += zoom_out_data_buffer[i].y; >> - count++; >> - //printk("i = %d. \n", i); >> - } >> - >> - sample_data->dx /= count; >> - sample_data->dy /= count; >> - sample_data->x /= count; >> - sample_data->y /= count; >> - >> - report_data->x = sample_data->x; >> - report_data->y = sample_data->y; >> - report_data->dx = sample_data->dx; >> - report_data->dy = sample_data->dy; >> - >> - //printk("after filter zoom out: sample_data->dx = %d, >> sample_data->dy = %d. \n", sample_data->dx, sample_data->dy); >> - zoom_out_buffer_cnt++; >> - //printk("using mean value for nosie reduction: >> zoom_out_buffer_cnt = %d. \n", zoom_out_buffer_cnt); >> - >> - return; >> -} >> - >> -static int filter_double_point(struct sun4i_ts_data *ts_data, struct >> ts_sample_data *sample_data) >> -{ >> - int ret = 0; >> - static int prev_sample_ds = 0; >> - static int cur_sample_ds = 0; >> - static int delta_ds = 0; >> - >> - #define DELTA_DS_LIMIT (1) >> - #define HOLD_DS_LIMIT (3) >> - #define ZOOM_IN_CNT_LIMIT (3) >> - #define FIRST_ZOOM_IN_COMPENSTATE (3) >> //actually zoom out, usually with zoom in ops first. >> - #define ZOOM_OUT_CNT_LIMIT (tp_regidity_level) >> //related with screen's regidity >> - #define GLIDE_DELTA_DS_MAX_TIMES (4) >> - #define GLIDE_DELTA_DS_MAX_LIMIT (glide_delta_ds_max_limit) >> - >> - if(ZOOM_INIT_STATE == zoom_flag && (0 == zoom_out_count && 0 == >> zoom_in_count)){ >> - prev_sample_ds = >> int_sqrt((prev_double_sample_data.dx)*(prev_double_sample_data.dx) + >> (prev_double_sample_data.dy)*(prev_double_sample_data.dy)); >> - /*printk("sun4i-ts: prev_double_sample_data->x = %d, >> prev_double_sample_data->y = %d, \ >> - prev_double_sample_data.dx = %d, >> prev_double_sample_data.dy = %d. \n", \ >> - prev_double_sample_data.x, prev_double_sample_data.y, >> prev_double_sample_data.dx, prev_double_sample_data.dy); >> - */ >> - } >> - >> - cur_sample_ds = int_sqrt((sample_data->dx)*(sample_data->dx) + >> (sample_data->dy)*(sample_data->dy)); >> - delta_ds = cur_sample_ds - prev_sample_ds; >> - //print_filter_double_point_status_info("delta_ds = %d, >> prev_sample_ds = %d, cur_sample_ds = %d. \n", delta_ds, prev_sample_ds, >> cur_sample_ds); >> - /*print_filter_double_point_status_info("zoom_in_count = %d, >> accmulate_zoom_in_ds = %d, zoom_out_count = %d, accmulate_zoom_out_ds=%d. >> \n", \ >> - zoom_in_count, accmulate_zoom_in_ds, zoom_out_count, >> accmulate_zoom_out_ds); >> - */ >> - >> - //update prev_double_sample_data >> - memcpy((void*)&prev_double_sample_data, (void*)sample_data, >> sizeof(*sample_data)); >> - prev_sample_ds = cur_sample_ds; >> - //printk("prev_sample_ds = %d, cur_sample_ds = %d. \n", >> prev_sample_ds, cur_sample_ds); >> - >> - if(delta_ds > HOLD_DS_LIMIT){//zoom in >> - >> - if(ZOOM_OUT == zoom_flag){//zoom in when zoom out >> - //printk("delta_ds = %d, (4*accmulate_zoom_out_ds/zoom_out_count) >> = %d. \n", delta_ds, >> (GLIDE_DELTA_DS_MAX_TIMES*accmulate_zoom_out_ds/zoom_out_count)); >> - if(delta_ds > min(GLIDE_DELTA_DS_MAX_LIMIT, >> (GLIDE_DELTA_DS_MAX_TIMES*accmulate_zoom_out_ds/zoom_out_count))){ >> - //noise >> - //printk("delta_ds = %d, prev_sample_ds = %d, >> cur_sample_ds = %d. \n", delta_ds, prev_sample_ds, cur_sample_ds); >> - cur_sample_ds = prev_sample_ds; //discard the >> noise, and can not be reference. >> - //printk("delta_ds = %d, >> (4*accmulate_zoom_out_ds/zoom_out_count) = %d. \n", delta_ds, >> (4*accmulate_zoom_out_ds/zoom_out_count)); >> - print_filter_double_point_status_info("sun4i-ts: noise, >> zoom in when zoom out. \n"); >> - //printk("discard noise. \n"); >> - ret = TRUE; >> - }else{ >> - //normal zoom in >> - zoom_change_cnt++; >> - accmulate_zoom_in_ds += delta_ds; >> - zoom_in_count++; >> - if(zoom_change_cnt > ZOOM_IN_CNT_LIMIT){ >> - print_filter_double_point_status_info("change to >> ZOOM_IN from ZOOM_OUT. \n"); >> - change_to_zoom_in(ts_data, sample_data); >> - filter_zoom_in_data_init(); >> - filter_zoom_in_data(&prev_report_samp, sample_data); >> - }else{ >> - //zoom_change_cnt = 0; >> - print_filter_double_point_status_info("sun4i-ts: >> normal zoom in, but this will cause twitter. \n"); >> - ret = TRUE; >> - } >> - } >> - //accmulate_zoom_out_ds -= delta_ds; >> - //zoom_out_count++; >> - }else if(ZOOM_IN == zoom_flag){ >> - if(delta_ds > min(GLIDE_DELTA_DS_MAX_LIMIT, >> (GLIDE_DELTA_DS_MAX_TIMES*accmulate_zoom_in_ds/zoom_in_count))){ >> - cur_sample_ds = prev_sample_ds; //discard the >> noise, and can not be reference. >> - //printk("discard noise. \n"); >> - ret = TRUE; >> - }else{ >> - accmulate_zoom_in_ds += delta_ds; >> - zoom_in_count++; >> - filter_zoom_in_data(&prev_report_samp, sample_data); >> - } >> - zoom_change_cnt = 0; >> - accmulate_zoom_out_ds = 0; >> - zoom_out_count = 0; >> - #if 0 >> - printk("ZOOM_IN: delta_ds= %d. \n", delta_ds); >> - #endif >> - }else if(ZOOM_INIT_STATE == zoom_flag ||ZOOM_STATIC == >> zoom_flag){ >> - zoom_in_count++; >> - if(zoom_in_count > (ZOOM_CHANGE_LIMIT_CNT + >> FIRST_ZOOM_IN_COMPENSTATE)){ >> - accmulate_zoom_in_ds = delta_ds; >> - zoom_in_count = 1; >> - if(ZOOM_INIT_STATE == zoom_flag){ >> - orientation_flag = >> judge_zoom_orientation(sample_data); >> - report_up_event_implement(ts_data); >> - } >> - filter_zoom_in_data_init(); >> - filter_zoom_in_data(&prev_report_samp, sample_data); >> - print_filter_double_point_status_info("change to ZOOM_IN >> from ZOOM_INIT_STATE. \n"); >> - change_to_zoom_in(ts_data, sample_data); >> - #if 1 >> - print_filter_double_point_status_info("ZOOM_INIT_STATE: >> delta_ds= %d. \n", delta_ds); >> - #endif >> - }else{ >> - ret = TRUE; >> - } >> - >> - } >> - }else if(delta_ds<(-HOLD_DS_LIMIT)){//zoom out >> - delta_ds = -delta_ds; >> - >> - if(ZOOM_IN == zoom_flag){//zoom out when zoom in >> - print_filter_double_point_status_info("delta_ds = %d, >> (4*accmulate_zoom_in_ds/zoom_in_count) = %d. \n", -delta_ds, >> (4*accmulate_zoom_in_ds/zoom_in_count)); >> - if(delta_ds > min(GLIDE_DELTA_DS_MAX_LIMIT, >> (GLIDE_DELTA_DS_MAX_TIMES*accmulate_zoom_in_ds/zoom_in_count))){ //noise >> - //printk("delta_ds = %d, prev_sample_ds = %d, cur_sample_ds = >> %d. \n", delta_ds, prev_sample_ds, cur_sample_ds); >> - cur_sample_ds = prev_sample_ds; //discard the >> noise, and can not be reference. >> - print_filter_double_point_status_info("sun4i-ts: noise, >> zoom out when zoom in. \n"); >> - //printk("discard noise. \n"); >> - //zoom_change_cnt = 0; >> - ret = TRUE; >> - }else{//normal zoom out >> - zoom_change_cnt++; >> - accmulate_zoom_out_ds += delta_ds; >> - zoom_out_count++; >> - if(zoom_change_cnt > ZOOM_OUT_CNT_LIMIT){ >> - print_filter_double_point_status_info("change to >> ZOOM_OUT from ZOOM_IN. \n"); >> - change_to_zoom_out(ts_data, sample_data); >> - filter_zoom_out_data_init(); >> - filter_zoom_out_data(&prev_report_samp, sample_data); >> - }else{ >> - //zoom_change_cnt = 0; >> - print_filter_double_point_status_info("sun4i-ts: >> normal zoom out, but this will cause twitter. \n"); >> - ret = TRUE; >> - } >> - } >> - //accmulate_zoom_in_ds -= delta_ds; >> - //zoom_in_count++; >> - }else if(ZOOM_OUT == zoom_flag){ //zoom out when zoom out >> - if(delta_ds > min(GLIDE_DELTA_DS_MAX_LIMIT, >> (GLIDE_DELTA_DS_MAX_TIMES*accmulate_zoom_out_ds/zoom_out_count))){ >> - cur_sample_ds = prev_sample_ds; >> - //printk("discard noise. \n"); >> - ret = TRUE; >> - }else{ >> - accmulate_zoom_out_ds += delta_ds; >> - zoom_out_count++; >> - filter_zoom_out_data(&prev_report_samp, sample_data); >> - } >> - zoom_change_cnt = 0; >> - accmulate_zoom_in_ds = 0; >> - zoom_in_count = 0; >> - //printk("ZOOM_OUT: delta_ds= %d. \n", delta_ds); >> - }else if(ZOOM_INIT_STATE == zoom_flag ||ZOOM_STATIC == >> zoom_flag){ >> - zoom_out_count ++; >> - if(zoom_out_count > ZOOM_CHANGE_LIMIT_CNT){ >> - accmulate_zoom_out_ds = delta_ds; >> - zoom_out_count = 1; >> - if(ZOOM_INIT_STATE == zoom_flag){ >> - orientation_flag = >> judge_zoom_orientation(sample_data); >> - report_up_event_implement(ts_data); >> - } >> - filter_zoom_out_data_init(); >> - filter_zoom_out_data(&prev_report_samp, sample_data); >> - print_filter_double_point_status_info("change to ZOOM_OUT >> from ZOOM_INIT_STATE. \n"); >> - change_to_zoom_out(ts_data, sample_data); >> - #if 1 >> - print_filter_double_point_status_info("ZOOM_INIT_STATE: >> delta_ds= %d. \n", delta_ds); >> - #endif >> - }else{ >> - //have not known orientation, discard the point >> - ret = TRUE; >> - } >> - >> - } >> - >> - }else{ //delta_ds <= HOLD_DS_LIMIT, static mode >> - //printk("delta_ds == %d. \n", delta_ds); >> - //zoom_change_cnt >> - //printk("delta_ds == %d. \n", delta_ds); >> - hold_cnt++; >> - cur_sample_ds = prev_sample_ds; >> - if(hold_cnt > 100000){ >> - hold_cnt = 100; >> - } >> - >> - if(unlikely(ZOOM_INIT_STATE == zoom_flag )){ >> - >> print_filter_double_point_status_info("ZOOM_INIT_STATE: delta_ds == %d. >> \n", delta_ds); >> - if(hold_cnt <= ZOOM_CHANGE_LIMIT_CNT){ //discard the >> first 3 point >> - ret = TRUE; >> - }else{ >> - //when change to static mode, and not know >> orientation yet, need judge orientation. >> - orientation_flag = >> judge_zoom_orientation(sample_data); >> - report_up_event_implement(ts_data); >> - zoom_flag = ZOOM_STATIC; >> - change_to_double_mode(ts_data); >> - memcpy((void*)&prev_report_samp, >> (void*)sample_data, sizeof(*sample_data)); >> - } >> - }else{ >> - memcpy((void*)sample_data, (void*)&prev_report_samp, >> sizeof(*sample_data)); >> - } >> - >> - //filter_double_point_init(sample_data, 0); >> - >> - } >> - >> - >> - return ret; >> - >> -} >> -static void report_double_point(struct sun4i_ts_data *ts_data, struct >> ts_sample_data *... > > -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
