aboutsummaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/ts_filter_variance.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/ts_filter_variance.c')
-rw-r--r--drivers/input/touchscreen/ts_filter_variance.c205
1 files changed, 0 insertions, 205 deletions
diff --git a/drivers/input/touchscreen/ts_filter_variance.c b/drivers/input/touchscreen/ts_filter_variance.c
deleted file mode 100644
index c3352105c9f..00000000000
--- a/drivers/input/touchscreen/ts_filter_variance.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Copyright (C) 2008 by Openmoko, Inc.
- * Author: Nelson Castillo <arhuaco@freaks-unidos.net>
- * All rights reserved.
- *
- * This filter is useful to reject clicks that are not reliable. We
- * only care about what happens when we receive DOWN events for the fist time.
- * If this filter does not reject the first samples then it will change
- * its internal state to "passed" and the remaining samples
- * will be passed to the next filter in the chain.
- *
- * First we collect N samples, then then we sort them. We discard the borders
- * (with a window) and then compute the variance of the remaining set.
- * If the computed variance is bigger than a threshold, we reject the click.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sort.h>
-#include <linux/ts_filter_variance.h>
-
-static void ts_filter_variance_clear_internal(struct ts_filter_variance *tsfv,
- int attempts)
-{
- tsfv->N = 0;
- tsfv->passed = 0;
- tsfv->tries_left = attempts;
-}
-
-static void ts_filter_variance_clear(struct ts_filter *tsf)
-{
- struct ts_filter_variance *tsfv = (struct ts_filter_variance *)tsf;
-
- ts_filter_variance_clear_internal(tsfv, tsfv->config->attempts);
-
- if (tsf->next) /* chain */
- (tsf->next->api->clear)(tsf->next);
-}
-
-static struct ts_filter *ts_filter_variance_create(void *conf, int count_coords)
-{
- struct ts_filter_variance *tsfv;
- int i;
-
- BUG_ON((count_coords < 1) || (count_coords > MAX_TS_FILTER_COORDS));
-
- tsfv = kzalloc(sizeof(struct ts_filter_variance), GFP_KERNEL);
- if (!tsfv)
- return NULL;
-
- tsfv->config = (struct ts_filter_variance_configuration *)conf;
- tsfv->tsf.count_coords = count_coords;
-
- BUG_ON(tsfv->config->attempts <= 0);
-
- tsfv->samples[0] = kmalloc(count_coords * sizeof(int) *
- tsfv->config->extent, GFP_KERNEL);
- if (!tsfv->samples[0]) {
- kfree(tsfv);
- return NULL;
- }
- for (i = 1; i < count_coords; ++i)
- tsfv->samples[i] = tsfv->samples[0] + i * tsfv->config->extent;
-
- ts_filter_variance_clear_internal(tsfv, tsfv->config->attempts);
-
- printk(KERN_INFO" Created Variance ts filter len %d depth %d window"
- " %d thresh %d\n", tsfv->config->extent,
- count_coords, tsfv->config->window,
- tsfv->config->threshold);
-
- /* scale the threshold to avoid divisions later */
- tsfv->config->threshold *= tsfv->config->extent -
- (tsfv->config->window << 1);
-
- return &tsfv->tsf;
-}
-
-static void ts_filter_variance_destroy(struct ts_filter *tsf)
-{
- struct ts_filter_variance *tsfv = (struct ts_filter_variance *)tsf;
-
- kfree(tsfv->samples[0]); /* first guy has pointer from kmalloc */
- kfree(tsf);
-}
-
-static void ts_filter_variance_scale(struct ts_filter *tsf, int *coords)
-{
- struct ts_filter_variance *tsfv = (struct ts_filter_variance *)tsf;
-
- if (!tsfv->passed)
- return;
-
- if (tsf->next) {
- (tsf->next->api->scale)(tsf->next, coords);
- } else {
- int n;
- for (n = 0; n < tsf->count_coords; n++) {
- int c = tsfv->samples[n][tsfv->N / 2] +
- tsfv->samples[n][tsfv->N / 2 + 1] +
- tsfv->samples[n][tsfv->N / 2 - 1];
- coords[n] = (c + 2) / 3;
- }
- }
-}
-
-static int int_cmp(const void *_a, const void *_b)
-{
- const int *a = _a;
- const int *b = _b;
-
- if (*a > *b)
- return 1;
- if (*a < *b)
- return -1;
- return 0;
-}
-
-/* give us the raw sample data coords, and if we return 1 then you can
- * get a filtered coordinate from coords: if we return 0 you didn't
- * fill all the filters with samples yet.
- */
-
-static int ts_filter_variance_process(struct ts_filter *tsf, int *coords)
-{
- struct ts_filter_variance *tsfv = (struct ts_filter_variance *)tsf;
- int n;
-
- if (tsfv->passed) { /* chain */
- if (tsf->next)
- return (tsf->next->api->process)(tsf->next, coords);
- return 1;
- }
-
- for (n = 0; n < tsf->count_coords; n++)
- tsfv->samples[n][tsfv->N] = coords[n];
-
- if (++tsfv->N < tsfv->config->extent)
- return 0; /* we meed more samples */
-
- tsfv->passed = 1;
-
- for (n = 0; n < tsfv->tsf.count_coords; n++) {
- int i;
- int avg = 0;
- int variance = 0;
-
- sort(tsfv->samples[n], tsfv->config->extent, sizeof(int),
- int_cmp, NULL);
-
- for (i = tsfv->config->window; i < tsfv->config->extent -
- tsfv->config->window; ++i)
- avg += tsfv->samples[n][i];
-
- avg /= tsfv->config->extent - (tsfv->config->window << 1);
-
- for (i = tsfv->config->window; i < tsfv->config->extent -
- tsfv->config->window; ++i) {
- int s = tsfv->samples[n][i] - avg;
- variance += s * s;
- }
-
- if (variance > tsfv->config->threshold) {
- tsfv->passed = 0;
- break;
- }
- }
-
- if (tsfv->passed) /* Let's reuse the last sample */
- return ts_filter_variance_process(tsf, coords);
-
- if (--tsfv->tries_left) {
- ts_filter_variance_clear_internal(tsfv, tsfv->tries_left);
- return 0; /* ask for more samples */
- }
-
- /* avoid overflow if we are called again without clearing the filter */
- ts_filter_variance_clear_internal(tsfv, tsfv->config->attempts);
-
- return -1;
-}
-
-struct ts_filter_api ts_filter_variance_api = {
- .create = ts_filter_variance_create,
- .destroy = ts_filter_variance_destroy,
- .clear = ts_filter_variance_clear,
- .process = ts_filter_variance_process,
- .scale = ts_filter_variance_scale,
-};
-