User: Password:
|
|
Subscribe / Log in / New account

usbtouchscreen, 2.6.25

From:  "=?ISO-8859-1?Q?S=F8ren_Hauberg?=" <hauberg@gmail.com>
To:  linux-kernel@vger.kernel.org
Subject:  [PATCH] usbtouchscreen, 2.6.25
Date:  Tue, 23 Sep 2008 10:42:56 +0200
Message-ID:  <ed7dcf450809230142l62bb00aapb92e6cb225f0cbba@mail.gmail.com>

Hi,
  Currently, the 'usbtouchscreen' module sends raw data from the
touchscreen directly to the user. However, in general, touchscreens
need to be calibrated, and the raw data needs to be transformed
according to the calibration, before the data can be used as an input
device. Currently, some special purpose drivers exists for this in X,
but the situation is a bit messy. I propose to add support for
calibration parameters in the kernel. That way, we can also get usable
touchscreens without X, without having to write special purpose
drivers to handle the data from the touchscreen. The attached patch
adds support for this. A module parameter (transform_xy)
enables/disables this behavior, so the patch is not very intrusive,
and should cause issues to current users.

Comments would be appricated,
Søren

P.S. I'm not subscribed to the list so please keep me in the CC.

--- /root/touch/usbtouchscreen.c.org	2008-09-16 15:32:40.000000000 +0200
+++ drivers/input/touchscreen/usbtouchscreen.c	2008-09-23 10:26:43.000000000 +0200
@@ -59,6 +59,49 @@
 module_param(swap_xy, bool, 0644);
 MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
 
+static int flip_x;
+module_param(flip_x, bool, 0644);
+MODULE_PARM_DESC(flip_x, "If set X is subtracted from the range_x parameter.");
+
+static int flip_y;
+module_param(flip_y, bool, 0644);
+MODULE_PARM_DESC(flip_y, "If set X is subtracted from the range_x parameter.");
+
+static int transform_xy;
+module_param(transform_xy, bool, 0644);
+MODULE_PARM_DESC(transform_xy, "If set the X-coordinate is computed as\
+ (range_x * (raw_x - min_x))/(max_x-min_x) and similar for the y-coordinate.");
+
+static int min_x;
+module_param(min_x, int, 0644);
+MODULE_PARM_DESC(min_x, "The value of the min_x parameter. See 'transform_xy'\
+ for details.");
+
+static int max_x;
+module_param(max_x, int, 0644);
+MODULE_PARM_DESC(max_x, "The value of the max_x parameter. See 'transform_xy'\
+ for details.");
+
+static int min_y;
+module_param(min_y, int, 0644);
+MODULE_PARM_DESC(min_y, "The value of the min_y parameter. See 'transform_xy'\
+ for details.");
+
+static int max_y;
+module_param(max_y, int, 0644);
+MODULE_PARM_DESC(max_y, "The value of the max_y parameter. See 'transform_xy'\
+ for details.");
+
+static int range_x;
+module_param(range_x, int, 0644);
+MODULE_PARM_DESC(range_x, "The X-coordinate of the output will be in the\
+ interval [0, range_x].");
+
+static int range_y;
+module_param(range_y, int, 0644);
+MODULE_PARM_DESC(range_y, "The Y-coordinate of the output will be in the\
+ interval [0, range_y].");
+
 /* device specifc data/functions */
 struct usbtouch_usb;
 struct usbtouch_device_info {
@@ -672,6 +715,18 @@
 /*****************************************************************************
  * Generic Part
  */
+inline int usbtouch_transform_pkt (int p, int min, int max, int phys)
+{
+  int result = (phys * (p - min))/(max-min);
+  if (result < 0) {
+    return 0;
+  } else if (result > phys) {
+    return phys;
+  } else {
+    return result;
+  }
+}
+
 static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
                                  unsigned char *pkt, int len)
 {
@@ -680,15 +735,27 @@
 	if (!type->read_data(usbtouch, pkt))
 			return;
 
-	input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);
-
 	if (swap_xy) {
-		input_report_abs(usbtouch->input, ABS_X, usbtouch->y);
-		input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);
-	} else {
-		input_report_abs(usbtouch->input, ABS_X, usbtouch->x);
-		input_report_abs(usbtouch->input, ABS_Y, usbtouch->y);
+		int tmp;
+		tmp = usbtouch->x;
+		usbtouch->x = usbtouch->y;
+		usbtouch->y = tmp;
 	}
+
+	if (transform_xy) {
+		usbtouch->x = usbtouch_transform_pkt (usbtouch->x, min_x, max_x, range_x);
+		usbtouch->y = usbtouch_transform_pkt (usbtouch->y, min_y, max_y, range_y);
+	}
+
+	if (flip_x)
+		usbtouch->x = range_x - usbtouch->x;
+
+	if (flip_y)
+		usbtouch->y = range_y - usbtouch->y;
+	
+	input_report_abs(usbtouch->input, ABS_X, usbtouch->x);
+	input_report_abs(usbtouch->input, ABS_Y, usbtouch->y);
+	input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);
 	if (type->max_press)
 		input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);
 	input_sync(usbtouch->input);


Copyright © 2008, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds