From: Ferruh Yigit <fery@cypress.com>
To: Dan Carpenter <dan.carpenter@oracle.com>,
Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: ttdrivers@cypress.com,
Javier Martinez Canillas <javier@dowhile0.org>,
linux-input@vger.kernel.org, Ferruh Yigit <fery@cypress.com>
Subject: [PATCH] Input: cyttsp4 - use 16bit address for I2C/SPI communication
Date: Wed, 3 Jul 2013 23:36:20 +0300 [thread overview]
Message-ID: <1372883780-29851-1-git-send-email-fery@cypress.com> (raw)
In-Reply-To: <20130703135248.GV5714@mwanda>
In TSG4, register map is 512bytes long and to access all of it,
one bit from address byte is used (which bit to use differs for
I2C and SPI);
Since common code used for TSG3 and TSG4 for I2C, this parameter
wrongly used as u8. TSG3 does not access beyond 255 bytes
but TSG4 may.
Signed-off-by: Ferruh Yigit <fery@cypress.com>
Tested-on: TMA3XX DVB && TMA4XX DVB
---
drivers/input/touchscreen/cyttsp4_core.h | 12 +++++-----
drivers/input/touchscreen/cyttsp4_spi.c | 20 ++++++++---------
drivers/input/touchscreen/cyttsp_core.h | 8 +++----
drivers/input/touchscreen/cyttsp_i2c_common.c | 30 ++++++++++++++++++-------
drivers/input/touchscreen/cyttsp_spi.c | 6 ++---
5 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/drivers/input/touchscreen/cyttsp4_core.h b/drivers/input/touchscreen/cyttsp4_core.h
index 86a2543..8e0d4d4 100644
--- a/drivers/input/touchscreen/cyttsp4_core.h
+++ b/drivers/input/touchscreen/cyttsp4_core.h
@@ -369,9 +369,9 @@ struct cyttsp4 {
struct cyttsp4_bus_ops {
u16 bustype;
- int (*write)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length,
+ int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
const void *values);
- int (*read)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length,
+ int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
void *values);
};
@@ -448,13 +448,13 @@ enum cyttsp4_event_id {
/* y-axis, 0:origin is on top side of panel, 1: bottom */
#define CY_PCFG_ORIGIN_Y_MASK 0x80
-static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u8 addr, int size,
+static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u16 addr, int size,
void *buf)
{
return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf);
}
-static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u8 addr, int size,
+static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u16 addr, int size,
const void *buf)
{
return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf);
@@ -463,9 +463,9 @@ static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u8 addr, int size,
extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops,
struct device *dev, u16 irq, size_t xfer_buf_size);
extern int cyttsp4_remove(struct cyttsp4 *ts);
-int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u8 addr,
+int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
u8 length, const void *values);
-int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u8 addr,
+int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
u8 length, void *values);
extern const struct dev_pm_ops cyttsp4_pm_ops;
diff --git a/drivers/input/touchscreen/cyttsp4_spi.c b/drivers/input/touchscreen/cyttsp4_spi.c
index f8f891b..a71e114 100644
--- a/drivers/input/touchscreen/cyttsp4_spi.c
+++ b/drivers/input/touchscreen/cyttsp4_spi.c
@@ -44,7 +44,7 @@
#define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
- u8 op, u8 reg, u8 *buf, int length)
+ u8 op, u16 reg, u8 *buf, int length)
{
struct spi_device *spi = to_spi_device(dev);
struct spi_message msg;
@@ -63,14 +63,12 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE);
memset(rd_buf, 0, CY_SPI_CMD_BYTES);
- if (reg > 255)
- wr_buf[0] = op + CY_SPI_A8_BIT;
- else
- wr_buf[0] = op;
- if (op == CY_SPI_WR_OP)
- wr_buf[1] = reg % 256;
- if (op == CY_SPI_WR_OP && length > 0)
- memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
+ wr_buf[0] = op + (((reg >> 8) & 0x1) ? CY_SPI_A8_BIT : 0);
+ if (op == CY_SPI_WR_OP) {
+ wr_buf[1] = reg & 0xFF;
+ if (length > 0)
+ memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
+ }
memset(xfer, 0, sizeof(xfer));
spi_message_init(&msg);
@@ -130,7 +128,7 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
}
static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
- u8 addr, u8 length, void *data)
+ u16 addr, u8 length, void *data)
{
int rc;
@@ -143,7 +141,7 @@ static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
}
static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf,
- u8 addr, u8 length, const void *data)
+ u16 addr, u8 length, const void *data)
{
return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
length);
diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h
index 0cf564a..0707411 100644
--- a/drivers/input/touchscreen/cyttsp_core.h
+++ b/drivers/input/touchscreen/cyttsp_core.h
@@ -112,9 +112,9 @@ struct cyttsp;
struct cyttsp_bus_ops {
u16 bustype;
- int (*write)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length,
+ int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
const void *values);
- int (*read)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length,
+ int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
void *values);
};
@@ -145,9 +145,9 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
struct device *dev, int irq, size_t xfer_buf_size);
void cyttsp_remove(struct cyttsp *ts);
-int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u8 addr,
+int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
u8 length, const void *values);
-int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u8 addr,
+int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
u8 length, void *values);
extern const struct dev_pm_ops cyttsp_pm_ops;
diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c
index 07c553f..1d7b6f1 100644
--- a/drivers/input/touchscreen/cyttsp_i2c_common.c
+++ b/drivers/input/touchscreen/cyttsp_i2c_common.c
@@ -32,18 +32,20 @@
#include <linux/types.h>
int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf,
- u8 addr, u8 length, void *values)
+ u16 addr, u8 length, void *values)
{
struct i2c_client *client = to_i2c_client(dev);
+ u8 client_addr = client->addr | ((addr >> 8) & 0x1);
+ u8 addr_lo = addr & 0xFF;
struct i2c_msg msgs[] = {
{
- .addr = client->addr,
+ .addr = client_addr,
.flags = 0,
.len = 1,
- .buf = &addr,
+ .buf = &addr_lo,
},
{
- .addr = client->addr,
+ .addr = client_addr,
.flags = I2C_M_RD,
.len = length,
.buf = values,
@@ -60,17 +62,29 @@ int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf,
EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data);
int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf,
- u8 addr, u8 length, const void *values)
+ u16 addr, u8 length, const void *values)
{
struct i2c_client *client = to_i2c_client(dev);
+ u8 client_addr = client->addr | ((addr >> 8) & 0x1);
+ u8 addr_lo = addr & 0xFF;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client_addr,
+ .flags = 0,
+ .len = length + 1,
+ .buf = xfer_buf,
+ },
+ };
int retval;
- xfer_buf[0] = addr;
+ xfer_buf[0] = addr_lo;
memcpy(&xfer_buf[1], values, length);
- retval = i2c_master_send(client, xfer_buf, length + 1);
+ retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (retval < 0)
+ return retval;
- return retval < 0 ? retval : 0;
+ return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
}
EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data);
diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c
index 1df6253..4728bcb 100644
--- a/drivers/input/touchscreen/cyttsp_spi.c
+++ b/drivers/input/touchscreen/cyttsp_spi.c
@@ -41,7 +41,7 @@
#define CY_SPI_BITS_PER_WORD 8
static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
- u8 op, u8 reg, u8 *buf, int length)
+ u8 op, u16 reg, u8 *buf, int length)
{
struct spi_device *spi = to_spi_device(dev);
struct spi_message msg;
@@ -126,14 +126,14 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
}
static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
- u8 addr, u8 length, void *data)
+ u16 addr, u8 length, void *data)
{
return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data,
length);
}
static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf,
- u8 addr, u8 length, const void *data)
+ u16 addr, u8 length, const void *data)
{
return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
length);
--
1.7.9.5
next prev parent reply other threads:[~2013-07-03 20:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-02 21:47 Input: cyttsp4 - SPI driver for Cypress TMA4XX touchscreen devices Dan Carpenter
2013-07-03 13:24 ` Ferruh Yigit
2013-07-03 13:52 ` Dan Carpenter
2013-07-03 20:36 ` Ferruh Yigit [this message]
2013-07-04 12:25 ` [PATCH] Input: cyttsp4 - use 16bit address for I2C/SPI communication Javier Martinez Canillas
2013-07-07 5:08 ` Dmitry Torokhov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1372883780-29851-1-git-send-email-fery@cypress.com \
--to=fery@cypress.com \
--cc=dan.carpenter@oracle.com \
--cc=dmitry.torokhov@gmail.com \
--cc=javier@dowhile0.org \
--cc=linux-input@vger.kernel.org \
--cc=ttdrivers@cypress.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).