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

Re: Wrestling with Dell Precision laptop. You too? Discuss tips & experience



Here's my progress report on Debian and the Dell Precision M4600.

I am in a state of "currently not broken" usage.

I still use noapic and it allows suspend and restart.

I have worked A LOT on the touchpad question. There are hundreds of
posts about it, too confusing.  The best thing i've found is this
thread on the Redhat bugzilla.

 https://bugzilla.redhat.com/show_bug.cgi?id=590880

I think you will conclude the following.

1. We do not yet have data from ALPS to make the true multitouch features work.

However

2. There is a patch for the Linux kernel that you can apply.  Toward
the end of the thread, you see my post about it, and I'm happy to say
that the newest version of the patch solves the worst of the problems.
The patch I'm using now is attached to this email, and you can find
instructions on how to apply it on many sites, this one seem best to
me

http://budts.be/weblog/2010/12/dell-latitude-e6510-screen-and-touchpad

https://patchwork.kernel.org/patch/350841/

After this, you should get a thing that is seen as

1. vertical scrolling by drawing finger down right side
2. tap to click
3. double-click on sliders to "grab" them
4. no touchpad failures after suspend/resume

It also fixes the "accidental cursor movement" problem while typing.

I asked "why is this not in the kernel now."  If you go read here:

https://bugzilla.kernel.org/show_bug.cgi?id=14660

you see that the people who manage the kernel are waiting until ALPS
gives the data for a fully functional multi touch device, they do not
want to emulate some glide ps/2 mouse with the patch that ALPS and
dell are providing.

So now i see no "touchpad" config options in the Gnome mouse config
thing, and cannot use the synapctics tools to adjust it.  It is a
more-or-less dumb mouse device without many options.

$ cat /proc/bus/input/devices

I: Bus=0011 Vendor=0002 Product=0005 Version=7326
N: Name="ImPS/2 ALPS GlidePoint"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input5
U: Uniq=
H: Handlers=mouse0 event5
B: PROP=0
B: EV=7
B: KEY=70000 0 0 0 0
B: REL=103

Nevertheless, I am not so disgusted to own this Dell anymore.  The
only thing that really
upsets me about the machine now is that the touchpad is set on the far
left side of the keyboard,
and I can't reach the buttons without moving my right hand off the
keys. I would NEVER have chosen  this keyboard if I had seen it, but I
was trying to order the M4500,  which I had used in the past,
but it was no longer available.

This may not seem like much progress, but I've invested at least 30
hours on the touchpad alone, and I am glad to report some progress.

pj





-- 
Paul E. Johnson
Professor, Political Science
1541 Lilac Lane, Room 504
University of Kansas
diff -urNp a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
--- a/drivers/input/mouse/alps.c	2010-08-06 12:43:11.000000000 -0500
+++ b/drivers/input/mouse/alps.c	2010-09-20 15:42:26.000000000 -0500
@@ -15,6 +15,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/dmi.h>
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/serio.h>
@@ -63,6 +64,8 @@ static const struct alps_model_info alps
 	/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
 	{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
 		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
+	/* Dell Precision 4500 */
+	{ { 0x73, 0x02, 0x64 }, 0x80, 0x80, 0 },
 	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },	  /* Dell Vostro 1400 */
 	{ { 0x52, 0x01, 0x14 }, 0xff, 0xff,
 		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },	  /* Toshiba Tecra A11-11L */
@@ -111,6 +114,92 @@ static const struct alps_model_info alps
  * on a dualpoint, etc.
  */
 
+static const struct dmi_system_id dell_quirk_table[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "8"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "9"),
+		},
+	},
+	{ }
+};
+
+int alps_model_quirk_enabled;
+static void dell_e2_model_init(void *data);
+
+ /* Magic Sequence to enable Intellimouse Mode on Dell E2 Touchpads*/
+
+static int dell_e2_setup_intellimouse_mode(void *data)
+{
+	struct psmouse *psmouse = (struct psmouse *)(data);
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[] = {0, 0, 0};
+
+	if (!dmi_check_system(dell_quirk_table))
+		return -1;
+
+	if (ps2_command(ps2dev, param, 0x00f5) ||
+		ps2_command(ps2dev, param, 0x00ea) ||
+		ps2_command(ps2dev, param, 0x00ec) ||
+		ps2_command(ps2dev, param, 0x00ec) ||
+		ps2_command(ps2dev, param, 0x00ec) ||
+		ps2_command(ps2dev, param, 0x03e9))
+			return -1;
+
+	dbg("alps:dell_e2_setup: param[0]: %x,"
+		"param[1]: %x, param[2]: %x\n", param[0],
+					param[1], param[2]);
+ /* Check for supported model to continue */
+
+	if (!((param[0] == 0x88) && (param[1] == 0x07)
+		&& ((param[2] == 0x9D) || (param[2] == 0x9B))))
+		return -1;
+
+	if (ps2_command(ps2dev, NULL, 0x00ec) ||
+		ps2_command(ps2dev, NULL, 0x00f0) ||
+		ps2_command(ps2dev, NULL, 0x00f0) ||
+		ps2_command(ps2dev, NULL, 0x00f0) ||
+		ps2_command(ps2dev, NULL, 0x00f3) ||
+		ps2_command(ps2dev, NULL, 0x0028) ||
+		ps2_command(ps2dev, NULL, 0x00f0) ||
+		ps2_command(ps2dev, NULL, 0x00f6) ||
+		ps2_command(ps2dev, NULL, 0x00ea) ||
+		ps2_command(ps2dev, NULL, 0x00f4))
+			return -1;
+
+	return 0;
+}
+
+static const struct alps_model_quirk alps_model_init_quirk_tbl[] = {
+
+	{ {0x73, 0x02, 0x64}, dell_e2_setup_intellimouse_mode, dell_e2_model_init }
+};
+
+static int alps_model_hw_init_quirk(struct psmouse *psmouse,
+					const struct alps_model_info *model)
+{
+	int rc = 1;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(alps_model_init_quirk_tbl); i++) {
+		if (!memcmp(model->signature,
+			alps_model_init_quirk_tbl[i].signature,
+			    sizeof(alps_model_init_quirk_tbl[i].signature))) {
+				rc = alps_model_init_quirk_tbl[i].alps_model_quirk_hw_init(psmouse);
+				alps_model_quirk_enabled = i + 1;
+				break;
+		}
+	}
+
+	return rc;
+}
+
 static bool alps_is_valid_first_byte(const struct alps_model_info *model,
 				     unsigned char data)
 {
@@ -599,6 +688,10 @@ static int alps_hw_init(struct psmouse *
 	struct alps_data *priv = psmouse->private;
 	const struct alps_model_info *model = priv->i;
 
+	if (alps_model_hw_init_quirk(psmouse, model)) {
+		alps_model_quirk_enabled = 0;
+	}
+
 	if ((model->flags & ALPS_PASS) &&
 	    alps_passthrough_mode(psmouse, true)) {
 		return -1;
@@ -651,6 +744,21 @@ static void alps_disconnect(struct psmou
 	kfree(priv);
 }
 
+static void dell_e2_model_init(void *data)
+{
+	struct psmouse *psmouse = (struct psmouse *)(data);
+	struct input_dev *dev = psmouse->dev;
+
+	__set_bit(BTN_MIDDLE, dev->keybit);
+	__set_bit(REL_WHEEL, dev->relbit);
+
+	psmouse->pktsize = 4;
+	psmouse->type = PSMOUSE_IMPS;
+	psmouse->disconnect = alps_disconnect;
+	psmouse->reconnect = alps_reconnect;
+
+}
+
 int alps_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv;
@@ -677,6 +785,12 @@ int alps_init(struct psmouse *psmouse)
 	if (alps_hw_init(psmouse))
 		goto init_fail;
 
+	if (alps_model_quirk_enabled) {
+		printk(KERN_WARNING "alps.c: Enabled hardware quirk, falling back to psmouse-core\n");
+		alps_model_init_quirk_tbl[alps_model_quirk_enabled-1].alps_model_quirk_init(psmouse);
+		return 0;
+	}
+
 	/*
 	 * Undo part of setup done for us by psmouse core since touchpad
 	 * is not a relative device.
diff -urNp a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
--- a/drivers/input/mouse/alps.h	2010-08-06 12:43:06.000000000 -0500
+++ b/drivers/input/mouse/alps.h	2010-09-20 03:20:07.000000000 -0500
@@ -26,6 +26,12 @@ struct alps_data {
 	struct timer_list timer;
 };
 
+struct alps_model_quirk {
+unsigned char signature[3];
+int (*alps_model_quirk_hw_init)(void *data);
+void (*alps_model_quirk_init)(void *data);
+};
+
 #ifdef CONFIG_MOUSE_PS2_ALPS
 int alps_detect(struct psmouse *psmouse, bool set_properties);
 int alps_init(struct psmouse *psmouse);
diff -urNp a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2010-08-06 12:42:57.000000000 -0500
+++ b/drivers/input/mouse/psmouse-base.c	2010-09-20 15:20:35.000000000 -0500
@@ -659,7 +659,8 @@ static int psmouse_extensions(struct psm
 		ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
 		if (alps_detect(psmouse, set_properties) == 0) {
 			if (!set_properties || alps_init(psmouse) == 0)
-				return PSMOUSE_ALPS;
+/* If ALPS model quirk was applied, don't change the settings */
+				return psmouse->type ? psmouse->type : PSMOUSE_ALPS;
 /*
  * Init failed, try basic relative protocols
  */

Reply to: