diff mbox

[U-Boot,2/8] input: Add polytouch touch sensor controller

Message ID 1400164490-14673-3-git-send-email-dietho@gmx.de
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

dietho@gmx.de May 15, 2014, 2:34 p.m. UTC
From: Thomas Diener <dietho@gmx.de>

Signed-off-by: Thomas Diener <dietho@gmx.de>
---
 drivers/input/Makefile    |    1 +
 drivers/input/polytouch.c |  138 +++++++++++++++++++++++++++++++++++++++++++++
 include/polytouch.h       |   35 ++++++++++++
 3 files changed, 174 insertions(+)
 create mode 100644 drivers/input/polytouch.c
 create mode 100644 include/polytouch.h
diff mbox

Patch

diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index a8e9be2..65c40ba 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -14,3 +14,4 @@  obj-$(CONFIG_PS2MULT) += ps2mult.o ps2ser.o
 endif
 obj-y += input.o
 obj-$(CONFIG_OF_CONTROL) += key_matrix.o
+obj-$(CONFIG_POLYTOUCH) += polytouch.o
\ No newline at end of file
diff --git a/drivers/input/polytouch.c b/drivers/input/polytouch.c
new file mode 100644
index 0000000..9f1f38f
--- /dev/null
+++ b/drivers/input/polytouch.c
@@ -0,0 +1,138 @@ 
+/*
+ * (c) 2013 Graf-Syteco, Matthias Weisser
+ * <weisserm@arcor.de>
+ *
+ * polytouch.c - EDT PolyTouch capacitive touch sensor controller
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <polytouch.h>
+#include <i2c.h>
+
+
+#define POLYTOUCH_CMD_GETVERSION	0xBB
+#define POLYTOUCH_CMD_GETTOUCH		0xF9
+#define POLYTOUCH_CMD_SETREG		0xFC
+#define POLYTOUCH_CMD_GETREG		0xFC
+
+#define POLYTOUCH_REG_THRESHOLD		0x00
+#define POLYTOUCH_REG_MONITORTIME	0x07
+#define POLYTOUCH_REG_REPORTRATE	0x08
+#define POLYTOUCH_REG_GAIN		0x30
+#define POLYTOUCH_REG_OFFSET		0x31
+#define POLYTOUCH_REG_XRES		0x33
+#define POLYTOUCH_REG_YRES		0x34
+#define POLYTOUCH_REG_HIBERNATE		0x3A
+
+#define POLYTOUCH_PACKET_LENGTH		26
+
+static int xres;
+static int yres;
+
+static int32_t polytouch_set_reg(uint32_t reg, uint32_t val)
+{
+	uint8_t buf[3];
+	int r;
+
+	buf[0] = reg;
+	buf[1] = val;
+	buf[2] = POLYTOUCH_CMD_SETREG ^ buf[0] ^ buf[1];
+
+	r = i2c_write(POLYTOUCH_SA, POLYTOUCH_CMD_SETREG, 1, buf, 3);
+
+	if (0 != r)
+		printf("i2c_write failed with %d\n", r);
+
+	return r;
+}
+
+static int32_t polytouch_get_reg(uint32_t reg)
+{
+	uint8_t buf;
+
+	if (i2c_read(POLYTOUCH_SA, (POLYTOUCH_CMD_GETREG<<8) +
+		((reg + 0x40)<<0), 2, &buf, 1) == 0)
+		return buf;
+
+	return -1;
+}
+
+int polytouch_init(void)
+{
+	char buf[32];
+
+	if (!i2c_probe(POLYTOUCH_SA)) {
+		if (i2c_read(POLYTOUCH_SA, POLYTOUCH_CMD_GETVERSION, 1,
+			(uint8_t *)buf, 22) == 0) {
+			uint32_t gain = 7;
+			uint32_t threshold = 40;
+			uint32_t offset = 0;
+
+			buf[22] = '\0';
+
+			xres = polytouch_get_reg(POLYTOUCH_REG_XRES) * 64;
+			yres = polytouch_get_reg(POLYTOUCH_REG_YRES) * 64;
+
+			if (0 != strstr(buf, "EP035")) {
+				gain = 3;
+				threshold = 25;
+				offset = 34;
+			} else if (0 != strstr(buf, "EP043")) {
+				gain = 5;
+				threshold = 35;
+				offset = 34;
+			} else if (0 != strstr(buf, "EP057")) {
+				gain = 2;
+				threshold = 25;
+				offset = 34;
+			} else if (0 != strstr(buf, "EP070")) {
+				gain = 2;
+				threshold = 27;
+				offset = 34;
+			}
+
+			polytouch_set_reg(POLYTOUCH_REG_GAIN, gain);
+			polytouch_set_reg(POLYTOUCH_REG_THRESHOLD, threshold);
+			polytouch_set_reg(POLYTOUCH_REG_OFFSET, offset);
+			polytouch_set_reg(POLYTOUCH_REG_REPORTRATE, 8);
+			polytouch_set_reg(POLYTOUCH_REG_MONITORTIME, 0xC8);
+
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void polytouch_get_resolution(struct polytouch_resolution *res)
+{
+	if (NULL != res) {
+		res->x = xres;
+		res->y = yres;
+	}
+}
+
+int polytouch_is_touched(struct polytouch_area *area)
+{
+	if (NULL != area) {
+		uint8_t buf[POLYTOUCH_PACKET_LENGTH];
+		if (0 == i2c_read(POLYTOUCH_SA, POLYTOUCH_CMD_GETTOUCH, 1, buf,
+				  POLYTOUCH_PACKET_LENGTH)) {
+			if ((buf[0] == 0xAA) && (buf[1] == 0xAA) &&
+				(buf[2] == 0x1A) && (buf[3] == 0x01)) {
+				uint16_t x;
+				uint16_t y;
+
+				x = ((buf[5] & 0x0F) << 8) + buf[6];
+				y = ((buf[7] & 0x0F) << 8) + buf[8];
+
+				if ((x > area->x1) && (x < area->x2) &&
+					(y > area->y1) && (x < area->y2))
+					return 1;
+			}
+		}
+	}
+	return 0;
+}
diff --git a/include/polytouch.h b/include/polytouch.h
new file mode 100644
index 0000000..f906bbe
--- /dev/null
+++ b/include/polytouch.h
@@ -0,0 +1,35 @@ 
+/*
+ * (c) 2012 Graf-Syteco, Matthias Weisser
+ * <weisserm@arcor.de>
+ *
+ * polytouch.h - EDT PolyTouch capacitive touch sensor controller
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ */
+
+#ifndef __POLYTOUCH_H
+#define __POLYTOUCH_H
+
+#define POLYTOUCH_SA		0x38	/* I2C slave address of PolyTouch */
+
+
+struct polytouch_resolution {
+	uint x;
+	uint y;
+};
+
+struct polytouch_area {
+	uint x1; /* Start position x */
+	uint y1; /* Start position y */
+	uint x2; /* End position x */
+	uint y2; /* End position y */
+};
+
+
+int polytouch_init(void);
+void polytouch_get_resolution(struct polytouch_resolution *res);
+int polytouch_is_touched(struct polytouch_area *area);
+
+#endif
+