HID: uclogic: Add support for XP-PEN Deco L
[sfrench/cifs-2.6.git] / drivers / hid / hid-uclogic-rdesc.c
index 04644d93bd117cb1f64acc1a0bc93089a8bd22f8..3d68e8b0784d0190439a249699aa58cbeb01105d 100644 (file)
@@ -21,7 +21,7 @@
 /* Fixed WP4030U report descriptor */
 __u8 uclogic_rdesc_wp4030u_fixed_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -66,7 +66,7 @@ const size_t uclogic_rdesc_wp4030u_fixed_size =
 /* Fixed WP5540U report descriptor */
 __u8 uclogic_rdesc_wp5540u_fixed_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -143,7 +143,7 @@ const size_t uclogic_rdesc_wp5540u_fixed_size =
 /* Fixed WP8060U report descriptor */
 __u8 uclogic_rdesc_wp8060u_fixed_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -220,7 +220,7 @@ const size_t uclogic_rdesc_wp8060u_fixed_size =
 /* Fixed WP1062 report descriptor */
 __u8 uclogic_rdesc_wp1062_fixed_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -268,7 +268,7 @@ const size_t uclogic_rdesc_wp1062_fixed_size =
 /* Fixed PF1209 report descriptor */
 __u8 uclogic_rdesc_pf1209_fixed_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -345,7 +345,7 @@ const size_t uclogic_rdesc_pf1209_fixed_size =
 /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */
 __u8 uclogic_rdesc_twhl850_fixed0_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -457,7 +457,7 @@ const size_t uclogic_rdesc_twhl850_fixed2_size =
 /* Fixed TWHA60 report descriptor, interface 0 (stylus) */
 __u8 uclogic_rdesc_twha60_fixed0_arr[] = {
        0x05, 0x0D,         /*  Usage Page (Digitizer),             */
-       0x09, 0x02,         /*  Usage (Pen),                        */
+       0x09, 0x01,         /*  Usage (Digitizer),                  */
        0xA1, 0x01,         /*  Collection (Application),           */
        0x85, 0x09,         /*      Report ID (9),                  */
        0x09, 0x20,         /*      Usage (Stylus),                 */
@@ -534,7 +534,7 @@ const size_t uclogic_rdesc_twha60_fixed1_size =
 /* Fixed report descriptor template for (tweaked) v1 pen reports */
 const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
        0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
-       0x09, 0x02,             /*  Usage (Pen),                            */
+       0x09, 0x01,             /*  Usage (Digitizer),                      */
        0xA1, 0x01,             /*  Collection (Application),               */
        0x85, 0x07,             /*      Report ID (7),                      */
        0x09, 0x20,             /*      Usage (Stylus),                     */
@@ -588,7 +588,7 @@ const size_t uclogic_rdesc_v1_pen_template_size =
 /* Fixed report descriptor template for (tweaked) v2 pen reports */
 const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
        0x05, 0x0D,             /*  Usage Page (Digitizer),                 */
-       0x09, 0x02,             /*  Usage (Pen),                            */
+       0x09, 0x01,             /*  Usage (Digitizer),                      */
        0xA1, 0x01,             /*  Collection (Application),               */
        0x85, 0x08,             /*      Report ID (8),                      */
        0x09, 0x20,             /*      Usage (Stylus),                     */
@@ -652,12 +652,12 @@ const size_t uclogic_rdesc_v2_pen_template_size =
                        sizeof(uclogic_rdesc_v2_pen_template_arr);
 
 /*
- * Expand to the contents of a generic frame report descriptor.
+ * Expand to the contents of a generic frame buttons report descriptor.
  *
  * @_id:       The report ID to use.
  * @_size:     Size of the report to pad to, including report ID, bytes.
  */
-#define UCLOGIC_RDESC_FRAME_BYTES(_id, _size) \
+#define UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(_id, _size) \
        0x05, 0x01,     /*  Usage Page (Desktop),               */ \
        0x09, 0x07,     /*  Usage (Keypad),                     */ \
        0xA1, 0x01,     /*  Collection (Application),           */ \
@@ -700,17 +700,266 @@ const size_t uclogic_rdesc_v2_pen_template_size =
 
 /* Fixed report descriptor for (tweaked) v1 frame reports */
 const __u8 uclogic_rdesc_v1_frame_arr[] = {
-       UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
+       UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
 };
 const size_t uclogic_rdesc_v1_frame_size =
                        sizeof(uclogic_rdesc_v1_frame_arr);
 
-/* Fixed report descriptor for (tweaked) v2 frame reports */
-const __u8 uclogic_rdesc_v2_frame_arr[] = {
-       UCLOGIC_RDESC_FRAME_BYTES(UCLOGIC_RDESC_V2_FRAME_ID, 12)
+/* Fixed report descriptor for (tweaked) v2 frame button reports */
+const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = {
+       UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID,
+                                         12)
 };
-const size_t uclogic_rdesc_v2_frame_size =
-                       sizeof(uclogic_rdesc_v2_frame_arr);
+const size_t uclogic_rdesc_v2_frame_buttons_size =
+                       sizeof(uclogic_rdesc_v2_frame_buttons_arr);
+
+/* Fixed report descriptor for (tweaked) v2 frame touch ring reports */
+const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = {
+       0x05, 0x01,         /*  Usage Page (Desktop),               */
+       0x09, 0x07,         /*  Usage (Keypad),                     */
+       0xA1, 0x01,         /*  Collection (Application),           */
+       0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID,
+                           /*      Report ID (TOUCH_ID),           */
+       0x14,               /*      Logical Minimum (0),            */
+       0x05, 0x0D,         /*      Usage Page (Digitizer),         */
+       0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
+       0xA0,               /*      Collection (Physical),          */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x75, 0x01,         /*          Report Size (1),            */
+       0x05, 0x09,         /*          Usage Page (Button),        */
+       0x09, 0x01,         /*          Usage (01h),                */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x95, 0x07,         /*          Report Count (7),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x75, 0x08,         /*          Report Size (8),            */
+       0x95, 0x02,         /*          Report Count (2),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x05, 0x0D,         /*          Usage Page (Digitizer),     */
+       0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
+       0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x05, 0x01,         /*          Usage Page (Desktop),       */
+       0x09, 0x38,         /*          Usage (Wheel),              */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x15, 0x00,         /*          Logical Minimum (0),        */
+       0x25, 0x0B,         /*          Logical Maximum (11),       */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x09, 0x30,         /*          Usage (X),                  */
+       0x09, 0x31,         /*          Usage (Y),                  */
+       0x14,               /*          Logical Minimum (0),        */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x75, 0x01,         /*          Report Size (1),            */
+       0x95, 0x02,         /*          Report Count (2),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x95, 0x2E,         /*          Report Count (46),          */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0xC0,               /*      End Collection,                 */
+       0xC0                /*  End Collection                      */
+};
+const size_t uclogic_rdesc_v2_frame_touch_ring_size =
+                       sizeof(uclogic_rdesc_v2_frame_touch_ring_arr);
+
+/* Fixed report descriptor for (tweaked) v2 frame touch strip reports */
+const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = {
+       0x05, 0x01,         /*  Usage Page (Desktop),               */
+       0x09, 0x07,         /*  Usage (Keypad),                     */
+       0xA1, 0x01,         /*  Collection (Application),           */
+       0x85, UCLOGIC_RDESC_V2_FRAME_TOUCH_ID,
+                           /*      Report ID (TOUCH_ID),           */
+       0x14,               /*      Logical Minimum (0),            */
+       0x05, 0x0D,         /*      Usage Page (Digitizer),         */
+       0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
+       0xA0,               /*      Collection (Physical),          */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x75, 0x01,         /*          Report Size (1),            */
+       0x05, 0x09,         /*          Usage Page (Button),        */
+       0x09, 0x01,         /*          Usage (01h),                */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x95, 0x07,         /*          Report Count (7),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x75, 0x08,         /*          Report Size (8),            */
+       0x95, 0x02,         /*          Report Count (2),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x05, 0x0D,         /*          Usage Page (Digitizer),     */
+       0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
+       0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x05, 0x01,         /*          Usage Page (Desktop),       */
+       0x09, 0x38,         /*          Usage (Wheel),              */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x15, 0x00,         /*          Logical Minimum (0),        */
+       0x25, 0x07,         /*          Logical Maximum (7),        */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x09, 0x30,         /*          Usage (X),                  */
+       0x09, 0x31,         /*          Usage (Y),                  */
+       0x14,               /*          Logical Minimum (0),        */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x75, 0x01,         /*          Report Size (1),            */
+       0x95, 0x02,         /*          Report Count (2),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x95, 0x2E,         /*          Report Count (46),          */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0xC0,               /*      End Collection,                 */
+       0xC0                /*  End Collection                      */
+};
+const size_t uclogic_rdesc_v2_frame_touch_strip_size =
+                       sizeof(uclogic_rdesc_v2_frame_touch_strip_arr);
+
+/* Fixed report descriptor for (tweaked) v2 frame dial reports */
+const __u8 uclogic_rdesc_v2_frame_dial_arr[] = {
+       0x05, 0x01,         /*  Usage Page (Desktop),               */
+       0x09, 0x07,         /*  Usage (Keypad),                     */
+       0xA1, 0x01,         /*  Collection (Application),           */
+       0x85, UCLOGIC_RDESC_V2_FRAME_DIAL_ID,
+                           /*      Report ID (DIAL_ID),            */
+       0x14,               /*      Logical Minimum (0),            */
+       0x05, 0x0D,         /*      Usage Page (Digitizer),         */
+       0x09, 0x39,         /*      Usage (Tablet Function Keys),   */
+       0xA0,               /*      Collection (Physical),          */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x75, 0x01,         /*          Report Size (1),            */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x05, 0x09,         /*          Usage Page (Button),        */
+       0x09, 0x01,         /*          Usage (01h),                */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x95, 0x06,         /*          Report Count (6),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x75, 0x08,         /*          Report Size (8),            */
+       0x95, 0x02,         /*          Report Count (2),           */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0x05, 0x0D,         /*          Usage Page (Digitizer),     */
+       0x0A, 0xFF, 0xFF,   /*          Usage (FFFFh),              */
+       0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x05, 0x01,         /*          Usage Page (Desktop),       */
+       0x09, 0x38,         /*          Usage (Wheel),              */
+       0x95, 0x01,         /*          Report Count (1),           */
+       0x15, 0xFF,         /*          Logical Minimum (-1),       */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x81, 0x06,         /*          Input (Variable, Relative), */
+       0x09, 0x30,         /*          Usage (X),                  */
+       0x09, 0x31,         /*          Usage (Y),                  */
+       0x14,               /*          Logical Minimum (0),        */
+       0x25, 0x01,         /*          Logical Maximum (1),        */
+       0x75, 0x01,         /*          Report Size (1),            */
+       0x95, 0x02,         /*          Report Count (2),           */
+       0x81, 0x02,         /*          Input (Variable),           */
+       0x95, 0x2E,         /*          Report Count (46),          */
+       0x81, 0x01,         /*          Input (Constant),           */
+       0xC0,               /*      End Collection,                 */
+       0xC0                /*  End Collection                      */
+};
+const size_t uclogic_rdesc_v2_frame_dial_size =
+                       sizeof(uclogic_rdesc_v2_frame_dial_arr);
+
+/* Fixed report descriptor template for UGEE v2 pen reports */
+const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[] = {
+       0x05, 0x0d,         /*  Usage Page (Digitizers),                */
+       0x09, 0x01,         /*  Usage (Digitizer),                      */
+       0xa1, 0x01,         /*  Collection (Application),               */
+       0x85, 0x02,         /*      Report ID (2),                      */
+       0x09, 0x20,         /*      Usage (Stylus),                     */
+       0xa1, 0x00,         /*      Collection (Physical),              */
+       0x09, 0x42,         /*          Usage (Tip Switch),             */
+       0x09, 0x44,         /*          Usage (Barrel Switch),          */
+       0x09, 0x46,         /*          Usage (Tablet Pick),            */
+       0x75, 0x01,         /*          Report Size (1),                */
+       0x95, 0x03,         /*          Report Count (3),               */
+       0x14,               /*          Logical Minimum (0),            */
+       0x25, 0x01,         /*          Logical Maximum (1),            */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0x95, 0x02,         /*          Report Count (2),               */
+       0x81, 0x03,         /*          Input (Constant, Variable),     */
+       0x09, 0x32,         /*          Usage (In Range),               */
+       0x95, 0x01,         /*          Report Count (1),               */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0x95, 0x02,         /*          Report Count (2),               */
+       0x81, 0x03,         /*          Input (Constant, Variable),     */
+       0x75, 0x10,         /*          Report Size (16),               */
+       0x95, 0x01,         /*          Report Count (1),               */
+       0x35, 0x00,         /*          Physical Minimum (0),           */
+       0xa4,               /*          Push,                           */
+       0x05, 0x01,         /*          Usage Page (Desktop),           */
+       0x09, 0x30,         /*          Usage (X),                      */
+       0x65, 0x13,         /*          Unit (Inch),                    */
+       0x55, 0x0d,         /*          Unit Exponent (-3),             */
+       0x27, UCLOGIC_RDESC_PEN_PH(X_LM),
+                           /*          Logical Maximum (PLACEHOLDER),  */
+       0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
+                           /*          Physical Maximum (PLACEHOLDER), */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0x09, 0x31,         /*          Usage (Y),                      */
+       0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
+                           /*          Logical Maximum (PLACEHOLDER),  */
+       0x47, UCLOGIC_RDESC_PEN_PH(Y_PM),
+                           /*          Physical Maximum (PLACEHOLDER), */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0xb4,               /*          Pop,                            */
+       0x09, 0x30,         /*          Usage (Tip Pressure),           */
+       0x45, 0x00,         /*          Physical Maximum (0),           */
+       0x27, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
+                           /*          Logical Maximum (PLACEHOLDER),  */
+       0x75, 0x0D,         /*          Report Size (13),               */
+       0x95, 0x01,         /*          Report Count (1),               */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0x75, 0x01,         /*          Report Size (1),                */
+       0x95, 0x03,         /*          Report Count (3),               */
+       0x81, 0x01,         /*          Input (Constant),               */
+       0x09, 0x3d,         /*          Usage (X Tilt),                 */
+       0x35, 0xC3,         /*          Physical Minimum (-61),         */
+       0x45, 0x3C,         /*          Physical Maximum (60),          */
+       0x15, 0xC3,         /*          Logical Minimum (-61),          */
+       0x25, 0x3C,         /*          Logical Maximum (60),           */
+       0x75, 0x08,         /*          Report Size (8),                */
+       0x95, 0x01,         /*          Report Count (1),               */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0x09, 0x3e,         /*          Usage (Y Tilt),                 */
+       0x35, 0xC3,         /*          Physical Minimum (-61),         */
+       0x45, 0x3C,         /*          Physical Maximum (60),          */
+       0x15, 0xC3,         /*          Logical Minimum (-61),          */
+       0x25, 0x3C,         /*          Logical Maximum (60),           */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0xc0,               /*      End Collection,                     */
+       0xc0,               /*  End Collection                          */
+};
+const size_t uclogic_rdesc_ugee_v2_pen_template_size =
+                       sizeof(uclogic_rdesc_ugee_v2_pen_template_arr);
+
+/* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */
+const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = {
+       0x05, 0x01,         /*  Usage Page (Desktop),                   */
+       0x09, 0x07,         /*  Usage (Keypad),                         */
+       0xA1, 0x01,         /*  Collection (Application),               */
+       0x85, UCLOGIC_RDESC_V1_FRAME_ID,
+                           /*      Report ID,                          */
+       0x05, 0x0D,         /*      Usage Page (Digitizer),             */
+       0x09, 0x39,         /*      Usage (Tablet Function Keys),       */
+       0xA0,               /*      Collection (Physical),              */
+       0x75, 0x01,         /*          Report Size (1),                */
+       0x95, 0x08,         /*          Report Count (8),               */
+       0x81, 0x01,         /*          Input (Constant),               */
+       0x05, 0x09,         /*          Usage Page (Button),            */
+       0x19, 0x01,         /*          Usage Minimum (01h),            */
+       UCLOGIC_RDESC_FRAME_PH_BTN,
+                           /*          Usage Maximum (PLACEHOLDER),    */
+       0x95, 0x0A,         /*          Report Count (10),              */
+       0x14,               /*          Logical Minimum (0),            */
+       0x25, 0x01,         /*          Logical Maximum (1),            */
+       0x81, 0x02,         /*          Input (Variable),               */
+       0x95, 0x46,         /*          Report Count (70),              */
+       0x81, 0x01,         /*          Input (Constant),               */
+       0xC0,               /*      End Collection,                     */
+       0xC0                /*  End Collection                          */
+};
+const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size =
+                       sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
 
 /* Fixed report descriptor for Ugee EX07 frame */
 const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
@@ -832,7 +1081,7 @@ const size_t uclogic_rdesc_xppen_deco01_frame_size =
  * uclogic_rdesc_template_apply() - apply report descriptor parameters to a
  * report descriptor template, creating a report descriptor. Copies the
  * template over to the new report descriptor and replaces every occurrence of
- * UCLOGIC_RDESC_PH_HEAD, followed by an index byte, with the value from the
+ * the template placeholders, followed by an index byte, with the value from the
  * parameter list at that index.
  *
  * @template_ptr:      Pointer to the template buffer.
@@ -849,7 +1098,8 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
                                   const s32 *param_list,
                                   size_t param_num)
 {
-       static const __u8 head[] = {UCLOGIC_RDESC_PH_HEAD};
+       static const __u8 btn_head[] = {UCLOGIC_RDESC_FRAME_PH_BTN_HEAD};
+       static const __u8 pen_head[] = {UCLOGIC_RDESC_PEN_PH_HEAD};
        __u8 *rdesc_ptr;
        __u8 *p;
        s32 v;
@@ -858,12 +1108,19 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
        if (rdesc_ptr == NULL)
                return NULL;
 
-       for (p = rdesc_ptr; p + sizeof(head) < rdesc_ptr + template_size;) {
-               if (memcmp(p, head, sizeof(head)) == 0 &&
-                   p[sizeof(head)] < param_num) {
-                       v = param_list[p[sizeof(head)]];
+       for (p = rdesc_ptr; p + sizeof(btn_head) < rdesc_ptr + template_size;) {
+               if (p + sizeof(pen_head) < rdesc_ptr + template_size &&
+                   memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
+                   p[sizeof(pen_head)] < param_num) {
+                       v = param_list[p[sizeof(pen_head)]];
                        put_unaligned(cpu_to_le32(v), (s32 *)p);
-                       p += sizeof(head) + 1;
+                       p += sizeof(pen_head) + 1;
+               } else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
+                          p[sizeof(btn_head)] < param_num) {
+                       v = param_list[p[sizeof(btn_head)]];
+                       put_unaligned((__u8)0x2A, p); /* Usage Maximum */
+                       put_unaligned_le16((__force u16)cpu_to_le16(v), p + 1);
+                       p += sizeof(btn_head) + 1;
                } else {
                        p++;
                }