diff --git a/device/linux-chuwi-hi10plus/0001-input-touchscreen-gslx680_ts_acpi-Add-driver-from-on.patch b/device/linux-chuwi-hi10plus/0001-input-touchscreen-gslx680_ts_acpi-Add-driver-from-on.patch deleted file mode 100644 index 3bc07b07b..000000000 --- a/device/linux-chuwi-hi10plus/0001-input-touchscreen-gslx680_ts_acpi-Add-driver-from-on.patch +++ /dev/null @@ -1,824 +0,0 @@ -From 2526b028584e38e8becb690bbe8b3a74bbfe36b1 Mon Sep 17 00:00:00 2001 -From: Danct12 -Date: Tue, 14 May 2019 17:33:56 +0700 -Subject: [PATCH] input: touchscreen: gslx680_ts_acpi: Add driver from onitake. - ---- - drivers/input/touchscreen/Kconfig | 10 + - drivers/input/touchscreen/Makefile | 1 + - drivers/input/touchscreen/gslx680_ts_acpi.c | 775 ++++++++++++++++++++ - 3 files changed, 786 insertions(+) - create mode 100644 drivers/input/touchscreen/gslx680_ts_acpi.c - -diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 7a4884ad198b..9cf92795bf87 100644 ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -1312,4 +1312,14 @@ config TOUCHSCREEN_ROHM_BU21023 - To compile this driver as a module, choose M here: the - module will be called bu21023_ts. - -+config TOUCHSCREEN_GSLX680 -+ tristate "Silead GSLX680 Touch Screen Driver" -+ depends on I2C -+ help -+ Say Y here if you have a touchscreen using Silead GSL1680/GSL3680. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called gslx680_ts_acpi. - endif -diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index fcc7605fba8d..2b77586bef53 100644 ---- a/drivers/input/touchscreen/Makefile -+++ b/drivers/input/touchscreen/Makefile -@@ -110,3 +110,4 @@ obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o - obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o - obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o - obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o -+obj-$(CONFIG_TOUCHSCREEN_GSLX680) += gslx680_ts_acpi.o -diff --git a/drivers/input/touchscreen/gslx680_ts_acpi.c b/drivers/input/touchscreen/gslx680_ts_acpi.c -new file mode 100644 -index 000000000000..748cedb2f13b ---- /dev/null -+++ b/drivers/input/touchscreen/gslx680_ts_acpi.c -@@ -0,0 +1,775 @@ -+/* -+ * Silead GSL1680/3680 touchscreen driver -+ * -+ * Copyright (c) 2015 Gregor Riepl -+ * -+ * This driver is based on gslx680_ts.c and elan_ts.c -+ * Copyright (c) 2012 Shanghai Basewin -+ * Guan Yuwei -+ * Copyright (c) 2013 Joe Burmeister -+ * Joe Burmeister -+ * Copyright (C) 2014 Elan Microelectronics Corporation. -+ * Scott Liu -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Device and driver information */ -+#define DEVICE_NAME "gslx680" -+#define DRIVER_VERSION "0.2.1" -+ -+/* Hardware API constants */ -+#define GSL_DATA_REG 0x80 -+#define GSL_STATUS_REG 0xe0 -+#define GSL_PAGE_REG 0xf0 -+#define GSL_TOUCH_STATUS_REG 0xbc -+#define GSL_PAGE_SIZE 128 -+/* Why 126? */ -+#define GSL_MAX_READ 126 -+/* Actually 129: 1 command byte and 128 data bytes -+ * this was 125 originally - using 128 to allow firmware transfers -+ */ -+#define GSL_MAX_WRITE 128 -+#define GSL_STATUS_FW 0x80 -+#define GSL_STATUS_TOUCH 0x00 -+ -+#define GSL_PWR_GPIO "power" -+ -+#define GSL_MAX_CONTACTS 10 -+#define GSL_MAX_AXIS 0xfff -+#define GSL_DMAX 0 -+#define GSL_JITTER 0 -+#define GSL_DEADZONE 0 -+ -+#define GSL_PACKET_SIZE ( \ -+ GSL_MAX_CONTACTS * sizeof(struct gsl_ts_packet_touch) + \ -+ sizeof(struct gsl_ts_packet_header) \ -+) -+ -+#define GSL_FW_NAME_MAXLEN 32 -+#define GSL_FW_NAME_DEFAULT "silead_ts.fw" -+#define GSL_FW_VERSION 1 -+#define GSL_FW_ID_LIT(a, b, c, d) ( \ -+ ((a) & 0xff) | \ -+ (((b) & 0xff) << 8) | \ -+ (((c) & 0xff) << 16) | \ -+ (((d) & 0xff) << 24) \ -+) -+#define GSL_FW_MAGIC GSL_FW_ID_LIT('G', 'S', 'L', 'X') -+#define GSL_FW_MODEL_LIT(m) GSL_FW_ID_LIT( \ -+ (m)/1000%10+'0', \ -+ (m)/100%10+'0', \ -+ (m)/10%10+'0', \ -+ (m)%10+'0' \ -+) -+#define GSL_FW_MODEL_1680 GSL_FW_MODEL_LIT(1680) -+ -+/* Module Parameters (optional) */ -+static char *gsl_fw_name = NULL; -+module_param_named(fw_name, gsl_fw_name, charp, 0); -+ -+/* Driver state */ -+enum gsl_ts_state { -+ GSL_TS_INIT, -+ GSL_TS_SHUTDOWN, -+ GSL_TS_GREEN, -+}; -+ -+/* Driver instance data structure */ -+struct gsl_ts_data { -+ struct i2c_client *client; -+ struct input_dev *input; -+ struct gpio_desc *gpio; -+ char fw_name[GSL_FW_NAME_MAXLEN]; -+ -+ enum gsl_ts_state state; -+ -+ bool wake_irq_enabled; -+ -+ unsigned int x_max; -+ unsigned int y_max; -+ unsigned int multi_touches; -+ bool x_reversed; -+ bool y_reversed; -+ bool xy_swapped; -+ bool soft_tracking; -+ int jitter; -+ int deadzone; -+}; -+ -+/* Firmware header */ -+struct gsl_ts_fw_header { -+ u32 magic; -+ u32 model; -+ u16 version; -+ u16 touches; -+ u16 width; -+ u16 height; -+ u8 swapped; -+ u8 xflipped; -+ u8 yflipped; -+ u8 tracking; -+ u32 pages; -+} __packed; -+/* Firmware data page */ -+struct gsl_ts_fw_page { -+ u16 address; -+ u16 size; -+ u8 data[128]; -+} __packed; -+ -+/* TODO use get_unaligned_le16 instead of packed structures */ -+/* Hardware touch event data header */ -+struct gsl_ts_packet_header { -+ u8 num_fingers; -+ u8 reserved; -+ u16 time_stamp; /* little-endian */ -+} __packed; -+/* Hardware touch event data per finger */ -+struct gsl_ts_packet_touch { -+ u16 y_z; /* little endian, lower 12 bits = y, upper 4 bits = pressure (?) */ -+ u16 x_id; /* little endian, lower 12 bits = x, upper 4 bits = id */ -+} __packed; -+ -+ -+static int gsl_ts_init(struct gsl_ts_data *ts, const struct firmware *fw) -+{ -+ struct gsl_ts_fw_header *header; -+ u32 magic; -+ u16 version; -+ -+ dev_dbg(&ts->client->dev, "%s: initialising driver state\n", __func__); -+ -+ ts->wake_irq_enabled = false; -+ ts->state = GSL_TS_INIT; -+ -+ if (fw->size < sizeof(struct gsl_ts_fw_header)) { -+ dev_err(&ts->client->dev, "%s: invalid firmware: file too small.\n", __func__); -+ return -EINVAL; -+ } -+ -+ header = (struct gsl_ts_fw_header *) fw->data; -+ magic = le32_to_cpu(header->magic); -+ if (magic != GSL_FW_MAGIC) { -+ dev_err(&ts->client->dev, "%s: invalid firmware: invalid magic 0x%08x.\n", __func__, magic); -+ return -EINVAL; -+ } -+ -+ version = le16_to_cpu(header->version); -+ if (version != GSL_FW_VERSION) { -+ dev_err(&ts->client->dev, "%s: invalid firmware: unsupported version %d.\n", __func__, version); -+ return -EINVAL; -+ } -+ -+ ts->x_max = le16_to_cpu(header->width); -+ ts->y_max = le16_to_cpu(header->height); -+ ts->multi_touches = le16_to_cpu(header->touches); -+ if (ts->x_max == 0 || ts->y_max == 0 || ts->multi_touches == 0) { -+ dev_err(&ts->client->dev, "%s: invalid firmware: panel width, height or number of touch points is zero.\n", __func__); -+ return -EINVAL; -+ } -+ if (ts->x_max > GSL_MAX_AXIS || ts->y_max > GSL_MAX_AXIS || ts->multi_touches > GSL_MAX_CONTACTS) { -+ dev_err(&ts->client->dev, "%s: invalid firmware: maximum panel width, height or number of touch points exceeded.\n", __func__); -+ return -EINVAL; -+ } -+ -+ ts->x_reversed = header->xflipped ? 1 : 0; -+ ts->y_reversed = header->yflipped ? 1 : 0; -+ ts->xy_swapped = header->swapped ? 1 : 0; -+ ts->soft_tracking = header->tracking ? 1 : 0; -+ ts->jitter = GSL_JITTER; -+ ts->deadzone = GSL_DEADZONE; -+ -+ return 0; -+} -+ -+static int gsl_ts_write(struct i2c_client *client, u8 reg, const u8 *pdata, int datalen) -+{ -+ u8 buf[GSL_PAGE_SIZE + 1]; -+ unsigned int bytelen = 0; -+ -+ if (datalen > GSL_MAX_WRITE) { -+ dev_err(&client->dev, "%s: data transfer too large (%d > %d)\n", __func__, datalen, GSL_MAX_WRITE); -+ return -EINVAL; -+ } -+ -+ buf[0] = reg; -+ bytelen++; -+ -+ if (datalen != 0 && pdata != NULL) { -+ memcpy(&buf[bytelen], pdata, datalen); -+ bytelen += datalen; -+ } -+ -+ return i2c_master_send(client, buf, bytelen); -+} -+ -+static int gsl_ts_read(struct i2c_client *client, u8 reg, u8 *pdata, unsigned int datalen) -+{ -+ int ret = 0; -+ -+ if (datalen > GSL_MAX_READ) { -+ dev_err(&client->dev, "%s: data transfer too large (%d > %d)\n", __func__, datalen, GSL_MAX_READ); -+ return -EINVAL; -+ } -+ -+ ret = gsl_ts_write(client, reg, NULL, 0); -+ if (ret < 0) { -+ dev_err(&client->dev, "%s: sending register location failed\n", __func__); -+ return ret; -+ } -+ -+ return i2c_master_recv(client, pdata, datalen); -+} -+ -+static int gsl_ts_startup_chip(struct i2c_client *client) -+{ -+ int rc; -+ u8 tmp = 0x00; -+ -+ dev_dbg(&client->dev, "%s: starting up\n", __func__); -+ rc = gsl_ts_write(client, 0xe0, &tmp, 1); -+ usleep_range(10000, 20000); -+ -+ return rc; -+} -+ -+static int gsl_ts_reset_chip(struct i2c_client *client) -+{ -+ int rc; -+ u8 arg[4] = { 0x00, 0x00, 0x00, 0x00 }; -+ -+ dev_dbg(&client->dev, "%s: resetting\n", __func__); -+ -+ arg[0] = 0x88; -+ rc = gsl_ts_write(client, 0xe0, arg, 1); -+ if (rc < 0) { -+ dev_err(&client->dev, "%s: gsl_ts_write 1 fail!\n", __func__); -+ return rc; -+ } -+ usleep_range(10000, 20000); -+ -+ arg[0] = 0x04; -+ rc = gsl_ts_write(client, 0xe4, arg, 1); -+ if (rc < 0) { -+ dev_err(&client->dev, "%s: gsl_ts_write 2 fail!\n", __func__); -+ return rc; -+ } -+ usleep_range(10000, 20000); -+ -+ arg[0] = 0x00; -+ rc = gsl_ts_write(client, 0xbc, arg, 4); -+ if (rc < 0) { -+ dev_err(&client->dev, "%s: gsl_ts_write 3 fail!\n", __func__); -+ return rc; -+ } -+ usleep_range(10000, 20000); -+ -+ return 0; -+} -+ -+static int gsl_ts_write_fw(struct gsl_ts_data *ts, const struct firmware *fw) -+{ -+ int rc = 0; -+ struct i2c_client *client = ts->client; -+ const struct gsl_ts_fw_header *header; -+ const struct gsl_ts_fw_page *page; -+ u32 pages, address; -+ u16 size; -+ size_t i; -+ -+ dev_dbg(&client->dev, "%s: sending firmware\n", __func__); -+ -+ header = (const struct gsl_ts_fw_header *) fw->data; -+ pages = le32_to_cpu(header->pages); -+ if (fw->size < sizeof(struct gsl_ts_fw_header) + pages * sizeof(struct gsl_ts_fw_page)) { -+ dev_err(&client->dev, "%s: firmware page data too small.\n", __func__); -+ return -EINVAL; -+ } -+ -+ for (i = 0; rc >= 0 && i < pages; i++) { -+ page = (const struct gsl_ts_fw_page *) &fw->data[sizeof(struct gsl_ts_fw_header) + i * sizeof(struct gsl_ts_fw_page)]; -+ /* The controller expects a little endian address */ -+ address = cpu_to_le32(le16_to_cpu(page->address)); -+ size = le16_to_cpu(page->size); -+ rc = gsl_ts_write(client, GSL_PAGE_REG, (u8 *) &address, sizeof(address)); -+ if (rc < 0) { -+ dev_err(&client->dev, "%s: error setting page register. (page = 0x%x)\n", __func__, le32_to_cpu(address)); -+ } else { -+ rc = gsl_ts_write(client, 0, page->data, size); -+ if (rc < 0) { -+ dev_err(&client->dev, "%s: error writing page data. (page = 0x%x)\n", __func__, le32_to_cpu(address)); -+ } -+ } -+ } -+ -+ if (rc < 0) { -+ return rc; -+ } -+ return 0; -+} -+ -+static void gsl_ts_mt_event(struct gsl_ts_data *ts, u8 *buf) -+{ -+ int rc; -+ struct input_dev *input = ts->input; -+ struct device *dev = &ts->client->dev; -+ struct gsl_ts_packet_header *header; -+ struct gsl_ts_packet_touch *touch; -+ u8 i; -+ u16 touches, tseq, x, y, id, pressure; -+ struct input_mt_pos positions[GSL_MAX_CONTACTS]; -+ int slots[GSL_MAX_CONTACTS]; -+ -+ header = (struct gsl_ts_packet_header *) buf; -+ touches = header->num_fingers; -+ tseq = le16_to_cpu(header->time_stamp); -+ /* time_stamp is 0 on zero-touch events, seems to wrap around 21800 */ -+ dev_vdbg(dev, "%s: got touch events for %u fingers @%u\n", __func__, touches, tseq); -+ -+ if (touches > GSL_MAX_CONTACTS) { -+ touches = GSL_MAX_CONTACTS; -+ } -+ -+ for (i = 0; i < touches; i++) { -+ touch = (struct gsl_ts_packet_touch *) &buf[sizeof(*header) + i * sizeof(*touch)]; -+ y = le16_to_cpu(touch->y_z); -+ x = le16_to_cpu(touch->x_id); -+ id = x >> 12; -+ x &= 0xfff; -+ pressure = y >> 12; -+ y &= 0xfff; -+ -+ if (ts->xy_swapped) { -+ swap(x, y); -+ } -+ if (ts->x_reversed) { -+ x = ts->x_max - x; -+ } -+ if (ts->y_reversed) { -+ y = ts->y_max - y; -+ } -+ -+ dev_vdbg(dev, "%s: touch event %u: x=%u y=%u id=0x%x p=%u\n", __func__, i, x, y, id, pressure); -+ -+ positions[i].x = x; -+ positions[i].y = y; -+ if (!ts->soft_tracking) { -+ slots[i] = id; -+ } -+ } -+ if (ts->soft_tracking) { -+ /* This platform does not support finger tracking. -+ * Use the input core finger tracker instead. -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -+ rc = input_mt_assign_slots(input, slots, positions, touches); -+#else -+ rc = input_mt_assign_slots(input, slots, positions, touches, GSL_DMAX); -+#endif -+ if (rc < 0) { -+ dev_err(dev, "%s: input_mt_assign_slots returned %d\n", __func__, rc); -+ return; -+ } -+ } -+ -+ for (i = 0; i < touches; i++) { -+ input_mt_slot(input, slots[i]); -+ input_mt_report_slot_state(input, MT_TOOL_FINGER, true); -+ input_report_abs(input, ABS_MT_POSITION_X, positions[i].x); -+ input_report_abs(input, ABS_MT_POSITION_Y, positions[i].y); -+ } -+ -+ input_mt_sync_frame(input); -+ input_sync(input); -+} -+ -+static irqreturn_t gsl_ts_irq(int irq, void *arg) -+{ -+ int rc; -+ struct gsl_ts_data *ts = (struct gsl_ts_data *) arg; -+ struct i2c_client *client = ts->client; -+ struct device *dev = &client->dev; -+ u8 status[4] = { 0, 0, 0, 0 }; -+ u8 event[GSL_PACKET_SIZE]; -+ -+ dev_dbg(&client->dev, "%s: IRQ received\n", __func__); -+ -+ if (ts->state == GSL_TS_SHUTDOWN) { -+ dev_warn(&client->dev, "%s: device supended, not handling interrupt\n", __func__); -+ return IRQ_HANDLED; -+ } -+ -+ rc = gsl_ts_read(client, GSL_STATUS_REG, status, sizeof(status)); -+ if (rc < 0) { -+ dev_err(dev, "%s: error reading chip status\n", __func__); -+ return IRQ_HANDLED; -+ } -+ -+ if (status[0] == GSL_STATUS_FW) { -+ /* TODO: Send firmware here instead of during init */ -+ dev_info(dev, "%s: device waiting for firmware\n", __func__); -+ -+ } else if (status[0] == GSL_STATUS_TOUCH) { -+ dev_vdbg(dev, "%s: touch event\n", __func__); -+ -+ rc = gsl_ts_read(client, GSL_DATA_REG, event, sizeof(event)); -+ if (rc < 0) { -+ dev_err(dev, "%s: touch data read failed\n", __func__); -+ return IRQ_HANDLED; -+ } -+ if (event[0] == 0xff) { -+ dev_warn(dev, "%s: ignoring invalid touch record (0xff)\n", __func__); -+ return IRQ_HANDLED; -+ } -+ -+ rc = gsl_ts_read(client, GSL_TOUCH_STATUS_REG, status, sizeof(status)); -+ if (rc < 0) { -+ dev_err(dev, "%s: reading touch status register failed\n", __func__); -+ return IRQ_HANDLED; -+ } -+ -+ if ((status[0] | status[1] | status[2] | status[3]) == 0) { -+ gsl_ts_mt_event(ts, event); -+ -+ } else { -+ dev_warn(dev, "%s: device seems to be stuck, resetting\n", __func__); -+ -+ rc = gsl_ts_reset_chip(ts->client); -+ if (rc < 0) { -+ dev_err(dev, "%s: reset_chip failed\n", __func__); -+ return IRQ_HANDLED; -+ } -+ rc = gsl_ts_startup_chip(ts->client); -+ if (rc < 0) { -+ dev_err(dev, "%s: startup_chip failed\n", __func__); -+ return IRQ_HANDLED; -+ } -+ } -+ } else { -+ dev_warn(&client->dev, "%s: IRQ received, unknown status 0x%02x\n", __func__, status[0]); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void gsl_ts_power(struct i2c_client *client, bool turnoff) -+{ -+ struct gsl_ts_data *data = i2c_get_clientdata(client); -+#ifdef CONFIG_ACPI -+ int error; -+#endif -+ -+ if (data) { -+ if (data->gpio) { -+ gpiod_set_value_cansleep(data->gpio, turnoff ? 0 : 1); -+#ifdef CONFIG_ACPI -+ } else { -+ error = acpi_bus_set_power(ACPI_HANDLE(&client->dev), turnoff ? ACPI_STATE_D3 : ACPI_STATE_D0); -+ if (error) { -+ dev_warn(&client->dev, "%s: error changing power state: %d\n", __func__, error); -+ } -+#endif -+ } -+ usleep_range(20000, 50000); -+ } -+} -+ -+static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) -+{ -+ struct gsl_ts_data *ts; -+ const struct firmware *fw = NULL; -+ unsigned long irqflags; -+ int error; -+ bool acpipower; -+ -+ dev_warn(&client->dev, "%s: got a device named %s at address 0x%x, IRQ %d, flags 0x%x\n", __func__, client->name, client->addr, client->irq, client->flags); -+ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { -+ dev_err(&client->dev, "%s: i2c check functionality error\n", __func__); -+ error = -ENXIO; -+ goto release; -+ } -+ -+ if (client->irq <= 0) { -+ dev_err(&client->dev, "%s: missing IRQ configuration\n", __func__); -+ error = -ENODEV; -+ goto release; -+ } -+ -+ ts = devm_kzalloc(&client->dev, sizeof(struct gsl_ts_data), GFP_KERNEL); -+ if (!ts) { -+ error = -ENOMEM; -+ goto release; -+ } -+ -+ ts->client = client; -+ i2c_set_clientdata(client, ts); -+ -+ if (gsl_fw_name != NULL) { -+ strncpy(ts->fw_name, gsl_fw_name, sizeof(ts->fw_name)); -+ } else { -+ strncpy(ts->fw_name, GSL_FW_NAME_DEFAULT, sizeof(ts->fw_name)); -+ } -+ error = request_firmware(&fw, ts->fw_name, &ts->client->dev); -+ if (error < 0) { -+ dev_err(&client->dev, "%s: failed to load firmware: %d\n", __func__, error); -+ goto release; -+ } -+ -+ error = gsl_ts_init(ts, fw); -+ if (error < 0) { -+ dev_err(&client->dev, "%s: failed to initialize: %d\n", __func__, error); -+ goto release; -+ } -+ -+ ts->input = devm_input_allocate_device(&client->dev); -+ if (!ts->input) { -+ dev_err(&client->dev, "%s: failed to allocate input device\n", __func__); -+ error = -ENOMEM; -+ goto release; -+ } -+ -+ ts->input->name = "Silead GSLx680 Touchscreen"; -+ ts->input->id.bustype = BUS_I2C; -+ ts->input->phys = "input/ts"; -+ -+ input_set_capability(ts->input, EV_ABS, ABS_X); -+ input_set_capability(ts->input, EV_ABS, ABS_Y); -+ -+ input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, ts->jitter, ts->deadzone); -+ input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, ts->jitter, ts->deadzone); -+ -+ input_mt_init_slots(ts->input, ts->multi_touches, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); -+ -+ input_set_drvdata(ts->input, ts); -+ -+ error = input_register_device(ts->input); -+ if (error) { -+ dev_err(&client->dev, "%s: unable to register input device: %d\n", __func__, error); -+ goto release; -+ } -+ -+ /* Try to use ACPI power methods first */ -+ acpipower = false; -+#ifdef CONFIG_ACPI -+ if (ACPI_COMPANION(&client->dev)) { -+ /* Wake the device up with a power on reset */ -+ if (acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3)) { -+ dev_warn(&client->dev, "%s: failed to wake up device through ACPI: %d, using GPIO controls instead\n", __func__, error); -+ } else { -+ acpipower = true; -+ } -+ } -+#endif -+ /* Not available, use GPIO settings from DSDT/DT instead */ -+ if (!acpipower) { -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+ ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0); -+#else -+ ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0, GPIOD_OUT_LOW); -+#endif -+ if (IS_ERR(ts->gpio)) { -+ dev_err(&client->dev, "%s: error obtaining power pin GPIO resource\n", __func__); -+ error = PTR_ERR(ts->gpio); -+ goto release; -+ } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) -+ error = gpiod_direction_output(ts->gpio, 0); -+ if (error < 0) { -+ dev_err(&client->dev, "%s: error setting GPIO pin direction\n", __func__); -+ goto release; -+ } -+#endif -+ } else { -+ ts->gpio = NULL; -+ } -+ -+ /* Enable power */ -+ gsl_ts_power(client, false); -+ -+ /* Execute the controller startup sequence */ -+ error = gsl_ts_reset_chip(client); -+ if (error < 0) { -+ dev_err(&client->dev, "%s: chip reset failed\n", __func__); -+ goto release; -+ } -+ error = gsl_ts_write_fw(ts, fw); -+ if (error < 0) { -+ dev_err(&client->dev, "%s: firmware transfer failed\n", __func__); -+ goto release; -+ } -+ error = gsl_ts_startup_chip(client); -+ if (error < 0) { -+ dev_err(&client->dev, "%s: chip startup failed\n", __func__); -+ goto release; -+ } -+ -+ /* -+ * Systems using device tree should set up interrupt via DTS, -+ * the rest will use the default falling edge interrupts. -+ */ -+ irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; -+ -+ /* Set up interrupt handler - do we still need to account for shared interrupts? */ -+ error = devm_request_threaded_irq( -+ &client->dev, -+ client->irq, -+ NULL, -+ gsl_ts_irq, -+ irqflags | IRQF_ONESHOT, -+ client->name, -+ ts -+ ); -+ if (error) { -+ dev_err(&client->dev, "%s: failed to register interrupt\n", __func__); -+ goto release; -+ } -+ -+ /* -+ * Systems using device tree should set up wakeup via DTS, -+ * the rest will configure device as wakeup source by default. -+ */ -+ if (!client->dev.of_node) { -+ device_init_wakeup(&client->dev, true); -+ } -+ -+ ts->state = GSL_TS_GREEN; -+ -+release: -+ if (fw) { -+ release_firmware(fw); -+ } -+ -+ if (error < 0) { -+ return error; -+ } -+ return 0; -+} -+ -+int gsl_ts_remove(struct i2c_client *client) { -+ /* Power the device off */ -+ gsl_ts_power(client, true); -+ return 0; -+} -+ -+static int __maybe_unused gsl_ts_suspend(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct gsl_ts_data *ts = i2c_get_clientdata(client); -+ -+ dev_warn(&client->dev, "%s: suspending device\n", __func__); -+ -+ disable_irq(client->irq); -+ -+ gsl_ts_reset_chip(client); -+ usleep_range(10000, 20000); -+ -+ gsl_ts_power(client, true); -+ -+ if (device_may_wakeup(dev)) { -+ ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0); -+ } -+ -+ ts->state = GSL_TS_SHUTDOWN; -+ -+ return 0; -+} -+ -+static int __maybe_unused gsl_ts_resume(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct gsl_ts_data *ts = i2c_get_clientdata(client); -+ -+ dev_warn(&client->dev, "%s: resuming device\n", __func__); -+ -+ if (device_may_wakeup(dev) && ts->wake_irq_enabled) { -+ disable_irq_wake(client->irq); -+ } -+ -+ gsl_ts_power(client, false); -+ -+ gsl_ts_reset_chip(client); -+ gsl_ts_startup_chip(client); -+ -+ enable_irq(client->irq); -+ -+ ts->state = GSL_TS_GREEN; -+ -+ return 0; -+} -+ -+static const struct i2c_device_id gsl_ts_i2c_id[] = { -+ { DEVICE_NAME, 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, gsl_ts_i2c_id); -+ -+#ifdef CONFIG_PM -+static SIMPLE_DEV_PM_OPS(gsl_ts_pm_ops, gsl_ts_suspend, gsl_ts_resume); -+#endif -+ -+#ifdef CONFIG_ACPI -+/* GSL3680 ACPI IDs are untested */ -+static const struct acpi_device_id gsl_ts_acpi_match[] = { -+ { "MSSL1680", 0 }, -+ { "MSSL3680", 0 }, -+ { "PNP1680", 0 }, -+ { "PNP3680", 0 }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(acpi, gsl_ts_acpi_match); -+#endif -+ -+#ifdef CONFIG_OF -+/* These should work, but more testing is needed */ -+static const struct of_device_id gsl_ts_of_match[] = { -+ { .compatible = "silead,gsl1680" }, -+ { .compatible = "silead,gsl3680" }, -+ { .compatible = "silead,gslx680" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, gsl_ts_of_match); -+#endif -+ -+static struct i2c_driver gslx680_ts_driver = { -+ .probe = gsl_ts_probe, -+ .remove = gsl_ts_remove, -+ .id_table = gsl_ts_i2c_id, -+ .driver = { -+ .name = DEVICE_NAME, -+ .owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .pm = &gsl_ts_pm_ops, -+#endif -+#ifdef CONFIG_ACPI -+ .acpi_match_table = ACPI_PTR(gsl_ts_acpi_match), -+#endif -+#ifdef CONFIG_OF -+ .of_match_table = of_match_ptr(gsl_ts_of_match), -+#endif -+ }, -+}; -+module_i2c_driver(gslx680_ts_driver); -+ -+MODULE_DESCRIPTION("GSLX680 touchscreen controller driver"); -+MODULE_AUTHOR("Gregor Riepl "); -+MODULE_PARM_DESC(fw_name, "firmware file name (default: " GSL_FW_NAME_DEFAULT ")"); -+MODULE_VERSION(DRIVER_VERSION); -+MODULE_LICENSE("GPL"); --- -2.21.0 - diff --git a/device/linux-chuwi-hi10plus/APKBUILD b/device/linux-chuwi-hi10plus/APKBUILD index 5b01849e2..f39e40c5b 100644 --- a/device/linux-chuwi-hi10plus/APKBUILD +++ b/device/linux-chuwi-hi10plus/APKBUILD @@ -2,9 +2,9 @@ # Kernel config based on: pkgname="linux-chuwi-hi10plus" -pkgver=5.1 -pkgrel=1 -pkgdesc="Chuwi Hi10 Plus mainline kernel" +pkgver=5.1.5 +pkgrel=0 +pkgdesc="Chuwi Hi10 Plus stable kernel" arch="x86_64" _carch="x86" _flavor="chuwi-hi10plus" @@ -20,15 +20,14 @@ HOSTCC="${CC:-gcc}" HOSTCC="${HOSTCC#${CROSS_COMPILE}}" # Source -_repository="linux" -_commit="e93c9c99a629c61837d5a7fc2120cd2b6c70dbdd" _config="config-${_flavor}.${arch}" source=" - $pkgname-$_commit.tar.gz::https://github.com/torvalds/${_repository}/archive/${_commit}.tar.gz + $pkgname-$pkgver.tar.gz::https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/linux-$pkgver.tar.gz $_config - 0001-input-touchscreen-gslx680_ts_acpi-Add-driver-from-on.patch + input-silead-Add-MSSL0017-to-acpi_device_id.patch + platform-x86-touchscreen_dmi-Add-info-for-the-CHUWI-.patch " -builddir="$srcdir/${_repository}-${_commit}" +builddir="$srcdir/linux-$pkgver" prepare() { default_prepare @@ -71,13 +70,14 @@ package() { dev() { cd $builddir - + # https://github.com/torvalds/linux/blob/master/Documentation/kbuild/headers_install.txt make -j1 headers_install \ ARCH="$_carch" \ INSTALL_HDR_PATH="$subpkgdir"/usr } -sha512sums="a2a4463056bbec1187f2a113e514dd58ed8f8e74a4c6dbe4477ba635c12d8a8bc50d431168579ee22f720ef799b21033ea52425a0c0a79849a96783545034ff5 linux-chuwi-hi10plus-e93c9c99a629c61837d5a7fc2120cd2b6c70dbdd.tar.gz +sha512sums="bd1e61520c88e66064aba04ec3e5dbbc7c3c5d2c8685a33715adca5b8989cf3cab76a705fbb913389a2ef00f70b00b602c24dfe6ffa1076c83e534d07d0723ff linux-chuwi-hi10plus-5.1.5.tar.gz 4378e9e6b087f354fc61a747c9f7be4ee0b40b29aac78351641b2548406f1f576d2bc8422ed17b33680fe590ad9cc33ca5603ad2d119610e4cbfe8707783be3b config-chuwi-hi10plus.x86_64 -a545d9a0cab4b30ed1a012a6a3a27df3dd9d44d096d0832c938ba5a14c54bc5c7a9cce12fe7b5a6797db676f6275b1308a2febb715a4faf653eb3c1ee3a32857 0001-input-touchscreen-gslx680_ts_acpi-Add-driver-from-on.patch" +cffb4b1dc204a15697aa26749df49b3f450de808cb630cf53d4718d933031a42789b79e94d39a9fe44a75e385f609c70aa8ccfb2e91e4fe473e0ee5245146c66 input-silead-Add-MSSL0017-to-acpi_device_id.patch +b97509150d4061001e90e1a595723c479252647b5f94f50b7be0673d11556b28a90fa0afff9f0961a4512c3cbc8d4b02b827e75f75385cbb3ad63b378f3931e3 platform-x86-touchscreen_dmi-Add-info-for-the-CHUWI-.patch" diff --git a/device/linux-chuwi-hi10plus/input-silead-Add-MSSL0017-to-acpi_device_id.patch b/device/linux-chuwi-hi10plus/input-silead-Add-MSSL0017-to-acpi_device_id.patch new file mode 100644 index 000000000..5af22789c --- /dev/null +++ b/device/linux-chuwi-hi10plus/input-silead-Add-MSSL0017-to-acpi_device_id.patch @@ -0,0 +1,27 @@ +From ef2c8011be280a926c59198eff073e5e96697d1f Mon Sep 17 00:00:00 2001 +From: Daniel Smith +Date: Wed, 22 May 2019 10:39:41 +0700 +Subject: [PATCH] input: silead: Add MSSL0017 to acpi_device_id. + +On Chuwi Hi10 Plus, the Silead device id is MSSL0017. + +Signed-off-by: Daniel Smith +--- + drivers/input/touchscreen/silead.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c +index 09241d4cdebc..06f0eb04a8fd 100644 +--- a/drivers/input/touchscreen/silead.c ++++ b/drivers/input/touchscreen/silead.c +@@ -617,6 +617,7 @@ static const struct acpi_device_id silead_ts_acpi_match[] = { + { "MSSL1680", 0 }, + { "MSSL0001", 0 }, + { "MSSL0002", 0 }, ++ { "MSSL0017", 0 }, + { } + }; + MODULE_DEVICE_TABLE(acpi, silead_ts_acpi_match); +-- +2.21.0 + diff --git a/device/linux-chuwi-hi10plus/platform-x86-touchscreen_dmi-Add-info-for-the-CHUWI-.patch b/device/linux-chuwi-hi10plus/platform-x86-touchscreen_dmi-Add-info-for-the-CHUWI-.patch new file mode 100644 index 000000000..41fe5cf17 --- /dev/null +++ b/device/linux-chuwi-hi10plus/platform-x86-touchscreen_dmi-Add-info-for-the-CHUWI-.patch @@ -0,0 +1,59 @@ +From 472b35c7960a2aa93c19a96550913d413f9f2da2 Mon Sep 17 00:00:00 2001 +From: Daniel Smith +Date: Wed, 22 May 2019 13:22:49 +0700 +Subject: [PATCH] platform/x86: touchscreen_dmi: Add info for the CHUWI Hi10 + Plus tablet. + +Added touch screen info for CHUWI Hi10 Plus tablet. + +Signed-off-by: Daniel Smith +--- + drivers/platform/x86/touchscreen_dmi.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index bd0856d2e825..1dbb53c3f1e7 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -91,6 +91,22 @@ static const struct ts_dmi_data chuwi_hi10_air_data = { + .properties = chuwi_hi10_air_props, + }; + ++static const struct property_entry chuwi_hi10_plus_props[] = { ++ PROPERTY_ENTRY_U32("touchscreen-min-x", 0), ++ PROPERTY_ENTRY_U32("touchscreen-min-y", 5), ++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1914), ++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1283), ++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10plus.fw"), ++ PROPERTY_ENTRY_U32("silead,max-fingers", 10), ++ PROPERTY_ENTRY_BOOL("silead,home-button"), ++ { } ++}; ++ ++static const struct ts_dmi_data chuwi_hi10_plus_data = { ++ .acpi_name = "MSSL0017:00", ++ .properties = chuwi_hi10_plus_props, ++}; ++ + static const struct property_entry chuwi_vi8_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 4), + PROPERTY_ENTRY_U32("touchscreen-min-y", 6), +@@ -605,6 +621,15 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "P1W6_C109D_B"), + }, + }, ++ { ++ /* Chuwi Hi10 Plus (CWI527) */ ++ .driver_data = (void *)&chuwi_hi10_plus_data, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Hi10 plus tablet"), ++ DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), ++ }, ++ }, + { + /* Chuwi Vi8 (CWI506) */ + .driver_data = (void *)&chuwi_vi8_data, +-- +2.21.0 +