kern/128553: [patch] [acpi] add support for Asus A8Sr notebook

Eygene Ryabinkin rea-fbsd at codelabs.ru
Sun Nov 2 22:30:05 PST 2008


>Number:         128553
>Category:       kern
>Synopsis:       [patch] [acpi] add support for Asus A8Sr notebook
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 03 06:30:03 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Eygene Ryabinkin
>Release:        FreeBSD 7.1-PRERELEASE amd64
>Organization:
Code Labs
>Environment:

System: FreeBSD XXX 7.1-PRERELEASE FreeBSD 7.1-PRERELEASE #79: Sun Nov 2 23:19:14 MSK 2008 root at XXX:/usr/src/sys/amd64/compile/XXX amd64

>Description:

Module acpi_asus was not aware of the Asus A8Sr notebook.  By chance, I
have this beast in my hands, so I wrote some missing bits.

>How-To-Repeat:

Grab Asus A8Sr and try to use function keys for brightness, volume
and other stuff.

>Fix:

The following patch adds the configuration items for the A8Sr.  It also
hooks the LCDD notifications, since backlight control buttons are sending
notifications to the 'LCDD' object.

--- 0001-Add-support-for-the-Asus-A8Sr-laptop.patch begins here ---
>From c39a72ca3ef7bd7822618cb4133817d9dff21ebb Mon Sep 17 00:00:00 2001
From: Eygene Ryabinkin <rea-fbsd at codelabs.ru>
Date: Tue, 20 May 2008 11:03:03 +0400

A8Sr is a bit tricky with respect to the brightness: it sends brightness
notifications to the 'LCDD' object, not to the 'ATKD', where other
events are sent.  So, we're hooking 'LCDD' object as well with a special
notification processing routine.

All other buttons are standard and handled by the 'ATKD' object itself.

Brightness change is done via the module's sysctl interface.  For the
current implementation, it won't harm, but probably we should have the
routine to change brightness level and call it both from the sysctl call
processor and from the notification handler.

Signed-off-by: Eygene Ryabinkin <rea-fbsd at codelabs.ru>
---
 sys/dev/acpi_support/acpi_asus.c |   75 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/sys/dev/acpi_support/acpi_asus.c b/sys/dev/acpi_support/acpi_asus.c
index 50a4d5b..108047b 100644
--- a/sys/dev/acpi_support/acpi_asus.c
+++ b/sys/dev/acpi_support/acpi_asus.c
@@ -89,6 +89,9 @@ struct acpi_asus_model {
 	char	*crd_set;
 
 	void	(*n_func)(ACPI_HANDLE, UINT32, void *);
+
+	char	*lcdd;
+	void	(*lcdd_n_func)(ACPI_HANDLE, UINT32, void *);
 };
 
 struct acpi_asus_led {
@@ -109,6 +112,7 @@ struct acpi_asus_led {
 struct acpi_asus_softc {
 	device_t		dev;
 	ACPI_HANDLE		handle;
+	ACPI_HANDLE		lcdd_handle;
 
 	struct acpi_asus_model	*model;
 	struct sysctl_ctx_list	sysctl_ctx;
@@ -128,6 +132,9 @@ struct acpi_asus_softc {
 	int			s_crd;
 };
 
+static void	acpi_asus_lcdd_notify(ACPI_HANDLE h, UINT32 notify,
+    void *context);
+
 /*
  * We can identify Asus laptops from the string they return
  * as a result of calling the ATK0100 'INIT' method.
@@ -200,6 +207,20 @@ static struct acpi_asus_model acpi_asus_models[] = {
 		.disp_set	= "SDSP"
 	},
 	{
+		.name		= "A8SR",
+		.bled_set	= "BLED",
+		.mled_set	= "MLED",
+		.wled_set	= "WLED",
+		.lcd_get	= NULL,
+		.lcd_set	= "\\_SB.PCI0.SBRG.EC0._Q10",
+		.brn_get	= "GPLV",
+		.brn_set	= "SPLV",
+		.disp_get	= "\\_SB.PCI0.P0P1.VGA.GETD",
+		.disp_set	= "SDSP",
+		.lcdd		= "\\_SB.PCI0.P0P1.VGA.LCDD",
+		.lcdd_n_func	= acpi_asus_lcdd_notify
+	},
+	{
 		.name		= "D1x",
 		.mled_set	= "MLED",
 		.lcd_get	= "\\GP11",
@@ -749,6 +770,22 @@ acpi_asus_attach(device_t dev)
 	AcpiInstallNotifyHandler(sc->handle, ACPI_SYSTEM_NOTIFY,
 	    sc->model->n_func, dev);
 
+	/* Find and hook the 'LCDD' object */
+	if (sc->model->lcdd != NULL && sc->model->lcdd_n_func != NULL) {
+		ACPI_STATUS res;
+
+		sc->lcdd_handle = NULL;
+		res = AcpiGetHandle((sc->model->lcdd[0] == '\\' ?
+		    NULL : sc->handle), sc->model->lcdd, &(sc->lcdd_handle));
+		if (ACPI_SUCCESS(res)) {
+			AcpiInstallNotifyHandler((sc->lcdd_handle),
+			    ACPI_DEVICE_NOTIFY, sc->model->lcdd_n_func, dev);
+	    	} else {
+	    		printf("%s: unable to find LCD device '%s'\n",
+	    		    __func__, sc->model->lcdd);
+	    	}
+	}
+
 	return (0);
 }
 
@@ -783,6 +820,13 @@ acpi_asus_detach(device_t dev)
 	/* Remove notify handler */
 	AcpiRemoveNotifyHandler(sc->handle, ACPI_SYSTEM_NOTIFY,
 	    acpi_asus_notify);
+	
+	if (sc->lcdd_handle) {
+		KASSERT(sc->model->lcdd_n_func != NULL,
+		    ("model->lcdd_n_func is NULL, but lcdd_handle is non-zero"));
+		AcpiRemoveNotifyHandler((sc->lcdd_handle),
+		    ACPI_DEVICE_NOTIFY, sc->model->lcdd_n_func);
+	}
 
 	/* Free sysctl tree */
 	sysctl_ctx_free(&sc->sysctl_ctx);
@@ -1124,6 +1168,12 @@ acpi_asus_notify(ACPI_HANDLE h, UINT32 notify, void *context)
 	} else if (notify == 0x34) {
 		sc->s_lcd = 0;
 		ACPI_VPRINT(sc->dev, acpi_sc, "LCD turned off\n");
+	} else if (notify == 0x86) {
+		acpi_asus_sysctl_set(sc, ACPI_ASUS_METHOD_BRN, sc->s_brn-1);
+		ACPI_VPRINT(sc->dev, acpi_sc, "Brightness decreased\n");
+	} else if (notify == 0x87) {
+		acpi_asus_sysctl_set(sc, ACPI_ASUS_METHOD_BRN, sc->s_brn+1);
+		ACPI_VPRINT(sc->dev, acpi_sc, "Brightness increased\n");
 	} else {
 		/* Notify devd(8) */
 		acpi_UserNotify("ASUS", h, notify);
@@ -1132,6 +1182,31 @@ acpi_asus_notify(ACPI_HANDLE h, UINT32 notify, void *context)
 }
 
 static void
+acpi_asus_lcdd_notify(ACPI_HANDLE h, UINT32 notify, void *context)
+{
+	struct acpi_asus_softc	*sc;
+	struct acpi_softc	*acpi_sc;
+
+	ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+	sc = device_get_softc((device_t)context);
+	acpi_sc = acpi_device_get_parent_softc(sc->dev);
+
+	ACPI_SERIAL_BEGIN(asus);
+	switch (notify) {
+	case 0x87:
+		acpi_asus_sysctl_set(sc, ACPI_ASUS_METHOD_BRN, sc->s_brn-1);
+		ACPI_VPRINT(sc->dev, acpi_sc, "Brightness decreased\n");
+		break;
+	case 0x86:
+		acpi_asus_sysctl_set(sc, ACPI_ASUS_METHOD_BRN, sc->s_brn+1);
+		ACPI_VPRINT(sc->dev, acpi_sc, "Brightness increased\n");
+		break;
+	}
+	ACPI_SERIAL_END(asus);
+}
+
+static void
 acpi_asus_eeepc_notify(ACPI_HANDLE h, UINT32 notify, void *context)
 {
 	struct acpi_asus_softc	*sc;
-- 
1.6.0.3
--- 0001-Add-support-for-the-Asus-A8Sr-laptop.patch ends here ---

I had almost fully tested this patch -- things work as expected.  One
untested thing is the external DVI/VGA output function keys -- I have no
external monitor at hand.  Will try to test is as soon as I will be
close to one.

And the following patch adds devd(8) stuff to handle volume keys.
--- 0002-Devd-hook-volume-function-keys-on-Asus-laptops.patch begins here ---
>From 7c5490d4608305ddcc4906f3e2bf9b6e76e91b3b Mon Sep 17 00:00:00 2001
From: Eygene Ryabinkin <rea-fbsd at codelabs.ru>
Date: Sun, 2 Nov 2008 23:30:44 +0300
Subject: [PATCH] Devd: hook volume function keys on Asus laptops

Just now, I had added hooks for the Asus A8Sr laptop.  May be we should
create our own codes for the Asus volume control buttons and pass them
to the devd(8): if two Asus notebooks will have same notification codes
for the different events, the current scheme will fail.

Signed-off-by: Eygene Ryabinkin <rea-fbsd at codelabs.ru>
---
 etc/devd.conf |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/etc/devd.conf b/etc/devd.conf
index 83e89aa..32b2e7c 100644
--- a/etc/devd.conf
+++ b/etc/devd.conf
@@ -252,6 +252,28 @@ notify 10 {
 	action "/etc/rc.resume acpi $notify";
 };
 
+# The next blocks enable volume hotkeys that can be found on the Asus laptops
+notify 0 {
+        match "system"          "ACPI";
+        match "subsystem"       "ASUS";
+        match "notify"          "0x32";
+        action                  "mixer 0";
+};
+
+notify 0 {
+        match "system"          "ACPI";
+        match "subsystem"       "ASUS";
+        match "notify"          "0x31";
+        action                  "mixer vol -10";
+};
+
+notify 0 {
+        match "system"          "ACPI";
+        match "subsystem"       "ASUS";
+        match "notify"          "0x30";
+        action                  "mixer vol +10";
+};
+
 # The next blocks enable volume hotkeys that can be found on the Asus EeePC
 notify 0 {
         match "system"          "ACPI";
-- 
1.6.0.3
--- 0002-Devd-hook-volume-function-keys-on-Asus-laptops.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list