於 四,2011-08-11 於 10:48 +0800,AceLan Kao 提到: > Dear Joey, > > This is the dmesg log. > [ 9010.944053] acer_wmi: Acer Laptop ACPI-WMI Extras > [ 9010.944071] acer_wmi: Function bitmap for Communication Button: 0x1 > [ 9010.944075] acer_wmi: Brightness must be controlled by generic video driver > [ 9010.944996] input: Acer WMI hotkeys as /devices/virtual/input/input21 > [ 9010.947095] acer_wmi: Set Device Status failed: 0xe2 - 0x0 > > And after adding my quirk, the set device status still failed, but > except that, everything works well. > So, you machine have wifi hardware module or not? > The "failed" comes from acer_rfkill_init(), it'll call > acer_rfkill_register() with ACER_CAP_WIRELESS parameter without > checking the capability. > I don't know why only wifi doesn't check the capability and call > acer_rfkill_register() directly, but it doesn't hurt the system. > > === > static int acer_rfkill_init(struct device *dev) > { > wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, > "acer-wireless", ACER_CAP_WIRELESS); > if (IS_ERR(wireless_rfkill)) > return PTR_ERR(wireless_rfkill); > === > > Best regards, > AceLan Kao. > I checked the history, looks like it's just a original design in old patch. Yes, you are right, add ACER_CAP_WIRELESS check is better. I am doing generate a patch to add ACER_CAP_WIRELESS check. Will attached patch on mail. Thank's Joey Lee > 2011/8/10 Joey Lee <jlee@xxxxxxxxxx>: > > Hi AceLan, > > > > 於 三,2011-08-10 於 10:13 +0800,joeyli 提到: > >> 於 二,2011-08-09 於 14:33 +0800,AceLan Kao 提到: > >> > Dear Joey, > >> > > >> > The current project we have right now have to follow the Acer WMI to > >> > handle the key events, that means no EC key event. > >> > And we have 3 keys that are not working now, they are touchpad > > toggle, > >> > brightness up, and brightness down. > >> > The touchpad toggle function is a Hotkey Break Event(function number > >> > 0x2), and brightness key events are Brightness Change Event(function > >> > number 0x4). But now acer-wmi driver only handles General Hotkey > >> > Event(function number 0x1). > >> > > >> > >> Yes, current acer-wmi only capture the event function number 0x1, you > >> can add those new function to acer_wmi_notify(). > >> > >> > I just implemented those 3 key events, so I think maybe we don't > > have > >> > to create a new acer-wmi driver. > >> > >> Great! Welcome for you patches, I will also test it. > >> > >> > I'm longing for your work to clear up the acer-wmi driver, so that I > >> > can add the new machine id and send you the patch. > >> > Thanks. > >> > > >> > BTW, I'm available to help if you are too busy to do that. > >> > > >> > Best regards, > >> > AceLan Kao. > >> > > >> > >> I am doing the clear up, now, will send out patch (I hope today). > >> > >> > >> Thank's > >> Joey Lee > >> > > > > I add a new ACER_WMID_v2 interface flag and do some clear up in acer-wmi > > initial function and get_u32 functions. > > > > Please kindly test this patch: > > > > > > Thank's > > Joey Lee > > > > >From 28b2e2ebaa230d339d5749b581c667ed074bb7ea Mon Sep 17 00:00:00 2001 > > From: Lee, Chun-Yi <jlee@xxxxxxxx> > > Date: Wed, 10 Aug 2011 16:36:02 +0800 > > Subject: [PATCH] acer-wmi: add ACER_WMID_v2 interface flag to represent new notebooks > > > > There have new acer notebooks' BIOS provide new WMID_GUID3 and > > ACERWMID_EVENT_GUID methods. > > > > Some of machines still keep the old WMID_GUID1 method but more and > > more machines were already removed old wmi methods from DSDT. > > > > So, this patch add a new ACER_WMID_v2 interface flag to represent > > new acer notebooks, the following is definition: > > > > + ACER_WMID: > > It means this machine only provides WMID_GUID1/2 methods. > > > > + ACER_WMID_v2: > > It means this machine provide new WMID_GUID3 and WMID_EVENT_GUID > > methods. > > Some ACER_> > but we still query/set communication device's state by new > > WMID_GUID3 method. > > > > Tested on Acer Travelmate 8572 > > > > Signed-off-by: Lee, Chun-Yi <jlee@xxxxxxxx> > > --- > > drivers/platform/x86/acer-wmi.c | 409 ++++++++++++++++++++------------------- > > 1 files changed, 211 insertions(+), 198 deletions(-) > > > > diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c > > index af2bb20..712a505 100644 > > --- a/drivers/platform/x86/acer-wmi.c > > +++ b/drivers/platform/x86/acer-wmi.c > > @@ -190,6 +190,7 @@ enum interface_flags { > > ACER_AMW0, > > ACER_AMW0_V2, > > ACER_WMID, > > + ACER_WMID_v2, > > }; > > > > #define ACER_DEFAULT_WIRELESS 0 > > @@ -868,6 +869,176 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) > > return WMI_execute_u32(method_id, (u32)value, NULL); > > } > > > > +static acpi_status wmid3_get_device_status(u32 *value, u16 device) > > +{ > > + struct wmid3_gds_return_value return_value; > > + acpi_status status; > > + union acpi_object *obj; > > + struct wmid3_gds_input_param params = { > > + .function_num = 0x1, > > + .hotkey_number = 0x01, > > + .devices = device, > > + }; > > + struct acpi_buffer input = { > > + sizeof(struct wmid3_gds_input_param), > > + ¶ms > > + }; > > + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; > > + > > + status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); > > + if (ACPI_FAILURE(status)) > > + return status; > > + > > + obj = output.pointer; > > + > > + if (!obj) > > + return AE_ERROR; > > + else if (obj->type != ACPI_TYPE_BUFFER) { > > + kfree(obj); > > + return AE_ERROR; > > + } > > + if (obj->buffer.length != 8) { > > + pr_warn("Unknown buffer length %d\n", obj->buffer.length); > > + kfree(obj); > > + return AE_ERROR; > > + } > > + > > + return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); > > + kfree(obj); > > + > > + if (return_value.error_code || return_value.ec_return_value) > > + pr_warn("Get Device Status failed: 0x%x - 0x%x\n", > > + return_value.error_code, > > + return_value.ec_return_value); > > + else > > + *value = !!(return_value.devices & device); > > + > > + return status; > > +} > > + > > +static acpi_status wmid_v2_get_u32(u32 *value, u32 cap) > > +{ > > + u16 device; > > + > > + switch (cap) { > > + case ACER_CAP_WIRELESS: > > + device = ACER_WMID3_GDS_WIRELESS; > > + break; > > + case ACER_CAP_BLUETOOTH: > > + device = ACER_WMID3_GDS_BLUETOOTH; > > + break; > > + case ACER_CAP_THREEG: > > + device = ACER_WMID3_GDS_THREEG; > > + break; > > + default: > > + return AE_ERROR; > > + } > > + return wmid3_get_device_status(value, device); > > +} > > + > > +static acpi_status wmid3_set_device_status(u32 value, u16 device) > > +{ > > + struct wmid3_gds_return_value return_value; > > + acpi_status status; > > + union acpi_object *obj; > > + u16 devices; > > + struct wmid3_gds_input_param params = { > > + .function_num = 0x1, > > + .hotkey_number = 0x01, > > + .devices = ACER_WMID3_GDS_WIRELESS | > > + ACER_WMID3_GDS_THREEG | > > + ACER_WMID3_GDS_WIMAX | > > + ACER_WMID3_GDS_BLUETOOTH, > > + }; > > + struct acpi_buffer input = { > > + sizeof(struct wmid3_gds_input_param), > > + > > + struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; > > + > > + status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); > > + if (ACPI_FAILURE(status)) > > + return status; > > + > > + obj = output.pointer; > > + > > + if (!obj) > > + return AE_ERROR; > > + else if (obj->type != ACPI_TYPE_BUFFER) { > > + kfree(obj); > > + return AE_ERROR; > > + } > > + if (obj->buffer.length != 8) { > > + pr_warning("Unknown buffer length %d\n", obj->buffer.length); > > + kfree(obj); > > + return AE_ERROR; > > + } > > + > > + return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); > > + kfree(obj); > > + > > + if (return_value.error_code || return_value.ec_return_value) { > > + pr_warning("Get Current Device Status failed: " > > + "0x%x - 0x%x\n", return_value.error_code, > > + return_value.ec_return_value); > > + return status; > > + } > > + > > + devices = return_value.devices; > > + params.function_num = 0x2; > > + params.hotkey_number = 0x01; > > + params.devices = (value) ? (devices | device) : (devices & ~device); > > + > > + status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); > > + if (ACPI_FAILURE(status)) > > + return status; > > + > > + obj = output2.pointer; > > + > > + if (!obj) > > + return AE_ERROR; > > + else if (obj->type != ACPI_TYPE_BUFFER) { > > + kfree(obj); > > + return AE_ERROR; > > + } > > + if (obj->buffer.length != 4) { > > + pr_warning("Unknown buffer length %d\n", obj->buffer.length); > > + kfree(obj); > > + return AE_ERROR; > > + } > > + > > + return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); > > + kfree(obj); > > + > > + if (return_value.error_code || return_value.ec_return_value) > > + pr_warning("Set Device Status failed: " > > + "0x%x - 0x%x\n", return_value.error_code, > > + return_value.ec_return_value); > > + > > + return status; > > +} > > + > > +static acpi_status wmid_v2_set_u32(u32 value, u32 cap) > > +{ > > + u16 device; > > + > > + switch (cap) { > > + case ACER_CAP_WIRELESS: > > + device = ACER_WMID3_GDS_WIRELESS; > > + break; > > + case ACER_CAP_BLUETOOTH: > > + device = ACER_WMID3_GDS_BLUETOOTH; > > + break; > > + case ACER_CAP_THREEG: > > + device = ACER_WMID3_GDS_THREEG; > > + break; > > + default: > > + return AE_ERROR; > > + } > > + return wmid3_set_device_status(value, device); > > +} > > + > > static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) > > { > > struct hotkey_function_type_aa *type_aa; > > @@ -913,17 +1084,11 @@ static acpi_status WMID_set_capabilities(void) > > return AE_ERROR; > > } > > > > - dmi_walk(type_aa_dmi_decode, NULL); > > - if (!has_type_aa) { > > - interface->capability |= ACER_CAP_WIRELESS; > > - if (devices & 0x40) > > - interface->capability |= ACER_CAP_THREEG; > > - if (devices & 0x10) > > - interface->capability |= ACER_CAP_BLUETOOTH; > > - } > > - > > - /* WMID always provides brightness methods */ > > - interface->capability |= ACER_CAP_BRIGHTNESS; > > + interface->capability |= ACER_CAP_WIRELESS; > > + if (devices & 0x40) > > + interface->capability |= ACER_CAP_THREEG; > > + if (devices & 0x10) > > + interface->capability |= A> > @@ -936,6 +1101,10 @@ static struct wmi_interface wmid_interface = { > > .type = ACER_WMID, > > }; > > > > +static struct wmi_interface wmid_v2_interface = { > > + .type = ACER_WMID_v2, > > +}; > > + > > /* > > * Generic Device (interface-independent) > > */ > > @@ -956,6 +1125,14 @@ static acpi_status get_u32(u32 *value, u32 cap) > > case ACER_WMID: > > status = WMID_get_u32(value, cap, interface); > > break; > > + case ACER_WMID_v2: > > + if (cap & (ACER_CAP_WIRELESS | > > + ACER_CAP_BLUETOOTH | > > + ACER_CAP_THREEG)) > > + status = wmid_v2_get_u32(value, cap); > > + else if (wmi_has_guid(WMID_GUID2)) > > + status = WMID_get_u32(value, cap, interface); > > + break; > > } > > > > return status; > > @@ -989,6 +1166,13 @@ static acpi_status set_u32(u32 value, u32 cap) > > } > > case ACER_WMID: > > return WMID_set_u32(value, cap, interface); > > + case ACER_WMID_v2: > > + if (cap & (ACER_CAP_WIRELESS | > > + ACER_CAP_BLUETOOTH | > > + ACER_CAP_THREEG)) > > + return wmid_v2_set_u32(value, cap); > > + else if (wmi_has_guid(WMID_GUID2)) > > + return WMID_set_u32(value, cap, interface); > > default: > > return AE_BAD_PARAMETER; > > } > > @@ -1095,186 +1279,6 @@ static void acer_backlight_exit(void) > > backlight_device_unregister(acer_backlight_device); > > } > > > > -static acpi_status wmid3_get_device_status(u32 *value, u16 device) > > -{ > > - struct wmid3_gds_return_value return_value; > > - acpi_status status; > > - union acpi_object *obj; > > - struct wmid3_gds_input_param params = { > > - .function_num = 0x1, > > - .hotkey_number = 0x01, > > - .devices = device, > > - }; > > - struct acpi_buffer input = { > > - sizeof(struct wmid3_gds_input_param), > > - ¶ms > > - }; > > - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; > > - > > - status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); > > - if (ACPI_FAILURE(status)) > > - return status; > > - > > - obj = output.pointer; > > - > > - if (!obj) > > - return AE_ERROR; > > - else if (obj->type != ACPI_TYPE_BUFFER) { > > - kfree(obj); > > - return AE_ERROR; > > - } > > - if (obj->buffer.length != 8) { > > - pr_warn("Unknown buffer length %d\n", obj->buffer.length); > > - kfree(obj); > > - return AE_ERROR; > > - } > > - > > - return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); > > - kfree(obj); > > - > > - if (return_value.error_code || return_value.ec_return_value) > > - pr_warn("Get Device Status failed: 0x%x - 0x%x\n", > > - return_value.error_code, > > - return_value.ec_return_value); > > - else > > - *value = !!(return_value.devices & device); > > - > > - return status; > > -} > > - > > -static acpi_status get_device_status(u32 *value, u32 cap) > > -{ > > - if (wmi_has_guid(WMID_GUID3)) { > > - u16 device; > > - > > - switch (cap) { > > - case ACER_CAP_WIRELESS: > > - device = ACER_WMID3_GDS_WIRELESS; > > - break; > > - case ACER_CAP_BLUETOOTH: > > - device = ACER_WMID3_GDS_BLUETOOTH; > > - break; > > -> > - break; > > - default: > > - return AE_ERROR; > > - } > > - return wmid3_get_device_status(value, device); > > - > > - } else { > > - return get_u32(value, cap); > > - } > > -} > > - > > -static acpi_status wmid3_set_device_status(u32 value, u16 device) > > -{ > > - struct wmid3_gds_return_value return_value; > > - acpi_status status; > > - union acpi_object *obj; > > - u16 devices; > > - struct wmid3_gds_input_param params = { > > - .function_num = 0x1, > > - .hotkey_number = 0x01, > > - .devices = ACER_WMID3_GDS_WIRELESS | > > - ACER_WMID3_GDS_THREEG | > > - ACER_WMID3_GDS_WIMAX | > > - ACER_WMID3_GDS_BLUETOOTH, > > - }; > > - struct acpi_buffer input = { > > - sizeof(struct wmid3_gds_input_param), > > - ¶ms > > - }; > > - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; > > - struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; > > - > > - status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); > > - if (ACPI_FAILURE(status)) > > - return status; > > - > > - obj = output.pointer; > > - > > - if (!obj) > > - return AE_ERROR; > > - else if (obj->type != ACPI_TYPE_BUFFER) { > > - kfree(obj); > > - return AE_ERROR; > > - } > > - if (obj->buffer.length != 8) { > > - pr_warning("Unknown buffer length %d\n", obj->buffer.length); > > - kfree(obj); > > - return AE_ERROR; > > - } > > - > > - return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); > > - kfree(obj); > > - > > - if (return_value.error_code || return_value.ec_return_value) { > > - pr_warning("Get Current Device Status failed: " > > - "0x%x - 0x%x\n", return_value.error_code, > > - return_value.ec_return_value); > > - return status; > > - } > > - > > - devices = return_value.devices; > > - params.function_num = 0x2; > > - params.hotkey_number = 0x01; > > - params.devices = (value) ? (devices | device) : (devices & ~device); > > - > > - status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); > > - if (ACPI_FAILURE(status)) > > - return status; > > - > > - obj = output2.pointer; > > - > > - if (!obj) > > - return AE_ERROR; > > - else if (obj->type != ACPI_TYPE_BUFFER) { > > - kfree(obj); > > - return AE_ERROR; > > - } > > - if (obj->buffer.length != 4) { > > - pr_warning("Unknown buffer length %d\n", obj->buffer.length); > > - kfree(obj); > > - return AE_ERROR; > > - } > > - > > - return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); > > - kfree(obj); > > - > > - if (return_value.error_code || return_value.ec_return_value) > > - pr_warning("Set Device Status failed: " > > - "0x%x - 0x%x\n", return_value.error_code, > > - return_value.ec_return_value); > > - > > - return status; > > -} > > - > > -static acpi_status set_device_status(u32 value, u32 cap) > > -{ > > - if (wmi_has_guid(WMID_GUID3)) { > > - u16 device; > > - > > - switch (cap) { > > - case ACER_CAP_WIRELESS: > > - device = ACER_WMID3_GDS_WIRELESS; > > - break; > > - case ACER_CAP_BLUETOOTH: > > - device = ACER_WMID3_GDS_BLUETOOTH; > > - break; > > - case ACER_CAP_THREEG: > > - device = ACE> > - return AE_ERROR; > > - } > > - return wmid3_set_device_status(value, device); > > - > > - } else { > > - return set_u32(value, cap); > > - } > > -} > > - > > /* > > * Rfkill devices > > */ > > @@ -1301,8 +1305,7 @@ static void acer_rfkill_update(struct work_struct *ignored) > > } > > > > if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { > > - status = wmid3_get_device_status(&state, > > - ACER_WMID3_GDS_THREEG); > > + status = get_u32(&state, ACER_WMID3_GDS_THREEG); > > if (ACPI_SUCCESS(status)) > > rfkill_set_sw_state(threeg_rfkill, !state); > > } > > @@ -1316,7 +1319,7 @@ static int acer_rfkill_set(void *data, bool blocked) > > u32 cap = (unsigned long)data; > > > > if (rfkill_inited) { > > - status = set_device_status(!blocked, cap); > > + status = set_u32(!blocked, cap); > > if (ACPI_FAILURE(status)) > > return -ENODEV; > > } > > @@ -1343,7 +1346,7 @@ static struct rfkill *acer_rfkill_register(struct device *dev, > > if (!rfkill_dev) > > return ERR_PTR(-ENOMEM); > > > > - status = get_device_status(&state, cap); > > + status = get_u32(&state, cap); > > > > err = rfkill_register(rfkill_dev); > > if (err) { > > @@ -1464,6 +1467,8 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr, > > return sprintf(buf, "AMW0 v2\n"); > > case ACER_WMID: > > return sprintf(buf, "WMID\n"); > > + case ACER_WMID_v2: > > + return sprintf(buf, "WMID v2\n"); > > default: > > return sprintf(buf, "Error!\n"); > > } > > @@ -1883,12 +1888,20 @@ static int __init acer_wmi_init(void) > > if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) > > interface = &wmid_interface; > > > > + if (wmi_has_guid(WMID_GUID3)) > > + interface = &wmid_v2_interface; > > + > > + if (interface) > > + dmi_walk(type_aa_dmi_decode, NULL); > > + > > if (wmi_has_guid(WMID_GUID2) && interface) { > > - if (ACPI_FAILURE(WMID_set_capabilities())) { > > + if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) { > > pr_err("Unable to detect available WMID devices\n"); > > return -ENODEV; > > } > > - } else if (!wmi_has_guid(WMID_GUID2) && interface) { > > + /* WMID always provides brightness methods */ > > + interface->capability |= ACER_CAP_BRIGHTNESS; > > + } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { > > pr_err("No WMID device detection method found\n"); > > return -ENODEV; > > } > > @@ -1912,7 +1925,7 @@ static int __init acer_wmi_init(void) > > > > set_quirks(); > > > > - if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { > > + if (acpi_video_backlight_support()) { > > interface->capability &= ~ACER_CAP_BRIGHTNESS; > > pr_info("Brightness must be controlled by " > > "generic video driver\n"); > > -- > > 1.6.0.2 > > > > > > > > > > > -- To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html