aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/acer-wmi.c110
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
132struct 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
140struct lm_return_value {
141 u8 error_code; /* Error Code */
142 u8 ec_return_value; /* EC Return Value */
143 u16 reserved;
144} __attribute__((packed));
145
132struct wmid3_gds_input_param { /* Get Device Status input parameter */ 146struct 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;
179static int brightness = -1; 193static int brightness = -1;
180static int threeg = -1; 194static int threeg = -1;
181static int force_series; 195static int force_series;
196static bool ec_raw_mode;
182static bool has_type_aa; 197static bool has_type_aa;
183 198
184module_param(mailled, int, 0444); 199module_param(mailled, int, 0444);
185module_param(brightness, int, 0444); 200module_param(brightness, int, 0444);
186module_param(threeg, int, 0444); 201module_param(threeg, int, 0444);
187module_param(force_series, int, 0444); 202module_param(force_series, int, 0444);
203module_param(ec_raw_mode, bool, 0444);
188MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); 204MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
189MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); 205MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
190MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); 206MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
191MODULE_PARM_DESC(force_series, "Force a different laptop series"); 207MODULE_PARM_DESC(force_series, "Force a different laptop series");
208MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
192 209
193struct acer_data { 210struct 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
1350static acpi_status
1351wmid3_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
1385static 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(&params, &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
1408static 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(&params, &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
1333static int __init acer_wmi_input_setup(void) 1429static 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)