Thread (1 message) 1 message, 1 author, 2012-08-07
DORMANTno replies

[PATCH 4/4] Input: cyttsp4 - I2C driver for Cypress TMA4XX touchscreen devices

From: Ferruh Yigit <hidden>
Date: 2012-08-07 13:15:24
Also in: lkml
Subsystem: cyttsp touchscreen driver, input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers: Linus Walleij, Dmitry Torokhov, Linus Torvalds

From: Ferruh YIGIT <redacted>

Cypress TrueTouch(tm) Standard Product controllers, Generation4 devices,
I2C adapter module.

This driver adds communication support with TTSP controller using I2C
bus.

Signed-off-by: Ferruh YIGIT <redacted>
---
 drivers/input/touchscreen/Kconfig       |   13 ++
 drivers/input/touchscreen/Makefile      |    3 +
 drivers/input/touchscreen/cyttsp4_i2c.c |  246 +++++++++++++++++++++++++++++++
 drivers/input/touchscreen/cyttsp4_i2c.h |   35 +++++
 4 files changed, 297 insertions(+)
 create mode 100644 drivers/input/touchscreen/cyttsp4_i2c.c
 create mode 100644 drivers/input/touchscreen/cyttsp4_i2c.h
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 57a38f8..58f5d0b 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -192,6 +192,7 @@ config TOUCHSCREEN_CYPRESS_CYTTSP4
        tristate "Cypress TrueTouch Gen4 Touchscreen Driver"
        default m
        select CYPRESS_CYTTSP4_BUS
+       select TOUCHSCREEN_CYPRESS_CYTTSP4_I2C
        select TOUCHSCREEN_CYPRESS_CYTTSP4_MT_B
        help
          Core driver for Cypress TrueTouch(tm) Standard Product
@@ -223,6 +224,18 @@ config TOUCHSCREEN_CYPRESS_CYTTSP4_VDEBUG

          Say Y here to enable verbose debug output.

+config TOUCHSCREEN_CYPRESS_CYTTSP4_I2C
+       tristate "Cypress TrueTouch Gen4 I2C"
+       depends on TOUCHSCREEN_CYPRESS_CYTTSP4
+       select I2C
+       default m
+       help
+         Cypress TrueTouch(tm) Standard Product Generation4
+         I2C bus interface.
+
+         Say Y here to enable I2C bus interface to TTSP
+         touchscreen controller.
+
 config TOUCHSCREEN_CYPRESS_CYTTSP4_MT_B
        tristate "Cypress TrueTouch Gen4 MultiTouch Protocol B"
        depends on TOUCHSCREEN_CYPRESS_CYTTSP4
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 8feae16..c5e5fc6 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -75,11 +75,13 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)   += w90p910_ts.o
 obj-$(CONFIG_TOUCHSCREEN_TPS6507X)     += tps6507x-ts.o
 obj-$(CONFIG_CYPRESS_CYTTSP4_BUS) += cyttsp4_bus.o
 obj-$(CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP4)      += cyttsp4_core.o
+obj-$(CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP4_I2C)  += cyttsp4_i2c.o
 obj-$(CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP4_MT_B) += cyttsp4_mt_b.o
 cyttsp4_mt_b-y := cyttsp4_mtb.o cyttsp4_mt_common.o
 ifeq ($(CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP4_DEBUG),y)
 CFLAGS_cyttsp4_core.o += -DDEBUG
 CFLAGS_cyttsp4_bus.o += -DDEBUG
+CFLAGS_cyttsp4_i2c.o += -DDEBUG
 CFLAGS_cyttsp4_mtb.o += -DDEBUG
 CFLAGS_cyttsp4_mt_b.o += -DDEBUG
 CFLAGS_cyttsp4_mt_common.o += -DDEBUG
@@ -88,6 +90,7 @@ endif
 ifeq ($(CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP4_VDEBUG),y)
 CFLAGS_cyttsp4_core.o += -DVERBOSE_DEBUG
 CFLAGS_cyttsp4_bus.o += -DVERBOSE_DEBUG
+CFLAGS_cyttsp4_i2c.o += -DVERBOSE_DEBUG
 CFLAGS_cyttsp4_mtb.o += -DVERBOSE_DEBUG
 CFLAGS_cyttsp4_mt_b.o += -DVERBOSE_DEBUG
 CFLAGS_cyttsp4_mt_common.o += -DVERBOSE_DEBUG
diff --git a/drivers/input/touchscreen/cyttsp4_i2c.c b/drivers/input/touchscreen/cyttsp4_i2c.c
new file mode 100644
index 0000000..e330219
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp4_i2c.c
@@ -0,0 +1,246 @@
+/*
+ * cyttsp4_i2c.c
+ * Cypress TrueTouch(TM) Standard Product V4 I2C Driver module.
+ * For use with Cypress Txx4xx parts.
+ * Supported parts include:
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2012 Cypress Semiconductor
+ * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
+ *
+ * Author: Aleksej Makarov <aleksej.makarov@sonyericsson.com>
+ * Modified by: Cypress Semiconductor for test with device
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#include <linux/cyttsp4_bus.h>
+#include "cyttsp4_i2c.h"
+
+#include <linux/delay.h>
+#include <linux/hrtimer.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#define CY_I2C_DATA_SIZE  (3 * 256)
+
+struct cyttsp4_i2c {
+       struct i2c_client *client;
+       u8 wr_buf[CY_I2C_DATA_SIZE];
+       struct hrtimer timer;
+       struct mutex lock;
+       atomic_t timeout;
+};
+
+static int cyttsp4_i2c_read_block_data(struct cyttsp4_i2c *ts_i2c, u8 addr,
+       size_t length, void *values)
+{
+       int rc;
+
+       /* write addr */
+       rc = i2c_master_send(ts_i2c->client, &addr, sizeof(addr));
+       if (rc < 0)
+               return rc;
+       else if (rc != sizeof(addr))
+               return -EIO;
+
+       /* read data */
+       rc = i2c_master_recv(ts_i2c->client, values, length);
+
+       return (rc < 0) ? rc : rc != length ? -EIO : 0;
+}
+
+static int cyttsp4_i2c_write_block_data(struct cyttsp4_i2c *ts_i2c, u8 addr,
+       size_t length, const void *values)
+{
+       int rc;
+
+       if (sizeof(ts_i2c->wr_buf) < (length + 1))
+               return -ENOMEM;
+
+       ts_i2c->wr_buf[0] = addr;
+       memcpy(&ts_i2c->wr_buf[1], values, length);
+       length += 1;
+
+       /* write data */
+       rc = i2c_master_send(ts_i2c->client, ts_i2c->wr_buf, length);
+
+       return (rc < 0) ? rc : rc != length ? -EIO : 0;
+}
+
+static int cyttsp4_i2c_write(struct cyttsp4_adapter *adap, u8 addr,
+       const void *buf, int size)
+{
+       struct cyttsp4_i2c *ts = dev_get_drvdata(adap->dev);
+       int rc;
+
+       pm_runtime_get_noresume(adap->dev);
+       mutex_lock(&ts->lock);
+       rc = cyttsp4_i2c_write_block_data(ts, addr, size, buf);
+       mutex_unlock(&ts->lock);
+       pm_runtime_put_noidle(adap->dev);
+
+       return rc;
+}
+
+static int cyttsp4_i2c_read(struct cyttsp4_adapter *adap, u8 addr,
+       void *buf, int size)
+{
+       struct cyttsp4_i2c *ts = dev_get_drvdata(adap->dev);
+       int rc;
+
+       pm_runtime_get_noresume(adap->dev);
+       mutex_lock(&ts->lock);
+       rc = cyttsp4_i2c_read_block_data(ts, addr, size, buf);
+       mutex_unlock(&ts->lock);
+       pm_runtime_put_noidle(adap->dev);
+
+       return rc;
+}
+
+static struct cyttsp4_ops ops = {
+       .write = cyttsp4_i2c_write,
+       .read = cyttsp4_i2c_read,
+};
+
+static int __devinit cyttsp4_i2c_probe(struct i2c_client *client,
+       const struct i2c_device_id *i2c_id)
+{
+       struct cyttsp4_i2c *ts_i2c;
+       struct device *dev = &client->dev;
+       char const *adap_id = dev_get_platdata(dev);
+       char const *id;
+       int rc;
+
+       dev_info(dev, "%s: Starting %s probe...\n", __func__, CYTTSP4_I2C_NAME);
+
+       dev_dbg(dev, "%s: debug on\n", __func__);
+       dev_vdbg(dev, "%s: verbose debug on\n", __func__);
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               dev_err(dev, "%s: fail check I2C functionality\n", __func__);
+               rc = -EIO;
+               goto error_alloc_data_failed;
+       }
+
+       ts_i2c = kzalloc(sizeof(struct cyttsp4_i2c), GFP_KERNEL);
+       if (ts_i2c == NULL) {
+               dev_err(dev, "%s: Error, kzalloc.\n", __func__);
+               rc = -ENOMEM;
+               goto error_alloc_data_failed;
+       }
+
+       mutex_init(&ts_i2c->lock);
+       ts_i2c->client = client;
+       client->dev.bus = &i2c_bus_type;
+       i2c_set_clientdata(client, ts_i2c);
+       dev_set_drvdata(&client->dev, ts_i2c);
+
+       if (adap_id)
+               id = adap_id;
+       else
+               id = CYTTSP4_I2C_NAME;
+
+       dev_dbg(dev, "%s: add adap='%s' (CYTTSP4_I2C_NAME=%s)\n", __func__, id,
+               CYTTSP4_I2C_NAME);
+
+       pm_runtime_enable(&client->dev);
+
+       rc = cyttsp4_add_adapter(id, &ops, dev);
+       if (rc) {
+               dev_err(dev, "%s: Error on probe %s\n", __func__,
+                       CYTTSP4_I2C_NAME);
+               goto add_adapter_err;
+       }
+
+       dev_info(dev, "%s: Successful probe %s\n", __func__, CYTTSP4_I2C_NAME);
+
+       return 0;
+
+add_adapter_err:
+       pm_runtime_disable(&client->dev);
+       dev_set_drvdata(&client->dev, NULL);
+       i2c_set_clientdata(client, NULL);
+       kfree(ts_i2c);
+error_alloc_data_failed:
+       return rc;
+}
+
+/* registered in driver struct */
+static int __devexit cyttsp4_i2c_remove(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       struct cyttsp4_i2c *ts_i2c = dev_get_drvdata(dev);
+       char const *adap_id = dev_get_platdata(dev);
+       char const *id;
+
+       if (adap_id)
+               id = adap_id;
+       else
+               id = CYTTSP4_I2C_NAME;
+
+       dev_info(dev, "%s\n", __func__);
+       cyttsp4_del_adapter(id);
+       pm_runtime_disable(&client->dev);
+       dev_set_drvdata(&client->dev, NULL);
+       i2c_set_clientdata(client, NULL);
+       kfree(ts_i2c);
+       return 0;
+}
+
+static const struct i2c_device_id cyttsp4_i2c_id[] = {
+       { CYTTSP4_I2C_NAME, 0 },  { }
+};
+
+static struct i2c_driver cyttsp4_i2c_driver = {
+       .driver = {
+               .name = CYTTSP4_I2C_NAME,
+               .owner = THIS_MODULE,
+       },
+       .probe = cyttsp4_i2c_probe,
+       .remove = __devexit_p(cyttsp4_i2c_remove),
+       .id_table = cyttsp4_i2c_id,
+};
+
+static int __init cyttsp4_i2c_init(void)
+{
+       int rc = i2c_add_driver(&cyttsp4_i2c_driver);
+
+       pr_info("%s: Cypress TTSP I2C Touchscreen Driver (Built %s @ %s) rc=%d\n",
+                __func__, __DATE__, __TIME__, rc);
+       return rc;
+}
+module_init(cyttsp4_i2c_init);
+
+static void __exit cyttsp4_i2c_exit(void)
+{
+       i2c_del_driver(&cyttsp4_i2c_driver);
+       pr_info("%s: module exit\n", __func__);
+}
+module_exit(cyttsp4_i2c_exit);
+
+MODULE_ALIAS(CYTTSP4_I2C_NAME);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver");
+MODULE_AUTHOR("Cypress");
+MODULE_DEVICE_TABLE(i2c, cyttsp4_i2c_id);
diff --git a/drivers/input/touchscreen/cyttsp4_i2c.h b/drivers/input/touchscreen/cyttsp4_i2c.h
new file mode 100644
index 0000000..94fd104
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp4_i2c.h
@@ -0,0 +1,35 @@
+/*
+ * cyttsp4_i2c.h
+ * Cypress TrueTouch(TM) Standard Product V4 I2C driver module.
+ * For use with Cypress Txx4xx parts.
+ * Supported parts include:
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2012 Cypress Semiconductor
+ * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#ifndef _LINUX_CYTTSP4_I2C_H
+#define _LINUX_CYTTSP4_I2C_H
+
+#define CYTTSP4_I2C_NAME "cyttsp4_i2c_adapter"
+
+#endif /* _LINUX_CYTTSP4_I2C_H */
--
1.7.9.5


This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help