summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlison Wang <b18965@freescale.com>2012-10-08 14:19:40 +0800
committerAndy Voltz <andy.voltz@timesys.com>2012-10-17 14:37:24 -0400
commit32788800d684c30297e35a99fbe69e36476f7464 (patch)
tree817be3850b8fe576e481c70bf2f783c53b9fa46a
parent493a365e3619b58a315fd568546b8bd4acd09c98 (diff)
ENGR00181407-3: Add Compaq touch screen interface for nano-x
Add Compaq touch screen interface for nano-x. Nano-x work with touch screen driver via Compaq touch screen event format, this patch could add the support above mouse device. Signed-off-by: Alison Wang <b18965@freescale.com>
-rw-r--r--drivers/input/Kconfig9
-rw-r--r--drivers/input/mousedev.c69
2 files changed, 73 insertions, 5 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 23e82e46656d..376fdb6decc7 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -92,6 +92,15 @@ config INPUT_MOUSEDEV_PSAUX
If unsure, say Y.
+config TSDEV_COMPATIBLE
+ bool "Compaq touchscreen interface compatible mouse"
+ default n
+ depends on INPUT_MOUSEDEV
+ ---help---
+ Say Y here if you have an application that only can understand the
+ Compaq touchscreen protocol for absolute pointer data. This is
+ useful namely for embedded configurations.
+ If unsure, say N.
config INPUT_MOUSEDEV_SCREEN_X
int "Horizontal screen resolution"
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 0110b5a3a167..beaf4a27774b 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 1999-2002 Vojtech Pavlik
* Copyright (c) 2004 Dmitry Torokhov
+ * Copyright 2012 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published by
@@ -52,6 +53,14 @@ static unsigned tap_time = 200;
module_param(tap_time, uint, 0644);
MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
+#ifdef CONFIG_TSDEV_COMPATIBLE
+struct ts_event {
+ short pressure;
+ short x;
+ short y;
+ short millisecs;
+};
+#endif
struct mousedev_hw_data {
int dx, dy, dz;
int x, y;
@@ -91,13 +100,21 @@ struct mousedev_motion {
unsigned long buttons;
};
+#ifdef CONFIG_TSDEV_COMPATIBLE
+#define PACKET_QUEUE_LEN 64
+#else
#define PACKET_QUEUE_LEN 16
+#endif
struct mousedev_client {
struct fasync_struct *fasync;
struct mousedev *mousedev;
struct list_head node;
+#ifdef CONFIG_TSDEV_COMPATIBLE
+ struct ts_event packets[PACKET_QUEUE_LEN];
+#else
struct mousedev_motion packets[PACKET_QUEUE_LEN];
+#endif
unsigned int head, tail;
spinlock_t packet_lock;
int pos_x, pos_y;
@@ -188,8 +205,11 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
size = xres ? : 1;
value = clamp(value, min, max);
-
+#ifndef CONFIG_TSDEV_COMPATIBLE
mousedev->packet.x = ((value - min) * xres) / size;
+#else
+ mousedev->packet.x = value;
+#endif
mousedev->packet.abs_event = 1;
break;
@@ -202,8 +222,11 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
size = yres ? : 1;
value = clamp(value, min, max);
-
+#ifndef CONFIG_TSDEV_COMPATIBLE
mousedev->packet.y = yres - ((value - min) * yres) / size;
+#else
+ mousedev->packet.y = value;
+#endif
mousedev->packet.abs_event = 1;
break;
}
@@ -270,7 +293,11 @@ static void mousedev_notify_readers(struct mousedev *mousedev,
struct mousedev_hw_data *packet)
{
struct mousedev_client *client;
+#ifdef CONFIG_TSDEV_COMPATIBLE
+ struct ts_event *p;
+#else
struct mousedev_motion *p;
+#endif
unsigned int new_head;
int wake_readers = 0;
@@ -281,6 +308,14 @@ static void mousedev_notify_readers(struct mousedev *mousedev,
spin_lock(&client->packet_lock);
p = &client->packets[client->head];
+#ifdef CONFIG_TSDEV_COMPATIBLE
+ p->x = packet->x;
+ p->y = packet->y;
+ p->pressure = packet->buttons;
+ client->ready = 1;
+ new_head = (client->head + 1) % PACKET_QUEUE_LEN;
+ client->head = new_head;
+#else
if (client->ready && p->buttons != mousedev->packet.buttons) {
new_head = (client->head + 1) % PACKET_QUEUE_LEN;
if (new_head != client->tail) {
@@ -311,7 +346,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev,
if (p->dx || p->dy || p->dz ||
p->buttons != client->last_buttons)
client->ready = 1;
-
+#endif
spin_unlock(&client->packet_lock);
if (client->ready) {
@@ -734,14 +769,21 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer,
struct mousedev_client *client = file->private_data;
struct mousedev *mousedev = client->mousedev;
signed char data[sizeof(client->ps2)];
+#ifdef CONFIG_TSDEV_COMPATIBLE
+ struct ts_event *p;
+#endif
int retval = 0;
if (!client->ready && !client->buffer && mousedev->exist &&
(file->f_flags & O_NONBLOCK))
return -EAGAIN;
-
+#ifdef CONFIG_TSDEV_COMPATIBLE
+ retval = wait_event_interruptible(mousedev->wait,
+ client->head != client->tail || !mousedev->exist);
+#else
retval = wait_event_interruptible(mousedev->wait,
!mousedev->exist || client->ready || client->buffer);
+#endif
if (retval)
return retval;
@@ -749,7 +791,24 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer,
return -ENODEV;
spin_lock_irq(&client->packet_lock);
+#ifdef CONFIG_TSDEV_COMPATIBLE
+ p = &client->packets[client->tail];
+
+ while (client->head != client->tail && client->ready &&
+ retval + sizeof(struct ts_event) <= count) {
+
+ if (copy_to_user(buffer, p, sizeof(struct ts_event)))
+ return -EFAULT;
+
+ retval += sizeof(struct ts_event);
+ client->tail = (client->tail + 1) % PACKET_QUEUE_LEN;
+ if (client->tail == client->head)
+ client->ready = 0;
+ }
+ spin_unlock_irq(&client->packet_lock);
+ return retval;
+#else
if (!client->buffer && client->ready) {
mousedev_packet(client, client->ps2);
client->buffer = client->bufsiz;
@@ -760,7 +819,7 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer,
memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
client->buffer -= count;
-
+#endif
spin_unlock_irq(&client->packet_lock);
if (copy_to_user(buffer, data, count))