Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 
0003 /*
0004  * Quirks for I2C-HID devices that do not supply proper descriptors
0005  *
0006  * Copyright (c) 2018 Julian Sax <jsbc@gmx.de>
0007  *
0008  */
0009 
0010 #include <linux/types.h>
0011 #include <linux/dmi.h>
0012 #include <linux/mod_devicetable.h>
0013 
0014 #include "i2c-hid.h"
0015 
0016 
0017 struct i2c_hid_desc_override {
0018     union {
0019         struct i2c_hid_desc *i2c_hid_desc;
0020         uint8_t             *i2c_hid_desc_buffer;
0021     };
0022     uint8_t              *hid_report_desc;
0023     unsigned int          hid_report_desc_size;
0024     uint8_t              *i2c_name;
0025 };
0026 
0027 
0028 /*
0029  * descriptors for the SIPODEV SP1064 touchpad
0030  *
0031  * This device does not supply any descriptors and on windows a filter
0032  * driver operates between the i2c-hid layer and the device and injects
0033  * these descriptors when the device is prompted. The descriptors were
0034  * extracted by listening to the i2c-hid traffic that occurs between the
0035  * windows filter driver and the windows i2c-hid driver.
0036  */
0037 
0038 static const struct i2c_hid_desc_override sipodev_desc = {
0039     .i2c_hid_desc_buffer = (uint8_t [])
0040     {0x1e, 0x00,                  /* Length of descriptor                 */
0041      0x00, 0x01,                  /* Version of descriptor                */
0042      0xdb, 0x01,                  /* Length of report descriptor          */
0043      0x21, 0x00,                  /* Location of report descriptor        */
0044      0x24, 0x00,                  /* Location of input report             */
0045      0x1b, 0x00,                  /* Max input report length              */
0046      0x25, 0x00,                  /* Location of output report            */
0047      0x11, 0x00,                  /* Max output report length             */
0048      0x22, 0x00,                  /* Location of command register         */
0049      0x23, 0x00,                  /* Location of data register            */
0050      0x11, 0x09,                  /* Vendor ID                            */
0051      0x88, 0x52,                  /* Product ID                           */
0052      0x06, 0x00,                  /* Version ID                           */
0053      0x00, 0x00, 0x00, 0x00       /* Reserved                             */
0054     },
0055 
0056     .hid_report_desc = (uint8_t [])
0057     {0x05, 0x01,                  /* Usage Page (Desktop),                */
0058      0x09, 0x02,                  /* Usage (Mouse),                       */
0059      0xA1, 0x01,                  /* Collection (Application),            */
0060      0x85, 0x01,                  /*     Report ID (1),                   */
0061      0x09, 0x01,                  /*     Usage (Pointer),                 */
0062      0xA1, 0x00,                  /*     Collection (Physical),           */
0063      0x05, 0x09,                  /*         Usage Page (Button),         */
0064      0x19, 0x01,                  /*         Usage Minimum (01h),         */
0065      0x29, 0x02,                  /*         Usage Maximum (02h),         */
0066      0x25, 0x01,                  /*         Logical Maximum (1),         */
0067      0x75, 0x01,                  /*         Report Size (1),             */
0068      0x95, 0x02,                  /*         Report Count (2),            */
0069      0x81, 0x02,                  /*         Input (Variable),            */
0070      0x95, 0x06,                  /*         Report Count (6),            */
0071      0x81, 0x01,                  /*         Input (Constant),            */
0072      0x05, 0x01,                  /*         Usage Page (Desktop),        */
0073      0x09, 0x30,                  /*         Usage (X),                   */
0074      0x09, 0x31,                  /*         Usage (Y),                   */
0075      0x15, 0x81,                  /*         Logical Minimum (-127),      */
0076      0x25, 0x7F,                  /*         Logical Maximum (127),       */
0077      0x75, 0x08,                  /*         Report Size (8),             */
0078      0x95, 0x02,                  /*         Report Count (2),            */
0079      0x81, 0x06,                  /*         Input (Variable, Relative),  */
0080      0xC0,                        /*     End Collection,                  */
0081      0xC0,                        /* End Collection,                      */
0082      0x05, 0x0D,                  /* Usage Page (Digitizer),              */
0083      0x09, 0x05,                  /* Usage (Touchpad),                    */
0084      0xA1, 0x01,                  /* Collection (Application),            */
0085      0x85, 0x04,                  /*     Report ID (4),                   */
0086      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0087      0x09, 0x22,                  /*     Usage (Finger),                  */
0088      0xA1, 0x02,                  /*     Collection (Logical),            */
0089      0x15, 0x00,                  /*         Logical Minimum (0),         */
0090      0x25, 0x01,                  /*         Logical Maximum (1),         */
0091      0x09, 0x47,                  /*         Usage (Touch Valid),         */
0092      0x09, 0x42,                  /*         Usage (Tip Switch),          */
0093      0x95, 0x02,                  /*         Report Count (2),            */
0094      0x75, 0x01,                  /*         Report Size (1),             */
0095      0x81, 0x02,                  /*         Input (Variable),            */
0096      0x95, 0x01,                  /*         Report Count (1),            */
0097      0x75, 0x03,                  /*         Report Size (3),             */
0098      0x25, 0x05,                  /*         Logical Maximum (5),         */
0099      0x09, 0x51,                  /*         Usage (Contact Identifier),  */
0100      0x81, 0x02,                  /*         Input (Variable),            */
0101      0x75, 0x01,                  /*         Report Size (1),             */
0102      0x95, 0x03,                  /*         Report Count (3),            */
0103      0x81, 0x03,                  /*         Input (Constant, Variable),  */
0104      0x05, 0x01,                  /*         Usage Page (Desktop),        */
0105      0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
0106      0x75, 0x10,                  /*         Report Size (16),            */
0107      0x55, 0x0E,                  /*         Unit Exponent (14),          */
0108      0x65, 0x11,                  /*         Unit (Centimeter),           */
0109      0x09, 0x30,                  /*         Usage (X),                   */
0110      0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
0111      0x95, 0x01,                  /*         Report Count (1),            */
0112      0x81, 0x02,                  /*         Input (Variable),            */
0113      0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
0114      0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
0115      0x09, 0x31,                  /*         Usage (Y),                   */
0116      0x81, 0x02,                  /*         Input (Variable),            */
0117      0xC0,                        /*     End Collection,                  */
0118      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0119      0x09, 0x22,                  /*     Usage (Finger),                  */
0120      0xA1, 0x02,                  /*     Collection (Logical),            */
0121      0x25, 0x01,                  /*         Logical Maximum (1),         */
0122      0x09, 0x47,                  /*         Usage (Touch Valid),         */
0123      0x09, 0x42,                  /*         Usage (Tip Switch),          */
0124      0x95, 0x02,                  /*         Report Count (2),            */
0125      0x75, 0x01,                  /*         Report Size (1),             */
0126      0x81, 0x02,                  /*         Input (Variable),            */
0127      0x95, 0x01,                  /*         Report Count (1),            */
0128      0x75, 0x03,                  /*         Report Size (3),             */
0129      0x25, 0x05,                  /*         Logical Maximum (5),         */
0130      0x09, 0x51,                  /*         Usage (Contact Identifier),  */
0131      0x81, 0x02,                  /*         Input (Variable),            */
0132      0x75, 0x01,                  /*         Report Size (1),             */
0133      0x95, 0x03,                  /*         Report Count (3),            */
0134      0x81, 0x03,                  /*         Input (Constant, Variable),  */
0135      0x05, 0x01,                  /*         Usage Page (Desktop),        */
0136      0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
0137      0x75, 0x10,                  /*         Report Size (16),            */
0138      0x09, 0x30,                  /*         Usage (X),                   */
0139      0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
0140      0x95, 0x01,                  /*         Report Count (1),            */
0141      0x81, 0x02,                  /*         Input (Variable),            */
0142      0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
0143      0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
0144      0x09, 0x31,                  /*         Usage (Y),                   */
0145      0x81, 0x02,                  /*         Input (Variable),            */
0146      0xC0,                        /*     End Collection,                  */
0147      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0148      0x09, 0x22,                  /*     Usage (Finger),                  */
0149      0xA1, 0x02,                  /*     Collection (Logical),            */
0150      0x25, 0x01,                  /*         Logical Maximum (1),         */
0151      0x09, 0x47,                  /*         Usage (Touch Valid),         */
0152      0x09, 0x42,                  /*         Usage (Tip Switch),          */
0153      0x95, 0x02,                  /*         Report Count (2),            */
0154      0x75, 0x01,                  /*         Report Size (1),             */
0155      0x81, 0x02,                  /*         Input (Variable),            */
0156      0x95, 0x01,                  /*         Report Count (1),            */
0157      0x75, 0x03,                  /*         Report Size (3),             */
0158      0x25, 0x05,                  /*         Logical Maximum (5),         */
0159      0x09, 0x51,                  /*         Usage (Contact Identifier),  */
0160      0x81, 0x02,                  /*         Input (Variable),            */
0161      0x75, 0x01,                  /*         Report Size (1),             */
0162      0x95, 0x03,                  /*         Report Count (3),            */
0163      0x81, 0x03,                  /*         Input (Constant, Variable),  */
0164      0x05, 0x01,                  /*         Usage Page (Desktop),        */
0165      0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
0166      0x75, 0x10,                  /*         Report Size (16),            */
0167      0x09, 0x30,                  /*         Usage (X),                   */
0168      0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
0169      0x95, 0x01,                  /*         Report Count (1),            */
0170      0x81, 0x02,                  /*         Input (Variable),            */
0171      0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
0172      0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
0173      0x09, 0x31,                  /*         Usage (Y),                   */
0174      0x81, 0x02,                  /*         Input (Variable),            */
0175      0xC0,                        /*     End Collection,                  */
0176      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0177      0x09, 0x22,                  /*     Usage (Finger),                  */
0178      0xA1, 0x02,                  /*     Collection (Logical),            */
0179      0x25, 0x01,                  /*         Logical Maximum (1),         */
0180      0x09, 0x47,                  /*         Usage (Touch Valid),         */
0181      0x09, 0x42,                  /*         Usage (Tip Switch),          */
0182      0x95, 0x02,                  /*         Report Count (2),            */
0183      0x75, 0x01,                  /*         Report Size (1),             */
0184      0x81, 0x02,                  /*         Input (Variable),            */
0185      0x95, 0x01,                  /*         Report Count (1),            */
0186      0x75, 0x03,                  /*         Report Size (3),             */
0187      0x25, 0x05,                  /*         Logical Maximum (5),         */
0188      0x09, 0x51,                  /*         Usage (Contact Identifier),  */
0189      0x81, 0x02,                  /*         Input (Variable),            */
0190      0x75, 0x01,                  /*         Report Size (1),             */
0191      0x95, 0x03,                  /*         Report Count (3),            */
0192      0x81, 0x03,                  /*         Input (Constant, Variable),  */
0193      0x05, 0x01,                  /*         Usage Page (Desktop),        */
0194      0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
0195      0x75, 0x10,                  /*         Report Size (16),            */
0196      0x09, 0x30,                  /*         Usage (X),                   */
0197      0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
0198      0x95, 0x01,                  /*         Report Count (1),            */
0199      0x81, 0x02,                  /*         Input (Variable),            */
0200      0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
0201      0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
0202      0x09, 0x31,                  /*         Usage (Y),                   */
0203      0x81, 0x02,                  /*         Input (Variable),            */
0204      0xC0,                        /*     End Collection,                  */
0205      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0206      0x55, 0x0C,                  /*     Unit Exponent (12),              */
0207      0x66, 0x01, 0x10,            /*     Unit (Seconds),                  */
0208      0x47, 0xFF, 0xFF, 0x00, 0x00,/*     Physical Maximum (65535),        */
0209      0x27, 0xFF, 0xFF, 0x00, 0x00,/*     Logical Maximum (65535),         */
0210      0x75, 0x10,                  /*     Report Size (16),                */
0211      0x95, 0x01,                  /*     Report Count (1),                */
0212      0x09, 0x56,                  /*     Usage (Scan Time),               */
0213      0x81, 0x02,                  /*     Input (Variable),                */
0214      0x09, 0x54,                  /*     Usage (Contact Count),           */
0215      0x25, 0x7F,                  /*     Logical Maximum (127),           */
0216      0x75, 0x08,                  /*     Report Size (8),                 */
0217      0x81, 0x02,                  /*     Input (Variable),                */
0218      0x05, 0x09,                  /*     Usage Page (Button),             */
0219      0x09, 0x01,                  /*     Usage (01h),                     */
0220      0x25, 0x01,                  /*     Logical Maximum (1),             */
0221      0x75, 0x01,                  /*     Report Size (1),                 */
0222      0x95, 0x01,                  /*     Report Count (1),                */
0223      0x81, 0x02,                  /*     Input (Variable),                */
0224      0x95, 0x07,                  /*     Report Count (7),                */
0225      0x81, 0x03,                  /*     Input (Constant, Variable),      */
0226      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0227      0x85, 0x02,                  /*     Report ID (2),                   */
0228      0x09, 0x55,                  /*     Usage (Contact Count Maximum),   */
0229      0x09, 0x59,                  /*     Usage (59h),                     */
0230      0x75, 0x04,                  /*     Report Size (4),                 */
0231      0x95, 0x02,                  /*     Report Count (2),                */
0232      0x25, 0x0F,                  /*     Logical Maximum (15),            */
0233      0xB1, 0x02,                  /*     Feature (Variable),              */
0234      0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
0235      0x85, 0x07,                  /*     Report ID (7),                   */
0236      0x09, 0x60,                  /*     Usage (60h),                     */
0237      0x75, 0x01,                  /*     Report Size (1),                 */
0238      0x95, 0x01,                  /*     Report Count (1),                */
0239      0x25, 0x01,                  /*     Logical Maximum (1),             */
0240      0xB1, 0x02,                  /*     Feature (Variable),              */
0241      0x95, 0x07,                  /*     Report Count (7),                */
0242      0xB1, 0x03,                  /*     Feature (Constant, Variable),    */
0243      0x85, 0x06,                  /*     Report ID (6),                   */
0244      0x06, 0x00, 0xFF,            /*     Usage Page (FF00h),              */
0245      0x09, 0xC5,                  /*     Usage (C5h),                     */
0246      0x26, 0xFF, 0x00,            /*     Logical Maximum (255),           */
0247      0x75, 0x08,                  /*     Report Size (8),                 */
0248      0x96, 0x00, 0x01,            /*     Report Count (256),              */
0249      0xB1, 0x02,                  /*     Feature (Variable),              */
0250      0xC0,                        /* End Collection,                      */
0251      0x06, 0x00, 0xFF,            /* Usage Page (FF00h),                  */
0252      0x09, 0x01,                  /* Usage (01h),                         */
0253      0xA1, 0x01,                  /* Collection (Application),            */
0254      0x85, 0x0D,                  /*     Report ID (13),                  */
0255      0x26, 0xFF, 0x00,            /*     Logical Maximum (255),           */
0256      0x19, 0x01,                  /*     Usage Minimum (01h),             */
0257      0x29, 0x02,                  /*     Usage Maximum (02h),             */
0258      0x75, 0x08,                  /*     Report Size (8),                 */
0259      0x95, 0x02,                  /*     Report Count (2),                */
0260      0xB1, 0x02,                  /*     Feature (Variable),              */
0261      0xC0,                        /* End Collection,                      */
0262      0x05, 0x0D,                  /* Usage Page (Digitizer),              */
0263      0x09, 0x0E,                  /* Usage (Configuration),               */
0264      0xA1, 0x01,                  /* Collection (Application),            */
0265      0x85, 0x03,                  /*     Report ID (3),                   */
0266      0x09, 0x22,                  /*     Usage (Finger),                  */
0267      0xA1, 0x02,                  /*     Collection (Logical),            */
0268      0x09, 0x52,                  /*         Usage (Device Mode),         */
0269      0x25, 0x0A,                  /*         Logical Maximum (10),        */
0270      0x95, 0x01,                  /*         Report Count (1),            */
0271      0xB1, 0x02,                  /*         Feature (Variable),          */
0272      0xC0,                        /*     End Collection,                  */
0273      0x09, 0x22,                  /*     Usage (Finger),                  */
0274      0xA1, 0x00,                  /*     Collection (Physical),           */
0275      0x85, 0x05,                  /*         Report ID (5),               */
0276      0x09, 0x57,                  /*         Usage (57h),                 */
0277      0x09, 0x58,                  /*         Usage (58h),                 */
0278      0x75, 0x01,                  /*         Report Size (1),             */
0279      0x95, 0x02,                  /*         Report Count (2),            */
0280      0x25, 0x01,                  /*         Logical Maximum (1),         */
0281      0xB1, 0x02,                  /*         Feature (Variable),          */
0282      0x95, 0x06,                  /*         Report Count (6),            */
0283      0xB1, 0x03,                  /*         Feature (Constant, Variable),*/
0284      0xC0,                        /*     End Collection,                  */
0285      0xC0                         /* End Collection                       */
0286     },
0287     .hid_report_desc_size = 475,
0288     .i2c_name = "SYNA3602:00"
0289 };
0290 
0291 
0292 static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
0293     {
0294         .ident = "Teclast F6 Pro",
0295         .matches = {
0296             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
0297             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F6 Pro"),
0298         },
0299         .driver_data = (void *)&sipodev_desc
0300     },
0301     {
0302         .ident = "Teclast F7",
0303         .matches = {
0304             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
0305             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F7"),
0306         },
0307         .driver_data = (void *)&sipodev_desc
0308     },
0309     {
0310         .ident = "Trekstor Primebook C13",
0311         .matches = {
0312             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
0313             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
0314         },
0315         .driver_data = (void *)&sipodev_desc
0316     },
0317     {
0318         .ident = "Trekstor Primebook C11",
0319         .matches = {
0320             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
0321             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
0322         },
0323         .driver_data = (void *)&sipodev_desc
0324     },
0325     {
0326         /*
0327          * There are at least 2 Primebook C11B versions, the older
0328          * version has a product-name of "Primebook C11B", and a
0329          * bios version / release / firmware revision of:
0330          * V2.1.2 / 05/03/2018 / 18.2
0331          * The new version has "PRIMEBOOK C11B" as product-name and a
0332          * bios version / release / firmware revision of:
0333          * CFALKSW05_BIOS_V1.1.2 / 11/19/2018 / 19.2
0334          * Only the older version needs this quirk, note the newer
0335          * version will not match as it has a different product-name.
0336          */
0337         .ident = "Trekstor Primebook C11B",
0338         .matches = {
0339             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
0340             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11B"),
0341         },
0342         .driver_data = (void *)&sipodev_desc
0343     },
0344     {
0345         .ident = "Trekstor SURFBOOK E11B",
0346         .matches = {
0347             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
0348             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"),
0349         },
0350         .driver_data = (void *)&sipodev_desc
0351     },
0352     {
0353         .ident = "Direkt-Tek DTLAPY116-2",
0354         .matches = {
0355             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
0356             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY116-2"),
0357         },
0358         .driver_data = (void *)&sipodev_desc
0359     },
0360     {
0361         .ident = "Direkt-Tek DTLAPY133-1",
0362         .matches = {
0363             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
0364             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY133-1"),
0365         },
0366         .driver_data = (void *)&sipodev_desc
0367     },
0368     {
0369         .ident = "Mediacom Flexbook Edge 11",
0370         .matches = {
0371             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
0372             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"),
0373         },
0374         .driver_data = (void *)&sipodev_desc
0375     },
0376     {
0377         .ident = "Mediacom FlexBook edge 13",
0378         .matches = {
0379             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
0380             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook_edge13-M-FBE13"),
0381         },
0382         .driver_data = (void *)&sipodev_desc
0383     },
0384     {
0385         .ident = "Odys Winbook 13",
0386         .matches = {
0387             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AXDIA International GmbH"),
0388             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "WINBOOK 13"),
0389         },
0390         .driver_data = (void *)&sipodev_desc
0391     },
0392     {
0393         .ident = "iBall Aer3",
0394         .matches = {
0395             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "iBall"),
0396             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Aer3"),
0397         },
0398         .driver_data = (void *)&sipodev_desc
0399     },
0400     {
0401         .ident = "Schneider SCL142ALM",
0402         .matches = {
0403             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"),
0404             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"),
0405         },
0406         .driver_data = (void *)&sipodev_desc
0407     },
0408     {
0409         .ident = "Vero K147",
0410         .matches = {
0411             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VERO"),
0412             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "K147"),
0413         },
0414         .driver_data = (void *)&sipodev_desc
0415     },
0416     { } /* Terminate list */
0417 };
0418 
0419 
0420 struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
0421 {
0422     struct i2c_hid_desc_override *override;
0423     const struct dmi_system_id *system_id;
0424 
0425     system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
0426     if (!system_id)
0427         return NULL;
0428 
0429     override = system_id->driver_data;
0430     if (strcmp(override->i2c_name, i2c_name))
0431         return NULL;
0432 
0433     return override->i2c_hid_desc;
0434 }
0435 
0436 char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
0437                            unsigned int *size)
0438 {
0439     struct i2c_hid_desc_override *override;
0440     const struct dmi_system_id *system_id;
0441 
0442     system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
0443     if (!system_id)
0444         return NULL;
0445 
0446     override = system_id->driver_data;
0447     if (strcmp(override->i2c_name, i2c_name))
0448         return NULL;
0449 
0450     *size = override->hid_report_desc_size;
0451     return override->hid_report_desc;
0452 }