Input: cyttsp4 - use 16bit address for I2C/SPI communication
authorFerruh Yigit <fery@cypress.com>
Thu, 4 Jul 2013 21:02:57 +0000 (14:02 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sun, 7 Jul 2013 04:57:06 +0000 (21:57 -0700)
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.

Tested-on:TMA3XX DVB && TMA4XX DVB

Signed-off-by: Ferruh Yigit <fery@cypress.com>
Acked-by: Javier Martinez Canillas <javier@dowhile0.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/cyttsp4_core.h
drivers/input/touchscreen/cyttsp4_spi.c
drivers/input/touchscreen/cyttsp_core.h
drivers/input/touchscreen/cyttsp_i2c_common.c
drivers/input/touchscreen/cyttsp_spi.c

index 86a254354136e96eede0d308c8707e169b2a1652..8e0d4d490b20ecb68540390b0e9a4dddae67652a 100644 (file)
@@ -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;
 
index f8f891bead34759d83759fa55374e4b22fd003b7..a71e1141d6386f9546fe32e5496437e72e393885 100644 (file)
@@ -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);
index 0cf564a79fb55466d83318b01248f76fbc1bcfee..07074110a902136eeb53dad02260302d7f5637c9 100644 (file)
@@ -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;
 
index 07c553fbcef2a4ecf77018afa5fe829f1116d20c..1d7b6f154168cc213e75ea64ee4f973782d0a108 100644 (file)
 #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);
 
index 1df625337b84c53557587441934d8e157bbdc79c..4728bcb1916c37f9a3ce379689d3dc7e8101a8a0 100644 (file)
@@ -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);