OSDN Git Service

HID: uclogic: Support fragmented high-res reports
authorNikolai Kondrashov <spbnick@gmail.com>
Sun, 10 Feb 2019 10:13:55 +0000 (12:13 +0200)
committerBenjamin Tissoires <benjamin.tissoires@redhat.com>
Thu, 21 Feb 2019 11:00:53 +0000 (12:00 +0100)
Support parsing fragmented high-resolution reports in hid-uclogic to
support v2 reporting protocol.

Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
drivers/hid/hid-uclogic-core.c
drivers/hid/hid-uclogic-params.h

index 2066428..8169318 100644 (file)
@@ -265,6 +265,31 @@ static int uclogic_raw_event(struct hid_device *hdev,
                        /* Invert the in-range bit */
                        data[1] ^= 0x40;
                }
+               /*
+                * If report contains fragmented high-resolution pen
+                * coordinates
+                */
+               if (size >= 10 && params->pen.fragmented_hires) {
+                       u8 pressure_low_byte;
+                       u8 pressure_high_byte;
+
+                       /* Lift pressure bytes */
+                       pressure_low_byte = data[6];
+                       pressure_high_byte = data[7];
+                       /*
+                        * Move Y coord to make space for high-order X
+                        * coord byte
+                        */
+                       data[6] = data[5];
+                       data[5] = data[4];
+                       /* Move high-order X coord byte */
+                       data[4] = data[8];
+                       /* Move high-order Y coord byte */
+                       data[7] = data[9];
+                       /* Place pressure bytes */
+                       data[8] = pressure_low_byte;
+                       data[9] = pressure_high_byte;
+               }
                /* If we need to emulate in-range detection */
                if (params->pen.inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE) {
                        /* Set in-range bit */
index 665954d..1060f70 100644 (file)
@@ -56,6 +56,12 @@ struct uclogic_params_pen {
        unsigned int id;
        /* Type of in-range reporting, only valid if "id" is not zero */
        enum uclogic_params_pen_inrange inrange;
+       /*
+        * True, if reports include fragmented high resolution coords, with
+        * high-order X and then Y bytes following the pressure field.
+        * Only valid if "id" is not zero.
+        */
+       bool fragmented_hires;
 };
 
 /*
@@ -151,6 +157,7 @@ extern int uclogic_params_init(struct uclogic_params *params,
                ".pen.desc_size = %u\n"             \
                ".pen.id = %u\n"                    \
                ".pen.inrange = %s\n"               \
+               ".pen.fragmented_hires = %s\n"      \
                ".frame.desc_ptr = %p\n"            \
                ".frame.desc_size = %u\n"           \
                ".frame.id = %u\n"                  \
@@ -166,6 +173,7 @@ extern int uclogic_params_init(struct uclogic_params *params,
                (_params)->pen.desc_size,                                   \
                (_params)->pen.id,                                          \
                uclogic_params_pen_inrange_to_str((_params)->pen.inrange),  \
+               ((_params)->pen.fragmented_hires ? "true" : "false"),       \
                (_params)->frame.desc_ptr,                                  \
                (_params)->frame.desc_size,                                 \
                (_params)->frame.id,                                        \