2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * Copyright (c) 2008,2009
17 * Andy Green <andy@openmoko.com>
18 * Nelson Castillo <arhuaco@freaks-unidos.net>
24 #include <linux/errno.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
28 #include <linux/touchscreen/ts_filter_mean.h>
30 struct ts_filter_mean
{
31 /* Copy of the private filter configuration. */
32 struct ts_filter_mean_configuration
*config
;
36 /* Index on a circular buffer. */
38 /* Useful to tell if the circular buffer is full(read:ready). */
40 /* Sumation used to compute the mean. */
41 int sum
[MAX_TS_FILTER_COORDS
];
42 /* Keep point values and decrement them from the sum on time. */
43 int *fifo
[MAX_TS_FILTER_COORDS
];
44 /* Store the output of this filter. */
48 #define ts_filter_to_filter_mean(f) container_of(f, struct ts_filter_mean, tsf)
51 static void ts_filter_mean_clear(struct ts_filter
*tsf
);
53 static struct ts_filter
*ts_filter_mean_create(
54 struct platform_device
*pdev
,
55 const struct ts_filter_configuration
*conf
,
58 struct ts_filter_mean
*priv
;
62 priv
= kzalloc(sizeof(struct ts_filter_mean
), GFP_KERNEL
);
66 priv
->tsf
.count_coords
= count_coords
;
67 priv
->config
= container_of(conf
,
68 struct ts_filter_mean_configuration
,
71 BUG_ON(priv
->config
->length
<= 0);
73 v
= kmalloc(priv
->config
->length
* sizeof(int) * count_coords
,
78 for (n
= 0; n
< count_coords
; n
++) {
80 v
+= priv
->config
->length
;
83 ts_filter_mean_clear(&priv
->tsf
);
85 dev_info(&pdev
->dev
, "Created Mean filter len:%d coords:%d\n",
86 priv
->config
->length
, count_coords
);
91 static void ts_filter_mean_destroy(struct ts_filter
*tsf
)
93 struct ts_filter_mean
*priv
= ts_filter_to_filter_mean(tsf
);
95 kfree(priv
->fifo
[0]); /* first guy has pointer from kmalloc */
99 static void ts_filter_mean_clear(struct ts_filter
*tsf
)
101 struct ts_filter_mean
*priv
= ts_filter_to_filter_mean(tsf
);
106 memset(priv
->sum
, 0, tsf
->count_coords
* sizeof(int));
109 static int ts_filter_mean_process(struct ts_filter
*tsf
, int *coords
)
111 struct ts_filter_mean
*priv
= ts_filter_to_filter_mean(tsf
);
116 for (n
= 0; n
< tsf
->count_coords
; n
++) {
117 priv
->sum
[n
] += coords
[n
];
118 priv
->fifo
[n
][priv
->curr
] = coords
[n
];
121 if (priv
->count
+ 1 == priv
->config
->length
)
126 priv
->curr
= (priv
->curr
+ 1) % priv
->config
->length
;
128 return 0; /* No error. */
131 static int ts_filter_mean_haspoint(struct ts_filter
*tsf
)
133 struct ts_filter_mean
*priv
= ts_filter_to_filter_mean(tsf
);
138 static void ts_filter_mean_getpoint(struct ts_filter
*tsf
, int *point
)
140 struct ts_filter_mean
*priv
= ts_filter_to_filter_mean(tsf
);
143 BUG_ON(!priv
->ready
);
145 for (n
= 0; n
< tsf
->count_coords
; n
++) {
146 point
[n
] = priv
->sum
[n
];
147 priv
->sum
[n
] -= priv
->fifo
[n
][priv
->curr
];
153 static void ts_filter_mean_scale(struct ts_filter
*tsf
, int *coords
)
156 struct ts_filter_mean
*priv
= ts_filter_to_filter_mean(tsf
);
158 for (n
= 0; n
< tsf
->count_coords
; n
++) {
159 coords
[n
] += priv
->config
->length
>> 1; /* Rounding. */
160 coords
[n
] /= priv
->config
->length
;
164 const struct ts_filter_api ts_filter_mean_api
= {
165 .create
= ts_filter_mean_create
,
166 .destroy
= ts_filter_mean_destroy
,
167 .clear
= ts_filter_mean_clear
,
168 .process
= ts_filter_mean_process
,
169 .scale
= ts_filter_mean_scale
,
170 .haspoint
= ts_filter_mean_haspoint
,
171 .getpoint
= ts_filter_mean_getpoint
,
173 EXPORT_SYMBOL_GPL(ts_filter_mean_api
);