All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Add support for Nsiway NS2009 touchscreen controller
@ 2017-03-15 15:51 ` Icenowy Zheng
  0 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Maxime Ripard
  Cc: devicetree, Icenowy Zheng, linux-kernel, linux-arm-kernel, linux-input

The production batch of Lichee Pi Zero board have a Nsiway NS2009 touchscreen
controller on board, which is used for connecting resistive touch panels on
40-pin LCD connector.

This patchset adds support for it.

Patch 1 adds vendor prefix for Nsiway, and patch 2 adds device tree binding
for NS2009.

Patch 3 is the real driver of NS2009, which currently supports only polling
(as the IRQ pin is not connected on Lichee Pi Zero).

Patch 4 adds NS2009 node to Lichee Pi Zero device tree.

Icenowy Zheng (4):
  dt-bindings: add vendor prefix for Shenzhen Nsiway Techonology Co.,
    Ltd.
  dt-bindings: add binding for Nsiway NS2009 touchscreen controller
  Input: add driver for Nsiway NS2009 resistive touchscreen controller
  ARM: sun8i: v3s: add ns2009 node for Lichee Pi Zero board

 .../bindings/input/touchscreen/ns2009.txt          |  23 +++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 MAINTAINERS                                        |   6 +
 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts      |   9 +
 drivers/input/touchscreen/Kconfig                  |  13 ++
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/ns2009.c                 | 212 +++++++++++++++++++++
 7 files changed, 265 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ns2009.txt
 create mode 100644 drivers/input/touchscreen/ns2009.c

-- 
2.12.0

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

* [PATCH 0/4] Add support for Nsiway NS2009 touchscreen controller
@ 2017-03-15 15:51 ` Icenowy Zheng
  0 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

The production batch of Lichee Pi Zero board have a Nsiway NS2009 touchscreen
controller on board, which is used for connecting resistive touch panels on
40-pin LCD connector.

This patchset adds support for it.

Patch 1 adds vendor prefix for Nsiway, and patch 2 adds device tree binding
for NS2009.

Patch 3 is the real driver of NS2009, which currently supports only polling
(as the IRQ pin is not connected on Lichee Pi Zero).

Patch 4 adds NS2009 node to Lichee Pi Zero device tree.

Icenowy Zheng (4):
  dt-bindings: add vendor prefix for Shenzhen Nsiway Techonology Co.,
    Ltd.
  dt-bindings: add binding for Nsiway NS2009 touchscreen controller
  Input: add driver for Nsiway NS2009 resistive touchscreen controller
  ARM: sun8i: v3s: add ns2009 node for Lichee Pi Zero board

 .../bindings/input/touchscreen/ns2009.txt          |  23 +++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 MAINTAINERS                                        |   6 +
 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts      |   9 +
 drivers/input/touchscreen/Kconfig                  |  13 ++
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/ns2009.c                 | 212 +++++++++++++++++++++
 7 files changed, 265 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ns2009.txt
 create mode 100644 drivers/input/touchscreen/ns2009.c

-- 
2.12.0

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

* [PATCH 1/4] dt-bindings: add vendor prefix for Shenzhen Nsiway Techonology Co., Ltd.
  2017-03-15 15:51 ` Icenowy Zheng
@ 2017-03-15 15:51   ` Icenowy Zheng
  -1 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Maxime Ripard
  Cc: devicetree, Icenowy Zheng, linux-kernel, linux-arm-kernel, linux-input

Shenzhen Nsiway Technology Co., Ltd. manufactures various analog ICs,
including pulse amplifiers, power management ICs and resistive
touchscreen controllers.

http://www.nsiway.com.cn

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 28c868638c6c..55ecac6737c3 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -215,6 +215,7 @@ newhaven	Newhaven Display International
 ni	National Instruments
 nintendo	Nintendo
 nokia	Nokia
+nsiway	Shenzhen Nsiway Technology Co., Ltd.
 nuvoton	Nuvoton Technology Corporation
 nvd	New Vision Display
 nvidia	NVIDIA
-- 
2.12.0

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

* [PATCH 1/4] dt-bindings: add vendor prefix for Shenzhen Nsiway Techonology Co., Ltd.
@ 2017-03-15 15:51   ` Icenowy Zheng
  0 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

Shenzhen Nsiway Technology Co., Ltd. manufactures various analog ICs,
including pulse amplifiers, power management ICs and resistive
touchscreen controllers.

http://www.nsiway.com.cn

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 28c868638c6c..55ecac6737c3 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -215,6 +215,7 @@ newhaven	Newhaven Display International
 ni	National Instruments
 nintendo	Nintendo
 nokia	Nokia
+nsiway	Shenzhen Nsiway Technology Co., Ltd.
 nuvoton	Nuvoton Technology Corporation
 nvd	New Vision Display
 nvidia	NVIDIA
-- 
2.12.0

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

* [PATCH 2/4] dt-bindings: add binding for Nsiway NS2009 touchscreen controller
  2017-03-15 15:51 ` Icenowy Zheng
@ 2017-03-15 15:51   ` Icenowy Zheng
  -1 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Maxime Ripard
  Cc: devicetree, Icenowy Zheng, linux-kernel, linux-arm-kernel, linux-input

Nsiway NS2009 is a resistive touchscreen controller, with I2C interface
and optional interrupt pin.

Add binding document for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 .../bindings/input/touchscreen/ns2009.txt          | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ns2009.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/ns2009.txt b/Documentation/devicetree/bindings/input/touchscreen/ns2009.txt
new file mode 100644
index 000000000000..0e9090ba978c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ns2009.txt
@@ -0,0 +1,23 @@
+* Nsiway NS2009 Resistive Touchscreen Controller
+
+Required properties:
+- compatible		  : "nsiway,ns2009"
+- reg			  : I2C slave address of the chip (0x48 or 0x49, depends on
+			    the hardware)
+
+Optional properties:
+- interrupt-parent	  : a phandle pointing to the interrupt controller
+			    serving the interrupt for this chip
+- interrupts		  : interrupt specification for the ns2009 pen interrupt
+- properties defined in touchscreen.txt
+
+Example:
+
+i2c@00000000 {
+	ns2009: touchscreen@48 {
+		compatible = "nsiway,ns2009";
+		reg = <0x48>;
+		touchscreen-fuzz-x = <8>;
+		touchscreen-fuzz-y = <8>;
+	};
+};
-- 
2.12.0

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

* [PATCH 2/4] dt-bindings: add binding for Nsiway NS2009 touchscreen controller
@ 2017-03-15 15:51   ` Icenowy Zheng
  0 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

Nsiway NS2009 is a resistive touchscreen controller, with I2C interface
and optional interrupt pin.

Add binding document for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 .../bindings/input/touchscreen/ns2009.txt          | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ns2009.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/ns2009.txt b/Documentation/devicetree/bindings/input/touchscreen/ns2009.txt
new file mode 100644
index 000000000000..0e9090ba978c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ns2009.txt
@@ -0,0 +1,23 @@
+* Nsiway NS2009 Resistive Touchscreen Controller
+
+Required properties:
+- compatible		  : "nsiway,ns2009"
+- reg			  : I2C slave address of the chip (0x48 or 0x49, depends on
+			    the hardware)
+
+Optional properties:
+- interrupt-parent	  : a phandle pointing to the interrupt controller
+			    serving the interrupt for this chip
+- interrupts		  : interrupt specification for the ns2009 pen interrupt
+- properties defined in touchscreen.txt
+
+Example:
+
+i2c at 00000000 {
+	ns2009: touchscreen at 48 {
+		compatible = "nsiway,ns2009";
+		reg = <0x48>;
+		touchscreen-fuzz-x = <8>;
+		touchscreen-fuzz-y = <8>;
+	};
+};
-- 
2.12.0

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

* [PATCH 3/4] Input: add driver for Nsiway NS2009 resistive touchscreen controller
  2017-03-15 15:51 ` Icenowy Zheng
@ 2017-03-15 15:51   ` Icenowy Zheng
  -1 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Maxime Ripard
  Cc: devicetree, Icenowy Zheng, linux-kernel, linux-arm-kernel, linux-input

Add a driver for the NS2009 resistive touchscreen controller chip by
Nsiway, which is connected via I2C.

Only polling is support now, as the hardware available now didn't use
the IRQ pin.

Pressure measurement is also not supported, as it will need more
investigation to convert raw readout to real value. Currently the
pressure readout is only used to detect pen up/down status.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 MAINTAINERS                        |   6 ++
 drivers/input/touchscreen/Kconfig  |  13 +++
 drivers/input/touchscreen/Makefile |   1 +
 drivers/input/touchscreen/ns2009.c | 212 +++++++++++++++++++++++++++++++++++++
 4 files changed, 232 insertions(+)
 create mode 100644 drivers/input/touchscreen/ns2009.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e922e0b9f0d5..655e65628d2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9008,6 +9008,12 @@ F:	drivers/power/supply/bq27xxx_battery_i2c.c
 F:	drivers/power/supply/isp1704_charger.c
 F:	drivers/power/supply/rx51_battery.c
 
+NSIWAY NS2009 TOUCHSCREEN CONTROLLER
+M:	Icenowy Zheng <icenowy@aosc.xyz>
+L:	linux-input@vger.kernel.org
+S:	Maintained
+F:	drivers/input/touchscreen/ns2009.c
+
 NTB DRIVER CORE
 M:	Jon Mason <jdmason@kudzu.us>
 M:	Dave Jiang <dave.jiang@intel.com>
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6515e649e204..eb22de1cb0fb 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -639,6 +639,19 @@ config TOUCHSCREEN_MIGOR
 	  To compile this driver as a module, choose M here: the
 	  module will be called migor_ts.
 
+config TOUCHSCREEN_NS2009
+	tristate "Nsiway NS2009 touchscreen"
+	depends on I2C
+	select INPUT_POLLDEV
+	help
+	  Say Y here to enable Nsiway NS2009 resistive touchscreen
+	  controller support.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ns2009.
+
 config TOUCHSCREEN_TOUCHRIGHT
 	tristate "Touchright serial touchscreen"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index ad5c896222bc..8bf172e73415 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_TOUCHSCREEN_HP600)		+= hp680_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
 obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO)	+= ipaq-micro-ts.o
 obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
+obj-$(CONFIG_TOUCHSCREEN_NS2009)	+= ns2009.o
 obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE)	+= usbtouchscreen.o
 obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
 obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= penmount.o
diff --git a/drivers/input/touchscreen/ns2009.c b/drivers/input/touchscreen/ns2009.c
new file mode 100644
index 000000000000..f52721276c96
--- /dev/null
+++ b/drivers/input/touchscreen/ns2009.c
@@ -0,0 +1,212 @@
+/*
+ * Nsiway NS2009 touchscreen controller driver
+ *
+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+ *
+ * Some codes are from silead.c, which is
+ *   Copyright (C) 2014-2015 Intel Corporation
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/input-polldev.h>
+#include <linux/input/touchscreen.h>
+#include <linux/i2c.h>
+
+/* polling interval in ms */
+#define POLL_INTERVAL	30
+
+/* this driver uses 12-bit readout */
+#define MAX_12BIT	0xfff
+
+#define NS2009_TS_NAME	"ns2009_ts"
+
+#define NS2009_READ_X_LOW_POWER_12BIT	0xc0
+#define NS2009_READ_Y_LOW_POWER_12BIT	0xd0
+#define NS2009_READ_Z1_LOW_POWER_12BIT	0xe0
+#define NS2009_READ_Z2_LOW_POWER_12BIT	0xf0
+
+#define NS2009_DEF_X_FUZZ	32
+#define NS2009_DEF_Y_FUZZ	16
+
+/*
+ * The chip have some error in z1 value when pen is up, so the data read out
+ * is sometimes not accurately 0.
+ * This value is based on experiements.
+ */
+#define NS2009_PEN_UP_Z1_ERR	80
+
+struct ns2009_data {
+	struct i2c_client		*client;
+	struct input_dev		*input;
+
+	struct touchscreen_properties	prop;
+
+	bool				pen_down;
+};
+
+static int ns2009_ts_read_data(struct ns2009_data *data, u8 cmd, u16 *val)
+{
+	u8 raw_data[2];
+	int error;
+
+	error = i2c_smbus_read_i2c_block_data(data->client, cmd, 2, raw_data);
+	if (error < 0)
+		return error;
+
+	if (unlikely(raw_data[1] & 0xf))
+		return -EINVAL;
+
+	*val = (raw_data[0] << 4) | (raw_data[1] >> 4);
+
+	return 0;
+}
+
+static int ns2009_ts_report(struct ns2009_data *data)
+{
+	u16 x, y, z1;
+	int ret;
+
+	/*
+	 * NS2009 chip supports pressure measurement, but currently it needs
+	 * more investigation, so we only use z1 axis to detect pen down
+	 * here.
+	 */
+	ret = ns2009_ts_read_data(data, NS2009_READ_Z1_LOW_POWER_12BIT, &z1);
+	if (ret)
+		return ret;
+
+	if (z1 >= NS2009_PEN_UP_Z1_ERR) {
+		ret = ns2009_ts_read_data(data, NS2009_READ_X_LOW_POWER_12BIT,
+					  &x);
+		if (ret)
+			return ret;
+
+		ret = ns2009_ts_read_data(data, NS2009_READ_Y_LOW_POWER_12BIT,
+					  &y);
+		if (ret)
+			return ret;
+
+		if (!data->pen_down) {
+			input_report_key(data->input, BTN_TOUCH, 1);
+			data->pen_down = true;
+		}
+
+		input_report_abs(data->input, ABS_X, x);
+		input_report_abs(data->input, ABS_Y, y);
+		input_sync(data->input);
+	} else if (data->pen_down) {
+		input_report_key(data->input, BTN_TOUCH, 0);
+		input_sync(data->input);
+		data->pen_down = false;
+	}
+	return 0;
+}
+
+static void ns2009_ts_poll(struct input_polled_dev *dev)
+{
+	struct ns2009_data *data = dev->private;
+	int ret;
+
+	ret = ns2009_ts_report(data);
+	if (ret)
+		dev_err(&dev->input->dev, "Poll touch data failed: %d\n", ret);
+}
+
+static void ns2009_ts_config_input_dev(struct ns2009_data *data)
+{
+	struct input_dev *input = data->input;
+
+	input_set_abs_params(input, ABS_X, 0, MAX_12BIT, NS2009_DEF_X_FUZZ, 0);
+	input_set_abs_params(input, ABS_Y, 0, MAX_12BIT, NS2009_DEF_Y_FUZZ, 0);
+	touchscreen_parse_properties(input, false, &data->prop);
+
+	input->name = NS2009_TS_NAME;
+	input->phys = "input/ts";
+	input->id.bustype = BUS_I2C;
+	input_set_capability(input, EV_KEY, BTN_TOUCH);
+}
+
+static int ns2009_ts_request_polled_input_dev(struct ns2009_data *data)
+{
+	struct device *dev = &data->client->dev;
+	struct input_polled_dev *polled_dev;
+	int error;
+
+	polled_dev = devm_input_allocate_polled_device(dev);
+	if (!polled_dev) {
+		dev_err(dev,
+			"Failed to allocate polled input device\n");
+		return -ENOMEM;
+	}
+	data->input = polled_dev->input;
+
+	ns2009_ts_config_input_dev(data);
+	polled_dev->private = data;
+	polled_dev->poll = ns2009_ts_poll;
+	polled_dev->poll_interval = POLL_INTERVAL;
+
+	error = input_register_polled_device(polled_dev);
+	if (error) {
+		dev_err(dev, "Failed to register polled input device: %d\n",
+			error);
+		return error;
+	}
+
+	return 0;
+}
+
+static int ns2009_ts_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
+{
+	struct ns2009_data *data;
+	struct device *dev = &client->dev;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_I2C |
+				     I2C_FUNC_SMBUS_READ_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
+		dev_err(dev, "I2C functionality check failed\n");
+		return -ENXIO;
+	}
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	data->client = client;
+
+	error = ns2009_ts_request_polled_input_dev(data);
+	if (error)
+		return error;
+
+	return 0;
+};
+
+static const struct i2c_device_id ns2009_ts_id[] = {
+	{ "ns2009", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ns2009_ts_id);
+
+static struct i2c_driver ns2009_ts_driver = {
+	.probe = ns2009_ts_probe,
+	.id_table = ns2009_ts_id,
+	.driver = {
+		.name = NS2009_TS_NAME,
+	},
+};
+module_i2c_driver(ns2009_ts_driver);
-- 
2.12.0

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

* [PATCH 3/4] Input: add driver for Nsiway NS2009 resistive touchscreen controller
@ 2017-03-15 15:51   ` Icenowy Zheng
  0 siblings, 0 replies; 8+ messages in thread
From: Icenowy Zheng @ 2017-03-15 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

Add a driver for the NS2009 resistive touchscreen controller chip by
Nsiway, which is connected via I2C.

Only polling is support now, as the hardware available now didn't use
the IRQ pin.

Pressure measurement is also not supported, as it will need more
investigation to convert raw readout to real value. Currently the
pressure readout is only used to detect pen up/down status.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 MAINTAINERS                        |   6 ++
 drivers/input/touchscreen/Kconfig  |  13 +++
 drivers/input/touchscreen/Makefile |   1 +
 drivers/input/touchscreen/ns2009.c | 212 +++++++++++++++++++++++++++++++++++++
 4 files changed, 232 insertions(+)
 create mode 100644 drivers/input/touchscreen/ns2009.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e922e0b9f0d5..655e65628d2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9008,6 +9008,12 @@ F:	drivers/power/supply/bq27xxx_battery_i2c.c
 F:	drivers/power/supply/isp1704_charger.c
 F:	drivers/power/supply/rx51_battery.c
 
+NSIWAY NS2009 TOUCHSCREEN CONTROLLER
+M:	Icenowy Zheng <icenowy@aosc.xyz>
+L:	linux-input at vger.kernel.org
+S:	Maintained
+F:	drivers/input/touchscreen/ns2009.c
+
 NTB DRIVER CORE
 M:	Jon Mason <jdmason@kudzu.us>
 M:	Dave Jiang <dave.jiang@intel.com>
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6515e649e204..eb22de1cb0fb 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -639,6 +639,19 @@ config TOUCHSCREEN_MIGOR
 	  To compile this driver as a module, choose M here: the
 	  module will be called migor_ts.
 
+config TOUCHSCREEN_NS2009
+	tristate "Nsiway NS2009 touchscreen"
+	depends on I2C
+	select INPUT_POLLDEV
+	help
+	  Say Y here to enable Nsiway NS2009 resistive touchscreen
+	  controller support.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ns2009.
+
 config TOUCHSCREEN_TOUCHRIGHT
 	tristate "Touchright serial touchscreen"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index ad5c896222bc..8bf172e73415 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_TOUCHSCREEN_HP600)		+= hp680_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
 obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO)	+= ipaq-micro-ts.o
 obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
+obj-$(CONFIG_TOUCHSCREEN_NS2009)	+= ns2009.o
 obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE)	+= usbtouchscreen.o
 obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
 obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= penmount.o
diff --git a/drivers/input/touchscreen/ns2009.c b/drivers/input/touchscreen/ns2009.c
new file mode 100644
index 000000000000..f52721276c96
--- /dev/null
+++ b/drivers/input/touchscreen/ns2009.c
@@ -0,0 +1,212 @@
+/*
+ * Nsiway NS2009 touchscreen controller driver
+ *
+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+ *
+ * Some codes are from silead.c, which is
+ *   Copyright (C) 2014-2015 Intel Corporation
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/input-polldev.h>
+#include <linux/input/touchscreen.h>
+#include <linux/i2c.h>
+
+/* polling interval in ms */
+#define POLL_INTERVAL	30
+
+/* this driver uses 12-bit readout */
+#define MAX_12BIT	0xfff
+
+#define NS2009_TS_NAME	"ns2009_ts"
+
+#define NS2009_READ_X_LOW_POWER_12BIT	0xc0
+#define NS2009_READ_Y_LOW_POWER_12BIT	0xd0
+#define NS2009_READ_Z1_LOW_POWER_12BIT	0xe0
+#define NS2009_READ_Z2_LOW_POWER_12BIT	0xf0
+
+#define NS2009_DEF_X_FUZZ	32
+#define NS2009_DEF_Y_FUZZ	16
+
+/*
+ * The chip have some error in z1 value when pen is up, so the data read out
+ * is sometimes not accurately 0.
+ * This value is based on experiements.
+ */
+#define NS2009_PEN_UP_Z1_ERR	80
+
+struct ns2009_data {
+	struct i2c_client		*client;
+	struct input_dev		*input;
+
+	struct touchscreen_properties	prop;
+
+	bool				pen_down;
+};
+
+static int ns2009_ts_read_data(struct ns2009_data *data, u8 cmd, u16 *val)
+{
+	u8 raw_data[2];
+	int error;
+
+	error = i2c_smbus_read_i2c_block_data(data->client, cmd, 2, raw_data);
+	if (error < 0)
+		return error;
+
+	if (unlikely(raw_data[1] & 0xf))
+		return -EINVAL;
+
+	*val = (raw_data[0] << 4) | (raw_data[1] >> 4);
+
+	return 0;
+}
+
+static int ns2009_ts_report(struct ns2009_data *data)
+{
+	u16 x, y, z1;
+	int ret;
+
+	/*
+	 * NS2009 chip supports pressure measurement, but currently it needs
+	 * more investigation, so we only use z1 axis to detect pen down
+	 * here.
+	 */
+	ret = ns2009_ts_read_data(data, NS2009_READ_Z1_LOW_POWER_12BIT, &z1);
+	if (ret)
+		return ret;
+
+	if (z1 >= NS2009_PEN_UP_Z1_ERR) {
+		ret = ns2009_ts_read_data(data, NS2009_READ_X_LOW_POWER_12BIT,
+					  &x);
+		if (ret)
+			return ret;
+
+		ret = ns2009_ts_read_data(data, NS2009_READ_Y_LOW_POWER_12BIT,
+					  &y);
+		if (ret)
+			return ret;
+
+		if (!data->pen_down) {
+			input_report_key(data->input, BTN_TOUCH, 1);
+			data->pen_down = true;
+		}
+
+		input_report_abs(data->input, ABS_X, x);
+		input_report_abs(data->input, ABS_Y, y);
+		input_sync(data->input);
+	} else if (data->pen_down) {
+		input_report_key(data->input, BTN_TOUCH, 0);
+		input_sync(data->input);
+		data->pen_down = false;
+	}
+	return 0;
+}
+
+static void ns2009_ts_poll(struct input_polled_dev *dev)
+{
+	struct ns2009_data *data = dev->private;
+	int ret;
+
+	ret = ns2009_ts_report(data);
+	if (ret)
+		dev_err(&dev->input->dev, "Poll touch data failed: %d\n", ret);
+}
+
+static void ns2009_ts_config_input_dev(struct ns2009_data *data)
+{
+	struct input_dev *input = data->input;
+
+	input_set_abs_params(input, ABS_X, 0, MAX_12BIT, NS2009_DEF_X_FUZZ, 0);
+	input_set_abs_params(input, ABS_Y, 0, MAX_12BIT, NS2009_DEF_Y_FUZZ, 0);
+	touchscreen_parse_properties(input, false, &data->prop);
+
+	input->name = NS2009_TS_NAME;
+	input->phys = "input/ts";
+	input->id.bustype = BUS_I2C;
+	input_set_capability(input, EV_KEY, BTN_TOUCH);
+}
+
+static int ns2009_ts_request_polled_input_dev(struct ns2009_data *data)
+{
+	struct device *dev = &data->client->dev;
+	struct input_polled_dev *polled_dev;
+	int error;
+
+	polled_dev = devm_input_allocate_polled_device(dev);
+	if (!polled_dev) {
+		dev_err(dev,
+			"Failed to allocate polled input device\n");
+		return -ENOMEM;
+	}
+	data->input = polled_dev->input;
+
+	ns2009_ts_config_input_dev(data);
+	polled_dev->private = data;
+	polled_dev->poll = ns2009_ts_poll;
+	polled_dev->poll_interval = POLL_INTERVAL;
+
+	error = input_register_polled_device(polled_dev);
+	if (error) {
+		dev_err(dev, "Failed to register polled input device: %d\n",
+			error);
+		return error;
+	}
+
+	return 0;
+}
+
+static int ns2009_ts_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
+{
+	struct ns2009_data *data;
+	struct device *dev = &client->dev;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_I2C |
+				     I2C_FUNC_SMBUS_READ_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
+		dev_err(dev, "I2C functionality check failed\n");
+		return -ENXIO;
+	}
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	data->client = client;
+
+	error = ns2009_ts_request_polled_input_dev(data);
+	if (error)
+		return error;
+
+	return 0;
+};
+
+static const struct i2c_device_id ns2009_ts_id[] = {
+	{ "ns2009", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ns2009_ts_id);
+
+static struct i2c_driver ns2009_ts_driver = {
+	.probe = ns2009_ts_probe,
+	.id_table = ns2009_ts_id,
+	.driver = {
+		.name = NS2009_TS_NAME,
+	},
+};
+module_i2c_driver(ns2009_ts_driver);
-- 
2.12.0

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

end of thread, other threads:[~2017-03-15 15:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-15 15:51 [PATCH 0/4] Add support for Nsiway NS2009 touchscreen controller Icenowy Zheng
2017-03-15 15:51 ` Icenowy Zheng
2017-03-15 15:51 ` [PATCH 1/4] dt-bindings: add vendor prefix for Shenzhen Nsiway Techonology Co., Ltd Icenowy Zheng
2017-03-15 15:51   ` Icenowy Zheng
2017-03-15 15:51 ` [PATCH 2/4] dt-bindings: add binding for Nsiway NS2009 touchscreen controller Icenowy Zheng
2017-03-15 15:51   ` Icenowy Zheng
2017-03-15 15:51 ` [PATCH 3/4] Input: add driver for Nsiway NS2009 resistive " Icenowy Zheng
2017-03-15 15:51   ` Icenowy Zheng

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.