Skip to content

Instantly share code, notes, and snippets.

@papodaca
Last active September 15, 2018 19:56
Show Gist options
  • Save papodaca/6496dd3ae77e8a3d6eddcee1fee3d58e to your computer and use it in GitHub Desktop.
Save papodaca/6496dd3ae77e8a3d6eddcee1fee3d58e to your computer and use it in GitHub Desktop.
kernel patch for teclast f7 touchpad
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index eae0cb3ddec6..cce5c43b9bc2 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -47,7 +47,86 @@
/* quirks to control the device */
#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0)
#define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
-#define I2C_HID_QUIRK_RESEND_REPORT_DESCR BIT(2)
+
+/* quirk for SIPODEV SP1064 aka SYNA3602 */
+#define SIPODEV_QUIRK
+
+#ifdef SIPODEV_QUIRK
+static unsigned char hiddesc_quirk[]={ 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 };
+
+static unsigned char rdesc_quirk[] = { 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 };
+#endif
/* flags */
#define I2C_HID_STARTED 0
@@ -131,6 +210,8 @@ static const struct i2c_hid_cmd hid_no_cmd = { .length = 0 };
* static const struct i2c_hid_cmd hid_set_protocol_cmd = { I2C_HID_CMD(0x07) };
*/
+static DEFINE_MUTEX(i2c_hid_open_mut);
+
/* The main device structure */
struct i2c_hid {
struct i2c_client *client; /* i2c client */
@@ -143,10 +224,10 @@ struct i2c_hid {
* register of the HID
* descriptor. */
unsigned int bufsize; /* i2c buffer size */
- u8 *inbuf; /* Input buffer */
- u8 *rawbuf; /* Raw Input buffer */
- u8 *cmdbuf; /* Command buffer */
- u8 *argsbuf; /* Command arguments buffer */
+ char *inbuf; /* Input buffer */
+ char *rawbuf; /* Raw Input buffer */
+ char *cmdbuf; /* Command buffer */
+ char *argsbuf; /* Command arguments buffer */
unsigned long flags; /* device flags */
unsigned long quirks; /* Various quirks */
@@ -170,10 +251,6 @@ static const struct i2c_hid_quirks {
I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
- { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
- I2C_HID_QUIRK_RESEND_REPORT_DESCR },
- { USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS10FB_TOUCH,
- I2C_HID_QUIRK_RESEND_REPORT_DESCR },
{ 0, 0 }
};
@@ -458,8 +535,7 @@ static int i2c_hid_hwreset(struct i2c_client *client)
static void i2c_hid_get_input(struct i2c_hid *ihid)
{
- int ret;
- u32 ret_size;
+ int ret, ret_size;
int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
if (size > ihid->bufsize)
@@ -484,7 +560,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
return;
}
- if ((ret_size > size) || (ret_size < 2)) {
+ if (ret_size > size) {
dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
__func__, size, ret_size);
return;
@@ -705,6 +781,12 @@ static int i2c_hid_parse(struct hid_device *hid)
return -EIO;
}
+#ifdef SIPODEV_QUIRK
+ int i;
+ for(i=0;i<sizeof(rdesc_quirk);i++)
+ rdesc[i]=rdesc_quirk[i];
+#endif
+
i2c_hid_dbg(ihid, "Report Descriptor: %*ph\n", rsize, rdesc);
ret = hid_parse_report(hid, rdesc, rsize);
@@ -843,6 +925,12 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
return -ENODEV;
}
+#ifdef SIPODEV_QUIRK
+ int i;
+ for(i=0;i<sizeof(hiddesc_quirk);i++)
+ ihid->hdesc_buffer[i]=hiddesc_quirk[i];
+#endif
+
/* Validate the length of HID descriptor, the 4 first bytes:
* bytes 0-1 -> length
* bytes 2-3 -> bcdVersion (has to be 1.00) */
@@ -866,15 +954,6 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
}
#ifdef CONFIG_ACPI
-static const struct acpi_device_id i2c_hid_acpi_blacklist[] = {
- /*
- * The CHPN0001 ACPI device, which is used to describe the Chipone
- * ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible.
- */
- {"CHPN0001", 0 },
- { },
-};
-
static int i2c_hid_acpi_pdata(struct i2c_client *client,
struct i2c_hid_platform_data *pdata)
{
@@ -886,18 +965,13 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
acpi_handle handle;
handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
-
- if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0)
+ if (!handle || acpi_bus_get_device(handle, &adev))
return -ENODEV;
obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL,
ACPI_TYPE_INTEGER);
if (!obj) {
- dev_err(&client->dev, "Error _DSM call to get HID descriptor address failed\n");
+ dev_err(&client->dev, "device _DSM execution failed\n");
return -ENODEV;
}
@@ -909,10 +983,10 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
static void i2c_hid_acpi_fix_up_power(struct device *dev)
{
+ acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_device *adev;
- adev = ACPI_COMPANION(dev);
- if (adev)
+ if (handle && acpi_bus_get_device(handle, &adev) == 0)
acpi_device_fix_up_power(adev);
}
@@ -1012,8 +1086,11 @@ static int i2c_hid_probe(struct i2c_client *client,
goto err;
} else if (!platform_data) {
ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
- if (ret)
+ if (ret) {
+ dev_err(&client->dev,
+ "HID register address not provided\n");
goto err;
+ }
} else {
ihid->pdata = *platform_data;
}
@@ -1063,14 +1140,6 @@ static int i2c_hid_probe(struct i2c_client *client,
pm_runtime_enable(&client->dev);
device_enable_async_suspend(&client->dev);
- /* Make sure there is something at this address */
- ret = i2c_smbus_read_byte(client);
- if (ret < 0) {
- dev_dbg(&client->dev, "nothing at this address: %d\n", ret);
- ret = -ENXIO;
- goto err_pm;
- }
-
ret = i2c_hid_fetch_hid_descriptor(ihid);
if (ret < 0)
goto err_pm;
@@ -1242,16 +1311,6 @@ static int i2c_hid_resume(struct device *dev)
if (ret)
return ret;
- /* RAYDIUM device (2386:3118) need to re-send report descr cmd
- * after resume, after this it will be back normal.
- * otherwise it issues too many incomplete reports.
- */
- if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) {
- ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0);
- if (ret)
- return ret;
- }
-
if (hid->driver && hid->driver->reset_resume) {
ret = hid->driver->reset_resume(hid);
return ret;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment