drivers/acpi/asus_acpi.c updates
cover drivers/acpi/asus_acpi.c updates
Hi,
The following batch of patches update the asus_acpi driver to version 0.30 through the following changes:
Readd WLED for S1N
Rework model detection for more flexibility and less oopses Resolve confusion, "bluetooth" entry controls both the internal adapter
*and* its LED
Added support for L5D
Added support for W5A (patch from Fernando A. P. Gomes) Added support for A4759GUH (A4G, patch from Giuseppe Rota) Added support for W3400N
Added support for W1N LED display (thx Éric BURGHARD)
Added support for A3000G
Please apply.
Best regards,
Signature · 6 lines
Karol 'sziwan' Kozimor [email protected] - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/9 misc cleanups
This patch updates the version string, copyright notices and does whitespace cleanup (it looks weird, blame Lindent).
drivers/acpi/asus_acpi.c +7 -20
@@ -2,7 +2,7 @@* asus_acpi.c - Asus Laptop ACPI Extras * * -* Copyright (C) 2002, 2003, 2004 Julien Lerouge, Karol Kozimor +* Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
@@ -27,10 +27,6 @@* Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. * -* TODO: -* add Fn key status -* Add mode selection on module loading (parameter) -> still necessary? -* Complete display switching -- may require dirty hacks or calling _DOS? */ #include <linux/kernel.h>
@@ -42,7 +38,7 @@#include <acpi/acpi_bus.h> #include <asm/uaccess.h> -#define ASUS_ACPI_VERSION "0.29" +#define ASUS_ACPI_VERSION "0.30"#define PROC_ASUS "asus" //the directory#define PROC_MLED "mled"
@@ -149,17 +145,8 @@static struct model_data model_conf[END_MODEL ] = {/* -* Those pathnames are relative to the HOTK / ATKD device : -* - mt_mled -* - mt_wled -* - brightness_set -* - brightness_get -* - display_set -* - display_get -* * TODO I have seen a SWBX and AIBX method on some models, like L1400B, * it seems to be a kind of switch, but what for ? -* */ {
@@ -993,7 +980,7 @@if (buffer.pointer ==NULL )return -EINVAL ; - model = (union acpi_object *) buffer.pointer; + model = (union acpi_object *)buffer.pointer;/* * Samsung P30 has a device with a valid _HID whose INIT does not * return anything. It used to be possible to catch this exception,
@@ -1002,7 +989,8 @@* identifier but it's still possible to get completely bogus data. */ if (model->type ==ACPI_TYPE_STRING ) { -printk (KERN_NOTICE " %s model detected, " , model->string.pointer); +printk (KERN_NOTICE " %s model detected, " , + model->string.pointer); }else {if (asus_info &&/* Samsung P30 */ strncmp (asus_info->oem_table_id,"ODEM" ,4 ) ==0 ) {
@@ -1016,7 +1004,7 @@ "the developers with your DSDT\n"); } hotk->methods = &model_conf[hotk->model]; - +acpi_os_free (model);return AE_OK ;
@@ -1162,8 +1150,7 @@/* For laptops without GPLV: init the hotk->brightness value */ if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) - && (hotk->methods->brightness_up - && hotk->methods->brightness_down)) { + && (hotk->methods->brightness_up && hotk->methods->brightness_down)) { status =acpi_evaluate_object (NULL , hotk->methods->brightness_down,NULL ,NULL );
PATCH 2/9 support A3G
In reply to Karol KozimorThis patch adds support for Asus A3G.
drivers/acpi/asus_acpi.c +6 -2
@@ -127,7 +127,7 @@ struct asus_hotk {M1A ,//M1300A M2E ,//M2400E, L4400L M6N ,//M6800N -M6R ,//M6700R +M6R ,//M6700R, A3000G P30 ,//Samsung P30 S1x,//S1300A, but also L1400B and M2400A (L84F) S2x, //S200 (J1 reported), Victor MP-XP7210
@@ -1038,7 +1038,8 @@ static int __init asus_hotk_get_info(voi hotk->model =L4R ; else if (strncmp(model->string.pointer, "M6N", 3) == 0) hotk->model = M6N; - else if (strncmp(model->string.pointer, "M6R", 3) == 0) + else if (strncmp(model->string.pointer, "M6R", 3) == 0 || + strncmp(model->string.pointer, "A3G", 3) == 0) hotk->model =M6R ; else if (strncmp(model->string.pointer, "M2N", 3) == 0 || strncmp(model->string.pointer, "M3N", 3) == 0 ||
@@ -1083,6 +1084,9 @@ static int __init asus_hotk_get_info(voi hotk->methods->lcd_status =NULL ;/* L2B is similar enough to L3C to use its settings, with this only exception */ + else if (strncmp(model->string.pointer, "A3G", 3) == 0) + hotk->methods->lcd_status = "\\BLFG"; +/* A3G is like M6R */ else if (strncmp(model->string.pointer, "S5N", 3) == 0 || strncmp(model->string.pointer, "M5N", 3) == 0) hotk->methods->mt_mled =NULL ;
PATCH 3/9 LED display support
In reply to Karol KozimorThis patch adds handling for front LED displays found on W1N and the like. Additionally, W1N is given its own model_data instance.
Patch originally by Éric Burghard.
drivers/acpi/asus_acpi.c +63 -6
@@ -26,6 +26,7 @@* Pontus Fuchs - Helper functions, cleanup * Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. +* Éric Burghard - LED display support for W1N * * TODO: * add Fn key status
@@ -48,6 +49,7 @@#define PROC_MLED "mled"#define PROC_WLED "wled"#define PROC_TLED "tled" +#define PROC_LEDD "ledd"#define PROC_INFO "info"#define PROC_LCD "lcd"#define PROC_BRN "brn"
@@ -92,6 +94,7 @@ struct model_data {char *wled_status;//node to handle wled reading_______A char *mt_tled;//method to handle tled_____________R char *tled_status;//node to handle tled reading_______A +char *mt_ledd;//method to handle LED display______R char *mt_lcd_switch;//method to turn LCD ON/OFF_________A char *lcd_status;//node to read LCD panel state______A char *brightness_up;//method to set brightness up_______A
@@ -111,6 +114,7 @@ struct asus_hotk {struct acpi_device *device;//the device we are in acpi_handle handle;//the handle of the hotk device char status;//status of the hotk, for LEDs, ... +u32 ledd_status;//status of the LED display struct model_data *methods;//methods available on the laptop u8 brightness;//brightness level enum {
@@ -131,7 +135,8 @@ struct asus_hotk {P30 ,//Samsung P30 S1x,//S1300A, but also L1400B and M2400A (L84F) S2x,//S200 (J1 reported), Victor MP-XP7210 - xxN,//M2400N, M3700N, M5200N, S1300N, S5200N, W1OOON +W1N ,//W1000N + xxN,//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N //(Centrino) END_MODEL } model;//Models currently supported
@@ -345,6 +350,18 @@ static struct model_data model_conf[END_ .brightness_down = S2x_PREFIX "_Q0A"}, { + .name = "W1N", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_ledd = "SLCM", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .lcd_status = "\\BKLT", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\ADVG"}, + + { .name = "xxN", .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */
@@ -563,6 +580,36 @@ proc_write_mled(struct file *file, const }/* +* Proc handlers for LED display +*/ +static int +proc_read_ledd (char *page,char **start,off_t off,int count,int *eof, +void *data) +{ +return sprintf (page,"0x%08x\n" , hotk->ledd_status); +} + +static int +proc_write_ledd (struct file *file,const char __user * buffer, +unsigned long count,void *data) +{ +int value; + + count =parse_arg (buffer, count, &value); +if (count >0 ) { +if (!write_acpi_int + (hotk->handle, hotk->methods->mt_ledd, value,NULL )) +printk (KERN_WARNING +"Asus ACPI: LED display write failed\n" ); +else + hotk->ledd_status = (u32 ) value; + }else if (count <0 ) +printk (KERN_WARNING "Asus ACPI: Error reading user input\n" ); + +return count; +} + +/* * Proc handlers for WLED */ static int
@@ -876,6 +923,11 @@ static int __init asus_hotk_add_fs(struc mode, device); } +if (hotk->methods->mt_ledd) { +asus_proc_add (PROC_LEDD , &proc_write_ledd, &proc_read_ledd, + mode, device); + } +if (hotk->methods->mt_mled) {asus_proc_add (PROC_MLED , &proc_write_mled, &proc_read_mled, mode, device);
@@ -919,6 +971,8 @@ static int asus_hotk_remove_fs(struct acremove_proc_entry (PROC_MLED ,acpi_device_dir (device));if (hotk->methods->mt_tled)remove_proc_entry (PROC_TLED ,acpi_device_dir (device)); +if (hotk->methods->mt_ledd) +remove_proc_entry (PROC_LEDD ,acpi_device_dir (device));if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status)remove_proc_entry (PROC_LCD ,acpi_device_dir (device)); if ((hotk->methods->brightness_up
@@ -1046,8 +1100,7 @@ static int __init asus_hotk_get_info(voistrncmp (model->string.pointer,"M5N" ,3 ) ==0 ||strncmp (model->string.pointer,"M6N" ,3 ) ==0 ||strncmp (model->string.pointer,"S1N" ,3 ) ==0 || -strncmp (model->string.pointer,"S5N" ,3 ) ==0 || - strncmp(model->string.pointer, "W1N", 3) == 0) + strncmp(model->string.pointer, "S5N", 3) == 0) hotk->model = xxN; else if (strncmp(model->string.pointer, "M1", 2) == 0) hotk->model = M1A;
@@ -1068,6 +1121,8 @@ static int __init asus_hotk_get_info(voi hotk->model = S2x; else if (strncmp(model->string.pointer, "L5", 2) == 0) hotk->model = L5x; + else if (strncmp(model->string.pointer, "W1N", 3) == 0) + hotk->model = W1N;if (hotk->model ==END_MODEL ) { printk("unsupported, trying default values, supply the "
@@ -1091,10 +1146,9 @@ static int __init asus_hotk_get_info(voi strncmp(model->string.pointer, "M5N", 3) == 0) hotk->methods->mt_mled = NULL;/* S5N and M5N have no MLED */ - else if (strncmp(model->string.pointer, "M2N", 3) == 0 || - strncmp(model->string.pointer, "W1N", 3) == 0) + else if (strncmp(model->string.pointer, "M2N", 3) == 0) hotk->methods->mt_wled = "WLED"; -/* M2N and W1N have a usable WLED */ +/* M2N has a usable WLED */ else if (asus_info) {if (strncmp (asus_info->oem_table_id,"L1" ,2 ) ==0 ) hotk->methods->mled_status =NULL ;
@@ -1184,6 +1238,9 @@ static int __init asus_hotk_add(struct a } } +/* LED display is off by default */ + hotk->ledd_status =0xFFF ; + end:if (result) {kfree (hotk);
-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/9 support W3400N
In reply to Karol KozimorThis patch adds support for Asus W3400N.
drivers/acpi/asus_acpi.c +6 -4
@@ -130,7 +130,7 @@ struct asus_hotk {L8L ,//L8400L M1A ,//M1300A M2E ,//M2400E, L4400L -M6N ,//M6800N +M6N ,//M6800N, W3400N M6R ,//M6700R, A3000G P30 ,//Samsung P30 S1x, //S1300A, but also L1400B and M2400A (L84F)
@@ -1090,7 +1090,8 @@ static int __init asus_hotk_get_info(voi hotk->model =L8L ; else if (strncmp(model->string.pointer, "L4R", 3) == 0) hotk->model = L4R; - else if (strncmp(model->string.pointer, "M6N", 3) == 0) + else if (strncmp(model->string.pointer, "M6N", 3) == 0 || + strncmp(model->string.pointer, "W3N", 3) == 0) hotk->model =M6N ; else if (strncmp(model->string.pointer, "M6R", 3) == 0 || strncmp(model->string.pointer, "A3G", 3) == 0)
@@ -1143,9 +1144,10 @@ static int __init asus_hotk_get_info(voi hotk->methods->lcd_status ="\\BLFG" ;/* A3G is like M6R */ else if (strncmp(model->string.pointer, "S5N", 3) == 0 || - strncmp(model->string.pointer, "M5N", 3) == 0) + strncmp(model->string.pointer, "M5N", 3) == 0 || + strncmp(model->string.pointer, "W3N", 3) == 0) hotk->methods->mt_mled =NULL ; -/* S5N and M5N have no MLED */ +/* S5N, M5N and W3N have no MLED */ else if (strncmp(model->string.pointer, "M2N", 3) == 0) hotk->methods->mt_wled = "WLED";/* M2N has a usable WLED */
PATCH 5/9 support A4G
In reply to Karol KozimorThis patch adds support for Asus A4G.
Originally by Giuseppe Rota.
drivers/acpi/asus_acpi.c +13 -0
@@ -120,6 +120,7 @@ struct asus_hotk {enum { A1x =0 ,//A1340D, A1300F A2x,//A2500H +A4G ,//A4700G D1x,//D1 L2D ,//L2000D L3C ,//L3800C
@@ -189,6 +190,16 @@ static struct model_data model_conf[END_ .display_get = "\\INFB"}, { + .name = "A4G", + .mt_mled = "MLED", +/* WLED present, but not controlled by ACPI */ + .mt_lcd_switch = xxN_PREFIX "_Q10", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\ADVG"}, + + { .name = "D1x", .mt_mled = "MLED", .mt_lcd_switch = "\\Q0D",
@@ -1122,6 +1133,8 @@ static int __init asus_hotk_get_info(voi hotk->model = S2x; else if (strncmp(model->string.pointer, "L5", 2) == 0) hotk->model = L5x; + else if (strncmp(model->string.pointer, "A4G", 3) == 0) + hotk->model = A4G; else if (strncmp(model->string.pointer, "W1N", 3) == 0) hotk->model = W1N;
PATCH 6/9 handle internal Bluetooth / support W5A
In reply to Karol KozimorThis patch creates a new file named "bluetooth" under /proc/acpi/asus/. This file controls both the internal Bluetooth adapter's presence on the USB bus and the associated LED.
echo 1 > /proc/acpi/asus/bluetooth to enable, 0 to disable.
Additionally, the patch add support for Asus W5A, the first model that uses this feature.
Patch originally by Fernando A. P. Gomes.
drivers/acpi/asus_acpi.c +47 -4
@@ -49,6 +49,7 @@#define PROC_MLED "mled"#define PROC_WLED "wled"#define PROC_TLED "tled" +#define PROC_BT "bluetooth"#define PROC_LEDD "ledd"#define PROC_INFO "info"#define PROC_LCD "lcd"
@@ -69,9 +70,10 @@/* * Flags for hotk status */ -#define MLED_ON 0x01 //is MLED ON ? -#define WLED_ON 0x02 -#define TLED_ON 0x04 +#define MLED_ON 0x01 //mail LED +#define WLED_ON 0x02 //wireless LED +#define TLED_ON 0x04 //touchpad LED +#define BT_ON 0x08 //internal BluetoothMODULE_AUTHOR ("Julien Lerouge, Karol Kozimor" );MODULE_DESCRIPTION (ACPI_HOTK_NAME );
@@ -95,7 +97,9 @@ struct model_data {char *mt_tled;//method to handle tled_____________R char *tled_status;//node to handle tled reading_______A char *mt_ledd;//method to handle LED display______R -char *mt_lcd_switch;//method to turn LCD ON/OFF_________A +char *mt_bt_switch;//method to switch Bluetooth on/off_R +char *bt_status;//no model currently supports this__? +char *mt_lcd_switch;//method to turn LCD on/off_________A char *lcd_status;//node to read LCD panel state______A char *brightness_up;//method to set brightness up_______A char *brightness_down;//guess what ?______________________A
@@ -137,6 +141,7 @@ struct asus_hotk { S1x,//S1300A, but also L1400B and M2400A (L84F) S2x,//S200 (J1 reported), Victor MP-XP7210 W1N ,//W1000N +W5A ,//W5A xxN,//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N //(Centrino) END_MODEL
@@ -373,6 +378,16 @@ static struct model_data model_conf[END_ .display_get = "\\ADVG"}, { + .name = "W5A", + .mt_bt_switch = "BLED", + .mt_wled = "WLED", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\ADVG"}, + + { .name = "xxN", .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */
@@ -639,6 +654,25 @@ proc_write_wled(struct file *file, const }/* +* Proc handlers for Bluetooth +*/ +static int +proc_read_bluetooth (char *page,char **start,off_t off,int count,int *eof, +void *data) +{ +return sprintf (page,"%d\n" ,read_led (hotk->methods->bt_status,BT_ON )); +} + +static int +proc_write_bluetooth (struct file *file,const char __user * buffer, +unsigned long count,void *data) +{ +/* Note: mt_bt_switch controls both internal Bluetooth adapter's +presence and its LED */ +return write_led (buffer, count, hotk->methods->mt_bt_switch,BT_ON ,0 ); +} + +/* * Proc handlers for TLED */ static int
@@ -949,6 +983,11 @@ static int __init asus_hotk_add_fs(struc mode, device); } +if (hotk->methods->mt_bt_switch) { +asus_proc_add (PROC_BT , &proc_write_bluetooth, + &proc_read_bluetooth, mode, device); + } +/* * We need both read node and write method as LCD switch is also accessible * from keyboard
@@ -984,6 +1023,8 @@ static int asus_hotk_remove_fs(struct acremove_proc_entry (PROC_TLED ,acpi_device_dir (device));if (hotk->methods->mt_ledd)remove_proc_entry (PROC_LEDD ,acpi_device_dir (device)); +if (hotk->methods->mt_bt_switch) +remove_proc_entry (PROC_BT ,acpi_device_dir (device));if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status)remove_proc_entry (PROC_LCD ,acpi_device_dir (device)); if ((hotk->methods->brightness_up
@@ -1137,6 +1178,8 @@ static int __init asus_hotk_get_info(voi hotk->model =A4G ; else if (strncmp(model->string.pointer, "W1N", 3) == 0) hotk->model = W1N; + else if (strncmp(model->string.pointer, "W5A", 3) == 0) + hotk->model = W5A;if (hotk->model ==END_MODEL ) { printk("unsupported, trying default values, supply the "
PATCH 7/9 support L5D
In reply to Karol KozimorThis patch adds support for Asus L5D and thus fixes
http://bugme.osdl.org/show_bug.cgi?id=4695
drivers/acpi/asus_acpi.c +7 -3
@@ -129,7 +129,7 @@ struct asus_hotk {L2D ,//L2000D L3C ,//L3800C L3D ,//L3400D -L3H ,//L3H, but also L2000E +L3H ,//L3H, L2000E, L5D L4R ,//L4500R L5x,//L5800C L8L, //L8400L
@@ -1123,8 +1123,9 @@ static int __init asus_hotk_get_info(voi hotk->model =END_MODEL ;if (strncmp (model->string.pointer,"L3D" ,3 ) ==0 ) hotk->model =L3D ; -else if (strncmp (model->string.pointer,"L3H" ,3 ) ==0 || -strncmp (model->string.pointer,"L2E" ,3 ) ==0 ) +else if (strncmp (model->string.pointer,"L2E" ,3 ) ==0 || +strncmp (model->string.pointer,"L3H" ,3 ) ==0 || +strncmp (model->string.pointer,"L5D" ,3 ) ==0 ) hotk->model =L3H ;else if (strncmp (model->string.pointer,"L3" ,2 ) ==0 ||strncmp (model->string.pointer,"L2B" ,3 ) ==0 )
@@ -1195,6 +1196,9 @@ static int __init asus_hotk_get_info(voi strncmp(model->string.pointer, "W3N", 3) == 0) hotk->methods->mt_mled = NULL;/* S5N, M5N and W3N have no MLED */ + else if (strncmp(model->string.pointer, "L5D", 3) == 0) + hotk->methods->mt_wled = NULL; +/* L5D's WLED is not controlled by ACPI */ else if (strncmp(model->string.pointer, "M2N", 3) == 0) hotk->methods->mt_wled = "WLED";/* M2N has a usable WLED */
PATCH 8/9 rework model detection
In reply to Karol KozimorThis patch reworks laptop model detection.
This addresses the Samsung P30 issue, where the INIT method would return no object, but the implicit return in the AML interpreter would confuse the driver. It also accounts for a newer batch of Asus models whose INIT returns ACPI_TYPE_BUFFER instead of STRING.
The handling is now much leaner, if we get a buffer or a string, we check against known values, in every other case we use a different path (currently DSDT signatures). The bulk of this patch is separating the string matching from asus_hotk_get_info() into a separate function.
This patch properly fixes http://bugme.osdl.org/show_bug.cgi?id=5067 and
http://bugme.osdl.org/show_bug.cgi?id=5092 and makes the driver fully functional again with acpi=strict on all machines.
drivers/acpi/asus_acpi.c +93 -90
@@ -1048,6 +1048,65 @@ static void asus_hotk_notify(acpi_handle }/* +* Match the model string to the list of supported models. Return END_MODEL if +* no match or model is NULL. +*/ +static int __init asus_model_match (char *model) +{ +if (model ==NULL ) +return END_MODEL ; + +if (strncmp (model,"L3D" ,3 ) ==0 ) +return L3D ; +else if (strncmp (model,"L2E" ,3 ) ==0 || +strncmp (model,"L3H" ,3 ) ==0 ||strncmp (model,"L5D" ,3 ) ==0 ) +return L3H ; +else if (strncmp (model,"L3" ,2 ) ==0 ||strncmp (model,"L2B" ,3 ) ==0 ) +return L3C ; +else if (strncmp (model,"L8L" ,3 ) ==0 ) +return L8L ; +else if (strncmp (model,"L4R" ,3 ) ==0 ) +return L4R ; +else if (strncmp (model,"M6N" ,3 ) ==0 ||strncmp (model,"W3N" ,3 ) ==0 ) +return M6N ; +else if (strncmp (model,"M6R" ,3 ) ==0 ||strncmp (model,"A3G" ,3 ) ==0 ) +return M6R ; +else if (strncmp (model,"M2N" ,3 ) ==0 || +strncmp (model,"M3N" ,3 ) ==0 || +strncmp (model,"M5N" ,3 ) ==0 || +strncmp (model,"M6N" ,3 ) ==0 || +strncmp (model,"S1N" ,3 ) ==0 || +strncmp (model,"S5N" ,3 ) ==0 ||strncmp (model,"W1N" ,3 ) ==0 ) +return xxN; +else if (strncmp (model,"M1" ,2 ) ==0 ) +return M1A ; +else if (strncmp (model,"M2" ,2 ) ==0 ||strncmp (model,"L4E" ,3 ) ==0 ) +return M2E ; +else if (strncmp (model,"L2" ,2 ) ==0 ) +return L2D ; +else if (strncmp (model,"L8" ,2 ) ==0 ) +return S1x; +else if (strncmp (model,"D1" ,2 ) ==0 ) +return D1x; +else if (strncmp (model,"A1" ,2 ) ==0 ) +return A1x; +else if (strncmp (model,"A2" ,2 ) ==0 ) +return A2x; +else if (strncmp (model,"J1" ,2 ) ==0 ) +return S2x; +else if (strncmp (model,"L5" ,2 ) ==0 ) +return L5x; +else if (strncmp (model,"A4G" ,3 ) ==0 ) +return A4G ; +else if (strncmp (model,"W1N" ,3 ) ==0 ) +return W1N ; +else if (strncmp (model,"W5A" ,3 ) ==0 ) +return W5A ; +else +return END_MODEL ; +} + +/* * This function is used to initialize the hotk with right values. In this * method, we can make all the detection we want, and modify the hotk struct */
@@ -1057,6 +1116,7 @@ static int __init asus_hotk_get_info(voistruct acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER ,NULL };union acpi_object *model =NULL ;int bsts_result; +char *string =NULL ;acpi_status status;/*
@@ -1086,120 +1146,63 @@ static int __init asus_hotk_get_info(voiprintk (KERN_NOTICE " BSTS called, 0x%02x returned\n" , bsts_result); -/* This is unlikely with implicit return */ -if (buffer.pointer ==NULL ) -return -EINVAL ; - - model = (union acpi_object *)buffer.pointer;/* -* Samsung P30 has a device with a valid _HID whose INIT does not -* return anything. It used to be possible to catch this exception, -* but the implicit return code will now happily confuse the -* driver. We assume that every ACPI_TYPE_STRING is a valid model -* identifier but it's still possible to get completely bogus data. +* Try to match the object returned by INIT to the specific model. +* Handle every possible object (or the lack of thereof) the DSDT +* writers might throw at us. When in trouble, we pass NULL to +* asus_model_match() and try something completely different. */ -if (model->type ==ACPI_TYPE_STRING ) { -printk (KERN_NOTICE " %s model detected, " , - model->string.pointer); - }else { -if (asus_info &&/* Samsung P30 */ +if (buffer.pointer) { + model = (union acpi_object *)buffer.pointer; +switch (model->type) { +case ACPI_TYPE_STRING : + string = model->string.pointer; +break ; +case ACPI_TYPE_BUFFER : + string = model->buffer.pointer; +break ; +default : +acpi_os_free (model); +break ; + } + } + hotk->model =asus_model_match (string); +if (hotk->model ==END_MODEL ) {/* match failed */ +if (asus_info &&strncmp (asus_info->oem_table_id,"ODEM" ,4 ) ==0 ) { hotk->model =P30 ;printk (KERN_NOTICE " Samsung P30 detected, supported\n" ); }else { hotk->model =M2E ; -printk (KERN_WARNING " no string returned by INIT\n" ); -printk (KERN_WARNING " trying default values, supply " -"the developers with your DSDT\n" ); +printk (KERN_NOTICE " unsupported model %s, trying " +"default values\n" , string); +printk (KERN_NOTICE +" send /proc/acpi/dsdt to the developers\n" ); } hotk->methods = &model_conf[hotk->model]; - -acpi_os_free (model); -return AE_OK ; } - - hotk->model =END_MODEL ; -if (strncmp (model->string.pointer,"L3D" ,3 ) ==0 ) - hotk->model =L3D ; -else if (strncmp (model->string.pointer,"L2E" ,3 ) ==0 || -strncmp (model->string.pointer,"L3H" ,3 ) ==0 || -strncmp (model->string.pointer,"L5D" ,3 ) ==0 ) - hotk->model =L3H ; -else if (strncmp (model->string.pointer,"L3" ,2 ) ==0 || -strncmp (model->string.pointer,"L2B" ,3 ) ==0 ) - hotk->model =L3C ; -else if (strncmp (model->string.pointer,"L8L" ,3 ) ==0 ) - hotk->model =L8L ; -else if (strncmp (model->string.pointer,"L4R" ,3 ) ==0 ) - hotk->model =L4R ; -else if (strncmp (model->string.pointer,"M6N" ,3 ) ==0 || -strncmp (model->string.pointer,"W3N" ,3 ) ==0 ) - hotk->model =M6N ; -else if (strncmp (model->string.pointer,"M6R" ,3 ) ==0 || -strncmp (model->string.pointer,"A3G" ,3 ) ==0 ) - hotk->model =M6R ; -else if (strncmp (model->string.pointer,"M2N" ,3 ) ==0 || -strncmp (model->string.pointer,"M3N" ,3 ) ==0 || -strncmp (model->string.pointer,"M5N" ,3 ) ==0 || -strncmp (model->string.pointer,"M6N" ,3 ) ==0 || -strncmp (model->string.pointer,"S1N" ,3 ) ==0 || -strncmp (model->string.pointer,"S5N" ,3 ) ==0 ) - hotk->model = xxN; -else if (strncmp (model->string.pointer,"M1" ,2 ) ==0 ) - hotk->model =M1A ; -else if (strncmp (model->string.pointer,"M2" ,2 ) ==0 || -strncmp (model->string.pointer,"L4E" ,3 ) ==0 ) - hotk->model =M2E ; -else if (strncmp (model->string.pointer,"L2" ,2 ) ==0 ) - hotk->model =L2D ; -else if (strncmp (model->string.pointer,"L8" ,2 ) ==0 ) - hotk->model = S1x; -else if (strncmp (model->string.pointer,"D1" ,2 ) ==0 ) - hotk->model = D1x; -else if (strncmp (model->string.pointer,"A1" ,2 ) ==0 ) - hotk->model = A1x; -else if (strncmp (model->string.pointer,"A2" ,2 ) ==0 ) - hotk->model = A2x; -else if (strncmp (model->string.pointer,"J1" ,2 ) ==0 ) - hotk->model = S2x; -else if (strncmp (model->string.pointer,"L5" ,2 ) ==0 ) - hotk->model = L5x; -else if (strncmp (model->string.pointer,"A4G" ,3 ) ==0 ) - hotk->model =A4G ; -else if (strncmp (model->string.pointer,"W1N" ,3 ) ==0 ) - hotk->model =W1N ; -else if (strncmp (model->string.pointer,"W5A" ,3 ) ==0 ) - hotk->model =W5A ; - -if (hotk->model ==END_MODEL ) { -printk ("unsupported, trying default values, supply the " -"developers with your DSDT\n" ); - hotk->model =M2E ; - }else { -printk ("supported\n" ); - } - hotk->methods = &model_conf[hotk->model]; +printk (KERN_NOTICE " %s model detected, supported\n" , string);/* Sort of per-model blacklist */ -if (strncmp (model->string.pointer,"L2B" ,3 ) ==0 ) +if (strncmp (string,"L2B" ,3 ) ==0 ) hotk->methods->lcd_status =NULL ;/* L2B is similar enough to L3C to use its settings, with this only exception */ -else if (strncmp (model->string.pointer,"A3G" ,3 ) ==0 ) +else if (strncmp (string,"A3G" ,3 ) ==0 ) hotk->methods->lcd_status ="\\BLFG" ;/* A3G is like M6R */ -else if (strncmp (model->string.pointer,"S5N" ,3 ) ==0 || -strncmp (model->string.pointer,"M5N" ,3 ) ==0 || -strncmp (model->string.pointer,"W3N" ,3 ) ==0 ) +else if (strncmp (string,"S5N" ,3 ) ==0 || +strncmp (string,"M5N" ,3 ) ==0 || +strncmp (string,"W3N" ,3 ) ==0 ) hotk->methods->mt_mled =NULL ;/* S5N, M5N and W3N have no MLED */ -else if (strncmp (model->string.pointer,"L5D" ,3 ) ==0 ) +else if (strncmp (string,"L5D" ,3 ) ==0 ) hotk->methods->mt_wled =NULL ;/* L5D's WLED is not controlled by ACPI */ -else if (strncmp (model->string.pointer,"M2N" ,3 ) ==0 ) +else if (strncmp (string,"M2N" ,3 ) ==0 ) hotk->methods->mt_wled ="WLED" ;/* M2N has a usable WLED */ else if (asus_info) {
PATCH 9/9 add S1N WLED control
In reply to Karol KozimorThis small patch adds back WLED control for S1N models, this was accidentally removed a while ago.
drivers/acpi/asus_acpi.c +3 -2
@@ -1202,9 +1202,10 @@ static int __init asus_hotk_get_info(voielse if (strncmp (string,"L5D" ,3 ) ==0 ) hotk->methods->mt_wled =NULL ;/* L5D's WLED is not controlled by ACPI */ -else if (strncmp (string,"M2N" ,3 ) ==0 ) +else if (strncmp (string,"M2N" ,3 ) ==0 || +strncmp (string,"S1N" ,3 ) ==0 ) hotk->methods->mt_wled ="WLED" ; -/* M2N has a usable WLED */ +/* M2N and S1N have a usable WLED */ else if (asus_info) {if (strncmp (asus_info->oem_table_id,"L1" ,2 ) ==0 ) hotk->methods->mled_status =NULL ;
cover drivers/acpi/asus_acpi.c updates [RESEND]
Hi,
The following batch of patches update the asus_acpi driver to version 0.30 through the following changes:
Readd WLED for S1N
Rework model detection for more flexibility and less oopses Resolve confusion, "bluetooth" entry controls both the internal adapter
*and* its LED
Added support for L5D
Added support for W5A (patch from Fernando A. P. Gomes) Added support for A4759GUH (A4G, patch from Giuseppe Rota) Added support for W3400N
Added support for W1N LED display (thx Éric BURGHARD)
Added support for A3000G
Fix M6R/M6N mismerge
Please apply.
Best regards,
Signature · 6 lines
Karol 'sziwan' Kozimor [email protected] - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/10 misc cleanups
This patch updates the version string, copyright notices and does whitespace cleanup (it looks weird, blame Lindent).
drivers/acpi/asus_acpi.c +7 -20
@@ -2,7 +2,7 @@* asus_acpi.c - Asus Laptop ACPI Extras * * -* Copyright (C) 2002, 2003, 2004 Julien Lerouge, Karol Kozimor +* Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
@@ -27,10 +27,6 @@* Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. * -* TODO: -* add Fn key status -* Add mode selection on module loading (parameter) -> still necessary? -* Complete display switching -- may require dirty hacks or calling _DOS? */ #include <linux/kernel.h>
@@ -42,7 +38,7 @@#include <acpi/acpi_bus.h> #include <asm/uaccess.h> -#define ASUS_ACPI_VERSION "0.29" +#define ASUS_ACPI_VERSION "0.30"#define PROC_ASUS "asus" //the directory#define PROC_MLED "mled"
@@ -149,17 +145,8 @@static struct model_data model_conf[END_MODEL ] = {/* -* Those pathnames are relative to the HOTK / ATKD device : -* - mt_mled -* - mt_wled -* - brightness_set -* - brightness_get -* - display_set -* - display_get -* * TODO I have seen a SWBX and AIBX method on some models, like L1400B, * it seems to be a kind of switch, but what for ? -* */ {
@@ -993,7 +980,7 @@if (buffer.pointer ==NULL )return -EINVAL ; - model = (union acpi_object *) buffer.pointer; + model = (union acpi_object *)buffer.pointer;/* * Samsung P30 has a device with a valid _HID whose INIT does not * return anything. It used to be possible to catch this exception,
@@ -1002,7 +989,8 @@* identifier but it's still possible to get completely bogus data. */ if (model->type ==ACPI_TYPE_STRING ) { -printk (KERN_NOTICE " %s model detected, " , model->string.pointer); +printk (KERN_NOTICE " %s model detected, " , + model->string.pointer); }else {if (asus_info &&/* Samsung P30 */ strncmp (asus_info->oem_table_id,"ODEM" ,4 ) ==0 ) {
@@ -1016,7 +1004,7 @@ "the developers with your DSDT\n"); } hotk->methods = &model_conf[hotk->model]; - +kfree (model);return AE_OK ;
@@ -1162,8 +1150,7 @@/* For laptops without GPLV: init the hotk->brightness value */ if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) - && (hotk->methods->brightness_up - && hotk->methods->brightness_down)) { + && (hotk->methods->brightness_up && hotk->methods->brightness_down)) { status =acpi_evaluate_object (NULL , hotk->methods->brightness_down,NULL ,NULL );
PATCH 2/10 support A3G
In reply to Karol KozimorThis patch adds support for Asus A3G.
drivers/acpi/asus_acpi.c +6 -2
@@ -127,7 +127,7 @@ struct asus_hotk {M1A ,//M1300A M2E ,//M2400E, L4400L M6N ,//M6800N -M6R ,//M6700R +M6R ,//M6700R, A3000G P30 ,//Samsung P30 S1x,//S1300A, but also L1400B and M2400A (L84F) S2x, //S200 (J1 reported), Victor MP-XP7210
@@ -1038,7 +1038,8 @@ static int __init asus_hotk_get_info(voi hotk->model =L4R ; else if (strncmp(model->string.pointer, "M6N", 3) == 0) hotk->model = M6N; - else if (strncmp(model->string.pointer, "M6R", 3) == 0) + else if (strncmp(model->string.pointer, "M6R", 3) == 0 || + strncmp(model->string.pointer, "A3G", 3) == 0) hotk->model =M6R ; else if (strncmp(model->string.pointer, "M2N", 3) == 0 || strncmp(model->string.pointer, "M3N", 3) == 0 ||
@@ -1083,6 +1084,9 @@ static int __init asus_hotk_get_info(voi hotk->methods->lcd_status =NULL ;/* L2B is similar enough to L3C to use its settings, with this only exception */ + else if (strncmp(model->string.pointer, "A3G", 3) == 0) + hotk->methods->lcd_status = "\\BLFG"; +/* A3G is like M6R */ else if (strncmp(model->string.pointer, "S5N", 3) == 0 || strncmp(model->string.pointer, "M5N", 3) == 0) hotk->methods->mt_mled =NULL ;
PATCH 3/10 LED display support
In reply to Karol KozimorThis patch adds handling for front LED displays found on W1N and the like. Additionally, W1N is given its own model_data instance.
Patch originally by Éric Burghard.
drivers/acpi/asus_acpi.c +63 -6
@@ -26,6 +26,7 @@* Pontus Fuchs - Helper functions, cleanup * Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. +* Éric Burghard - LED display support for W1N * * TODO: * add Fn key status
@@ -48,6 +49,7 @@#define PROC_MLED "mled"#define PROC_WLED "wled"#define PROC_TLED "tled" +#define PROC_LEDD "ledd"#define PROC_INFO "info"#define PROC_LCD "lcd"#define PROC_BRN "brn"
@@ -92,6 +94,7 @@ struct model_data {char *wled_status;//node to handle wled reading_______A char *mt_tled;//method to handle tled_____________R char *tled_status;//node to handle tled reading_______A +char *mt_ledd;//method to handle LED display______R char *mt_lcd_switch;//method to turn LCD ON/OFF_________A char *lcd_status;//node to read LCD panel state______A char *brightness_up;//method to set brightness up_______A
@@ -111,6 +114,7 @@ struct asus_hotk {struct acpi_device *device;//the device we are in acpi_handle handle;//the handle of the hotk device char status;//status of the hotk, for LEDs, ... +u32 ledd_status;//status of the LED display struct model_data *methods;//methods available on the laptop u8 brightness;//brightness level enum {
@@ -131,7 +135,8 @@ struct asus_hotk {P30 ,//Samsung P30 S1x,//S1300A, but also L1400B and M2400A (L84F) S2x,//S200 (J1 reported), Victor MP-XP7210 - xxN,//M2400N, M3700N, M5200N, S1300N, S5200N, W1OOON +W1N ,//W1000N + xxN,//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N //(Centrino) END_MODEL } model;//Models currently supported
@@ -345,6 +350,18 @@ static struct model_data model_conf[END_ .brightness_down = S2x_PREFIX "_Q0A"}, { + .name = "W1N", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_ledd = "SLCM", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .lcd_status = "\\BKLT", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\ADVG"}, + + { .name = "xxN", .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */
@@ -563,6 +580,36 @@ proc_write_mled(struct file *file, const }/* +* Proc handlers for LED display +*/ +static int +proc_read_ledd (char *page,char **start,off_t off,int count,int *eof, +void *data) +{ +return sprintf (page,"0x%08x\n" , hotk->ledd_status); +} + +static int +proc_write_ledd (struct file *file,const char __user * buffer, +unsigned long count,void *data) +{ +int value; + + count =parse_arg (buffer, count, &value); +if (count >0 ) { +if (!write_acpi_int + (hotk->handle, hotk->methods->mt_ledd, value,NULL )) +printk (KERN_WARNING +"Asus ACPI: LED display write failed\n" ); +else + hotk->ledd_status = (u32 ) value; + }else if (count <0 ) +printk (KERN_WARNING "Asus ACPI: Error reading user input\n" ); + +return count; +} + +/* * Proc handlers for WLED */ static int
@@ -876,6 +923,11 @@ static int __init asus_hotk_add_fs(struc mode, device); } +if (hotk->methods->mt_ledd) { +asus_proc_add (PROC_LEDD , &proc_write_ledd, &proc_read_ledd, + mode, device); + } +if (hotk->methods->mt_mled) {asus_proc_add (PROC_MLED , &proc_write_mled, &proc_read_mled, mode, device);
@@ -919,6 +971,8 @@ static int asus_hotk_remove_fs(struct acremove_proc_entry (PROC_MLED ,acpi_device_dir (device));if (hotk->methods->mt_tled)remove_proc_entry (PROC_TLED ,acpi_device_dir (device)); +if (hotk->methods->mt_ledd) +remove_proc_entry (PROC_LEDD ,acpi_device_dir (device));if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status)remove_proc_entry (PROC_LCD ,acpi_device_dir (device)); if ((hotk->methods->brightness_up
@@ -1046,8 +1100,7 @@ static int __init asus_hotk_get_info(voistrncmp (model->string.pointer,"M5N" ,3 ) ==0 ||strncmp (model->string.pointer,"M6N" ,3 ) ==0 ||strncmp (model->string.pointer,"S1N" ,3 ) ==0 || -strncmp (model->string.pointer,"S5N" ,3 ) ==0 || - strncmp(model->string.pointer, "W1N", 3) == 0) + strncmp(model->string.pointer, "S5N", 3) == 0) hotk->model = xxN; else if (strncmp(model->string.pointer, "M1", 2) == 0) hotk->model = M1A;
@@ -1068,6 +1121,8 @@ static int __init asus_hotk_get_info(voi hotk->model = S2x; else if (strncmp(model->string.pointer, "L5", 2) == 0) hotk->model = L5x; + else if (strncmp(model->string.pointer, "W1N", 3) == 0) + hotk->model = W1N;if (hotk->model ==END_MODEL ) { printk("unsupported, trying default values, supply the "
@@ -1091,10 +1146,9 @@ static int __init asus_hotk_get_info(voi strncmp(model->string.pointer, "M5N", 3) == 0) hotk->methods->mt_mled = NULL;/* S5N and M5N have no MLED */ - else if (strncmp(model->string.pointer, "M2N", 3) == 0 || - strncmp(model->string.pointer, "W1N", 3) == 0) + else if (strncmp(model->string.pointer, "M2N", 3) == 0) hotk->methods->mt_wled = "WLED"; -/* M2N and W1N have a usable WLED */ +/* M2N has a usable WLED */ else if (asus_info) {if (strncmp (asus_info->oem_table_id,"L1" ,2 ) ==0 ) hotk->methods->mled_status =NULL ;
@@ -1184,6 +1238,9 @@ static int __init asus_hotk_add(struct a } } +/* LED display is off by default */ + hotk->ledd_status =0xFFF ; + end:if (result) {kfree (hotk);
-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/10 support W3400N
In reply to Karol KozimorThis patch adds support for Asus W3400N.
drivers/acpi/asus_acpi.c +6 -4
@@ -130,7 +130,7 @@ struct asus_hotk {L8L ,//L8400L M1A ,//M1300A M2E ,//M2400E, L4400L -M6N ,//M6800N +M6N ,//M6800N, W3400N M6R ,//M6700R, A3000G P30 ,//Samsung P30 S1x, //S1300A, but also L1400B and M2400A (L84F)
@@ -1090,7 +1090,8 @@ static int __init asus_hotk_get_info(voi hotk->model =L8L ; else if (strncmp(model->string.pointer, "L4R", 3) == 0) hotk->model = L4R; - else if (strncmp(model->string.pointer, "M6N", 3) == 0) + else if (strncmp(model->string.pointer, "M6N", 3) == 0 || + strncmp(model->string.pointer, "W3N", 3) == 0) hotk->model =M6N ; else if (strncmp(model->string.pointer, "M6R", 3) == 0 || strncmp(model->string.pointer, "A3G", 3) == 0)
@@ -1143,9 +1144,10 @@ static int __init asus_hotk_get_info(voi hotk->methods->lcd_status ="\\BLFG" ;/* A3G is like M6R */ else if (strncmp(model->string.pointer, "S5N", 3) == 0 || - strncmp(model->string.pointer, "M5N", 3) == 0) + strncmp(model->string.pointer, "M5N", 3) == 0 || + strncmp(model->string.pointer, "W3N", 3) == 0) hotk->methods->mt_mled =NULL ; -/* S5N and M5N have no MLED */ +/* S5N, M5N and W3N have no MLED */ else if (strncmp(model->string.pointer, "M2N", 3) == 0) hotk->methods->mt_wled = "WLED";/* M2N has a usable WLED */
PATCH 5/10 support A4G
In reply to Karol KozimorThis patch adds support for Asus A4G.
Originally by Giuseppe Rota.
drivers/acpi/asus_acpi.c +13 -0
@@ -120,6 +120,7 @@ struct asus_hotk {enum { A1x =0 ,//A1340D, A1300F A2x,//A2500H +A4G ,//A4700G D1x,//D1 L2D ,//L2000D L3C ,//L3800C
@@ -189,6 +190,16 @@ static struct model_data model_conf[END_ .display_get = "\\INFB"}, { + .name = "A4G", + .mt_mled = "MLED", +/* WLED present, but not controlled by ACPI */ + .mt_lcd_switch = xxN_PREFIX "_Q10", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\ADVG"}, + + { .name = "D1x", .mt_mled = "MLED", .mt_lcd_switch = "\\Q0D",
@@ -1122,6 +1133,8 @@ static int __init asus_hotk_get_info(voi hotk->model = S2x; else if (strncmp(model->string.pointer, "L5", 2) == 0) hotk->model = L5x; + else if (strncmp(model->string.pointer, "A4G", 3) == 0) + hotk->model = A4G; else if (strncmp(model->string.pointer, "W1N", 3) == 0) hotk->model = W1N;
PATCH 6/10 handle internal Bluetooth / support W5A
In reply to Karol KozimorThis patch creates a new file named "bluetooth" under /proc/acpi/asus/. This file controls both the internal Bluetooth adapter's presence on the USB bus and the associated LED.
echo 1 > /proc/acpi/asus/bluetooth to enable, 0 to disable.
Additionally, the patch add support for Asus W5A, the first model that uses this feature.
Patch originally by Fernando A. P. Gomes.
drivers/acpi/asus_acpi.c +47 -4
@@ -49,6 +49,7 @@#define PROC_MLED "mled"#define PROC_WLED "wled"#define PROC_TLED "tled" +#define PROC_BT "bluetooth"#define PROC_LEDD "ledd"#define PROC_INFO "info"#define PROC_LCD "lcd"
@@ -69,9 +70,10 @@/* * Flags for hotk status */ -#define MLED_ON 0x01 //is MLED ON ? -#define WLED_ON 0x02 -#define TLED_ON 0x04 +#define MLED_ON 0x01 //mail LED +#define WLED_ON 0x02 //wireless LED +#define TLED_ON 0x04 //touchpad LED +#define BT_ON 0x08 //internal BluetoothMODULE_AUTHOR ("Julien Lerouge, Karol Kozimor" );MODULE_DESCRIPTION (ACPI_HOTK_NAME );
@@ -95,7 +97,9 @@ struct model_data {char *mt_tled;//method to handle tled_____________R char *tled_status;//node to handle tled reading_______A char *mt_ledd;//method to handle LED display______R -char *mt_lcd_switch;//method to turn LCD ON/OFF_________A +char *mt_bt_switch;//method to switch Bluetooth on/off_R +char *bt_status;//no model currently supports this__? +char *mt_lcd_switch;//method to turn LCD on/off_________A char *lcd_status;//node to read LCD panel state______A char *brightness_up;//method to set brightness up_______A char *brightness_down;//guess what ?______________________A
@@ -137,6 +141,7 @@ struct asus_hotk { S1x,//S1300A, but also L1400B and M2400A (L84F) S2x,//S200 (J1 reported), Victor MP-XP7210 W1N ,//W1000N +W5A ,//W5A xxN,//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N //(Centrino) END_MODEL
@@ -373,6 +378,16 @@ static struct model_data model_conf[END_ .display_get = "\\ADVG"}, { + .name = "W5A", + .mt_bt_switch = "BLED", + .mt_wled = "WLED", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\ADVG"}, + + { .name = "xxN", .mt_mled = "MLED",/* WLED present, but not controlled by ACPI */
@@ -639,6 +654,25 @@ proc_write_wled(struct file *file, const }/* +* Proc handlers for Bluetooth +*/ +static int +proc_read_bluetooth (char *page,char **start,off_t off,int count,int *eof, +void *data) +{ +return sprintf (page,"%d\n" ,read_led (hotk->methods->bt_status,BT_ON )); +} + +static int +proc_write_bluetooth (struct file *file,const char __user * buffer, +unsigned long count,void *data) +{ +/* Note: mt_bt_switch controls both internal Bluetooth adapter's +presence and its LED */ +return write_led (buffer, count, hotk->methods->mt_bt_switch,BT_ON ,0 ); +} + +/* * Proc handlers for TLED */ static int
@@ -949,6 +983,11 @@ static int __init asus_hotk_add_fs(struc mode, device); } +if (hotk->methods->mt_bt_switch) { +asus_proc_add (PROC_BT , &proc_write_bluetooth, + &proc_read_bluetooth, mode, device); + } +/* * We need both read node and write method as LCD switch is also accessible * from keyboard
@@ -984,6 +1023,8 @@ static int asus_hotk_remove_fs(struct acremove_proc_entry (PROC_TLED ,acpi_device_dir (device));if (hotk->methods->mt_ledd)remove_proc_entry (PROC_LEDD ,acpi_device_dir (device)); +if (hotk->methods->mt_bt_switch) +remove_proc_entry (PROC_BT ,acpi_device_dir (device));if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status)remove_proc_entry (PROC_LCD ,acpi_device_dir (device)); if ((hotk->methods->brightness_up
@@ -1137,6 +1178,8 @@ static int __init asus_hotk_get_info(voi hotk->model =A4G ; else if (strncmp(model->string.pointer, "W1N", 3) == 0) hotk->model = W1N; + else if (strncmp(model->string.pointer, "W5A", 3) == 0) + hotk->model = W5A;if (hotk->model ==END_MODEL ) { printk("unsupported, trying default values, supply the "
PATCH 7/10 support L5D
In reply to Karol KozimorThis patch adds support for Asus L5D and thus fixes
http://bugme.osdl.org/show_bug.cgi?id=4695
drivers/acpi/asus_acpi.c +7 -3
@@ -129,7 +129,7 @@ struct asus_hotk {L2D ,//L2000D L3C ,//L3800C L3D ,//L3400D -L3H ,//L3H, but also L2000E +L3H ,//L3H, L2000E, L5D L4R ,//L4500R L5x,//L5800C L8L, //L8400L
@@ -1123,8 +1123,9 @@ static int __init asus_hotk_get_info(voi hotk->model =END_MODEL ;if (strncmp (model->string.pointer,"L3D" ,3 ) ==0 ) hotk->model =L3D ; -else if (strncmp (model->string.pointer,"L3H" ,3 ) ==0 || -strncmp (model->string.pointer,"L2E" ,3 ) ==0 ) +else if (strncmp (model->string.pointer,"L2E" ,3 ) ==0 || +strncmp (model->string.pointer,"L3H" ,3 ) ==0 || +strncmp (model->string.pointer,"L5D" ,3 ) ==0 ) hotk->model =L3H ;else if (strncmp (model->string.pointer,"L3" ,2 ) ==0 ||strncmp (model->string.pointer,"L2B" ,3 ) ==0 )
@@ -1195,6 +1196,9 @@ static int __init asus_hotk_get_info(voi strncmp(model->string.pointer, "W3N", 3) == 0) hotk->methods->mt_mled = NULL;/* S5N, M5N and W3N have no MLED */ + else if (strncmp(model->string.pointer, "L5D", 3) == 0) + hotk->methods->mt_wled = NULL; +/* L5D's WLED is not controlled by ACPI */ else if (strncmp(model->string.pointer, "M2N", 3) == 0) hotk->methods->mt_wled = "WLED";/* M2N has a usable WLED */
PATCH 8/10 rework model detection
In reply to Karol KozimorThis patch reworks laptop model detection.
This addresses the Samsung P30 issue, where the INIT method would return no object, but the implicit return in the AML interpreter would confuse the driver. It also accounts for a newer batch of Asus models whose INIT returns ACPI_TYPE_BUFFER instead of STRING.
The handling is now much leaner, if we get a buffer or a string, we check against known values, in every other case we use a different path (currently DSDT signatures). The bulk of this patch is separating the string matching from asus_hotk_get_info() into a separate function.
This patch properly fixes http://bugme.osdl.org/show_bug.cgi?id=5067 and
http://bugme.osdl.org/show_bug.cgi?id=5092 and makes the driver fully functional again with acpi=strict on all machines.
drivers/acpi/asus_acpi.c +93 -90
@@ -1048,6 +1048,65 @@ static void asus_hotk_notify(acpi_handle }/* +* Match the model string to the list of supported models. Return END_MODEL if +* no match or model is NULL. +*/ +static int asus_model_match (char *model) +{ +if (model ==NULL ) +return END_MODEL ; + +if (strncmp (model,"L3D" ,3 ) ==0 ) +return L3D ; +else if (strncmp (model,"L2E" ,3 ) ==0 || +strncmp (model,"L3H" ,3 ) ==0 ||strncmp (model,"L5D" ,3 ) ==0 ) +return L3H ; +else if (strncmp (model,"L3" ,2 ) ==0 ||strncmp (model,"L2B" ,3 ) ==0 ) +return L3C ; +else if (strncmp (model,"L8L" ,3 ) ==0 ) +return L8L ; +else if (strncmp (model,"L4R" ,3 ) ==0 ) +return L4R ; +else if (strncmp (model,"M6N" ,3 ) ==0 ||strncmp (model,"W3N" ,3 ) ==0 ) +return M6N ; +else if (strncmp (model,"M6R" ,3 ) ==0 ||strncmp (model,"A3G" ,3 ) ==0 ) +return M6R ; +else if (strncmp (model,"M2N" ,3 ) ==0 || +strncmp (model,"M3N" ,3 ) ==0 || +strncmp (model,"M5N" ,3 ) ==0 || +strncmp (model,"M6N" ,3 ) ==0 || +strncmp (model,"S1N" ,3 ) ==0 || +strncmp (model,"S5N" ,3 ) ==0 ||strncmp (model,"W1N" ,3 ) ==0 ) +return xxN; +else if (strncmp (model,"M1" ,2 ) ==0 ) +return M1A ; +else if (strncmp (model,"M2" ,2 ) ==0 ||strncmp (model,"L4E" ,3 ) ==0 ) +return M2E ; +else if (strncmp (model,"L2" ,2 ) ==0 ) +return L2D ; +else if (strncmp (model,"L8" ,2 ) ==0 ) +return S1x; +else if (strncmp (model,"D1" ,2 ) ==0 ) +return D1x; +else if (strncmp (model,"A1" ,2 ) ==0 ) +return A1x; +else if (strncmp (model,"A2" ,2 ) ==0 ) +return A2x; +else if (strncmp (model,"J1" ,2 ) ==0 ) +return S2x; +else if (strncmp (model,"L5" ,2 ) ==0 ) +return L5x; +else if (strncmp (model,"A4G" ,3 ) ==0 ) +return A4G ; +else if (strncmp (model,"W1N" ,3 ) ==0 ) +return W1N ; +else if (strncmp (model,"W5A" ,3 ) ==0 ) +return W5A ; +else +return END_MODEL ; +} + +/* * This function is used to initialize the hotk with right values. In this * method, we can make all the detection we want, and modify the hotk struct */
@@ -1057,6 +1116,7 @@ static int __init asus_hotk_get_info(voistruct acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER ,NULL };union acpi_object *model =NULL ;int bsts_result; +char *string =NULL ;acpi_status status;/*
@@ -1086,120 +1146,63 @@ static int __init asus_hotk_get_info(voiprintk (KERN_NOTICE " BSTS called, 0x%02x returned\n" , bsts_result); -/* This is unlikely with implicit return */ -if (buffer.pointer ==NULL ) -return -EINVAL ; - - model = (union acpi_object *)buffer.pointer;/* -* Samsung P30 has a device with a valid _HID whose INIT does not -* return anything. It used to be possible to catch this exception, -* but the implicit return code will now happily confuse the -* driver. We assume that every ACPI_TYPE_STRING is a valid model -* identifier but it's still possible to get completely bogus data. +* Try to match the object returned by INIT to the specific model. +* Handle every possible object (or the lack of thereof) the DSDT +* writers might throw at us. When in trouble, we pass NULL to +* asus_model_match() and try something completely different. */ -if (model->type ==ACPI_TYPE_STRING ) { -printk (KERN_NOTICE " %s model detected, " , - model->string.pointer); - }else { -if (asus_info &&/* Samsung P30 */ +if (buffer.pointer) { + model = (union acpi_object *)buffer.pointer; +switch (model->type) { +case ACPI_TYPE_STRING : + string = model->string.pointer; +break ; +case ACPI_TYPE_BUFFER : + string = model->buffer.pointer; +break ; +default : +kfree (model); +break ; + } + } + hotk->model =asus_model_match (string); +if (hotk->model ==END_MODEL ) {/* match failed */ +if (asus_info &&strncmp (asus_info->oem_table_id,"ODEM" ,4 ) ==0 ) { hotk->model =P30 ;printk (KERN_NOTICE " Samsung P30 detected, supported\n" ); }else { hotk->model =M2E ; -printk (KERN_WARNING " no string returned by INIT\n" ); -printk (KERN_WARNING " trying default values, supply " -"the developers with your DSDT\n" ); +printk (KERN_NOTICE " unsupported model %s, trying " +"default values\n" , string); +printk (KERN_NOTICE +" send /proc/acpi/dsdt to the developers\n" ); } hotk->methods = &model_conf[hotk->model]; - -kfree (model); -return AE_OK ; } - - hotk->model =END_MODEL ; -if (strncmp (model->string.pointer,"L3D" ,3 ) ==0 ) - hotk->model =L3D ; -else if (strncmp (model->string.pointer,"L2E" ,3 ) ==0 || -strncmp (model->string.pointer,"L3H" ,3 ) ==0 || -strncmp (model->string.pointer,"L5D" ,3 ) ==0 ) - hotk->model =L3H ; -else if (strncmp (model->string.pointer,"L3" ,2 ) ==0 || -strncmp (model->string.pointer,"L2B" ,3 ) ==0 ) - hotk->model =L3C ; -else if (strncmp (model->string.pointer,"L8L" ,3 ) ==0 ) - hotk->model =L8L ; -else if (strncmp (model->string.pointer,"L4R" ,3 ) ==0 ) - hotk->model =L4R ; -else if (strncmp (model->string.pointer,"M6N" ,3 ) ==0 || -strncmp (model->string.pointer,"W3N" ,3 ) ==0 ) - hotk->model =M6N ; -else if (strncmp (model->string.pointer,"M6R" ,3 ) ==0 || -strncmp (model->string.pointer,"A3G" ,3 ) ==0 ) - hotk->model =M6R ; -else if (strncmp (model->string.pointer,"M2N" ,3 ) ==0 || -strncmp (model->string.pointer,"M3N" ,3 ) ==0 || -strncmp (model->string.pointer,"M5N" ,3 ) ==0 || -strncmp (model->string.pointer,"M6N" ,3 ) ==0 || -strncmp (model->string.pointer,"S1N" ,3 ) ==0 || -strncmp (model->string.pointer,"S5N" ,3 ) ==0 ) - hotk->model = xxN; -else if (strncmp (model->string.pointer,"M1" ,2 ) ==0 ) - hotk->model =M1A ; -else if (strncmp (model->string.pointer,"M2" ,2 ) ==0 || -strncmp (model->string.pointer,"L4E" ,3 ) ==0 ) - hotk->model =M2E ; -else if (strncmp (model->string.pointer,"L2" ,2 ) ==0 ) - hotk->model =L2D ; -else if (strncmp (model->string.pointer,"L8" ,2 ) ==0 ) - hotk->model = S1x; -else if (strncmp (model->string.pointer,"D1" ,2 ) ==0 ) - hotk->model = D1x; -else if (strncmp (model->string.pointer,"A1" ,2 ) ==0 ) - hotk->model = A1x; -else if (strncmp (model->string.pointer,"A2" ,2 ) ==0 ) - hotk->model = A2x; -else if (strncmp (model->string.pointer,"J1" ,2 ) ==0 ) - hotk->model = S2x; -else if (strncmp (model->string.pointer,"L5" ,2 ) ==0 ) - hotk->model = L5x; -else if (strncmp (model->string.pointer,"A4G" ,3 ) ==0 ) - hotk->model =A4G ; -else if (strncmp (model->string.pointer,"W1N" ,3 ) ==0 ) - hotk->model =W1N ; -else if (strncmp (model->string.pointer,"W5A" ,3 ) ==0 ) - hotk->model =W5A ; - -if (hotk->model ==END_MODEL ) { -printk ("unsupported, trying default values, supply the " -"developers with your DSDT\n" ); - hotk->model =M2E ; - }else { -printk ("supported\n" ); - } - hotk->methods = &model_conf[hotk->model]; +printk (KERN_NOTICE " %s model detected, supported\n" , string);/* Sort of per-model blacklist */ -if (strncmp (model->string.pointer,"L2B" ,3 ) ==0 ) +if (strncmp (string,"L2B" ,3 ) ==0 ) hotk->methods->lcd_status =NULL ;/* L2B is similar enough to L3C to use its settings, with this only exception */ -else if (strncmp (model->string.pointer,"A3G" ,3 ) ==0 ) +else if (strncmp (string,"A3G" ,3 ) ==0 ) hotk->methods->lcd_status ="\\BLFG" ;/* A3G is like M6R */ -else if (strncmp (model->string.pointer,"S5N" ,3 ) ==0 || -strncmp (model->string.pointer,"M5N" ,3 ) ==0 || -strncmp (model->string.pointer,"W3N" ,3 ) ==0 ) +else if (strncmp (string,"S5N" ,3 ) ==0 || +strncmp (string,"M5N" ,3 ) ==0 || +strncmp (string,"W3N" ,3 ) ==0 ) hotk->methods->mt_mled =NULL ;/* S5N, M5N and W3N have no MLED */ -else if (strncmp (model->string.pointer,"L5D" ,3 ) ==0 ) +else if (strncmp (string,"L5D" ,3 ) ==0 ) hotk->methods->mt_wled =NULL ;/* L5D's WLED is not controlled by ACPI */ -else if (strncmp (model->string.pointer,"M2N" ,3 ) ==0 ) +else if (strncmp (string,"M2N" ,3 ) ==0 ) hotk->methods->mt_wled ="WLED" ;/* M2N has a usable WLED */ else if (asus_info) {
PATCH 9/10 add S1N WLED control
In reply to Karol KozimorThis small patch adds back WLED control for S1N models, this was accidentally removed a while ago.
drivers/acpi/asus_acpi.c +3 -2
@@ -1202,9 +1202,10 @@ static int __init asus_hotk_get_info(voielse if (strncmp (string,"L5D" ,3 ) ==0 ) hotk->methods->mt_wled =NULL ;/* L5D's WLED is not controlled by ACPI */ -else if (strncmp (string,"M2N" ,3 ) ==0 ) +else if (strncmp (string,"M2N" ,3 ) ==0 || +strncmp (string,"S1N" ,3 ) ==0 ) hotk->methods->mt_wled ="WLED" ; -/* M2N has a usable WLED */ +/* M2N and S1N have a usable WLED */ else if (asus_info) {if (strncmp (asus_info->oem_table_id,"L1" ,2 ) ==0 ) hotk->methods->mled_status =NULL ;
PATCH 10/10 add S1N WLED control
In reply to Karol KozimorThis patch switches back the display nodes for M6R and M6N -- this happened a while ago when a patch was misapplied (only the in-tree version was affected).
drivers/acpi/asus_acpi.c +3 -2
@@ -310,7 +310,8 @@ .brightness_set = "SPLV", .brightness_get = "GPLV", .display_set = "SDSP", - .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"}, + .display_get = "\\SSTE"}, + { .name = "M6R", .mt_mled = "MLED",
@@ -320,7 +321,7 @@ .brightness_set = "SPLV", .brightness_get = "GPLV", .display_set = "SDSP", - .display_get = "\\SSTE"}, + .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"}, { .name = "P30",