OSDN Git Service

cy8mrln-palmpre: remove unused struct
[android-x86/external-tslib.git] / plugins / cy8mrln-palmpre.c
1 /*
2  *  tslib/plugins/cy8mrln-palmpre.c
3  *
4  *  Copyright (C) 2010 Frederik Sdun <frederik.sdun@googlemail.com>
5  *                     Thomas Zimmermann <ml@vdm-design.de>
6  *
7  *
8  * This file is placed under the LGPL.  Please see the file
9  * COPYING for more details.
10  *
11  *
12  * Pluging for the cy8mrln touchscreen with the Firmware used on the Palm Pre
13  */
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <linux/spi/cy8mrln.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/ioctl.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
27 #include "config.h"
28 #include "tslib-private.h"
29 #include "tslib-filter.h"
30
31 #define NOISE          12
32 #define SCREEN_WIDTH   319
33 #define SCREEN_HEIGHT  527
34 #define H_FIELDS       7
35 #define V_FIELDS       11
36
37 struct cy8mrln_palmpre_input
38 {  
39         uint16_t n_r;
40         uint16_t field[H_FIELDS * V_FIELDS];
41         uint16_t ffff;            //seperator? always ff
42         uint8_t seq_nr1;                //incremented if seq_nr0 = scanrate
43         uint16_t seq_nr2;              //incremeted if seq_nr1 = 255
44         uint8_t unknown[4]; 
45         uint8_t seq_nr0;                //incremented. 0- scanrate
46         uint8_t null;              //\0
47 }__attribute__((packed));
48
49 struct tslib_cy8mrln_palmpre 
50 {
51         struct tslib_module_info module;
52         uint16_t nulls[7][11];
53 };
54
55 static int scanrate = 60;
56 static int verbose = 1;
57 static int wot_threshold = 22;
58 static int sleepmode = CY8MRLN_ON_STATE;
59 static int wot_scanrate = WOT_SCANRATE_512HZ;
60 static int timestamp_mode = 1;
61
62 static int 
63 cy8mrln_palmpre_set_scanrate(struct tsdev* dev, int rate)
64 {
65         if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_SCANRATE,&rate) < 0)
66              return -1;
67         scanrate = rate;
68         return 0;
69 }
70
71 static int 
72 cy8mrln_palmpre_set_verbose(struct tsdev* dev, int v)
73 {
74         if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_VERBOSE_MODE,&v) < 0)
75              return -1;
76         verbose = v;
77         return 0;
78 }
79
80 static int 
81 cy8mrln_palmpre_set_sleepmode(struct tsdev* dev, int mode)
82 {
83         if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_SLEEPMODE,&mode) < 0)
84              return -1;
85         sleepmode = mode;
86         return 0;
87 }
88
89 static int 
90 cy8mrln_palmpre_set_wot_scanrate(struct tsdev* dev, int rate)
91 {
92         if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_WOT_SCANRATE,&rate) < 0)
93              return -1;
94         wot_scanrate = rate;
95         return 0;
96 }
97
98 static int 
99 cy8mrln_palmpre_set_wot_threshold(struct tsdev* dev, int v)
100 {
101         if(v < WOT_THRESHOLD_MIN || v > WOT_THRESHOLD_MAX)
102              return -1;
103         if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_WOT_THRESHOLD,&v) < 0)
104              return -1;
105         wot_threshold = v;
106         return 0;
107 }
108
109 static int 
110 cy8mrln_palmpre_set_timestamp_mode(struct tsdev* dev, int v)
111 {
112         v = v ? 1 : 0;
113         if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_TIMESTAMP_MODE,&v) < 0)
114              return -1;
115         timestamp_mode = v;
116         return 0;
117 }
118
119 static int
120 parse_scanrate(struct tslib_module_info *info, char *str, void *data)
121 {
122         (void)data;
123         struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
124         unsigned long rate = strtoul(str, NULL, 0);
125
126         if(rate == ULONG_MAX && errno == ERANGE)
127                 return -1;
128
129         return cy8mrln_palmpre_set_scanrate(i->module.dev, scanrate);
130 }
131
132 static int
133 parse_verbose(struct tslib_module_info *info, char *str, void *data)
134 {
135         (void)data;
136         struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
137         unsigned long v = strtoul(str, NULL, 0);
138
139         if(v == ULONG_MAX && errno == ERANGE)
140                 return -1;
141
142         return cy8mrln_palmpre_set_verbose(i->module.dev, scanrate);
143 }
144
145 static int
146 parse_wot_scanrate(struct tslib_module_info *info, char *str, void *data)
147 {
148         (void)data;
149         struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
150         unsigned long rate = strtoul(str, NULL, 0);
151
152         return cy8mrln_palmpre_set_wot_scanrate(i->module.dev, rate);
153 }
154
155 static int
156 parse_wot_threshold(struct tslib_module_info *info, char *str, void *data)
157 {
158         (void)data;
159         struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
160         unsigned long threshold = strtoul(str, NULL, 0);
161
162         return cy8mrln_palmpre_set_wot_threshold(i->module.dev, threshold);
163 }
164
165 static int
166 parse_sleepmode(struct tslib_module_info *info, char *str, void *data)
167 {
168         (void)data;
169         struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
170         unsigned long sleep = strtoul(str, NULL, 0);
171
172         return cy8mrln_palmpre_set_sleepmode(i->module.dev, sleep);
173         return 0;
174 }
175
176 static int
177 parse_timestamp_mode(struct tslib_module_info *info, char *str, void *data)
178 {
179         (void)data;
180         struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
181         unsigned long sleep = strtoul(str, NULL, 0);
182
183         return cy8mrln_palmpre_set_sleepmode(i->module.dev, sleep);
184         return 0;
185 }
186
187 static const struct tslib_vars raw_vars[] =
188 {
189         { "scanrate", NULL, parse_scanrate},
190         { "verbose", NULL, parse_verbose},
191         { "wot_scanrate", NULL, parse_wot_scanrate},
192         { "wot_threshold", NULL, parse_wot_threshold},
193         { "sleepmode", NULL, parse_sleepmode},
194         { "timestamp_mode", NULL, parse_timestamp_mode}
195 };
196
197 #define NR_VARS (sizeof(raw_vars) / sizeof(raw_vars[0]))
198
199 void
200 interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) {
201         float f11, f12, f13, f21, f22, f23, f31, f32, f33;
202         int x = SCREEN_WIDTH / H_FIELDS * (H_FIELDS - (i % H_FIELDS));
203         int y = SCREEN_HEIGHT / (V_FIELDS - 1) * (i / H_FIELDS);
204         static int dx = SCREEN_WIDTH / H_FIELDS;
205         static int dy = SCREEN_HEIGHT / V_FIELDS;
206         
207         /* caluculate corrections for top, bottom, left and right fields */
208         f12 = (i < (H_FIELDS + 1)) ? 0.0 : 0.5 * field[i - H_FIELDS] / field[i];
209         f32 = (i > (H_FIELDS * (V_FIELDS - 2)))
210               ? 0.0 : 0.5 * field[i + H_FIELDS] / field[i];
211         f21 = (i % H_FIELDS == (H_FIELDS - 1))
212               ? 0.0 : 0.5 * field[i + 1] / field[i];
213         f23 = (i % H_FIELDS == 0) ? 0.0 : 0.5 * field[i - 1] / field[i];
214
215         /*
216            correct values for the edges, shift the mesuarment point by half a 
217            field diminsion to the outside
218         */
219         if (i == 0) {
220                 x = x + dx / 2;
221                 f21 = f21 * 2.0;
222                 y = y - dy / 2;
223                 f32 = f32 * 2.0;
224         } else if (i == (H_FIELDS - 1)) {
225                 x = x - dx / 2;
226                 f23 = f23 * 2.0;
227                 y = y - dy / 2;
228                 f32 = f32 * 2.0;
229         } else if (i % H_FIELDS == (H_FIELDS - 1)) {
230                 x = x - dx / 2;
231                 f23 = f23 * 2.0;
232         } else if (i % H_FIELDS == 0) {
233                 x = x + dx / 2;
234                 f21 = f21 * 2.0;
235         } else if (i < H_FIELDS) {
236                 y = y - dy / 2;
237                 f32 = f32 * 2.0;
238         } else if (i == (H_FIELDS * (V_FIELDS - 2))) {
239                 x = x + dx / 2;
240                 f21 = f21 * 2.0;
241                 y = y + dy / 2;
242                 f12 = f12 * 2.0;
243         } else if (i == (H_FIELDS * (V_FIELDS - 1) - 1)) {
244                 x = x - dx / 2;
245                 f23 = f23 * 2.0;
246                 y = y + dy / 2;
247                 f12 = f12 * 2.0;
248         } else if (i > (H_FIELDS * (V_FIELDS - 2))) {
249                 y = y + dy / 2;
250                 f12 = f12 * 2.0;
251         }
252
253         /* caluclate corrections for the corners */
254 /*
255         f11 = (i % H_FIELDS == (H_FIELDS - 1) || i < (H_FIELDS + 1))
256               ? 0.0 : 0.4 * field[i - H_FIELDS + 1] / field[i];
257         f13 = (i % H_FIELDS == 0 || i < (H_FIELDS + 1))
258               ? 0.0 : 0.4 * field[i - H_FIELDS - 1] / field[i];
259         f31 = (i % H_FIELDS == (H_FIELDS - 1)
260                || i > (H_FIELDS * (V_FIELDS - 1) - 1))
261               ? 0.0 : 0.4 * field[i + H_FIELDS + 1] / field[i];
262         f33 = (i % H_FIELDS == 0 || i > (H_FIELDS * (V_FIELDS - 1) - 1))
263               ? 0.0 : 0.4 * field[i + H_FIELDS - 1] / field[i];
264 */
265
266         out->x = x // + (f13 + f33 - f11 - f31) * dx /* use corners too?*/
267                  + (f23 - f21) * dx
268 //               + (f21 == 0.0) ? ((f23 * 2 + (dx / 2)) * dx) : (f23 * dx)
269 //               - (f23 == 0.0) ? ((f21 * 2 + (dx / 2)) * dx) : (f21 * dx)
270                  - (dx / 2);
271         out->y = y // + (f31 + f33 - f11 - f13) * dy /* use corners too?*/
272                  + (f32 - f12) * dy + (dy / 2);
273
274         out->pressure = field[i];
275 #ifdef DEBUG
276         printf("RAW--------------------------->f21: %f (%d), f23: %f (%d), f12: %f (%d), f32: %f (%d), ", 
277                f21, field[i - 1], f23, field[i + 1], f12,
278                field[i - H_FIELDS], f32, field[i + H_FIELDS]);
279 #endif /*DEBUG*/
280 }
281
282 static int
283 cy8mrln_palmpre_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
284 {
285         struct tsdev *ts = info->dev;
286         struct cy8mrln_palmpre_input *cy8mrln_evt;
287         int ret;
288         cy8mrln_evt = alloca(sizeof(*cy8mrln_evt) * nr);
289         ret = read(ts->fd, cy8mrln_evt, sizeof(*cy8mrln_evt) * nr);
290         if (ret > 0) {
291                 int nr = ret / sizeof(*cy8mrln_evt);
292                 max_index = 0;
293                 max_value = 0;
294                 while(ret >= (int)sizeof(*cy8mrln_evt)) {
295                         for (i = 0; i < (H_FIELDS * V_FIELDS); i++) {
296                                 /* auto calibrate zero values */
297                                 if (cy8mrln_evt->field[i] > info->nulls[i])
298                                         info->nulls[i] = cy8mrln_evt->field[i];
299
300                                 tmp_value = abs(info->nulls[i] - cy8mrln_evt->field[i]);
301
302                                 /* check for the maximum value */
303                                 if (tmp_value > max_value) {
304                                         max_value = tmp_value;
305                                         max_index = i;
306                                 }
307
308                                 cy8mrln_evt->field[i] = tmp_value;
309                         }
310                         /* only caluclate events that are not noise */
311                         if (max_value > NOISE) {
312                                 interpolate(cy8mrln_evt->field, max_index, samp);
313 #ifdef DEBUG
314                                 fprintf(stderr,"RAW---------------------------> %d %d %d\n",
315                                         samp->x, samp->y, samp->pressure);
316 #endif /*DEBUG*/
317                         }
318
319                         gettimeofday(&samp->tv,NULL);
320                         samp++;
321                         cy8mrln_evt++;
322                         ret -= sizeof(*cy8mrln_evt);
323                 }
324         } else {
325                 return -1;
326         }
327
328         ret = nr;
329         return ret;
330 }
331
332 static int 
333 cy8mrln_palmpre_fini(struct tslib_module_info *inf)
334 {
335         return 0;
336 }
337
338
339 static const struct tslib_ops cy8mrln_palmpre_ops = 
340 {
341         .read = cy8mrln_palmpre_read,
342         .fini = cy8mrln_palmpre_fini,
343 };
344
345 TSAPI struct tslib_module_info *cy8mrln_palmpre_mod_init(struct tsdev *dev, const char *params)
346 {
347         struct tslib_cy8mrln_palmpre *info;
348         struct cy8mrln_palmpre_input input;
349         
350         info = malloc(sizeof(struct tslib_cy8mrln_palmpre));
351         if(info == NULL)
352              return NULL;
353         info->module.ops = &cy8mrln_palmpre_ops;
354
355         cy8mrln_palmpre_set_verbose(dev,verbose);
356         cy8mrln_palmpre_set_scanrate(dev,scanrate);
357         cy8mrln_palmpre_set_timestamp_mode(dev,timestamp_mode);
358         cy8mrln_palmpre_set_sleepmode(dev,sleepmode);
359         cy8mrln_palmpre_set_wot_scanrate(dev,wot_scanrate);
360         cy8mrln_palmpre_set_wot_threshold(dev,wot_threshold);
361
362         if (tslib_parse_vars(&info->module, raw_vars, NR_VARS, params)) {
363                 free(info);
364                 return NULL;
365         }
366
367         read(dev->fd, &input, sizeof(input));
368
369         memcpy(info->nulls, input.values, 7*11*sizeof(uint16_t));
370
371         return &(info->module);
372 }
373 #ifndef TSLIB_STATIC_CY8MRLN_MODULE
374         TSLIB_MODULE_INIT(cy8mrln_palmpre_mod_init);
375 #endif