
From: Sanggun Leesg0724.lee@samsung.com
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 Leesg0724.lee@samsung.com Signed-off-by: Joonyoung Shimjy0922.shim@samsung.com Signed-off=by: MyungJoo Hammyungjoo.ham@samsung.com --- 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 Leesg0724.lee@samsung.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. + * + * 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 Leesg0724.lee@samsung.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. + * + * 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