All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH resend 0/5] input: resend of 5 touchscreen patches
@ 2016-09-11 18:44 ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring
  Cc: linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree

Hi Dmitry,

Thank you for merging the 2 silead touchscreen firmware loading patches
into your for-linus branch.

Here is a resend of 5 patches intended for next, which do not seem to
be getting anywhere hence the resend. Esp. patches 4 and 5, which
already have Robh's ack for the dt bits seem ready for merging to me.

Rob, patches 1, 2 have a dt-bindings component, you had some questions
about the dt bits in patch 1, which I've answered here:

http://www.spinics.net/lists/arm-kernel/msg521450.html

Regards,

Hans

p.s.

Thank you both for all the great work you're doing on the kernel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH resend 0/5] input: resend of 5 touchscreen patches
@ 2016-09-11 18:44 ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dmitry,

Thank you for merging the 2 silead touchscreen firmware loading patches
into your for-linus branch.

Here is a resend of 5 patches intended for next, which do not seem to
be getting anywhere hence the resend. Esp. patches 4 and 5, which
already have Robh's ack for the dt bits seem ready for merging to me.

Rob, patches 1, 2 have a dt-bindings component, you had some questions
about the dt bits in patch 1, which I've answered here:

http://www.spinics.net/lists/arm-kernel/msg521450.html

Regards,

Hans

p.s.

Thank you both for all the great work you're doing on the kernel.

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

* [PATCH resend 1/5] input: touchscreen: Add generic touchscreen softbutton handling code
  2016-09-11 18:44 ` Hans de Goede
@ 2016-09-11 18:44     ` Hans de Goede
  -1 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring
  Cc: linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	Hans de Goede

Some touchscreens extend over the display they cover and have a number
of capacative softbuttons outside of the display the cover.

With some hardware these softbuttons simply report touches with
coordinates outside of the normal coordinate space for touches on the
display.

This commit adds a devicetree binding for describing such buttons in
devicetree and a bunch of helper functions to easily add support for
these to existing touchscreen drivers.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 .../bindings/input/touchscreen/softbuttons.txt     |  58 +++++++++
 drivers/input/touchscreen/Makefile                 |   2 +-
 drivers/input/touchscreen/softbuttons.c            | 145 +++++++++++++++++++++
 include/linux/input/touchscreen.h                  |   9 ++
 4 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
 create mode 100644 drivers/input/touchscreen/softbuttons.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
new file mode 100644
index 0000000..3eb6f4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
@@ -0,0 +1,58 @@
+General Touchscreen Softbutton Properties:
+
+Some touchscreens extend over the display they cover and have a number
+of capacative softbuttons outside of the display the cover.
+
+Some of these softbuttons simply report touches with coordinates outside of
+the normal coordinate space for touches on the display. This binding is for
+describing such buttons in devicetree.
+
+Each softkey is represented as a sub-node of the touchscreen node.
+
+Required subnode-properties:
+ - label			: Descriptive name of the key.
+ - linux,code			: Keycode to emit.
+ - softbutton-min-x		: X start of the area the softbutton area covers
+ - softbutton-max-x		: X end of the area the softbutton area covers
+ - softbutton-min-y		: Y start of the area the softbutton area covers
+ - softbutton-max-y		: Y end of the area the softbutton area covers
+
+Example:
+
+#include <dt-bindings/input/input.h>
+
+&i2c2 {
+	ft5406ee8: touchscreen@38 {
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+		touchscreen-size-x = <1024>;
+		touchscreen-size-y = <768>;
+
+		button@0 {
+			label = "Esc";
+			linux,code = <KEY_ESC>;
+			softbutton-min-x = <1084>;
+			softbutton-max-x = <1098>;
+			softbutton-min-y = <0>;
+			softbutton-max-y = <49>;
+		};
+
+		button@1 {
+			label = "Home";
+			linux,code = <KEY_HOMEPAGE>;
+			softbutton-min-x = <1084>;
+			softbutton-max-x = <1098>;
+			softbutton-min-y = <50>;
+			softbutton-max-y = <99>;
+		};
+
+		button@2 {
+			label = "Menu";
+			linux,code = <KEY_MENU>;
+			softbutton-min-x = <1084>;
+			softbutton-max-x = <1098>;
+			softbutton-min-y = <100>;
+			softbutton-max-y = <149>;
+		};
+	};
+};
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 57a1c09..33b2eb8 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,7 +6,7 @@
 
 wm97xx-ts-y := wm97xx-core.o
 
-obj-$(CONFIG_TOUCHSCREEN_PROPERTIES)	+= of_touchscreen.o
+obj-$(CONFIG_TOUCHSCREEN_PROPERTIES)	+= of_touchscreen.o softbuttons.o
 obj-$(CONFIG_TOUCHSCREEN_88PM860X)	+= 88pm860x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_AD7877)	+= ad7877.o
 obj-$(CONFIG_TOUCHSCREEN_AD7879)	+= ad7879.o
diff --git a/drivers/input/touchscreen/softbuttons.c b/drivers/input/touchscreen/softbuttons.c
new file mode 100644
index 0000000..47aea18
--- /dev/null
+++ b/drivers/input/touchscreen/softbuttons.c
@@ -0,0 +1,145 @@
+/*
+ * touchscreen softbutton helper functions
+ *
+ * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@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.
+ */
+
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/of.h>
+
+struct touchscreen_softbutton {
+	u32 min_x;
+	u32 max_x;
+	u32 min_y;
+	u32 max_y;
+	u32 keycode;
+};
+
+struct touchscreen_softbutton_info {
+	struct input_dev *input;
+	struct touchscreen_softbutton *buttons;
+	int button_count;
+};
+
+/**
+ * devm_touchscreen_alloc_softbuttons - allocate softbuttons
+ * @input: touchscreen input device for which softbuttons should be allocated
+ *
+ * This function parses touschcreen softbutton DT properties for touchscreens
+ * and allocates and fill a touchscreen_softbutton_info struct if any
+ * softbuttons are found.
+ *
+ * Returns prepared struct touchscreen_softbutton_info on success,
+ * %NULL if no softbuttons were found (this is not an error) or a ERR_PTR
+ * in case of an error.
+ *
+ * Note as this is a devm function the returned pointer does not need to
+ * be freed.
+ */
+struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
+					struct input_dev *input)
+{
+	struct device *dev = input->dev.parent;
+	struct device_node *np, *pp;
+	struct touchscreen_softbutton_info *info;
+	int i, err, button_count;
+
+	np = dev->of_node;
+	if (!np)
+		return NULL;
+
+	button_count = of_get_child_count(np);
+	if (button_count == 0)
+		return NULL;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return ERR_PTR(-ENOMEM);
+
+	info->input = input;
+	info->button_count = button_count;
+	info->buttons = devm_kzalloc(dev, button_count * sizeof(*info->buttons),
+				     GFP_KERNEL);
+	if (!info->buttons)
+		return ERR_PTR(-ENOMEM);
+
+	for (pp = of_get_next_child(np, NULL), i = 0;
+	     pp != NULL;
+	     pp = of_get_next_child(np, pp), i++) {
+		struct touchscreen_softbutton *btn = &info->buttons[i];
+
+		err = of_property_read_u32(pp, "linux,code", &btn->keycode);
+		if (err) {
+			dev_err(dev, "%s: Inval linux,code prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-min-x", &btn->min_x);
+		if (err) {
+			dev_err(dev, "%s: Inval min-x prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-max-x", &btn->max_x);
+		if (err) {
+			dev_err(dev, "%s: Inval max-x prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-min-y", &btn->min_y);
+		if (err) {
+			dev_err(dev, "%s: Inval min-y prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-max-y", &btn->max_y);
+		if (err) {
+			dev_err(dev, "%s: Inval max-y prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	__set_bit(EV_KEY, input->evbit);
+	for (i = 0; i < info->button_count; i++)
+		__set_bit(info->buttons[i].keycode, input->keybit);
+
+	return info;
+}
+
+/**
+ * touchscreen_handle_softbuttons - check for softbutton press
+ * @info: softbutton info retured by devm_touchscreen_alloc_softbuttons.
+ *
+ * This function checks if the passed in coordinates match any softbutton,
+ * and when they do reports a key press / release for the softbutton.
+ *
+ * Returns true if the coordinates match a softbutton and a key press / release
+ * was reported, false otherwise.
+ */
+bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
+				    unsigned int x, unsigned int y, bool down)
+{
+	int i;
+
+	if (info == NULL)
+		return false;
+
+	for (i = 0; i < info->button_count; i++) {
+		if (x >= info->buttons[i].min_x &&
+		    x <= info->buttons[i].max_x &&
+		    y >= info->buttons[i].min_y &&
+		    y <= info->buttons[i].max_y) {
+			input_report_key(info->input,
+					 info->buttons[i].keycode, down);
+			return true;
+		}
+	}
+
+	return false;
+}
diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h
index 09d22cc..0b9d4ee 100644
--- a/include/linux/input/touchscreen.h
+++ b/include/linux/input/touchscreen.h
@@ -9,8 +9,11 @@
 #ifndef _TOUCHSCREEN_H
 #define _TOUCHSCREEN_H
 
+#include <linux/types.h>
+
 struct input_dev;
 struct input_mt_pos;
+struct touchscreen_softbutton_info;
 
 struct touchscreen_properties {
 	unsigned int max_x;
@@ -32,4 +35,10 @@ void touchscreen_report_pos(struct input_dev *input,
 			    unsigned int x, unsigned int y,
 			    bool multitouch);
 
+struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
+					struct input_dev *input);
+
+bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
+				    unsigned int x, unsigned int y, bool down);
+
 #endif
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH resend 1/5] input: touchscreen: Add generic touchscreen softbutton handling code
@ 2016-09-11 18:44     ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

Some touchscreens extend over the display they cover and have a number
of capacative softbuttons outside of the display the cover.

With some hardware these softbuttons simply report touches with
coordinates outside of the normal coordinate space for touches on the
display.

This commit adds a devicetree binding for describing such buttons in
devicetree and a bunch of helper functions to easily add support for
these to existing touchscreen drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../bindings/input/touchscreen/softbuttons.txt     |  58 +++++++++
 drivers/input/touchscreen/Makefile                 |   2 +-
 drivers/input/touchscreen/softbuttons.c            | 145 +++++++++++++++++++++
 include/linux/input/touchscreen.h                  |   9 ++
 4 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
 create mode 100644 drivers/input/touchscreen/softbuttons.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
new file mode 100644
index 0000000..3eb6f4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
@@ -0,0 +1,58 @@
+General Touchscreen Softbutton Properties:
+
+Some touchscreens extend over the display they cover and have a number
+of capacative softbuttons outside of the display the cover.
+
+Some of these softbuttons simply report touches with coordinates outside of
+the normal coordinate space for touches on the display. This binding is for
+describing such buttons in devicetree.
+
+Each softkey is represented as a sub-node of the touchscreen node.
+
+Required subnode-properties:
+ - label			: Descriptive name of the key.
+ - linux,code			: Keycode to emit.
+ - softbutton-min-x		: X start of the area the softbutton area covers
+ - softbutton-max-x		: X end of the area the softbutton area covers
+ - softbutton-min-y		: Y start of the area the softbutton area covers
+ - softbutton-max-y		: Y end of the area the softbutton area covers
+
+Example:
+
+#include <dt-bindings/input/input.h>
+
+&i2c2 {
+	ft5406ee8: touchscreen at 38 {
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+		touchscreen-size-x = <1024>;
+		touchscreen-size-y = <768>;
+
+		button at 0 {
+			label = "Esc";
+			linux,code = <KEY_ESC>;
+			softbutton-min-x = <1084>;
+			softbutton-max-x = <1098>;
+			softbutton-min-y = <0>;
+			softbutton-max-y = <49>;
+		};
+
+		button at 1 {
+			label = "Home";
+			linux,code = <KEY_HOMEPAGE>;
+			softbutton-min-x = <1084>;
+			softbutton-max-x = <1098>;
+			softbutton-min-y = <50>;
+			softbutton-max-y = <99>;
+		};
+
+		button at 2 {
+			label = "Menu";
+			linux,code = <KEY_MENU>;
+			softbutton-min-x = <1084>;
+			softbutton-max-x = <1098>;
+			softbutton-min-y = <100>;
+			softbutton-max-y = <149>;
+		};
+	};
+};
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 57a1c09..33b2eb8 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,7 +6,7 @@
 
 wm97xx-ts-y := wm97xx-core.o
 
-obj-$(CONFIG_TOUCHSCREEN_PROPERTIES)	+= of_touchscreen.o
+obj-$(CONFIG_TOUCHSCREEN_PROPERTIES)	+= of_touchscreen.o softbuttons.o
 obj-$(CONFIG_TOUCHSCREEN_88PM860X)	+= 88pm860x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_AD7877)	+= ad7877.o
 obj-$(CONFIG_TOUCHSCREEN_AD7879)	+= ad7879.o
diff --git a/drivers/input/touchscreen/softbuttons.c b/drivers/input/touchscreen/softbuttons.c
new file mode 100644
index 0000000..47aea18
--- /dev/null
+++ b/drivers/input/touchscreen/softbuttons.c
@@ -0,0 +1,145 @@
+/*
+ * touchscreen softbutton helper functions
+ *
+ * Copyright (c) 2016 Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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.
+ */
+
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/of.h>
+
+struct touchscreen_softbutton {
+	u32 min_x;
+	u32 max_x;
+	u32 min_y;
+	u32 max_y;
+	u32 keycode;
+};
+
+struct touchscreen_softbutton_info {
+	struct input_dev *input;
+	struct touchscreen_softbutton *buttons;
+	int button_count;
+};
+
+/**
+ * devm_touchscreen_alloc_softbuttons - allocate softbuttons
+ * @input: touchscreen input device for which softbuttons should be allocated
+ *
+ * This function parses touschcreen softbutton DT properties for touchscreens
+ * and allocates and fill a touchscreen_softbutton_info struct if any
+ * softbuttons are found.
+ *
+ * Returns prepared struct touchscreen_softbutton_info on success,
+ * %NULL if no softbuttons were found (this is not an error) or a ERR_PTR
+ * in case of an error.
+ *
+ * Note as this is a devm function the returned pointer does not need to
+ * be freed.
+ */
+struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
+					struct input_dev *input)
+{
+	struct device *dev = input->dev.parent;
+	struct device_node *np, *pp;
+	struct touchscreen_softbutton_info *info;
+	int i, err, button_count;
+
+	np = dev->of_node;
+	if (!np)
+		return NULL;
+
+	button_count = of_get_child_count(np);
+	if (button_count == 0)
+		return NULL;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return ERR_PTR(-ENOMEM);
+
+	info->input = input;
+	info->button_count = button_count;
+	info->buttons = devm_kzalloc(dev, button_count * sizeof(*info->buttons),
+				     GFP_KERNEL);
+	if (!info->buttons)
+		return ERR_PTR(-ENOMEM);
+
+	for (pp = of_get_next_child(np, NULL), i = 0;
+	     pp != NULL;
+	     pp = of_get_next_child(np, pp), i++) {
+		struct touchscreen_softbutton *btn = &info->buttons[i];
+
+		err = of_property_read_u32(pp, "linux,code", &btn->keycode);
+		if (err) {
+			dev_err(dev, "%s: Inval linux,code prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-min-x", &btn->min_x);
+		if (err) {
+			dev_err(dev, "%s: Inval min-x prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-max-x", &btn->max_x);
+		if (err) {
+			dev_err(dev, "%s: Inval max-x prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-min-y", &btn->min_y);
+		if (err) {
+			dev_err(dev, "%s: Inval min-y prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+
+		err = of_property_read_u32(pp, "softbutton-max-y", &btn->max_y);
+		if (err) {
+			dev_err(dev, "%s: Inval max-y prop\n", pp->name);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	__set_bit(EV_KEY, input->evbit);
+	for (i = 0; i < info->button_count; i++)
+		__set_bit(info->buttons[i].keycode, input->keybit);
+
+	return info;
+}
+
+/**
+ * touchscreen_handle_softbuttons - check for softbutton press
+ * @info: softbutton info retured by devm_touchscreen_alloc_softbuttons.
+ *
+ * This function checks if the passed in coordinates match any softbutton,
+ * and when they do reports a key press / release for the softbutton.
+ *
+ * Returns true if the coordinates match a softbutton and a key press / release
+ * was reported, false otherwise.
+ */
+bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
+				    unsigned int x, unsigned int y, bool down)
+{
+	int i;
+
+	if (info == NULL)
+		return false;
+
+	for (i = 0; i < info->button_count; i++) {
+		if (x >= info->buttons[i].min_x &&
+		    x <= info->buttons[i].max_x &&
+		    y >= info->buttons[i].min_y &&
+		    y <= info->buttons[i].max_y) {
+			input_report_key(info->input,
+					 info->buttons[i].keycode, down);
+			return true;
+		}
+	}
+
+	return false;
+}
diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h
index 09d22cc..0b9d4ee 100644
--- a/include/linux/input/touchscreen.h
+++ b/include/linux/input/touchscreen.h
@@ -9,8 +9,11 @@
 #ifndef _TOUCHSCREEN_H
 #define _TOUCHSCREEN_H
 
+#include <linux/types.h>
+
 struct input_dev;
 struct input_mt_pos;
+struct touchscreen_softbutton_info;
 
 struct touchscreen_properties {
 	unsigned int max_x;
@@ -32,4 +35,10 @@ void touchscreen_report_pos(struct input_dev *input,
 			    unsigned int x, unsigned int y,
 			    bool multitouch);
 
+struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
+					struct input_dev *input);
+
+bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
+				    unsigned int x, unsigned int y, bool down);
+
 #endif
-- 
2.9.3

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

* [PATCH resend 2/5] input: touchscreen: Add LED trigger support to the softbutton code
  2016-09-11 18:44 ` Hans de Goede
@ 2016-09-11 18:44   ` Hans de Goede
  -1 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring
  Cc: linux-input, linux-arm-kernel, devicetree, Hans de Goede

In some hardware there are 1 or more LEDs behind the touchscreen
softbuttons, which are intended to provide visual feedback to the
user that the softbutton has been pressed, this commit adds support
for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../bindings/input/touchscreen/softbuttons.txt     |  4 ++
 drivers/input/touchscreen/softbuttons.c            | 49 +++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
index 3eb6f4c..b425b95 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
@@ -17,6 +17,10 @@ Required subnode-properties:
  - softbutton-min-y		: Y start of the area the softbutton area covers
  - softbutton-max-y		: Y end of the area the softbutton area covers
 
+Optional subnode-properties:
+- linux,led-trigger		: String for a LED trigger for providing visual
+				  feedback that the softbutton has been pressed
+
 Example:
 
 #include <dt-bindings/input/input.h>
diff --git a/drivers/input/touchscreen/softbuttons.c b/drivers/input/touchscreen/softbuttons.c
index 47aea18..9a3fbfa 100644
--- a/drivers/input/touchscreen/softbuttons.c
+++ b/drivers/input/touchscreen/softbuttons.c
@@ -11,6 +11,7 @@
 
 #include <linux/input.h>
 #include <linux/input/touchscreen.h>
+#include <linux/leds.h>
 #include <linux/of.h>
 
 struct touchscreen_softbutton {
@@ -19,6 +20,8 @@ struct touchscreen_softbutton {
 	u32 min_y;
 	u32 max_y;
 	u32 keycode;
+	const char *ledtrigger_name;
+	struct led_trigger *ledtrigger;
 };
 
 struct touchscreen_softbutton_info {
@@ -48,7 +51,7 @@ struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
 	struct device *dev = input->dev.parent;
 	struct device_node *np, *pp;
 	struct touchscreen_softbutton_info *info;
-	int i, err, button_count;
+	int i, j, err, button_count;
 
 	np = dev->of_node;
 	if (!np)
@@ -103,6 +106,36 @@ struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
 			dev_err(dev, "%s: Inval max-y prop\n", pp->name);
 			return ERR_PTR(-EINVAL);
 		}
+
+		err = of_property_read_string(pp, "linux,led-trigger",
+					      &btn->ledtrigger_name);
+		if (err)
+			continue; /* The LED trigger is optional */
+
+		/* Check if another softbutton uses the same trigger */
+		for (j = 0; j < i; j++) {
+			if (info->buttons[j].ledtrigger_name &&
+			    strcmp(info->buttons[j].ledtrigger_name,
+				   btn->ledtrigger_name) == 0) {
+				btn->ledtrigger = info->buttons[j].ledtrigger;
+				break;
+			}
+		}
+		if (!btn->ledtrigger) {
+			btn->ledtrigger =
+				devm_kzalloc(dev, sizeof(*btn->ledtrigger),
+					     GFP_KERNEL);
+			if (!btn->ledtrigger)
+				return ERR_PTR(-ENOMEM);
+
+			btn->ledtrigger->name = btn->ledtrigger_name;
+			err = devm_led_trigger_register(dev, btn->ledtrigger);
+			if (err) {
+				dev_err(dev, "%s: Ledtrigger register error\n",
+					pp->name);
+				return ERR_PTR(err);
+			}
+		}
 	}
 
 	__set_bit(EV_KEY, input->evbit);
@@ -126,6 +159,7 @@ bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
 				    unsigned int x, unsigned int y, bool down)
 {
 	int i;
+	unsigned long led_delay = 1000; /* Keep the led on 1s after release */
 
 	if (info == NULL)
 		return false;
@@ -137,6 +171,19 @@ bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
 		    y <= info->buttons[i].max_y) {
 			input_report_key(info->input,
 					 info->buttons[i].keycode, down);
+
+			if (info->buttons[i].ledtrigger && down) {
+				led_trigger_event(info->buttons[i].ledtrigger,
+						  LED_FULL);
+			} else if (info->buttons[i].ledtrigger && !down) {
+				/* Led must be off before calling blink */
+				led_trigger_event(info->buttons[i].ledtrigger,
+						  LED_OFF);
+				led_trigger_blink_oneshot(
+					info->buttons[i].ledtrigger,
+					&led_delay, &led_delay, 0);
+			}
+
 			return true;
 		}
 	}
-- 
2.9.3


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

* [PATCH resend 2/5] input: touchscreen: Add LED trigger support to the softbutton code
@ 2016-09-11 18:44   ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

In some hardware there are 1 or more LEDs behind the touchscreen
softbuttons, which are intended to provide visual feedback to the
user that the softbutton has been pressed, this commit adds support
for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../bindings/input/touchscreen/softbuttons.txt     |  4 ++
 drivers/input/touchscreen/softbuttons.c            | 49 +++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
index 3eb6f4c..b425b95 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
@@ -17,6 +17,10 @@ Required subnode-properties:
  - softbutton-min-y		: Y start of the area the softbutton area covers
  - softbutton-max-y		: Y end of the area the softbutton area covers
 
+Optional subnode-properties:
+- linux,led-trigger		: String for a LED trigger for providing visual
+				  feedback that the softbutton has been pressed
+
 Example:
 
 #include <dt-bindings/input/input.h>
diff --git a/drivers/input/touchscreen/softbuttons.c b/drivers/input/touchscreen/softbuttons.c
index 47aea18..9a3fbfa 100644
--- a/drivers/input/touchscreen/softbuttons.c
+++ b/drivers/input/touchscreen/softbuttons.c
@@ -11,6 +11,7 @@
 
 #include <linux/input.h>
 #include <linux/input/touchscreen.h>
+#include <linux/leds.h>
 #include <linux/of.h>
 
 struct touchscreen_softbutton {
@@ -19,6 +20,8 @@ struct touchscreen_softbutton {
 	u32 min_y;
 	u32 max_y;
 	u32 keycode;
+	const char *ledtrigger_name;
+	struct led_trigger *ledtrigger;
 };
 
 struct touchscreen_softbutton_info {
@@ -48,7 +51,7 @@ struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
 	struct device *dev = input->dev.parent;
 	struct device_node *np, *pp;
 	struct touchscreen_softbutton_info *info;
-	int i, err, button_count;
+	int i, j, err, button_count;
 
 	np = dev->of_node;
 	if (!np)
@@ -103,6 +106,36 @@ struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons(
 			dev_err(dev, "%s: Inval max-y prop\n", pp->name);
 			return ERR_PTR(-EINVAL);
 		}
+
+		err = of_property_read_string(pp, "linux,led-trigger",
+					      &btn->ledtrigger_name);
+		if (err)
+			continue; /* The LED trigger is optional */
+
+		/* Check if another softbutton uses the same trigger */
+		for (j = 0; j < i; j++) {
+			if (info->buttons[j].ledtrigger_name &&
+			    strcmp(info->buttons[j].ledtrigger_name,
+				   btn->ledtrigger_name) == 0) {
+				btn->ledtrigger = info->buttons[j].ledtrigger;
+				break;
+			}
+		}
+		if (!btn->ledtrigger) {
+			btn->ledtrigger =
+				devm_kzalloc(dev, sizeof(*btn->ledtrigger),
+					     GFP_KERNEL);
+			if (!btn->ledtrigger)
+				return ERR_PTR(-ENOMEM);
+
+			btn->ledtrigger->name = btn->ledtrigger_name;
+			err = devm_led_trigger_register(dev, btn->ledtrigger);
+			if (err) {
+				dev_err(dev, "%s: Ledtrigger register error\n",
+					pp->name);
+				return ERR_PTR(err);
+			}
+		}
 	}
 
 	__set_bit(EV_KEY, input->evbit);
@@ -126,6 +159,7 @@ bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
 				    unsigned int x, unsigned int y, bool down)
 {
 	int i;
+	unsigned long led_delay = 1000; /* Keep the led on 1s after release */
 
 	if (info == NULL)
 		return false;
@@ -137,6 +171,19 @@ bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info,
 		    y <= info->buttons[i].max_y) {
 			input_report_key(info->input,
 					 info->buttons[i].keycode, down);
+
+			if (info->buttons[i].ledtrigger && down) {
+				led_trigger_event(info->buttons[i].ledtrigger,
+						  LED_FULL);
+			} else if (info->buttons[i].ledtrigger && !down) {
+				/* Led must be off before calling blink */
+				led_trigger_event(info->buttons[i].ledtrigger,
+						  LED_OFF);
+				led_trigger_blink_oneshot(
+					info->buttons[i].ledtrigger,
+					&led_delay, &led_delay, 0);
+			}
+
 			return true;
 		}
 	}
-- 
2.9.3

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

* [PATCH resend 3/5] input: touchscreen: edt-ft5x06: Add support for softbuttons
  2016-09-11 18:44 ` Hans de Goede
@ 2016-09-11 18:44   ` Hans de Goede
  -1 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring
  Cc: linux-input, linux-arm-kernel, devicetree, Hans de Goede

Add support for softbuttons to the edt-ft5x06 driver.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/touchscreen/edt-ft5x06.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 28466e3..481d8ba 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -86,6 +86,7 @@ struct edt_reg_addr {
 struct edt_ft5x06_ts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
+	struct touchscreen_softbutton_info *buttons;
 	struct touchscreen_properties prop;
 	u16 num_x;
 	u16 num_y;
@@ -241,6 +242,9 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
 		id = (buf[2] >> 4) & 0x0f;
 		down = type != TOUCH_EVENT_UP;
 
+		if (touchscreen_handle_softbuttons(tsdata->buttons, x, y, down))
+			continue;
+
 		input_mt_slot(tsdata->input, id);
 		input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, down);
 
@@ -975,6 +979,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
 
 	touchscreen_parse_properties(input, true, &tsdata->prop);
 
+	tsdata->buttons = devm_touchscreen_alloc_softbuttons(input);
+	if (IS_ERR(tsdata->buttons))
+		return PTR_ERR(tsdata->buttons);
+
 	error = input_mt_init_slots(input, tsdata->max_support_points,
 				INPUT_MT_DIRECT);
 	if (error) {
-- 
2.9.3


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

* [PATCH resend 3/5] input: touchscreen: edt-ft5x06: Add support for softbuttons
@ 2016-09-11 18:44   ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for softbuttons to the edt-ft5x06 driver.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/input/touchscreen/edt-ft5x06.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 28466e3..481d8ba 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -86,6 +86,7 @@ struct edt_reg_addr {
 struct edt_ft5x06_ts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
+	struct touchscreen_softbutton_info *buttons;
 	struct touchscreen_properties prop;
 	u16 num_x;
 	u16 num_y;
@@ -241,6 +242,9 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
 		id = (buf[2] >> 4) & 0x0f;
 		down = type != TOUCH_EVENT_UP;
 
+		if (touchscreen_handle_softbuttons(tsdata->buttons, x, y, down))
+			continue;
+
 		input_mt_slot(tsdata->input, id);
 		input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, down);
 
@@ -975,6 +979,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
 
 	touchscreen_parse_properties(input, true, &tsdata->prop);
 
+	tsdata->buttons = devm_touchscreen_alloc_softbuttons(input);
+	if (IS_ERR(tsdata->buttons))
+		return PTR_ERR(tsdata->buttons);
+
 	error = input_mt_init_slots(input, tsdata->max_support_points,
 				INPUT_MT_DIRECT);
 	if (error) {
-- 
2.9.3

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

* [PATCH resend 4/5] input: touchscreen: silead: Add regulator support
  2016-09-11 18:44 ` Hans de Goede
@ 2016-09-11 18:44     ` Hans de Goede
  -1 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring
  Cc: linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	Hans de Goede

On some tablets the touchscreen controller is powered by seperate
regulators, add support for this.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 .../bindings/input/touchscreen/silead_gsl1680.txt  |  2 +
 drivers/input/touchscreen/silead.c                 | 51 ++++++++++++++++++++--
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
index 820fee4..ce85ee5 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
@@ -18,6 +18,8 @@ Optional properties:
 - touchscreen-inverted-y  : See touchscreen.txt
 - touchscreen-swapped-x-y : See touchscreen.txt
 - silead,max-fingers	  : maximum number of fingers the touchscreen can detect
+- vddio-supply		  : regulator phandle for controller VDDIO
+- avdd-supply		  : regulator phandle for controller AVDD
 
 Example:
 
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
index f502c84..c6a1ae9 100644
--- a/drivers/input/touchscreen/silead.c
+++ b/drivers/input/touchscreen/silead.c
@@ -29,6 +29,7 @@
 #include <linux/input/touchscreen.h>
 #include <linux/pm.h>
 #include <linux/irq.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/unaligned.h>
 
@@ -72,6 +73,8 @@ enum silead_ts_power {
 struct silead_ts_data {
 	struct i2c_client *client;
 	struct gpio_desc *gpio_power;
+	struct regulator *vddio;
+	struct regulator *avdd;
 	struct input_dev *input;
 	char fw_name[64];
 	struct touchscreen_properties prop;
@@ -465,21 +468,52 @@ static int silead_ts_probe(struct i2c_client *client,
 	if (client->irq <= 0)
 		return -ENODEV;
 
+	data->vddio = devm_regulator_get_optional(dev, "vddio");
+	if (IS_ERR(data->vddio)) {
+		if (PTR_ERR(data->vddio) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		data->vddio = NULL;
+	}
+
+	data->avdd = devm_regulator_get_optional(dev, "avdd");
+	if (IS_ERR(data->avdd)) {
+		if (PTR_ERR(data->avdd) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		data->avdd = NULL;
+	}
+
+	/*
+	 * Enable regulators at probe and disable them at remove, we need
+	 * to keep the chip powered otherwise it forgets its firmware.
+	 */
+	if (data->vddio) {
+		error = regulator_enable(data->vddio);
+		if (error)
+			return error;
+	}
+
+	if (data->avdd) {
+		error = regulator_enable(data->avdd);
+		if (error)
+			goto disable_vddio;
+	}
+
 	/* Power GPIO pin */
 	data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
 	if (IS_ERR(data->gpio_power)) {
 		if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
 			dev_err(dev, "Shutdown GPIO request failed\n");
-		return PTR_ERR(data->gpio_power);
+		error = PTR_ERR(data->gpio_power);
+		goto disable_avdd;
 	}
 
 	error = silead_ts_setup(client);
 	if (error)
-		return error;
+		goto disable_avdd;
 
 	error = silead_ts_request_input_dev(data);
 	if (error)
-		return error;
+		goto disable_avdd;
 
 	error = devm_request_threaded_irq(dev, client->irq,
 					  NULL, silead_ts_threaded_irq_handler,
@@ -487,10 +521,19 @@ static int silead_ts_probe(struct i2c_client *client,
 	if (error) {
 		if (error != -EPROBE_DEFER)
 			dev_err(dev, "IRQ request failed %d\n", error);
-		return error;
+		goto disable_avdd;
 	}
 
 	return 0;
+
+disable_avdd:
+	if (data->avdd)
+		regulator_disable(data->avdd);
+disable_vddio:
+	if (data->vddio)
+		regulator_disable(data->vddio);
+
+	return error;
 }
 
 static int __maybe_unused silead_ts_suspend(struct device *dev)
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH resend 4/5] input: touchscreen: silead: Add regulator support
@ 2016-09-11 18:44     ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

On some tablets the touchscreen controller is powered by seperate
regulators, add support for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/input/touchscreen/silead_gsl1680.txt  |  2 +
 drivers/input/touchscreen/silead.c                 | 51 ++++++++++++++++++++--
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
index 820fee4..ce85ee5 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
@@ -18,6 +18,8 @@ Optional properties:
 - touchscreen-inverted-y  : See touchscreen.txt
 - touchscreen-swapped-x-y : See touchscreen.txt
 - silead,max-fingers	  : maximum number of fingers the touchscreen can detect
+- vddio-supply		  : regulator phandle for controller VDDIO
+- avdd-supply		  : regulator phandle for controller AVDD
 
 Example:
 
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
index f502c84..c6a1ae9 100644
--- a/drivers/input/touchscreen/silead.c
+++ b/drivers/input/touchscreen/silead.c
@@ -29,6 +29,7 @@
 #include <linux/input/touchscreen.h>
 #include <linux/pm.h>
 #include <linux/irq.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/unaligned.h>
 
@@ -72,6 +73,8 @@ enum silead_ts_power {
 struct silead_ts_data {
 	struct i2c_client *client;
 	struct gpio_desc *gpio_power;
+	struct regulator *vddio;
+	struct regulator *avdd;
 	struct input_dev *input;
 	char fw_name[64];
 	struct touchscreen_properties prop;
@@ -465,21 +468,52 @@ static int silead_ts_probe(struct i2c_client *client,
 	if (client->irq <= 0)
 		return -ENODEV;
 
+	data->vddio = devm_regulator_get_optional(dev, "vddio");
+	if (IS_ERR(data->vddio)) {
+		if (PTR_ERR(data->vddio) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		data->vddio = NULL;
+	}
+
+	data->avdd = devm_regulator_get_optional(dev, "avdd");
+	if (IS_ERR(data->avdd)) {
+		if (PTR_ERR(data->avdd) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		data->avdd = NULL;
+	}
+
+	/*
+	 * Enable regulators at probe and disable them at remove, we need
+	 * to keep the chip powered otherwise it forgets its firmware.
+	 */
+	if (data->vddio) {
+		error = regulator_enable(data->vddio);
+		if (error)
+			return error;
+	}
+
+	if (data->avdd) {
+		error = regulator_enable(data->avdd);
+		if (error)
+			goto disable_vddio;
+	}
+
 	/* Power GPIO pin */
 	data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
 	if (IS_ERR(data->gpio_power)) {
 		if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
 			dev_err(dev, "Shutdown GPIO request failed\n");
-		return PTR_ERR(data->gpio_power);
+		error = PTR_ERR(data->gpio_power);
+		goto disable_avdd;
 	}
 
 	error = silead_ts_setup(client);
 	if (error)
-		return error;
+		goto disable_avdd;
 
 	error = silead_ts_request_input_dev(data);
 	if (error)
-		return error;
+		goto disable_avdd;
 
 	error = devm_request_threaded_irq(dev, client->irq,
 					  NULL, silead_ts_threaded_irq_handler,
@@ -487,10 +521,19 @@ static int silead_ts_probe(struct i2c_client *client,
 	if (error) {
 		if (error != -EPROBE_DEFER)
 			dev_err(dev, "IRQ request failed %d\n", error);
-		return error;
+		goto disable_avdd;
 	}
 
 	return 0;
+
+disable_avdd:
+	if (data->avdd)
+		regulator_disable(data->avdd);
+disable_vddio:
+	if (data->vddio)
+		regulator_disable(data->vddio);
+
+	return error;
 }
 
 static int __maybe_unused silead_ts_suspend(struct device *dev)
-- 
2.9.3

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

* [PATCH resend 5/5] input: touchscreen: Add support for Elan eKTF2127 touchscreen controller
  2016-09-11 18:44 ` Hans de Goede
@ 2016-09-11 18:44   ` Hans de Goede
  -1 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring
  Cc: linux-input, linux-arm-kernel, devicetree, Siebren Vroegindeweij,
	Michel Verlaan, Hans de Goede

From: Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>

This adds a driver for the Elan eKTF2127 touchscreen controller,
which speaks an i2c protocol which is distinctly different from
the already supported eKTH controllers.

Signed-off-by: Michel Verlaan <michel.verl@gmail.com>
Signed-off-by: Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Changes in v2:
-Improve devicetree bindings document
-Use touchscreen_parse_properties and touchscreen_report_pos instead of DIY
-Remove a bunch of unused defines (copy and paste leftover from chipone driver)
-Some other minor cleanups and review comments addressed
-Add defines for some command / address hex-values
-Check packet header in interrupt handler
---
 .../bindings/input/touchscreen/ektf2127.txt        |  27 ++
 drivers/input/touchscreen/Kconfig                  |  12 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/ektf2127.c               | 333 +++++++++++++++++++++
 4 files changed, 373 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
 create mode 100644 drivers/input/touchscreen/ektf2127.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
new file mode 100644
index 0000000..70a949b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
@@ -0,0 +1,27 @@
+* Elan eKTF2127 I2C touchscreen controller
+
+Required properties:
+ - compatible		  : "elan,ektf2127"
+ - reg			  : I2C slave address of the chip (0x40)
+ - interrupt-parent	  : a phandle pointing to the interrupt controller
+			    serving the interrupt for this chip
+ - interrupts		  : interrupt specification for the ektf2127 interrupt
+ - power-gpios		  : GPIO specification for the pin connected to the
+			    ektf2127's wake input. This needs to be driven high
+			    to take ektf2127 out of it's low power state
+
+For additional optional properties see: touchscreen.txt
+
+Example:
+
+i2c@00000000 {
+	ektf2127: touchscreen@15 {
+		compatible = "elan,ektf2127";
+		reg = <0x15>;
+		interrupt-parent = <&pio>;
+		interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>;
+		power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>;
+		touchscreen-inverted-x;
+		touchscreen-swapped-x-y;
+	};
+};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 3b3d07a..880aa50 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -396,6 +396,18 @@ config TOUCHSCREEN_ELAN
 	  To compile this driver as a module, choose M here: the
 	  module will be called elants_i2c.
 
+config TOUCHSCREEN_EKTF2127
+	tristate "Elan eKTF2127 I2C touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have an Elan eKTF2127 touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ektf2127.
+
 config TOUCHSCREEN_ELO
 	tristate "Elo serial touchscreens"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 33b2eb8..db876ef 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE)	+= hampshire.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
 obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ELAN)		+= elants_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_EKTF2127)	+= ektf2127.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL)	+= egalax_ts_serial.o
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
new file mode 100644
index 0000000..512a394
--- /dev/null
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -0,0 +1,333 @@
+/*
+ * Driver for ELAN eKTF2127 i2c touchscreen controller
+ *
+ * For this driver the layout of the Chipone icn8318 i2c
+ * touchscreencontroller is used.
+ *
+ * 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.
+ *
+ * Author:
+ * Michel Verlaan <michel.verl@gmail.com>
+ * Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
+ *
+ * Original chipone_icn8318 driver:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+
+/* Packet header defines (first byte of data send / received) */
+#define EKTF2127_NOISE			0x40
+#define EKTF2127_RESPONSE		0x52
+#define EKTF2127_REQUEST		0x53
+#define EKTF2127_HELLO			0x55
+#define EKTF2127_REPORT			0x5d
+#define EKTF2127_CALIB_DONE		0x66
+
+/* Register deines (second byte of data send / received) */
+#define EKTF2127_ENV_NOISY		0x41
+#define EKTF2127_HEIGHT			0x60
+#define EKTF2127_WIDTH			0x63
+
+/* 2 bytes header + 5 * 3 bytes coordinates + 3 bytes pressure info + footer */
+#define EKTF2127_TOUCH_REPORT_SIZE	21
+#define EKTF2127_MAX_TOUCHES		5
+
+struct ektf2127_data {
+	struct i2c_client *client;
+	struct input_dev *input;
+	struct gpio_desc *power_gpios;
+	struct touchscreen_properties prop;
+};
+
+static void retrieve_coordinates(struct input_mt_pos *touches,
+				int touch_count, char *buf)
+{
+	int index = 0;
+	int i = 0;
+
+	for (i = 0; i < touch_count; i++) {
+		index = 2 + i * 3;
+
+		touches[i].x = (buf[index] & 0x0f);
+		touches[i].x <<= 8;
+		touches[i].x |= buf[index + 2];
+
+		touches[i].y = (buf[index] & 0xf0);
+		touches[i].y <<= 4;
+		touches[i].y |= buf[index + 1];
+	}
+}
+
+static irqreturn_t ektf2127_irq(int irq, void *dev_id)
+{
+	struct ektf2127_data *data = dev_id;
+	struct device *dev = &data->client->dev;
+	struct input_mt_pos touches[EKTF2127_MAX_TOUCHES];
+	int touch_count;
+	int slots[EKTF2127_MAX_TOUCHES];
+	char buff[EKTF2127_TOUCH_REPORT_SIZE];
+	int i, ret;
+
+	ret = i2c_master_recv(data->client, buff, EKTF2127_TOUCH_REPORT_SIZE);
+	if (ret != EKTF2127_TOUCH_REPORT_SIZE) {
+		dev_err(dev, "Error reading touch data\n");
+		return IRQ_HANDLED;
+	}
+
+	switch (buff[0]) {
+	case EKTF2127_REPORT:
+		/* Handled below */
+		break;
+	case EKTF2127_NOISE:
+		if (buff[1] == EKTF2127_ENV_NOISY)
+			dev_dbg(dev, "Environment is electically noisy\n");
+		return IRQ_HANDLED;
+	case EKTF2127_HELLO:
+	case EKTF2127_CALIB_DONE:
+		return IRQ_HANDLED;
+	default:
+		dev_err(dev, "Unexpected packet header byte %02x\n", buff[0]);
+		return IRQ_HANDLED;
+	}
+
+	touch_count = buff[1] & 0x07;
+
+	if (touch_count > EKTF2127_MAX_TOUCHES) {
+		dev_err(dev, "Too many touches %d > %d\n",
+			touch_count, EKTF2127_MAX_TOUCHES);
+		touch_count = EKTF2127_MAX_TOUCHES;
+	}
+
+	retrieve_coordinates(touches, touch_count, buff);
+	input_mt_assign_slots(data->input, slots, touches,
+			      touch_count, 0);
+
+	for (i = 0; i < touch_count; i++) {
+		input_mt_slot(data->input, slots[i]);
+		input_mt_report_slot_state(data->input, MT_TOOL_FINGER, true);
+		touchscreen_report_pos(data->input, &data->prop, touches[i].x,
+			touches[i].y, true);
+	}
+
+	input_mt_sync_frame(data->input);
+	input_sync(data->input);
+
+	return IRQ_HANDLED;
+}
+
+static int ektf2127_start(struct input_dev *dev)
+{
+	struct ektf2127_data *data = input_get_drvdata(dev);
+
+	enable_irq(data->client->irq);
+	gpiod_set_value_cansleep(data->power_gpios, 1);
+
+	return 0;
+}
+
+static void ektf2127_stop(struct input_dev *dev)
+{
+	struct ektf2127_data *data = input_get_drvdata(dev);
+
+	disable_irq(data->client->irq);
+	gpiod_set_value_cansleep(data->power_gpios, 0);
+}
+
+static int ektf2127_suspend(struct device *dev)
+{
+	struct ektf2127_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	mutex_lock(&data->input->mutex);
+	if (data->input->users)
+		ektf2127_stop(data->input);
+	mutex_unlock(&data->input->mutex);
+
+	return 0;
+}
+
+static int ektf2127_resume(struct device *dev)
+{
+	struct ektf2127_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	mutex_lock(&data->input->mutex);
+	if (data->input->users)
+		ektf2127_start(data->input);
+	mutex_unlock(&data->input->mutex);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ektf2127_pm_ops, ektf2127_suspend,
+			ektf2127_resume);
+
+static int ektf2127_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct ektf2127_data *data;
+	struct input_dev *input;
+	char buff[4];
+	int error, max_x, max_y, ret = 0;
+
+	if (!client->irq) {
+		dev_err(dev, "Error no irq specified\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* This requests the gpio *and* turns on the touchscreen controller */
+	data->power_gpios = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
+	if (IS_ERR(data->power_gpios)) {
+		error = PTR_ERR(data->power_gpios);
+		if (error != -EPROBE_DEFER)
+			dev_err(dev, "Error getting power gpio: %d\n", error);
+		return error;
+	}
+
+	input = devm_input_allocate_device(dev);
+	if (!input)
+		return -ENOMEM;
+
+	input->name = client->name;
+	input->id.bustype = BUS_I2C;
+	input->open = ektf2127_start;
+	input->close = ektf2127_stop;
+
+	data->client = client;
+
+	/* Read hello (ignore result, depends on initial power state) */
+	msleep(20);
+	i2c_master_recv(data->client, buff, 4);
+
+	/* Read resolution from chip */
+
+	/* Request width */
+	buff[0] = EKTF2127_REQUEST;
+	buff[1] = EKTF2127_WIDTH;
+	buff[2] = 0x00;
+	buff[3] = 0x00;
+	ret = i2c_master_send(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error requesting width\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	msleep(20);
+
+	/* Read response */
+	ret = i2c_master_recv(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error receiving width\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	if ((buff[0] == EKTF2127_RESPONSE) && (buff[1] == EKTF2127_WIDTH)) {
+		max_x = (((buff[3] & 0xf0) << 4) | buff[2]) - 1;
+	} else {
+		dev_err(dev, "Error unexpected width data\n");
+		return -EIO;
+	}
+
+	/* Request height */
+	buff[0] = EKTF2127_REQUEST;
+	buff[1] = EKTF2127_HEIGHT;
+	buff[2] = 0x00;
+	buff[3] = 0x00;
+	ret = i2c_master_send(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error requesting height\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	msleep(20);
+
+	/* Read response */
+	ret = i2c_master_recv(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error receiving height\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	if ((buff[0] == EKTF2127_RESPONSE) && (buff[1] == EKTF2127_HEIGHT)) {
+		max_y = (((buff[3] & 0xf0) << 4) | buff[2]) - 1;
+	} else {
+		dev_err(dev, "Error unexpected height data\n");
+		return -EIO;
+	}
+
+	input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
+	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+	touchscreen_parse_properties(input, true, &data->prop);
+
+	error = input_mt_init_slots(input, EKTF2127_MAX_TOUCHES,
+				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED
+				    | INPUT_MT_TRACK);
+	if (error)
+		return error;
+
+	data->input = input;
+	input_set_drvdata(input, data);
+
+	error = devm_request_threaded_irq(dev, client->irq, NULL, ektf2127_irq,
+					  IRQF_ONESHOT, client->name, data);
+	if (error) {
+		dev_err(dev, "Error requesting irq: %d\n", error);
+		return error;
+	}
+
+	/* Stop device till opened */
+	ektf2127_stop(data->input);
+
+	error = input_register_device(input);
+	if (error)
+		return error;
+
+	i2c_set_clientdata(client, data);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ektf2127_of_match[] = {
+	{ .compatible = "elan,ektf2127" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, ektf2127_of_match);
+#endif
+
+static const struct i2c_device_id ektf2127_i2c_id[] = {
+	{ "ektf2127", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
+
+static struct i2c_driver ektf2127_driver = {
+	.driver = {
+		.name	= "elan_ektf2127",
+		.pm	= &ektf2127_pm_ops,
+		.of_match_table = of_match_ptr(ektf2127_of_match),
+	},
+	.probe = ektf2127_probe,
+	.id_table = ektf2127_i2c_id,
+};
+
+module_i2c_driver(ektf2127_driver);
+
+MODULE_DESCRIPTION("ELAN eKTF2127 I2C Touchscreen Driver");
+MODULE_AUTHOR("Michel Verlaan, Siebren Vroegindeweij");
+MODULE_LICENSE("GPL");
-- 
2.9.3


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

* [PATCH resend 5/5] input: touchscreen: Add support for Elan eKTF2127 touchscreen controller
@ 2016-09-11 18:44   ` Hans de Goede
  0 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2016-09-11 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

From: Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>

This adds a driver for the Elan eKTF2127 touchscreen controller,
which speaks an i2c protocol which is distinctly different from
the already supported eKTH controllers.

Signed-off-by: Michel Verlaan <michel.verl@gmail.com>
Signed-off-by: Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Changes in v2:
-Improve devicetree bindings document
-Use touchscreen_parse_properties and touchscreen_report_pos instead of DIY
-Remove a bunch of unused defines (copy and paste leftover from chipone driver)
-Some other minor cleanups and review comments addressed
-Add defines for some command / address hex-values
-Check packet header in interrupt handler
---
 .../bindings/input/touchscreen/ektf2127.txt        |  27 ++
 drivers/input/touchscreen/Kconfig                  |  12 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/ektf2127.c               | 333 +++++++++++++++++++++
 4 files changed, 373 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
 create mode 100644 drivers/input/touchscreen/ektf2127.c

diff --git a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
new file mode 100644
index 0000000..70a949b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
@@ -0,0 +1,27 @@
+* Elan eKTF2127 I2C touchscreen controller
+
+Required properties:
+ - compatible		  : "elan,ektf2127"
+ - reg			  : I2C slave address of the chip (0x40)
+ - interrupt-parent	  : a phandle pointing to the interrupt controller
+			    serving the interrupt for this chip
+ - interrupts		  : interrupt specification for the ektf2127 interrupt
+ - power-gpios		  : GPIO specification for the pin connected to the
+			    ektf2127's wake input. This needs to be driven high
+			    to take ektf2127 out of it's low power state
+
+For additional optional properties see: touchscreen.txt
+
+Example:
+
+i2c at 00000000 {
+	ektf2127: touchscreen at 15 {
+		compatible = "elan,ektf2127";
+		reg = <0x15>;
+		interrupt-parent = <&pio>;
+		interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>;
+		power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>;
+		touchscreen-inverted-x;
+		touchscreen-swapped-x-y;
+	};
+};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 3b3d07a..880aa50 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -396,6 +396,18 @@ config TOUCHSCREEN_ELAN
 	  To compile this driver as a module, choose M here: the
 	  module will be called elants_i2c.
 
+config TOUCHSCREEN_EKTF2127
+	tristate "Elan eKTF2127 I2C touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have an Elan eKTF2127 touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ektf2127.
+
 config TOUCHSCREEN_ELO
 	tristate "Elo serial touchscreens"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 33b2eb8..db876ef 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE)	+= hampshire.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
 obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ELAN)		+= elants_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_EKTF2127)	+= ektf2127.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL)	+= egalax_ts_serial.o
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
new file mode 100644
index 0000000..512a394
--- /dev/null
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -0,0 +1,333 @@
+/*
+ * Driver for ELAN eKTF2127 i2c touchscreen controller
+ *
+ * For this driver the layout of the Chipone icn8318 i2c
+ * touchscreencontroller is used.
+ *
+ * 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.
+ *
+ * Author:
+ * Michel Verlaan <michel.verl@gmail.com>
+ * Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
+ *
+ * Original chipone_icn8318 driver:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+
+/* Packet header defines (first byte of data send / received) */
+#define EKTF2127_NOISE			0x40
+#define EKTF2127_RESPONSE		0x52
+#define EKTF2127_REQUEST		0x53
+#define EKTF2127_HELLO			0x55
+#define EKTF2127_REPORT			0x5d
+#define EKTF2127_CALIB_DONE		0x66
+
+/* Register deines (second byte of data send / received) */
+#define EKTF2127_ENV_NOISY		0x41
+#define EKTF2127_HEIGHT			0x60
+#define EKTF2127_WIDTH			0x63
+
+/* 2 bytes header + 5 * 3 bytes coordinates + 3 bytes pressure info + footer */
+#define EKTF2127_TOUCH_REPORT_SIZE	21
+#define EKTF2127_MAX_TOUCHES		5
+
+struct ektf2127_data {
+	struct i2c_client *client;
+	struct input_dev *input;
+	struct gpio_desc *power_gpios;
+	struct touchscreen_properties prop;
+};
+
+static void retrieve_coordinates(struct input_mt_pos *touches,
+				int touch_count, char *buf)
+{
+	int index = 0;
+	int i = 0;
+
+	for (i = 0; i < touch_count; i++) {
+		index = 2 + i * 3;
+
+		touches[i].x = (buf[index] & 0x0f);
+		touches[i].x <<= 8;
+		touches[i].x |= buf[index + 2];
+
+		touches[i].y = (buf[index] & 0xf0);
+		touches[i].y <<= 4;
+		touches[i].y |= buf[index + 1];
+	}
+}
+
+static irqreturn_t ektf2127_irq(int irq, void *dev_id)
+{
+	struct ektf2127_data *data = dev_id;
+	struct device *dev = &data->client->dev;
+	struct input_mt_pos touches[EKTF2127_MAX_TOUCHES];
+	int touch_count;
+	int slots[EKTF2127_MAX_TOUCHES];
+	char buff[EKTF2127_TOUCH_REPORT_SIZE];
+	int i, ret;
+
+	ret = i2c_master_recv(data->client, buff, EKTF2127_TOUCH_REPORT_SIZE);
+	if (ret != EKTF2127_TOUCH_REPORT_SIZE) {
+		dev_err(dev, "Error reading touch data\n");
+		return IRQ_HANDLED;
+	}
+
+	switch (buff[0]) {
+	case EKTF2127_REPORT:
+		/* Handled below */
+		break;
+	case EKTF2127_NOISE:
+		if (buff[1] == EKTF2127_ENV_NOISY)
+			dev_dbg(dev, "Environment is electically noisy\n");
+		return IRQ_HANDLED;
+	case EKTF2127_HELLO:
+	case EKTF2127_CALIB_DONE:
+		return IRQ_HANDLED;
+	default:
+		dev_err(dev, "Unexpected packet header byte %02x\n", buff[0]);
+		return IRQ_HANDLED;
+	}
+
+	touch_count = buff[1] & 0x07;
+
+	if (touch_count > EKTF2127_MAX_TOUCHES) {
+		dev_err(dev, "Too many touches %d > %d\n",
+			touch_count, EKTF2127_MAX_TOUCHES);
+		touch_count = EKTF2127_MAX_TOUCHES;
+	}
+
+	retrieve_coordinates(touches, touch_count, buff);
+	input_mt_assign_slots(data->input, slots, touches,
+			      touch_count, 0);
+
+	for (i = 0; i < touch_count; i++) {
+		input_mt_slot(data->input, slots[i]);
+		input_mt_report_slot_state(data->input, MT_TOOL_FINGER, true);
+		touchscreen_report_pos(data->input, &data->prop, touches[i].x,
+			touches[i].y, true);
+	}
+
+	input_mt_sync_frame(data->input);
+	input_sync(data->input);
+
+	return IRQ_HANDLED;
+}
+
+static int ektf2127_start(struct input_dev *dev)
+{
+	struct ektf2127_data *data = input_get_drvdata(dev);
+
+	enable_irq(data->client->irq);
+	gpiod_set_value_cansleep(data->power_gpios, 1);
+
+	return 0;
+}
+
+static void ektf2127_stop(struct input_dev *dev)
+{
+	struct ektf2127_data *data = input_get_drvdata(dev);
+
+	disable_irq(data->client->irq);
+	gpiod_set_value_cansleep(data->power_gpios, 0);
+}
+
+static int ektf2127_suspend(struct device *dev)
+{
+	struct ektf2127_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	mutex_lock(&data->input->mutex);
+	if (data->input->users)
+		ektf2127_stop(data->input);
+	mutex_unlock(&data->input->mutex);
+
+	return 0;
+}
+
+static int ektf2127_resume(struct device *dev)
+{
+	struct ektf2127_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	mutex_lock(&data->input->mutex);
+	if (data->input->users)
+		ektf2127_start(data->input);
+	mutex_unlock(&data->input->mutex);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ektf2127_pm_ops, ektf2127_suspend,
+			ektf2127_resume);
+
+static int ektf2127_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct ektf2127_data *data;
+	struct input_dev *input;
+	char buff[4];
+	int error, max_x, max_y, ret = 0;
+
+	if (!client->irq) {
+		dev_err(dev, "Error no irq specified\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* This requests the gpio *and* turns on the touchscreen controller */
+	data->power_gpios = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
+	if (IS_ERR(data->power_gpios)) {
+		error = PTR_ERR(data->power_gpios);
+		if (error != -EPROBE_DEFER)
+			dev_err(dev, "Error getting power gpio: %d\n", error);
+		return error;
+	}
+
+	input = devm_input_allocate_device(dev);
+	if (!input)
+		return -ENOMEM;
+
+	input->name = client->name;
+	input->id.bustype = BUS_I2C;
+	input->open = ektf2127_start;
+	input->close = ektf2127_stop;
+
+	data->client = client;
+
+	/* Read hello (ignore result, depends on initial power state) */
+	msleep(20);
+	i2c_master_recv(data->client, buff, 4);
+
+	/* Read resolution from chip */
+
+	/* Request width */
+	buff[0] = EKTF2127_REQUEST;
+	buff[1] = EKTF2127_WIDTH;
+	buff[2] = 0x00;
+	buff[3] = 0x00;
+	ret = i2c_master_send(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error requesting width\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	msleep(20);
+
+	/* Read response */
+	ret = i2c_master_recv(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error receiving width\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	if ((buff[0] == EKTF2127_RESPONSE) && (buff[1] == EKTF2127_WIDTH)) {
+		max_x = (((buff[3] & 0xf0) << 4) | buff[2]) - 1;
+	} else {
+		dev_err(dev, "Error unexpected width data\n");
+		return -EIO;
+	}
+
+	/* Request height */
+	buff[0] = EKTF2127_REQUEST;
+	buff[1] = EKTF2127_HEIGHT;
+	buff[2] = 0x00;
+	buff[3] = 0x00;
+	ret = i2c_master_send(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error requesting height\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	msleep(20);
+
+	/* Read response */
+	ret = i2c_master_recv(data->client, buff, 4);
+	if (ret != 4) {
+		dev_err(dev, "Error receiving height\n");
+		return ret < 0 ? ret : -EIO;
+	}
+
+	if ((buff[0] == EKTF2127_RESPONSE) && (buff[1] == EKTF2127_HEIGHT)) {
+		max_y = (((buff[3] & 0xf0) << 4) | buff[2]) - 1;
+	} else {
+		dev_err(dev, "Error unexpected height data\n");
+		return -EIO;
+	}
+
+	input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
+	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+	touchscreen_parse_properties(input, true, &data->prop);
+
+	error = input_mt_init_slots(input, EKTF2127_MAX_TOUCHES,
+				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED
+				    | INPUT_MT_TRACK);
+	if (error)
+		return error;
+
+	data->input = input;
+	input_set_drvdata(input, data);
+
+	error = devm_request_threaded_irq(dev, client->irq, NULL, ektf2127_irq,
+					  IRQF_ONESHOT, client->name, data);
+	if (error) {
+		dev_err(dev, "Error requesting irq: %d\n", error);
+		return error;
+	}
+
+	/* Stop device till opened */
+	ektf2127_stop(data->input);
+
+	error = input_register_device(input);
+	if (error)
+		return error;
+
+	i2c_set_clientdata(client, data);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ektf2127_of_match[] = {
+	{ .compatible = "elan,ektf2127" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, ektf2127_of_match);
+#endif
+
+static const struct i2c_device_id ektf2127_i2c_id[] = {
+	{ "ektf2127", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
+
+static struct i2c_driver ektf2127_driver = {
+	.driver = {
+		.name	= "elan_ektf2127",
+		.pm	= &ektf2127_pm_ops,
+		.of_match_table = of_match_ptr(ektf2127_of_match),
+	},
+	.probe = ektf2127_probe,
+	.id_table = ektf2127_i2c_id,
+};
+
+module_i2c_driver(ektf2127_driver);
+
+MODULE_DESCRIPTION("ELAN eKTF2127 I2C Touchscreen Driver");
+MODULE_AUTHOR("Michel Verlaan, Siebren Vroegindeweij");
+MODULE_LICENSE("GPL");
-- 
2.9.3

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

* Re: [PATCH resend 1/5] input: touchscreen: Add generic touchscreen softbutton handling code
  2016-09-11 18:44     ` Hans de Goede
@ 2016-09-20 14:34       ` Rob Herring
  -1 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2016-09-20 14:34 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Dmitry Torokhov, linux-input, linux-arm-kernel, devicetree

On Sun, Sep 11, 2016 at 08:44:04PM +0200, Hans de Goede wrote:
> Some touchscreens extend over the display they cover and have a number
> of capacative softbuttons outside of the display the cover.
> 
> With some hardware these softbuttons simply report touches with
> coordinates outside of the normal coordinate space for touches on the
> display.
> 
> This commit adds a devicetree binding for describing such buttons in
> devicetree and a bunch of helper functions to easily add support for
> these to existing touchscreen drivers.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../bindings/input/touchscreen/softbuttons.txt     |  58 +++++++++
>  drivers/input/touchscreen/Makefile                 |   2 +-
>  drivers/input/touchscreen/softbuttons.c            | 145 +++++++++++++++++++++
>  include/linux/input/touchscreen.h                  |   9 ++
>  4 files changed, 213 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
>  create mode 100644 drivers/input/touchscreen/softbuttons.c
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> new file mode 100644
> index 0000000..3eb6f4c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> @@ -0,0 +1,58 @@
> +General Touchscreen Softbutton Properties:
> +
> +Some touchscreens extend over the display they cover and have a number
> +of capacative softbuttons outside of the display the cover.
> +
> +Some of these softbuttons simply report touches with coordinates outside of
> +the normal coordinate space for touches on the display. This binding is for
> +describing such buttons in devicetree.
> +
> +Each softkey is represented as a sub-node of the touchscreen node.
> +
> +Required subnode-properties:
> + - label			: Descriptive name of the key.
> + - linux,code			: Keycode to emit.
> + - softbutton-min-x		: X start of the area the softbutton area covers
> + - softbutton-max-x		: X end of the area the softbutton area covers
> + - softbutton-min-y		: Y start of the area the softbutton area covers
> + - softbutton-max-y		: Y end of the area the softbutton area covers

Please add the note about these values are signed.

With that,

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

Rob

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

* [PATCH resend 1/5] input: touchscreen: Add generic touchscreen softbutton handling code
@ 2016-09-20 14:34       ` Rob Herring
  0 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2016-09-20 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Sep 11, 2016 at 08:44:04PM +0200, Hans de Goede wrote:
> Some touchscreens extend over the display they cover and have a number
> of capacative softbuttons outside of the display the cover.
> 
> With some hardware these softbuttons simply report touches with
> coordinates outside of the normal coordinate space for touches on the
> display.
> 
> This commit adds a devicetree binding for describing such buttons in
> devicetree and a bunch of helper functions to easily add support for
> these to existing touchscreen drivers.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../bindings/input/touchscreen/softbuttons.txt     |  58 +++++++++
>  drivers/input/touchscreen/Makefile                 |   2 +-
>  drivers/input/touchscreen/softbuttons.c            | 145 +++++++++++++++++++++
>  include/linux/input/touchscreen.h                  |   9 ++
>  4 files changed, 213 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
>  create mode 100644 drivers/input/touchscreen/softbuttons.c
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> new file mode 100644
> index 0000000..3eb6f4c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> @@ -0,0 +1,58 @@
> +General Touchscreen Softbutton Properties:
> +
> +Some touchscreens extend over the display they cover and have a number
> +of capacative softbuttons outside of the display the cover.
> +
> +Some of these softbuttons simply report touches with coordinates outside of
> +the normal coordinate space for touches on the display. This binding is for
> +describing such buttons in devicetree.
> +
> +Each softkey is represented as a sub-node of the touchscreen node.
> +
> +Required subnode-properties:
> + - label			: Descriptive name of the key.
> + - linux,code			: Keycode to emit.
> + - softbutton-min-x		: X start of the area the softbutton area covers
> + - softbutton-max-x		: X end of the area the softbutton area covers
> + - softbutton-min-y		: Y start of the area the softbutton area covers
> + - softbutton-max-y		: Y end of the area the softbutton area covers

Please add the note about these values are signed.

With that,

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

Rob

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

* Re: [PATCH resend 2/5] input: touchscreen: Add LED trigger support to the softbutton code
  2016-09-11 18:44   ` Hans de Goede
@ 2016-09-20 14:40       ` Rob Herring
  -1 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2016-09-20 14:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Dmitry Torokhov, linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree

On Sun, Sep 11, 2016 at 08:44:05PM +0200, Hans de Goede wrote:
> In some hardware there are 1 or more LEDs behind the touchscreen
> softbuttons, which are intended to provide visual feedback to the
> user that the softbutton has been pressed, this commit adds support
> for this.
> 
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  .../bindings/input/touchscreen/softbuttons.txt     |  4 ++
>  drivers/input/touchscreen/softbuttons.c            | 49 +++++++++++++++++++++-
>  2 files changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> index 3eb6f4c..b425b95 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> @@ -17,6 +17,10 @@ Required subnode-properties:
>   - softbutton-min-y		: Y start of the area the softbutton area covers
>   - softbutton-max-y		: Y end of the area the softbutton area covers
>  
> +Optional subnode-properties:
> +- linux,led-trigger		: String for a LED trigger for providing visual
> +				  feedback that the softbutton has been pressed

This should just be a phandle to the LED if you want to describe the 
link. Or standardize the trigger naming (in the kernel) for buttons and 
just use the existing 'linux,default-trigger' in the LED node.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH resend 2/5] input: touchscreen: Add LED trigger support to the softbutton code
@ 2016-09-20 14:40       ` Rob Herring
  0 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2016-09-20 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Sep 11, 2016 at 08:44:05PM +0200, Hans de Goede wrote:
> In some hardware there are 1 or more LEDs behind the touchscreen
> softbuttons, which are intended to provide visual feedback to the
> user that the softbutton has been pressed, this commit adds support
> for this.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../bindings/input/touchscreen/softbuttons.txt     |  4 ++
>  drivers/input/touchscreen/softbuttons.c            | 49 +++++++++++++++++++++-
>  2 files changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> index 3eb6f4c..b425b95 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt
> @@ -17,6 +17,10 @@ Required subnode-properties:
>   - softbutton-min-y		: Y start of the area the softbutton area covers
>   - softbutton-max-y		: Y end of the area the softbutton area covers
>  
> +Optional subnode-properties:
> +- linux,led-trigger		: String for a LED trigger for providing visual
> +				  feedback that the softbutton has been pressed

This should just be a phandle to the LED if you want to describe the 
link. Or standardize the trigger naming (in the kernel) for buttons and 
just use the existing 'linux,default-trigger' in the LED node.

Rob

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

end of thread, other threads:[~2016-09-20 14:40 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-11 18:44 [PATCH resend 0/5] input: resend of 5 touchscreen patches Hans de Goede
2016-09-11 18:44 ` Hans de Goede
2016-09-11 18:44 ` [PATCH resend 2/5] input: touchscreen: Add LED trigger support to the softbutton code Hans de Goede
2016-09-11 18:44   ` Hans de Goede
     [not found]   ` <20160911184408.11657-3-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-09-20 14:40     ` Rob Herring
2016-09-20 14:40       ` Rob Herring
2016-09-11 18:44 ` [PATCH resend 3/5] input: touchscreen: edt-ft5x06: Add support for softbuttons Hans de Goede
2016-09-11 18:44   ` Hans de Goede
     [not found] ` <20160911184408.11657-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-09-11 18:44   ` [PATCH resend 1/5] input: touchscreen: Add generic touchscreen softbutton handling code Hans de Goede
2016-09-11 18:44     ` Hans de Goede
2016-09-20 14:34     ` Rob Herring
2016-09-20 14:34       ` Rob Herring
2016-09-11 18:44   ` [PATCH resend 4/5] input: touchscreen: silead: Add regulator support Hans de Goede
2016-09-11 18:44     ` Hans de Goede
2016-09-11 18:44 ` [PATCH resend 5/5] input: touchscreen: Add support for Elan eKTF2127 touchscreen controller Hans de Goede
2016-09-11 18:44   ` Hans de Goede

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.