s3c2442: R.I.P.
[openwrt/svn-archive/archive.git] / target / linux / s3c24xx / files-2.6.30 / drivers / input / touchscreen / ts_filter_group.c
diff --git a/target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_group.c b/target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_group.c
deleted file mode 100644 (file)
index f53f16d..0000000
+++ /dev/null
@@ -1,296 +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,2009 by Openmoko, Inc.
- * Author: Nelson Castillo <arhuaco@freaks-unidos.net>
- * All rights reserved.
- *
- *
- * This filter is useful to reject samples that are not reliable. We consider
- * that a sample is not reliable if it deviates form the Majority.
- *
- * 1) We collect S samples.
- *
- * 2) For each dimension:
- *
- *  - We sort the points.
- *  - Points that are "close enough" are considered to be in the same set.
- *  - We choose the set with more elements. If more than "threshold"
- *    points are in this set we use the first and the last point of the set
- *    to define the valid range for this dimension [min, max], otherwise we
- *    discard all the points and go to step 1.
- *
- * 3) We consider the unsorted S samples and try to feed them to the next
- *    filter in the chain. If one of the points of each sample
- *    is not in the allowed range for its dimension, we discard the sample.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sort.h>
-#include <linux/touchscreen/ts_filter_group.h>
-
-struct ts_filter_group {
-       /* Private filter configuration. */
-       struct ts_filter_group_configuration *config;
-       /* Filter API. */
-       struct ts_filter tsf;
-
-       int N;                  /* How many samples we have. */
-       int *samples[MAX_TS_FILTER_COORDS];     /* The samples: our input. */
-
-       int *group_size;        /* Used for temporal computations. */
-       int *sorted_samples;    /* Used for temporal computations. */
-
-       int range_max[MAX_TS_FILTER_COORDS];    /* Max. computed ranges. */
-       int range_min[MAX_TS_FILTER_COORDS];    /* Min. computed ranges. */
-
-       int tries_left;         /* We finish if we don't get enough samples. */
-       int ready;              /* If we are ready to deliver samples. */
-       int result;             /* Index of the point being returned. */
-};
-
-#define ts_filter_to_filter_group(f) \
-       container_of(f, struct ts_filter_group, tsf)
-
-
-static void ts_filter_group_clear_internal(struct ts_filter_group *tsfg,
-                                          int attempts)
-{
-       tsfg->N = 0;
-       tsfg->tries_left = attempts;
-       tsfg->ready = 0;
-       tsfg->result = 0;
-}
-
-static void ts_filter_group_clear(struct ts_filter *tsf)
-{
-       struct ts_filter_group *tsfg = ts_filter_to_filter_group(tsf);
-
-       ts_filter_group_clear_internal(tsfg, tsfg->config->attempts);
-}
-
-static struct ts_filter *ts_filter_group_create(
-       struct platform_device *pdev,
-       const struct ts_filter_configuration *conf,
-       int count_coords)
-{
-       struct ts_filter_group *tsfg;
-       int i;
-
-       tsfg = kzalloc(sizeof(struct ts_filter_group), GFP_KERNEL);
-       if (!tsfg)
-               return NULL;
-
-       tsfg->config = container_of(conf,
-                                   struct ts_filter_group_configuration,
-                                   config);
-       tsfg->tsf.count_coords = count_coords;
-
-       BUG_ON(tsfg->config->attempts <= 0);
-
-       tsfg->samples[0] = kmalloc((2 + count_coords) * sizeof(int) *
-                                  tsfg->config->length, GFP_KERNEL);
-       if (!tsfg->samples[0]) {
-               kfree(tsfg);
-               return NULL;
-       }
-       for (i = 1; i < count_coords; ++i)
-               tsfg->samples[i] = tsfg->samples[0] + i * tsfg->config->length;
-       tsfg->sorted_samples = tsfg->samples[0] + count_coords *
-                              tsfg->config->length;
-       tsfg->group_size = tsfg->samples[0] + (1 + count_coords) *
-                              tsfg->config->length;
-
-       ts_filter_group_clear_internal(tsfg, tsfg->config->attempts);
-
-       dev_info(&pdev->dev, "Created Group filter len:%d coords:%d close:%d "
-                "thresh:%d\n", tsfg->config->length, count_coords,
-                tsfg->config->close_enough, tsfg->config->threshold);
-
-       return &tsfg->tsf;
-}
-
-static void ts_filter_group_destroy(struct ts_filter *tsf)
-{
-       struct ts_filter_group *tsfg = ts_filter_to_filter_group(tsf);
-
-       kfree(tsfg->samples[0]); /* first guy has pointer from kmalloc */
-       kfree(tsf);
-}
-
-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;
-}
-
-static void ts_filter_group_prepare_next(struct ts_filter *tsf);
-
-static int ts_filter_group_process(struct ts_filter *tsf, int *coords)
-{
-       struct ts_filter_group *tsfg = ts_filter_to_filter_group(tsf);
-       int n;
-       int i;
-
-       BUG_ON(tsfg->N >= tsfg->config->length);
-       BUG_ON(tsfg->ready);
-
-       for (n = 0; n < tsf->count_coords; n++)
-               tsfg->samples[n][tsfg->N] = coords[n];
-
-       if (++tsfg->N < tsfg->config->length)
-               return 0;       /* We need more samples. */
-
-       for (n = 0; n < tsfg->tsf.count_coords; n++) {
-               int *v = tsfg->sorted_samples;
-               int ngroups = 0;
-               int best_size;
-               int best_idx = 0;
-               int idx = 0;
-
-               memcpy(v, tsfg->samples[n], tsfg->N * sizeof(int));
-               /*
-                * FIXME: Remove this sort call. We already have the
-                * algorithm for this modification. The filter will
-                * need less points (about half) if there is not a
-                * lot of noise. Right now we are doing a constant
-                * amount of work no matter how much noise we are
-                * dealing with.
-                */
-               sort(v, tsfg->N, sizeof(int), int_cmp, NULL);
-
-               tsfg->group_size[0] = 1;
-               for (i = 1; i < tsfg->N; ++i) {
-                       if (v[i] - v[i - 1] <= tsfg->config->close_enough)
-                               tsfg->group_size[ngroups]++;
-                       else
-                               tsfg->group_size[++ngroups] = 1;
-               }
-               ngroups++;
-
-               best_size = tsfg->group_size[0];
-               for (i = 1; i < ngroups; i++) {
-                       idx += tsfg->group_size[i - 1];
-                       if (best_size < tsfg->group_size[i]) {
-                               best_size = tsfg->group_size[i];
-                               best_idx = idx;
-                       }
-               }
-
-               if (best_size < tsfg->config->threshold) {
-                       /* This set is not good enough for us. */
-                       if (--tsfg->tries_left) {
-                               ts_filter_group_clear_internal
-                                       (tsfg, tsfg->tries_left);
-                               /* No errors but we need more samples. */
-                               return 0;
-                       }
-                       return 1; /* We give up: error. */
-               }
-
-               tsfg->range_min[n] = v[best_idx];
-               tsfg->range_max[n] = v[best_idx + best_size - 1];
-       }
-
-       ts_filter_group_prepare_next(tsf);
-
-       return 0;
-}
-
-/*
- * This private function prepares a point that will be returned
- * in ts_filter_group_getpoint if it is available. It updates
- * the priv->ready state also.
- */
-static void ts_filter_group_prepare_next(struct ts_filter *tsf)
-{
-       struct ts_filter_group *priv = ts_filter_to_filter_group(tsf);
-       int n;
-
-       while (priv->result < priv->N) {
-               for (n = 0; n < priv->tsf.count_coords; ++n) {
-                       if (priv->samples[n][priv->result] <
-                           priv->range_min[n] ||
-                           priv->samples[n][priv->result] > priv->range_max[n])
-                               break;
-               }
-
-               if (n == priv->tsf.count_coords) /* Sample is OK. */
-                       break;
-
-               priv->result++;
-       }
-
-       if (unlikely(priv->result >= priv->N)) { /* No sample to deliver. */
-               ts_filter_group_clear_internal(priv, priv->config->attempts);
-               priv->ready = 0;
-       } else {
-               priv->ready = 1;
-       }
-}
-
-static int ts_filter_group_haspoint(struct ts_filter *tsf)
-{
-       struct ts_filter_group *priv = ts_filter_to_filter_group(tsf);
-
-       return priv->ready;
-}
-
-static void ts_filter_group_getpoint(struct ts_filter *tsf, int *point)
-{
-       struct ts_filter_group *priv = ts_filter_to_filter_group(tsf);
-       int n;
-
-       BUG_ON(!priv->ready);
-
-       for (n = 0; n < priv->tsf.count_coords; n++)
-               point[n] = priv->samples[n][priv->result];
-
-       priv->result++;
-
-       /* This call will update priv->ready. */
-       ts_filter_group_prepare_next(tsf);
-}
-
-/*
- * Get ready to process the next batch of points, forget
- * points we could have delivered.
- */
-static void ts_filter_group_scale(struct ts_filter *tsf, int *coords)
-{
-       struct ts_filter_group *priv = ts_filter_to_filter_group(tsf);
-
-       ts_filter_group_clear_internal(priv, priv->config->attempts);
-}
-
-const struct ts_filter_api ts_filter_group_api = {
-       .create =       ts_filter_group_create,
-       .destroy =      ts_filter_group_destroy,
-       .clear =        ts_filter_group_clear,
-       .process =      ts_filter_group_process,
-       .haspoint =     ts_filter_group_haspoint,
-       .getpoint =     ts_filter_group_getpoint,
-       .scale =        ts_filter_group_scale,
-};
-EXPORT_SYMBOL_GPL(ts_filter_group_api);
-