lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1257847427.4921.13.camel@maxim-laptop>
Date:	Tue, 10 Nov 2009 12:03:47 +0200
From:	Maxim Levitsky <maximlevitsky@...il.com>
To:	linux-kernel <linux-kernel@...r.kernel.org>
Cc:	Vojtech Pavlik <vojtech@...e.cz>, Dmitry Torokhov <dtor@...l.ru>
Subject: [PATCH] ALPS: Add support for 4 directions button on Acer Aspire
 5720

>>From 4aefbe6c09df53881c4738c1a524be595a388e28 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@...il.com>
Date: Tue, 10 Nov 2009 11:57:56 +0200
Subject: [PATCH] ALPS: Add support for 4 directions button on Acer Aspire 5720
 Implemented using DMI due to uncertainty about systems that have
 only the middle button

Signed-off-by: Maxim Levitsky <maximlevitsky@...il.com>
---
 drivers/input/mouse/alps.c |   81 +++++++++++++++++++++++++++++++++++--------
 drivers/input/mouse/alps.h |    2 +-
 2 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index f361106..06a5709 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -17,6 +17,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
+#include <linux/dmi.h>
 
 #include "psmouse.h"
 #include "alps.h"
@@ -28,13 +29,17 @@
 #define dbg(format, arg...) do {} while (0)
 #endif
 
-#define ALPS_DUALPOINT	0x01
-#define ALPS_WHEEL	0x02
-#define ALPS_FW_BK_1	0x04
-#define ALPS_4BTN	0x08
-#define ALPS_OLDPROTO	0x10
-#define ALPS_PASS	0x20
-#define ALPS_FW_BK_2	0x40
+
+#define ALPS_OLDPROTO	0x01	/* old style input */
+#define ALPS_DUALPOINT	0x02	/* touchpad has trackstick */
+#define ALPS_PASS	0x04	/* select which device to address each time */
+
+
+#define ALPS_WHEEL	0x08	/* hardware wheel present */
+#define ALPS_FW_BK_1	0x10	/* front & back buttons present */
+#define ALPS_FW_BK_2	0x20	/* front & back buttons present */
+#define ALPS_EXTRA	0x40	/* 4 direction button present */
+
 
 static const struct alps_model_info alps_model_data[] = {
 	{ { 0x32, 0x02, 0x14 },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
@@ -147,7 +152,13 @@ static void alps_process_packet(struct psmouse *psmouse)
 
 	input_report_key(dev, BTN_LEFT, left);
 	input_report_key(dev, BTN_RIGHT, right);
-	input_report_key(dev, BTN_MIDDLE, middle);
+
+
+	/* middle button serves as left scroll button */
+	if ((priv->i->flags & ALPS_EXTRA))
+		input_report_key(dev, BTN_2, middle);
+	else
+		input_report_key(dev, BTN_MIDDLE, middle);
 
 	/* Convert hardware tap to a reasonable Z value */
 	if (ges && !fin) z = 40;
@@ -181,10 +192,13 @@ static void alps_process_packet(struct psmouse *psmouse)
 		input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
 
 	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
-		input_report_key(dev, BTN_FORWARD, forward);
-		input_report_key(dev, BTN_BACK, back);
+		input_report_key(dev, BTN_0, forward);
+		input_report_key(dev, BTN_1, back);
 	}
 
+	if (priv->i->flags & ALPS_EXTRA)
+		input_report_key(dev, BTN_3, packet[0] & 0x20);
+
 	input_sync(dev);
 }
 
@@ -216,9 +230,10 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 	return PSMOUSE_GOOD_DATA;
 }
 
-static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
+static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	struct alps_model_info *model_info;
 	static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
 	unsigned char param[4];
 	int i;
@@ -268,9 +283,16 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
 
 	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
 		if (!memcmp(param, alps_model_data[i].signature,
-			    sizeof(alps_model_data[i].signature)))
-			return alps_model_data + i;
+			    sizeof(alps_model_data[i].signature))) {
+
+			model_info = kmalloc(sizeof(struct alps_model_info),
+				GFP_KERNEL);
 
+			memcpy(model_info, alps_model_data + i,
+				sizeof(struct alps_model_info));
+
+			return model_info;
+		}
 	return NULL;
 }
 
@@ -393,6 +415,25 @@ static int alps_poll(struct psmouse *psmouse)
 	return 0;
 }
 
+static int alps_dmi_flags;
+static int alps_acer_5720_flags(const struct dmi_system_id *d)
+{
+	alps_dmi_flags = ALPS_EXTRA | ALPS_FW_BK_1;
+	return 0;
+}
+
+static struct dmi_system_id alps_dmi_table[] = {
+	{
+	 .callback = alps_acer_5720_flags,
+	 .ident = "Acer Aspire 5720",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+		},
+	},
+	{}
+};
+
 static int alps_hw_init(struct psmouse *psmouse, int *version)
 {
 	struct alps_data *priv = psmouse->private;
@@ -401,6 +442,10 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
 	if (!priv->i)
 		return -1;
 
+	dmi_check_system(alps_dmi_table);
+	if (alps_dmi_flags)
+		priv->i->flags = alps_dmi_flags;
+
 	if ((priv->i->flags & ALPS_PASS) &&
 	    alps_passthrough_mode(psmouse, true)) {
 		return -1;
@@ -446,6 +491,7 @@ static void alps_disconnect(struct psmouse *psmouse)
 
 	psmouse_reset(psmouse);
 	input_unregister_device(priv->dev2);
+	kfree(priv->i);
 	kfree(priv);
 }
 
@@ -483,8 +529,13 @@ int alps_init(struct psmouse *psmouse)
 	}
 
 	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
-		dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
-		dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
+		dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
+		dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
+	}
+
+	if (priv->i->flags & ALPS_EXTRA) {
+		dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
+		dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
 	}
 
 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index bc87936..92505d5 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -21,7 +21,7 @@ struct alps_model_info {
 struct alps_data {
 	struct input_dev *dev2;		/* Relative device */
 	char phys[32];			/* Phys */
-	const struct alps_model_info *i;/* Info */
+	struct alps_model_info *i;	/* Info */
 	int prev_fin;			/* Finger bit from previous packet */
 };
 
-- 
1.6.3.3



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ