summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig17
-rw-r--r--drivers/input/touchscreen/Makefile2
-rw-r--r--drivers/input/touchscreen/ar1020-i2c.c500
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c44
-rw-r--r--drivers/input/touchscreen/fusion_F0710A.c510
-rw-r--r--drivers/input/touchscreen/fusion_F0710A.h88
-rw-r--r--drivers/input/touchscreen/stmpe-ts.c11
7 files changed, 1145 insertions, 27 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 14931da02921..3c65fe480fcb 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -103,6 +103,16 @@ config TOUCHSCREEN_AD7879_SPI
To compile this driver as a module, choose M here: the
module will be called ad7879-spi.
+config TOUCHSCREEN_AR1020_I2C
+ tristate "Microchip AR1020 I2C touchscreen"
+ depends on I2C
+ help
+ Say Y here if you have a Microchip AR1020 I2C Controller and
+ want to enable support for the built-in touchscreen.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ar1020-i2c.
+
config TOUCHSCREEN_AR1021_I2C
tristate "Microchip AR1021 i2c touchscreen"
depends on I2C && OF
@@ -674,6 +684,13 @@ config TOUCHSCREEN_MIGOR
To compile this driver as a module, choose M here: the
module will be called migor_ts.
+config TOUCHSCREEN_FUSION_F0710A
+ tristate "TouchRevolution Fusion F0710A Touchscreens"
+ depends on I2C
+ help
+ Say Y here if you want to support the multi-touch input driver for
+ the TouchRevolution Fusion 7 and 10 panels.
+
config TOUCHSCREEN_TOUCHRIGHT
tristate "Touchright serial touchscreen"
select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index d9a53317f05a..ae4876458cfa 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
+obj-$(CONFIG_TOUCHSCREEN_AR1020_I2C) += ar1020-i2c.o
obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
@@ -103,3 +104,4 @@ obj-$(CONFIG_TOUCHSCREEN_CT36X_WLD) += vtl/
obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o
obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
+obj-$(CONFIG_TOUCHSCREEN_FUSION_F0710A) += fusion_F0710A.o
diff --git a/drivers/input/touchscreen/ar1020-i2c.c b/drivers/input/touchscreen/ar1020-i2c.c
new file mode 100644
index 000000000000..1ecfbecf460d
--- /dev/null
+++ b/drivers/input/touchscreen/ar1020-i2c.c
@@ -0,0 +1,500 @@
+/*
+ * Microchip I2C Touchscreen Driver
+ *
+ * Copyright (c) 2011 Microchip Technology, Inc.
+ *
+ * http://www.microchip.com/mtouch
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+/* The private data structure that is referenced within the I2C bus driver */
+struct ar1020_i2c_priv {
+ struct i2c_client *client;
+ struct input_dev *input;
+ int irq;
+ int testCount;
+ int command_pending;
+ int use_count;
+ int button;
+ struct delayed_work reenable_work;
+};
+
+/*
+ * These are all the sysfs variables used to store and retrieve information
+ * from a user-level application
+ */
+static char sendBuffer[100];
+static char receiveBuffer[100];
+static int commandDataPending;
+
+/*
+ * These variables allows the IRQ to be specified via a module parameter
+ * or kernel parameter. To configuration of these value, please see
+ * driver documentation.
+ */
+static int touchIRQ;
+
+module_param(touchIRQ, int, S_IRUGO);
+
+
+/*
+ * Since the reference to private data is stored within the I2C
+ * bus driver, we will store another reference within this driver
+ * so the sysfs related function may also access this data
+ */
+struct ar1020_i2c_priv *g_priv;
+
+/*
+ * Display value of "commandDataPending" variable to application that is
+ * requesting it's value.
+ */
+static ssize_t commandDataPending_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d", commandDataPending);
+}
+
+/*
+ * Save value to "commandDataPending" variable from application that is
+ * requesting this.
+ */
+static ssize_t commandDataPending_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ sscanf(buf, "%d", &commandDataPending);
+ return count;
+}
+
+static struct kobj_attribute commandDataPending_attribute =
+ __ATTR(commandDataPending, 0666, commandDataPending_show,
+ commandDataPending_store);
+
+
+/*
+ * Display value of "receiveBuffer" variable to application that is
+ * requesting it's value.
+ */
+static ssize_t receiveBuffer_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ /* receive data is no longer pending */
+ commandDataPending = 0;
+ return sprintf(buf, "%s", receiveBuffer);
+}
+
+/*
+ * Save value to "receiveBuffer" variable from application that is
+ * requesting this.
+ */
+static ssize_t receiveBuffer_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ return snprintf(receiveBuffer, sizeof(receiveBuffer), "%s", buf);
+}
+
+static struct kobj_attribute receiveBuffer_attribute =
+ __ATTR(receiveBuffer, 0666, receiveBuffer_show, receiveBuffer_store);
+
+/*
+ * Display value of "sendBuffer" variable to application that is
+ * requesting it's value.
+ */
+static ssize_t sendBuffer_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s", sendBuffer);
+}
+
+/*
+ * Save value to "sendBuffer" variable from application that is
+ * requesting this.
+ */
+static ssize_t sendBuffer_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int data[8];
+ char buff[8];
+ int cnt;
+ int i;
+ struct ar1020_i2c_priv *priv = g_priv;
+
+ commandDataPending = 0;
+
+ cnt = sscanf(buf, "%x %x %x %x %x %x %x %x", &data[0], &data[1],
+ &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]);
+
+ pr_debug("AR1020 I2C: Processed %d bytes.\n", cnt);
+
+ /* Verify command string to send to controller is valid */
+ if (cnt < 3)
+ pr_info("AR1020 I2C: Insufficient command bytes to process.\n");
+ else if (data[0] != 0x0)
+ pr_info("AR1020 I2C: Leading zero required when sending I2C commands.\n");
+ else if (data[1] != 0x55)
+ pr_info("AR1020 I2C: Invalid header byte (0x55 expected).\n");
+ else if (data[2] != (cnt - 3))
+ pr_info("AR1020 I2C: Number of command bytes specified not "
+ "valid for current string.\n");
+
+ strcpy(sendBuffer, "");
+ pr_debug("AR1020 I2C: sending command bytes: ");
+ for (i = 0; i < cnt; i++) {
+ buff[i] = (char)data[i];
+ pr_debug("0x%02x ", data[i]);
+ }
+ pr_debug("\n");
+
+ if (priv) {
+ priv->command_pending = 1;
+ i2c_master_send(priv->client, buff, cnt);
+ }
+
+ return snprintf(sendBuffer, sizeof(sendBuffer), "%s", buf);
+}
+
+static struct kobj_attribute sendBuffer_attribute =
+ __ATTR(sendBuffer, 0666, sendBuffer_show, sendBuffer_store);
+
+/*
+ * Create a group of calibration attributes so we may work with them
+ * as a set.
+ */
+static struct attribute *attrs[] = {
+ &commandDataPending_attribute.attr,
+ &receiveBuffer_attribute.attr,
+ &sendBuffer_attribute.attr,
+ NULL,
+};
+
+static struct attribute_group attr_group = {
+ .attrs = attrs,
+};
+
+static struct kobject *ar1020_kobj;
+
+static void irq_reenable_work(struct work_struct *work)
+{
+ struct ar1020_i2c_priv *priv = container_of(work,
+ struct ar1020_i2c_priv, reenable_work.work);
+
+ enable_irq(priv->irq);
+}
+
+/*
+ * When the controller interrupt is asserted, this function is scheduled
+ * to be called to read the controller data.
+ */
+static irqreturn_t touch_irq_handler_func(int irq, void *dev_id)
+{
+ struct ar1020_i2c_priv *priv = (struct ar1020_i2c_priv *)dev_id;
+ int i;
+ int cnt;
+ unsigned char packet[9];
+ int x;
+ int y;
+ int button;
+
+ for (i = 0; i < 5; i++)
+ packet[i] = 0;
+
+ /*
+ * We want to ensure we only read packets when we are not in the middle
+ * of command communication. Disable command mode after receiving
+ * command response to resume receiving packets.
+ */
+ cnt = i2c_master_recv(priv->client, packet,
+ (priv->command_pending) ? 9 : 5);
+
+ if (cnt <= 0)
+ goto error;
+
+ if (packet[0] == 0x55) {
+ unsigned char *p = receiveBuffer;
+ unsigned char *pend = p + sizeof(receiveBuffer) - 2;
+ /* process up to 9 bytes */
+ strcpy(receiveBuffer, "");
+
+ priv->command_pending = 0;
+
+ if (packet[1] > 6)
+ pr_info("AR1020 I2C: invalid byte count\n");
+ else if (cnt > packet[1] + 2)
+ cnt = packet[1] + 2;
+
+ for (i = 0; i < cnt; i++) {
+ int ret = snprintf(p, pend - p, " 0x%02x", packet[i]);
+ if (ret <= 0)
+ break;
+ p += ret;
+ if (p >= pend)
+ break;
+ }
+ *p++ = '\n';
+ *p++ = 0;
+ pr_info("AR1020 I2C: command response: %s", receiveBuffer);
+ commandDataPending = 1;
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * Decode packets of data from a device path using AR1XXX protocol.
+ * Data format, 5 bytes: SYNC, DATA1, DATA2, DATA3, DATA4
+ * SYNC [7:0]: 1,0,0,0,0,TOUCHSTATUS[0:0]
+ * DATA1[7:0]: 0,X-LOW[6:0]
+ * DATA2[7:0]: 0,X-HIGH[4:0]
+ * DATA3[7:0]: 0,Y-LOW[6:0]
+ * DATA4[7:0]: 0,Y-HIGH[4:0]
+ *
+ * TOUCHSTATUS: 0 = Touch up, 1 = Touch down
+ */
+ if ((packet[0] & 0xfe) != 0x80) {
+ pr_err("AR1020 I2C: 1st Touch byte not valid. Value: 0x%02x\n",
+ packet[0]);
+ goto error; /* irq line may be shorted high, let's delay */
+ }
+ for (i = 1; i < 5; i++) {
+ /* verify byte is valid for current index */
+ if (0x80 & packet[i]) {
+ pr_err("AR1020 I2C: Touch byte not valid. Value: "
+ "0x%02x Index: 0x%02x\n", packet[i], i);
+ goto error;
+ }
+ }
+ x = ((packet[2] & 0x1f) << 7) | (packet[1] & 0x7f);
+ y = ((packet[4] & 0x1f) << 7) | (packet[3] & 0x7f);
+ button = (packet[0] & 1);
+
+ if (!button && !priv->button)
+ return IRQ_HANDLED;
+
+ priv->button = button;
+ input_report_abs(priv->input, ABS_X, x);
+ input_report_abs(priv->input, ABS_Y, y);
+ input_report_key(priv->input, BTN_TOUCH, button);
+ input_sync(priv->input);
+ return IRQ_HANDLED;
+error:
+ disable_irq_nosync(priv->irq);
+ schedule_delayed_work(&priv->reenable_work, 100);
+ return IRQ_HANDLED;
+}
+
+static int ar1020_i2c_open(struct input_dev *idev)
+{
+ struct ar1020_i2c_priv *priv = input_get_drvdata(idev);
+
+ if (priv->use_count++ == 0)
+ enable_irq(priv->irq);
+ return 0;
+}
+
+static void ar1020_i2c_close(struct input_dev *idev)
+{
+ struct ar1020_i2c_priv *priv = input_get_drvdata(idev);
+
+ if (--priv->use_count == 0)
+ disable_irq(priv->irq);
+}
+
+/*
+ * After the kernel's platform specific source files have been modified to
+ * reference the "ar1020_i2c" driver, this function will then be called.
+ * This function needs to be called to finish registering the driver.
+ */
+static int ar1020_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ar1020_i2c_priv *priv = NULL;
+ struct input_dev *input_dev = NULL;
+ int err = 0;
+ int irq;
+
+ pr_info("%s: begin\n", __func__);
+
+ if (!client) {
+ pr_err("AR1020 I2C: client pointer is NULL\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ irq = client->irq;
+ if (touchIRQ)
+ irq = touchIRQ;
+
+ if (!irq) {
+ pr_err("AR1020 I2C: no IRQ set for touch controller\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ priv = kzalloc(sizeof(struct ar1020_i2c_priv), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!priv) {
+ pr_err("AR1020 I2C: kzalloc error\n");
+ err = -ENOMEM;
+ goto error;
+ }
+
+ if (!input_dev) {
+ pr_err("AR1020 I2C: input allocate error\n");
+ err = -ENOMEM;
+ goto error;
+ }
+
+ priv->client = client;
+ priv->irq = irq;
+ priv->input = input_dev;
+ INIT_DELAYED_WORK(&priv->reenable_work, irq_reenable_work);
+
+ input_dev->name = "AR1020 Touchscreen";
+ input_dev->id.bustype = BUS_I2C;
+
+ input_dev->open = ar1020_i2c_open;
+ input_dev->close = ar1020_i2c_close;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+ input_set_abs_params(input_dev, ABS_X, 0, 4095, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 4095, 0, 0);
+ input_set_drvdata(input_dev, priv);
+ err = input_register_device(input_dev);
+ if (err) {
+ pr_err("AR1020 I2C: error registering input device\n");
+ goto error;
+ }
+
+ /* set type and register gpio pin as our interrupt */
+ err = request_threaded_irq(priv->irq, NULL, touch_irq_handler_func,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "AR1020 I2C IRQ",
+ priv);
+ if (err < 0)
+ goto error1;
+ disable_irq(priv->irq); /* wait for open */
+ i2c_set_clientdata(client, priv);
+ /*
+ * save pointer so sysfs helper functions may also have access
+ * to private data
+ */
+ g_priv = priv;
+ return 0;
+
+error1:
+ input_unregister_device(input_dev);
+error:
+ if (input_dev)
+ input_free_device(input_dev);
+
+ kfree(priv);
+ return err;
+
+}
+
+/*
+ * Unregister/remove the kernel driver from memory.
+ */
+static int ar1020_i2c_remove(struct i2c_client *client)
+{
+ struct ar1020_i2c_priv *priv =
+ (struct ar1020_i2c_priv *)i2c_get_clientdata(client);
+
+ free_irq(priv->irq, priv);
+ input_unregister_device(priv->input);
+ kfree(priv);
+ g_priv = NULL;
+ return 0;
+}
+
+/* This structure describe a list of supported slave chips */
+static const struct i2c_device_id ar1020_i2c_id[] = {
+ { "ar1020_i2c", 0 },
+ { }
+};
+
+/*
+ * This is the initial set of information the kernel has
+ * before probing drivers on the system
+ */
+static struct i2c_driver ar1020_i2c_driver = {
+ .driver = {
+ .name = "ar1020_i2c",
+ },
+ .probe = ar1020_i2c_probe,
+ .remove = ar1020_i2c_remove,
+ /*
+ * suspend/resume functions not needed since controller automatically
+ * put's itself to sleep mode after configurable short period of time
+ */
+ .suspend = NULL,
+ .resume = NULL,
+ .id_table = ar1020_i2c_id,
+};
+
+/*
+ * This function is called during startup even if the platform specific
+ * files have not been setup yet.
+ */
+static int __init ar1020_i2c_init(void)
+{
+ int retval;
+
+ pr_debug("AR1020 I2C: ar1020_i2c_init: begin\n");
+ strcpy(receiveBuffer, "");
+ strcpy(sendBuffer, "");
+
+ /*
+ * Creates a kobject "ar1020" that appears as a sub-directory
+ * under "/sys/kernel".
+ */
+ ar1020_kobj = kobject_create_and_add("ar1020", kernel_kobj);
+ if (!ar1020_kobj) {
+ pr_err("AR1020 I2C: cannot create kobject\n");
+ return -ENOMEM;
+ }
+
+ /* Create the files associated with this kobject */
+ retval = sysfs_create_group(ar1020_kobj, &attr_group);
+ if (retval) {
+ pr_err("AR1020 I2C: error registering ar1020-i2c driver's sysfs interface\n");
+ kobject_put(ar1020_kobj);
+ }
+
+ return i2c_add_driver(&ar1020_i2c_driver);
+}
+
+/*
+ * This function is called after ar1020_i2c_remove() immediately before
+ * being removed from the kernel.
+ */
+static void __exit ar1020_i2c_exit(void)
+{
+ pr_debug("AR1020 I2C: ar1020_i2c_exit begin\n");
+ kobject_put(ar1020_kobj);
+ i2c_del_driver(&ar1020_i2c_driver);
+}
+
+MODULE_AUTHOR("Steve Grahovac <steve.grahovac@microchip.com>");
+MODULE_DESCRIPTION("AR1020 touchscreen I2C bus driver");
+MODULE_LICENSE("GPL");
+
+module_init(ar1020_i2c_init);
+module_exit(ar1020_i2c_exit);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index c2fb0236a47c..eff12ea59470 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
#include <asm/unaligned.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
@@ -192,6 +193,8 @@ enum t100_type {
/* Delay times */
#define MXT_BACKUP_TIME 50 /* msec */
+#define MXT_RESET_GPIO_TIME 20 /* msec */
+#define MXT_RESET_INVALID_CHG 100 /* msec */
#define MXT_RESET_TIME 200 /* msec */
#define MXT_RESET_TIMEOUT 3000 /* msec */
#define MXT_CRC_TIMEOUT 1000 /* msec */
@@ -300,6 +303,7 @@ struct mxt_data {
u8 multitouch;
struct t7_config t7_cfg;
struct mxt_dbg dbg;
+ struct gpio_desc *reset_gpio;
/* Cached parameters from object table */
u16 T5_address;
@@ -1194,7 +1198,7 @@ static int mxt_soft_reset(struct mxt_data *data)
return ret;
/* Ignore CHG line for 100ms after reset */
- msleep(100);
+ msleep(MXT_RESET_INVALID_CHG);
mxt_acquire_irq(data);
@@ -3126,11 +3130,9 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (IS_ERR(pdata))
return PTR_ERR(pdata);
- data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
- if (!data) {
- dev_err(&client->dev, "Failed to allocate memory\n");
+ data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL);
+ if (!data)
return -ENOMEM;
- }
snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
client->adapter->nr, client->addr);
@@ -3144,19 +3146,34 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
- error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
- pdata->irqflags | IRQF_ONESHOT,
- client->name, data);
+ data->reset_gpio = devm_gpiod_get_optional(&client->dev,
+ "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(data->reset_gpio)) {
+ error = PTR_ERR(data->reset_gpio);
+ dev_err(&client->dev, "Failed to get reset gpio: %d\n", error);
+ return error;
+ }
+
+ error = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, mxt_interrupt,
+ pdata->irqflags | IRQF_ONESHOT,
+ client->name, data);
if (error) {
dev_err(&client->dev, "Failed to register interrupt\n");
- goto err_free_mem;
+ return error;
}
disable_irq(client->irq);
+ if (data->reset_gpio) {
+ msleep(MXT_RESET_GPIO_TIME);
+ gpiod_set_value(data->reset_gpio, 1);
+ msleep(MXT_RESET_INVALID_CHG);
+ }
+
error = mxt_initialize(data);
if (error)
- goto err_free_irq;
+ return error;
error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
if (error) {
@@ -3170,10 +3187,6 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
err_free_object:
mxt_free_input_device(data);
mxt_free_object_table(data);
-err_free_irq:
- free_irq(client->irq, data);
-err_free_mem:
- kfree(data);
return error;
}
@@ -3181,11 +3194,10 @@ static int mxt_remove(struct i2c_client *client)
{
struct mxt_data *data = i2c_get_clientdata(client);
+ disable_irq(data->irq);
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
- free_irq(data->irq, data);
mxt_free_input_device(data);
mxt_free_object_table(data);
- kfree(data);
return 0;
}
diff --git a/drivers/input/touchscreen/fusion_F0710A.c b/drivers/input/touchscreen/fusion_F0710A.c
new file mode 100644
index 000000000000..779c3e83a402
--- /dev/null
+++ b/drivers/input/touchscreen/fusion_F0710A.c
@@ -0,0 +1,510 @@
+/*
+ * "fusion_F0710A" touchscreen driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <asm/irq.h>
+#include <linux/gpio.h>
+#include <linux/input/fusion_F0710A.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/of_gpio.h>
+
+
+#include "fusion_F0710A.h"
+
+#define DRV_NAME "fusion_F0710A"
+#define MAX_TOUCHES 2
+
+static struct fusion_F0710A_data fusion_F0710A;
+
+static unsigned short normal_i2c[] = { fusion_F0710A_I2C_SLAVE_ADDR, I2C_CLIENT_END };
+
+static int fusion_F0710A_write_u8(u8 addr, u8 data)
+{
+ return i2c_smbus_write_byte_data(fusion_F0710A.client, addr, data);
+}
+
+static int fusion_F0710A_read_u8(u8 addr)
+{
+ return i2c_smbus_read_byte_data(fusion_F0710A.client, addr);
+}
+
+static int fusion_F0710A_read_block(u8 addr, u8 len, u8 *data)
+{
+ u8 msgbuf0[1] = { addr };
+ u16 slave = fusion_F0710A.client->addr;
+ u16 flags = fusion_F0710A.client->flags;
+ struct i2c_msg msg[2] = { { slave, flags, 1, msgbuf0 },
+ { slave, flags | I2C_M_RD, len, data }
+ };
+
+ return i2c_transfer(fusion_F0710A.client->adapter, msg, ARRAY_SIZE(msg));
+}
+
+static int fusion_F0710A_register_input(void)
+{
+ int ret;
+ struct input_dev *dev;
+
+ dev = fusion_F0710A.input = input_allocate_device();
+ if (dev == NULL)
+ return -ENOMEM;
+
+ dev->name = "fusion_F0710A";
+
+ set_bit(EV_KEY, dev->evbit);
+ set_bit(EV_ABS, dev->evbit);
+ set_bit(EV_SYN, dev->evbit);
+ set_bit(BTN_TOUCH, dev->keybit);
+
+ input_mt_init_slots(dev, MAX_TOUCHES, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_X, 0, fusion_F0710A.info.xres-1, 0, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, fusion_F0710A.info.yres-1, 0, 0);
+ input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
+
+ input_set_abs_params(dev, ABS_X, 0, fusion_F0710A.info.xres-1, 0, 0);
+ input_set_abs_params(dev, ABS_Y, 0, fusion_F0710A.info.yres-1, 0, 0);
+ input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+
+ ret = input_register_device(dev);
+ if (ret < 0)
+ goto bail1;
+
+ return 0;
+
+bail1:
+ input_free_device(dev);
+ return ret;
+}
+
+static void fusion_F0710A_reset(void)
+{
+ /* Generate a 0 => 1 edge explicitly, and wait for startup... */
+ gpio_set_value(fusion_F0710A.gpio_reset, 0);
+ msleep(10);
+ gpio_set_value(fusion_F0710A.gpio_reset, 1);
+ /* Wait for startup (up to 125ms according to datasheet) */
+ msleep(125);
+}
+
+#define WC_RETRY_COUNT 3
+static int fusion_F0710A_write_complete(void)
+{
+ int ret, i;
+
+ for(i=0; i<WC_RETRY_COUNT; i++)
+ {
+ ret = fusion_F0710A_write_u8(fusion_F0710A_SCAN_COMPLETE, 0);
+ if(ret == 0)
+ break;
+ else {
+ dev_warn(&fusion_F0710A.client->dev,
+ "Write complete failed(%d): %d. Resetting controller...\n", i, ret);
+ fusion_F0710A_reset();
+ }
+ }
+
+ return ret;
+}
+
+#define DATA_START fusion_F0710A_DATA_INFO
+#define DATA_END fusion_F0710A_SEC_TIDTS
+#define DATA_LEN (DATA_END - DATA_START + 1)
+#define DATA_OFF(x) ((x) - DATA_START)
+
+static int fusion_F0710A_read_sensor(void)
+{
+ int ret;
+ u8 data[DATA_LEN];
+
+#define DATA(x) (data[DATA_OFF(x)])
+ /* To ensure data coherency, read the sensor with a single transaction. */
+ ret = fusion_F0710A_read_block(DATA_START, DATA_LEN, data);
+ if (ret < 0) {
+ dev_err(&fusion_F0710A.client->dev,
+ "Read block failed: %d\n", ret);
+
+ return ret;
+ }
+
+ fusion_F0710A.f_num = DATA(fusion_F0710A_DATA_INFO)&0x03;
+
+ fusion_F0710A.y1 = DATA(fusion_F0710A_POS_X1_HI) << 8;
+ fusion_F0710A.y1 |= DATA(fusion_F0710A_POS_X1_LO);
+ fusion_F0710A.x1 = DATA(fusion_F0710A_POS_Y1_HI) << 8;
+ fusion_F0710A.x1 |= DATA(fusion_F0710A_POS_Y1_LO);
+ fusion_F0710A.z1 = DATA(fusion_F0710A_FIR_PRESS);
+ fusion_F0710A.tip1 = DATA(fusion_F0710A_FIR_TIDTS)&0x0f;
+ fusion_F0710A.tid1 = (DATA(fusion_F0710A_FIR_TIDTS)&0xf0)>>4;
+
+
+ fusion_F0710A.y2 = DATA(fusion_F0710A_POS_X2_HI) << 8;
+ fusion_F0710A.y2 |= DATA(fusion_F0710A_POS_X2_LO);
+ fusion_F0710A.x2 = DATA(fusion_F0710A_POS_Y2_HI) << 8;
+ fusion_F0710A.x2 |= DATA(fusion_F0710A_POS_Y2_LO);
+ fusion_F0710A.z2 = DATA(fusion_F0710A_SEC_PRESS);
+ fusion_F0710A.tip2 = DATA(fusion_F0710A_SEC_TIDTS)&0x0f;
+ fusion_F0710A.tid2 =(DATA(fusion_F0710A_SEC_TIDTS)&0xf0)>>4;
+#undef DATA
+
+ return 0;
+}
+
+#define val_cut_max(x, max, reverse) \
+do \
+{ \
+ if(x > max) \
+ x = max; \
+ if(reverse) \
+ x = (max) - (x); \
+} \
+while(0)
+
+static void fusion_F0710A_wq(struct work_struct *work)
+{
+ struct input_dev *dev = fusion_F0710A.input;
+
+ if (fusion_F0710A_read_sensor() < 0)
+ goto restore_irq;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "tip1, tid1, x1, y1, z1 (%x,%x,%d,%d,%d); tip2, tid2, x2, y2, z2 (%x,%x,%d,%d,%d)\n",
+ fusion_F0710A.tip1, fusion_F0710A.tid1, fusion_F0710A.x1, fusion_F0710A.y1, fusion_F0710A.z1,
+ fusion_F0710A.tip2, fusion_F0710A.tid2, fusion_F0710A.x2, fusion_F0710A.y2, fusion_F0710A.z2);
+#endif /* DEBUG */
+
+ val_cut_max(fusion_F0710A.x1, fusion_F0710A.info.xres-1, fusion_F0710A.info.xy_reverse);
+ val_cut_max(fusion_F0710A.y1, fusion_F0710A.info.yres-1, fusion_F0710A.info.xy_reverse);
+ val_cut_max(fusion_F0710A.x2, fusion_F0710A.info.xres-1, fusion_F0710A.info.xy_reverse);
+ val_cut_max(fusion_F0710A.y2, fusion_F0710A.info.yres-1, fusion_F0710A.info.xy_reverse);
+
+ if (fusion_F0710A.tid1) {
+ input_mt_slot(dev, fusion_F0710A.tid1 - 1);
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, fusion_F0710A.tip1);
+ if (fusion_F0710A.tip1) {
+ input_report_abs(dev, ABS_MT_POSITION_X, fusion_F0710A.x1);
+ input_report_abs(dev, ABS_MT_POSITION_Y, fusion_F0710A.y1);
+ input_report_abs(dev, ABS_MT_PRESSURE, fusion_F0710A.z1);
+ }
+ }
+
+ if (fusion_F0710A.tid2) {
+ input_mt_slot(dev, fusion_F0710A.tid2 - 1);
+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, fusion_F0710A.tip2);
+ if (fusion_F0710A.tip2) {
+ input_report_abs(dev, ABS_MT_POSITION_X, fusion_F0710A.x2);
+ input_report_abs(dev, ABS_MT_POSITION_Y, fusion_F0710A.y2);
+ input_report_abs(dev, ABS_MT_PRESSURE, fusion_F0710A.z2);
+ }
+ }
+
+ input_mt_report_pointer_emulation(dev, false);
+ input_sync(dev);
+
+restore_irq:
+ enable_irq(fusion_F0710A.client->irq);
+
+ /* Clear fusion_F0710A interrupt */
+ fusion_F0710A_write_complete();
+}
+static DECLARE_WORK(fusion_F0710A_work, fusion_F0710A_wq);
+
+static irqreturn_t fusion_F0710A_interrupt(int irq, void *dev_id)
+{
+ disable_irq_nosync(fusion_F0710A.client->irq);
+
+ queue_work(fusion_F0710A.workq, &fusion_F0710A_work);
+
+ return IRQ_HANDLED;
+}
+
+const static u8* g_ver_product[4] = {
+ "10Z8", "70Z7", "43Z6", ""
+};
+
+static int of_fusion_F0710A_get_pins(struct device_node *np,
+ unsigned int *int_pin, unsigned int *reset_pin)
+{
+ if (of_gpio_count(np) < 2)
+ return -ENODEV;
+
+ *int_pin = of_get_gpio(np, 0);
+ *reset_pin = of_get_gpio(np, 1);
+
+ if (!gpio_is_valid(*int_pin) || !gpio_is_valid(*reset_pin)) {
+ pr_err("%s: invalid GPIO pins, int=%d/reset=%d\n",
+ np->full_name, *int_pin, *reset_pin);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int fusion_F0710A_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct fusion_f0710a_init_data *pdata = i2c->dev.platform_data;
+ int ret;
+ u8 ver_product, ver_id;
+ u32 version;
+
+ if (np != NULL) {
+ pdata = i2c->dev.platform_data =
+ devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+ if (pdata == NULL) {
+ dev_err(&i2c->dev, "No platform data for Fusion driver\n");
+ return -ENODEV;
+ }
+ /* the dtb did the pinmuxing for us */
+ pdata->pinmux_fusion_pins = NULL;
+ ret = of_fusion_F0710A_get_pins(i2c->dev.of_node,
+ &pdata->gpio_int, &pdata->gpio_reset);
+ if (ret)
+ return ret;
+ }
+ else if (pdata == NULL) {
+ dev_err(&i2c->dev, "No platform data for Fusion driver\n");
+ return -ENODEV;
+ }
+
+ /* Request pinmuxing, if necessary */
+ if (pdata->pinmux_fusion_pins != NULL) {
+ ret = pdata->pinmux_fusion_pins();
+ if (ret < 0) {
+ dev_err(&i2c->dev, "muxing GPIOs failed\n");
+ return -ENODEV;
+ }
+ }
+
+ if ((gpio_request(pdata->gpio_int, "Fusion pen down interrupt") == 0) &&
+ (gpio_direction_input(pdata->gpio_int) == 0)) {
+ gpio_export(pdata->gpio_int, 0);
+ } else {
+ dev_warn(&i2c->dev, "Could not obtain GPIO for Fusion pen down\n");
+ return -ENODEV;
+ }
+
+ if ((gpio_request(pdata->gpio_reset, "Fusion reset") == 0) &&
+ (gpio_direction_output(pdata->gpio_reset, 1) == 0)) {
+ fusion_F0710A.gpio_reset = pdata->gpio_reset;
+ fusion_F0710A_reset();
+ gpio_export(pdata->gpio_reset, 0);
+ } else {
+ dev_warn(&i2c->dev, "Could not obtain GPIO for Fusion reset\n");
+ ret = -ENODEV;
+ goto bail0;
+ }
+
+ /* Use Pen Down GPIO as sampling interrupt */
+ i2c->irq = gpio_to_irq(pdata->gpio_int);
+ irq_set_irq_type(i2c->irq, IRQ_TYPE_LEVEL_HIGH);
+
+ if(!i2c->irq)
+ {
+ dev_err(&i2c->dev, "fusion_F0710A irq < 0 \n");
+ ret = -ENOMEM;
+ goto bail1;
+ }
+
+ /* Attach the I2C client */
+ fusion_F0710A.client = i2c;
+ i2c_set_clientdata(i2c, &fusion_F0710A);
+
+ dev_info(&i2c->dev, "Touchscreen registered with bus id (%d) with slave address 0x%x\n",
+ i2c_adapter_id(fusion_F0710A.client->adapter), fusion_F0710A.client->addr);
+
+ /* Read out a lot of registers */
+ ret = fusion_F0710A_read_u8(fusion_F0710A_VIESION_INFO_LO);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "query failed: %d\n", ret);
+ goto bail1;
+ }
+ ver_product = (((u8)ret) & 0xc0) >> 6;
+ version = (10 + ((((u32)ret)&0x30) >> 4)) * 100000;
+ version += (((u32)ret)&0xf) * 1000;
+ /* Read out a lot of registers */
+ ret = fusion_F0710A_read_u8(fusion_F0710A_VIESION_INFO);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "query failed: %d\n", ret);
+ goto bail1;
+ }
+ ver_id = ((u8)(ret) & 0x6) >> 1;
+ version += ((((u32)ret) & 0xf8) >> 3) * 10;
+ version += (((u32)ret) & 0x1) + 1; /* 0 is build 1, 1 is build 2 */
+ dev_info(&i2c->dev, "version product %s(%d)\n", g_ver_product[ver_product] ,ver_product);
+ dev_info(&i2c->dev, "version id %s(%d)\n", ver_id ? "1.4" : "1.0", ver_id);
+ dev_info(&i2c->dev, "version series (%d)\n", version);
+
+ switch(ver_product)
+ {
+ case fusion_F0710A_VIESION_07: /* 7 inch */
+ fusion_F0710A.info.xres = fusion_F0710A07_XMAX;
+ fusion_F0710A.info.yres = fusion_F0710A07_YMAX;
+ fusion_F0710A.info.xy_reverse = fusion_F0710A07_REV;
+ break;
+ case fusion_F0710A_VIESION_43: /* 4.3 inch */
+ fusion_F0710A.info.xres = fusion_F0710A43_XMAX;
+ fusion_F0710A.info.yres = fusion_F0710A43_YMAX;
+ fusion_F0710A.info.xy_reverse = fusion_F0710A43_REV;
+ break;
+ default: /* fusion_F0710A_VIESION_10 10 inch */
+ fusion_F0710A.info.xres = fusion_F0710A10_XMAX;
+ fusion_F0710A.info.yres = fusion_F0710A10_YMAX;
+ fusion_F0710A.info.xy_reverse = fusion_F0710A10_REV;
+ break;
+ }
+
+ /* Register the input device. */
+ ret = fusion_F0710A_register_input();
+ if (ret < 0) {
+ dev_err(&i2c->dev, "can't register input: %d\n", ret);
+ goto bail1;
+ }
+
+ /* Create a worker thread */
+ fusion_F0710A.workq = create_singlethread_workqueue(DRV_NAME);
+ if (fusion_F0710A.workq == NULL) {
+ dev_err(&i2c->dev, "can't create work queue\n");
+ ret = -ENOMEM;
+ goto bail2;
+ }
+
+
+ /* Register for the interrupt and enable it. Our handler will
+ * start getting invoked after this call. */
+ ret = request_irq(i2c->irq, fusion_F0710A_interrupt, IRQF_TRIGGER_RISING,
+ i2c->name, &fusion_F0710A);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "can't get irq %d: %d\n", i2c->irq, ret);
+ goto bail3;
+ }
+ /* clear the irq first */
+ ret = fusion_F0710A_write_u8(fusion_F0710A_SCAN_COMPLETE, 0);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Clear irq failed: %d\n", ret);
+ goto bail4;
+ }
+
+ return 0;
+
+bail4:
+ free_irq(i2c->irq, &fusion_F0710A);
+
+bail3:
+ destroy_workqueue(fusion_F0710A.workq);
+ fusion_F0710A.workq = NULL;
+
+bail2:
+ input_unregister_device(fusion_F0710A.input);
+bail1:
+ gpio_free(pdata->gpio_reset);
+bail0:
+ gpio_free(pdata->gpio_int);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int fusion_F0710A_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+ disable_irq(i2c->irq);
+ flush_workqueue(fusion_F0710A.workq);
+
+ return 0;
+}
+
+static int fusion_F0710A_resume(struct device *dev)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+ enable_irq(i2c->irq);
+
+ return 0;
+}
+#endif
+
+static int fusion_F0710A_remove(struct i2c_client *i2c)
+{
+ struct fusion_f0710a_init_data *pdata = i2c->dev.platform_data;
+
+ gpio_free(pdata->gpio_int);
+ gpio_free(pdata->gpio_reset);
+ destroy_workqueue(fusion_F0710A.workq);
+ free_irq(i2c->irq, &fusion_F0710A);
+ input_unregister_device(fusion_F0710A.input);
+ i2c_set_clientdata(i2c, NULL);
+
+ dev_info(&i2c->dev, "driver removed\n");
+
+ return 0;
+}
+
+static struct i2c_device_id fusion_F0710A_id[] = {
+ {"fusion_F0710A", 0},
+ {},
+};
+
+
+static const struct of_device_id fusion_F0710A_dt_ids[] = {
+ {
+ .compatible = "touchrevolution,fusion-f0710a",
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, fusion_F0710A_dt_ids);
+
+static const struct dev_pm_ops fusion_F0710A_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(fusion_F0710A_suspend, fusion_F0710A_resume)
+};
+
+static struct i2c_driver fusion_F0710A_i2c_drv = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .pm = &fusion_F0710A_pm_ops,
+ .of_match_table = fusion_F0710A_dt_ids,
+ },
+ .probe = fusion_F0710A_probe,
+ .remove = fusion_F0710A_remove,
+ .id_table = fusion_F0710A_id,
+ .address_list = normal_i2c,
+};
+
+static int __init fusion_F0710A_init( void )
+{
+ int ret;
+
+ memset(&fusion_F0710A, 0, sizeof(fusion_F0710A));
+
+ /* Probe for fusion_F0710A on I2C. */
+ ret = i2c_add_driver(&fusion_F0710A_i2c_drv);
+ if (ret < 0) {
+ printk(KERN_WARNING DRV_NAME " can't add i2c driver: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static void __exit fusion_F0710A_exit( void )
+{
+ i2c_del_driver(&fusion_F0710A_i2c_drv);
+}
+module_init(fusion_F0710A_init);
+module_exit(fusion_F0710A_exit);
+
+MODULE_DESCRIPTION("fusion_F0710A Touchscreen Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/input/touchscreen/fusion_F0710A.h b/drivers/input/touchscreen/fusion_F0710A.h
new file mode 100644
index 000000000000..3e5af9e72b78
--- /dev/null
+++ b/drivers/input/touchscreen/fusion_F0710A.h
@@ -0,0 +1,88 @@
+/*
+ * "fusion_F0710A" touchscreen driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* I2C slave address */
+#define fusion_F0710A_I2C_SLAVE_ADDR 0x10
+
+/* I2C registers */
+#define fusion_F0710A_DATA_INFO 0x00
+
+/* First Point*/
+#define fusion_F0710A_POS_X1_HI 0x01 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_X1_LO 0x02 /* 16-bit register, LSB */
+#define fusion_F0710A_POS_Y1_HI 0x03 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_Y1_LO 0x04 /* 16-bit register, LSB */
+#define fusion_F0710A_FIR_PRESS 0X05
+#define fusion_F0710A_FIR_TIDTS 0X06
+
+/* Second Point */
+#define fusion_F0710A_POS_X2_HI 0x07 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_X2_LO 0x08 /* 16-bit register, LSB */
+#define fusion_F0710A_POS_Y2_HI 0x09 /* 16-bit register, MSB */
+#define fusion_F0710A_POS_Y2_LO 0x0A /* 16-bit register, LSB */
+#define fusion_F0710A_SEC_PRESS 0x0B
+#define fusion_F0710A_SEC_TIDTS 0x0C
+
+#define fusion_F0710A_VIESION_INFO_LO 0X0E
+#define fusion_F0710A_VIESION_INFO 0X0F
+
+#define fusion_F0710A_RESET 0x10
+#define fusion_F0710A_SCAN_COMPLETE 0x11
+
+
+#define fusion_F0710A_VIESION_10 0
+#define fusion_F0710A_VIESION_07 1
+#define fusion_F0710A_VIESION_43 2
+
+/* fusion_F0710A 10 inch panel */
+#define fusion_F0710A10_XMAX 2275
+#define fusion_F0710A10_YMAX 1275
+#define fusion_F0710A10_REV 1
+
+/* fusion_F0710A 7 inch panel */
+#define fusion_F0710A07_XMAX 1500
+#define fusion_F0710A07_YMAX 900
+#define fusion_F0710A07_REV 0
+
+/* fusion_F0710A 4.3 inch panel */
+#define fusion_F0710A43_XMAX 900
+#define fusion_F0710A43_YMAX 500
+#define fusion_F0710A43_REV 0
+
+#define fusion_F0710A_SAVE_PT1 0x1
+#define fusion_F0710A_SAVE_PT2 0x2
+
+
+
+/* fusion_F0710A touch screen information */
+struct fusion_F0710A_info {
+ int xres; /* x resolution */
+ int yres; /* y resolution */
+ int xy_reverse; /* if need reverse in the x,y value x=xres-1-x, y=yres-1-y*/
+};
+
+struct fusion_F0710A_data {
+ struct fusion_F0710A_info info;
+ struct i2c_client *client;
+ struct workqueue_struct *workq;
+ struct input_dev *input;
+ int gpio_reset;
+ u16 x1;
+ u16 y1;
+ u8 z1;
+ u8 tip1;
+ u8 tid1;
+ u16 x2;
+ u16 y2;
+ u8 z2;
+ u8 tip2;
+ u8 tid2;
+ u8 f_num;
+ u8 save_points;
+};
+
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c
index 2a78e27b4495..05674e0e233f 100644
--- a/drivers/input/touchscreen/stmpe-ts.c
+++ b/drivers/input/touchscreen/stmpe-ts.c
@@ -49,17 +49,6 @@
#define STMPE_IRQ_TOUCH_DET 0
-#define SAMPLE_TIME(x) ((x & 0xf) << 4)
-#define MOD_12B(x) ((x & 0x1) << 3)
-#define REF_SEL(x) ((x & 0x1) << 1)
-#define ADC_FREQ(x) (x & 0x3)
-#define AVE_CTRL(x) ((x & 0x3) << 6)
-#define DET_DELAY(x) ((x & 0x7) << 3)
-#define SETTLING(x) (x & 0x7)
-#define FRACTION_Z(x) (x & 0x7)
-#define I_DRIVE(x) (x & 0x1)
-#define OP_MODE(x) ((x & 0x7) << 1)
-
#define STMPE_TS_NAME "stmpe-ts"
#define XY_MASK 0xfff