OSDN Git Service

cy8mrln-palmpre: Add configuration to the info
authorFrederik 'playya' Sdun <Frederik.Sdun@googlemail.com>
Tue, 28 Sep 2010 22:15:58 +0000 (00:15 +0200)
committerChris Larson <chris_larson@mentor.com>
Wed, 27 Oct 2010 16:48:55 +0000 (09:48 -0700)
struct and add noise and ts_pressure option

plugins/cy8mrln-palmpre.c

index c571405..0404e3c 100644 (file)
@@ -2,15 +2,16 @@
  *  tslib/plugins/cy8mrln-palmpre.c
  *
  *  Copyright (C) 2010 Frederik Sdun <frederik.sdun@googlemail.com>
- *                    Thomas Zimmermann <ml@vdm-design.de>
- *
+ *                     Thomas Zimmermann <ml@vdm-design.de>
+ *                     Simon Busch <morphis@gravedo.de>
  *
  * This file is placed under the LGPL.  Please see the file
  * COPYING for more details.
  *
+ * Plugin for the cy8mrln touchscreen with the firmware used on the Palm Pre (Plus).
  *
- * Pluging for the cy8mrln touchscreen with the Firmware used on the Palm Pre
  */
+
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-
+#include <linux/spi/cy8mrln.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
 #include "config.h"
 #include "tslib-private.h"
 #include "tslib-filter.h"
 
-#include "cy8mrln.h"
-
-#define NOISE          25
 #define SCREEN_WIDTH   319
 #define SCREEN_HEIGHT  527
 #define H_FIELDS       7
 #define V_FIELDS       11
-#define TS_PRESSURE    255
+#define DEFAULT_SCANRATE 60
+#define DEFAULT_VERBOSE 0
+#define DEFAULT_WOT_THRESHOLD 22
+#define DEFAULT_SLEEPMODE CY8MRLN_ON_STATE
+#define DEFAULT_WOT_SCANRATE WOT_SCANRATE_512HZ
+#define DEFAULT_TIMESTAMP_MODE 1
+#define DEFAULT_TS_PRESSURE 255
+#define DEFAULT_NOISE 25
 
 #define container_of(ptr, type, member) ({ \
        const typeof( ((type*)0)->member ) *__mptr = (ptr); \
 
 struct cy8mrln_palmpre_input
 {  
-       uint16_t n_r;
-       uint16_t field[H_FIELDS * V_FIELDS];
-       uint16_t ffff;            //seperator? always ff
-       uint8_t seq_nr1;                //incremented if seq_nr0 = scanrate
-       uint16_t seq_nr2;              //incremeted if seq_nr1 = 255
-       uint8_t unknown[4]; 
-       uint8_t seq_nr0;                //incremented. 0- scanrate
-       uint8_t null;              //\0
+       uint16_t        n_r;
+       uint16_t        field[H_FIELDS * V_FIELDS];
+       uint16_t        ffff;                   /* always 0xffff */
+       uint8_t         seq_nr1;                /* incremented if seq_nr0 == scanrate */
+       uint16_t        seq_nr2;                /* incremeted if seq_nr1 == 255 */
+       uint8_t         unknown[4]; 
+       uint8_t         seq_nr0;                /* incremented [0:scanrate] */
+       uint8_t         null;              /* NULL byte */
 }__attribute__((packed));
 
 struct tslib_cy8mrln_palmpre 
 {
        struct tslib_module_info module;
        uint16_t nulls[H_FIELDS * V_FIELDS];
+        int scanrate;
+        int verbose;
+        int wot_threshold;
+        int sleepmode;
+        int wot_scanrate;
+        int timestamp_mode;
+        int ts_pressure;
+        int noise;
 };
 
-static int scanrate = 60;
-static int verbose = 0;
-static int wot_threshold = 22;
-static int sleepmode = CY8MRLN_ON_STATE;
-static int wot_scanrate = WOT_SCANRATE_512HZ;
-static int timestamp_mode = 1;
 
 static int 
-cy8mrln_palmpre_set_scanrate(struct tsdev* dev, int rate)
+cy8mrln_palmpre_set_scanrate(struct tslib_cy8mrln_palmpre* info, int rate)
 {
-       if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_SCANRATE,&rate) < 0)
+       if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_SCANRATE,&rate) < 0)
                goto error;
                
-       scanrate = rate;
+       info->scanrate = rate;
        return 0;
        
 error:
@@ -81,12 +93,12 @@ error:
 }
 
 static int 
-cy8mrln_palmpre_set_verbose(struct tsdev* dev, int v)
+cy8mrln_palmpre_set_verbose(struct tslib_cy8mrln_palmpre* info, int v)
 {
-       if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_VERBOSE_MODE,&v) < 0)
+       if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_VERBOSE_MODE,&v) < 0)
                goto error;
        
-       verbose = v;
+       info->verbose = v;
        return 0;
 
 error:
@@ -95,12 +107,12 @@ error:
 }
 
 static int 
-cy8mrln_palmpre_set_sleepmode(struct tsdev* dev, int mode)
+cy8mrln_palmpre_set_sleepmode(struct tslib_cy8mrln_palmpre* info, int mode)
 {
-       if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_SLEEPMODE,&mode) < 0)
+       if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_SLEEPMODE,&mode) < 0)
                goto error;
 
-       sleepmode = mode;
+       info->sleepmode = mode;
        return 0;
        
 error:
@@ -109,12 +121,12 @@ error:
 }
 
 static int 
-cy8mrln_palmpre_set_wot_scanrate(struct tsdev* dev, int rate)
+cy8mrln_palmpre_set_wot_scanrate(struct tslib_cy8mrln_palmpre* info, int rate)
 {
-       if (dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_WOT_SCANRATE,&rate) < 0)
+       if (info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_WOT_SCANRATE,&rate) < 0)
                goto error;
 
-       wot_scanrate = rate;
+       info->wot_scanrate = rate;
        return 0;
 
 error:
@@ -123,16 +135,16 @@ error:
 }
 
 static int 
-cy8mrln_palmpre_set_wot_threshold(struct tsdev* dev, int v)
+cy8mrln_palmpre_set_wot_threshold(struct tslib_cy8mrln_palmpre* info, int v)
 {
-       if (dev == NULL) 
+       if (info == NULL || info->module.dev == NULL) 
                goto error;
        if(v < WOT_THRESHOLD_MIN || v > WOT_THRESHOLD_MAX)
                goto error;
-       if(ioctl(dev->fd,CY8MRLN_IOCTL_SET_WOT_THRESHOLD,&v) < 0)
+       if(ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_WOT_THRESHOLD,&v) < 0)
                goto error;
                
-       wot_threshold = v;
+       info->wot_threshold = v;
        return 0;
        
 error:
@@ -141,12 +153,12 @@ error:
 }
 
 static int 
-cy8mrln_palmpre_set_timestamp_mode(struct tsdev* dev, int v)
+cy8mrln_palmpre_set_timestamp_mode(struct tslib_cy8mrln_palmpre* info, int v)
 {
        v = v ? 1 : 0;
-       if(dev == NULL || ioctl(dev->fd,CY8MRLN_IOCTL_SET_TIMESTAMP_MODE,&v) < 0)
+       if(info == NULL || info->module.dev == NULL || ioctl(info->module.dev->fd,CY8MRLN_IOCTL_SET_TIMESTAMP_MODE,&v) < 0)
             goto error;
-       timestamp_mode = v;
+       info->timestamp_mode = v;
        return 0;
        
 error:
@@ -154,64 +166,122 @@ error:
        return -1;
 }
 
+static int 
+cy8mrln_palmpre_set_noise (struct tslib_cy8mrln_palmpre* info, int n)
+{
+        if (info == NULL) {
+                printf("TSLIB: cy8mrln_palmpre: ERROR: could not set noise value\n");
+                return -1;
+        }
+        info->noise = n;
+        return 0;
+}
+
+static int
+cy8mrln_palmpre_set_ts_pressure(struct tslib_cy8mrln_palmpre* info, int p)
+{
+        if (info == NULL) {
+                printf("TSLIB: cy8mrln_palmpre: ERROR: could not set ts_pressure value\n");
+                return -1;
+        }
+        info->ts_pressure = p;
+        return 0;
+}
+
 static int
 parse_scanrate(struct tslib_module_info *info, char *str, void *data)
 {
-       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module);
        unsigned long rate = strtoul(str, NULL, 0);
 
        if(rate == ULONG_MAX && errno == ERANGE)
                return -1;
 
-       return cy8mrln_palmpre_set_scanrate(i->module.dev, scanrate);
+       return cy8mrln_palmpre_set_scanrate(irate);
 }
 
 static int
 parse_verbose(struct tslib_module_info *info, char *str, void *data)
 {
-       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module);
        unsigned long v = strtoul(str, NULL, 0);
 
        if(v == ULONG_MAX && errno == ERANGE)
                return -1;
 
-       return cy8mrln_palmpre_set_verbose(i->module.dev, scanrate);
+       return cy8mrln_palmpre_set_verbose(i, v);
 }
 
 static int
 parse_wot_scanrate(struct tslib_module_info *info, char *str, void *data)
 {
-       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module);
        unsigned long rate = strtoul(str, NULL, 0);
 
-       return cy8mrln_palmpre_set_wot_scanrate(i->module.dev, rate);
+       return cy8mrln_palmpre_set_wot_scanrate(i, rate);
 }
 
 static int
 parse_wot_threshold(struct tslib_module_info *info, char *str, void *data)
 {
-       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module);
        unsigned long threshold = strtoul(str, NULL, 0);
 
-       return cy8mrln_palmpre_set_wot_threshold(i->module.dev, threshold);
+       return cy8mrln_palmpre_set_wot_threshold(i, threshold);
 }
 
 static int
 parse_sleepmode(struct tslib_module_info *info, char *str, void *data)
 {
-       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = container_of(info, struct tslib_cy8mrln_palmpre, module);
        unsigned long sleep = strtoul(str, NULL, 0);
 
-       return cy8mrln_palmpre_set_sleepmode(i->module.dev, sleep);
+       return cy8mrln_palmpre_set_sleepmode(i, sleep);
 }
 
 static int
 parse_timestamp_mode(struct tslib_module_info *info, char *str, void *data)
 {
+        (void)data;
        struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
        unsigned long sleep = strtoul(str, NULL, 0);
 
-       return cy8mrln_palmpre_set_sleepmode(i->module.dev, sleep);
+       if(sleep == ULONG_MAX && errno == ERANGE)
+               return -1;
+
+
+       return cy8mrln_palmpre_set_sleepmode(i, sleep);
+}
+static int
+parse_noise(struct tslib_module_info *info, char *str, void *data)
+{
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        unsigned long noise = strtoul (str, NULL, 0);
+
+       if(noise == ULONG_MAX && errno == ERANGE)
+               return -1;
+
+
+        return cy8mrln_palmpre_set_noise (i, noise);
+}
+
+static int
+parse_ts_pressure(struct tslib_module_info *info, char *str, void *data)
+{
+        (void)data;
+       struct tslib_cy8mrln_palmpre *i = (struct tslib_cy8mrln_palmpre*) info;
+        unsigned long tp = strtoul (str, NULL, 0);
+
+       if(tp == ULONG_MAX && errno == ERANGE)
+               return -1;
+
+        return cy8mrln_palmpre_set_ts_pressure (i, tp);
 }
 
 static const struct tslib_vars raw_vars[] =
@@ -221,14 +291,16 @@ static const struct tslib_vars raw_vars[] =
        { "wot_scanrate", NULL, parse_wot_scanrate},
        { "wot_threshold", NULL, parse_wot_threshold},
        { "sleepmode", NULL, parse_sleepmode},
-       { "timestamp_mode", NULL, parse_timestamp_mode}
+       { "timestamp_mode", NULL, parse_timestamp_mode},
+        { "noise", NULL, parse_noise},
+        { "ts_pressure", NULL, parse_ts_pressure}
 };
 
 #define NR_VARS (sizeof(raw_vars) / sizeof(raw_vars[0]))
 
 void
 interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) {
-       float f11, f12, f13, f21, f22, f23, f31, f32, f33;
+       float f12, f21, f22, f23, f32; //f33, f31, f13, f11
        int x = SCREEN_WIDTH / H_FIELDS * (H_FIELDS - (i % H_FIELDS));
        int y = SCREEN_HEIGHT / (V_FIELDS - 1) * (i / H_FIELDS);
        static int dx = SCREEN_WIDTH / H_FIELDS;
@@ -242,10 +314,8 @@ interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) {
              ? 0.0 : 0.5 * field[i + 1] / field[i];
        f23 = (i % H_FIELDS == 0) ? 0.0 : 0.5 * field[i - 1] / field[i];
 
-       /*
-          correct values for the edges, shift the mesuarment point by half a 
-          field diminsion to the outside
-       */
+       /* correct values for the edges, shift the mesuarment point by half a 
+        * field diminsion to the outside */
        if (i == 0) {
                x = x + dx / 2;
                f21 = f21 * 2.0;
@@ -301,7 +371,6 @@ interpolate(uint16_t field[H_FIELDS * V_FIELDS], int i, struct ts_sample *out) {
        out->y = y // + (f31 + f33 - f11 - f13) * dy /* use corners too?*/
                 + (f32 - f12) * dy + (dy / 2);
 
-       out->pressure = TS_PRESSURE;
 #ifdef DEBUG
        printf("RAW---------------------------> f22: %f (%d) f21: %f (%d), f23: %f (%d), f12: %f (%d), f32: %f (%d), \n", 
               f22, field[i],
@@ -314,7 +383,8 @@ static int
 cy8mrln_palmpre_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
 {
        struct tsdev *ts = info->dev;
-       struct cy8mrln_palmpre_input *cy8mrln_evt;
+        //We can only read one input struct at once
+       struct cy8mrln_palmpre_input cy8mrln_evt;
        struct tslib_cy8mrln_palmpre *cy8mrln_info;
        int max_index = 0, max_value = 0, i = 0;
        uint16_t tmp_value;
@@ -322,61 +392,50 @@ cy8mrln_palmpre_read(struct tslib_module_info *info, struct ts_sample *samp, int
        struct ts_sample *p = samp;
        
        /* initalize all samples with proper values */
-       for (i = 0; i < nr; i++, p++)
-       {
-               p->x = 0;
-               p->y = 0;
-               p->pressure = 0;
-       }
+        memset(p, '\0', nr * sizeof (*p));
        
        cy8mrln_info = container_of(info, struct tslib_cy8mrln_palmpre, module);
        
-       cy8mrln_evt = alloca(sizeof(*cy8mrln_evt) * nr);
-       ret = read(ts->fd, cy8mrln_evt, sizeof(*cy8mrln_evt) * nr);
+       ret = read(ts->fd, &cy8mrln_evt, sizeof(cy8mrln_evt));
        if (ret > 0) {
                max_index = 0;
                max_value = 0;
-               while(ret >= (int)sizeof(*cy8mrln_evt)) {
-                        for (i = 0; i < (H_FIELDS * V_FIELDS); i++) {
-                               /* auto calibrate zero values */
-                               if (cy8mrln_evt->field[i] > cy8mrln_info->nulls[i])
-                                       cy8mrln_info->nulls[i] = cy8mrln_evt->field[i];
-
-                               tmp_value = abs(cy8mrln_info->nulls[i] - cy8mrln_evt->field[i]);
-
-                               /* check for the maximum value */
-                               if (tmp_value > max_value) {
-                                       max_value = tmp_value;
-                                       max_index = i;
-                               }
-
-                               cy8mrln_evt->field[i] = tmp_value;
-                       }
-                       /* only caluclate events that are not noise */
-                       if (max_value > NOISE) {
-                               interpolate(cy8mrln_evt->field, max_index, samp);
+                for (i = 0; i < (H_FIELDS * V_FIELDS); i++) {
+                        /* auto calibrate zero values */
+                        if (cy8mrln_evt.field[i] > cy8mrln_info->nulls[i])
+                                cy8mrln_info->nulls[i] = cy8mrln_evt.field[i];
+
+                        tmp_value = abs(cy8mrln_info->nulls[i] - cy8mrln_evt.field[i]);
+
+                        /* check for the maximum value */
+                        if (tmp_value > max_value) {
+                                max_value = tmp_value;
+                                max_index = i;
+                        }
+
+                        cy8mrln_evt.field[i] = tmp_value;
+                }
+                /* only caluclate events that are not noise */
+                if (max_value > cy8mrln_info->noise) {
+                        interpolate(cy8mrln_evt.field, max_index, samp);
+                        samp->pressure = cy8mrln_info -> ts_pressure;
 #ifdef DEBUG
-                               fprintf(stderr,"RAW---------------------------> %d %d %d\n",
-                                       samp->x, samp->y, samp->pressure);
+                        fprintf(stderr,"RAW---------------------------> %d %d %d\n",
+                                samp->x, samp->y, samp->pressure);
 #endif /*DEBUG*/
-                               gettimeofday(&samp->tv,NULL);
-                               samp++;
-                               valid_samples++;
-                       }
-
-                       cy8mrln_evt++;
-                       ret -= sizeof(*cy8mrln_evt);
-               }
-       } else {
-               return -1;
+                        gettimeofday(&samp->tv,NULL);
+                        samp++;
+                        valid_samples++;
+                }
        }
 
        return valid_samples;
 }
 
 static int 
-cy8mrln_palmpre_fini(struct tslib_module_info *inf)
+cy8mrln_palmpre_fini(struct tslib_module_info *info)
 {
+        (void)info;
        return 0;
 }
 
@@ -398,19 +457,21 @@ TSAPI struct tslib_module_info *cy8mrln_palmpre_mod_init(struct tsdev *dev, cons
             return NULL;
        info->module.ops = &cy8mrln_palmpre_ops;
 
-       cy8mrln_palmpre_set_verbose(dev,verbose);
-       cy8mrln_palmpre_set_scanrate(dev,scanrate);
-       cy8mrln_palmpre_set_timestamp_mode(dev,timestamp_mode);
-       cy8mrln_palmpre_set_sleepmode(dev,sleepmode);
-       cy8mrln_palmpre_set_wot_scanrate(dev,wot_scanrate);
-       cy8mrln_palmpre_set_wot_threshold(dev,wot_threshold);
+       cy8mrln_palmpre_set_verbose(info, DEFAULT_VERBOSE);
+       cy8mrln_palmpre_set_scanrate(info, DEFAULT_SCANRATE);
+       cy8mrln_palmpre_set_timestamp_mode(info, DEFAULT_TIMESTAMP_MODE);
+       cy8mrln_palmpre_set_sleepmode(info, DEFAULT_SLEEPMODE);
+       cy8mrln_palmpre_set_wot_scanrate(info, DEFAULT_WOT_SCANRATE);
+       cy8mrln_palmpre_set_wot_threshold(info, DEFAULT_WOT_THRESHOLD);
+        cy8mrln_palmpre_set_noise(info, DEFAULT_NOISE);
+        cy8mrln_palmpre_set_ts_pressure(info, DEFAULT_TS_PRESSURE);
 
        if (tslib_parse_vars(&info->module, raw_vars, NR_VARS, params)) {
                free(info);
                return NULL;
        }
 
-       /* We need the intial values the touchscreen repots with no touch input force
+       /* We need the intial values the touchscreen repots with no touch input for
         * later use */
        do {
                ret = read(dev->fd, &input, sizeof(input));