aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/sony-laptop.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 33d9555470c3..8f709aec4da0 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -138,6 +138,8 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
138 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " 138 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
139 "(default: 0)"); 139 "(default: 0)");
140 140
141static void sony_nc_kbd_backlight_resume(void);
142
141enum sony_nc_rfkill { 143enum sony_nc_rfkill {
142 SONY_WIFI, 144 SONY_WIFI,
143 SONY_BLUETOOTH, 145 SONY_BLUETOOTH,
@@ -1176,6 +1178,9 @@ static int sony_nc_resume(struct acpi_device *device)
1176 /* re-read rfkill state */ 1178 /* re-read rfkill state */
1177 sony_nc_rfkill_update(); 1179 sony_nc_rfkill_update();
1178 1180
1181 /* restore kbd backlight states */
1182 sony_nc_kbd_backlight_resume();
1183
1179 return 0; 1184 return 0;
1180} 1185}
1181 1186
@@ -1363,6 +1368,7 @@ out_no_enum:
1363#define KBDBL_HANDLER 0x137 1368#define KBDBL_HANDLER 0x137
1364#define KBDBL_PRESENT 0xB00 1369#define KBDBL_PRESENT 0xB00
1365#define SET_MODE 0xC00 1370#define SET_MODE 0xC00
1371#define SET_STATE 0xD00
1366#define SET_TIMEOUT 0xE00 1372#define SET_TIMEOUT 0xE00
1367 1373
1368struct kbd_backlight { 1374struct kbd_backlight {
@@ -1385,6 +1391,10 @@ static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
1385 (value << 0x10) | SET_MODE, &result)) 1391 (value << 0x10) | SET_MODE, &result))
1386 return -EIO; 1392 return -EIO;
1387 1393
1394 /* Try to turn the light on/off immediately */
1395 sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE,
1396 &result);
1397
1388 kbdbl_handle->mode = value; 1398 kbdbl_handle->mode = value;
1389 1399
1390 return 0; 1400 return 0;
@@ -1466,7 +1476,7 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
1466{ 1476{
1467 int result; 1477 int result;
1468 1478
1469 if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result)) 1479 if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result))
1470 return 0; 1480 return 0;
1471 if (!(result & 0x02)) 1481 if (!(result & 0x02))
1472 return 0; 1482 return 0;
@@ -1509,13 +1519,36 @@ outkzalloc:
1509static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) 1519static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
1510{ 1520{
1511 if (kbdbl_handle) { 1521 if (kbdbl_handle) {
1522 int result;
1523
1512 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); 1524 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
1513 device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr); 1525 device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
1526
1527 /* restore the default hw behaviour */
1528 sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result);
1529 sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result);
1530
1514 kfree(kbdbl_handle); 1531 kfree(kbdbl_handle);
1515 } 1532 }
1516 return 0; 1533 return 0;
1517} 1534}
1518 1535
1536static void sony_nc_kbd_backlight_resume(void)
1537{
1538 int ignore = 0;
1539
1540 if (!kbdbl_handle)
1541 return;
1542
1543 if (kbdbl_handle->mode == 0)
1544 sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore);
1545
1546 if (kbdbl_handle->timeout != 0)
1547 sony_call_snc_handle(KBDBL_HANDLER,
1548 (kbdbl_handle->timeout << 0x10) | SET_TIMEOUT,
1549 &ignore);
1550}
1551
1519static void sony_nc_backlight_setup(void) 1552static void sony_nc_backlight_setup(void)
1520{ 1553{
1521 acpi_handle unused; 1554 acpi_handle unused;