aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2018-06-08 04:28:24 -0400
committerJiri Kosina <jkosina@suse.cz>2018-06-08 04:28:24 -0400
commit06d8b9067c9bb9d65c7479506e682b211735fa1a (patch)
treefc0a998e703c7ed98c42dd0268f04b074932e288
parent43e7b1494161bd56dc2bd9bf7c995abc3894089a (diff)
parent8947b0cfdcc111722b2293f26debdab8697f4c68 (diff)
Merge branch 'for-4.18/wacom' into for-linus
Support for "In Range" flag for Wacom Intuos/Bamboo devices from Jason Gerecke
-rw-r--r--drivers/hid/wacom_wac.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 5f947ec20dcb..0bb44d0088ed 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -2894,24 +2894,31 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
2894 struct wacom_features *features = &wacom->features; 2894 struct wacom_features *features = &wacom->features;
2895 struct input_dev *input = wacom->pen_input; 2895 struct input_dev *input = wacom->pen_input;
2896 unsigned char *data = wacom->data; 2896 unsigned char *data = wacom->data;
2897 int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; 2897 int x = 0, y = 0, p = 0, d = 0;
2898 bool pen = false, btn1 = false, btn2 = false;
2899 bool range, prox, rdy;
2898 2900
2899 if (data[0] != WACOM_REPORT_PENABLED) 2901 if (data[0] != WACOM_REPORT_PENABLED)
2900 return 0; 2902 return 0;
2901 2903
2902 prox = (data[1] & 0x20) == 0x20; 2904 range = (data[1] & 0x80) == 0x80;
2905 prox = (data[1] & 0x40) == 0x40;
2906 rdy = (data[1] & 0x20) == 0x20;
2907
2908 wacom->shared->stylus_in_proximity = range;
2909 if (delay_pen_events(wacom))
2910 return 0;
2911
2912 if (rdy) {
2913 p = le16_to_cpup((__le16 *)&data[6]);
2914 pen = data[1] & 0x01;
2915 btn1 = data[1] & 0x02;
2916 btn2 = data[1] & 0x04;
2917 }
2918 if (prox) {
2919 x = le16_to_cpup((__le16 *)&data[2]);
2920 y = le16_to_cpup((__le16 *)&data[4]);
2903 2921
2904 /*
2905 * All reports shared between PEN and RUBBER tool must be
2906 * forced to a known starting value (zero) when transitioning to
2907 * out-of-prox.
2908 *
2909 * If not reset then, to userspace, it will look like lost events
2910 * if new tool comes in-prox with same values as previous tool sent.
2911 *
2912 * Hardware does report zero in most out-of-prox cases but not all.
2913 */
2914 if (!wacom->shared->stylus_in_proximity) {
2915 if (data[1] & 0x08) { 2922 if (data[1] & 0x08) {
2916 wacom->tool[0] = BTN_TOOL_RUBBER; 2923 wacom->tool[0] = BTN_TOOL_RUBBER;
2917 wacom->id[0] = ERASER_DEVICE_ID; 2924 wacom->id[0] = ERASER_DEVICE_ID;
@@ -2919,16 +2926,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
2919 wacom->tool[0] = BTN_TOOL_PEN; 2926 wacom->tool[0] = BTN_TOOL_PEN;
2920 wacom->id[0] = STYLUS_DEVICE_ID; 2927 wacom->id[0] = STYLUS_DEVICE_ID;
2921 } 2928 }
2929 wacom->reporting_data = true;
2922 } 2930 }
2923 2931 if (range) {
2924 wacom->shared->stylus_in_proximity = prox;
2925 if (delay_pen_events(wacom))
2926 return 0;
2927
2928 if (prox) {
2929 x = le16_to_cpup((__le16 *)&data[2]);
2930 y = le16_to_cpup((__le16 *)&data[4]);
2931 p = le16_to_cpup((__le16 *)&data[6]);
2932 /* 2932 /*
2933 * Convert distance from out prox to distance from tablet. 2933 * Convert distance from out prox to distance from tablet.
2934 * distance will be greater than distance_max once 2934 * distance will be greater than distance_max once
@@ -2937,25 +2937,29 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
2937 */ 2937 */
2938 if (data[8] <= features->distance_max) 2938 if (data[8] <= features->distance_max)
2939 d = features->distance_max - data[8]; 2939 d = features->distance_max - data[8];
2940
2941 pen = data[1] & 0x01;
2942 btn1 = data[1] & 0x02;
2943 btn2 = data[1] & 0x04;
2944 } else { 2940 } else {
2945 wacom->id[0] = 0; 2941 wacom->id[0] = 0;
2946 } 2942 }
2947 2943
2948 input_report_key(input, BTN_TOUCH, pen); 2944 if (wacom->reporting_data) {
2949 input_report_key(input, BTN_STYLUS, btn1); 2945 input_report_key(input, BTN_TOUCH, pen);
2950 input_report_key(input, BTN_STYLUS2, btn2); 2946 input_report_key(input, BTN_STYLUS, btn1);
2947 input_report_key(input, BTN_STYLUS2, btn2);
2951 2948
2952 input_report_abs(input, ABS_X, x); 2949 if (prox || !range) {
2953 input_report_abs(input, ABS_Y, y); 2950 input_report_abs(input, ABS_X, x);
2954 input_report_abs(input, ABS_PRESSURE, p); 2951 input_report_abs(input, ABS_Y, y);
2955 input_report_abs(input, ABS_DISTANCE, d); 2952 }
2953 input_report_abs(input, ABS_PRESSURE, p);
2954 input_report_abs(input, ABS_DISTANCE, d);
2956 2955
2957 input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ 2956 input_report_key(input, wacom->tool[0], range); /* PEN or RUBBER */
2958 input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ 2957 input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
2958 }
2959
2960 if (!range) {
2961 wacom->reporting_data = false;
2962 }
2959 2963
2960 return 1; 2964 return 1;
2961} 2965}