--- v2
+++ v4
@@ -1,125 +1,62 @@
-Instead of reading each object separately, fetch the whole table in one
-large i2c transaction. A 6 byte table object requires 10 bytes to read,
-so doing this dramatically reduces overhead.
+The i2c bus requires 4 bytes to do a 1-byte write
+(1 byte i2c address + 2 byte offset + 1 byte data).
-Also, as a cleanup, move object_table allocation (and post-fw-update
-reallocation) into mxt_get_object_table().
+By taking a length with writes, the driver can amortize transaction
+overhead by performing larger transactions where appropriate.
+
+This patch just sets up the new API. Later patches refactor writes
+to take advantage of the larger transactions.
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
---
- drivers/input/touchscreen/atmel_mxt_ts.c | 66 +++++++++++++++---------------
- 1 files changed, 33 insertions(+), 33 deletions(-)
+ drivers/input/touchscreen/atmel_mxt_ts.c | 22 +++++++++++++++++-----
+ 1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
-index 9d88faf..0d0dab6 100644
+index 1ef3aef..2e49488 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
-@@ -437,14 +437,7 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
- return 0;
+@@ -430,17 +430,24 @@ static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
+ return __mxt_read_reg(client, reg, 1, val);
}
--static int mxt_read_object_table(struct i2c_client *client,
-- u16 reg, u8 *object_buf)
--{
-- return mxt_read_reg(client, reg, MXT_OBJECT_SIZE, object_buf);
--}
--
--static struct mxt_object *
--mxt_get_object(struct mxt_data *data, u8 type)
-+static struct mxt_object *mxt_get_object(struct mxt_data *data, u8 type)
+-static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
++static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
++ const void *val)
{
- struct mxt_object *object;
- int i;
-@@ -733,25 +726,41 @@ static void mxt_handle_pdata(struct mxt_data *data)
+- u8 buf[3];
++ u8 *buf;
++ size_t count;
+ int ret;
- static int mxt_get_object_table(struct mxt_data *data)
- {
-+ struct i2c_client *client = data->client;
-+ struct device *dev = &client->dev;
- int error;
- int i;
-- u16 reg;
- u8 reportid = 0;
-- u8 buf[MXT_OBJECT_SIZE];
-+ u8 *buf;
-+ size_t buf_size;
-
-- for (i = 0; i < data->info.object_num; i++) {
-- struct mxt_object *object = data->object_table + i;
-+ /* Free old object table, if there was one. */
-+ kfree(data->object_table);
-+ data->object_table = kcalloc(data->info.object_num,
-+ sizeof(struct mxt_object), GFP_KERNEL);
-+ if (!data->object_table) {
-+ dev_err(dev, "Failed to allocate object table\n");
-+ return -ENOMEM;
-+ }
-
-- reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i;
-- error = mxt_read_object_table(data->client, reg, buf);
-- if (error)
-- return error;
-+ buf_size = MXT_OBJECT_SIZE * data->info.object_num;
-+ buf = kmalloc(buf_size, GFP_KERNEL);
++ count = len + 2;
++ buf = kmalloc(count, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
++
+ buf[0] = reg & 0xff;
+ buf[1] = (reg >> 8) & 0xff;
+- buf[2] = val;
++ memcpy(&buf[2], val, len);
-- object->type = buf[0];
-- object->start_address = (buf[2] << 8) | buf[1];
-- object->size = buf[3] + 1;
-- object->instances = buf[4] + 1;
-- object->num_report_ids = buf[5];
-+ error = mxt_read_reg(client, MXT_OBJECT_START, buf_size, buf);
-+ if (error)
-+ goto done;
-+
-+ for (i = 0; i < data->info.object_num; i++) {
-+ struct mxt_object *object = &data->object_table[i];
-+ u8 *obj_buf = &buf[i * MXT_OBJECT_SIZE];
-+
-+ object->type = obj_buf[0];
-+ object->start_address = (obj_buf[2] << 8) | obj_buf[1];
-+ object->size = obj_buf[3] + 1;
-+ object->instances = obj_buf[4] + 1;
-+ object->num_report_ids = obj_buf[5];
-
- if (object->num_report_ids) {
- reportid += object->num_report_ids * object->instances;
-@@ -759,7 +768,9 @@ static int mxt_get_object_table(struct mxt_data *data)
- }
- }
-
-- return 0;
-+done:
-+ kfree(buf);
-+ return error;
+- ret = i2c_master_send(client, buf, 3);
+- if (ret == 3) {
++ ret = i2c_master_send(client, buf, count);
++ if (ret == count) {
+ ret = 0;
+ } else {
+ if (ret >= 0)
+@@ -452,6 +459,11 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
+ return ret;
}
- static int mxt_initialize(struct mxt_data *data)
-@@ -774,14 +785,6 @@ static int mxt_initialize(struct mxt_data *data)
- if (error)
- return error;
-
-- data->object_table = kcalloc(info->object_num,
-- sizeof(struct mxt_object),
-- GFP_KERNEL);
-- if (!data->object_table) {
-- dev_err(&client->dev, "Failed to allocate memory\n");
-- return -ENOMEM;
-- }
--
- /* Get object table information */
- error = mxt_get_object_table(data);
- if (error)
-@@ -971,9 +974,6 @@ static ssize_t mxt_update_fw_store(struct device *dev,
- /* Wait for reset */
- msleep(MXT_FWRESET_TIME);
-
-- kfree(data->object_table);
-- data->object_table = NULL;
--
- mxt_initialize(data);
- }
-
++static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
++{
++ return __mxt_write_reg(client, reg, 1, &val);
++}
++
+ static int mxt_read_object_table(struct i2c_client *client,
+ u16 reg, u8 *object_buf)
+ {
--
1.7.7.3