From: Sanggun Lee<[email protected]>
This is a TSP driver for touchscreen chip mms144 of MELFAS.
It uses soft I2C interface and supports single touch.

This driver uses polling method.
If there are touch events, mms144_interrupt() reads and returns 0.
If not, mms144_interrupt() returns -1.

Signed-off-by: SangGun Lee<[email protected]>
Signed-off-by: Joonyoung Shim<[email protected]>
Signed-off=by: MyungJoo Ham<[email protected]>
---
 drivers/input/Makefile |    1 +
 drivers/input/mms144.c |  202 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/mms144.h       |   41 ++++++++++
 3 files changed, 244 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/mms144.c
 create mode 100644 include/mms144.h

diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 0805e86..c802188 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -33,6 +33,7 @@ COBJS-$(CONFIG_PS2MULT) += ps2mult.o ps2ser.o
 endif
 COBJS-y += input.o
 COBJS-$(CONFIG_OF_CONTROL) += key_matrix.o
+COBJS-$(CONFIG_MMS144) += mms144.o
COBJS := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/input/mms144.c b/drivers/input/mms144.c
new file mode 100644
index 0000000..7532131
--- /dev/null
+++ b/drivers/input/mms144.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics
+ * Sang-gun Lee<[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <mms144.h>
+#include <i2c.h>
+
+/* Operating Mode */
+#define mms144_SLEEP                   0x01
+#define mms144_ACTIVE                  0x02
+#define mms144_SW_RESET                        0x03
+
+/* Write only registers */
+#define mms144_MODE_CONTROL            0x01
+
+/* Read only registers */
+#define mms144_PACKET_SIZE             0x0F
+#define mms144_INFOMATION              0x10
+
+/* Minimum delay time is 50us between stop and start signal of i2c */
+#define mms144_I2C_DELAY               50
+
+/* 200ms needs after power on */
+#define mms144_POWERON_DELAY           200
+
+/* Touchscreen absolute values */
+#define mms144_MAX_TOUCH               10
+
+/* XY calculate */
+#define X_SHIFT                                8
+#define Y_SHIFT                                4
+#define XY_HI_MASK                     0xF00
+#define XY_LOW_MASK                    0xFF
+#define X_LOW_MASK                     0x0F
+#define Y_LOW_MASK                     0xF0
+
+/* Others */
+#define SETUP_REG_LEN                  6
+#define POWER_ON                       1
+#define POWER_OFF                      0
+
+struct mms144_touch {
+       unsigned char info;
+       unsigned char xy_hi;
+       unsigned char x_lo;
+       unsigned char y_lo;
+} __packed;
+
+static struct mms144_platform *pdata;
+
+static int
+mms144_read_reg(unsigned int addr, unsigned char *val, unsigned int len)
+{
+       int error;
+
+       i2c_set_bus_num(pdata->bus_num);
+
+       error = i2c_read(pdata->chip, addr, 1, val, len);
+       if (error != 0) {
+               printf("mms144_read_reg is failed\n");
+                       return error;
+       }
+       udelay(mms144_I2C_DELAY);
+
+       return 0;
+}
+
+static int
+mms144_write_reg(unsigned int addr, unsigned char *val, unsigned int len)
+{
+       int error;
+
+       i2c_set_bus_num(pdata->bus_num);
+
+       error = i2c_write(pdata->chip, addr, 1, val, len);
+       if (error != 0) {
+               printf("mms144_write_reg is failed\n");
+               return error;
+       }
+       udelay(mms144_I2C_DELAY);
+
+       return 0;
+}
+
+static int mms144_setup_reg(void)
+{
+       unsigned char setup_reg_buf[SETUP_REG_LEN];
+       int error;
+
+       /*
+        * 0 = Mode Control
+        * 1 = XY hi resolution
+        * 2 = X low resolution
+        * 3 = Y low resolution
+        * 4 = Contact on event Threshold
+        * 5 = Moving event Threshold
+        */
+       setup_reg_buf[0] = mms144_ACTIVE;
+       setup_reg_buf[1] = ((pdata->y_size >> Y_SHIFT) & Y_LOW_MASK) |
+                          ((pdata->x_size >> X_SHIFT) & X_LOW_MASK);
+       setup_reg_buf[2] = pdata->x_size & XY_LOW_MASK;
+       setup_reg_buf[3] = pdata->y_size & XY_LOW_MASK;
+       setup_reg_buf[4] = pdata->contact_threshold;
+       setup_reg_buf[5] = pdata->moving_threshold;
+
+       /* burst write */
+       error = mms144_write_reg(mms144_MODE_CONTROL,
+                                setup_reg_buf, SETUP_REG_LEN);
+       if (error != 0) {
+               printf("mms144_setup_reg is failed\n");
+               return error;
+       }
+
+       return 0;
+}
+
+int mms144_start(struct mms144_platform *platform_data)
+{
+       int error;
+
+       pdata = platform_data;
+
+       /* TSP POWER ON */
+       pdata->cfg_power_pin(POWER_ON);
+       mdelay(mms144_POWERON_DELAY);
+
+       /* setup register. burst write from 0x01 */
+       error = mms144_setup_reg();
+       if (error != 0) {
+               printf("mms144_start is failed\n");
+               return error;
+       }
+
+       return 0;
+}
+
+void mms144_stop(void)
+{
+       /* TSP POWER disable */
+       pdata->cfg_power_pin(POWER_OFF);
+}
+
+static void
+mms144_calcul_xy(struct mms144_touch *touch, struct mms144_coord *coord)
+{
+       int x, y;
+
+       x = touch->xy_hi;
+       x = (x << X_SHIFT) & XY_HI_MASK;
+       x = x | (touch->x_lo & XY_LOW_MASK);
+
+       y = touch->xy_hi;
+       y = (y << Y_SHIFT) & XY_HI_MASK;
+       y = y | (touch->y_lo & XY_LOW_MASK);
+
+       coord->x = x;
+       coord->y = y;
+}
+
+int mms144_interrupt(struct mms144_coord *coord)
+{
+       int error;
+       unsigned char packet_size;
+       struct mms144_touch touch[mms144_MAX_TOUCH];
+
+       error = mms144_read_reg(mms144_PACKET_SIZE, &packet_size, 1);
+       if (error != 0) {
+               printf("\nmms144_interrupt is failed\n");
+               return -1;
+       }
+
+       if (packet_size == 0)
+               return -1;
+
+       error = mms144_read_reg(mms144_INFOMATION, touch, packet_size);
+       if (error != 0) {
+               printf("\nmms144_interrupt is failed\n");
+               return -1;
+       }
+
+       mms144_calcul_xy(touch, coord);
+
+       return 0;
+}
diff --git a/include/mms144.h b/include/mms144.h
new file mode 100644
index 0000000..a7a8d07
--- /dev/null
+++ b/include/mms144.h
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics
+ * Sang-gun Lee<[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifdef CONFIG_mms144
+struct mms144_platform {
+       unsigned char   chip;
+       unsigned int    bus_num;
+       unsigned int    x_size;
+       unsigned int    y_size;
+       unsigned int    contact_threshold;
+       unsigned int    moving_threshold;
+       void            (*cfg_power_pin)(int enable);
+};
+
+struct mms144_coord {
+       unsigned int x;
+       unsigned int y;
+};
+
+int mms144_start(struct mms144_platform *pdata);
+void mms144_stop(void);
+int mms144_interrupt(struct mms144_coord *coord);
+#endif
-- 1.7.4.1

_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to