devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 0/3] add pressure calculation support for resistive-adc-touch driver
@ 2021-05-17 12:59 Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 1/3] dt-bindings: touchscreen: add touchscreen-x/y-plate-ohms property Oleksij Rempel
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Oleksij Rempel @ 2021-05-17 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Jonathan Cameron
  Cc: Oleksij Rempel, kernel, linux-kernel, linux-input, David Jander,
	devicetree

This series add pressure calculation support based on different measure
points of a basic resistive touchscreen.

Oleksij Rempel (3):
  dt-bindings: touchscreen: add touchscreen-x/y-plate-ohms property
  dt-bindings: touchscreen: resistive-adc-touch: add support for z1 and
    z2 channels
  Input: resistive-adc-touch: add support for z1 and z2 channels

 .../touchscreen/resistive-adc-touch.yaml      |   9 ++
 .../input/touchscreen/touchscreen.yaml        |   6 +
 .../input/touchscreen/resistive-adc-touch.c   | 142 ++++++++++++++++--
 3 files changed, 144 insertions(+), 13 deletions(-)

-- 
2.29.2


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

* [RFC PATCH v1 1/3] dt-bindings: touchscreen: add touchscreen-x/y-plate-ohms property
  2021-05-17 12:59 [RFC PATCH v1 0/3] add pressure calculation support for resistive-adc-touch driver Oleksij Rempel
@ 2021-05-17 12:59 ` Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 2/3] dt-bindings: touchscreen: resistive-adc-touch: add support for z1 and z2 channels Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 3/3] Input: " Oleksij Rempel
  2 siblings, 0 replies; 4+ messages in thread
From: Oleksij Rempel @ 2021-05-17 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Jonathan Cameron
  Cc: Oleksij Rempel, kernel, linux-kernel, linux-input, David Jander,
	devicetree

Te calculate the pressure on a restrictive touchscreen we need need to
know resistance at least of X plate. Some calculations need to use both
X and Y values.
So, add generic properties which can be used by all drivers

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 .../devicetree/bindings/input/touchscreen/touchscreen.yaml  | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
index 046ace461cc9..4b5b212c772c 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
@@ -74,6 +74,12 @@ properties:
   touchscreen-y-mm:
     description: vertical length in mm of the touchscreen
 
+  touchscreen-x-plate-ohms:
+    description: Resistance of the X-plate in Ohms
+
+  touchscreen-y-plate-ohms:
+    description: Resistance of the Y-plate in Ohms
+
 dependencies:
   touchscreen-size-x: [ touchscreen-size-y ]
   touchscreen-size-y: [ touchscreen-size-x ]
-- 
2.29.2


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

* [RFC PATCH v1 2/3] dt-bindings: touchscreen: resistive-adc-touch: add support for z1 and z2 channels
  2021-05-17 12:59 [RFC PATCH v1 0/3] add pressure calculation support for resistive-adc-touch driver Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 1/3] dt-bindings: touchscreen: add touchscreen-x/y-plate-ohms property Oleksij Rempel
@ 2021-05-17 12:59 ` Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 3/3] Input: " Oleksij Rempel
  2 siblings, 0 replies; 4+ messages in thread
From: Oleksij Rempel @ 2021-05-17 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Jonathan Cameron
  Cc: Oleksij Rempel, kernel, linux-kernel, linux-input, David Jander,
	devicetree

For pressure calculation based on plates resistance we need some additional
properties:
- z1 and z2 channels with additional measurements between plates
- actual resistance of the touchscreen. Currently we use only
  X-resistance.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 .../bindings/input/touchscreen/resistive-adc-touch.yaml  | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/resistive-adc-touch.yaml b/Documentation/devicetree/bindings/input/touchscreen/resistive-adc-touch.yaml
index 53df21a6589e..538c3b1ef1e1 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/resistive-adc-touch.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/resistive-adc-touch.yaml
@@ -43,6 +43,7 @@ properties:
   touchscreen-inverted-y: true
   touchscreen-swapped-x-y: true
   touchscreen-min-pressure: true
+  touchscreen-x-plate-ohms: true
 
 additionalProperties: false
 
@@ -59,3 +60,11 @@ examples:
       io-channels = <&adc 24>, <&adc 25>, <&adc 26>;
       io-channel-names = "x", "y", "pressure";
     };
+  - |
+    resistive_touch {
+      compatible = "resistive-adc-touch";
+      touchscreen-min-pressure = <50000>;
+      io-channels = <&adc 1>, <&adc 2>, <&adc 3>, <&adc 4>;
+      io-channel-names = "x", "y", "z1", "z2";
+      touchscreen-x-plate-ohms = <800>;
+    };
-- 
2.29.2


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

* [RFC PATCH v1 3/3] Input: resistive-adc-touch: add support for z1 and z2 channels
  2021-05-17 12:59 [RFC PATCH v1 0/3] add pressure calculation support for resistive-adc-touch driver Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 1/3] dt-bindings: touchscreen: add touchscreen-x/y-plate-ohms property Oleksij Rempel
  2021-05-17 12:59 ` [RFC PATCH v1 2/3] dt-bindings: touchscreen: resistive-adc-touch: add support for z1 and z2 channels Oleksij Rempel
@ 2021-05-17 12:59 ` Oleksij Rempel
  2 siblings, 0 replies; 4+ messages in thread
From: Oleksij Rempel @ 2021-05-17 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Jonathan Cameron
  Cc: Oleksij Rempel, kernel, linux-kernel, linux-input, David Jander,
	devicetree

Typical touchscreen do not report pressure. Instead, it is calculated by
measuring resistance of touchscreen plates on different reference
points. Some ADC controllers, for example TI TSC2046, can provide this
measurements. With this patch resistive-adc-touch will be able to use it
and calculate pressure out if measured resistance.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 .../input/touchscreen/resistive-adc-touch.c   | 142 ++++++++++++++++--
 1 file changed, 129 insertions(+), 13 deletions(-)

diff --git a/drivers/input/touchscreen/resistive-adc-touch.c b/drivers/input/touchscreen/resistive-adc-touch.c
index e50af30183f4..f53f8a7fd186 100644
--- a/drivers/input/touchscreen/resistive-adc-touch.c
+++ b/drivers/input/touchscreen/resistive-adc-touch.c
@@ -20,7 +20,18 @@
 
 #define DRIVER_NAME					"resistive-adc-touch"
 #define GRTS_DEFAULT_PRESSURE_MIN			50000
+#define GRTS_DEFAULT_PRESSURE_MAX			65535
 #define GRTS_MAX_POS_MASK				GENMASK(11, 0)
+#define GRTS_MAX_CHANNELS				4
+
+enum grts_ch_type {
+	GRTS_CH_NONE = 0,
+	GRTS_CH_X,
+	GRTS_CH_Y,
+	GRTS_CH_PRESSURE,
+	GRTS_CH_Z1,
+	GRTS_CH_Z2,
+};
 
 /**
  * struct grts_state - generic resistive touch screen information struct
@@ -33,24 +44,61 @@
  */
 struct grts_state {
 	u32				pressure_min;
+	u32				x_plate_ohms;
 	bool				pressure;
 	struct iio_channel		*iio_chans;
 	struct iio_cb_buffer		*iio_cb;
 	struct input_dev		*input;
 	struct touchscreen_properties	prop;
+	enum grts_ch_type		ch[GRTS_MAX_CHANNELS];
 };
 
 static int grts_cb(const void *data, void *private)
 {
 	const u16 *touch_info = data;
 	struct grts_state *st = private;
-	unsigned int x, y, press = 0x0;
+	unsigned int x, y, press = 0x0, z1, z2;
+	unsigned int Rt;
+	unsigned int idx;
+
+	for (idx = 0; st->ch[idx] != GRTS_CH_NONE; idx++) {
+		switch (st->ch[idx]) {
+		case GRTS_CH_X:
+			x = touch_info[idx];
+			break;
+		case GRTS_CH_Y:
+			y = touch_info[idx];
+			break;
+		case GRTS_CH_PRESSURE:
+			press = touch_info[idx];
+			break;
+		case GRTS_CH_Z1:
+			z1 = touch_info[idx];
+			break;
+		case GRTS_CH_Z2:
+			z2 = touch_info[idx];
+			break;
+		case GRTS_CH_NONE:
+			break;
+		}
+	}
 
-	/* channel data coming in buffer in the order below */
-	x = touch_info[0];
-	y = touch_info[1];
-	if (st->pressure)
-		press = touch_info[2];
+	if (z1) {
+		Rt = z2;
+		Rt -= z1;
+		Rt *= st->x_plate_ohms;
+		Rt = DIV_ROUND_CLOSEST(Rt, 16);
+		Rt *= x;
+		Rt /= z1;
+		Rt = DIV_ROUND_CLOSEST(Rt, 256);
+		/* On increased pressure the resistance (Rt) is decreasing
+		 * so, convert values to make it looks as real pressure.
+		 */
+		if (Rt < GRTS_DEFAULT_PRESSURE_MAX)
+			press = GRTS_DEFAULT_PRESSURE_MAX - Rt;
+		else
+			press = 0;
+	}
 
 	if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
 		/* report end of touch */
@@ -94,6 +142,73 @@ static void grts_disable(void *data)
 	iio_channel_release_all_cb(data);
 }
 
+static int grts_get_properties(struct grts_state *st, struct device *dev)
+{
+	int idx;
+
+	idx = device_property_match_string(dev, "io-channel-names", "x");
+	if (idx < 0)
+		return idx;
+
+	if (idx >= GRTS_MAX_CHANNELS)
+		return -EOVERFLOW;
+
+	st->ch[idx] = GRTS_CH_X;
+
+	idx = device_property_match_string(dev, "io-channel-names", "y");
+	if (idx < 0)
+		return idx;
+
+	if (idx >= GRTS_MAX_CHANNELS)
+		return -EOVERFLOW;
+
+	st->ch[idx] = GRTS_CH_Y;
+
+	/* pressure is optional */
+	idx = device_property_match_string(dev, "io-channel-names", "pressure");
+	if (idx >= 0) {
+		if (idx >= GRTS_MAX_CHANNELS)
+			return -EOVERFLOW;
+
+		st->ch[idx] = GRTS_CH_PRESSURE;
+		st->pressure = true;
+
+		return 0;
+	}
+
+	/* if no pressure is defined, try optional z1 + z2 */
+	idx = device_property_match_string(dev, "io-channel-names", "z1");
+	if (idx >= 0) {
+		int error;
+
+		if (idx >= GRTS_MAX_CHANNELS)
+			return -EOVERFLOW;
+
+		st->ch[idx] = GRTS_CH_Z1;
+
+		/* if z1 is provided z2 is not optional */
+		idx = device_property_match_string(dev, "io-channel-names", "z2");
+		if (idx < 0)
+			return idx;
+
+		if (idx >= GRTS_MAX_CHANNELS)
+			return -EOVERFLOW;
+
+		st->ch[idx] = GRTS_CH_Z2;
+		st->pressure = true;
+
+		error = device_property_read_u32(dev,
+						 "touchscreen-x-plate-ohms",
+						 &st->x_plate_ohms);
+		if (error) {
+			dev_err(dev, "can't get touchscreen-x-plate-ohms property\n");
+			return error;
+		}
+	}
+
+	return 0;
+}
+
 static int grts_probe(struct platform_device *pdev)
 {
 	struct grts_state *st;
@@ -115,12 +230,13 @@ static int grts_probe(struct platform_device *pdev)
 		return error;
 	}
 
-	chan = &st->iio_chans[0];
-	st->pressure = false;
-	while (chan && chan->indio_dev) {
-		if (!strcmp(chan->channel->datasheet_name, "pressure"))
-			st->pressure = true;
-		chan++;
+	if (!device_property_present(dev, "io-channel-names"))
+		return -ENODEV;
+
+	error = grts_get_properties(st, dev);
+	if (error) {
+		dev_err(dev, "Failed to parse properties\n");
+		return error;
 	}
 
 	if (st->pressure) {
@@ -148,7 +264,7 @@ static int grts_probe(struct platform_device *pdev)
 	input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
 	if (st->pressure)
 		input_set_abs_params(input, ABS_PRESSURE, st->pressure_min,
-				     0xffff, 0, 0);
+				     GRTS_DEFAULT_PRESSURE_MAX, 0, 0);
 
 	input_set_capability(input, EV_KEY, BTN_TOUCH);
 
-- 
2.29.2


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

end of thread, other threads:[~2021-05-17 12:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-17 12:59 [RFC PATCH v1 0/3] add pressure calculation support for resistive-adc-touch driver Oleksij Rempel
2021-05-17 12:59 ` [RFC PATCH v1 1/3] dt-bindings: touchscreen: add touchscreen-x/y-plate-ohms property Oleksij Rempel
2021-05-17 12:59 ` [RFC PATCH v1 2/3] dt-bindings: touchscreen: resistive-adc-touch: add support for z1 and z2 channels Oleksij Rempel
2021-05-17 12:59 ` [RFC PATCH v1 3/3] Input: " Oleksij Rempel

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