diff options
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/s3c2410_ts.c | 102 | ||||
-rw-r--r-- | drivers/input/touchscreen/ts_filter.c | 3 | ||||
-rw-r--r-- | drivers/input/touchscreen/ts_filter_mean.c | 6 | ||||
-rw-r--r-- | drivers/input/touchscreen/ts_filter_median.c | 3 |
4 files changed, 50 insertions, 64 deletions
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 8f0afc3e023..8e580a833e5 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -98,9 +98,10 @@ static char *s3c2410ts_name = "s3c2410 TouchScreen"; struct s3c2410ts { struct input_dev *dev; - int flag_first_touch_sent; struct ts_filter *tsf[MAX_TS_FILTER_CHAIN]; int coords[2]; /* just X and Y for us */ + int is_down; + int need_to_send_first_touch; }; static struct s3c2410ts ts; @@ -116,69 +117,58 @@ static inline void s3c2410_ts_connect(void) s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON); } -static void touch_timer_fire(unsigned long data) -{ - unsigned long data0; - unsigned long data1; - int updown; - - data0 = readl(base_addr + S3C2410_ADCDAT0); - data1 = readl(base_addr + S3C2410_ADCDAT1); +enum ts_input_event {IE_DOWN = 0, IE_UP, IE_UPDATE}; - updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && - (!(data1 & S3C2410_ADCDAT0_UPDOWN)); - - // if we need to send an untouch event, but we haven't yet sent the - // touch event (this happens if the touchscreen was tapped lightly), - // send the touch event first - if (!updown && !ts.flag_first_touch_sent) { - if (ts.tsf[0]) - (ts.tsf[0]->api->scale)(ts.tsf[0], &ts.coords[0]); +static void ts_input_report(int event) +{ + if (event == IE_DOWN || event == IE_UPDATE) { input_report_abs(ts.dev, ABS_X, ts.coords[0]); input_report_abs(ts.dev, ABS_Y, ts.coords[1]); - input_report_key(ts.dev, BTN_TOUCH, 1); input_report_abs(ts.dev, ABS_PRESSURE, 1); - input_sync(ts.dev); - ts.flag_first_touch_sent = 1; + } else { + input_report_key(ts.dev, BTN_TOUCH, 0); + input_report_abs(ts.dev, ABS_PRESSURE, 0); } - if (updown) { - - if (ts.tsf[0]) - (ts.tsf[0]->api->scale)(ts.tsf[0], &ts.coords[0]); + input_sync(ts.dev); #ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG - { - struct timeval tv; - - do_gettimeofday(&tv); - printk(DEBUG_LVL "T:%06d, X:%03ld, Y:%03ld\n", - (int)tv.tv_usec, ts.coords[0], ts.coords[1]); - } + { + static char *s[] = {"down", "up", "update"}; + struct timeval tv; + do_gettimeofday(&tv); + printk(DEBUG_LVL "T:%06d %6s (X:%03d, Y:%03d)\n", + (int)tv.tv_usec, s[event], ts.coords[0], ts.coords[1]); + } #endif +} +static void touch_timer_fire(unsigned long data) +{ + if (ts.tsf[0]) + (ts.tsf[0]->api->scale)(ts.tsf[0], &ts.coords[0]); + + if (ts.need_to_send_first_touch) { + ts.need_to_send_first_touch = 0; + ts_input_report(IE_DOWN); + if (!ts.is_down) { /* Do we need this? I think so. */ + ts_input_report(IE_UPDATE); + ts_input_report(IE_UP); + } + } else if (ts.is_down) { + ts_input_report(IE_UPDATE); + } else { + ts_input_report(IE_UP); + } - input_report_abs(ts.dev, ABS_X, ts.coords[0]); - input_report_abs(ts.dev, ABS_Y, ts.coords[1]); - - input_report_key(ts.dev, BTN_TOUCH, 1); - input_report_abs(ts.dev, ABS_PRESSURE, 1); - input_sync(ts.dev); - + if (ts.is_down) { writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC); writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON); } else { - if (ts.tsf[0]) (ts.tsf[0]->api->clear)(ts.tsf[0]); - - input_report_key(ts.dev, BTN_TOUCH, 0); - input_report_abs(ts.dev, ABS_PRESSURE, 0); - input_sync(ts.dev); - ts.flag_first_touch_sent = 0; - writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); } } @@ -190,20 +180,20 @@ static irqreturn_t stylus_updown(int irq, void *dev_id) { unsigned long data0; unsigned long data1; - int updown; data0 = readl(base_addr+S3C2410_ADCDAT0); data1 = readl(base_addr+S3C2410_ADCDAT1); - updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && + ts.is_down = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); - /* TODO we should never get an interrupt with updown set while - * the timer is running, but maybe we ought to verify that the - * timer isn't running anyways. */ - - if (updown) - touch_timer_fire(0); + if (ts.is_down) { + ts.need_to_send_first_touch = 1; + writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, + base_addr+S3C2410_ADCTSC); + writel(readl(base_addr+S3C2410_ADCCON) | + S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON); + } return IRQ_HANDLED; } @@ -336,7 +326,9 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) else /* this is OK, just means there won't be any filtering */ dev_info(&pdev->dev, "Unfiltered output selected\n"); - if (!ts.tsf[0]) + if (ts.tsf[0]) + (ts.tsf[0]->api->clear)(ts.tsf[0]); + else dev_info(&pdev->dev, "No filtering\n"); /* Get irqs */ diff --git a/drivers/input/touchscreen/ts_filter.c b/drivers/input/touchscreen/ts_filter.c index f8b2b2f5846..4c650a5c66f 100644 --- a/drivers/input/touchscreen/ts_filter.c +++ b/drivers/input/touchscreen/ts_filter.c @@ -49,9 +49,12 @@ EXPORT_SYMBOL_GPL(ts_filter_create_chain); void ts_filter_destroy_chain(struct ts_filter **list) { + struct ts_filter **first; + first = list; while (*list) { ((*list)->api->destroy)(*list); list++; } + *first = NULL; } EXPORT_SYMBOL_GPL(ts_filter_destroy_chain); diff --git a/drivers/input/touchscreen/ts_filter_mean.c b/drivers/input/touchscreen/ts_filter_mean.c index b589bee826f..2322432fc3f 100644 --- a/drivers/input/touchscreen/ts_filter_mean.c +++ b/drivers/input/touchscreen/ts_filter_mean.c @@ -94,12 +94,6 @@ static void ts_filter_mean_destroy(struct ts_filter *tsf) { struct ts_filter_mean *tsfs = (struct ts_filter_mean *)tsf; - if (!tsf) - return; - - if (tsf->next) /* chain */ - (tsf->next->api->destroy)(tsf->next); - kfree(tsfs->fifo[0]); /* first guy has pointer from kmalloc */ kfree(tsf); } diff --git a/drivers/input/touchscreen/ts_filter_median.c b/drivers/input/touchscreen/ts_filter_median.c index fe1b35f110b..47970da3c6a 100644 --- a/drivers/input/touchscreen/ts_filter_median.c +++ b/drivers/input/touchscreen/ts_filter_median.c @@ -119,9 +119,6 @@ static void ts_filter_median_destroy(struct ts_filter *tsf) { struct ts_filter_median *tsfm = (struct ts_filter_median *)tsf; - if (tsf->next) /* chain */ - (tsf->next->api->destroy)(tsf->next); - kfree(tsfm->sort[0]); /* first guy has pointer from kmalloc */ kfree(tsf); } |