[PATCH v2] Input: usbtouchscreen - add strays output via sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



With surface capacitance touchscreens the capacitance is measured
through readings obtained from measurements taken at the four
corners of the glass.  These measurements are accessible in the I/Q
modulation format from the the controller which becomes meaningful
data when converted to an absolute value using the pythagorean
theorem.

Signed-off-by: Nick Dyer <nick@xxxxxxxxxxxxx>
---
Changes in v2:
- Values read from device must be treated as signed

 drivers/input/touchscreen/usbtouchscreen.c | 58 ++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index d61570d64ee7..af8fb1ab3a67 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -55,6 +55,7 @@
 #include <linux/usb/input.h>
 #include <linux/hid.h>
 #include <linux/mutex.h>
+#include <asm/unaligned.h>
 
 static bool swap_xy;
 module_param(swap_xy, bool, 0644);
@@ -437,11 +438,18 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 #ifdef CONFIG_TOUCHSCREEN_USB_3M
 
 #define MTOUCHUSB_ASYNC_REPORT          1
+#define MTOUCHUSB_GET_BLOCK		2
+#define MTOUCHUSB_STRAYS_BLOCK_CMD	3
 #define MTOUCHUSB_RESET                 7
 #define MTOUCHUSB_REQ_CTRLLR_ID         10
 
 #define MTOUCHUSB_REQ_CTRLLR_ID_LEN	16
 
+struct mtouch_strays {
+	u8 hdr[3];
+	__le32 data[8];
+} __attribute__ ((packed));
+
 static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
 	if (hwcalib_xy) {
@@ -459,8 +467,22 @@ static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 struct mtouch_priv {
 	u8 fw_rev_major;
 	u8 fw_rev_minor;
+	u64 strays[4];
 };
 
+static ssize_t mtouch_strays_show(struct device *dev,
+				  struct device_attribute *attr, char *output)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
+	struct mtouch_priv *priv = usbtouch->priv;
+
+	return scnprintf(output, PAGE_SIZE, "ul=%llu ur=%llu ll=%llu lr=%llu\n",
+			 priv->strays[0], priv->strays[1],
+			 priv->strays[2], priv->strays[3]);
+}
+static DEVICE_ATTR(strays, 0444, mtouch_strays_show, NULL);
+
 static ssize_t mtouch_firmware_rev_show(struct device *dev,
 				struct device_attribute *attr, char *output)
 {
@@ -475,6 +497,7 @@ static DEVICE_ATTR(firmware_rev, 0444, mtouch_firmware_rev_show, NULL);
 
 static struct attribute *mtouch_attrs[] = {
 	&dev_attr_firmware_rev.attr,
+	&dev_attr_strays.attr,
 	NULL
 };
 
@@ -482,6 +505,39 @@ static const struct attribute_group mtouch_attr_group = {
 	.attrs = mtouch_attrs,
 };
 
+static void mtouch_get_strays_report(struct usbtouch_usb *usbtouch)
+{
+	struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
+	struct mtouch_priv *priv = usbtouch->priv;
+	struct mtouch_strays *sbuf;
+	int ret;
+	int i;
+
+	sbuf = kzalloc(sizeof(struct mtouch_strays), GFP_NOIO);
+	if (!sbuf)
+		return;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			      MTOUCHUSB_GET_BLOCK,
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      MTOUCHUSB_STRAYS_BLOCK_CMD,
+			      0, sbuf, sizeof(struct mtouch_strays),
+			      USB_CTRL_SET_TIMEOUT);
+	if (ret != sizeof(struct mtouch_strays))
+		goto out_free;
+
+	for (i = 0; i < 4; i++) {
+		s64 a, b;
+
+		a = (s32)get_unaligned_le32(&sbuf->data[i*2]);
+		b = (s32)get_unaligned_le32(&sbuf->data[i*2 + 1]);
+		priv->strays[i] = int_sqrt64(a * a + b * b);
+	}
+
+out_free:
+	kfree(sbuf);
+}
+
 static int mtouch_get_fw_revision(struct usbtouch_usb *usbtouch)
 {
 	struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
@@ -568,6 +624,8 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
 			return ret;
 	}
 
+	mtouch_get_strays_report(usbtouch);
+
 	/* Default min/max xy are the raw values, override if using hw-calib */
 	if (hwcalib_xy) {
 		input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0);
-- 
2.17.1

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux