diff options
author | Jiri Kosina <jkosina@suse.cz> | 2018-06-08 04:28:24 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-06-08 04:28:24 -0400 |
commit | 06d8b9067c9bb9d65c7479506e682b211735fa1a (patch) | |
tree | fc0a998e703c7ed98c42dd0268f04b074932e288 | |
parent | 43e7b1494161bd56dc2bd9bf7c995abc3894089a (diff) | |
parent | 8947b0cfdcc111722b2293f26debdab8697f4c68 (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.c | 74 |
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 | } |