Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754740Ab2HGNPY (ORCPT ); Tue, 7 Aug 2012 09:15:24 -0400 Received: from relay.ihostexchange.net ([66.46.182.57]:12749 "EHLO relay.ihostexchange.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753661Ab2HGNPS convert rfc822-to-8bit (ORCPT ); Tue, 7 Aug 2012 09:15:18 -0400 From: Ferruh Yigit To: Dmitry Torokhov CC: Kevin McNeely , Ferruh YIGIT , Javier Martinez Canillas , Henrik Rydberg , Shawn Landden , Ashish Jangam , Olivier Sobrie , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] Input: cyttsp4 - I2C driver for Cypress TMA4XX touchscreen devices Date: Tue, 7 Aug 2012 16:10:47 +0300 Message-ID: <1344345051-30578-1-git-send-email-fery@cypress.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12481 Lines: 378 From: Ferruh YIGIT 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 --- 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 + * 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 + * + */ + +#include +#include "cyttsp4_i2c.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * + */ + +#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. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/