linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen
@ 2015-12-07  7:25 Priit Laes
  2015-12-07  7:26 ` [PATCH 1/2] ARM: dts: sun4i: gemei-g9: Add touchscreen (Goodix gt801x2) support Priit Laes
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Priit Laes @ 2015-12-07  7:25 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-input,
	Aleksei Mamlin, linux-sunxi, Priit Laes

This series adds support for Goodix GT801 2+1 touchscreen controller
and hooks it up on Gemei G9 tablet.

Now about GT801 2+1 - I initially tried to implement this inside the
existing Goodix driver, but unfortunately there are too many small
bits and pieces that would make the otherwise simple driver a
complicated mess:
  - endianness differences of coordinate readouts
  - totally different touch protocol
  - configuration layout and version information
  - I2C register differences (2 bytes vs single byte)

To apply the patchset, you need both linux-input/next and
linux-sunxi/next merged.

Patch 1 (Gemei G9 devicetree bits) should go via linux-sunxi tree.
Patch 2 (GT801 2+1 driver implementation) via linux-input

Priit Laes (2):
  ARM: dts: sun4i: gemei-g9: Add touchscreen (Goodix gt801x2) support
  input: gt801_2plus1 - Add initial support for Goodix GT801 2+1

 .../bindings/input/touchscreen/gt801_2plus1.txt    |  23 ++
 MAINTAINERS                                        |   6 +
 arch/arm/boot/dts/sun4i-a10-gemei-g9.dts           |  26 +-
 drivers/input/touchscreen/Kconfig                  |  19 +-
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/gt801_2plus1.c           | 375 +++++++++++++++++++++
 6 files changed, 445 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
 create mode 100644 drivers/input/touchscreen/gt801_2plus1.c

-- 
2.6.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] ARM: dts: sun4i: gemei-g9: Add touchscreen (Goodix gt801x2) support
  2015-12-07  7:25 [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Priit Laes
@ 2015-12-07  7:26 ` Priit Laes
  2015-12-07  7:26 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Priit Laes
  2015-12-08 12:14 ` [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Bastien Nocera
  2 siblings, 0 replies; 8+ messages in thread
From: Priit Laes @ 2015-12-07  7:26 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-input,
	Aleksei Mamlin, linux-sunxi, Priit Laes

Goodix GT801 2+1 is a touchscreen controller supporting up to
10 touches.

Enable pin and wakeup pin support is currently not implemented:
 - enable pin (PI16, specified in FEX) seems to be wrong
 - wakeup pin needs some additional reverse engineering work

Signed-off-by: Priit Laes <plaes@plaes.org>
---
 arch/arm/boot/dts/sun4i-a10-gemei-g9.dts | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
index 1d73a98..52e6275 100644
--- a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
+++ b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
@@ -48,6 +48,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
 
 / {
 	model = "Gemei G9 Tablet";
@@ -65,11 +66,11 @@
 /*
  * TODO:
  *   2x cameras via CSI
- *   audio input
+ *   audio input (+ ext. amplifier enable GPIO)
  *   AXP battery management
  *   NAND
  *   OTG
- *   Touchscreen - gt801_2plus1 @ i2c adapter 2 @ 0x48
+ *   Touchscreen enable and wakeup pins
  */
 &codec {
 	status = "okay";
@@ -114,6 +115,27 @@
 	};
 };
 
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+
+	touchscreen@55 {
+		compatible = "goodix,gt801_2plus1";
+		reg = <0x55>;
+
+		interrupt-parent = <&pio>;
+		interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; /* EINT21 (PH21) */
+
+		/*
+		 * TODO - figure out the wakeup pin:
+		 *   ctp_wakeup = port:PB13<1><default><default><1>
+		 * TODO - find correct GPIO pin, PI16 seems to be incorrect:
+		 *   ctp_en     = port:PI16<1><default><default><0>
+		 */
+	};
+};
+
 &lradc {
 	vref-supply = <&reg_ldo2>;
 
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1
  2015-12-07  7:25 [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Priit Laes
  2015-12-07  7:26 ` [PATCH 1/2] ARM: dts: sun4i: gemei-g9: Add touchscreen (Goodix gt801x2) support Priit Laes
@ 2015-12-07  7:26 ` Priit Laes
  2015-12-08 12:14   ` Bastien Nocera
  2015-12-08 15:18   ` Rob Herring
  2015-12-08 12:14 ` [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Bastien Nocera
  2 siblings, 2 replies; 8+ messages in thread
From: Priit Laes @ 2015-12-07  7:26 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-input,
	Aleksei Mamlin, linux-sunxi, Priit Laes

This patch adds Goodix GT801 2+1 touchscreen controller support.

GT801 2+1 is a 10-finger touch controller consisting of
ARM controller interfacing two GT801 5-finger controllers.

Signed-off-by: Priit Laes <plaes@plaes.org>
---
 .../bindings/input/touchscreen/gt801_2plus1.txt    |  23 ++
 MAINTAINERS                                        |   6 +
 drivers/input/touchscreen/Kconfig                  |  19 +-
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/gt801_2plus1.c           | 375 +++++++++++++++++++++
 5 files changed, 421 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
 create mode 100644 drivers/input/touchscreen/gt801_2plus1.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt b/Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
new file mode 100644
index 0000000..070ff5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
@@ -0,0 +1,23 @@
+Device tree bindings for Goodix GT801 2+1 series touchscreen controller
+
+Required properties:
+
+ - compatible		: Should be "goodix,gt801_2plus1"
+ - reg			: I2C address of the chip. Should be 0x55
+ - interrupt-parent	: Interrupt controller to which the chip is connected
+ - interrupts		: Interrupt to which the chip is connected
+
+Example:
+
+	i2c@00000000 {
+		/* ... */
+
+		touchscreen@55 {
+			compatible = "goodix,gt801_2plus1";
+			reg = <0x55>;
+			interrupt-parent = <&gpio>;
+			interrupts = <0 0>;
+		};
+
+		/* ... */
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index cba790b..e292126 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4743,6 +4743,12 @@ L:	linux-input@vger.kernel.org
 S:	Maintained
 F:	drivers/input/touchscreen/goodix.c
 
+GOODIX GT801 2PLUS1 TOUCHSCREEN
+M:	Priit Laes <plaes@plaes.org>
+L:	linux-input@vger.kernel.org
+S:	Maintained
+F:	drivers/input/touchscreen/gt801_2plus1.c
+
 GPIO SUBSYSTEM
 M:	Linus Walleij <linus.walleij@linaro.org>
 M:	Alexandre Courbot <gnurou@gmail.com>
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index ae33da7..c7c3324 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -322,11 +322,11 @@ config TOUCHSCREEN_FUJITSU
 	  module will be called fujitsu-ts.
 
 config TOUCHSCREEN_GOODIX
-	tristate "Goodix I2C touchscreen"
+	tristate "Goodix GT9xx I2C touchscreen"
 	depends on I2C
 	help
-	  Say Y here if you have the Goodix touchscreen (such as one
-	  installed in Onda v975w tablets) connected to your
+	  Say Y here if you have one of the Goodix GT9xx touchscreens
+	  (such as one installed in Onda v975w tablet) connected to your
 	  system. It also supports 5-finger chip models, which can be
 	  found on ARM tablets, like Wexler TAB7200 and MSI Primo73.
 
@@ -335,6 +335,19 @@ config TOUCHSCREEN_GOODIX
 	  To compile this driver as a module, choose M here: the
 	  module will be called goodix.
 
+config TOUCHSCREEN_GT801_2PLUS1
+	tristate "Goodix GT801 2+1 I2C touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have the Goodix GT801 2+1 touchscreen.
+	  This controller is found on some older ARM tablets like
+	  (Gemei G9 and Zareason Zatab).
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gt801_2plus1.
+
 config TOUCHSCREEN_ILI210X
 	tristate "Ilitek ILI210X based touchscreen"
 	depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index cbaa6ab..ff25d1b4 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_FT6236)	+= ft6236.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
+obj-$(CONFIG_TOUCHSCREEN_GT801_2PLUS1)	+= gt801_2plus1.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
diff --git a/drivers/input/touchscreen/gt801_2plus1.c b/drivers/input/touchscreen/gt801_2plus1.c
new file mode 100644
index 0000000..e2be479
--- /dev/null
+++ b/drivers/input/touchscreen/gt801_2plus1.c
@@ -0,0 +1,375 @@
+/*
+ *  Driver for Goodix GT801 2+1 ARM touchscreen controllers
+ *
+ *  Copyright (c) 2015 Priit Laes <plaes@plaes.org>.
+ *
+ *  This code is based on goodix.c driver (c) 2014 Red Hat Inc,
+ *  various Android codedumps (c) 2010 - 2012 Goodix Technology
+ *  and cleanups done by Emilio López (turl) for linux-sunxi.
+ *
+ * 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; version 2 of the License.
+ */
+#include <asm/unaligned.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/input/mt.h>
+
+struct gt801x_ts_data {
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	int abs_x_max;
+	int abs_y_max;
+	unsigned int max_touch_num;
+	unsigned int int_trigger_type;
+};
+
+#define GOODIX_MAX_HEIGHT		4096
+#define GOODIX_MAX_WIDTH		4096
+#define GOODIX_INT_TRIGGER		1
+#define GOODIX_MAX_CONTACTS		10
+#define MAX_CONTACTS_LOC	5
+#define RESOLUTION_LOC		1
+#define TRIGGER_LOC		6
+
+/* Register defines */
+#define GT801X_COOR_ADDR		0x01
+#define GT801X_CONFIG_DATA	0x65
+#define GT801X_REG_ID			0xf0
+
+/* Device specific defines */
+#define GT801X_CONFIG_MAX_LENGTH	7
+#define GT801X_CONTACT_SIZE		5
+
+static const unsigned long goodix_irq_flags[] = {
+	IRQ_TYPE_EDGE_RISING,
+	IRQ_TYPE_EDGE_FALLING,
+	IRQ_TYPE_LEVEL_LOW,
+	IRQ_TYPE_LEVEL_HIGH,
+};
+
+/**
+ * gt801x_i2c_read - read data from a register of the i2c slave device.
+ *
+ * @client: i2c device.
+ * @reg: the register to read from.
+ * @buf: raw write data buffer.
+ * @len: length of the buffer to write
+ */
+static int gt801x_i2c_read(struct i2c_client *client,
+			   u8 reg, u8 *buf, int len)
+{
+	struct i2c_msg msgs[2];
+	int ret;
+
+	msgs[0].flags = 0;
+	msgs[0].addr  = client->addr;
+	msgs[0].len   = 1;
+	msgs[0].buf   = &reg;
+
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].addr  = client->addr;
+	msgs[1].len   = len;
+	msgs[1].buf   = buf;
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+	return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
+}
+
+/**
+ * gt801x_process_events - Process incoming events
+ *
+ * @ts: our gt801x_ts_data pointer
+ *
+ * Called when the IRQ is triggered. Read the current device state, and push
+ * the input events to the user space.
+ */
+static void gt801x_process_events(struct gt801x_ts_data *ts)
+{
+	u8 point_data[3 + GT801X_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
+	u8 touch_map[GOODIX_MAX_CONTACTS] = {0};
+	int input_x, input_y, input_w;
+	u8 checksum = 0;
+	u16 touch_raw;
+	u8 touch_num;
+	int error;
+	int loc;
+	int i;
+
+	error = gt801x_i2c_read(ts->client, GT801X_COOR_ADDR,
+				point_data, sizeof(point_data));
+	if (error) {
+		dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
+		return;
+	}
+
+	/* Fetch touch mapping bits */
+	touch_raw = get_unaligned_le16(&point_data[0]);
+	if (!touch_raw)
+		return;
+
+	/* Build touch map */
+	touch_num = 0;
+	for (i = 0; (touch_raw != 0) && (i < ts->max_touch_num); i++) {
+		if (touch_raw & 1)
+			touch_map[touch_num++] = i;
+			touch_raw >>= 1;
+	}
+
+	/* Calculate checksum */
+	for (i = 0; i < (touch_num*GT801X_CONTACT_SIZE + 3); i++)
+		checksum += point_data[i];
+	if (checksum != 0)
+		return;
+
+	/* Report touches */
+	for (i = 0; i < touch_num; i++) {
+		loc = 2 + GT801X_CONTACT_SIZE * i;
+		input_x = get_unaligned_be16(&point_data[loc]);
+		input_y = get_unaligned_be16(&point_data[loc + 2]);
+		input_w = point_data[loc + 4];
+
+		input_mt_slot(ts->input_dev, i);
+		input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
+		input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
+		input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
+		input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
+		input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
+	}
+
+	input_mt_sync_frame(ts->input_dev);
+	input_sync(ts->input_dev);
+}
+
+/**
+ * gt801x_ts_irq_handler - The IRQ handler
+ *
+ * @irq: interrupt number.
+ * @dev_id: private data pointer.
+ */
+static irqreturn_t gt801x_ts_irq_handler(int irq, void *dev_id)
+{
+	gt801x_process_events((struct gt801x_ts_data *)dev_id);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * gt801x_read_config - Read the embedded configuration of the panel
+ *
+ * @ts: our gt801x_ts_data pointer
+ *
+ * Must be called during probe
+ */
+static void gt801x_read_config(struct gt801x_ts_data *ts)
+{
+	u8 config[GT801X_CONFIG_MAX_LENGTH];
+	int error;
+
+	error = gt801x_i2c_read(ts->client, GT801X_CONFIG_DATA,
+				config,
+				GT801X_CONFIG_MAX_LENGTH);
+	if (error) {
+		dev_warn(&ts->client->dev,
+			 "Error reading config (%d), using defaults\n",
+			 error);
+		ts->abs_x_max = GOODIX_MAX_WIDTH;
+		ts->abs_y_max = GOODIX_MAX_HEIGHT;
+		ts->int_trigger_type = GOODIX_INT_TRIGGER;
+		ts->max_touch_num = GOODIX_MAX_CONTACTS;
+		return;
+	}
+
+	ts->abs_x_max = get_unaligned_be16(&config[RESOLUTION_LOC]);
+	ts->abs_y_max = get_unaligned_be16(&config[RESOLUTION_LOC + 2]);
+	ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
+	ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f;
+	if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) {
+		dev_err(&ts->client->dev,
+			"Invalid config, using defaults\n");
+		ts->abs_x_max = GOODIX_MAX_WIDTH;
+		ts->abs_y_max = GOODIX_MAX_HEIGHT;
+		ts->max_touch_num = GOODIX_MAX_CONTACTS;
+	}
+}
+
+/**
+ * gt801x_read_version - Read GT801 2+1 touchscreen version
+ *
+ * @client: the i2c client
+ * @version: output buffer containing the version on success
+ * @id: output buffer containing the id on success
+ */
+static int gt801x_read_version(struct i2c_client *client, u16 *version, u16 *id)
+{
+	int error;
+	u8 buf[16];
+
+	error = gt801x_i2c_read(client, GT801X_REG_ID, buf, sizeof(buf));
+	if (error) {
+		dev_err(&client->dev, "read version failed: %d\n", error);
+		return error;
+	}
+	/* TODO: version info contains 'GT801NI_3R15_1AV' */
+	print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, ARRAY_SIZE(buf));
+	*id = 0x802;
+	*version = 0x15;
+	dev_info(&client->dev, "ID %d, version: %04x\n", *id, *version);
+	return 0;
+}
+
+/**
+ * gt801x_i2c_test - I2C test function to check if the device answers.
+ *
+ * @client: the i2c client
+ */
+static int gt801x_i2c_test(struct i2c_client *client)
+{
+	int retry = 0;
+	int error;
+	u8 test;
+
+	while (retry++ < 2) {
+		error = gt801x_i2c_read(client, GT801X_CONFIG_DATA,
+					&test, 1);
+		if (!error)
+			return 0;
+
+		dev_err(&client->dev, "i2c test failed attempt %d: %d\n",
+			retry, error);
+		msleep(20);
+	}
+
+	return error;
+}
+
+/**
+ * gt801x_request_input_dev - Allocate, populate and register the input device
+ *
+ * @ts: our gt801x_ts_data pointer
+ * @version: device firmware version
+ * @id: device ID
+ *
+ * Must be called during probe
+ */
+static int gt801x_request_input_dev(struct gt801x_ts_data *ts,
+					u16 version, u16 id)
+{
+	int error;
+
+	ts->input_dev = devm_input_allocate_device(&ts->client->dev);
+	if (!ts->input_dev) {
+		dev_err(&ts->client->dev, "Failed to allocate input device.");
+		return -ENOMEM;
+	}
+
+	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
+			     0, ts->abs_x_max, 0, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+			     0, ts->abs_y_max, 0, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+
+	input_mt_init_slots(ts->input_dev, ts->max_touch_num,
+			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+
+	ts->input_dev->name = "Goodix Capacitive TouchScreen (GT801 2+1)";
+	ts->input_dev->phys = "input/ts";
+	ts->input_dev->id.bustype = BUS_I2C;
+	ts->input_dev->id.vendor = 0x0416;
+	ts->input_dev->id.product = id;
+	ts->input_dev->id.version = version;
+
+	error = input_register_device(ts->input_dev);
+	if (error) {
+		dev_err(&ts->client->dev,
+			"Failed to register input device: %d", error);
+		return error;
+	}
+
+	return 0;
+}
+
+static int gt801x_ts_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
+{
+	struct gt801x_ts_data *ts;
+	unsigned long irq_flags;
+	int error;
+	u16 version_info, id_info;
+
+	dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "I2C check functionality failed.\n");
+		return -ENXIO;
+	}
+
+	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	ts->client = client;
+	i2c_set_clientdata(client, ts);
+
+	error = gt801x_i2c_test(client);
+	if (error) {
+		dev_err(&client->dev, "I2C communication failure: %d\n", error);
+		return error;
+	}
+
+	error = gt801x_read_version(client, &version_info, &id_info);
+	if (error) {
+		dev_err(&client->dev, "Read version failed.\n");
+		return error;
+	}
+
+	gt801x_read_config(ts);
+
+	error = gt801x_request_input_dev(ts, version_info, id_info);
+	if (error)
+		return error;
+
+	irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
+	error = devm_request_threaded_irq(&ts->client->dev, client->irq,
+					  NULL, gt801x_ts_irq_handler,
+					  irq_flags, client->name, ts);
+	if (error) {
+		dev_err(&client->dev, "request IRQ failed: %d\n", error);
+		return error;
+	}
+
+	return 0;
+}
+
+static const struct i2c_device_id gt801x_ts_id[] = {
+	{ "GDIX1001:00", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, gt801x_ts_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gt801x_of_match[] = {
+	{ .compatible = "goodix,gt801_2plus1" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gt801x_of_match);
+#endif
+
+static struct i2c_driver gt801x_ts_driver = {
+	.probe = gt801x_ts_probe,
+	.id_table = gt801x_ts_id,
+	.driver = {
+		.name = "Goodix-TS",
+		.of_match_table = of_match_ptr(gt801x_of_match),
+	},
+};
+module_i2c_driver(gt801x_ts_driver);
+
+MODULE_AUTHOR("Priit Laes <plaes@plaes.org>");
+MODULE_DESCRIPTION("Goodix GT801 2+1 touchscreen driver");
+MODULE_LICENSE("GPL v2");
-- 
2.6.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen
  2015-12-07  7:25 [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Priit Laes
  2015-12-07  7:26 ` [PATCH 1/2] ARM: dts: sun4i: gemei-g9: Add touchscreen (Goodix gt801x2) support Priit Laes
  2015-12-07  7:26 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Priit Laes
@ 2015-12-08 12:14 ` Bastien Nocera
  2 siblings, 0 replies; 8+ messages in thread
From: Bastien Nocera @ 2015-12-08 12:14 UTC (permalink / raw)
  To: Priit Laes, Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Tirdea Irina
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-input,
	Aleksei Mamlin, linux-sunxi

On Mon, 2015-12-07 at 09:25 +0200, Priit Laes wrote:
> This series adds support for Goodix GT801 2+1 touchscreen controller
> and hooks it up on Gemei G9 tablet.
> 
> Now about GT801 2+1 - I initially tried to implement this inside the
> existing Goodix driver, but unfortunately there are too many small
> bits and pieces that would make the otherwise simple driver a
> complicated mess:
>   - endianness differences of coordinate readouts
>   - totally different touch protocol
>   - configuration layout and version information
>   - I2C register differences (2 bytes vs single byte)

The goodix driver will get more complicated after we merge Irina's
patchset. Instead of looking at the differences between the protocols,
which don't look insurmountable (a switch statement in a few places,
right?), you should look at the code you could share:
- power management
- ESD support
- ACPI support
- the support for variants in goodix.c (911-variants, and 967-variants)
- ability to read and write config data to the device

Taking this into account (and the fact that I can't read Chinese that
well, so my reading of the specs is cursory), would it make sense to
merge the 2 drivers?

CC'ing Irina about this.

Cheers

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1
  2015-12-07  7:26 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Priit Laes
@ 2015-12-08 12:14   ` Bastien Nocera
  2015-12-08 15:18   ` Rob Herring
  1 sibling, 0 replies; 8+ messages in thread
From: Bastien Nocera @ 2015-12-08 12:14 UTC (permalink / raw)
  To: Priit Laes, Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-input,
	Aleksei Mamlin, linux-sunxi

Hey Priit,

On Mon, 2015-12-07 at 09:26 +0200, Priit Laes wrote:
> This patch adds Goodix GT801 2+1 touchscreen controller support.
> 
> GT801 2+1 is a 10-finger touch controller consisting of
> ARM controller interfacing two GT801 5-finger controllers.

This would implement support for the "Guitar" protocol used by a few
more variants of the GT80x devices. Can you rename the driver/docs to that effect?
<snip>
> +
> +static const struct i2c_device_id gt801x_ts_id[] = {
> +	{ "GDIX1001:00", 0 },

This clashes with the ID used in the goodix.c driver.

Cheers

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1
  2015-12-07  7:26 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Priit Laes
  2015-12-08 12:14   ` Bastien Nocera
@ 2015-12-08 15:18   ` Rob Herring
  1 sibling, 0 replies; 8+ messages in thread
From: Rob Herring @ 2015-12-08 15:18 UTC (permalink / raw)
  To: Priit Laes
  Cc: Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree, linux-kernel,
	linux-arm-kernel, linux-input, Aleksei Mamlin, linux-sunxi

On Mon, Dec 07, 2015 at 09:26:01AM +0200, Priit Laes wrote:
> This patch adds Goodix GT801 2+1 touchscreen controller support.
> 
> GT801 2+1 is a 10-finger touch controller consisting of
> ARM controller interfacing two GT801 5-finger controllers.
> 
> Signed-off-by: Priit Laes <plaes@plaes.org>
> ---
>  .../bindings/input/touchscreen/gt801_2plus1.txt    |  23 ++

For the binding:

Acked-by: Rob Herring <robh@kernel.org>

>  MAINTAINERS                                        |   6 +
>  drivers/input/touchscreen/Kconfig                  |  19 +-
>  drivers/input/touchscreen/Makefile                 |   1 +
>  drivers/input/touchscreen/gt801_2plus1.c           | 375 +++++++++++++++++++++
>  5 files changed, 421 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
>  create mode 100644 drivers/input/touchscreen/gt801_2plus1.c
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt b/Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
> new file mode 100644
> index 0000000..070ff5b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/gt801_2plus1.txt
> @@ -0,0 +1,23 @@
> +Device tree bindings for Goodix GT801 2+1 series touchscreen controller
> +
> +Required properties:
> +
> + - compatible		: Should be "goodix,gt801_2plus1"
> + - reg			: I2C address of the chip. Should be 0x55
> + - interrupt-parent	: Interrupt controller to which the chip is connected
> + - interrupts		: Interrupt to which the chip is connected
> +
> +Example:
> +
> +	i2c@00000000 {
> +		/* ... */
> +
> +		touchscreen@55 {
> +			compatible = "goodix,gt801_2plus1";
> +			reg = <0x55>;
> +			interrupt-parent = <&gpio>;
> +			interrupts = <0 0>;
> +		};
> +
> +		/* ... */
> +	};
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cba790b..e292126 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4743,6 +4743,12 @@ L:	linux-input@vger.kernel.org
>  S:	Maintained
>  F:	drivers/input/touchscreen/goodix.c
>  
> +GOODIX GT801 2PLUS1 TOUCHSCREEN
> +M:	Priit Laes <plaes@plaes.org>
> +L:	linux-input@vger.kernel.org
> +S:	Maintained
> +F:	drivers/input/touchscreen/gt801_2plus1.c
> +
>  GPIO SUBSYSTEM
>  M:	Linus Walleij <linus.walleij@linaro.org>
>  M:	Alexandre Courbot <gnurou@gmail.com>
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index ae33da7..c7c3324 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -322,11 +322,11 @@ config TOUCHSCREEN_FUJITSU
>  	  module will be called fujitsu-ts.
>  
>  config TOUCHSCREEN_GOODIX
> -	tristate "Goodix I2C touchscreen"
> +	tristate "Goodix GT9xx I2C touchscreen"
>  	depends on I2C
>  	help
> -	  Say Y here if you have the Goodix touchscreen (such as one
> -	  installed in Onda v975w tablets) connected to your
> +	  Say Y here if you have one of the Goodix GT9xx touchscreens
> +	  (such as one installed in Onda v975w tablet) connected to your
>  	  system. It also supports 5-finger chip models, which can be
>  	  found on ARM tablets, like Wexler TAB7200 and MSI Primo73.
>  
> @@ -335,6 +335,19 @@ config TOUCHSCREEN_GOODIX
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called goodix.
>  
> +config TOUCHSCREEN_GT801_2PLUS1
> +	tristate "Goodix GT801 2+1 I2C touchscreen"
> +	depends on I2C
> +	help
> +	  Say Y here if you have the Goodix GT801 2+1 touchscreen.
> +	  This controller is found on some older ARM tablets like
> +	  (Gemei G9 and Zareason Zatab).
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called gt801_2plus1.
> +
>  config TOUCHSCREEN_ILI210X
>  	tristate "Ilitek ILI210X based touchscreen"
>  	depends on I2C
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index cbaa6ab..ff25d1b4 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_FT6236)	+= ft6236.o
>  obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
> +obj-$(CONFIG_TOUCHSCREEN_GT801_2PLUS1)	+= gt801_2plus1.o
>  obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
>  obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
>  obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
> diff --git a/drivers/input/touchscreen/gt801_2plus1.c b/drivers/input/touchscreen/gt801_2plus1.c
> new file mode 100644
> index 0000000..e2be479
> --- /dev/null
> +++ b/drivers/input/touchscreen/gt801_2plus1.c
> @@ -0,0 +1,375 @@
> +/*
> + *  Driver for Goodix GT801 2+1 ARM touchscreen controllers
> + *
> + *  Copyright (c) 2015 Priit Laes <plaes@plaes.org>.
> + *
> + *  This code is based on goodix.c driver (c) 2014 Red Hat Inc,
> + *  various Android codedumps (c) 2010 - 2012 Goodix Technology
> + *  and cleanups done by Emilio López (turl) for linux-sunxi.
> + *
> + * 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; version 2 of the License.
> + */
> +#include <asm/unaligned.h>
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/input/mt.h>
> +
> +struct gt801x_ts_data {
> +	struct i2c_client *client;
> +	struct input_dev *input_dev;
> +	int abs_x_max;
> +	int abs_y_max;
> +	unsigned int max_touch_num;
> +	unsigned int int_trigger_type;
> +};
> +
> +#define GOODIX_MAX_HEIGHT		4096
> +#define GOODIX_MAX_WIDTH		4096
> +#define GOODIX_INT_TRIGGER		1
> +#define GOODIX_MAX_CONTACTS		10
> +#define MAX_CONTACTS_LOC	5
> +#define RESOLUTION_LOC		1
> +#define TRIGGER_LOC		6
> +
> +/* Register defines */
> +#define GT801X_COOR_ADDR		0x01
> +#define GT801X_CONFIG_DATA	0x65
> +#define GT801X_REG_ID			0xf0
> +
> +/* Device specific defines */
> +#define GT801X_CONFIG_MAX_LENGTH	7
> +#define GT801X_CONTACT_SIZE		5
> +
> +static const unsigned long goodix_irq_flags[] = {
> +	IRQ_TYPE_EDGE_RISING,
> +	IRQ_TYPE_EDGE_FALLING,
> +	IRQ_TYPE_LEVEL_LOW,
> +	IRQ_TYPE_LEVEL_HIGH,
> +};
> +
> +/**
> + * gt801x_i2c_read - read data from a register of the i2c slave device.
> + *
> + * @client: i2c device.
> + * @reg: the register to read from.
> + * @buf: raw write data buffer.
> + * @len: length of the buffer to write
> + */
> +static int gt801x_i2c_read(struct i2c_client *client,
> +			   u8 reg, u8 *buf, int len)
> +{
> +	struct i2c_msg msgs[2];
> +	int ret;
> +
> +	msgs[0].flags = 0;
> +	msgs[0].addr  = client->addr;
> +	msgs[0].len   = 1;
> +	msgs[0].buf   = &reg;
> +
> +	msgs[1].flags = I2C_M_RD;
> +	msgs[1].addr  = client->addr;
> +	msgs[1].len   = len;
> +	msgs[1].buf   = buf;
> +
> +	ret = i2c_transfer(client->adapter, msgs, 2);
> +	return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
> +}
> +
> +/**
> + * gt801x_process_events - Process incoming events
> + *
> + * @ts: our gt801x_ts_data pointer
> + *
> + * Called when the IRQ is triggered. Read the current device state, and push
> + * the input events to the user space.
> + */
> +static void gt801x_process_events(struct gt801x_ts_data *ts)
> +{
> +	u8 point_data[3 + GT801X_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
> +	u8 touch_map[GOODIX_MAX_CONTACTS] = {0};
> +	int input_x, input_y, input_w;
> +	u8 checksum = 0;
> +	u16 touch_raw;
> +	u8 touch_num;
> +	int error;
> +	int loc;
> +	int i;
> +
> +	error = gt801x_i2c_read(ts->client, GT801X_COOR_ADDR,
> +				point_data, sizeof(point_data));
> +	if (error) {
> +		dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
> +		return;
> +	}
> +
> +	/* Fetch touch mapping bits */
> +	touch_raw = get_unaligned_le16(&point_data[0]);
> +	if (!touch_raw)
> +		return;
> +
> +	/* Build touch map */
> +	touch_num = 0;
> +	for (i = 0; (touch_raw != 0) && (i < ts->max_touch_num); i++) {
> +		if (touch_raw & 1)
> +			touch_map[touch_num++] = i;
> +			touch_raw >>= 1;
> +	}
> +
> +	/* Calculate checksum */
> +	for (i = 0; i < (touch_num*GT801X_CONTACT_SIZE + 3); i++)
> +		checksum += point_data[i];
> +	if (checksum != 0)
> +		return;
> +
> +	/* Report touches */
> +	for (i = 0; i < touch_num; i++) {
> +		loc = 2 + GT801X_CONTACT_SIZE * i;
> +		input_x = get_unaligned_be16(&point_data[loc]);
> +		input_y = get_unaligned_be16(&point_data[loc + 2]);
> +		input_w = point_data[loc + 4];
> +
> +		input_mt_slot(ts->input_dev, i);
> +		input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
> +		input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
> +		input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
> +		input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
> +		input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
> +	}
> +
> +	input_mt_sync_frame(ts->input_dev);
> +	input_sync(ts->input_dev);
> +}
> +
> +/**
> + * gt801x_ts_irq_handler - The IRQ handler
> + *
> + * @irq: interrupt number.
> + * @dev_id: private data pointer.
> + */
> +static irqreturn_t gt801x_ts_irq_handler(int irq, void *dev_id)
> +{
> +	gt801x_process_events((struct gt801x_ts_data *)dev_id);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +/**
> + * gt801x_read_config - Read the embedded configuration of the panel
> + *
> + * @ts: our gt801x_ts_data pointer
> + *
> + * Must be called during probe
> + */
> +static void gt801x_read_config(struct gt801x_ts_data *ts)
> +{
> +	u8 config[GT801X_CONFIG_MAX_LENGTH];
> +	int error;
> +
> +	error = gt801x_i2c_read(ts->client, GT801X_CONFIG_DATA,
> +				config,
> +				GT801X_CONFIG_MAX_LENGTH);
> +	if (error) {
> +		dev_warn(&ts->client->dev,
> +			 "Error reading config (%d), using defaults\n",
> +			 error);
> +		ts->abs_x_max = GOODIX_MAX_WIDTH;
> +		ts->abs_y_max = GOODIX_MAX_HEIGHT;
> +		ts->int_trigger_type = GOODIX_INT_TRIGGER;
> +		ts->max_touch_num = GOODIX_MAX_CONTACTS;
> +		return;
> +	}
> +
> +	ts->abs_x_max = get_unaligned_be16(&config[RESOLUTION_LOC]);
> +	ts->abs_y_max = get_unaligned_be16(&config[RESOLUTION_LOC + 2]);
> +	ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
> +	ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f;
> +	if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) {
> +		dev_err(&ts->client->dev,
> +			"Invalid config, using defaults\n");
> +		ts->abs_x_max = GOODIX_MAX_WIDTH;
> +		ts->abs_y_max = GOODIX_MAX_HEIGHT;
> +		ts->max_touch_num = GOODIX_MAX_CONTACTS;
> +	}
> +}
> +
> +/**
> + * gt801x_read_version - Read GT801 2+1 touchscreen version
> + *
> + * @client: the i2c client
> + * @version: output buffer containing the version on success
> + * @id: output buffer containing the id on success
> + */
> +static int gt801x_read_version(struct i2c_client *client, u16 *version, u16 *id)
> +{
> +	int error;
> +	u8 buf[16];
> +
> +	error = gt801x_i2c_read(client, GT801X_REG_ID, buf, sizeof(buf));
> +	if (error) {
> +		dev_err(&client->dev, "read version failed: %d\n", error);
> +		return error;
> +	}
> +	/* TODO: version info contains 'GT801NI_3R15_1AV' */
> +	print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, ARRAY_SIZE(buf));
> +	*id = 0x802;
> +	*version = 0x15;
> +	dev_info(&client->dev, "ID %d, version: %04x\n", *id, *version);
> +	return 0;
> +}
> +
> +/**
> + * gt801x_i2c_test - I2C test function to check if the device answers.
> + *
> + * @client: the i2c client
> + */
> +static int gt801x_i2c_test(struct i2c_client *client)
> +{
> +	int retry = 0;
> +	int error;
> +	u8 test;
> +
> +	while (retry++ < 2) {
> +		error = gt801x_i2c_read(client, GT801X_CONFIG_DATA,
> +					&test, 1);
> +		if (!error)
> +			return 0;
> +
> +		dev_err(&client->dev, "i2c test failed attempt %d: %d\n",
> +			retry, error);
> +		msleep(20);
> +	}
> +
> +	return error;
> +}
> +
> +/**
> + * gt801x_request_input_dev - Allocate, populate and register the input device
> + *
> + * @ts: our gt801x_ts_data pointer
> + * @version: device firmware version
> + * @id: device ID
> + *
> + * Must be called during probe
> + */
> +static int gt801x_request_input_dev(struct gt801x_ts_data *ts,
> +					u16 version, u16 id)
> +{
> +	int error;
> +
> +	ts->input_dev = devm_input_allocate_device(&ts->client->dev);
> +	if (!ts->input_dev) {
> +		dev_err(&ts->client->dev, "Failed to allocate input device.");
> +		return -ENOMEM;
> +	}
> +
> +	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
> +			     0, ts->abs_x_max, 0, 0);
> +	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
> +			     0, ts->abs_y_max, 0, 0);
> +	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
> +	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
> +
> +	input_mt_init_slots(ts->input_dev, ts->max_touch_num,
> +			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
> +
> +	ts->input_dev->name = "Goodix Capacitive TouchScreen (GT801 2+1)";
> +	ts->input_dev->phys = "input/ts";
> +	ts->input_dev->id.bustype = BUS_I2C;
> +	ts->input_dev->id.vendor = 0x0416;
> +	ts->input_dev->id.product = id;
> +	ts->input_dev->id.version = version;
> +
> +	error = input_register_device(ts->input_dev);
> +	if (error) {
> +		dev_err(&ts->client->dev,
> +			"Failed to register input device: %d", error);
> +		return error;
> +	}
> +
> +	return 0;
> +}
> +
> +static int gt801x_ts_probe(struct i2c_client *client,
> +			   const struct i2c_device_id *id)
> +{
> +	struct gt801x_ts_data *ts;
> +	unsigned long irq_flags;
> +	int error;
> +	u16 version_info, id_info;
> +
> +	dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr);
> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> +		dev_err(&client->dev, "I2C check functionality failed.\n");
> +		return -ENXIO;
> +	}
> +
> +	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
> +	if (!ts)
> +		return -ENOMEM;
> +
> +	ts->client = client;
> +	i2c_set_clientdata(client, ts);
> +
> +	error = gt801x_i2c_test(client);
> +	if (error) {
> +		dev_err(&client->dev, "I2C communication failure: %d\n", error);
> +		return error;
> +	}
> +
> +	error = gt801x_read_version(client, &version_info, &id_info);
> +	if (error) {
> +		dev_err(&client->dev, "Read version failed.\n");
> +		return error;
> +	}
> +
> +	gt801x_read_config(ts);
> +
> +	error = gt801x_request_input_dev(ts, version_info, id_info);
> +	if (error)
> +		return error;
> +
> +	irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
> +	error = devm_request_threaded_irq(&ts->client->dev, client->irq,
> +					  NULL, gt801x_ts_irq_handler,
> +					  irq_flags, client->name, ts);
> +	if (error) {
> +		dev_err(&client->dev, "request IRQ failed: %d\n", error);
> +		return error;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct i2c_device_id gt801x_ts_id[] = {
> +	{ "GDIX1001:00", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, gt801x_ts_id);
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id gt801x_of_match[] = {
> +	{ .compatible = "goodix,gt801_2plus1" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, gt801x_of_match);
> +#endif
> +
> +static struct i2c_driver gt801x_ts_driver = {
> +	.probe = gt801x_ts_probe,
> +	.id_table = gt801x_ts_id,
> +	.driver = {
> +		.name = "Goodix-TS",
> +		.of_match_table = of_match_ptr(gt801x_of_match),
> +	},
> +};
> +module_i2c_driver(gt801x_ts_driver);
> +
> +MODULE_AUTHOR("Priit Laes <plaes@plaes.org>");
> +MODULE_DESCRIPTION("Goodix GT801 2+1 touchscreen driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.6.3
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1
  2015-12-07  8:34 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Julia Lawall
@ 2015-12-07  9:10   ` Priit Laes
  0 siblings, 0 replies; 8+ messages in thread
From: Priit Laes @ 2015-12-07  9:10 UTC (permalink / raw)
  To: Julia Lawall
  Cc: Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	linux-kernel, linux-arm-kernel, linux-input, Aleksei Mamlin,
	linux-sunxi, kbuild-all

On Mon, 2015-12-07 at 09:34 +0100, Julia Lawall wrote:
> It looks like braces may be mising.  Please check.

Thanks, nice catch!

It's actually messed up indenting. Code works as intended.
> 
> julia
> 
> On Mon, 7 Dec 2015, kbuild test robot wrote:
> 
> > Hi Priit,
> > 
> > [auto build test WARNING on mripard/sunxi/for-next]
> > [also build test WARNING on next-20151203]
> > [cannot apply to input/next v4.4-rc4]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Priit-Laes/input-D
> river-for-Goodix-GT801-2-1-touchscreen/20151207-152831
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/mripard/lin
> ux.git sunxi/for-next
> > :::::: branch date: 46 minutes ago
> > :::::: commit date: 46 minutes ago
> > 
> > >> drivers/input/touchscreen/gt801_2plus1.c:119:3-30: code aligned
> with following code on line 120
> > 
> > git remote add linux-review https://github.com/0day-ci/linux
> > git remote update linux-review
> > git checkout d66df313f96e04572821e49cada65cb5c1bea9e2
> > vim +119 drivers/input/touchscreen/gt801_2plus1.c
> > 
> > d66df313 Priit Laes 2015-12-07  113           return;
> > d66df313 Priit Laes 2015-12-07  114  
> > d66df313 Priit Laes 2015-12-07  115   /* Build touch map */
> > d66df313 Priit Laes 2015-12-07  116   touch_num = 0;
> > d66df313 Priit Laes 2015-12-07  117   for (i = 0; (touch_raw != 0)
> && (i < ts->max_touch_num); i++) {
> > d66df313 Priit Laes 2015-12-07  118           if (touch_raw & 1)
> > d66df313 Priit Laes 2015-12-07
> @119                   touch_map[touch_num++] = i;
> > d66df313 Priit Laes 2015-12-07 @120                   touch_raw >>=
> 1;
> > d66df313 Priit Laes 2015-12-07  121   }
> > d66df313 Priit Laes 2015-12-07  122  
> > d66df313 Priit Laes 2015-12-07  123   /* Calculate checksum */
> > 
> > ---
> > 0-DAY kernel test infrastructure                Open Source
> Technology Center
> > https://lists.01.org/pipermail/kbuild-all                  ; Intel
> Corporation
> > 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1
       [not found] <201512071608.oGt2n0Wn%fengguang.wu@intel.com>
@ 2015-12-07  8:34 ` Julia Lawall
  2015-12-07  9:10   ` Priit Laes
  0 siblings, 1 reply; 8+ messages in thread
From: Julia Lawall @ 2015-12-07  8:34 UTC (permalink / raw)
  To: Priit Laes
  Cc: Maxime Ripard, Chen-Yu Tsai, Dmitry Torokhov, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	linux-kernel, linux-arm-kernel, linux-input, Aleksei Mamlin,
	linux-sunxi, Priit Laes, kbuild-all

It looks like braces may be mising.  Please check.

julia

On Mon, 7 Dec 2015, kbuild test robot wrote:

> Hi Priit,
> 
> [auto build test WARNING on mripard/sunxi/for-next]
> [also build test WARNING on next-20151203]
> [cannot apply to input/next v4.4-rc4]
> 
> url:    https://github.com/0day-ci/linux/commits/Priit-Laes/input-Driver-for-Goodix-GT801-2-1-touchscreen/20151207-152831
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git sunxi/for-next
> :::::: branch date: 46 minutes ago
> :::::: commit date: 46 minutes ago
> 
> >> drivers/input/touchscreen/gt801_2plus1.c:119:3-30: code aligned with following code on line 120
> 
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout d66df313f96e04572821e49cada65cb5c1bea9e2
> vim +119 drivers/input/touchscreen/gt801_2plus1.c
> 
> d66df313 Priit Laes 2015-12-07  113  		return;
> d66df313 Priit Laes 2015-12-07  114  
> d66df313 Priit Laes 2015-12-07  115  	/* Build touch map */
> d66df313 Priit Laes 2015-12-07  116  	touch_num = 0;
> d66df313 Priit Laes 2015-12-07  117  	for (i = 0; (touch_raw != 0) && (i < ts->max_touch_num); i++) {
> d66df313 Priit Laes 2015-12-07  118  		if (touch_raw & 1)
> d66df313 Priit Laes 2015-12-07 @119  			touch_map[touch_num++] = i;
> d66df313 Priit Laes 2015-12-07 @120  			touch_raw >>= 1;
> d66df313 Priit Laes 2015-12-07  121  	}
> d66df313 Priit Laes 2015-12-07  122  
> d66df313 Priit Laes 2015-12-07  123  	/* Calculate checksum */
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-12-08 15:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-07  7:25 [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Priit Laes
2015-12-07  7:26 ` [PATCH 1/2] ARM: dts: sun4i: gemei-g9: Add touchscreen (Goodix gt801x2) support Priit Laes
2015-12-07  7:26 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Priit Laes
2015-12-08 12:14   ` Bastien Nocera
2015-12-08 15:18   ` Rob Herring
2015-12-08 12:14 ` [PATCH 0/2] input: Driver for Goodix GT801 2+1 touchscreen Bastien Nocera
     [not found] <201512071608.oGt2n0Wn%fengguang.wu@intel.com>
2015-12-07  8:34 ` [PATCH 2/2] input: gt801_2plus1 - Add initial support for Goodix GT801 2+1 Julia Lawall
2015-12-07  9:10   ` Priit Laes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).