diff options
Diffstat (limited to 'drivers/platform/x86/sony-laptop.c')
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 660 |
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 { \ | 76 | do { \ |
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 | ||
130 | static int kbd_backlight; /* = 1 */ | ||
131 | module_param(kbd_backlight, int, 0444); | ||
132 | MODULE_PARM_DESC(kbd_backlight, | ||
133 | "set this to 0 to disable keyboard backlight, " | ||
134 | "1 to enable it (default: 0)"); | ||
135 | |||
136 | static int kbd_backlight_timeout; /* = 0 */ | ||
137 | module_param(kbd_backlight_timeout, int, 0444); | ||
138 | MODULE_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 | |||
143 | static void sony_nc_kbd_backlight_resume(void); | ||
144 | |||
127 | enum sony_nc_rfkill { | 145 | enum 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 | ||
240 | static int sony_laptop_input_keycode_map[] = { | 259 | static 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 | ||
727 | static int sony_find_snc_handle(int handle) | 746 | struct sony_nc_handles { |
747 | u16 cap[0x10]; | ||
748 | struct device_attribute devattr; | ||
749 | }; | ||
750 | |||
751 | static struct sony_nc_handles *handles; | ||
752 | |||
753 | static 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 | |||
768 | static 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 | |||
803 | static 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 | |||
814 | static 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 | ||
741 | static int sony_call_snc_handle(int handle, int argument, int *result) | 833 | static 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 | */ |
938 | struct sony_backlight_props { | ||
939 | struct backlight_device *dev; | ||
940 | int handle; | ||
941 | u8 offset; | ||
942 | u8 maxlvl; | ||
943 | }; | ||
944 | struct sony_backlight_props sony_bl_props; | ||
945 | |||
842 | static int sony_backlight_update_status(struct backlight_device *bd) | 946 | static 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 | ||
858 | static struct backlight_device *sony_backlight_device; | 962 | static int sony_nc_get_brightness_ng(struct backlight_device *bd) |
859 | static 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 | |||
973 | static 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 | |||
986 | static 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 | }; |
991 | static 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 | ||
1134 | static void sony_nc_rfkill_update() | 1271 | static 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 | |||
1382 | struct kbd_backlight { | ||
1383 | int mode; | ||
1384 | int timeout; | ||
1385 | struct device_attribute mode_attr; | ||
1386 | struct device_attribute timeout_attr; | ||
1387 | }; | ||
1388 | |||
1389 | static struct kbd_backlight *kbdbl_handle; | ||
1390 | |||
1391 | static 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 | |||
1411 | static 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 | |||
1431 | static 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 | |||
1439 | static 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 | |||
1455 | static 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 | |||
1475 | static 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 | |||
1483 | static 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 | |||
1519 | outmode: | ||
1520 | device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); | ||
1521 | outkzalloc: | ||
1522 | kfree(kbdbl_handle); | ||
1523 | kbdbl_handle = NULL; | ||
1524 | return -1; | ||
1525 | } | ||
1526 | |||
1527 | static 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 | |||
1544 | static 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 | |||
1560 | static 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", ¶ms, | ||
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 | |||
1624 | out_invalid: | ||
1625 | kfree(buffer.pointer); | ||
1626 | return; | ||
1627 | } | ||
1628 | |||
1629 | static 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 | |||
1669 | static void sony_nc_backlight_cleanup(void) | ||
1670 | { | ||
1671 | if (sony_bl_props.dev) | ||
1672 | backlight_device_unregister(sony_bl_props.dev); | ||
1673 | } | ||
1674 | |||
1238 | static int sony_nc_add(struct acpi_device *device) | 1675 | static 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 */ |
1575 | static struct sonypi_event sonypi_wlessev[] = { | 2004 | static 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) | |||
1879 | static int __sony_pic_camera_off(void) | 2308 | static 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 | ||
2365 | static struct miscdevice sonypi_misc_device = { | 2794 | static 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 | } |
2550 | end: | 2976 | end: |
@@ -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 | ||