Input: cyttsp4 - use 16bit address for I2C/SPI communication
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>
This commit is contained in:
Родитель
57961e3ba7
Коммит
62f548d0c2
|
@ -369,9 +369,9 @@ struct cyttsp4 {
|
||||||
|
|
||||||
struct cyttsp4_bus_ops {
|
struct cyttsp4_bus_ops {
|
||||||
u16 bustype;
|
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);
|
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);
|
void *values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -448,13 +448,13 @@ enum cyttsp4_event_id {
|
||||||
/* y-axis, 0:origin is on top side of panel, 1: bottom */
|
/* y-axis, 0:origin is on top side of panel, 1: bottom */
|
||||||
#define CY_PCFG_ORIGIN_Y_MASK 0x80
|
#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)
|
void *buf)
|
||||||
{
|
{
|
||||||
return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, 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)
|
const void *buf)
|
||||||
{
|
{
|
||||||
return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, 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,
|
extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops,
|
||||||
struct device *dev, u16 irq, size_t xfer_buf_size);
|
struct device *dev, u16 irq, size_t xfer_buf_size);
|
||||||
extern int cyttsp4_remove(struct cyttsp4 *ts);
|
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);
|
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);
|
u8 length, void *values);
|
||||||
extern const struct dev_pm_ops cyttsp4_pm_ops;
|
extern const struct dev_pm_ops cyttsp4_pm_ops;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
|
#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,
|
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_device *spi = to_spi_device(dev);
|
||||||
struct spi_message msg;
|
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(wr_buf, 0, CY_SPI_DATA_BUF_SIZE);
|
||||||
memset(rd_buf, 0, CY_SPI_CMD_BYTES);
|
memset(rd_buf, 0, CY_SPI_CMD_BYTES);
|
||||||
|
|
||||||
if (reg > 255)
|
wr_buf[0] = op + (((reg >> 8) & 0x1) ? CY_SPI_A8_BIT : 0);
|
||||||
wr_buf[0] = op + CY_SPI_A8_BIT;
|
if (op == CY_SPI_WR_OP) {
|
||||||
else
|
wr_buf[1] = reg & 0xFF;
|
||||||
wr_buf[0] = op;
|
if (length > 0)
|
||||||
if (op == CY_SPI_WR_OP)
|
memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
|
||||||
wr_buf[1] = reg % 256;
|
}
|
||||||
if (op == CY_SPI_WR_OP && length > 0)
|
|
||||||
memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
|
|
||||||
|
|
||||||
memset(xfer, 0, sizeof(xfer));
|
memset(xfer, 0, sizeof(xfer));
|
||||||
spi_message_init(&msg);
|
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,
|
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;
|
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,
|
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,
|
return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
|
||||||
length);
|
length);
|
||||||
|
|
|
@ -112,9 +112,9 @@ struct cyttsp;
|
||||||
|
|
||||||
struct cyttsp_bus_ops {
|
struct cyttsp_bus_ops {
|
||||||
u16 bustype;
|
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);
|
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);
|
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);
|
struct device *dev, int irq, size_t xfer_buf_size);
|
||||||
void cyttsp_remove(struct cyttsp *ts);
|
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);
|
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);
|
u8 length, void *values);
|
||||||
extern const struct dev_pm_ops cyttsp_pm_ops;
|
extern const struct dev_pm_ops cyttsp_pm_ops;
|
||||||
|
|
||||||
|
|
|
@ -32,18 +32,20 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf,
|
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);
|
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[] = {
|
struct i2c_msg msgs[] = {
|
||||||
{
|
{
|
||||||
.addr = client->addr,
|
.addr = client_addr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.len = 1,
|
.len = 1,
|
||||||
.buf = &addr,
|
.buf = &addr_lo,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.addr = client->addr,
|
.addr = client_addr,
|
||||||
.flags = I2C_M_RD,
|
.flags = I2C_M_RD,
|
||||||
.len = length,
|
.len = length,
|
||||||
.buf = values,
|
.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);
|
EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data);
|
||||||
|
|
||||||
int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf,
|
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);
|
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;
|
int retval;
|
||||||
|
|
||||||
xfer_buf[0] = addr;
|
xfer_buf[0] = addr_lo;
|
||||||
memcpy(&xfer_buf[1], values, length);
|
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);
|
EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#define CY_SPI_BITS_PER_WORD 8
|
#define CY_SPI_BITS_PER_WORD 8
|
||||||
|
|
||||||
static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
|
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_device *spi = to_spi_device(dev);
|
||||||
struct spi_message msg;
|
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,
|
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,
|
return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data,
|
||||||
length);
|
length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cyttsp_spi_write_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,
|
return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
|
||||||
length);
|
length);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче