diff mbox

hid/i2c-hid: override HID descriptors for certain devices

Message ID 20180522195427.25853-1-jsbc@gmx.de (mailing list archive)
State New, archived
Headers show

Commit Message

Julian Sax May 22, 2018, 7:54 p.m. UTC
A particular touchpad (SIPODEV SP1064) refuses to supply the HID
descriptors. This patch provides the framework for overriding these
descriptors based on DMI data. It also includes the descriptors for
said touchpad, as well as the DMI data for the 4 laptops known to
use this device.

Relevant Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1526312

Cc: Hans de Goede <hdegoede@redhat.com>
Reported-and-tested-by: ahormann@gmx.net
Reported-and-tested-by: Bruno Jesus <bruno.fl.jesus@gmail.com>
Reported-and-tested-by: Dietrich <enaut.w@googlemail.com>
Reported-and-tested-by: kloxdami@yahoo.com
Signed-off-by: Julian Sax <jsbc@gmx.de>
---
 drivers/hid/i2c-hid/Makefile                  |   3 +
 .../hid/i2c-hid/{i2c-hid.c => i2c-hid-core.c} |  54 ++++---
 drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c      | 149 ++++++++++++++++++
 drivers/hid/i2c-hid/i2c-hid.h                 |  17 ++
 4 files changed, 205 insertions(+), 18 deletions(-)
 rename drivers/hid/i2c-hid/{i2c-hid.c => i2c-hid-core.c} (96%)
 create mode 100644 drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
 create mode 100644 drivers/hid/i2c-hid/i2c-hid.h

Comments

Dmitry Torokhov May 30, 2018, 10:01 p.m. UTC | #1
On Tue, May 22, 2018 at 12:54 PM, Julian Sax <jsbc@gmx.de> wrote:
> A particular touchpad (SIPODEV SP1064) refuses to supply the HID
> descriptors. This patch provides the framework for overriding these
> descriptors based on DMI data. It also includes the descriptors for
> said touchpad, as well as the DMI data for the 4 laptops known to
> use this device.

I would love if we did not have to build these quirks into kernel.
Given that majority of HID devices are compiled as modules, can we try
using request_firmware("<vid>-<pid>.descr") and try to load descriptor
overrides from disk before during device initialization? That would
also allow dropping bunch of trivial HID drivers that contain trivial
descriptor fixups.

Thanks.
Hans de Goede May 31, 2018, 8:23 a.m. UTC | #2
Hi,

On 31-05-18 00:01, Dmitry Torokhov wrote:
> On Tue, May 22, 2018 at 12:54 PM, Julian Sax <jsbc@gmx.de> wrote:
>> A particular touchpad (SIPODEV SP1064) refuses to supply the HID
>> descriptors. This patch provides the framework for overriding these
>> descriptors based on DMI data. It also includes the descriptors for
>> said touchpad, as well as the DMI data for the 4 laptops known to
>> use this device.
> 
> I would love if we did not have to build these quirks into kernel.
> Given that majority of HID devices are compiled as modules, can we try
> using request_firmware("<vid>-<pid>.descr") and try to load descriptor
> overrides from disk before during device initialization?

That is an interesting idea and might be worth-while implementing,
but not to fix these touchpads / replace this patch.

The vid-pid itself comes from the i2c-hid descriptor (which is a HID
over i2c specific descriptor) and these devices do not report that
either, they talk HID (over i2c) but seem to rely on a Windows
filter driver to inject both the i2c-hid descriptor and the actual
HID descriptors.

We could modify Julian's patch to only provide a i2c-hid descriptor
override based on DMI strings, but I'm afraid that the hid/pid on
these cheap Chinese devices are not going to be unique. Actually
a quick duckduckgo for 0911:5288 finds that the Jumper EZBook 3 PRO,
which uses a clearly different touchpad (judging from pictures),
now we could make up our own vid:pid for these touchpads, but that
feels wrong.

I know this patch is not pretty, but it fixes the touchpad on a
number of (somewhat popular) budget notebooks, so I think we should
move forward with this patch.

I've given the patch a good look and it is:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jiri Kosina May 31, 2018, 8:47 a.m. UTC | #3
On Wed, 30 May 2018, Dmitry Torokhov wrote:

> > A particular touchpad (SIPODEV SP1064) refuses to supply the HID
> > descriptors. This patch provides the framework for overriding these
> > descriptors based on DMI data. It also includes the descriptors for
> > said touchpad, as well as the DMI data for the 4 laptops known to
> > use this device.
> 
> I would love if we did not have to build these quirks into kernel.
> Given that majority of HID devices are compiled as modules, can we try
> using request_firmware("<vid>-<pid>.descr") and try to load descriptor
> overrides from disk before during device initialization? That would
> also allow dropping bunch of trivial HID drivers that contain trivial
> descriptor fixups.

Yeah, this has been on my TODO for years, but I never had time to actually 
implement that :/

In case you have anyone asking the "I want to work on kernel, what should 
I do?", this might be one of the tasks.

Thanks,
Benjamin Tissoires May 31, 2018, 9:14 a.m. UTC | #4
On Thu, May 31, 2018 at 10:47 AM, Jiri Kosina <jikos@kernel.org> wrote:
> On Wed, 30 May 2018, Dmitry Torokhov wrote:
>
>> > A particular touchpad (SIPODEV SP1064) refuses to supply the HID
>> > descriptors. This patch provides the framework for overriding these
>> > descriptors based on DMI data. It also includes the descriptors for
>> > said touchpad, as well as the DMI data for the 4 laptops known to
>> > use this device.
>>
>> I would love if we did not have to build these quirks into kernel.
>> Given that majority of HID devices are compiled as modules, can we try
>> using request_firmware("<vid>-<pid>.descr") and try to load descriptor
>> overrides from disk before during device initialization? That would
>> also allow dropping bunch of trivial HID drivers that contain trivial
>> descriptor fixups.
>
> Yeah, this has been on my TODO for years, but I never had time to actually
> implement that :/
>
> In case you have anyone asking the "I want to work on kernel, what should
> I do?", this might be one of the tasks.

Actually, I started to work on that for the Wacom devices a while
back. I still have code to generate the firmware files and to load
them. It seemed to be working great but the problem is that this
doesn't complies properly with the initramfs.
Let say your device needs a report descriptor override, but it is not
in the initramfs. When you boot, the kernel detects it and then tries
to load the "firmware". This fails, but the device is actually
"working" from a HID point of view so it is presented to user space.
Now the initial setup is done, we switched root, and we have the
firmware available. How can we tell the previously configured device
that it needs to re-probe itself and load the firmware?

This last question I couldn't answer. And we (the Linux Wacom
engineers and I) managed to convinced the Wacom firmware team to
provide a HID compliant firmware, so I dropped the ball.

For the Wacom devices, the solution I ended up doing was either not
having the wacom.ko driver in initramfs (let's assume you don't type
your lucks password with a tablet), or force the firmwares in the
initramfs, which could lead to potentially a lot of wasted space.

Cheers,
Benjamin

>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Benjamin Tissoires June 7, 2018, 9:41 a.m. UTC | #5
On Thu, May 31, 2018 at 10:23 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 31-05-18 00:01, Dmitry Torokhov wrote:
>>
>> On Tue, May 22, 2018 at 12:54 PM, Julian Sax <jsbc@gmx.de> wrote:
>>>
>>> A particular touchpad (SIPODEV SP1064) refuses to supply the HID
>>> descriptors. This patch provides the framework for overriding these
>>> descriptors based on DMI data. It also includes the descriptors for
>>> said touchpad, as well as the DMI data for the 4 laptops known to
>>> use this device.
>>
>>
>> I would love if we did not have to build these quirks into kernel.
>> Given that majority of HID devices are compiled as modules, can we try
>> using request_firmware("<vid>-<pid>.descr") and try to load descriptor
>> overrides from disk before during device initialization?
>
>
> That is an interesting idea and might be worth-while implementing,
> but not to fix these touchpads / replace this patch.
>
> The vid-pid itself comes from the i2c-hid descriptor (which is a HID
> over i2c specific descriptor) and these devices do not report that
> either, they talk HID (over i2c) but seem to rely on a Windows
> filter driver to inject both the i2c-hid descriptor and the actual
> HID descriptors.
>
> We could modify Julian's patch to only provide a i2c-hid descriptor
> override based on DMI strings, but I'm afraid that the hid/pid on
> these cheap Chinese devices are not going to be unique. Actually
> a quick duckduckgo for 0911:5288 finds that the Jumper EZBook 3 PRO,
> which uses a clearly different touchpad (judging from pictures),
> now we could make up our own vid:pid for these touchpads, but that
> feels wrong.
>
> I know this patch is not pretty, but it fixes the touchpad on a
> number of (somewhat popular) budget notebooks, so I think we should
> move forward with this patch.
>
> I've given the patch a good look and it is:
>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>

FWIW, Hans just pinged me again regarding this. Given that it is
sitting on the list for 2 weeks now and that it is not pretty but
fixes issues users are seeing, I am giving my:
Acked-By: Benjamin Tissoires <benjamin.tissoires@redhat.com>

I would also love to move this in out of the tree firmwares, but
currently -ETIME from me.

Cheers,
Benjamin

>
> Regards,
>
> Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jiri Kosina June 11, 2018, 2:08 p.m. UTC | #6
On Tue, 22 May 2018, Julian Sax wrote:

> A particular touchpad (SIPODEV SP1064) refuses to supply the HID
> descriptors. This patch provides the framework for overriding these
> descriptors based on DMI data. It also includes the descriptors for
> said touchpad, as well as the DMI data for the 4 laptops known to
> use this device.
> 
> Relevant Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1526312
> 
> Cc: Hans de Goede <hdegoede@redhat.com>
> Reported-and-tested-by: ahormann@gmx.net
> Reported-and-tested-by: Bruno Jesus <bruno.fl.jesus@gmail.com>
> Reported-and-tested-by: Dietrich <enaut.w@googlemail.com>
> Reported-and-tested-by: kloxdami@yahoo.com
> Signed-off-by: Julian Sax <jsbc@gmx.de>

Applied (and yeah, it'd be marvelous to have some better way of replacing 
HID descriptors one day).

Thanks,
diff mbox

Patch

diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile
index 832d8f9aaba2..099e1ce2f234 100644
--- a/drivers/hid/i2c-hid/Makefile
+++ b/drivers/hid/i2c-hid/Makefile
@@ -3,3 +3,6 @@ 
 #
 
 obj-$(CONFIG_I2C_HID)				+= i2c-hid.o
+
+i2c-hid-objs					=  i2c-hid-core.o
+i2c-hid-$(CONFIG_DMI)				+= i2c-hid-dmi-quirks.o
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid-core.c
similarity index 96%
rename from drivers/hid/i2c-hid/i2c-hid.c
rename to drivers/hid/i2c-hid/i2c-hid-core.c
index cc33622253aa..3cdd1e1aeb95 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -43,6 +43,7 @@ 
 #include <linux/platform_data/i2c-hid.h>
 
 #include "../hid-ids.h"
+#include "i2c-hid.h"
 
 /* quirks to control the device */
 #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV	BIT(0)
@@ -673,6 +674,7 @@  static int i2c_hid_parse(struct hid_device *hid)
 	char *rdesc;
 	int ret;
 	int tries = 3;
+	char *use_override;
 
 	i2c_hid_dbg(ihid, "entering %s\n", __func__);
 
@@ -691,26 +693,36 @@  static int i2c_hid_parse(struct hid_device *hid)
 	if (ret)
 		return ret;
 
-	rdesc = kzalloc(rsize, GFP_KERNEL);
+	use_override = i2c_hid_get_dmi_hid_report_desc_override(&rsize);
 
-	if (!rdesc) {
-		dbg_hid("couldn't allocate rdesc memory\n");
-		return -ENOMEM;
-	}
+	if (use_override) {
+		rdesc = use_override;
+		i2c_hid_dbg(ihid, "Using a HID report descriptor override\n");
+	} else {
+		rdesc = kzalloc(rsize, GFP_KERNEL);
 
-	i2c_hid_dbg(ihid, "asking HID report descriptor\n");
+		if (!rdesc) {
+			dbg_hid("couldn't allocate rdesc memory\n");
+			return -ENOMEM;
+		}
 
-	ret = i2c_hid_command(client, &hid_report_descr_cmd, rdesc, rsize);
-	if (ret) {
-		hid_err(hid, "reading report descriptor failed\n");
-		kfree(rdesc);
-		return -EIO;
+		i2c_hid_dbg(ihid, "asking HID report descriptor\n");
+
+		ret = i2c_hid_command(client, &hid_report_descr_cmd,
+				      rdesc, rsize);
+		if (ret) {
+			hid_err(hid, "reading report descriptor failed\n");
+			kfree(rdesc);
+			return -EIO;
+		}
 	}
 
 	i2c_hid_dbg(ihid, "Report Descriptor: %*ph\n", rsize, rdesc);
 
 	ret = hid_parse_report(hid, rdesc, rsize);
-	kfree(rdesc);
+	if (!use_override)
+		kfree(rdesc);
+
 	if (ret) {
 		dbg_hid("parsing report descriptor failed\n");
 		return ret;
@@ -837,12 +849,18 @@  static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
 	int ret;
 
 	/* i2c hid fetch using a fixed descriptor size (30 bytes) */
-	i2c_hid_dbg(ihid, "Fetching the HID descriptor\n");
-	ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer,
-				sizeof(struct i2c_hid_desc));
-	if (ret) {
-		dev_err(&client->dev, "hid_descr_cmd failed\n");
-		return -ENODEV;
+	if (i2c_hid_get_dmi_i2c_hid_desc_override()) {
+		i2c_hid_dbg(ihid, "Using a HID descriptor override\n");
+		ihid->hdesc = *i2c_hid_get_dmi_i2c_hid_desc_override();
+	} else {
+		i2c_hid_dbg(ihid, "Fetching the HID descriptor\n");
+		ret = i2c_hid_command(client, &hid_descr_cmd,
+				      ihid->hdesc_buffer,
+				      sizeof(struct i2c_hid_desc));
+		if (ret) {
+			dev_err(&client->dev, "hid_descr_cmd failed\n");
+			return -ENODEV;
+		}
 	}
 
 	/* Validate the length of HID descriptor, the 4 first bytes:
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
new file mode 100644
index 000000000000..400f076c6be3
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
@@ -0,0 +1,149 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Quirks for I2C-HID devices that do not supply proper descriptors
+ *
+ * Copyright (c) 2018 Julian Sax <jsbc@gmx.de>
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/dmi.h>
+#include <linux/mod_devicetable.h>
+
+#include "i2c-hid.h"
+
+
+struct i2c_hid_desc_override {
+	union {
+		struct i2c_hid_desc *i2c_hid_desc;
+		uint8_t             *i2c_hid_desc_buffer;
+	};
+	uint8_t              *hid_report_desc;
+	unsigned int          hid_report_desc_size;
+};
+
+
+/* descriptors for the SIPODEV SP1064 touchpad */
+static const struct i2c_hid_desc_override sipodev_desc = {
+	.i2c_hid_desc_buffer = (uint8_t [])
+	{0x1e, 0x00, 0x00, 0x01, 0xdb, 0x01, 0x21, 0x00, 0x24, 0x00,
+	 0x1b, 0x00, 0x25, 0x00, 0x11, 0x00, 0x22, 0x00, 0x23, 0x00,
+	 0x11, 0x09, 0x88, 0x52, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
+
+	.hid_report_desc = (uint8_t [])
+	{0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x01,
+	 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x02, 0x25, 0x01,
+	 0x75, 0x01, 0x95, 0x02, 0x81, 0x02, 0x95, 0x06, 0x81, 0x01,
+	 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, 0x25, 0x7f,
+	 0x75, 0x08, 0x95, 0x02, 0x81, 0x06, 0xc0, 0xc0, 0x05, 0x0d,
+	 0x09, 0x05, 0xa1, 0x01, 0x85, 0x04, 0x05, 0x0d, 0x09, 0x22,
+	 0xa1, 0x02, 0x15, 0x00, 0x25, 0x01, 0x09, 0x47, 0x09, 0x42,
+	 0x95, 0x02, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x03,
+	 0x25, 0x05, 0x09, 0x51, 0x81, 0x02, 0x75, 0x01, 0x95, 0x03,
+	 0x81, 0x03, 0x05, 0x01, 0x26, 0x44, 0x0a, 0x75, 0x10, 0x55,
+	 0x0e, 0x65, 0x11, 0x09, 0x30, 0x46, 0x1a, 0x04, 0x95, 0x01,
+	 0x81, 0x02, 0x46, 0xbc, 0x02, 0x26, 0x34, 0x05, 0x09, 0x31,
+	 0x81, 0x02, 0xc0, 0x05, 0x0d, 0x09, 0x22, 0xa1, 0x02, 0x25,
+	 0x01, 0x09, 0x47, 0x09, 0x42, 0x95, 0x02, 0x75, 0x01, 0x81,
+	 0x02, 0x95, 0x01, 0x75, 0x03, 0x25, 0x05, 0x09, 0x51, 0x81,
+	 0x02, 0x75, 0x01, 0x95, 0x03, 0x81, 0x03, 0x05, 0x01, 0x26,
+	 0x44, 0x0a, 0x75, 0x10, 0x09, 0x30, 0x46, 0x1a, 0x04, 0x95,
+	 0x01, 0x81, 0x02, 0x46, 0xbc, 0x02, 0x26, 0x34, 0x05, 0x09,
+	 0x31, 0x81, 0x02, 0xc0, 0x05, 0x0d, 0x09, 0x22, 0xa1, 0x02,
+	 0x25, 0x01, 0x09, 0x47, 0x09, 0x42, 0x95, 0x02, 0x75, 0x01,
+	 0x81, 0x02, 0x95, 0x01, 0x75, 0x03, 0x25, 0x05, 0x09, 0x51,
+	 0x81, 0x02, 0x75, 0x01, 0x95, 0x03, 0x81, 0x03, 0x05, 0x01,
+	 0x26, 0x44, 0x0a, 0x75, 0x10, 0x09, 0x30, 0x46, 0x1a, 0x04,
+	 0x95, 0x01, 0x81, 0x02, 0x46, 0xbc, 0x02, 0x26, 0x34, 0x05,
+	 0x09, 0x31, 0x81, 0x02, 0xc0, 0x05, 0x0d, 0x09, 0x22, 0xa1,
+	 0x02, 0x25, 0x01, 0x09, 0x47, 0x09, 0x42, 0x95, 0x02, 0x75,
+	 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x03, 0x25, 0x05, 0x09,
+	 0x51, 0x81, 0x02, 0x75, 0x01, 0x95, 0x03, 0x81, 0x03, 0x05,
+	 0x01, 0x26, 0x44, 0x0a, 0x75, 0x10, 0x09, 0x30, 0x46, 0x1a,
+	 0x04, 0x95, 0x01, 0x81, 0x02, 0x46, 0xbc, 0x02, 0x26, 0x34,
+	 0x05, 0x09, 0x31, 0x81, 0x02, 0xc0, 0x05, 0x0d, 0x55, 0x0c,
+	 0x66, 0x01, 0x10, 0x47, 0xff, 0xff, 0x00, 0x00, 0x27, 0xff,
+	 0xff, 0x00, 0x00, 0x75, 0x10, 0x95, 0x01, 0x09, 0x56, 0x81,
+	 0x02, 0x09, 0x54, 0x25, 0x7f, 0x75, 0x08, 0x81, 0x02, 0x05,
+	 0x09, 0x09, 0x01, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81,
+	 0x02, 0x95, 0x07, 0x81, 0x03, 0x05, 0x0d, 0x85, 0x02, 0x09,
+	 0x55, 0x09, 0x59, 0x75, 0x04, 0x95, 0x02, 0x25, 0x0f, 0xb1,
+	 0x02, 0x05, 0x0d, 0x85, 0x07, 0x09, 0x60, 0x75, 0x01, 0x95,
+	 0x01, 0x25, 0x01, 0xb1, 0x02, 0x95, 0x07, 0xb1, 0x03, 0x85,
+	 0x06, 0x06, 0x00, 0xff, 0x09, 0xc5, 0x26, 0xff, 0x00, 0x75,
+	 0x08, 0x96, 0x00, 0x01, 0xb1, 0x02, 0xc0, 0x06, 0x00, 0xff,
+	 0x09, 0x01, 0xa1, 0x01, 0x85, 0x0d, 0x26, 0xff, 0x00, 0x19,
+	 0x01, 0x29, 0x02, 0x75, 0x08, 0x95, 0x02, 0xb1, 0x02, 0xc0,
+	 0x05, 0x0d, 0x09, 0x0e, 0xa1, 0x01, 0x85, 0x03, 0x09, 0x22,
+	 0xa1, 0x02, 0x09, 0x52, 0x25, 0x0a, 0x95, 0x01, 0xb1, 0x02,
+	 0xc0, 0x09, 0x22, 0xa1, 0x00, 0x85, 0x05, 0x09, 0x57, 0x09,
+	 0x58, 0x75, 0x01, 0x95, 0x02, 0x25, 0x01, 0xb1, 0x02, 0x95,
+	 0x06, 0xb1, 0x03, 0xc0, 0xc0 },
+	.hid_report_desc_size = 475
+};
+
+
+static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
+	{
+		.ident = "Teclast F6 Pro",
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F6 Pro"),
+		},
+		.driver_data = (void *)&sipodev_desc
+	},
+	{
+		.ident = "Teclast F7",
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F7"),
+		},
+		.driver_data = (void *)&sipodev_desc
+	},
+	{
+		.ident = "Trekstor Primebook C13",
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
+		},
+		.driver_data = (void *)&sipodev_desc
+	},
+	{
+		.ident = "Trekstor Primebook C11",
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
+		},
+		.driver_data = (void *)&sipodev_desc
+	}
+};
+
+
+struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(void)
+{
+	struct i2c_hid_desc_override *override;
+	const struct dmi_system_id *system_id;
+
+	system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
+	if (!system_id)
+		return NULL;
+
+	override = system_id->driver_data;
+	return override->i2c_hid_desc;
+}
+
+char *i2c_hid_get_dmi_hid_report_desc_override(unsigned int *size)
+{
+	struct i2c_hid_desc_override *override;
+	const struct dmi_system_id *system_id;
+
+	system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
+	if (!system_id)
+		return NULL;
+
+	override = system_id->driver_data;
+	*size = override->hid_report_desc_size;
+	return override->hid_report_desc;
+}
+
diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h
new file mode 100644
index 000000000000..c543bb5ef1c1
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid.h
@@ -0,0 +1,17 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef I2C_HID_H
+#define I2C_HID_H
+
+
+#ifdef CONFIG_DMI
+struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(void);
+char *i2c_hid_get_dmi_hid_report_desc_override(unsigned int *size);
+#else
+static inline struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(void)
+{ return NULL; }
+static inline char *i2c_hid_get_dmi_hid_report_desc_override(unsigned int *size)
+{ return NULL; }
+#endif
+
+#endif