[ltp] Patch for X40 (was: [ANN] tp_smapi 0.19 adds dates, improves stability)

Elias Oltmanns linux-thinkpad@linux-thinkpad.org
Tue, 11 Apr 2006 18:32:03 +0200


--==-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=

Hi all,

just in case anybody is interested, here is the patch to hdaps which
makes it work on an x40. Basically, this is just the patch against the
original hdaps, which has been floating around on these lists, adapted
to tp_smapi. It applies to the kernel (2.6.16) on top of Shem's patch
you get by issuing
make patch

hdaps_invert has been changed to give a bitwise representation of
possibly inverted axes. Bit 1 refers to the x axis whereas bit 2
refers to the y axis. Wouldn't it make sense to adapt the inverted
axis handling in the original hdaps module and in tp_smape as well? I
know that the extra initialisation part for the X40 was not accepted
upstream because seems like a desperate guess rather than an
intelligent one. There should be know objection to the inverted axis
part, though.

Regards,

Elias

--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=missing-init.patch
Content-Transfer-Encoding: quoted-printable
Content-Description: tp_smapi-x40.patch

=2D-- linux/drivers/hwmon/hdaps.c.orig	2006-04-10 22:58:58.000000000 +0200
+++ linux/drivers/hwmon/hdaps.c	2006-04-11 09:02:11.000000000 +0200
@@ -124,15 +124,15 @@
 		return ret;
=20
 	if (row[HDAPS_IDX_STATE]>=3DSTATE_HAVE_POS) {
=2D		pos_x =3D *(s16*)(row+HDAPS_IDX_XPOS) * (hdaps_invert?-1:1);
=2D		pos_y =3D *(s16*)(row+HDAPS_IDX_YPOS) * (hdaps_invert?-1:1);
+		pos_x =3D *(s16*)(row+HDAPS_IDX_XPOS) * (hdaps_invert&1?-1:1);
+		pos_y =3D *(s16*)(row+HDAPS_IDX_YPOS) * (hdaps_invert&2?-1:1);
 	} else
 		return -EBUSY;
=20
 	/* Don't insist on a "variance" readout; it's useless anyway. */
 	if (row[HDAPS_IDX_STATE]>=3DSTATE_HAVE_VAR) {
=2D		var_x =3D *(s16*)(row+HDAPS_IDX_XVAR) * (hdaps_invert?-1:1);
=2D		var_y =3D *(s16*)(row+HDAPS_IDX_YVAR) * (hdaps_invert?-1:1);
+		var_x =3D *(s16*)(row+HDAPS_IDX_XVAR) * (hdaps_invert&1?-1:1);
+		var_y =3D *(s16*)(row+HDAPS_IDX_YVAR) * (hdaps_invert&2?-1:1);
 	}
=20
 	/* Keyboard and mouse activity status is cleared as soon as it's read,
@@ -191,11 +191,23 @@
=20
 	tp_controller_lock();
=20
+	/*
+	 * X40 seems to need to have this called twice or more
+	 * hdaps_invert is =3D=3D2 if we are running on a X40
+	 */
 	outb(0x13, 0x1610);
 	outb(0x01, 0x161f);
=2D	if (__wait_latch(0x161f, 0x00))
+	ret=3D__wait_latch(0x161f, 0x00);
+	if (hdaps_invert =3D=3D 2) {
+		outb(0x13, 0x1610);
+		outb(0x01, 0x161f);
+		ret=3D__wait_latch(0x161f, 0x00);
+	}
+	if (ret)
 		goto out;
=20
+	ret =3D -ENXIO;
+
 	status =3D inb(0x1611);
 	if (status !=3D 0x03 && /* Invertex axes (ThinkPad R50p, T41p, R42p) */
 	    status !=3D 0x02 && /* Chip already initialized */
@@ -451,14 +463,24 @@
 	return 1;
 }
=20
=2D/* hdaps_dmi_match_invert - found an inverted match. */
=2Dstatic int hdaps_dmi_match_invert(struct dmi_system_id *id)
+/* hdaps_dmi_match_invert_xy - found an inverted match. */
+static int hdaps_dmi_match_invert_xy(struct dmi_system_id *id)
 {
=2D	hdaps_invert =3D 1;
+	hdaps_invert =3D 3;
 	printk(KERN_INFO "hdaps: inverting axis readings.\n");
 	return hdaps_dmi_match(id);
 }
=20
+
+/* hdaps_dmi_match_invert_y - found an y-inverted match. */
+static int hdaps_dmi_match_invert_y(struct dmi_system_id *id)
+{
+    hdaps_invert =3D 2;
+    printk(KERN_INFO "hdaps: inverting y-axis readings.\n");
+    return hdaps_dmi_match(id);
+}
+
+
 #define HDAPS_DMI_MATCH_NORMAL(model)	{		\
 	.ident =3D "IBM " model,				\
 	.callback =3D hdaps_dmi_match,			\
@@ -468,31 +490,41 @@
 	}						\
 }
=20
=2D#define HDAPS_DMI_MATCH_INVERT(model)	{		\
+#define HDAPS_DMI_MATCH_INVERT_XY(model)	{		\
 	.ident =3D "IBM " model,				\
=2D	.callback =3D hdaps_dmi_match_invert,		\
+	.callback =3D hdaps_dmi_match_invert_xy,		\
 	.matches =3D {					\
 		DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),	\
 		DMI_MATCH(DMI_PRODUCT_VERSION, model)	\
 	}						\
 }
=20
+#define HDAPS_DMI_MATCH_INVERT_Y(model)   {       \
+    .ident =3D "IBM " model,              \
+    .callback =3D hdaps_dmi_match_invert_y,      \
+    .matches =3D {                    \
+        DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), \
+        DMI_MATCH(DMI_PRODUCT_VERSION, model)   \
+    }                       \
+}
+
+
 static int __init hdaps_init(void)
 {
 	int ret;
=20
 	/* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */
 	struct dmi_system_id hdaps_whitelist[] =3D {
=2D		HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),
+		HDAPS_DMI_MATCH_INVERT_XY("ThinkPad R50p"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"),
=2D		HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"),
+		HDAPS_DMI_MATCH_INVERT_XY("ThinkPad T41p"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"),
=2D		HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),
+		HDAPS_DMI_MATCH_INVERT_XY("ThinkPad T42p"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
=2D		HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
+		HDAPS_DMI_MATCH_INVERT_Y("ThinkPad X40"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"),
 		HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
 		{ .ident =3D NULL }
@@ -572,7 +604,7 @@
 module_init(hdaps_init);
 module_exit(hdaps_exit);
=20
=2Dmodule_param_named(invert, hdaps_invert, bool, 0);
+module_param_named(invert, hdaps_invert, int, 0);
 MODULE_PARM_DESC(invert, "invert data along each axis");
=20
 MODULE_AUTHOR("Robert Love");

--=-=-=--

--==-=-=
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)

iD8DBQBEO9o3UQAwKq4pPFkRAkdnAJsGD3cTgWnpZ5cdwYtInOTEf1dNrgCfYaj/
/Fl7bj02CVEJnto2Fq+yHbI=
=5mq0
-----END PGP SIGNATURE-----
--==-=-=--