Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Jan 2006 02:49:17 -0500
From:      Anish Mistry <mistry.7@osu.edu>
To:        freebsd-current@freebsd.org
Cc:        colazelli@gmail.com, Brandon Mitchell <magicsmoke@gmail.com>
Subject:   [PATCH] acpi_fujitsu UPDATE
Message-ID:  <200601290249.41648.mistry.7@osu.edu>

next in thread | raw e-mail | index | archive | help
--Boundary-00=_VOH3D8QYbbI4KBz
Content-Type: multipart/signed; boundary="nextPart2333793.72tP5KujUY";
	protocol="application/pgp-signature"; micalg=pgp-sha1
Content-Transfer-Encoding: 7bit

--nextPart2333793.72tP5KujUY
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

	I've attached a patch for acpi_fujitsu that SHOULD allow non-P=20
laptops to attach the device.  I need other people to test this=20
because the P-Series (My laptop P2110) has all of the methods so the=20
conditional method probing always works.  If you could report back=20
soon, hopefully we can get a commiter to squeeze it in before the=20
freeze.
	The major changes are:
	- Individual method probing - So if you are missing a few methods you=20
only lose that functionality.
	- I finally figured out what the RBLL, RVOL, GHKS, GSIF
		RBLL - lcd_brightness radix
		RVOL - volume radix
		GHKS - Currently activated hotkey (internal)
		GSIF - Hotkey mask (internal)

Also at:
http://am-productions.biz/docs/acpi_fujitsu.patch

=2D-=20
Anish Mistry

--nextPart2333793.72tP5KujUY
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (FreeBSD)

iD8DBQBD3HOVxqA5ziudZT0RAh/PAJ9fMuXAHgP9ozNf8S+DtIQ/fyw5wACeJbBY
EzFTFQqYaO9IZsy42ivsPt4=
=7n2S
-----END PGP SIGNATURE-----

--nextPart2333793.72tP5KujUY--

--Boundary-00=_VOH3D8QYbbI4KBz
Content-Type: text/x-diff;
  charset="us-ascii";
  name="acpi_fujitsu.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="acpi_fujitsu.patch"

--- acpi_fujitsu.c.orig	Sun Jan 29 02:19:52 2006
+++ acpi_fujitsu.c	Sun Jan 29 02:35:36 2006
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2002 Sean Bullington <seanATstalker.org>
- *               2003-2005 Anish Mistry <amistry@am-productions.biz>
+ *               2003-2006 Anish Mistry <amistry@am-productions.biz>
  *               2004 Mark Santcroos <marks@ripe.net>
  * All Rights Reserved.
  *
@@ -44,11 +44,8 @@
 #define _COMPONENT	ACPI_OEM
 ACPI_MODULE_NAME("Fujitsu")
 
-/* Change and update bits for the buttons */
-#define MOUSE_UPDATED_BIT	0x80000000
+/* Change and update bits for the hotkeys */
 #define VOLUME_MUTE_BIT		0x40000000
-#define VOLUME_CHANGE_BIT	0x80000000
-#define BRIGHTNESS_CHANGE_BIT	0x80000000
 
 /* Values of settings */
 #define GENERAL_SETTING_BITS	0x0fffffff
@@ -57,9 +54,20 @@
 #define BRIGHTNESS_SETTING_BITS	GENERAL_SETTING_BITS
 
 /* Possible state changes */
-#define VOLUME_CHANGED	1
-#define BRIGHT_CHANGED	2
-#define MOUSE_CHANGED	3
+/*
+ * These are NOT arbitrary values.  They are the
+ * GHKS return value from the device that says which
+ * hotkey is active.  They should match up with a bit
+ * from the GSIF bitmask.
+ */
+#define BRIGHT_CHANGED	0x01
+#define VOLUME_CHANGED	0x04
+#define MOUSE_CHANGED	0x08
+/*
+ * It is unknown which hotkey this bit is supposed to indicate, but
+ * according to values from GSIF this is a valid flag.
+ */
+#define UNKNOWN_CHANGED	0x10
 
 /* sysctl values */
 #define FN_MUTE			0
@@ -72,6 +80,10 @@
 #define METHOD_GMOU	2
 #define METHOD_GVOL	3
 #define METHOD_MUTE	4
+#define METHOD_RBLL	5
+#define METHOD_RVOL	6
+#define METHOD_GSIF	7
+#define METHOD_GHKS	8
 
 /* Notify event */
 #define	ACPI_NOTIFY_STATUS_CHANGED	0x80
@@ -83,6 +95,7 @@
 struct int_nameval {
 	char	*name;
 	int	value;
+	int	exists;
 };
 
 /*
@@ -95,12 +108,13 @@
 	/* Control methods */
 	struct int_nameval	_sta,	/* unused */
 				gbll,	/* brightness */
-				ghks,	/* unused */
+				ghks,	/* hotkey selector */
+				gbuf,	/* unused (buffer?) */
 				gmou,	/* mouse */
-				gsif,	/* unused */
+				gsif,	/* function key bitmask */
 				gvol,	/* volume */
-				rbll,	/* unused */
-				rvol;	/* unused */
+				rbll,	/* number of brightness levels (radix) */
+				rvol;	/* number of volume levels (radix) */
 
 	/* State variables */
 	uint8_t		bIsMuted;	/* Is volume muted */
@@ -126,6 +140,7 @@
 /* Utility function declarations */
 static uint8_t acpi_fujitsu_update(struct acpi_fujitsu_softc *sc);
 static uint8_t acpi_fujitsu_init(struct acpi_fujitsu_softc *sc);
+static uint8_t acpi_fujitsu_check_hardware(struct acpi_fujitsu_softc *sc);
 
 /* Driver/Module specific structure definitions. */
 static device_method_t acpi_fujitsu_methods[] = {
@@ -144,13 +159,13 @@
 	sizeof(struct acpi_fujitsu_softc),
 };
 
-/* Prototype for function buttons for getting/setting a value. */
+/* Prototype for function hotkeys for getting/setting a value. */
 static int acpi_fujitsu_method_get(struct acpi_fujitsu_softc *sc, int method);
 static int acpi_fujitsu_method_set(struct acpi_fujitsu_softc *sc, int method, int value);
 
 static char *fujitsu_ids[] = { "FUJ02B1", NULL };
 
-ACPI_SERIAL_DECL(fujitsu, "Fujitsu Function Buttons");
+ACPI_SERIAL_DECL(fujitsu, "Fujitsu Function Hotkeys");
 
 /* sysctl names and function calls */
 static struct {
@@ -178,6 +193,16 @@
 		.method		= METHOD_GVOL,
 		.description	= "Speakers/headphones volume level"
 	},
+	{
+		.name		= "volume_radix",
+		.method		= METHOD_RVOL,
+		.description	= "Number of volume level steps"
+	},
+	{
+		.name		= "lcd_brightness_radix",
+		.method		= METHOD_RBLL,
+		.description	= "Number of brightness level steps"
+	},
 
 	{ NULL, 0, NULL }
 };
@@ -197,7 +222,7 @@
 	    device_get_unit(dev) != 0)
 		return (ENXIO);
 
-	device_set_desc(dev, "Fujitsu Function Buttons");
+	device_set_desc(dev, "Fujitsu Function Hotkeys");
 
 	return (0);
 }
@@ -217,10 +242,10 @@
 	AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,
 	    acpi_fujitsu_notify_handler, sc);
 
-	/* Snag our default values for the buttons / button states. */
+	/* Snag our default values for the hotkys / hotkey states. */
 	ACPI_SERIAL_BEGIN(fujitsu);
 	if (!acpi_fujitsu_init(sc))
-		device_printf(dev, "Couldn't initialize button states!\n");
+		device_printf(dev, "Couldn't initialize hotkey states!\n");
 	ACPI_SERIAL_END(fujitsu);
 
 	return (0);
@@ -316,13 +341,13 @@
 
 /*
  * Initializes the names of the ACPI control methods and grabs
- * the current state of all of the ACPI buttons into the softc.
+ * the current state of all of the ACPI hotkeys into the softc.
  */
 static uint8_t
 acpi_fujitsu_init(struct acpi_fujitsu_softc *sc)
 {
 	struct acpi_softc *acpi_sc;
-	int i;
+	int i, exists;
 
 	ACPI_SERIAL_ASSERT(fujitsu);
 
@@ -333,9 +358,14 @@
 	sc->gmou.name = "GMOU";
 	sc->gsif.name = "GSIF";
 	sc->gvol.name = "GVOL";
+	sc->ghks.name = "GHKS";
+	sc->gsif.name = "GSIF";
 	sc->rbll.name = "RBLL";
 	sc->rvol.name = "RVOL";
 
+	/* Determine what hardware functionality is available */
+	acpi_fujitsu_check_hardware(sc);
+
 	/* Build the sysctl tree */
 	acpi_sc = acpi_device_get_parent_softc(sc->dev);
 	sysctl_ctx_init(&sc->sysctl_ctx);
@@ -344,6 +374,31 @@
 	    OID_AUTO, "fujitsu", CTLFLAG_RD, 0, "");
 
 	for (i = 0; sysctl_table[i].name != NULL; i++) {
+		exists = 0;
+		switch(sysctl_table[i].method) {
+			case METHOD_GMOU:
+				exists = sc->gmou.exists;
+				break;
+			case METHOD_GBLL:
+				exists = sc->gbll.exists;
+				break;
+			case METHOD_GVOL:
+			case METHOD_MUTE:
+				exists = sc->gvol.exists;
+				break;
+			case METHOD_RVOL:
+				exists = sc->rvol.exists;
+				break;
+			case METHOD_RBLL:
+				exists = sc->rbll.exists;
+				break;
+			default:
+				/* Allow by default */
+				exists = 1;
+				break;
+		}
+		if(!exists)
+			continue;
 		SYSCTL_ADD_PROC(&sc->sysctl_ctx,
 		    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
 		    sysctl_table[i].name,
@@ -352,9 +407,10 @@
 		    sysctl_table[i].description);
 	}
 
-	/* Set the buttons to their initial states */
+
+	/* Set the hotkeys to their initial states */
 	if (!acpi_fujitsu_update(sc)) {
-		device_printf(sc->dev, "Couldn't init button states\n");
+		device_printf(sc->dev, "Couldn't init hotkey states\n");
 		return (FALSE);
 	}
 
@@ -409,6 +465,18 @@
 		case METHOD_MUTE:
 			nv = sc->gvol;
 			break;
+		case METHOD_GHKS:
+			nv = sc->ghks;
+			break;
+		case METHOD_GSIF:
+			nv = sc->gsif;
+			break;
+		case METHOD_RBLL:
+			nv = sc->rbll;
+			break;
+		case METHOD_RVOL:
+			nv = sc->rvol;
+			break;
 		default:
 			return (FALSE);
 	}
@@ -479,86 +547,156 @@
 }
 
 /*
- * Query each of the ACPI control methods that contain information we're
- * interested in. We check the return values from the control methods and
- * adjust any state variables if they should be adjusted.
+ * Query the get methods to determine what functionality is available
+ * from the hardware function hotkeys.
  */
 static uint8_t
-acpi_fujitsu_update(struct acpi_fujitsu_softc *sc)
+acpi_fujitsu_check_hardware(struct acpi_fujitsu_softc *sc)
 {
+	int val;
 	struct acpi_softc *acpi_sc;
 
 	acpi_sc = acpi_device_get_parent_softc(sc->dev);
 
 	ACPI_SERIAL_ASSERT(fujitsu);
-
-	/* System Volume Level */
+	/* save the hotkey bitmask */
 	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
-	    sc->gvol.name, &(sc->gvol.value)))) {
-		device_printf(sc->dev, "Couldn't query volume level\n");
+	sc->gsif.name, &(sc->gsif.value)))) {
+		sc->gsif.exists = 0;
+		device_printf(sc->dev, "Couldn't query bitmask value\n");
 		return (FALSE);
 	}
+	sc->gsif.exists = 1;
 
-	if (sc->gvol.value & VOLUME_CHANGE_BIT) {
-		sc->bIsMuted =
-		    (uint8_t)((sc->gvol.value & VOLUME_MUTE_BIT) != 0);
-
-		/* Clear the modification bit */
-		sc->gvol.value &= VOLUME_SETTING_BITS;
-
-		if (sc->bIsMuted) {
-			acpi_UserNotify("FUJITSU", sc->handle, FN_MUTE);
-			ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now mute\n");
-		} else
-			ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now %d\n",
-			    sc->gvol.value);
-
-		acpi_UserNotify("FUJITSU", sc->handle, FN_VOLUME);
-
-		sc->lastValChanged = VOLUME_CHANGED;
+	/* System Volume Level */
+	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+	    sc->gvol.name, &val))) {
+		sc->gvol.exists = 0;
+	} else {
+		sc->gvol.exists = 1;
 	}
 
-	/* Internal mouse pointer (eraserhead) */
 	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
-	    sc->gmou.name, &(sc->gmou.value)))) {
-		device_printf(sc->dev, "Couldn't query pointer state\n");
-		return (FALSE);
+	    sc->gbll.name, &val))) {
+		sc->gbll.exists = 0;
+	} else {
+		sc->gbll.exists = 1;
 	}
 
-	if (sc->gmou.value & MOUSE_UPDATED_BIT) {
-		sc->bIntPtrEnabled = (uint8_t)(sc->gmou.value & 0x1);
-
-		/* Clear the modification bit */
-		sc->gmou.value &= MOUSE_SETTING_BITS;
-		
-		acpi_UserNotify("FUJITSU", sc->handle, FN_POINTER_ENABLE);
+	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+	    sc->ghks.name, &val))) {
+		sc->ghks.exists = 0;
+	} else {
+		sc->ghks.exists = 1;
+	}
 
-		ACPI_VPRINT(sc->dev, acpi_sc, "Internal pointer is now %s\n",
-		    (sc->bIntPtrEnabled) ? "enabled" : "disabled");
+	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+	    sc->gmou.name, &val))) {
+		sc->gmou.exists = 0;
+	} else {
+		sc->gmou.exists = 1;
+	}
 
-		sc->lastValChanged = MOUSE_CHANGED;
+	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+	    sc->rbll.name, &val))) {
+		sc->rbll.exists = 0;
+	} else {
+		sc->rbll.exists = 1;
 	}
 
-	/* Screen Brightness Level */
 	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
-	    sc->gbll.name, &(sc->gbll.value)))) {
-		device_printf(sc->dev, "Couldn't query brightness level\n");
-		return (FALSE);
+	    sc->rvol.name, &val))) {
+		sc->rvol.exists = 0;
+	} else {
+		sc->rvol.exists = 1;
 	}
 
-	if (sc->gbll.value & BRIGHTNESS_CHANGE_BIT) {
-		/* No state to record here. */
+	return (TRUE);
+}
 
-		/* Clear the modification bit */
-		sc->gbll.value &= BRIGHTNESS_SETTING_BITS;
+/*
+ * Query each of the ACPI control methods that contain information we're
+ * interested in. We check the return values from the control methods and
+ * adjust any state variables if they should be adjusted.
+ */
+static uint8_t
+acpi_fujitsu_update(struct acpi_fujitsu_softc *sc)
+{
+	int changed;
+	struct acpi_softc *acpi_sc;
 
-		acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS);
+	acpi_sc = acpi_device_get_parent_softc(sc->dev);
 
-		ACPI_VPRINT(sc->dev, acpi_sc, "Brightness level is now %d\n",
-		    sc->gbll.value);
+	ACPI_SERIAL_ASSERT(fujitsu);
+	changed = sc->gsif.value & acpi_fujitsu_method_get(sc,METHOD_GHKS);
+
+	/* System Volume Level */
+	if(sc->gvol.exists) {
+		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+		sc->gvol.name, &(sc->gvol.value)))) {
+			device_printf(sc->dev, "Couldn't query volume level\n");
+			return (FALSE);
+		}
+	
+		if (changed & VOLUME_CHANGED) {
+			sc->bIsMuted =
+			(uint8_t)((sc->gvol.value & VOLUME_MUTE_BIT) != 0);
+	
+			/* Clear the modification bit */
+			sc->gvol.value &= VOLUME_SETTING_BITS;
+	
+			if (sc->bIsMuted) {
+				acpi_UserNotify("FUJITSU", sc->handle, FN_MUTE);
+				ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now mute\n");
+			} else
+				ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now %d\n",
+				sc->gvol.value);
+	
+			acpi_UserNotify("FUJITSU", sc->handle, FN_VOLUME);
+		}
+	}
 
-		sc->lastValChanged = BRIGHT_CHANGED;
+	/* Internal mouse pointer (eraserhead) */
+	if(sc->gmou.exists) {
+		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+		sc->gmou.name, &(sc->gmou.value)))) {
+			device_printf(sc->dev, "Couldn't query pointer state\n");
+			return (FALSE);
+		}
+	
+		if (changed & MOUSE_CHANGED) {
+			sc->bIntPtrEnabled = (uint8_t)(sc->gmou.value & 0x1);
+	
+			/* Clear the modification bit */
+			sc->gmou.value &= MOUSE_SETTING_BITS;
+			
+			acpi_UserNotify("FUJITSU", sc->handle, FN_POINTER_ENABLE);
+	
+			ACPI_VPRINT(sc->dev, acpi_sc, "Internal pointer is now %s\n",
+			(sc->bIntPtrEnabled) ? "enabled" : "disabled");
+		}
 	}
 
+	/* Screen Brightness Level */
+	if(sc->gbll.exists) {
+		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
+		sc->gbll.name, &(sc->gbll.value)))) {
+			device_printf(sc->dev, "Couldn't query brightness level\n");
+			return (FALSE);
+		}
+	
+		if (changed & BRIGHT_CHANGED) {
+			/* No state to record here. */
+	
+			/* Clear the modification bit */
+			sc->gbll.value &= BRIGHTNESS_SETTING_BITS;
+	
+			acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS);
+	
+			ACPI_VPRINT(sc->dev, acpi_sc, "Brightness level is now %d\n",
+			sc->gbll.value);
+		}
+	}
+	sc->lastValChanged = changed;
 	return (TRUE);
 }

--Boundary-00=_VOH3D8QYbbI4KBz--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601290249.41648.mistry.7>