All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <220181476210841@web5j.yandex.ru>

diff --git a/a/1.txt b/N1/1.txt
index 5ed7f14..ec11dce 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,20 +1,20 @@
 
 
-12.10.2016, 01:40, "Dmitry Torokhov" <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
+12.10.2016, 01:40, "Dmitry Torokhov" <dmitry.torokhov@gmail.com>:
 > Hi Icenowy,
 >
 > On Tue, Oct 11, 2016 at 08:33:57AM +0800, Icenowy Zheng wrote:
->>  This driver adds support for Ilitek ili2139 touch IC, which is used in
->>  several Colorfly tablets (for example, Colorfly E708 Q1, which is an
->>  Allwinner A31s tablet with mainline kernel support).
+>> ?This driver adds support for Ilitek ili2139 touch IC, which is used in
+>> ?several Colorfly tablets (for example, Colorfly E708 Q1, which is an
+>> ?Allwinner A31s tablet with mainline kernel support).
 >>
->>  Theortically it may support more Ilitek touch ICs, however, only ili2139
->>  is used in any mainlined device.
+>> ?Theortically it may support more Ilitek touch ICs, however, only ili2139
+>> ?is used in any mainlined device.
 >>
->>  It supports device tree enumeration, with screen resolution and axis
->>  quirks configurable.
+>> ?It supports device tree enumeration, with screen resolution and axis
+>> ?quirks configurable.
 >>
->>  Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+>> ?Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
 >
 > Please extend ili210x.c instead of adding brand new driver, they look
 > very similar.
@@ -30,383 +30,378 @@ the old protocol (but I have no chips to test it), and drop the old ili210x.
 (This driver is capable of dt probing, and uses devm_ functions)
 
 >
->>  ---
->>   drivers/input/touchscreen/Kconfig | 14 ++
->>   drivers/input/touchscreen/Makefile | 1 +
->>   drivers/input/touchscreen/ili2139.c | 320 ++++++++++++++++++++++++++++++++++++
->>   3 files changed, 335 insertions(+)
->>   create mode 100644 drivers/input/touchscreen/ili2139.c
+>> ?---
+>> ??drivers/input/touchscreen/Kconfig | 14 ++
+>> ??drivers/input/touchscreen/Makefile | 1 +
+>> ??drivers/input/touchscreen/ili2139.c | 320 ++++++++++++++++++++++++++++++++++++
+>> ??3 files changed, 335 insertions(+)
+>> ??create mode 100644 drivers/input/touchscreen/ili2139.c
 >>
->>  diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
->>  index 5079813..bb4d9d2 100644
->>  --- a/drivers/input/touchscreen/Kconfig
->>  +++ b/drivers/input/touchscreen/Kconfig
->>  @@ -348,6 +348,20 @@ config TOUCHSCREEN_ILI210X
->>             To compile this driver as a module, choose M here: the
->>             module will be called ili210x.
+>> ?diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
+>> ?index 5079813..bb4d9d2 100644
+>> ?--- a/drivers/input/touchscreen/Kconfig
+>> ?+++ b/drivers/input/touchscreen/Kconfig
+>> ?@@ -348,6 +348,20 @@ config TOUCHSCREEN_ILI210X
+>> ????????????To compile this driver as a module, choose M here: the
+>> ????????????module will be called ili210x.
 >>
->>  +config TOUCHSCREEN_ILI2139
->>  + tristate "Ilitek ILI2139 based touchscreen"
->>  + depends on I2C
->>  + depends on OF
->>  + help
->>  + Say Y here if you have a ILI2139 based touchscreen
->>  + controller. Such kind of chipsets can be found in several
->>  + Colorfly tablets.
->>  +
->>  + If unsure, say N.
->>  +
->>  + To compile this driver as a module, choose M here; the
->>  + module will be called ili2139.
->>  +
->>   config TOUCHSCREEN_IPROC
->>           tristate "IPROC touch panel driver support"
->>           depends on ARCH_BCM_IPROC || COMPILE_TEST
->>  diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
->>  index 81b8645..930b5e2 100644
->>  --- a/drivers/input/touchscreen/Makefile
->>  +++ b/drivers/input/touchscreen/Makefile
->>  @@ -40,6 +40,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
->>   obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
->>   obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
->>   obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
->>  +obj-$(CONFIG_TOUCHSCREEN_ILI2139) += ili2139.o
->>   obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o
->>   obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
->>   obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
->>  diff --git a/drivers/input/touchscreen/ili2139.c b/drivers/input/touchscreen/ili2139.c
->>  new file mode 100644
->>  index 0000000..65c2dea
->>  --- /dev/null
->>  +++ b/drivers/input/touchscreen/ili2139.c
->>  @@ -0,0 +1,320 @@
->>  +/* -------------------------------------------------------------------------
->>  + * Copyright (C) 2016, Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
->>  + *
->>  + * Derived from:
->>  + * ili210x.c
->>  + * Copyright (C) Olivier Sobrie <olivier-Ui3EtX6WB9GzQB+pC5nmwQ@public.gmane.org>
->>  + *
->>  + * This program is free software; you can redistribute it and/or modify
->>  + * it under the terms of the GNU General Public License as published by
->>  + * the Free Software Foundation; either version 2 of the License, or
->>  + * (at your option) any later version.
->>  + *
->>  + * This program is distributed in the hope that it will be useful,
->>  + * but WITHOUT ANY WARRANTY; without even the implied warranty of
->>  + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
->>  + * GNU General Public License for more details.
->>  + * -------------------------------------------------------------------------
->>  + */
->>  +
->>  +#include <linux/module.h>
->>  +#include <linux/i2c.h>
->>  +#include <linux/interrupt.h>
->>  +#include <linux/slab.h>
->>  +#include <linux/input.h>
->>  +#include <linux/input/mt.h>
->>  +#include <linux/input/touchscreen.h>
->>  +#include <linux/delay.h>
->>  +#include <linux/workqueue.h>
->>  +
->>  +#define DEFAULT_POLL_PERIOD 20
->>  +
->>  +#define MAX_TOUCHES 10
->>  +#define COMPATIBLE_TOUCHES 2
->>  +
->>  +/* Touchscreen commands */
->>  +#define REG_TOUCHDATA 0x10
->>  +#define REG_TOUCHSUBDATA 0x11
->>  +#define REG_PANEL_INFO 0x20
->>  +#define REG_FIRMWARE_VERSION 0x40
->>  +#define REG_PROTO_VERSION 0x42
->>  +
->>  +#define SUBDATA_STATUS_TOUCH_POINT 0x80
->>  +#define SUBDATA_STATUS_RELEASE_POINT 0x00
->>  +
->>  +struct finger {
->>  + u8 x_low;
->>  + u8 x_high;
->>  + u8 y_low;
->>  + u8 y_high;
->>  +} __packed;
->>  +
->>  +struct touchdata {
->>  + u8 length;
->>  + struct finger finger[COMPATIBLE_TOUCHES];
->>  +} __packed;
->>  +
->>  +struct touch_subdata {
->>  + u8 status;
->>  + struct finger finger;
->>  +} __packed;
->>  +
->>  +struct panel_info {
->>  + struct finger finger_max;
->>  + u8 xchannel_num;
->>  + u8 ychannel_num;
->>  +} __packed;
->>  +
->>  +struct firmware_version {
->>  + u8 id;
->>  + u8 major;
->>  + u8 minor;
->>  +} __packed;
->>  +
->>  +struct ili2139 {
->>  + struct i2c_client *client;
->>  + struct input_dev *input;
->>  + unsigned int poll_period;
->>  + struct delayed_work dwork;
->>  + struct touchscreen_properties prop;
->>  + int slots[MAX_TOUCHES];
->>  + int ids[MAX_TOUCHES];
->>  + struct input_mt_pos pos[MAX_TOUCHES];
->>  +};
->>  +
->>  +static int ili2139_read_reg(struct i2c_client *client, u8 reg, void *buf,
->>  + size_t len)
->>  +{
->>  + struct i2c_msg msg[2] = {
->>  + {
->>  + .addr = client->addr,
->>  + .flags = 0,
->>  + .len = 1,
->>  + .buf = &reg,
->>  + },
->>  + {
->>  + .addr = client->addr,
->>  + .flags = I2C_M_RD,
->>  + .len = len,
->>  + .buf = buf,
->>  + }
->>  + };
->>  +
->>  + if (i2c_transfer(client->adapter, msg, 2) != 2) {
->>  + dev_err(&client->dev, "i2c transfer failed\n");
->>  + return -EIO;
->>  + }
->>  +
->>  + return 0;
->>  +}
->>  +
->>  +static void ili2139_work(struct work_struct *work)
->>  +{
->>  + int id;
->>  + struct ili2139 *priv = container_of(work, struct ili2139,
->>  + dwork.work);
->>  + struct i2c_client *client = priv->client;
->>  + struct touchdata touchdata;
->>  + struct touch_subdata subdata;
->>  + int error;
->>  +
->>  + error = ili2139_read_reg(client, REG_TOUCHDATA,
->>  + &touchdata, sizeof(touchdata));
->>  + if (error) {
->>  + dev_err(&client->dev,
->>  + "Unable to get touchdata, err = %d\n", error);
->>  + return;
->>  + }
->>  +
->>  + for (id = 0; id < touchdata.length; id++) {
->>  + error = ili2139_read_reg(client, REG_TOUCHSUBDATA, &subdata,
->>  + sizeof(subdata));
->>  + if (error) {
->>  + dev_err(&client->dev,
->>  + "Unable to get touch subdata, err = %d\n",
->>  + error);
->>  + return;
->>  + }
->>  +
->>  + priv->ids[id] = subdata.status & 0x3F;
->>  +
->>  + /* The sequence changed in the v2 subdata protocol. */
->>  + touchscreen_set_mt_pos(&priv->pos[id], &priv->prop,
->>  + (subdata.finger.x_high | (subdata.finger.x_low << 8)),
->>  + (subdata.finger.y_high | (subdata.finger.y_low << 8)));
->>  + }
->>  +
->>  + input_mt_assign_slots(priv->input, priv->slots, priv->pos,
->>  + touchdata.length, 0);
->>  +
->>  + for (id = 0; id < touchdata.length; id++) {
->>  + input_mt_slot(priv->input, priv->slots[id]);
->>  + input_mt_report_slot_state(priv->input, MT_TOOL_FINGER,
->>  + subdata.status &
->>  + SUBDATA_STATUS_TOUCH_POINT);
->>  + input_report_abs(priv->input, ABS_MT_POSITION_X,
->>  + priv->pos[id].x);
->>  + input_report_abs(priv->input, ABS_MT_POSITION_Y,
->>  + priv->pos[id].y);
->>  + }
->>  +
->>  + input_mt_sync_frame(priv->input);
->>  + input_sync(priv->input);
->>  +
->>  + schedule_delayed_work(&priv->dwork,
->>  + msecs_to_jiffies(priv->poll_period));
->>  +}
->>  +
->>  +static irqreturn_t ili2139_irq(int irq, void *irq_data)
->>  +{
->>  + struct ili2139 *priv = irq_data;
->>  +
->>  + schedule_delayed_work(&priv->dwork, 0);
->>  +
->>  + return IRQ_HANDLED;
->>  +}
->>  +
->>  +static int ili2139_i2c_probe(struct i2c_client *client,
->>  + const struct i2c_device_id *id)
->>  +{
->>  + struct device *dev = &client->dev;
->>  + struct ili2139 *priv;
->>  + struct input_dev *input;
->>  + struct panel_info panel;
->>  + struct firmware_version firmware;
->>  + int xmax, ymax;
->>  + int error;
->>  +
->>  + dev_dbg(dev, "Probing for ILI2139 I2C Touschreen driver");
->>  +
->>  + if (client->irq <= 0) {
->>  + dev_err(dev, "No IRQ!\n");
->>  + return -ENODEV;
->>  + }
->>  +
->>  + /* Get firmware version */
->>  + error = ili2139_read_reg(client, REG_FIRMWARE_VERSION,
->>  + &firmware, sizeof(firmware));
->>  + if (error) {
->>  + dev_err(dev, "Failed to get firmware version, err: %d\n",
->>  + error);
->>  + return error;
->>  + }
->>  +
->>  + /* get panel info */
->>  + error = ili2139_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));
->>  + if (error) {
->>  + dev_err(dev, "Failed to get panel information, err: %d\n",
->>  + error);
->>  + return error;
->>  + }
->>  +
->>  + xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8);
->>  + ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8);
->>  +
->>  + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
->>  + input = devm_input_allocate_device(dev);
->>  + if (!priv || !input)
->>  + return -ENOMEM;
->>  +
->>  + priv->client = client;
->>  + priv->input = input;
->>  + priv->poll_period = DEFAULT_POLL_PERIOD;
->>  + INIT_DELAYED_WORK(&priv->dwork, ili2139_work);
->>  +
->>  + /* Setup input device */
->>  + input->name = "ILI2139 Touchscreen";
->>  + input->id.bustype = BUS_I2C;
->>  + input->dev.parent = dev;
->>  +
->>  + __set_bit(EV_SYN, input->evbit);
->>  + __set_bit(EV_KEY, input->evbit);
->>  + __set_bit(EV_ABS, input->evbit);
->>  +
->>  + /* Multi touch */
->>  + input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_DIRECT |
->>  + INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);
->>  + input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);
->>  + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);
->>  +
->>  + touchscreen_parse_properties(input, true, &priv->prop);
->>  +
->>  + input_set_drvdata(input, priv);
->>  + i2c_set_clientdata(client, priv);
->>  +
->>  + error = devm_request_irq(dev, client->irq, ili2139_irq,
->>  + IRQF_TRIGGER_FALLING, client->name, priv);
->>  + if (error) {
->>  + dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
->>  + error);
->>  + return error;
->>  + }
->>  +
->>  + error = input_register_device(priv->input);
->>  + if (error) {
->>  + dev_err(dev, "Cannot register input device, err: %d\n", error);
->>  + return error;
->>  + }
->>  +
->>  + device_init_wakeup(&client->dev, 1);
->>  +
->>  + dev_dbg(dev,
->>  + "ILI2139 initialized (IRQ: %d), firmware version %d.%d.%d",
->>  + client->irq, firmware.id, firmware.major, firmware.minor);
->>  +
->>  + return 0;
->>  +}
->>  +
->>  +static int ili2139_i2c_remove(struct i2c_client *client)
->>  +{
->>  + struct ili2139 *priv = i2c_get_clientdata(client);
->>  +
->>  + cancel_delayed_work_sync(&priv->dwork);
->>  +
->>  + return 0;
->>  +}
->>  +
->>  +static int __maybe_unused ili2139_i2c_suspend(struct device *dev)
->>  +{
->>  + struct i2c_client *client = to_i2c_client(dev);
->>  +
->>  + if (device_may_wakeup(&client->dev))
->>  + enable_irq_wake(client->irq);
->>  +
->>  + return 0;
->>  +}
->>  +
->>  +static int __maybe_unused ili2139_i2c_resume(struct device *dev)
->>  +{
->>  + struct i2c_client *client = to_i2c_client(dev);
->>  +
->>  + if (device_may_wakeup(&client->dev))
->>  + disable_irq_wake(client->irq);
->>  +
->>  + return 0;
->>  +}
->>  +
->>  +static SIMPLE_DEV_PM_OPS(ili2139_i2c_pm,
->>  + ili2139_i2c_suspend, ili2139_i2c_resume);
->>  +
->>  +static const struct i2c_device_id ili2139_i2c_id[] = {
->>  + { "ili2139", 0 },
->>  + { }
->>  +};
->>  +MODULE_DEVICE_TABLE(i2c, ili2139_i2c_id);
->>  +
->>  +static struct i2c_driver ili2139_ts_driver = {
->>  + .driver = {
->>  + .name = "ili2139_i2c",
->>  + .pm = &ili2139_i2c_pm,
->>  + },
->>  + .id_table = ili2139_i2c_id,
->>  + .probe = ili2139_i2c_probe,
->>  + .remove = ili2139_i2c_remove,
->>  +};
->>  +
->>  +module_i2c_driver(ili2139_ts_driver);
->>  +
->>  +MODULE_AUTHOR("Olivier Sobrie <olivier-Ui3EtX6WB9GzQB+pC5nmwQ@public.gmane.org>");
->>  +MODULE_DESCRIPTION("ILI2139 I2C Touchscreen Driver");
->>  +MODULE_LICENSE("GPL");
->>  --
->>  2.10.1
+>> ?+config TOUCHSCREEN_ILI2139
+>> ?+ tristate "Ilitek ILI2139 based touchscreen"
+>> ?+ depends on I2C
+>> ?+ depends on OF
+>> ?+ help
+>> ?+ Say Y here if you have a ILI2139 based touchscreen
+>> ?+ controller. Such kind of chipsets can be found in several
+>> ?+ Colorfly tablets.
+>> ?+
+>> ?+ If unsure, say N.
+>> ?+
+>> ?+ To compile this driver as a module, choose M here; the
+>> ?+ module will be called ili2139.
+>> ?+
+>> ??config TOUCHSCREEN_IPROC
+>> ??????????tristate "IPROC touch panel driver support"
+>> ??????????depends on ARCH_BCM_IPROC || COMPILE_TEST
+>> ?diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
+>> ?index 81b8645..930b5e2 100644
+>> ?--- a/drivers/input/touchscreen/Makefile
+>> ?+++ b/drivers/input/touchscreen/Makefile
+>> ?@@ -40,6 +40,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
+>> ??obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
+>> ??obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
+>> ??obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
+>> ?+obj-$(CONFIG_TOUCHSCREEN_ILI2139) += ili2139.o
+>> ??obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o
+>> ??obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
+>> ??obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
+>> ?diff --git a/drivers/input/touchscreen/ili2139.c b/drivers/input/touchscreen/ili2139.c
+>> ?new file mode 100644
+>> ?index 0000000..65c2dea
+>> ?--- /dev/null
+>> ?+++ b/drivers/input/touchscreen/ili2139.c
+>> ?@@ -0,0 +1,320 @@
+>> ?+/* -------------------------------------------------------------------------
+>> ?+ * Copyright (C) 2016, Icenowy Zheng <icenowy@aosc.xyz>
+>> ?+ *
+>> ?+ * Derived from:
+>> ?+ * ili210x.c
+>> ?+ * Copyright (C) Olivier Sobrie <olivier@sobrie.be>
+>> ?+ *
+>> ?+ * This program is free software; you can redistribute it and/or modify
+>> ?+ * it under the terms of the GNU General Public License as published by
+>> ?+ * the Free Software Foundation; either version 2 of the License, or
+>> ?+ * (at your option) any later version.
+>> ?+ *
+>> ?+ * This program is distributed in the hope that it will be useful,
+>> ?+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+>> ?+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+>> ?+ * GNU General Public License for more details.
+>> ?+ * -------------------------------------------------------------------------
+>> ?+ */
+>> ?+
+>> ?+#include <linux/module.h>
+>> ?+#include <linux/i2c.h>
+>> ?+#include <linux/interrupt.h>
+>> ?+#include <linux/slab.h>
+>> ?+#include <linux/input.h>
+>> ?+#include <linux/input/mt.h>
+>> ?+#include <linux/input/touchscreen.h>
+>> ?+#include <linux/delay.h>
+>> ?+#include <linux/workqueue.h>
+>> ?+
+>> ?+#define DEFAULT_POLL_PERIOD 20
+>> ?+
+>> ?+#define MAX_TOUCHES 10
+>> ?+#define COMPATIBLE_TOUCHES 2
+>> ?+
+>> ?+/* Touchscreen commands */
+>> ?+#define REG_TOUCHDATA 0x10
+>> ?+#define REG_TOUCHSUBDATA 0x11
+>> ?+#define REG_PANEL_INFO 0x20
+>> ?+#define REG_FIRMWARE_VERSION 0x40
+>> ?+#define REG_PROTO_VERSION 0x42
+>> ?+
+>> ?+#define SUBDATA_STATUS_TOUCH_POINT 0x80
+>> ?+#define SUBDATA_STATUS_RELEASE_POINT 0x00
+>> ?+
+>> ?+struct finger {
+>> ?+ u8 x_low;
+>> ?+ u8 x_high;
+>> ?+ u8 y_low;
+>> ?+ u8 y_high;
+>> ?+} __packed;
+>> ?+
+>> ?+struct touchdata {
+>> ?+ u8 length;
+>> ?+ struct finger finger[COMPATIBLE_TOUCHES];
+>> ?+} __packed;
+>> ?+
+>> ?+struct touch_subdata {
+>> ?+ u8 status;
+>> ?+ struct finger finger;
+>> ?+} __packed;
+>> ?+
+>> ?+struct panel_info {
+>> ?+ struct finger finger_max;
+>> ?+ u8 xchannel_num;
+>> ?+ u8 ychannel_num;
+>> ?+} __packed;
+>> ?+
+>> ?+struct firmware_version {
+>> ?+ u8 id;
+>> ?+ u8 major;
+>> ?+ u8 minor;
+>> ?+} __packed;
+>> ?+
+>> ?+struct ili2139 {
+>> ?+ struct i2c_client *client;
+>> ?+ struct input_dev *input;
+>> ?+ unsigned int poll_period;
+>> ?+ struct delayed_work dwork;
+>> ?+ struct touchscreen_properties prop;
+>> ?+ int slots[MAX_TOUCHES];
+>> ?+ int ids[MAX_TOUCHES];
+>> ?+ struct input_mt_pos pos[MAX_TOUCHES];
+>> ?+};
+>> ?+
+>> ?+static int ili2139_read_reg(struct i2c_client *client, u8 reg, void *buf,
+>> ?+ size_t len)
+>> ?+{
+>> ?+ struct i2c_msg msg[2] = {
+>> ?+ {
+>> ?+ .addr = client->addr,
+>> ?+ .flags = 0,
+>> ?+ .len = 1,
+>> ?+ .buf = &reg,
+>> ?+ },
+>> ?+ {
+>> ?+ .addr = client->addr,
+>> ?+ .flags = I2C_M_RD,
+>> ?+ .len = len,
+>> ?+ .buf = buf,
+>> ?+ }
+>> ?+ };
+>> ?+
+>> ?+ if (i2c_transfer(client->adapter, msg, 2) != 2) {
+>> ?+ dev_err(&client->dev, "i2c transfer failed\n");
+>> ?+ return -EIO;
+>> ?+ }
+>> ?+
+>> ?+ return 0;
+>> ?+}
+>> ?+
+>> ?+static void ili2139_work(struct work_struct *work)
+>> ?+{
+>> ?+ int id;
+>> ?+ struct ili2139 *priv = container_of(work, struct ili2139,
+>> ?+ dwork.work);
+>> ?+ struct i2c_client *client = priv->client;
+>> ?+ struct touchdata touchdata;
+>> ?+ struct touch_subdata subdata;
+>> ?+ int error;
+>> ?+
+>> ?+ error = ili2139_read_reg(client, REG_TOUCHDATA,
+>> ?+ &touchdata, sizeof(touchdata));
+>> ?+ if (error) {
+>> ?+ dev_err(&client->dev,
+>> ?+ "Unable to get touchdata, err = %d\n", error);
+>> ?+ return;
+>> ?+ }
+>> ?+
+>> ?+ for (id = 0; id < touchdata.length; id++) {
+>> ?+ error = ili2139_read_reg(client, REG_TOUCHSUBDATA, &subdata,
+>> ?+ sizeof(subdata));
+>> ?+ if (error) {
+>> ?+ dev_err(&client->dev,
+>> ?+ "Unable to get touch subdata, err = %d\n",
+>> ?+ error);
+>> ?+ return;
+>> ?+ }
+>> ?+
+>> ?+ priv->ids[id] = subdata.status & 0x3F;
+>> ?+
+>> ?+ /* The sequence changed in the v2 subdata protocol. */
+>> ?+ touchscreen_set_mt_pos(&priv->pos[id], &priv->prop,
+>> ?+ (subdata.finger.x_high | (subdata.finger.x_low << 8)),
+>> ?+ (subdata.finger.y_high | (subdata.finger.y_low << 8)));
+>> ?+ }
+>> ?+
+>> ?+ input_mt_assign_slots(priv->input, priv->slots, priv->pos,
+>> ?+ touchdata.length, 0);
+>> ?+
+>> ?+ for (id = 0; id < touchdata.length; id++) {
+>> ?+ input_mt_slot(priv->input, priv->slots[id]);
+>> ?+ input_mt_report_slot_state(priv->input, MT_TOOL_FINGER,
+>> ?+ subdata.status &
+>> ?+ SUBDATA_STATUS_TOUCH_POINT);
+>> ?+ input_report_abs(priv->input, ABS_MT_POSITION_X,
+>> ?+ priv->pos[id].x);
+>> ?+ input_report_abs(priv->input, ABS_MT_POSITION_Y,
+>> ?+ priv->pos[id].y);
+>> ?+ }
+>> ?+
+>> ?+ input_mt_sync_frame(priv->input);
+>> ?+ input_sync(priv->input);
+>> ?+
+>> ?+ schedule_delayed_work(&priv->dwork,
+>> ?+ msecs_to_jiffies(priv->poll_period));
+>> ?+}
+>> ?+
+>> ?+static irqreturn_t ili2139_irq(int irq, void *irq_data)
+>> ?+{
+>> ?+ struct ili2139 *priv = irq_data;
+>> ?+
+>> ?+ schedule_delayed_work(&priv->dwork, 0);
+>> ?+
+>> ?+ return IRQ_HANDLED;
+>> ?+}
+>> ?+
+>> ?+static int ili2139_i2c_probe(struct i2c_client *client,
+>> ?+ const struct i2c_device_id *id)
+>> ?+{
+>> ?+ struct device *dev = &client->dev;
+>> ?+ struct ili2139 *priv;
+>> ?+ struct input_dev *input;
+>> ?+ struct panel_info panel;
+>> ?+ struct firmware_version firmware;
+>> ?+ int xmax, ymax;
+>> ?+ int error;
+>> ?+
+>> ?+ dev_dbg(dev, "Probing for ILI2139 I2C Touschreen driver");
+>> ?+
+>> ?+ if (client->irq <= 0) {
+>> ?+ dev_err(dev, "No IRQ!\n");
+>> ?+ return -ENODEV;
+>> ?+ }
+>> ?+
+>> ?+ /* Get firmware version */
+>> ?+ error = ili2139_read_reg(client, REG_FIRMWARE_VERSION,
+>> ?+ &firmware, sizeof(firmware));
+>> ?+ if (error) {
+>> ?+ dev_err(dev, "Failed to get firmware version, err: %d\n",
+>> ?+ error);
+>> ?+ return error;
+>> ?+ }
+>> ?+
+>> ?+ /* get panel info */
+>> ?+ error = ili2139_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));
+>> ?+ if (error) {
+>> ?+ dev_err(dev, "Failed to get panel information, err: %d\n",
+>> ?+ error);
+>> ?+ return error;
+>> ?+ }
+>> ?+
+>> ?+ xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8);
+>> ?+ ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8);
+>> ?+
+>> ?+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+>> ?+ input = devm_input_allocate_device(dev);
+>> ?+ if (!priv || !input)
+>> ?+ return -ENOMEM;
+>> ?+
+>> ?+ priv->client = client;
+>> ?+ priv->input = input;
+>> ?+ priv->poll_period = DEFAULT_POLL_PERIOD;
+>> ?+ INIT_DELAYED_WORK(&priv->dwork, ili2139_work);
+>> ?+
+>> ?+ /* Setup input device */
+>> ?+ input->name = "ILI2139 Touchscreen";
+>> ?+ input->id.bustype = BUS_I2C;
+>> ?+ input->dev.parent = dev;
+>> ?+
+>> ?+ __set_bit(EV_SYN, input->evbit);
+>> ?+ __set_bit(EV_KEY, input->evbit);
+>> ?+ __set_bit(EV_ABS, input->evbit);
+>> ?+
+>> ?+ /* Multi touch */
+>> ?+ input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_DIRECT |
+>> ?+ INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);
+>> ?+ input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);
+>> ?+ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);
+>> ?+
+>> ?+ touchscreen_parse_properties(input, true, &priv->prop);
+>> ?+
+>> ?+ input_set_drvdata(input, priv);
+>> ?+ i2c_set_clientdata(client, priv);
+>> ?+
+>> ?+ error = devm_request_irq(dev, client->irq, ili2139_irq,
+>> ?+ IRQF_TRIGGER_FALLING, client->name, priv);
+>> ?+ if (error) {
+>> ?+ dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
+>> ?+ error);
+>> ?+ return error;
+>> ?+ }
+>> ?+
+>> ?+ error = input_register_device(priv->input);
+>> ?+ if (error) {
+>> ?+ dev_err(dev, "Cannot register input device, err: %d\n", error);
+>> ?+ return error;
+>> ?+ }
+>> ?+
+>> ?+ device_init_wakeup(&client->dev, 1);
+>> ?+
+>> ?+ dev_dbg(dev,
+>> ?+ "ILI2139 initialized (IRQ: %d), firmware version %d.%d.%d",
+>> ?+ client->irq, firmware.id, firmware.major, firmware.minor);
+>> ?+
+>> ?+ return 0;
+>> ?+}
+>> ?+
+>> ?+static int ili2139_i2c_remove(struct i2c_client *client)
+>> ?+{
+>> ?+ struct ili2139 *priv = i2c_get_clientdata(client);
+>> ?+
+>> ?+ cancel_delayed_work_sync(&priv->dwork);
+>> ?+
+>> ?+ return 0;
+>> ?+}
+>> ?+
+>> ?+static int __maybe_unused ili2139_i2c_suspend(struct device *dev)
+>> ?+{
+>> ?+ struct i2c_client *client = to_i2c_client(dev);
+>> ?+
+>> ?+ if (device_may_wakeup(&client->dev))
+>> ?+ enable_irq_wake(client->irq);
+>> ?+
+>> ?+ return 0;
+>> ?+}
+>> ?+
+>> ?+static int __maybe_unused ili2139_i2c_resume(struct device *dev)
+>> ?+{
+>> ?+ struct i2c_client *client = to_i2c_client(dev);
+>> ?+
+>> ?+ if (device_may_wakeup(&client->dev))
+>> ?+ disable_irq_wake(client->irq);
+>> ?+
+>> ?+ return 0;
+>> ?+}
+>> ?+
+>> ?+static SIMPLE_DEV_PM_OPS(ili2139_i2c_pm,
+>> ?+ ili2139_i2c_suspend, ili2139_i2c_resume);
+>> ?+
+>> ?+static const struct i2c_device_id ili2139_i2c_id[] = {
+>> ?+ { "ili2139", 0 },
+>> ?+ { }
+>> ?+};
+>> ?+MODULE_DEVICE_TABLE(i2c, ili2139_i2c_id);
+>> ?+
+>> ?+static struct i2c_driver ili2139_ts_driver = {
+>> ?+ .driver = {
+>> ?+ .name = "ili2139_i2c",
+>> ?+ .pm = &ili2139_i2c_pm,
+>> ?+ },
+>> ?+ .id_table = ili2139_i2c_id,
+>> ?+ .probe = ili2139_i2c_probe,
+>> ?+ .remove = ili2139_i2c_remove,
+>> ?+};
+>> ?+
+>> ?+module_i2c_driver(ili2139_ts_driver);
+>> ?+
+>> ?+MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
+>> ?+MODULE_DESCRIPTION("ILI2139 I2C Touchscreen Driver");
+>> ?+MODULE_LICENSE("GPL");
+>> ?--
+>> ?2.10.1
 >
 > --
 > Dmitry
-
--- 
-You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
-To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
-For more options, visit https://groups.google.com/d/optout.
diff --git a/a/content_digest b/N1/content_digest
index 5c83bb0..f4fe95a 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,51 +1,29 @@
  "ref\020161011003359.26079-1-icenowy@aosc.xyz\0"
  "ref\020161011003359.26079-3-icenowy@aosc.xyz\0"
  "ref\020161011174046.GA27925@dtor-ws\0"
- "From\0Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>\0"
- "Subject\0Re: [PATCH 3/5] Input: add driver for Ilitek ili2139 touch IC\0"
+ "From\0icenowy@aosc.xyz (Icenowy Zheng)\0"
+ "Subject\0[PATCH 3/5] Input: add driver for Ilitek ili2139 touch IC\0"
  "Date\0Wed, 12 Oct 2016 02:34:01 +0800\0"
- "To\0Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>\0"
- "Cc\0Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>"
-  Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
-  Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
-  Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
-  Henrik Rydberg <rydberg-FFUHeuDi6mxAfugRpC6u6w@public.gmane.org>
-  Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
-  Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
-  Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
-  Shawn Guo <shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
-  Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
-  Marek Vasut <marex-ynQEQJNshbs@public.gmane.org>
-  Rask Ingemann Lambertsen <ccc94453-1EA3ORoCGBhoJ7GROcy7lA@public.gmane.org>
-  Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
-  Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
-  Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
-  Michael Welling <mwelling-EkmVulN54Sk@public.gmane.org>
-  Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
-  Markus Pargmann <mpa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
-  Damien Riegel <damien.riegel-4ysUXcep3aM1wj+D4I0NRVaTQe2KTcn/@public.gmane.org>
-  Benjamin Tissoires <benjamin.tissoires-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
-  Jeffrey Lin <jeffrey.lin-s3Ivl27awEzQT0dZR+AlfA@public.gmane.org>
- " Javier\0"
+ "To\0linux-arm-kernel@lists.infradead.org\0"
  "\00:1\0"
  "b\0"
  "\n"
  "\n"
- "12.10.2016, 01:40, \"Dmitry Torokhov\" <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:\n"
+ "12.10.2016, 01:40, \"Dmitry Torokhov\" <dmitry.torokhov@gmail.com>:\n"
  "> Hi Icenowy,\n"
  ">\n"
  "> On Tue, Oct 11, 2016 at 08:33:57AM +0800, Icenowy Zheng wrote:\n"
- ">> \302\240This driver adds support for Ilitek ili2139 touch IC, which is used in\n"
- ">> \302\240several Colorfly tablets (for example, Colorfly E708 Q1, which is an\n"
- ">> \302\240Allwinner A31s tablet with mainline kernel support).\n"
+ ">> ?This driver adds support for Ilitek ili2139 touch IC, which is used in\n"
+ ">> ?several Colorfly tablets (for example, Colorfly E708 Q1, which is an\n"
+ ">> ?Allwinner A31s tablet with mainline kernel support).\n"
  ">>\n"
- ">> \302\240Theortically it may support more Ilitek touch ICs, however, only ili2139\n"
- ">> \302\240is used in any mainlined device.\n"
+ ">> ?Theortically it may support more Ilitek touch ICs, however, only ili2139\n"
+ ">> ?is used in any mainlined device.\n"
  ">>\n"
- ">> \302\240It supports device tree enumeration, with screen resolution and axis\n"
- ">> \302\240quirks configurable.\n"
+ ">> ?It supports device tree enumeration, with screen resolution and axis\n"
+ ">> ?quirks configurable.\n"
  ">>\n"
- ">> \302\240Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>\n"
+ ">> ?Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>\n"
  ">\n"
  "> Please extend ili210x.c instead of adding brand new driver, they look\n"
  "> very similar.\n"
@@ -61,385 +39,380 @@
  "(This driver is capable of dt probing, and uses devm_ functions)\n"
  "\n"
  ">\n"
- ">> \302\240---\n"
- ">> \302\240\302\240drivers/input/touchscreen/Kconfig | 14 ++\n"
- ">> \302\240\302\240drivers/input/touchscreen/Makefile | 1 +\n"
- ">> \302\240\302\240drivers/input/touchscreen/ili2139.c | 320 ++++++++++++++++++++++++++++++++++++\n"
- ">> \302\240\302\2403 files changed, 335 insertions(+)\n"
- ">> \302\240\302\240create mode 100644 drivers/input/touchscreen/ili2139.c\n"
+ ">> ?---\n"
+ ">> ??drivers/input/touchscreen/Kconfig | 14 ++\n"
+ ">> ??drivers/input/touchscreen/Makefile | 1 +\n"
+ ">> ??drivers/input/touchscreen/ili2139.c | 320 ++++++++++++++++++++++++++++++++++++\n"
+ ">> ??3 files changed, 335 insertions(+)\n"
+ ">> ??create mode 100644 drivers/input/touchscreen/ili2139.c\n"
  ">>\n"
- ">> \302\240diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig\n"
- ">> \302\240index 5079813..bb4d9d2 100644\n"
- ">> \302\240--- a/drivers/input/touchscreen/Kconfig\n"
- ">> \302\240+++ b/drivers/input/touchscreen/Kconfig\n"
- ">> \302\240@@ -348,6 +348,20 @@ config TOUCHSCREEN_ILI210X\n"
- ">> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240To compile this driver as a module, choose M here: the\n"
- ">> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240module will be called ili210x.\n"
+ ">> ?diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig\n"
+ ">> ?index 5079813..bb4d9d2 100644\n"
+ ">> ?--- a/drivers/input/touchscreen/Kconfig\n"
+ ">> ?+++ b/drivers/input/touchscreen/Kconfig\n"
+ ">> ?@@ -348,6 +348,20 @@ config TOUCHSCREEN_ILI210X\n"
+ ">> ????????????To compile this driver as a module, choose M here: the\n"
+ ">> ????????????module will be called ili210x.\n"
  ">>\n"
- ">> \302\240+config TOUCHSCREEN_ILI2139\n"
- ">> \302\240+ tristate \"Ilitek ILI2139 based touchscreen\"\n"
- ">> \302\240+ depends on I2C\n"
- ">> \302\240+ depends on OF\n"
- ">> \302\240+ help\n"
- ">> \302\240+ Say Y here if you have a ILI2139 based touchscreen\n"
- ">> \302\240+ controller. Such kind of chipsets can be found in several\n"
- ">> \302\240+ Colorfly tablets.\n"
- ">> \302\240+\n"
- ">> \302\240+ If unsure, say N.\n"
- ">> \302\240+\n"
- ">> \302\240+ To compile this driver as a module, choose M here; the\n"
- ">> \302\240+ module will be called ili2139.\n"
- ">> \302\240+\n"
- ">> \302\240\302\240config TOUCHSCREEN_IPROC\n"
- ">> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240tristate \"IPROC touch panel driver support\"\n"
- ">> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240depends on ARCH_BCM_IPROC || COMPILE_TEST\n"
- ">> \302\240diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile\n"
- ">> \302\240index 81b8645..930b5e2 100644\n"
- ">> \302\240--- a/drivers/input/touchscreen/Makefile\n"
- ">> \302\240+++ b/drivers/input/touchscreen/Makefile\n"
- ">> \302\240@@ -40,6 +40,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o\n"
- ">> \302\240\302\240obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o\n"
- ">> \302\240\302\240obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o\n"
- ">> \302\240\302\240obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o\n"
- ">> \302\240+obj-$(CONFIG_TOUCHSCREEN_ILI2139) += ili2139.o\n"
- ">> \302\240\302\240obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o\n"
- ">> \302\240\302\240obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o\n"
- ">> \302\240\302\240obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o\n"
- ">> \302\240diff --git a/drivers/input/touchscreen/ili2139.c b/drivers/input/touchscreen/ili2139.c\n"
- ">> \302\240new file mode 100644\n"
- ">> \302\240index 0000000..65c2dea\n"
- ">> \302\240--- /dev/null\n"
- ">> \302\240+++ b/drivers/input/touchscreen/ili2139.c\n"
- ">> \302\240@@ -0,0 +1,320 @@\n"
- ">> \302\240+/* -------------------------------------------------------------------------\n"
- ">> \302\240+ * Copyright (C) 2016, Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>\n"
- ">> \302\240+ *\n"
- ">> \302\240+ * Derived from:\n"
- ">> \302\240+ * ili210x.c\n"
- ">> \302\240+ * Copyright (C) Olivier Sobrie <olivier-Ui3EtX6WB9GzQB+pC5nmwQ@public.gmane.org>\n"
- ">> \302\240+ *\n"
- ">> \302\240+ * This program is free software; you can redistribute it and/or modify\n"
- ">> \302\240+ * it under the terms of the GNU General Public License as published by\n"
- ">> \302\240+ * the Free Software Foundation; either version 2 of the License, or\n"
- ">> \302\240+ * (at your option) any later version.\n"
- ">> \302\240+ *\n"
- ">> \302\240+ * This program is distributed in the hope that it will be useful,\n"
- ">> \302\240+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- ">> \302\240+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- ">> \302\240+ * GNU General Public License for more details.\n"
- ">> \302\240+ * -------------------------------------------------------------------------\n"
- ">> \302\240+ */\n"
- ">> \302\240+\n"
- ">> \302\240+#include <linux/module.h>\n"
- ">> \302\240+#include <linux/i2c.h>\n"
- ">> \302\240+#include <linux/interrupt.h>\n"
- ">> \302\240+#include <linux/slab.h>\n"
- ">> \302\240+#include <linux/input.h>\n"
- ">> \302\240+#include <linux/input/mt.h>\n"
- ">> \302\240+#include <linux/input/touchscreen.h>\n"
- ">> \302\240+#include <linux/delay.h>\n"
- ">> \302\240+#include <linux/workqueue.h>\n"
- ">> \302\240+\n"
- ">> \302\240+#define DEFAULT_POLL_PERIOD 20\n"
- ">> \302\240+\n"
- ">> \302\240+#define MAX_TOUCHES 10\n"
- ">> \302\240+#define COMPATIBLE_TOUCHES 2\n"
- ">> \302\240+\n"
- ">> \302\240+/* Touchscreen commands */\n"
- ">> \302\240+#define REG_TOUCHDATA 0x10\n"
- ">> \302\240+#define REG_TOUCHSUBDATA 0x11\n"
- ">> \302\240+#define REG_PANEL_INFO 0x20\n"
- ">> \302\240+#define REG_FIRMWARE_VERSION 0x40\n"
- ">> \302\240+#define REG_PROTO_VERSION 0x42\n"
- ">> \302\240+\n"
- ">> \302\240+#define SUBDATA_STATUS_TOUCH_POINT 0x80\n"
- ">> \302\240+#define SUBDATA_STATUS_RELEASE_POINT 0x00\n"
- ">> \302\240+\n"
- ">> \302\240+struct finger {\n"
- ">> \302\240+ u8 x_low;\n"
- ">> \302\240+ u8 x_high;\n"
- ">> \302\240+ u8 y_low;\n"
- ">> \302\240+ u8 y_high;\n"
- ">> \302\240+} __packed;\n"
- ">> \302\240+\n"
- ">> \302\240+struct touchdata {\n"
- ">> \302\240+ u8 length;\n"
- ">> \302\240+ struct finger finger[COMPATIBLE_TOUCHES];\n"
- ">> \302\240+} __packed;\n"
- ">> \302\240+\n"
- ">> \302\240+struct touch_subdata {\n"
- ">> \302\240+ u8 status;\n"
- ">> \302\240+ struct finger finger;\n"
- ">> \302\240+} __packed;\n"
- ">> \302\240+\n"
- ">> \302\240+struct panel_info {\n"
- ">> \302\240+ struct finger finger_max;\n"
- ">> \302\240+ u8 xchannel_num;\n"
- ">> \302\240+ u8 ychannel_num;\n"
- ">> \302\240+} __packed;\n"
- ">> \302\240+\n"
- ">> \302\240+struct firmware_version {\n"
- ">> \302\240+ u8 id;\n"
- ">> \302\240+ u8 major;\n"
- ">> \302\240+ u8 minor;\n"
- ">> \302\240+} __packed;\n"
- ">> \302\240+\n"
- ">> \302\240+struct ili2139 {\n"
- ">> \302\240+ struct i2c_client *client;\n"
- ">> \302\240+ struct input_dev *input;\n"
- ">> \302\240+ unsigned int poll_period;\n"
- ">> \302\240+ struct delayed_work dwork;\n"
- ">> \302\240+ struct touchscreen_properties prop;\n"
- ">> \302\240+ int slots[MAX_TOUCHES];\n"
- ">> \302\240+ int ids[MAX_TOUCHES];\n"
- ">> \302\240+ struct input_mt_pos pos[MAX_TOUCHES];\n"
- ">> \302\240+};\n"
- ">> \302\240+\n"
- ">> \302\240+static int ili2139_read_reg(struct i2c_client *client, u8 reg, void *buf,\n"
- ">> \302\240+ size_t len)\n"
- ">> \302\240+{\n"
- ">> \302\240+ struct i2c_msg msg[2] = {\n"
- ">> \302\240+ {\n"
- ">> \302\240+ .addr = client->addr,\n"
- ">> \302\240+ .flags = 0,\n"
- ">> \302\240+ .len = 1,\n"
- ">> \302\240+ .buf = &reg,\n"
- ">> \302\240+ },\n"
- ">> \302\240+ {\n"
- ">> \302\240+ .addr = client->addr,\n"
- ">> \302\240+ .flags = I2C_M_RD,\n"
- ">> \302\240+ .len = len,\n"
- ">> \302\240+ .buf = buf,\n"
- ">> \302\240+ }\n"
- ">> \302\240+ };\n"
- ">> \302\240+\n"
- ">> \302\240+ if (i2c_transfer(client->adapter, msg, 2) != 2) {\n"
- ">> \302\240+ dev_err(&client->dev, \"i2c transfer failed\\n\");\n"
- ">> \302\240+ return -EIO;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ return 0;\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static void ili2139_work(struct work_struct *work)\n"
- ">> \302\240+{\n"
- ">> \302\240+ int id;\n"
- ">> \302\240+ struct ili2139 *priv = container_of(work, struct ili2139,\n"
- ">> \302\240+ dwork.work);\n"
- ">> \302\240+ struct i2c_client *client = priv->client;\n"
- ">> \302\240+ struct touchdata touchdata;\n"
- ">> \302\240+ struct touch_subdata subdata;\n"
- ">> \302\240+ int error;\n"
- ">> \302\240+\n"
- ">> \302\240+ error = ili2139_read_reg(client, REG_TOUCHDATA,\n"
- ">> \302\240+ &touchdata, sizeof(touchdata));\n"
- ">> \302\240+ if (error) {\n"
- ">> \302\240+ dev_err(&client->dev,\n"
- ">> \302\240+ \"Unable to get touchdata, err = %d\\n\", error);\n"
- ">> \302\240+ return;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ for (id = 0; id < touchdata.length; id++) {\n"
- ">> \302\240+ error = ili2139_read_reg(client, REG_TOUCHSUBDATA, &subdata,\n"
- ">> \302\240+ sizeof(subdata));\n"
- ">> \302\240+ if (error) {\n"
- ">> \302\240+ dev_err(&client->dev,\n"
- ">> \302\240+ \"Unable to get touch subdata, err = %d\\n\",\n"
- ">> \302\240+ error);\n"
- ">> \302\240+ return;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ priv->ids[id] = subdata.status & 0x3F;\n"
- ">> \302\240+\n"
- ">> \302\240+ /* The sequence changed in the v2 subdata protocol. */\n"
- ">> \302\240+ touchscreen_set_mt_pos(&priv->pos[id], &priv->prop,\n"
- ">> \302\240+ (subdata.finger.x_high | (subdata.finger.x_low << 8)),\n"
- ">> \302\240+ (subdata.finger.y_high | (subdata.finger.y_low << 8)));\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ input_mt_assign_slots(priv->input, priv->slots, priv->pos,\n"
- ">> \302\240+ touchdata.length, 0);\n"
- ">> \302\240+\n"
- ">> \302\240+ for (id = 0; id < touchdata.length; id++) {\n"
- ">> \302\240+ input_mt_slot(priv->input, priv->slots[id]);\n"
- ">> \302\240+ input_mt_report_slot_state(priv->input, MT_TOOL_FINGER,\n"
- ">> \302\240+ subdata.status &\n"
- ">> \302\240+ SUBDATA_STATUS_TOUCH_POINT);\n"
- ">> \302\240+ input_report_abs(priv->input, ABS_MT_POSITION_X,\n"
- ">> \302\240+ priv->pos[id].x);\n"
- ">> \302\240+ input_report_abs(priv->input, ABS_MT_POSITION_Y,\n"
- ">> \302\240+ priv->pos[id].y);\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ input_mt_sync_frame(priv->input);\n"
- ">> \302\240+ input_sync(priv->input);\n"
- ">> \302\240+\n"
- ">> \302\240+ schedule_delayed_work(&priv->dwork,\n"
- ">> \302\240+ msecs_to_jiffies(priv->poll_period));\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static irqreturn_t ili2139_irq(int irq, void *irq_data)\n"
- ">> \302\240+{\n"
- ">> \302\240+ struct ili2139 *priv = irq_data;\n"
- ">> \302\240+\n"
- ">> \302\240+ schedule_delayed_work(&priv->dwork, 0);\n"
- ">> \302\240+\n"
- ">> \302\240+ return IRQ_HANDLED;\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static int ili2139_i2c_probe(struct i2c_client *client,\n"
- ">> \302\240+ const struct i2c_device_id *id)\n"
- ">> \302\240+{\n"
- ">> \302\240+ struct device *dev = &client->dev;\n"
- ">> \302\240+ struct ili2139 *priv;\n"
- ">> \302\240+ struct input_dev *input;\n"
- ">> \302\240+ struct panel_info panel;\n"
- ">> \302\240+ struct firmware_version firmware;\n"
- ">> \302\240+ int xmax, ymax;\n"
- ">> \302\240+ int error;\n"
- ">> \302\240+\n"
- ">> \302\240+ dev_dbg(dev, \"Probing for ILI2139 I2C Touschreen driver\");\n"
- ">> \302\240+\n"
- ">> \302\240+ if (client->irq <= 0) {\n"
- ">> \302\240+ dev_err(dev, \"No IRQ!\\n\");\n"
- ">> \302\240+ return -ENODEV;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ /* Get firmware version */\n"
- ">> \302\240+ error = ili2139_read_reg(client, REG_FIRMWARE_VERSION,\n"
- ">> \302\240+ &firmware, sizeof(firmware));\n"
- ">> \302\240+ if (error) {\n"
- ">> \302\240+ dev_err(dev, \"Failed to get firmware version, err: %d\\n\",\n"
- ">> \302\240+ error);\n"
- ">> \302\240+ return error;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ /* get panel info */\n"
- ">> \302\240+ error = ili2139_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));\n"
- ">> \302\240+ if (error) {\n"
- ">> \302\240+ dev_err(dev, \"Failed to get panel information, err: %d\\n\",\n"
- ">> \302\240+ error);\n"
- ">> \302\240+ return error;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8);\n"
- ">> \302\240+ ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8);\n"
- ">> \302\240+\n"
- ">> \302\240+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);\n"
- ">> \302\240+ input = devm_input_allocate_device(dev);\n"
- ">> \302\240+ if (!priv || !input)\n"
- ">> \302\240+ return -ENOMEM;\n"
- ">> \302\240+\n"
- ">> \302\240+ priv->client = client;\n"
- ">> \302\240+ priv->input = input;\n"
- ">> \302\240+ priv->poll_period = DEFAULT_POLL_PERIOD;\n"
- ">> \302\240+ INIT_DELAYED_WORK(&priv->dwork, ili2139_work);\n"
- ">> \302\240+\n"
- ">> \302\240+ /* Setup input device */\n"
- ">> \302\240+ input->name = \"ILI2139 Touchscreen\";\n"
- ">> \302\240+ input->id.bustype = BUS_I2C;\n"
- ">> \302\240+ input->dev.parent = dev;\n"
- ">> \302\240+\n"
- ">> \302\240+ __set_bit(EV_SYN, input->evbit);\n"
- ">> \302\240+ __set_bit(EV_KEY, input->evbit);\n"
- ">> \302\240+ __set_bit(EV_ABS, input->evbit);\n"
- ">> \302\240+\n"
- ">> \302\240+ /* Multi touch */\n"
- ">> \302\240+ input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_DIRECT |\n"
- ">> \302\240+ INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);\n"
- ">> \302\240+ input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);\n"
- ">> \302\240+ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);\n"
- ">> \302\240+\n"
- ">> \302\240+ touchscreen_parse_properties(input, true, &priv->prop);\n"
- ">> \302\240+\n"
- ">> \302\240+ input_set_drvdata(input, priv);\n"
- ">> \302\240+ i2c_set_clientdata(client, priv);\n"
- ">> \302\240+\n"
- ">> \302\240+ error = devm_request_irq(dev, client->irq, ili2139_irq,\n"
- ">> \302\240+ IRQF_TRIGGER_FALLING, client->name, priv);\n"
- ">> \302\240+ if (error) {\n"
- ">> \302\240+ dev_err(dev, \"Unable to request touchscreen IRQ, err: %d\\n\",\n"
- ">> \302\240+ error);\n"
- ">> \302\240+ return error;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ error = input_register_device(priv->input);\n"
- ">> \302\240+ if (error) {\n"
- ">> \302\240+ dev_err(dev, \"Cannot register input device, err: %d\\n\", error);\n"
- ">> \302\240+ return error;\n"
- ">> \302\240+ }\n"
- ">> \302\240+\n"
- ">> \302\240+ device_init_wakeup(&client->dev, 1);\n"
- ">> \302\240+\n"
- ">> \302\240+ dev_dbg(dev,\n"
- ">> \302\240+ \"ILI2139 initialized (IRQ: %d), firmware version %d.%d.%d\",\n"
- ">> \302\240+ client->irq, firmware.id, firmware.major, firmware.minor);\n"
- ">> \302\240+\n"
- ">> \302\240+ return 0;\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static int ili2139_i2c_remove(struct i2c_client *client)\n"
- ">> \302\240+{\n"
- ">> \302\240+ struct ili2139 *priv = i2c_get_clientdata(client);\n"
- ">> \302\240+\n"
- ">> \302\240+ cancel_delayed_work_sync(&priv->dwork);\n"
- ">> \302\240+\n"
- ">> \302\240+ return 0;\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static int __maybe_unused ili2139_i2c_suspend(struct device *dev)\n"
- ">> \302\240+{\n"
- ">> \302\240+ struct i2c_client *client = to_i2c_client(dev);\n"
- ">> \302\240+\n"
- ">> \302\240+ if (device_may_wakeup(&client->dev))\n"
- ">> \302\240+ enable_irq_wake(client->irq);\n"
- ">> \302\240+\n"
- ">> \302\240+ return 0;\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static int __maybe_unused ili2139_i2c_resume(struct device *dev)\n"
- ">> \302\240+{\n"
- ">> \302\240+ struct i2c_client *client = to_i2c_client(dev);\n"
- ">> \302\240+\n"
- ">> \302\240+ if (device_may_wakeup(&client->dev))\n"
- ">> \302\240+ disable_irq_wake(client->irq);\n"
- ">> \302\240+\n"
- ">> \302\240+ return 0;\n"
- ">> \302\240+}\n"
- ">> \302\240+\n"
- ">> \302\240+static SIMPLE_DEV_PM_OPS(ili2139_i2c_pm,\n"
- ">> \302\240+ ili2139_i2c_suspend, ili2139_i2c_resume);\n"
- ">> \302\240+\n"
- ">> \302\240+static const struct i2c_device_id ili2139_i2c_id[] = {\n"
- ">> \302\240+ { \"ili2139\", 0 },\n"
- ">> \302\240+ { }\n"
- ">> \302\240+};\n"
- ">> \302\240+MODULE_DEVICE_TABLE(i2c, ili2139_i2c_id);\n"
- ">> \302\240+\n"
- ">> \302\240+static struct i2c_driver ili2139_ts_driver = {\n"
- ">> \302\240+ .driver = {\n"
- ">> \302\240+ .name = \"ili2139_i2c\",\n"
- ">> \302\240+ .pm = &ili2139_i2c_pm,\n"
- ">> \302\240+ },\n"
- ">> \302\240+ .id_table = ili2139_i2c_id,\n"
- ">> \302\240+ .probe = ili2139_i2c_probe,\n"
- ">> \302\240+ .remove = ili2139_i2c_remove,\n"
- ">> \302\240+};\n"
- ">> \302\240+\n"
- ">> \302\240+module_i2c_driver(ili2139_ts_driver);\n"
- ">> \302\240+\n"
- ">> \302\240+MODULE_AUTHOR(\"Olivier Sobrie <olivier-Ui3EtX6WB9GzQB+pC5nmwQ@public.gmane.org>\");\n"
- ">> \302\240+MODULE_DESCRIPTION(\"ILI2139 I2C Touchscreen Driver\");\n"
- ">> \302\240+MODULE_LICENSE(\"GPL\");\n"
- ">> \302\240--\n"
- ">> \302\2402.10.1\n"
+ ">> ?+config TOUCHSCREEN_ILI2139\n"
+ ">> ?+ tristate \"Ilitek ILI2139 based touchscreen\"\n"
+ ">> ?+ depends on I2C\n"
+ ">> ?+ depends on OF\n"
+ ">> ?+ help\n"
+ ">> ?+ Say Y here if you have a ILI2139 based touchscreen\n"
+ ">> ?+ controller. Such kind of chipsets can be found in several\n"
+ ">> ?+ Colorfly tablets.\n"
+ ">> ?+\n"
+ ">> ?+ If unsure, say N.\n"
+ ">> ?+\n"
+ ">> ?+ To compile this driver as a module, choose M here; the\n"
+ ">> ?+ module will be called ili2139.\n"
+ ">> ?+\n"
+ ">> ??config TOUCHSCREEN_IPROC\n"
+ ">> ??????????tristate \"IPROC touch panel driver support\"\n"
+ ">> ??????????depends on ARCH_BCM_IPROC || COMPILE_TEST\n"
+ ">> ?diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile\n"
+ ">> ?index 81b8645..930b5e2 100644\n"
+ ">> ?--- a/drivers/input/touchscreen/Makefile\n"
+ ">> ?+++ b/drivers/input/touchscreen/Makefile\n"
+ ">> ?@@ -40,6 +40,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o\n"
+ ">> ??obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o\n"
+ ">> ??obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o\n"
+ ">> ??obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o\n"
+ ">> ?+obj-$(CONFIG_TOUCHSCREEN_ILI2139) += ili2139.o\n"
+ ">> ??obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o\n"
+ ">> ??obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o\n"
+ ">> ??obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o\n"
+ ">> ?diff --git a/drivers/input/touchscreen/ili2139.c b/drivers/input/touchscreen/ili2139.c\n"
+ ">> ?new file mode 100644\n"
+ ">> ?index 0000000..65c2dea\n"
+ ">> ?--- /dev/null\n"
+ ">> ?+++ b/drivers/input/touchscreen/ili2139.c\n"
+ ">> ?@@ -0,0 +1,320 @@\n"
+ ">> ?+/* -------------------------------------------------------------------------\n"
+ ">> ?+ * Copyright (C) 2016, Icenowy Zheng <icenowy@aosc.xyz>\n"
+ ">> ?+ *\n"
+ ">> ?+ * Derived from:\n"
+ ">> ?+ * ili210x.c\n"
+ ">> ?+ * Copyright (C) Olivier Sobrie <olivier@sobrie.be>\n"
+ ">> ?+ *\n"
+ ">> ?+ * This program is free software; you can redistribute it and/or modify\n"
+ ">> ?+ * it under the terms of the GNU General Public License as published by\n"
+ ">> ?+ * the Free Software Foundation; either version 2 of the License, or\n"
+ ">> ?+ * (at your option) any later version.\n"
+ ">> ?+ *\n"
+ ">> ?+ * This program is distributed in the hope that it will be useful,\n"
+ ">> ?+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ ">> ?+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ ">> ?+ * GNU General Public License for more details.\n"
+ ">> ?+ * -------------------------------------------------------------------------\n"
+ ">> ?+ */\n"
+ ">> ?+\n"
+ ">> ?+#include <linux/module.h>\n"
+ ">> ?+#include <linux/i2c.h>\n"
+ ">> ?+#include <linux/interrupt.h>\n"
+ ">> ?+#include <linux/slab.h>\n"
+ ">> ?+#include <linux/input.h>\n"
+ ">> ?+#include <linux/input/mt.h>\n"
+ ">> ?+#include <linux/input/touchscreen.h>\n"
+ ">> ?+#include <linux/delay.h>\n"
+ ">> ?+#include <linux/workqueue.h>\n"
+ ">> ?+\n"
+ ">> ?+#define DEFAULT_POLL_PERIOD 20\n"
+ ">> ?+\n"
+ ">> ?+#define MAX_TOUCHES 10\n"
+ ">> ?+#define COMPATIBLE_TOUCHES 2\n"
+ ">> ?+\n"
+ ">> ?+/* Touchscreen commands */\n"
+ ">> ?+#define REG_TOUCHDATA 0x10\n"
+ ">> ?+#define REG_TOUCHSUBDATA 0x11\n"
+ ">> ?+#define REG_PANEL_INFO 0x20\n"
+ ">> ?+#define REG_FIRMWARE_VERSION 0x40\n"
+ ">> ?+#define REG_PROTO_VERSION 0x42\n"
+ ">> ?+\n"
+ ">> ?+#define SUBDATA_STATUS_TOUCH_POINT 0x80\n"
+ ">> ?+#define SUBDATA_STATUS_RELEASE_POINT 0x00\n"
+ ">> ?+\n"
+ ">> ?+struct finger {\n"
+ ">> ?+ u8 x_low;\n"
+ ">> ?+ u8 x_high;\n"
+ ">> ?+ u8 y_low;\n"
+ ">> ?+ u8 y_high;\n"
+ ">> ?+} __packed;\n"
+ ">> ?+\n"
+ ">> ?+struct touchdata {\n"
+ ">> ?+ u8 length;\n"
+ ">> ?+ struct finger finger[COMPATIBLE_TOUCHES];\n"
+ ">> ?+} __packed;\n"
+ ">> ?+\n"
+ ">> ?+struct touch_subdata {\n"
+ ">> ?+ u8 status;\n"
+ ">> ?+ struct finger finger;\n"
+ ">> ?+} __packed;\n"
+ ">> ?+\n"
+ ">> ?+struct panel_info {\n"
+ ">> ?+ struct finger finger_max;\n"
+ ">> ?+ u8 xchannel_num;\n"
+ ">> ?+ u8 ychannel_num;\n"
+ ">> ?+} __packed;\n"
+ ">> ?+\n"
+ ">> ?+struct firmware_version {\n"
+ ">> ?+ u8 id;\n"
+ ">> ?+ u8 major;\n"
+ ">> ?+ u8 minor;\n"
+ ">> ?+} __packed;\n"
+ ">> ?+\n"
+ ">> ?+struct ili2139 {\n"
+ ">> ?+ struct i2c_client *client;\n"
+ ">> ?+ struct input_dev *input;\n"
+ ">> ?+ unsigned int poll_period;\n"
+ ">> ?+ struct delayed_work dwork;\n"
+ ">> ?+ struct touchscreen_properties prop;\n"
+ ">> ?+ int slots[MAX_TOUCHES];\n"
+ ">> ?+ int ids[MAX_TOUCHES];\n"
+ ">> ?+ struct input_mt_pos pos[MAX_TOUCHES];\n"
+ ">> ?+};\n"
+ ">> ?+\n"
+ ">> ?+static int ili2139_read_reg(struct i2c_client *client, u8 reg, void *buf,\n"
+ ">> ?+ size_t len)\n"
+ ">> ?+{\n"
+ ">> ?+ struct i2c_msg msg[2] = {\n"
+ ">> ?+ {\n"
+ ">> ?+ .addr = client->addr,\n"
+ ">> ?+ .flags = 0,\n"
+ ">> ?+ .len = 1,\n"
+ ">> ?+ .buf = &reg,\n"
+ ">> ?+ },\n"
+ ">> ?+ {\n"
+ ">> ?+ .addr = client->addr,\n"
+ ">> ?+ .flags = I2C_M_RD,\n"
+ ">> ?+ .len = len,\n"
+ ">> ?+ .buf = buf,\n"
+ ">> ?+ }\n"
+ ">> ?+ };\n"
+ ">> ?+\n"
+ ">> ?+ if (i2c_transfer(client->adapter, msg, 2) != 2) {\n"
+ ">> ?+ dev_err(&client->dev, \"i2c transfer failed\\n\");\n"
+ ">> ?+ return -EIO;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ return 0;\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static void ili2139_work(struct work_struct *work)\n"
+ ">> ?+{\n"
+ ">> ?+ int id;\n"
+ ">> ?+ struct ili2139 *priv = container_of(work, struct ili2139,\n"
+ ">> ?+ dwork.work);\n"
+ ">> ?+ struct i2c_client *client = priv->client;\n"
+ ">> ?+ struct touchdata touchdata;\n"
+ ">> ?+ struct touch_subdata subdata;\n"
+ ">> ?+ int error;\n"
+ ">> ?+\n"
+ ">> ?+ error = ili2139_read_reg(client, REG_TOUCHDATA,\n"
+ ">> ?+ &touchdata, sizeof(touchdata));\n"
+ ">> ?+ if (error) {\n"
+ ">> ?+ dev_err(&client->dev,\n"
+ ">> ?+ \"Unable to get touchdata, err = %d\\n\", error);\n"
+ ">> ?+ return;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ for (id = 0; id < touchdata.length; id++) {\n"
+ ">> ?+ error = ili2139_read_reg(client, REG_TOUCHSUBDATA, &subdata,\n"
+ ">> ?+ sizeof(subdata));\n"
+ ">> ?+ if (error) {\n"
+ ">> ?+ dev_err(&client->dev,\n"
+ ">> ?+ \"Unable to get touch subdata, err = %d\\n\",\n"
+ ">> ?+ error);\n"
+ ">> ?+ return;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ priv->ids[id] = subdata.status & 0x3F;\n"
+ ">> ?+\n"
+ ">> ?+ /* The sequence changed in the v2 subdata protocol. */\n"
+ ">> ?+ touchscreen_set_mt_pos(&priv->pos[id], &priv->prop,\n"
+ ">> ?+ (subdata.finger.x_high | (subdata.finger.x_low << 8)),\n"
+ ">> ?+ (subdata.finger.y_high | (subdata.finger.y_low << 8)));\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ input_mt_assign_slots(priv->input, priv->slots, priv->pos,\n"
+ ">> ?+ touchdata.length, 0);\n"
+ ">> ?+\n"
+ ">> ?+ for (id = 0; id < touchdata.length; id++) {\n"
+ ">> ?+ input_mt_slot(priv->input, priv->slots[id]);\n"
+ ">> ?+ input_mt_report_slot_state(priv->input, MT_TOOL_FINGER,\n"
+ ">> ?+ subdata.status &\n"
+ ">> ?+ SUBDATA_STATUS_TOUCH_POINT);\n"
+ ">> ?+ input_report_abs(priv->input, ABS_MT_POSITION_X,\n"
+ ">> ?+ priv->pos[id].x);\n"
+ ">> ?+ input_report_abs(priv->input, ABS_MT_POSITION_Y,\n"
+ ">> ?+ priv->pos[id].y);\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ input_mt_sync_frame(priv->input);\n"
+ ">> ?+ input_sync(priv->input);\n"
+ ">> ?+\n"
+ ">> ?+ schedule_delayed_work(&priv->dwork,\n"
+ ">> ?+ msecs_to_jiffies(priv->poll_period));\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static irqreturn_t ili2139_irq(int irq, void *irq_data)\n"
+ ">> ?+{\n"
+ ">> ?+ struct ili2139 *priv = irq_data;\n"
+ ">> ?+\n"
+ ">> ?+ schedule_delayed_work(&priv->dwork, 0);\n"
+ ">> ?+\n"
+ ">> ?+ return IRQ_HANDLED;\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static int ili2139_i2c_probe(struct i2c_client *client,\n"
+ ">> ?+ const struct i2c_device_id *id)\n"
+ ">> ?+{\n"
+ ">> ?+ struct device *dev = &client->dev;\n"
+ ">> ?+ struct ili2139 *priv;\n"
+ ">> ?+ struct input_dev *input;\n"
+ ">> ?+ struct panel_info panel;\n"
+ ">> ?+ struct firmware_version firmware;\n"
+ ">> ?+ int xmax, ymax;\n"
+ ">> ?+ int error;\n"
+ ">> ?+\n"
+ ">> ?+ dev_dbg(dev, \"Probing for ILI2139 I2C Touschreen driver\");\n"
+ ">> ?+\n"
+ ">> ?+ if (client->irq <= 0) {\n"
+ ">> ?+ dev_err(dev, \"No IRQ!\\n\");\n"
+ ">> ?+ return -ENODEV;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ /* Get firmware version */\n"
+ ">> ?+ error = ili2139_read_reg(client, REG_FIRMWARE_VERSION,\n"
+ ">> ?+ &firmware, sizeof(firmware));\n"
+ ">> ?+ if (error) {\n"
+ ">> ?+ dev_err(dev, \"Failed to get firmware version, err: %d\\n\",\n"
+ ">> ?+ error);\n"
+ ">> ?+ return error;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ /* get panel info */\n"
+ ">> ?+ error = ili2139_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));\n"
+ ">> ?+ if (error) {\n"
+ ">> ?+ dev_err(dev, \"Failed to get panel information, err: %d\\n\",\n"
+ ">> ?+ error);\n"
+ ">> ?+ return error;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8);\n"
+ ">> ?+ ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8);\n"
+ ">> ?+\n"
+ ">> ?+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);\n"
+ ">> ?+ input = devm_input_allocate_device(dev);\n"
+ ">> ?+ if (!priv || !input)\n"
+ ">> ?+ return -ENOMEM;\n"
+ ">> ?+\n"
+ ">> ?+ priv->client = client;\n"
+ ">> ?+ priv->input = input;\n"
+ ">> ?+ priv->poll_period = DEFAULT_POLL_PERIOD;\n"
+ ">> ?+ INIT_DELAYED_WORK(&priv->dwork, ili2139_work);\n"
+ ">> ?+\n"
+ ">> ?+ /* Setup input device */\n"
+ ">> ?+ input->name = \"ILI2139 Touchscreen\";\n"
+ ">> ?+ input->id.bustype = BUS_I2C;\n"
+ ">> ?+ input->dev.parent = dev;\n"
+ ">> ?+\n"
+ ">> ?+ __set_bit(EV_SYN, input->evbit);\n"
+ ">> ?+ __set_bit(EV_KEY, input->evbit);\n"
+ ">> ?+ __set_bit(EV_ABS, input->evbit);\n"
+ ">> ?+\n"
+ ">> ?+ /* Multi touch */\n"
+ ">> ?+ input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_DIRECT |\n"
+ ">> ?+ INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);\n"
+ ">> ?+ input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);\n"
+ ">> ?+ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);\n"
+ ">> ?+\n"
+ ">> ?+ touchscreen_parse_properties(input, true, &priv->prop);\n"
+ ">> ?+\n"
+ ">> ?+ input_set_drvdata(input, priv);\n"
+ ">> ?+ i2c_set_clientdata(client, priv);\n"
+ ">> ?+\n"
+ ">> ?+ error = devm_request_irq(dev, client->irq, ili2139_irq,\n"
+ ">> ?+ IRQF_TRIGGER_FALLING, client->name, priv);\n"
+ ">> ?+ if (error) {\n"
+ ">> ?+ dev_err(dev, \"Unable to request touchscreen IRQ, err: %d\\n\",\n"
+ ">> ?+ error);\n"
+ ">> ?+ return error;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ error = input_register_device(priv->input);\n"
+ ">> ?+ if (error) {\n"
+ ">> ?+ dev_err(dev, \"Cannot register input device, err: %d\\n\", error);\n"
+ ">> ?+ return error;\n"
+ ">> ?+ }\n"
+ ">> ?+\n"
+ ">> ?+ device_init_wakeup(&client->dev, 1);\n"
+ ">> ?+\n"
+ ">> ?+ dev_dbg(dev,\n"
+ ">> ?+ \"ILI2139 initialized (IRQ: %d), firmware version %d.%d.%d\",\n"
+ ">> ?+ client->irq, firmware.id, firmware.major, firmware.minor);\n"
+ ">> ?+\n"
+ ">> ?+ return 0;\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static int ili2139_i2c_remove(struct i2c_client *client)\n"
+ ">> ?+{\n"
+ ">> ?+ struct ili2139 *priv = i2c_get_clientdata(client);\n"
+ ">> ?+\n"
+ ">> ?+ cancel_delayed_work_sync(&priv->dwork);\n"
+ ">> ?+\n"
+ ">> ?+ return 0;\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static int __maybe_unused ili2139_i2c_suspend(struct device *dev)\n"
+ ">> ?+{\n"
+ ">> ?+ struct i2c_client *client = to_i2c_client(dev);\n"
+ ">> ?+\n"
+ ">> ?+ if (device_may_wakeup(&client->dev))\n"
+ ">> ?+ enable_irq_wake(client->irq);\n"
+ ">> ?+\n"
+ ">> ?+ return 0;\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static int __maybe_unused ili2139_i2c_resume(struct device *dev)\n"
+ ">> ?+{\n"
+ ">> ?+ struct i2c_client *client = to_i2c_client(dev);\n"
+ ">> ?+\n"
+ ">> ?+ if (device_may_wakeup(&client->dev))\n"
+ ">> ?+ disable_irq_wake(client->irq);\n"
+ ">> ?+\n"
+ ">> ?+ return 0;\n"
+ ">> ?+}\n"
+ ">> ?+\n"
+ ">> ?+static SIMPLE_DEV_PM_OPS(ili2139_i2c_pm,\n"
+ ">> ?+ ili2139_i2c_suspend, ili2139_i2c_resume);\n"
+ ">> ?+\n"
+ ">> ?+static const struct i2c_device_id ili2139_i2c_id[] = {\n"
+ ">> ?+ { \"ili2139\", 0 },\n"
+ ">> ?+ { }\n"
+ ">> ?+};\n"
+ ">> ?+MODULE_DEVICE_TABLE(i2c, ili2139_i2c_id);\n"
+ ">> ?+\n"
+ ">> ?+static struct i2c_driver ili2139_ts_driver = {\n"
+ ">> ?+ .driver = {\n"
+ ">> ?+ .name = \"ili2139_i2c\",\n"
+ ">> ?+ .pm = &ili2139_i2c_pm,\n"
+ ">> ?+ },\n"
+ ">> ?+ .id_table = ili2139_i2c_id,\n"
+ ">> ?+ .probe = ili2139_i2c_probe,\n"
+ ">> ?+ .remove = ili2139_i2c_remove,\n"
+ ">> ?+};\n"
+ ">> ?+\n"
+ ">> ?+module_i2c_driver(ili2139_ts_driver);\n"
+ ">> ?+\n"
+ ">> ?+MODULE_AUTHOR(\"Olivier Sobrie <olivier@sobrie.be>\");\n"
+ ">> ?+MODULE_DESCRIPTION(\"ILI2139 I2C Touchscreen Driver\");\n"
+ ">> ?+MODULE_LICENSE(\"GPL\");\n"
+ ">> ?--\n"
+ ">> ?2.10.1\n"
  ">\n"
  "> --\n"
- "> Dmitry\n"
- "\n"
- "-- \n"
- "You received this message because you are subscribed to the Google Groups \"linux-sunxi\" group.\n"
- "To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org\n"
- For more options, visit https://groups.google.com/d/optout.
+ > Dmitry
 
-cbb8b6cbba6162938f860ba28cdbba9b8fe4bc33c1f7e4f134f7c86dd43baaf7
+628a4155faa96cf7a6ff3639df0fdc0b65f5f105301155ae5a6850230d3cab88

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.