From: Maxim Levitsky <maximlevitsky@gmail.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
Vojtech Pavlik <vojtech@suse.cz>
Subject: [PATCH v2] ALPS: Add support for 4 directions button on Acer Aspire 5720
Date: Wed, 11 Nov 2009 11:09:50 +0200 [thread overview]
Message-ID: <1257930590.3601.2.camel@maxim-laptop> (raw)
In-Reply-To: <20091110173047.GC15263@core.coreip.homeip.net>
>From 6b263982ffd62ae4621a5202f0084983af8dc093 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Wed, 11 Nov 2009 11:03:35 +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@gmail.com>
---
drivers/input/mouse/alps.c | 75 +++++++++++++++++++++++++++++++++++++-------
drivers/input/mouse/alps.h | 2 +-
2 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index f361106..96fa093 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,16 @@
#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_FOUR_BUTTONS 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 */
@@ -117,7 +121,7 @@ static void alps_process_packet(struct psmouse *psmouse)
z = packet[5];
}
- if (priv->i->flags & ALPS_FW_BK_1) {
+ if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FOUR_BUTTONS)) {
back = packet[0] & 0x10;
forward = packet[2] & 4;
}
@@ -147,7 +151,9 @@ 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);
+
+ if (!(priv->i->flags & ALPS_FOUR_BUTTONS))
+ input_report_key(dev, BTN_MIDDLE, middle);
/* Convert hardware tap to a reasonable Z value */
if (ges && !fin) z = 40;
@@ -185,6 +191,13 @@ static void alps_process_packet(struct psmouse *psmouse)
input_report_key(dev, BTN_BACK, back);
}
+ if (priv->i->flags & ALPS_FOUR_BUTTONS) {
+ input_report_key(dev, BTN_0, forward);
+ input_report_key(dev, BTN_1, back);
+ input_report_key(dev, BTN_2, middle);
+ input_report_key(dev, BTN_3, packet[0] & 0x20);
+ }
+
input_sync(dev);
}
@@ -216,7 +229,8 @@ 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;
static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
@@ -268,9 +282,15 @@ 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 +413,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_FOUR_BUTTONS;
+ 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 +440,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 +489,7 @@ static void alps_disconnect(struct psmouse *psmouse)
psmouse_reset(psmouse);
input_unregister_device(priv->dev2);
+ kfree(priv->i);
kfree(priv);
}
@@ -487,6 +531,13 @@ int alps_init(struct psmouse *psmouse)
dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
}
+ if (priv->i->flags & ALPS_FOUR_BUTTONS) {
+ dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
+ dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
+ 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);
dev2->phys = priv->phys;
dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
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
next prev parent reply other threads:[~2009-11-11 9:09 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-31 2:10 ALPS touchpad with 4 directions button doesnt work as intended Maxim Levitsky
2009-11-02 5:38 ` Dmitry Torokhov
2009-11-02 17:20 ` Maxim Levitsky
2009-11-02 18:00 ` Dmitry Torokhov
[not found] ` <1257199967.3164.8.camel@localhost.localdomain>
2009-11-02 22:16 ` Maxim Levitsky
2009-11-02 22:25 ` Dmitry Torokhov
2009-11-02 23:21 ` Maxim Levitsky
2009-11-10 9:55 ` Maxim Levitsky
2009-11-10 10:03 ` [PATCH] ALPS: Add support for 4 directions button on Acer Aspire 5720 Maxim Levitsky
2009-11-10 17:30 ` Dmitry Torokhov
2009-11-11 9:09 ` Maxim Levitsky [this message]
2009-11-15 8:53 ` [PATCH v2] " Dmitry Torokhov
2009-11-16 18:05 ` Maxim Levitsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1257930590.3601.2.camel@maxim-laptop \
--to=maximlevitsky@gmail.com \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=vojtech@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®