diff options
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/acer-wmi.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index d80db089938..ee40d681edd 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -129,6 +129,20 @@ struct event_return_value { | |||
129 | #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ | 129 | #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ |
130 | #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ | 130 | #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ |
131 | 131 | ||
132 | struct lm_input_params { | ||
133 | u8 function_num; /* Function Number */ | ||
134 | u16 commun_devices; /* Communication type devices default status */ | ||
135 | u16 devices; /* Other type devices default status */ | ||
136 | u8 lm_status; /* Launch Manager Status */ | ||
137 | u16 reserved; | ||
138 | } __attribute__((packed)); | ||
139 | |||
140 | struct lm_return_value { | ||
141 | u8 error_code; /* Error Code */ | ||
142 | u8 ec_return_value; /* EC Return Value */ | ||
143 | u16 reserved; | ||
144 | } __attribute__((packed)); | ||
145 | |||
132 | struct wmid3_gds_input_param { /* Get Device Status input parameter */ | 146 | struct wmid3_gds_input_param { /* Get Device Status input parameter */ |
133 | u8 function_num; /* Function Number */ | 147 | u8 function_num; /* Function Number */ |
134 | u8 hotkey_number; /* Hotkey Number */ | 148 | u8 hotkey_number; /* Hotkey Number */ |
@@ -179,16 +193,19 @@ static int mailled = -1; | |||
179 | static int brightness = -1; | 193 | static int brightness = -1; |
180 | static int threeg = -1; | 194 | static int threeg = -1; |
181 | static int force_series; | 195 | static int force_series; |
196 | static bool ec_raw_mode; | ||
182 | static bool has_type_aa; | 197 | static bool has_type_aa; |
183 | 198 | ||
184 | module_param(mailled, int, 0444); | 199 | module_param(mailled, int, 0444); |
185 | module_param(brightness, int, 0444); | 200 | module_param(brightness, int, 0444); |
186 | module_param(threeg, int, 0444); | 201 | module_param(threeg, int, 0444); |
187 | module_param(force_series, int, 0444); | 202 | module_param(force_series, int, 0444); |
203 | module_param(ec_raw_mode, bool, 0444); | ||
188 | MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); | 204 | MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); |
189 | MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); | 205 | MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); |
190 | MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); | 206 | MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); |
191 | MODULE_PARM_DESC(force_series, "Force a different laptop series"); | 207 | MODULE_PARM_DESC(force_series, "Force a different laptop series"); |
208 | MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); | ||
192 | 209 | ||
193 | struct acer_data { | 210 | struct acer_data { |
194 | int mailled; | 211 | int mailled; |
@@ -1330,6 +1347,85 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1330 | } | 1347 | } |
1331 | } | 1348 | } |
1332 | 1349 | ||
1350 | static acpi_status | ||
1351 | wmid3_set_lm_mode(struct lm_input_params *params, | ||
1352 | struct lm_return_value *return_value) | ||
1353 | { | ||
1354 | acpi_status status; | ||
1355 | union acpi_object *obj; | ||
1356 | |||
1357 | struct acpi_buffer input = { sizeof(struct lm_input_params), params }; | ||
1358 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1359 | |||
1360 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output); | ||
1361 | if (ACPI_FAILURE(status)) | ||
1362 | return status; | ||
1363 | |||
1364 | obj = output.pointer; | ||
1365 | |||
1366 | if (!obj) | ||
1367 | return AE_ERROR; | ||
1368 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
1369 | kfree(obj); | ||
1370 | return AE_ERROR; | ||
1371 | } | ||
1372 | if (obj->buffer.length != 4) { | ||
1373 | printk(ACER_WARNING "Unknown buffer length %d\n", | ||
1374 | obj->buffer.length); | ||
1375 | kfree(obj); | ||
1376 | return AE_ERROR; | ||
1377 | } | ||
1378 | |||
1379 | *return_value = *((struct lm_return_value *)obj->buffer.pointer); | ||
1380 | kfree(obj); | ||
1381 | |||
1382 | return status; | ||
1383 | } | ||
1384 | |||
1385 | static int acer_wmi_enable_ec_raw(void) | ||
1386 | { | ||
1387 | struct lm_return_value return_value; | ||
1388 | acpi_status status; | ||
1389 | struct lm_input_params params = { | ||
1390 | .function_num = 0x1, | ||
1391 | .commun_devices = 0xFFFF, | ||
1392 | .devices = 0xFFFF, | ||
1393 | .lm_status = 0x00, /* Launch Manager Deactive */ | ||
1394 | }; | ||
1395 | |||
1396 | status = wmid3_set_lm_mode(¶ms, &return_value); | ||
1397 | |||
1398 | if (return_value.error_code || return_value.ec_return_value) | ||
1399 | printk(ACER_WARNING "Enabling EC raw mode failed: " | ||
1400 | "0x%x - 0x%x\n", return_value.error_code, | ||
1401 | return_value.ec_return_value); | ||
1402 | else | ||
1403 | printk(ACER_INFO "Enabled EC raw mode"); | ||
1404 | |||
1405 | return status; | ||
1406 | } | ||
1407 | |||
1408 | static int acer_wmi_enable_lm(void) | ||
1409 | { | ||
1410 | struct lm_return_value return_value; | ||
1411 | acpi_status status; | ||
1412 | struct lm_input_params params = { | ||
1413 | .function_num = 0x1, | ||
1414 | .commun_devices = 0xFFFF, | ||
1415 | .devices = 0xFFFF, | ||
1416 | .lm_status = 0x01, /* Launch Manager Active */ | ||
1417 | }; | ||
1418 | |||
1419 | status = wmid3_set_lm_mode(¶ms, &return_value); | ||
1420 | |||
1421 | if (return_value.error_code || return_value.ec_return_value) | ||
1422 | printk(ACER_WARNING "Enabling Launch Manager failed: " | ||
1423 | "0x%x - 0x%x\n", return_value.error_code, | ||
1424 | return_value.ec_return_value); | ||
1425 | |||
1426 | return status; | ||
1427 | } | ||
1428 | |||
1333 | static int __init acer_wmi_input_setup(void) | 1429 | static int __init acer_wmi_input_setup(void) |
1334 | { | 1430 | { |
1335 | acpi_status status; | 1431 | acpi_status status; |
@@ -1618,6 +1714,20 @@ static int __init acer_wmi_init(void) | |||
1618 | "generic video driver\n"); | 1714 | "generic video driver\n"); |
1619 | } | 1715 | } |
1620 | 1716 | ||
1717 | if (wmi_has_guid(WMID_GUID3)) { | ||
1718 | if (ec_raw_mode) { | ||
1719 | if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) { | ||
1720 | printk(ACER_ERR "Cannot enable EC raw mode\n"); | ||
1721 | return -ENODEV; | ||
1722 | } | ||
1723 | } else if (ACPI_FAILURE(acer_wmi_enable_lm())) { | ||
1724 | printk(ACER_ERR "Cannot enable Launch Manager mode\n"); | ||
1725 | return -ENODEV; | ||
1726 | } | ||
1727 | } else if (ec_raw_mode) { | ||
1728 | printk(ACER_INFO "No WMID EC raw mode enable method\n"); | ||
1729 | } | ||
1730 | |||
1621 | if (wmi_has_guid(ACERWMID_EVENT_GUID)) { | 1731 | if (wmi_has_guid(ACERWMID_EVENT_GUID)) { |
1622 | err = acer_wmi_input_setup(); | 1732 | err = acer_wmi_input_setup(); |
1623 | if (err) | 1733 | if (err) |