aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.14/950-0162-Input-add-I2C-attached-EETI-EXC3000-multi-touch-driv.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.14/950-0162-Input-add-I2C-attached-EETI-EXC3000-multi-touch-driv.patch')
-rw-r--r--target/linux/brcm2708/patches-4.14/950-0162-Input-add-I2C-attached-EETI-EXC3000-multi-touch-driv.patch320
1 files changed, 0 insertions, 320 deletions
diff --git a/target/linux/brcm2708/patches-4.14/950-0162-Input-add-I2C-attached-EETI-EXC3000-multi-touch-driv.patch b/target/linux/brcm2708/patches-4.14/950-0162-Input-add-I2C-attached-EETI-EXC3000-multi-touch-driv.patch
deleted file mode 100644
index 033039e5cb..0000000000
--- a/target/linux/brcm2708/patches-4.14/950-0162-Input-add-I2C-attached-EETI-EXC3000-multi-touch-driv.patch
+++ /dev/null
@@ -1,320 +0,0 @@
-From 99aaee7d1fde86bd2119d84e90435d89d6d3af07 Mon Sep 17 00:00:00 2001
-From: Ahmet Inan <inan@distec.de>
-Date: Sat, 14 Oct 2017 10:10:53 -0700
-Subject: [PATCH 162/454] Input: add I2C attached EETI EXC3000 multi touch
- driver
-
-commit 7e577a17f2eefeef32f1106ebf91e7cd143ba654 upstream.
-beware: code adapted to use the old timer API.
-
-The 3000 series have a new protocol which allows to report up to 5 points
-in a single 66 byte frame. One must always read in 66 byte frames.
-To support up to 10 points, two consecutive frames need to be read:
-The first frame says how many points until sync.
-The second frame must say zero points or both frames must be discarded.
-
-To be able to work with the higher 400KHz I2C bus rate, one must
-successfully send a special package prior _each_ read or the controller
-will refuse to cooperate.
-
-This is a minimal implementation based on egalax_i2c.c (which can be found
-on the internet) and egalax_ts.c but without the vendor interface and no
-power management support.
-
-Signed-off-by: Ahmet Inan <inan@distec.de>
-Acked-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
----
- .../bindings/input/touchscreen/exc3000.txt | 27 +++
- drivers/input/touchscreen/Kconfig | 10 +
- drivers/input/touchscreen/Makefile | 1 +
- drivers/input/touchscreen/exc3000.c | 223 ++++++++++++++++++
- 4 files changed, 261 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/input/touchscreen/exc3000.txt
- create mode 100644 drivers/input/touchscreen/exc3000.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/input/touchscreen/exc3000.txt
-@@ -0,0 +1,27 @@
-+* EETI EXC3000 Multiple Touch Controller
-+
-+Required properties:
-+- compatible: must be "eeti,exc3000"
-+- reg: i2c slave address
-+- interrupt-parent: the phandle for the interrupt controller
-+- interrupts: touch controller interrupt
-+- touchscreen-size-x: See touchscreen.txt
-+- touchscreen-size-y: See touchscreen.txt
-+
-+Optional properties:
-+- touchscreen-inverted-x: See touchscreen.txt
-+- touchscreen-inverted-y: See touchscreen.txt
-+- touchscreen-swapped-x-y: See touchscreen.txt
-+
-+Example:
-+
-+ touchscreen@2a {
-+ compatible = "eeti,exc3000";
-+ reg = <0x2a>;
-+ interrupt-parent = <&gpio1>;
-+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
-+ touchscreen-size-x = <4096>;
-+ touchscreen-size-y = <4096>;
-+ touchscreen-inverted-x;
-+ touchscreen-swapped-x-y;
-+ };
---- a/drivers/input/touchscreen/Kconfig
-+++ b/drivers/input/touchscreen/Kconfig
-@@ -316,6 +316,16 @@ config TOUCHSCREEN_EGALAX_SERIAL
- To compile this driver as a module, choose M here: the
- module will be called egalax_ts_serial.
-
-+config TOUCHSCREEN_EXC3000
-+ tristate "EETI EXC3000 multi-touch panel support"
-+ depends on I2C
-+ help
-+ Say Y here to enable support for I2C connected EETI
-+ EXC3000 multi-touch panels.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called exc3000.
-+
- config TOUCHSCREEN_FUJITSU
- tristate "Fujitsu serial touchscreen"
- select SERIO
---- a/drivers/input/touchscreen/Makefile
-+++ b/drivers/input/touchscreen/Makefile
-@@ -39,6 +39,7 @@ obj-$(CONFIG_TOUCHSCREEN_ELAN) += elant
- obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
- obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
- obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
-+obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o
- obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
- obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
- obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
---- /dev/null
-+++ b/drivers/input/touchscreen/exc3000.c
-@@ -0,0 +1,223 @@
-+/*
-+ * Driver for I2C connected EETI EXC3000 multiple touch controller
-+ *
-+ * Copyright (C) 2017 Ahmet Inan <inan@distec.de>
-+ *
-+ * minimal implementation based on egalax_ts.c and egalax_i2c.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/bitops.h>
-+#include <linux/device.h>
-+#include <linux/i2c.h>
-+#include <linux/input.h>
-+#include <linux/input/mt.h>
-+#include <linux/input/touchscreen.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/timer.h>
-+#include <asm/unaligned.h>
-+
-+#define EXC3000_NUM_SLOTS 10
-+#define EXC3000_SLOTS_PER_FRAME 5
-+#define EXC3000_LEN_FRAME 66
-+#define EXC3000_LEN_POINT 10
-+#define EXC3000_MT_EVENT 6
-+#define EXC3000_TIMEOUT_MS 100
-+
-+struct exc3000_data {
-+ struct i2c_client *client;
-+ struct input_dev *input;
-+ struct touchscreen_properties prop;
-+ struct timer_list timer;
-+ u8 buf[2 * EXC3000_LEN_FRAME];
-+};
-+
-+static void exc3000_report_slots(struct input_dev *input,
-+ struct touchscreen_properties *prop,
-+ const u8 *buf, int num)
-+{
-+ for (; num--; buf += EXC3000_LEN_POINT) {
-+ if (buf[0] & BIT(0)) {
-+ input_mt_slot(input, buf[1]);
-+ input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
-+ touchscreen_report_pos(input, prop,
-+ get_unaligned_le16(buf + 2),
-+ get_unaligned_le16(buf + 4),
-+ true);
-+ }
-+ }
-+}
-+
-+static void exc3000_timer(unsigned long d)
-+{
-+ struct exc3000_data *data = (void *)d;
-+
-+ input_mt_sync_frame(data->input);
-+ input_sync(data->input);
-+}
-+
-+static int exc3000_read_frame(struct i2c_client *client, u8 *buf)
-+{
-+ int ret;
-+
-+ ret = i2c_master_send(client, "'", 2);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (ret != 2)
-+ return -EIO;
-+
-+ ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (ret != EXC3000_LEN_FRAME)
-+ return -EIO;
-+
-+ if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME ||
-+ buf[2] != EXC3000_MT_EVENT)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int exc3000_read_data(struct i2c_client *client,
-+ u8 *buf, int *n_slots)
-+{
-+ int error;
-+
-+ error = exc3000_read_frame(client, buf);
-+ if (error)
-+ return error;
-+
-+ *n_slots = buf[3];
-+ if (!*n_slots || *n_slots > EXC3000_NUM_SLOTS)
-+ return -EINVAL;
-+
-+ if (*n_slots > EXC3000_SLOTS_PER_FRAME) {
-+ /* Read 2nd frame to get the rest of the contacts. */
-+ error = exc3000_read_frame(client, buf + EXC3000_LEN_FRAME);
-+ if (error)
-+ return error;
-+
-+ /* 2nd chunk must have number of contacts set to 0. */
-+ if (buf[EXC3000_LEN_FRAME + 3] != 0)
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
-+{
-+ struct exc3000_data *data = dev_id;
-+ struct input_dev *input = data->input;
-+ u8 *buf = data->buf;
-+ int slots, total_slots;
-+ int error;
-+
-+ error = exc3000_read_data(data->client, buf, &total_slots);
-+ if (error) {
-+ /* Schedule a timer to release "stuck" contacts */
-+ mod_timer(&data->timer,
-+ jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS));
-+ goto out;
-+ }
-+
-+ /*
-+ * We read full state successfully, no contacts will be "stuck".
-+ */
-+ del_timer_sync(&data->timer);
-+
-+ while (total_slots > 0) {
-+ slots = min(total_slots, EXC3000_SLOTS_PER_FRAME);
-+ exc3000_report_slots(input, &data->prop, buf + 4, slots);
-+ total_slots -= slots;
-+ buf += EXC3000_LEN_FRAME;
-+ }
-+
-+ input_mt_sync_frame(input);
-+ input_sync(input);
-+
-+out:
-+ return IRQ_HANDLED;
-+}
-+
-+static int exc3000_probe(struct i2c_client *client,
-+ const struct i2c_device_id *id)
-+{
-+ struct exc3000_data *data;
-+ struct input_dev *input;
-+ int error;
-+
-+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->client = client;
-+ setup_timer(&data->timer, exc3000_timer, (unsigned long)data);
-+
-+ input = devm_input_allocate_device(&client->dev);
-+ if (!input)
-+ return -ENOMEM;
-+
-+ data->input = input;
-+
-+ input->name = "EETI EXC3000 Touch Screen";
-+ input->id.bustype = BUS_I2C;
-+
-+ input_set_abs_params(input, ABS_MT_POSITION_X, 0, 4095, 0, 0);
-+ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 4095, 0, 0);
-+ touchscreen_parse_properties(input, true, &data->prop);
-+
-+ error = input_mt_init_slots(input, EXC3000_NUM_SLOTS,
-+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
-+ if (error)
-+ return error;
-+
-+ error = input_register_device(input);
-+ if (error)
-+ return error;
-+
-+ error = devm_request_threaded_irq(&client->dev, client->irq,
-+ NULL, exc3000_interrupt, IRQF_ONESHOT,
-+ client->name, data);
-+ if (error)
-+ return error;
-+
-+ return 0;
-+}
-+
-+static const struct i2c_device_id exc3000_id[] = {
-+ { "exc3000", 0 },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(i2c, exc3000_id);
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id exc3000_of_match[] = {
-+ { .compatible = "eeti,exc3000" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, exc3000_of_match);
-+#endif
-+
-+static struct i2c_driver exc3000_driver = {
-+ .driver = {
-+ .name = "exc3000",
-+ .of_match_table = of_match_ptr(exc3000_of_match),
-+ },
-+ .id_table = exc3000_id,
-+ .probe = exc3000_probe,
-+};
-+
-+module_i2c_driver(exc3000_driver);
-+
-+MODULE_AUTHOR("Ahmet Inan <inan@distec.de>");
-+MODULE_DESCRIPTION("I2C connected EETI EXC3000 multiple touch controller driver");
-+MODULE_LICENSE("GPL v2");