diff options
author | Marco Chiappero <marco@absence.it> | 2011-04-05 10:38:34 -0400 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2011-04-12 11:27:44 -0400 |
commit | df410d522410e676602a14eb5957c4b3e1fa3902 (patch) | |
tree | 6d40e4c8544c6f64bb6d521403a6d3e5b45e3e21 /drivers/platform | |
parent | 855b8bc9953fdf40095fdec9d91d49736ca7b17c (diff) |
sony-laptop: keyboard backlight fixes
Restore the original state on module removal, set the latest values on
resume.
When setting the keyboard backlight mode try to turn on/off backlight
immediately.
[malattia@linux.it: patch taken from a largely modified sony-laptop.c,
ported and slightly modified to use defines already available.]
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 35 |
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 | ||
141 | static void sony_nc_kbd_backlight_resume(void); | ||
142 | |||
141 | enum sony_nc_rfkill { | 143 | enum 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 | ||
1368 | struct kbd_backlight { | 1374 | struct 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: | |||
1509 | static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) | 1519 | static 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 | ||
1536 | static 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 | |||
1519 | static void sony_nc_backlight_setup(void) | 1552 | static void sony_nc_backlight_setup(void) |
1520 | { | 1553 | { |
1521 | acpi_handle unused; | 1554 | acpi_handle unused; |