aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/sony-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/sony-laptop.c')
-rw-r--r--drivers/platform/x86/sony-laptop.c660
1 files changed, 542 insertions, 118 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index e3154ff7a39f..bbd182e178cb 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -42,6 +42,8 @@
42 * 42 *
43 */ 43 */
44 44
45#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
46
45#include <linux/kernel.h> 47#include <linux/kernel.h>
46#include <linux/module.h> 48#include <linux/module.h>
47#include <linux/moduleparam.h> 49#include <linux/moduleparam.h>
@@ -70,9 +72,10 @@
70#include <linux/miscdevice.h> 72#include <linux/miscdevice.h>
71#endif 73#endif
72 74
73#define DRV_PFX "sony-laptop: " 75#define dprintk(fmt, ...) \
74#define dprintk(msg...) do { \ 76do { \
75 if (debug) printk(KERN_WARNING DRV_PFX msg); \ 77 if (debug) \
78 pr_warn(fmt, ##__VA_ARGS__); \
76} while (0) 79} while (0)
77 80
78#define SONY_LAPTOP_DRIVER_VERSION "0.6" 81#define SONY_LAPTOP_DRIVER_VERSION "0.6"
@@ -124,6 +127,21 @@ MODULE_PARM_DESC(minor,
124 "default is -1 (automatic)"); 127 "default is -1 (automatic)");
125#endif 128#endif
126 129
130static int kbd_backlight; /* = 1 */
131module_param(kbd_backlight, int, 0444);
132MODULE_PARM_DESC(kbd_backlight,
133 "set this to 0 to disable keyboard backlight, "
134 "1 to enable it (default: 0)");
135
136static int kbd_backlight_timeout; /* = 0 */
137module_param(kbd_backlight_timeout, int, 0444);
138MODULE_PARM_DESC(kbd_backlight_timeout,
139 "set this to 0 to set the default 10 seconds timeout, "
140 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
141 "(default: 0)");
142
143static void sony_nc_kbd_backlight_resume(void);
144
127enum sony_nc_rfkill { 145enum sony_nc_rfkill {
128 SONY_WIFI, 146 SONY_WIFI,
129 SONY_BLUETOOTH, 147 SONY_BLUETOOTH,
@@ -235,6 +253,7 @@ static int sony_laptop_input_index[] = {
235 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ 253 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
236 -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ 254 -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
237 58, /* 72 SONYPI_EVENT_MEDIA_PRESSED */ 255 58, /* 72 SONYPI_EVENT_MEDIA_PRESSED */
256 59, /* 72 SONYPI_EVENT_VENDOR_PRESSED */
238}; 257};
239 258
240static int sony_laptop_input_keycode_map[] = { 259static int sony_laptop_input_keycode_map[] = {
@@ -297,6 +316,7 @@ static int sony_laptop_input_keycode_map[] = {
297 KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ 316 KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
298 KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ 317 KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
299 KEY_MEDIA, /* 58 SONYPI_EVENT_MEDIA_PRESSED */ 318 KEY_MEDIA, /* 58 SONYPI_EVENT_MEDIA_PRESSED */
319 KEY_VENDOR, /* 59 SONYPI_EVENT_VENDOR_PRESSED */
300}; 320};
301 321
302/* release buttons after a short delay if pressed */ 322/* release buttons after a short delay if pressed */
@@ -400,7 +420,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
400 error = kfifo_alloc(&sony_laptop_input.fifo, 420 error = kfifo_alloc(&sony_laptop_input.fifo,
401 SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); 421 SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
402 if (error) { 422 if (error) {
403 printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); 423 pr_err("kfifo_alloc failed\n");
404 goto err_dec_users; 424 goto err_dec_users;
405 } 425 }
406 426
@@ -589,7 +609,7 @@ struct sony_nc_value {
589 int value; /* current setting */ 609 int value; /* current setting */
590 int valid; /* Has ever been set */ 610 int valid; /* Has ever been set */
591 int debug; /* active only in debug mode ? */ 611 int debug; /* active only in debug mode ? */
592 struct device_attribute devattr; /* sysfs atribute */ 612 struct device_attribute devattr; /* sysfs attribute */
593}; 613};
594 614
595#define SNC_HANDLE_NAMES(_name, _values...) \ 615#define SNC_HANDLE_NAMES(_name, _values...) \
@@ -684,7 +704,7 @@ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
684 return 0; 704 return 0;
685 } 705 }
686 706
687 printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n"); 707 pr_warn("acpi_callreadfunc failed\n");
688 708
689 return -1; 709 return -1;
690} 710}
@@ -710,8 +730,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
710 if (status == AE_OK) { 730 if (status == AE_OK) {
711 if (result != NULL) { 731 if (result != NULL) {
712 if (out_obj.type != ACPI_TYPE_INTEGER) { 732 if (out_obj.type != ACPI_TYPE_INTEGER) {
713 printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad " 733 pr_warn("acpi_evaluate_object bad return type\n");
714 "return type\n");
715 return -1; 734 return -1;
716 } 735 }
717 *result = out_obj.integer.value; 736 *result = out_obj.integer.value;
@@ -719,34 +738,111 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
719 return 0; 738 return 0;
720 } 739 }
721 740
722 printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n"); 741 pr_warn("acpi_evaluate_object failed\n");
723 742
724 return -1; 743 return -1;
725} 744}
726 745
727static int sony_find_snc_handle(int handle) 746struct sony_nc_handles {
747 u16 cap[0x10];
748 struct device_attribute devattr;
749};
750
751static struct sony_nc_handles *handles;
752
753static ssize_t sony_nc_handles_show(struct device *dev,
754 struct device_attribute *attr, char *buffer)
755{
756 ssize_t len = 0;
757 int i;
758
759 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
760 len += snprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ",
761 handles->cap[i]);
762 }
763 len += snprintf(buffer + len, PAGE_SIZE - len, "\n");
764
765 return len;
766}
767
768static int sony_nc_handles_setup(struct platform_device *pd)
728{ 769{
729 int i; 770 int i;
730 int result; 771 int result;
731 772
732 for (i = 0x20; i < 0x30; i++) { 773 handles = kzalloc(sizeof(*handles), GFP_KERNEL);
733 acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result); 774 if (!handles)
734 if (result == handle) 775 return -ENOMEM;
735 return i-0x20; 776
777 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
778 if (!acpi_callsetfunc(sony_nc_acpi_handle,
779 "SN00", i + 0x20, &result)) {
780 dprintk("caching handle 0x%.4x (offset: 0x%.2x)\n",
781 result, i);
782 handles->cap[i] = result;
783 }
784 }
785
786 if (debug) {
787 sysfs_attr_init(&handles->devattr.attr);
788 handles->devattr.attr.name = "handles";
789 handles->devattr.attr.mode = S_IRUGO;
790 handles->devattr.show = sony_nc_handles_show;
791
792 /* allow reading capabilities via sysfs */
793 if (device_create_file(&pd->dev, &handles->devattr)) {
794 kfree(handles);
795 handles = NULL;
796 return -1;
797 }
798 }
799
800 return 0;
801}
802
803static int sony_nc_handles_cleanup(struct platform_device *pd)
804{
805 if (handles) {
806 if (debug)
807 device_remove_file(&pd->dev, &handles->devattr);
808 kfree(handles);
809 handles = NULL;
736 } 810 }
811 return 0;
812}
813
814static int sony_find_snc_handle(int handle)
815{
816 int i;
817
818 /* not initialized yet, return early */
819 if (!handles)
820 return -1;
737 821
822 for (i = 0; i < 0x10; i++) {
823 if (handles->cap[i] == handle) {
824 dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
825 handle, i);
826 return i;
827 }
828 }
829 dprintk("handle 0x%.4x not found\n", handle);
738 return -1; 830 return -1;
739} 831}
740 832
741static int sony_call_snc_handle(int handle, int argument, int *result) 833static int sony_call_snc_handle(int handle, int argument, int *result)
742{ 834{
835 int ret = 0;
743 int offset = sony_find_snc_handle(handle); 836 int offset = sony_find_snc_handle(handle);
744 837
745 if (offset < 0) 838 if (offset < 0)
746 return -1; 839 return -1;
747 840
748 return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument, 841 ret = acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
749 result); 842 result);
843 dprintk("called SN07 with 0x%.4x (result: 0x%.4x)\n", offset | argument,
844 *result);
845 return ret;
750} 846}
751 847
752/* 848/*
@@ -839,6 +935,14 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
839/* 935/*
840 * Backlight device 936 * Backlight device
841 */ 937 */
938struct sony_backlight_props {
939 struct backlight_device *dev;
940 int handle;
941 u8 offset;
942 u8 maxlvl;
943};
944struct sony_backlight_props sony_bl_props;
945
842static int sony_backlight_update_status(struct backlight_device *bd) 946static int sony_backlight_update_status(struct backlight_device *bd)
843{ 947{
844 return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", 948 return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT",
@@ -855,11 +959,40 @@ static int sony_backlight_get_brightness(struct backlight_device *bd)
855 return value - 1; 959 return value - 1;
856} 960}
857 961
858static struct backlight_device *sony_backlight_device; 962static int sony_nc_get_brightness_ng(struct backlight_device *bd)
859static struct backlight_ops sony_backlight_ops = { 963{
964 int result;
965 struct sony_backlight_props *sdev =
966 (struct sony_backlight_props *)bl_get_data(bd);
967
968 sony_call_snc_handle(sdev->handle, 0x0200, &result);
969
970 return (result & 0xff) - sdev->offset;
971}
972
973static int sony_nc_update_status_ng(struct backlight_device *bd)
974{
975 int value, result;
976 struct sony_backlight_props *sdev =
977 (struct sony_backlight_props *)bl_get_data(bd);
978
979 value = bd->props.brightness + sdev->offset;
980 if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result))
981 return -EIO;
982
983 return value;
984}
985
986static const struct backlight_ops sony_backlight_ops = {
987 .options = BL_CORE_SUSPENDRESUME,
860 .update_status = sony_backlight_update_status, 988 .update_status = sony_backlight_update_status,
861 .get_brightness = sony_backlight_get_brightness, 989 .get_brightness = sony_backlight_get_brightness,
862}; 990};
991static const struct backlight_ops sony_backlight_ng_ops = {
992 .options = BL_CORE_SUSPENDRESUME,
993 .update_status = sony_nc_update_status_ng,
994 .get_brightness = sony_nc_get_brightness_ng,
995};
863 996
864/* 997/*
865 * New SNC-only Vaios event mapping to driver known keys 998 * New SNC-only Vaios event mapping to driver known keys
@@ -894,10 +1027,18 @@ static struct sony_nc_event sony_100_events[] = {
894 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, 1027 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
895 { 0x8C, SONYPI_EVENT_FNKEY_F12 }, 1028 { 0x8C, SONYPI_EVENT_FNKEY_F12 },
896 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, 1029 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
1030 { 0x9d, SONYPI_EVENT_ZOOM_PRESSED },
1031 { 0x1d, SONYPI_EVENT_ANYBUTTON_RELEASED },
897 { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, 1032 { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
898 { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1033 { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
899 { 0xa1, SONYPI_EVENT_MEDIA_PRESSED }, 1034 { 0xa1, SONYPI_EVENT_MEDIA_PRESSED },
900 { 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1035 { 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED },
1036 { 0xa4, SONYPI_EVENT_CD_EJECT_PRESSED },
1037 { 0x24, SONYPI_EVENT_ANYBUTTON_RELEASED },
1038 { 0xa5, SONYPI_EVENT_VENDOR_PRESSED },
1039 { 0x25, SONYPI_EVENT_ANYBUTTON_RELEASED },
1040 { 0xa6, SONYPI_EVENT_HELP_PRESSED },
1041 { 0x26, SONYPI_EVENT_ANYBUTTON_RELEASED },
901 { 0, 0 }, 1042 { 0, 0 },
902}; 1043};
903 1044
@@ -962,10 +1103,8 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
962 } 1103 }
963 1104
964 if (!key_event->data) 1105 if (!key_event->data)
965 printk(KERN_INFO DRV_PFX 1106 pr_info("Unknown event: 0x%x 0x%x\n",
966 "Unknown event: 0x%x 0x%x\n", 1107 key_handle, ev);
967 key_handle,
968 ev);
969 else 1108 else
970 sony_laptop_report_input_event(ev); 1109 sony_laptop_report_input_event(ev);
971 } 1110 }
@@ -986,7 +1125,7 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
986 struct acpi_device_info *info; 1125 struct acpi_device_info *info;
987 1126
988 if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { 1127 if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
989 printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", 1128 pr_warn("method: name: %4.4s, args %X\n",
990 (char *)&info->name, info->param_count); 1129 (char *)&info->name, info->param_count);
991 1130
992 kfree(info); 1131 kfree(info);
@@ -1027,7 +1166,7 @@ static int sony_nc_resume(struct acpi_device *device)
1027 ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, 1166 ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset,
1028 item->value, NULL); 1167 item->value, NULL);
1029 if (ret < 0) { 1168 if (ret < 0) {
1030 printk("%s: %d\n", __func__, ret); 1169 pr_err("%s: %d\n", __func__, ret);
1031 break; 1170 break;
1032 } 1171 }
1033 } 1172 }
@@ -1044,14 +1183,12 @@ static int sony_nc_resume(struct acpi_device *device)
1044 sony_nc_function_setup(device); 1183 sony_nc_function_setup(device);
1045 } 1184 }
1046 1185
1047 /* set the last requested brightness level */
1048 if (sony_backlight_device &&
1049 sony_backlight_update_status(sony_backlight_device) < 0)
1050 printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
1051
1052 /* re-read rfkill state */ 1186 /* re-read rfkill state */
1053 sony_nc_rfkill_update(); 1187 sony_nc_rfkill_update();
1054 1188
1189 /* restore kbd backlight states */
1190 sony_nc_kbd_backlight_resume();
1191
1055 return 0; 1192 return 0;
1056} 1193}
1057 1194
@@ -1131,7 +1268,7 @@ static int sony_nc_setup_rfkill(struct acpi_device *device,
1131 return err; 1268 return err;
1132} 1269}
1133 1270
1134static void sony_nc_rfkill_update() 1271static void sony_nc_rfkill_update(void)
1135{ 1272{
1136 enum sony_nc_rfkill i; 1273 enum sony_nc_rfkill i;
1137 int result; 1274 int result;
@@ -1196,11 +1333,11 @@ static void sony_nc_rfkill_setup(struct acpi_device *device)
1196 1333
1197 device_enum = (union acpi_object *) buffer.pointer; 1334 device_enum = (union acpi_object *) buffer.pointer;
1198 if (!device_enum) { 1335 if (!device_enum) {
1199 pr_err("Invalid SN06 return object\n"); 1336 pr_err("No SN06 return object\n");
1200 goto out_no_enum; 1337 goto out_no_enum;
1201 } 1338 }
1202 if (device_enum->type != ACPI_TYPE_BUFFER) { 1339 if (device_enum->type != ACPI_TYPE_BUFFER) {
1203 pr_err("Invalid SN06 return object type 0x%.2x\n", 1340 pr_err("Invalid SN06 return object 0x%.2x\n",
1204 device_enum->type); 1341 device_enum->type);
1205 goto out_no_enum; 1342 goto out_no_enum;
1206 } 1343 }
@@ -1235,6 +1372,306 @@ out_no_enum:
1235 return; 1372 return;
1236} 1373}
1237 1374
1375/* Keyboard backlight feature */
1376#define KBDBL_HANDLER 0x137
1377#define KBDBL_PRESENT 0xB00
1378#define SET_MODE 0xC00
1379#define SET_STATE 0xD00
1380#define SET_TIMEOUT 0xE00
1381
1382struct kbd_backlight {
1383 int mode;
1384 int timeout;
1385 struct device_attribute mode_attr;
1386 struct device_attribute timeout_attr;
1387};
1388
1389static struct kbd_backlight *kbdbl_handle;
1390
1391static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
1392{
1393 int result;
1394
1395 if (value > 1)
1396 return -EINVAL;
1397
1398 if (sony_call_snc_handle(KBDBL_HANDLER,
1399 (value << 0x10) | SET_MODE, &result))
1400 return -EIO;
1401
1402 /* Try to turn the light on/off immediately */
1403 sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE,
1404 &result);
1405
1406 kbdbl_handle->mode = value;
1407
1408 return 0;
1409}
1410
1411static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev,
1412 struct device_attribute *attr,
1413 const char *buffer, size_t count)
1414{
1415 int ret = 0;
1416 unsigned long value;
1417
1418 if (count > 31)
1419 return -EINVAL;
1420
1421 if (strict_strtoul(buffer, 10, &value))
1422 return -EINVAL;
1423
1424 ret = __sony_nc_kbd_backlight_mode_set(value);
1425 if (ret < 0)
1426 return ret;
1427
1428 return count;
1429}
1430
1431static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev,
1432 struct device_attribute *attr, char *buffer)
1433{
1434 ssize_t count = 0;
1435 count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->mode);
1436 return count;
1437}
1438
1439static int __sony_nc_kbd_backlight_timeout_set(u8 value)
1440{
1441 int result;
1442
1443 if (value > 3)
1444 return -EINVAL;
1445
1446 if (sony_call_snc_handle(KBDBL_HANDLER,
1447 (value << 0x10) | SET_TIMEOUT, &result))
1448 return -EIO;
1449
1450 kbdbl_handle->timeout = value;
1451
1452 return 0;
1453}
1454
1455static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev,
1456 struct device_attribute *attr,
1457 const char *buffer, size_t count)
1458{
1459 int ret = 0;
1460 unsigned long value;
1461
1462 if (count > 31)
1463 return -EINVAL;
1464
1465 if (strict_strtoul(buffer, 10, &value))
1466 return -EINVAL;
1467
1468 ret = __sony_nc_kbd_backlight_timeout_set(value);
1469 if (ret < 0)
1470 return ret;
1471
1472 return count;
1473}
1474
1475static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev,
1476 struct device_attribute *attr, char *buffer)
1477{
1478 ssize_t count = 0;
1479 count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->timeout);
1480 return count;
1481}
1482
1483static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
1484{
1485 int result;
1486
1487 if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result))
1488 return 0;
1489 if (!(result & 0x02))
1490 return 0;
1491
1492 kbdbl_handle = kzalloc(sizeof(*kbdbl_handle), GFP_KERNEL);
1493 if (!kbdbl_handle)
1494 return -ENOMEM;
1495
1496 sysfs_attr_init(&kbdbl_handle->mode_attr.attr);
1497 kbdbl_handle->mode_attr.attr.name = "kbd_backlight";
1498 kbdbl_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR;
1499 kbdbl_handle->mode_attr.show = sony_nc_kbd_backlight_mode_show;
1500 kbdbl_handle->mode_attr.store = sony_nc_kbd_backlight_mode_store;
1501
1502 sysfs_attr_init(&kbdbl_handle->timeout_attr.attr);
1503 kbdbl_handle->timeout_attr.attr.name = "kbd_backlight_timeout";
1504 kbdbl_handle->timeout_attr.attr.mode = S_IRUGO | S_IWUSR;
1505 kbdbl_handle->timeout_attr.show = sony_nc_kbd_backlight_timeout_show;
1506 kbdbl_handle->timeout_attr.store = sony_nc_kbd_backlight_timeout_store;
1507
1508 if (device_create_file(&pd->dev, &kbdbl_handle->mode_attr))
1509 goto outkzalloc;
1510
1511 if (device_create_file(&pd->dev, &kbdbl_handle->timeout_attr))
1512 goto outmode;
1513
1514 __sony_nc_kbd_backlight_mode_set(kbd_backlight);
1515 __sony_nc_kbd_backlight_timeout_set(kbd_backlight_timeout);
1516
1517 return 0;
1518
1519outmode:
1520 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
1521outkzalloc:
1522 kfree(kbdbl_handle);
1523 kbdbl_handle = NULL;
1524 return -1;
1525}
1526
1527static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
1528{
1529 if (kbdbl_handle) {
1530 int result;
1531
1532 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
1533 device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
1534
1535 /* restore the default hw behaviour */
1536 sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result);
1537 sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result);
1538
1539 kfree(kbdbl_handle);
1540 }
1541 return 0;
1542}
1543
1544static void sony_nc_kbd_backlight_resume(void)
1545{
1546 int ignore = 0;
1547
1548 if (!kbdbl_handle)
1549 return;
1550
1551 if (kbdbl_handle->mode == 0)
1552 sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore);
1553
1554 if (kbdbl_handle->timeout != 0)
1555 sony_call_snc_handle(KBDBL_HANDLER,
1556 (kbdbl_handle->timeout << 0x10) | SET_TIMEOUT,
1557 &ignore);
1558}
1559
1560static void sony_nc_backlight_ng_read_limits(int handle,
1561 struct sony_backlight_props *props)
1562{
1563 int offset;
1564 acpi_status status;
1565 u8 brlvl, i;
1566 u8 min = 0xff, max = 0x00;
1567 struct acpi_object_list params;
1568 union acpi_object in_obj;
1569 union acpi_object *lvl_enum;
1570 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1571
1572 props->handle = handle;
1573 props->offset = 0;
1574 props->maxlvl = 0xff;
1575
1576 offset = sony_find_snc_handle(handle);
1577 if (offset < 0)
1578 return;
1579
1580 /* try to read the boundaries from ACPI tables, if we fail the above
1581 * defaults should be reasonable
1582 */
1583 params.count = 1;
1584 params.pointer = &in_obj;
1585 in_obj.type = ACPI_TYPE_INTEGER;
1586 in_obj.integer.value = offset;
1587 status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", &params,
1588 &buffer);
1589 if (ACPI_FAILURE(status))
1590 return;
1591
1592 lvl_enum = (union acpi_object *) buffer.pointer;
1593 if (!lvl_enum) {
1594 pr_err("No SN06 return object.");
1595 return;
1596 }
1597 if (lvl_enum->type != ACPI_TYPE_BUFFER) {
1598 pr_err("Invalid SN06 return object 0x%.2x\n",
1599 lvl_enum->type);
1600 goto out_invalid;
1601 }
1602
1603 /* the buffer lists brightness levels available, brightness levels are
1604 * from 0 to 8 in the array, other values are used by ALS control.
1605 */
1606 for (i = 0; i < 9 && i < lvl_enum->buffer.length; i++) {
1607
1608 brlvl = *(lvl_enum->buffer.pointer + i);
1609 dprintk("Brightness level: %d\n", brlvl);
1610
1611 if (!brlvl)
1612 break;
1613
1614 if (brlvl > max)
1615 max = brlvl;
1616 if (brlvl < min)
1617 min = brlvl;
1618 }
1619 props->offset = min;
1620 props->maxlvl = max;
1621 dprintk("Brightness levels: min=%d max=%d\n", props->offset,
1622 props->maxlvl);
1623
1624out_invalid:
1625 kfree(buffer.pointer);
1626 return;
1627}
1628
1629static void sony_nc_backlight_setup(void)
1630{
1631 acpi_handle unused;
1632 int max_brightness = 0;
1633 const struct backlight_ops *ops = NULL;
1634 struct backlight_properties props;
1635
1636 if (sony_find_snc_handle(0x12f) != -1) {
1637 ops = &sony_backlight_ng_ops;
1638 sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props);
1639 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
1640
1641 } else if (sony_find_snc_handle(0x137) != -1) {
1642 ops = &sony_backlight_ng_ops;
1643 sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props);
1644 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
1645
1646 } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
1647 &unused))) {
1648 ops = &sony_backlight_ops;
1649 max_brightness = SONY_MAX_BRIGHTNESS - 1;
1650
1651 } else
1652 return;
1653
1654 memset(&props, 0, sizeof(struct backlight_properties));
1655 props.type = BACKLIGHT_PLATFORM;
1656 props.max_brightness = max_brightness;
1657 sony_bl_props.dev = backlight_device_register("sony", NULL,
1658 &sony_bl_props,
1659 ops, &props);
1660
1661 if (IS_ERR(sony_bl_props.dev)) {
1662 pr_warn("unable to register backlight device\n");
1663 sony_bl_props.dev = NULL;
1664 } else
1665 sony_bl_props.dev->props.brightness =
1666 ops->get_brightness(sony_bl_props.dev);
1667}
1668
1669static void sony_nc_backlight_cleanup(void)
1670{
1671 if (sony_bl_props.dev)
1672 backlight_device_unregister(sony_bl_props.dev);
1673}
1674
1238static int sony_nc_add(struct acpi_device *device) 1675static int sony_nc_add(struct acpi_device *device)
1239{ 1676{
1240 acpi_status status; 1677 acpi_status status;
@@ -1242,8 +1679,7 @@ static int sony_nc_add(struct acpi_device *device)
1242 acpi_handle handle; 1679 acpi_handle handle;
1243 struct sony_nc_value *item; 1680 struct sony_nc_value *item;
1244 1681
1245 printk(KERN_INFO DRV_PFX "%s v%s.\n", 1682 pr_info("%s v%s\n", SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
1246 SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
1247 1683
1248 sony_nc_acpi_device = device; 1684 sony_nc_acpi_device = device;
1249 strcpy(acpi_device_class(device), "sony/hotkey"); 1685 strcpy(acpi_device_class(device), "sony/hotkey");
@@ -1259,13 +1695,18 @@ static int sony_nc_add(struct acpi_device *device)
1259 goto outwalk; 1695 goto outwalk;
1260 } 1696 }
1261 1697
1698 result = sony_pf_add();
1699 if (result)
1700 goto outpresent;
1701
1262 if (debug) { 1702 if (debug) {
1263 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, 1703 status = acpi_walk_namespace(ACPI_TYPE_METHOD,
1264 1, sony_walk_callback, NULL, NULL, NULL); 1704 sony_nc_acpi_handle, 1, sony_walk_callback,
1705 NULL, NULL, NULL);
1265 if (ACPI_FAILURE(status)) { 1706 if (ACPI_FAILURE(status)) {
1266 printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n"); 1707 pr_warn("unable to walk acpi resources\n");
1267 result = -ENODEV; 1708 result = -ENODEV;
1268 goto outwalk; 1709 goto outpresent;
1269 } 1710 }
1270 } 1711 }
1271 1712
@@ -1278,6 +1719,12 @@ static int sony_nc_add(struct acpi_device *device)
1278 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", 1719 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
1279 &handle))) { 1720 &handle))) {
1280 dprintk("Doing SNC setup\n"); 1721 dprintk("Doing SNC setup\n");
1722 result = sony_nc_handles_setup(sony_pf_device);
1723 if (result)
1724 goto outpresent;
1725 result = sony_nc_kbd_backlight_setup(sony_pf_device);
1726 if (result)
1727 goto outsnc;
1281 sony_nc_function_setup(device); 1728 sony_nc_function_setup(device);
1282 sony_nc_rfkill_setup(device); 1729 sony_nc_rfkill_setup(device);
1283 } 1730 }
@@ -1285,39 +1732,16 @@ static int sony_nc_add(struct acpi_device *device)
1285 /* setup input devices and helper fifo */ 1732 /* setup input devices and helper fifo */
1286 result = sony_laptop_setup_input(device); 1733 result = sony_laptop_setup_input(device);
1287 if (result) { 1734 if (result) {
1288 printk(KERN_ERR DRV_PFX 1735 pr_err("Unable to create input devices\n");
1289 "Unable to create input devices.\n"); 1736 goto outkbdbacklight;
1290 goto outwalk;
1291 } 1737 }
1292 1738
1293 if (acpi_video_backlight_support()) { 1739 if (acpi_video_backlight_support()) {
1294 printk(KERN_INFO DRV_PFX "brightness ignored, must be " 1740 pr_info("brightness ignored, must be controlled by ACPI video driver\n");
1295 "controlled by ACPI video driver\n"); 1741 } else {
1296 } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", 1742 sony_nc_backlight_setup();
1297 &handle))) {
1298 struct backlight_properties props;
1299 memset(&props, 0, sizeof(struct backlight_properties));
1300 props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
1301 sony_backlight_device = backlight_device_register("sony", NULL,
1302 NULL,
1303 &sony_backlight_ops,
1304 &props);
1305
1306 if (IS_ERR(sony_backlight_device)) {
1307 printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
1308 sony_backlight_device = NULL;
1309 } else {
1310 sony_backlight_device->props.brightness =
1311 sony_backlight_get_brightness
1312 (sony_backlight_device);
1313 }
1314
1315 } 1743 }
1316 1744
1317 result = sony_pf_add();
1318 if (result)
1319 goto outbacklight;
1320
1321 /* create sony_pf sysfs attributes related to the SNC device */ 1745 /* create sony_pf sysfs attributes related to the SNC device */
1322 for (item = sony_nc_values; item->name; ++item) { 1746 for (item = sony_nc_values; item->name; ++item) {
1323 1747
@@ -1363,14 +1787,19 @@ static int sony_nc_add(struct acpi_device *device)
1363 for (item = sony_nc_values; item->name; ++item) { 1787 for (item = sony_nc_values; item->name; ++item) {
1364 device_remove_file(&sony_pf_device->dev, &item->devattr); 1788 device_remove_file(&sony_pf_device->dev, &item->devattr);
1365 } 1789 }
1366 sony_pf_remove(); 1790 sony_nc_backlight_cleanup();
1367
1368 outbacklight:
1369 if (sony_backlight_device)
1370 backlight_device_unregister(sony_backlight_device);
1371 1791
1372 sony_laptop_remove_input(); 1792 sony_laptop_remove_input();
1373 1793
1794 outkbdbacklight:
1795 sony_nc_kbd_backlight_cleanup(sony_pf_device);
1796
1797 outsnc:
1798 sony_nc_handles_cleanup(sony_pf_device);
1799
1800 outpresent:
1801 sony_pf_remove();
1802
1374 outwalk: 1803 outwalk:
1375 sony_nc_rfkill_cleanup(); 1804 sony_nc_rfkill_cleanup();
1376 return result; 1805 return result;
@@ -1380,8 +1809,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
1380{ 1809{
1381 struct sony_nc_value *item; 1810 struct sony_nc_value *item;
1382 1811
1383 if (sony_backlight_device) 1812 sony_nc_backlight_cleanup();
1384 backlight_device_unregister(sony_backlight_device);
1385 1813
1386 sony_nc_acpi_device = NULL; 1814 sony_nc_acpi_device = NULL;
1387 1815
@@ -1389,6 +1817,8 @@ static int sony_nc_remove(struct acpi_device *device, int type)
1389 device_remove_file(&sony_pf_device->dev, &item->devattr); 1817 device_remove_file(&sony_pf_device->dev, &item->devattr);
1390 } 1818 }
1391 1819
1820 sony_nc_kbd_backlight_cleanup(sony_pf_device);
1821 sony_nc_handles_cleanup(sony_pf_device);
1392 sony_pf_remove(); 1822 sony_pf_remove();
1393 sony_laptop_remove_input(); 1823 sony_laptop_remove_input();
1394 sony_nc_rfkill_cleanup(); 1824 sony_nc_rfkill_cleanup();
@@ -1427,7 +1857,6 @@ static struct acpi_driver sony_nc_driver = {
1427#define SONYPI_DEVICE_TYPE1 0x00000001 1857#define SONYPI_DEVICE_TYPE1 0x00000001
1428#define SONYPI_DEVICE_TYPE2 0x00000002 1858#define SONYPI_DEVICE_TYPE2 0x00000002
1429#define SONYPI_DEVICE_TYPE3 0x00000004 1859#define SONYPI_DEVICE_TYPE3 0x00000004
1430#define SONYPI_DEVICE_TYPE4 0x00000008
1431 1860
1432#define SONYPI_TYPE1_OFFSET 0x04 1861#define SONYPI_TYPE1_OFFSET 0x04
1433#define SONYPI_TYPE2_OFFSET 0x12 1862#define SONYPI_TYPE2_OFFSET 0x12
@@ -1573,8 +2002,8 @@ static struct sonypi_event sonypi_blueev[] = {
1573 2002
1574/* The set of possible wireless events */ 2003/* The set of possible wireless events */
1575static struct sonypi_event sonypi_wlessev[] = { 2004static struct sonypi_event sonypi_wlessev[] = {
1576 { 0x59, SONYPI_EVENT_WIRELESS_ON }, 2005 { 0x59, SONYPI_EVENT_IGNORE },
1577 { 0x5a, SONYPI_EVENT_WIRELESS_OFF }, 2006 { 0x5a, SONYPI_EVENT_IGNORE },
1578 { 0, 0 } 2007 { 0, 0 }
1579}; 2008};
1580 2009
@@ -1831,9 +2260,9 @@ out:
1831 if (pcidev) 2260 if (pcidev)
1832 pci_dev_put(pcidev); 2261 pci_dev_put(pcidev);
1833 2262
1834 printk(KERN_INFO DRV_PFX "detected Type%d model\n", 2263 pr_info("detected Type%d model\n",
1835 dev->model == SONYPI_DEVICE_TYPE1 ? 1 : 2264 dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
1836 dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); 2265 dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
1837} 2266}
1838 2267
1839/* camera tests and poweron/poweroff */ 2268/* camera tests and poweron/poweroff */
@@ -1879,7 +2308,7 @@ static int __sony_pic_camera_ready(void)
1879static int __sony_pic_camera_off(void) 2308static int __sony_pic_camera_off(void)
1880{ 2309{
1881 if (!camera) { 2310 if (!camera) {
1882 printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); 2311 pr_warn("camera control not enabled\n");
1883 return -ENODEV; 2312 return -ENODEV;
1884 } 2313 }
1885 2314
@@ -1899,7 +2328,7 @@ static int __sony_pic_camera_on(void)
1899 int i, j, x; 2328 int i, j, x;
1900 2329
1901 if (!camera) { 2330 if (!camera) {
1902 printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); 2331 pr_warn("camera control not enabled\n");
1903 return -ENODEV; 2332 return -ENODEV;
1904 } 2333 }
1905 2334
@@ -1922,7 +2351,7 @@ static int __sony_pic_camera_on(void)
1922 } 2351 }
1923 2352
1924 if (j == 0) { 2353 if (j == 0) {
1925 printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); 2354 pr_warn("failed to power on camera\n");
1926 return -ENODEV; 2355 return -ENODEV;
1927 } 2356 }
1928 2357
@@ -1978,8 +2407,7 @@ int sony_pic_camera_command(int command, u8 value)
1978 ITERATIONS_SHORT); 2407 ITERATIONS_SHORT);
1979 break; 2408 break;
1980 default: 2409 default:
1981 printk(KERN_ERR DRV_PFX "sony_pic_camera_command invalid: %d\n", 2410 pr_err("sony_pic_camera_command invalid: %d\n", command);
1982 command);
1983 break; 2411 break;
1984 } 2412 }
1985 mutex_unlock(&spic_dev.lock); 2413 mutex_unlock(&spic_dev.lock);
@@ -2236,7 +2664,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
2236 mutex_lock(&spic_dev.lock); 2664 mutex_lock(&spic_dev.lock);
2237 switch (cmd) { 2665 switch (cmd) {
2238 case SONYPI_IOCGBRT: 2666 case SONYPI_IOCGBRT:
2239 if (sony_backlight_device == NULL) { 2667 if (sony_bl_props.dev == NULL) {
2240 ret = -EIO; 2668 ret = -EIO;
2241 break; 2669 break;
2242 } 2670 }
@@ -2249,7 +2677,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
2249 ret = -EFAULT; 2677 ret = -EFAULT;
2250 break; 2678 break;
2251 case SONYPI_IOCSBRT: 2679 case SONYPI_IOCSBRT:
2252 if (sony_backlight_device == NULL) { 2680 if (sony_bl_props.dev == NULL) {
2253 ret = -EIO; 2681 ret = -EIO;
2254 break; 2682 break;
2255 } 2683 }
@@ -2263,8 +2691,8 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
2263 break; 2691 break;
2264 } 2692 }
2265 /* sync the backlight device status */ 2693 /* sync the backlight device status */
2266 sony_backlight_device->props.brightness = 2694 sony_bl_props.dev->props.brightness =
2267 sony_backlight_get_brightness(sony_backlight_device); 2695 sony_backlight_get_brightness(sony_bl_props.dev);
2268 break; 2696 break;
2269 case SONYPI_IOCGBAT1CAP: 2697 case SONYPI_IOCGBAT1CAP:
2270 if (ec_read16(SONYPI_BAT1_FULL, &val16)) { 2698 if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
@@ -2360,6 +2788,7 @@ static const struct file_operations sonypi_misc_fops = {
2360 .release = sonypi_misc_release, 2788 .release = sonypi_misc_release,
2361 .fasync = sonypi_misc_fasync, 2789 .fasync = sonypi_misc_fasync,
2362 .unlocked_ioctl = sonypi_misc_ioctl, 2790 .unlocked_ioctl = sonypi_misc_ioctl,
2791 .llseek = noop_llseek,
2363}; 2792};
2364 2793
2365static struct miscdevice sonypi_misc_device = { 2794static struct miscdevice sonypi_misc_device = {
@@ -2384,7 +2813,7 @@ static int sonypi_compat_init(void)
2384 error = 2813 error =
2385 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); 2814 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
2386 if (error) { 2815 if (error) {
2387 printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); 2816 pr_err("kfifo_alloc failed\n");
2388 return error; 2817 return error;
2389 } 2818 }
2390 2819
@@ -2394,12 +2823,12 @@ static int sonypi_compat_init(void)
2394 sonypi_misc_device.minor = minor; 2823 sonypi_misc_device.minor = minor;
2395 error = misc_register(&sonypi_misc_device); 2824 error = misc_register(&sonypi_misc_device);
2396 if (error) { 2825 if (error) {
2397 printk(KERN_ERR DRV_PFX "misc_register failed\n"); 2826 pr_err("misc_register failed\n");
2398 goto err_free_kfifo; 2827 goto err_free_kfifo;
2399 } 2828 }
2400 if (minor == -1) 2829 if (minor == -1)
2401 printk(KERN_INFO DRV_PFX "device allocated minor is %d\n", 2830 pr_info("device allocated minor is %d\n",
2402 sonypi_misc_device.minor); 2831 sonypi_misc_device.minor);
2403 2832
2404 return 0; 2833 return 0;
2405 2834
@@ -2458,9 +2887,8 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
2458 } 2887 }
2459 for (i = 0; i < p->interrupt_count; i++) { 2888 for (i = 0; i < p->interrupt_count; i++) {
2460 if (!p->interrupts[i]) { 2889 if (!p->interrupts[i]) {
2461 printk(KERN_WARNING DRV_PFX 2890 pr_warn("Invalid IRQ %d\n",
2462 "Invalid IRQ %d\n", 2891 p->interrupts[i]);
2463 p->interrupts[i]);
2464 continue; 2892 continue;
2465 } 2893 }
2466 interrupt = kzalloc(sizeof(*interrupt), 2894 interrupt = kzalloc(sizeof(*interrupt),
@@ -2498,14 +2926,14 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
2498 ioport->io2.address_length); 2926 ioport->io2.address_length);
2499 } 2927 }
2500 else { 2928 else {
2501 printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); 2929 pr_err("Unknown SPIC Type, more than 2 IO Ports\n");
2502 return AE_ERROR; 2930 return AE_ERROR;
2503 } 2931 }
2504 return AE_OK; 2932 return AE_OK;
2505 } 2933 }
2506 default: 2934 default:
2507 dprintk("Resource %d isn't an IRQ nor an IO port\n", 2935 dprintk("Resource %d isn't an IRQ nor an IO port\n",
2508 resource->type); 2936 resource->type);
2509 2937
2510 case ACPI_RESOURCE_TYPE_END_TAG: 2938 case ACPI_RESOURCE_TYPE_END_TAG:
2511 return AE_OK; 2939 return AE_OK;
@@ -2526,7 +2954,7 @@ static int sony_pic_possible_resources(struct acpi_device *device)
2526 dprintk("Evaluating _STA\n"); 2954 dprintk("Evaluating _STA\n");
2527 result = acpi_bus_get_status(device); 2955 result = acpi_bus_get_status(device);
2528 if (result) { 2956 if (result) {
2529 printk(KERN_WARNING DRV_PFX "Unable to read status\n"); 2957 pr_warn("Unable to read status\n");
2530 goto end; 2958 goto end;
2531 } 2959 }
2532 2960
@@ -2542,9 +2970,7 @@ static int sony_pic_possible_resources(struct acpi_device *device)
2542 status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, 2970 status = acpi_walk_resources(device->handle, METHOD_NAME__PRS,
2543 sony_pic_read_possible_resource, &spic_dev); 2971 sony_pic_read_possible_resource, &spic_dev);
2544 if (ACPI_FAILURE(status)) { 2972 if (ACPI_FAILURE(status)) {
2545 printk(KERN_WARNING DRV_PFX 2973 pr_warn("Failure evaluating %s\n", METHOD_NAME__PRS);
2546 "Failure evaluating %s\n",
2547 METHOD_NAME__PRS);
2548 result = -ENODEV; 2974 result = -ENODEV;
2549 } 2975 }
2550end: 2976end:
@@ -2657,7 +3083,7 @@ static int sony_pic_enable(struct acpi_device *device,
2657 3083
2658 /* check for total failure */ 3084 /* check for total failure */
2659 if (ACPI_FAILURE(status)) { 3085 if (ACPI_FAILURE(status)) {
2660 printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); 3086 pr_err("Error evaluating _SRS\n");
2661 result = -ENODEV; 3087 result = -ENODEV;
2662 goto end; 3088 goto end;
2663 } 3089 }
@@ -2713,6 +3139,9 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2713 if (ev == dev->event_types[i].events[j].data) { 3139 if (ev == dev->event_types[i].events[j].data) {
2714 device_event = 3140 device_event =
2715 dev->event_types[i].events[j].event; 3141 dev->event_types[i].events[j].event;
3142 /* some events may require ignoring */
3143 if (!device_event)
3144 return IRQ_HANDLED;
2716 goto found; 3145 goto found;
2717 } 3146 }
2718 } 3147 }
@@ -2732,7 +3161,6 @@ found:
2732 sony_laptop_report_input_event(device_event); 3161 sony_laptop_report_input_event(device_event);
2733 acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event); 3162 acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event);
2734 sonypi_compat_report_event(device_event); 3163 sonypi_compat_report_event(device_event);
2735
2736 return IRQ_HANDLED; 3164 return IRQ_HANDLED;
2737} 3165}
2738 3166
@@ -2747,7 +3175,7 @@ static int sony_pic_remove(struct acpi_device *device, int type)
2747 struct sony_pic_irq *irq, *tmp_irq; 3175 struct sony_pic_irq *irq, *tmp_irq;
2748 3176
2749 if (sony_pic_disable(device)) { 3177 if (sony_pic_disable(device)) {
2750 printk(KERN_ERR DRV_PFX "Couldn't disable device.\n"); 3178 pr_err("Couldn't disable device\n");
2751 return -ENXIO; 3179 return -ENXIO;
2752 } 3180 }
2753 3181
@@ -2787,8 +3215,7 @@ static int sony_pic_add(struct acpi_device *device)
2787 struct sony_pic_ioport *io, *tmp_io; 3215 struct sony_pic_ioport *io, *tmp_io;
2788 struct sony_pic_irq *irq, *tmp_irq; 3216 struct sony_pic_irq *irq, *tmp_irq;
2789 3217
2790 printk(KERN_INFO DRV_PFX "%s v%s.\n", 3218 pr_info("%s v%s\n", SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
2791 SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
2792 3219
2793 spic_dev.acpi_dev = device; 3220 spic_dev.acpi_dev = device;
2794 strcpy(acpi_device_class(device), "sony/hotkey"); 3221 strcpy(acpi_device_class(device), "sony/hotkey");
@@ -2798,16 +3225,14 @@ static int sony_pic_add(struct acpi_device *device)
2798 /* read _PRS resources */ 3225 /* read _PRS resources */
2799 result = sony_pic_possible_resources(device); 3226 result = sony_pic_possible_resources(device);
2800 if (result) { 3227 if (result) {
2801 printk(KERN_ERR DRV_PFX 3228 pr_err("Unable to read possible resources\n");
2802 "Unable to read possible resources.\n");
2803 goto err_free_resources; 3229 goto err_free_resources;
2804 } 3230 }
2805 3231
2806 /* setup input devices and helper fifo */ 3232 /* setup input devices and helper fifo */
2807 result = sony_laptop_setup_input(device); 3233 result = sony_laptop_setup_input(device);
2808 if (result) { 3234 if (result) {
2809 printk(KERN_ERR DRV_PFX 3235 pr_err("Unable to create input devices\n");
2810 "Unable to create input devices.\n");
2811 goto err_free_resources; 3236 goto err_free_resources;
2812 } 3237 }
2813 3238
@@ -2817,7 +3242,7 @@ static int sony_pic_add(struct acpi_device *device)
2817 /* request io port */ 3242 /* request io port */
2818 list_for_each_entry_reverse(io, &spic_dev.ioports, list) { 3243 list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
2819 if (request_region(io->io1.minimum, io->io1.address_length, 3244 if (request_region(io->io1.minimum, io->io1.address_length,
2820 "Sony Programable I/O Device")) { 3245 "Sony Programmable I/O Device")) {
2821 dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", 3246 dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
2822 io->io1.minimum, io->io1.maximum, 3247 io->io1.minimum, io->io1.maximum,
2823 io->io1.address_length); 3248 io->io1.address_length);
@@ -2825,7 +3250,7 @@ static int sony_pic_add(struct acpi_device *device)
2825 if (io->io2.minimum) { 3250 if (io->io2.minimum) {
2826 if (request_region(io->io2.minimum, 3251 if (request_region(io->io2.minimum,
2827 io->io2.address_length, 3252 io->io2.address_length,
2828 "Sony Programable I/O Device")) { 3253 "Sony Programmable I/O Device")) {
2829 dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", 3254 dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
2830 io->io2.minimum, io->io2.maximum, 3255 io->io2.minimum, io->io2.maximum,
2831 io->io2.address_length); 3256 io->io2.address_length);
@@ -2848,7 +3273,7 @@ static int sony_pic_add(struct acpi_device *device)
2848 } 3273 }
2849 } 3274 }
2850 if (!spic_dev.cur_ioport) { 3275 if (!spic_dev.cur_ioport) {
2851 printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); 3276 pr_err("Failed to request_region\n");
2852 result = -ENODEV; 3277 result = -ENODEV;
2853 goto err_remove_compat; 3278 goto err_remove_compat;
2854 } 3279 }
@@ -2868,7 +3293,7 @@ static int sony_pic_add(struct acpi_device *device)
2868 } 3293 }
2869 } 3294 }
2870 if (!spic_dev.cur_irq) { 3295 if (!spic_dev.cur_irq) {
2871 printk(KERN_ERR DRV_PFX "Failed to request_irq.\n"); 3296 pr_err("Failed to request_irq\n");
2872 result = -ENODEV; 3297 result = -ENODEV;
2873 goto err_release_region; 3298 goto err_release_region;
2874 } 3299 }
@@ -2876,7 +3301,7 @@ static int sony_pic_add(struct acpi_device *device)
2876 /* set resource status _SRS */ 3301 /* set resource status _SRS */
2877 result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); 3302 result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq);
2878 if (result) { 3303 if (result) {
2879 printk(KERN_ERR DRV_PFX "Couldn't enable device.\n"); 3304 pr_err("Couldn't enable device\n");
2880 goto err_free_irq; 3305 goto err_free_irq;
2881 } 3306 }
2882 3307
@@ -2985,8 +3410,7 @@ static int __init sony_laptop_init(void)
2985 if (!no_spic && dmi_check_system(sonypi_dmi_table)) { 3410 if (!no_spic && dmi_check_system(sonypi_dmi_table)) {
2986 result = acpi_bus_register_driver(&sony_pic_driver); 3411 result = acpi_bus_register_driver(&sony_pic_driver);
2987 if (result) { 3412 if (result) {
2988 printk(KERN_ERR DRV_PFX 3413 pr_err("Unable to register SPIC driver\n");
2989 "Unable to register SPIC driver.");
2990 goto out; 3414 goto out;
2991 } 3415 }
2992 spic_drv_registered = 1; 3416 spic_drv_registered = 1;
@@ -2994,7 +3418,7 @@ static int __init sony_laptop_init(void)
2994 3418
2995 result = acpi_bus_register_driver(&sony_nc_driver); 3419 result = acpi_bus_register_driver(&sony_nc_driver);
2996 if (result) { 3420 if (result) {
2997 printk(KERN_ERR DRV_PFX "Unable to register SNC driver."); 3421 pr_err("Unable to register SNC driver\n");
2998 goto out_unregister_pic; 3422 goto out_unregister_pic;
2999 } 3423 }
3000 3424