diff options
| -rw-r--r-- | drivers/hid/wacom_wac.c | 250 |
1 files changed, 125 insertions, 125 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 037a9962d053..6b8f6b816195 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -773,131 +773,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 773 | return 0; | 773 | return 0; |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) | ||
| 777 | { | ||
| 778 | unsigned char *data = wacom_wac->data; | ||
| 779 | struct input_dev *input; | ||
| 780 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
| 781 | struct wacom_remote *remote = wacom->remote; | ||
| 782 | int bat_charging, bat_percent, touch_ring_mode; | ||
| 783 | __u32 serial; | ||
| 784 | int i, index = -1; | ||
| 785 | unsigned long flags; | ||
| 786 | |||
| 787 | if (data[0] != WACOM_REPORT_REMOTE) { | ||
| 788 | hid_dbg(wacom->hdev, "%s: received unknown report #%d", | ||
| 789 | __func__, data[0]); | ||
| 790 | return 0; | ||
| 791 | } | ||
| 792 | |||
| 793 | serial = data[3] + (data[4] << 8) + (data[5] << 16); | ||
| 794 | wacom_wac->id[0] = PAD_DEVICE_ID; | ||
| 795 | |||
| 796 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
| 797 | |||
| 798 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
| 799 | if (remote->remotes[i].serial == serial) { | ||
| 800 | index = i; | ||
| 801 | break; | ||
| 802 | } | ||
| 803 | } | ||
| 804 | |||
| 805 | if (index < 0 || !remote->remotes[index].registered) | ||
| 806 | goto out; | ||
| 807 | |||
| 808 | input = remote->remotes[index].input; | ||
| 809 | |||
| 810 | input_report_key(input, BTN_0, (data[9] & 0x01)); | ||
| 811 | input_report_key(input, BTN_1, (data[9] & 0x02)); | ||
| 812 | input_report_key(input, BTN_2, (data[9] & 0x04)); | ||
| 813 | input_report_key(input, BTN_3, (data[9] & 0x08)); | ||
| 814 | input_report_key(input, BTN_4, (data[9] & 0x10)); | ||
| 815 | input_report_key(input, BTN_5, (data[9] & 0x20)); | ||
| 816 | input_report_key(input, BTN_6, (data[9] & 0x40)); | ||
| 817 | input_report_key(input, BTN_7, (data[9] & 0x80)); | ||
| 818 | |||
| 819 | input_report_key(input, BTN_8, (data[10] & 0x01)); | ||
| 820 | input_report_key(input, BTN_9, (data[10] & 0x02)); | ||
| 821 | input_report_key(input, BTN_A, (data[10] & 0x04)); | ||
| 822 | input_report_key(input, BTN_B, (data[10] & 0x08)); | ||
| 823 | input_report_key(input, BTN_C, (data[10] & 0x10)); | ||
| 824 | input_report_key(input, BTN_X, (data[10] & 0x20)); | ||
| 825 | input_report_key(input, BTN_Y, (data[10] & 0x40)); | ||
| 826 | input_report_key(input, BTN_Z, (data[10] & 0x80)); | ||
| 827 | |||
| 828 | input_report_key(input, BTN_BASE, (data[11] & 0x01)); | ||
| 829 | input_report_key(input, BTN_BASE2, (data[11] & 0x02)); | ||
| 830 | |||
| 831 | if (data[12] & 0x80) | ||
| 832 | input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); | ||
| 833 | else | ||
| 834 | input_report_abs(input, ABS_WHEEL, 0); | ||
| 835 | |||
| 836 | bat_percent = data[7] & 0x7f; | ||
| 837 | bat_charging = !!(data[7] & 0x80); | ||
| 838 | |||
| 839 | if (data[9] | data[10] | (data[11] & 0x03) | data[12]) | ||
| 840 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
| 841 | else | ||
| 842 | input_report_abs(input, ABS_MISC, 0); | ||
| 843 | |||
| 844 | input_event(input, EV_MSC, MSC_SERIAL, serial); | ||
| 845 | |||
| 846 | input_sync(input); | ||
| 847 | |||
| 848 | /*Which mode select (LED light) is currently on?*/ | ||
| 849 | touch_ring_mode = (data[11] & 0xC0) >> 6; | ||
| 850 | |||
| 851 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
| 852 | if (remote->remotes[i].serial == serial) | ||
| 853 | wacom->led.groups[i].select = touch_ring_mode; | ||
| 854 | } | ||
| 855 | |||
| 856 | __wacom_notify_battery(&remote->remotes[index].battery, bat_percent, | ||
| 857 | bat_charging, 1, bat_charging); | ||
| 858 | |||
| 859 | out: | ||
| 860 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | |||
| 864 | static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) | ||
| 865 | { | ||
| 866 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
| 867 | unsigned char *data = wacom_wac->data; | ||
| 868 | struct wacom_remote *remote = wacom->remote; | ||
| 869 | struct wacom_remote_data remote_data; | ||
| 870 | unsigned long flags; | ||
| 871 | int i, ret; | ||
| 872 | |||
| 873 | if (data[0] != WACOM_REPORT_DEVICE_LIST) | ||
| 874 | return; | ||
| 875 | |||
| 876 | memset(&remote_data, 0, sizeof(struct wacom_remote_data)); | ||
| 877 | |||
| 878 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
| 879 | int j = i * 6; | ||
| 880 | int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4]; | ||
| 881 | bool connected = data[j+2]; | ||
| 882 | |||
| 883 | remote_data.remote[i].serial = serial; | ||
| 884 | remote_data.remote[i].connected = connected; | ||
| 885 | } | ||
| 886 | |||
| 887 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
| 888 | |||
| 889 | ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data)); | ||
| 890 | if (ret != sizeof(remote_data)) { | ||
| 891 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
| 892 | hid_err(wacom->hdev, "Can't queue Remote status event.\n"); | ||
| 893 | return; | ||
| 894 | } | ||
| 895 | |||
| 896 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
| 897 | |||
| 898 | wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); | ||
| 899 | } | ||
| 900 | |||
| 901 | static inline bool report_touch_events(struct wacom_wac *wacom) | 776 | static inline bool report_touch_events(struct wacom_wac *wacom) |
| 902 | { | 777 | { |
| 903 | return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); | 778 | return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); |
| @@ -1116,6 +991,131 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 1116 | return 0; | 991 | return 0; |
| 1117 | } | 992 | } |
| 1118 | 993 | ||
| 994 | static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) | ||
| 995 | { | ||
| 996 | unsigned char *data = wacom_wac->data; | ||
| 997 | struct input_dev *input; | ||
| 998 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
| 999 | struct wacom_remote *remote = wacom->remote; | ||
| 1000 | int bat_charging, bat_percent, touch_ring_mode; | ||
| 1001 | __u32 serial; | ||
| 1002 | int i, index = -1; | ||
| 1003 | unsigned long flags; | ||
| 1004 | |||
| 1005 | if (data[0] != WACOM_REPORT_REMOTE) { | ||
| 1006 | hid_dbg(wacom->hdev, "%s: received unknown report #%d", | ||
| 1007 | __func__, data[0]); | ||
| 1008 | return 0; | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | serial = data[3] + (data[4] << 8) + (data[5] << 16); | ||
| 1012 | wacom_wac->id[0] = PAD_DEVICE_ID; | ||
| 1013 | |||
| 1014 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
| 1015 | |||
| 1016 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
| 1017 | if (remote->remotes[i].serial == serial) { | ||
| 1018 | index = i; | ||
| 1019 | break; | ||
| 1020 | } | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | if (index < 0 || !remote->remotes[index].registered) | ||
| 1024 | goto out; | ||
| 1025 | |||
| 1026 | input = remote->remotes[index].input; | ||
| 1027 | |||
| 1028 | input_report_key(input, BTN_0, (data[9] & 0x01)); | ||
| 1029 | input_report_key(input, BTN_1, (data[9] & 0x02)); | ||
| 1030 | input_report_key(input, BTN_2, (data[9] & 0x04)); | ||
| 1031 | input_report_key(input, BTN_3, (data[9] & 0x08)); | ||
| 1032 | input_report_key(input, BTN_4, (data[9] & 0x10)); | ||
| 1033 | input_report_key(input, BTN_5, (data[9] & 0x20)); | ||
| 1034 | input_report_key(input, BTN_6, (data[9] & 0x40)); | ||
| 1035 | input_report_key(input, BTN_7, (data[9] & 0x80)); | ||
| 1036 | |||
| 1037 | input_report_key(input, BTN_8, (data[10] & 0x01)); | ||
| 1038 | input_report_key(input, BTN_9, (data[10] & 0x02)); | ||
| 1039 | input_report_key(input, BTN_A, (data[10] & 0x04)); | ||
| 1040 | input_report_key(input, BTN_B, (data[10] & 0x08)); | ||
| 1041 | input_report_key(input, BTN_C, (data[10] & 0x10)); | ||
| 1042 | input_report_key(input, BTN_X, (data[10] & 0x20)); | ||
| 1043 | input_report_key(input, BTN_Y, (data[10] & 0x40)); | ||
| 1044 | input_report_key(input, BTN_Z, (data[10] & 0x80)); | ||
| 1045 | |||
| 1046 | input_report_key(input, BTN_BASE, (data[11] & 0x01)); | ||
| 1047 | input_report_key(input, BTN_BASE2, (data[11] & 0x02)); | ||
| 1048 | |||
| 1049 | if (data[12] & 0x80) | ||
| 1050 | input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f)); | ||
| 1051 | else | ||
| 1052 | input_report_abs(input, ABS_WHEEL, 0); | ||
| 1053 | |||
| 1054 | bat_percent = data[7] & 0x7f; | ||
| 1055 | bat_charging = !!(data[7] & 0x80); | ||
| 1056 | |||
| 1057 | if (data[9] | data[10] | (data[11] & 0x03) | data[12]) | ||
| 1058 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
| 1059 | else | ||
| 1060 | input_report_abs(input, ABS_MISC, 0); | ||
| 1061 | |||
| 1062 | input_event(input, EV_MSC, MSC_SERIAL, serial); | ||
| 1063 | |||
| 1064 | input_sync(input); | ||
| 1065 | |||
| 1066 | /*Which mode select (LED light) is currently on?*/ | ||
| 1067 | touch_ring_mode = (data[11] & 0xC0) >> 6; | ||
| 1068 | |||
| 1069 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
| 1070 | if (remote->remotes[i].serial == serial) | ||
| 1071 | wacom->led.groups[i].select = touch_ring_mode; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | __wacom_notify_battery(&remote->remotes[index].battery, bat_percent, | ||
| 1075 | bat_charging, 1, bat_charging); | ||
| 1076 | |||
| 1077 | out: | ||
| 1078 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
| 1079 | return 0; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) | ||
| 1083 | { | ||
| 1084 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
| 1085 | unsigned char *data = wacom_wac->data; | ||
| 1086 | struct wacom_remote *remote = wacom->remote; | ||
| 1087 | struct wacom_remote_data remote_data; | ||
| 1088 | unsigned long flags; | ||
| 1089 | int i, ret; | ||
| 1090 | |||
| 1091 | if (data[0] != WACOM_REPORT_DEVICE_LIST) | ||
| 1092 | return; | ||
| 1093 | |||
| 1094 | memset(&remote_data, 0, sizeof(struct wacom_remote_data)); | ||
| 1095 | |||
| 1096 | for (i = 0; i < WACOM_MAX_REMOTES; i++) { | ||
| 1097 | int j = i * 6; | ||
| 1098 | int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4]; | ||
| 1099 | bool connected = data[j+2]; | ||
| 1100 | |||
| 1101 | remote_data.remote[i].serial = serial; | ||
| 1102 | remote_data.remote[i].connected = connected; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | spin_lock_irqsave(&remote->remote_lock, flags); | ||
| 1106 | |||
| 1107 | ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data)); | ||
| 1108 | if (ret != sizeof(remote_data)) { | ||
| 1109 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
| 1110 | hid_err(wacom->hdev, "Can't queue Remote status event.\n"); | ||
| 1111 | return; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | spin_unlock_irqrestore(&remote->remote_lock, flags); | ||
| 1115 | |||
| 1116 | wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | static int int_dist(int x1, int y1, int x2, int y2) | 1119 | static int int_dist(int x1, int y1, int x2, int y2) |
| 1120 | { | 1120 | { |
| 1121 | int x = x2 - x1; | 1121 | int x = x2 - x1; |
