@@ -103,6 +103,8 @@ static void uclogic_params_frame_hid_dbg(
103103 frame -> touch_flip_at );
104104 hid_dbg (hdev , "\t\t.bitmap_dial_byte = %u\n" ,
105105 frame -> bitmap_dial_byte );
106+ hid_dbg (hdev , "\t\t.bitmap_second_dial_destination_byte = %u\n" ,
107+ frame -> bitmap_second_dial_destination_byte );
106108}
107109
108110/**
@@ -1341,7 +1343,7 @@ static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev,
13411343 struct uclogic_params * p )
13421344{
13431345 struct uclogic_raw_event_hook * event_hook ;
1344- __u8 reconnect_event [] = {
1346+ static const __u8 reconnect_event [] = {
13451347 /* Event received on wireless tablet reconnection */
13461348 0x02 , 0xF8 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
13471349 };
@@ -1529,6 +1531,126 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
15291531 return rc ;
15301532}
15311533
1534+ /*
1535+ * uclogic_params_init_ugee_xppen_pro_22r() - Initializes a UGEE XP-Pen Pro 22R tablet device.
1536+ *
1537+ * @hdev: The HID device of the tablet interface to initialize and get
1538+ * parameters from. Cannot be NULL.
1539+ * @params: Parameters to fill in (to be cleaned with
1540+ * uclogic_params_cleanup()). Not modified in case of error.
1541+ * Cannot be NULL.
1542+ *
1543+ * Returns:
1544+ * Zero, if successful. A negative errno code on error.
1545+ */
1546+ static int uclogic_params_init_ugee_xppen_pro_22r (struct uclogic_params * params ,
1547+ struct hid_device * hdev ,
1548+ const u8 rdesc_frame_arr [],
1549+ const size_t rdesc_frame_size )
1550+ {
1551+ int rc = 0 ;
1552+ struct usb_interface * iface ;
1553+ __u8 bInterfaceNumber ;
1554+ const int str_desc_len = 12 ;
1555+ u8 * str_desc = NULL ;
1556+ __u8 * rdesc_pen = NULL ;
1557+ s32 desc_params [UCLOGIC_RDESC_PH_ID_NUM ];
1558+ enum uclogic_params_frame_type frame_type ;
1559+ /* The resulting parameters (noop) */
1560+ struct uclogic_params p = {0 , };
1561+
1562+ if (!hdev || !params ) {
1563+ rc = - EINVAL ;
1564+ goto cleanup ;
1565+ }
1566+
1567+ iface = to_usb_interface (hdev -> dev .parent );
1568+ bInterfaceNumber = iface -> cur_altsetting -> desc .bInterfaceNumber ;
1569+
1570+ /* Ignore non-pen interfaces */
1571+ if (bInterfaceNumber != 2 ) {
1572+ rc = - EINVAL ;
1573+ uclogic_params_init_invalid (& p );
1574+ goto cleanup ;
1575+ }
1576+
1577+ /*
1578+ * Initialize the interface by sending magic data.
1579+ * This magic data is the same as other UGEE v2 tablets.
1580+ */
1581+ rc = uclogic_probe_interface (hdev ,
1582+ uclogic_ugee_v2_probe_arr ,
1583+ uclogic_ugee_v2_probe_size ,
1584+ uclogic_ugee_v2_probe_endpoint );
1585+ if (rc ) {
1586+ uclogic_params_init_invalid (& p );
1587+ goto cleanup ;
1588+ }
1589+
1590+ /**
1591+ * Read the string descriptor containing pen and frame parameters.
1592+ * These are slightly different than typical UGEE v2 devices.
1593+ */
1594+ rc = uclogic_params_get_str_desc (& str_desc , hdev , 100 , str_desc_len );
1595+ if (rc != str_desc_len ) {
1596+ rc = (rc < 0 ) ? rc : - EINVAL ;
1597+ hid_err (hdev , "failed retrieving pen and frame parameters: %d\n" , rc );
1598+ uclogic_params_init_invalid (& p );
1599+ goto cleanup ;
1600+ }
1601+
1602+ rc = uclogic_params_parse_ugee_v2_desc (str_desc , str_desc_len ,
1603+ desc_params ,
1604+ ARRAY_SIZE (desc_params ),
1605+ & frame_type );
1606+ if (rc )
1607+ goto cleanup ;
1608+
1609+ // str_desc doesn't report the correct amount of buttons, so manually fix it
1610+ desc_params [UCLOGIC_RDESC_FRAME_PH_ID_UM ] = 20 ;
1611+
1612+ kfree (str_desc );
1613+ str_desc = NULL ;
1614+
1615+ /* Initialize the pen interface */
1616+ rdesc_pen = uclogic_rdesc_template_apply (
1617+ uclogic_rdesc_ugee_v2_pen_template_arr ,
1618+ uclogic_rdesc_ugee_v2_pen_template_size ,
1619+ desc_params , ARRAY_SIZE (desc_params ));
1620+ if (!rdesc_pen ) {
1621+ rc = - ENOMEM ;
1622+ goto cleanup ;
1623+ }
1624+
1625+ p .pen .desc_ptr = rdesc_pen ;
1626+ p .pen .desc_size = uclogic_rdesc_ugee_v2_pen_template_size ;
1627+ p .pen .id = 0x02 ;
1628+ p .pen .subreport_list [0 ].value = 0xf0 ;
1629+ p .pen .subreport_list [0 ].id = UCLOGIC_RDESC_V1_FRAME_ID ;
1630+
1631+ /* Initialize the frame interface */
1632+ rc = uclogic_params_frame_init_with_desc (
1633+ & p .frame_list [0 ],
1634+ rdesc_frame_arr ,
1635+ rdesc_frame_size ,
1636+ UCLOGIC_RDESC_V1_FRAME_ID );
1637+ if (rc < 0 ) {
1638+ hid_err (hdev , "initializing frame params failed: %d\n" , rc );
1639+ goto cleanup ;
1640+ }
1641+
1642+ p .frame_list [0 ].bitmap_dial_byte = 7 ;
1643+ p .frame_list [0 ].bitmap_second_dial_destination_byte = 8 ;
1644+
1645+ /* Output parameters */
1646+ memcpy (params , & p , sizeof (* params ));
1647+ memset (& p , 0 , sizeof (p ));
1648+ cleanup :
1649+ kfree (str_desc );
1650+ uclogic_params_cleanup (& p );
1651+ return rc ;
1652+ }
1653+
15321654/**
15331655 * uclogic_params_init() - initialize a tablet interface and discover its
15341656 * parameters.
@@ -1845,6 +1967,16 @@ int uclogic_params_init(struct uclogic_params *params,
18451967 uclogic_params_init_invalid (& p );
18461968 }
18471969
1970+ break ;
1971+ case VID_PID (USB_VENDOR_ID_UGEE ,
1972+ USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO ):
1973+ rc = uclogic_params_init_ugee_xppen_pro_22r (& p ,
1974+ hdev ,
1975+ uclogic_rdesc_xppen_artist_22r_pro_frame_arr ,
1976+ uclogic_rdesc_xppen_artist_22r_pro_frame_size );
1977+ if (rc != 0 )
1978+ goto cleanup ;
1979+
18481980 break ;
18491981 }
18501982
0 commit comments