aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2014-05-19 02:10:49 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-05-19 02:27:27 -0400
commitf28a842db6fc25d5ac53d70a9608d38d7a9dcd3a (patch)
treeb7f05212f4cfd2849541af55584f82dd0f86a580
parentc3f78043d5aea39205a14c580babd87fbdcfa148 (diff)
Input: atmel_mxt_ts - add additional bootloader addresses
Move bootloaders reads/writes into separate functions. Instead of switching client->addr, define new field bootloader_addr in mxt_data. Implement lookup calculation for bootloader addresses. Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Acked-by: Benson Leung <bleung@chromium.org> Acked-by: Yufeng Shen <miletus@chromium.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c138
1 files changed, 93 insertions, 45 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 61f9ef221d12..44c1be65dbb4 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -29,12 +29,6 @@
29#define MXT_VER_21 21 29#define MXT_VER_21 21
30#define MXT_VER_22 22 30#define MXT_VER_22 22
31 31
32/* Slave addresses */
33#define MXT_APP_LOW 0x4a
34#define MXT_APP_HIGH 0x4b
35#define MXT_BOOT_LOW 0x24
36#define MXT_BOOT_HIGH 0x25
37
38/* Firmware */ 32/* Firmware */
39#define MXT_FW_NAME "maxtouch.fw" 33#define MXT_FW_NAME "maxtouch.fw"
40 34
@@ -261,6 +255,7 @@ struct mxt_data {
261 unsigned int max_y; 255 unsigned int max_y;
262 bool in_bootloader; 256 bool in_bootloader;
263 u32 config_crc; 257 u32 config_crc;
258 u8 bootloader_addr;
264 259
265 /* Cached parameters from object table */ 260 /* Cached parameters from object table */
266 u8 T6_reportid; 261 u8 T6_reportid;
@@ -378,9 +373,82 @@ static int mxt_wait_for_completion(struct mxt_data *data,
378 return 0; 373 return 0;
379} 374}
380 375
376static int mxt_bootloader_read(struct mxt_data *data,
377 u8 *val, unsigned int count)
378{
379 int ret;
380 struct i2c_msg msg;
381
382 msg.addr = data->bootloader_addr;
383 msg.flags = data->client->flags & I2C_M_TEN;
384 msg.flags |= I2C_M_RD;
385 msg.len = count;
386 msg.buf = val;
387
388 ret = i2c_transfer(data->client->adapter, &msg, 1);
389
390 if (ret == 1) {
391 ret = 0;
392 } else {
393 ret = ret < 0 ? ret : -EIO;
394 dev_err(&data->client->dev, "%s: i2c recv failed (%d)\n",
395 __func__, ret);
396 }
397
398 return ret;
399}
400
401static int mxt_bootloader_write(struct mxt_data *data,
402 const u8 * const val, unsigned int count)
403{
404 int ret;
405 struct i2c_msg msg;
406
407 msg.addr = data->bootloader_addr;
408 msg.flags = data->client->flags & I2C_M_TEN;
409 msg.len = count;
410 msg.buf = (u8 *)val;
411
412 ret = i2c_transfer(data->client->adapter, &msg, 1);
413 if (ret == 1) {
414 ret = 0;
415 } else {
416 ret = ret < 0 ? ret : -EIO;
417 dev_err(&data->client->dev, "%s: i2c send failed (%d)\n",
418 __func__, ret);
419 }
420
421 return ret;
422}
423
424static int mxt_lookup_bootloader_address(struct mxt_data *data)
425{
426 u8 appmode = data->client->addr;
427 u8 bootloader;
428
429 switch (appmode) {
430 case 0x4a:
431 case 0x4b:
432 case 0x4c:
433 case 0x4d:
434 case 0x5a:
435 case 0x5b:
436 bootloader = appmode - 0x26;
437 break;
438 default:
439 dev_err(&data->client->dev,
440 "Appmode i2c address 0x%02x not found\n",
441 appmode);
442 return -EINVAL;
443 }
444
445 data->bootloader_addr = bootloader;
446 return 0;
447}
448
381static int mxt_check_bootloader(struct mxt_data *data, unsigned int state) 449static int mxt_check_bootloader(struct mxt_data *data, unsigned int state)
382{ 450{
383 struct i2c_client *client = data->client; 451 struct device *dev = &data->client->dev;
384 u8 val; 452 u8 val;
385 int ret; 453 int ret;
386 454
@@ -401,15 +469,14 @@ recheck:
401 * by writing length 0x000 to device (iff we are in 469 * by writing length 0x000 to device (iff we are in
402 * WAITING_FRAME_DATA state). 470 * WAITING_FRAME_DATA state).
403 */ 471 */
404 dev_err(&client->dev, "Update wait error %d\n", ret); 472 dev_err(dev, "Update wait error %d\n", ret);
405 return ret; 473 return ret;
406 } 474 }
407 } 475 }
408 476
409 if (i2c_master_recv(client, &val, 1) != 1) { 477 ret = mxt_bootloader_read(data, &val, 1);
410 dev_err(&client->dev, "%s: i2c recv failed\n", __func__); 478 if (ret)
411 return -EIO; 479 return ret;
412 }
413 480
414 switch (state) { 481 switch (state) {
415 case MXT_WAITING_BOOTLOAD_CMD: 482 case MXT_WAITING_BOOTLOAD_CMD:
@@ -425,7 +492,7 @@ recheck:
425 } 492 }
426 493
427 if (val != state) { 494 if (val != state) {
428 dev_err(&client->dev, "Invalid bootloader state %02X != %02X\n", 495 dev_err(dev, "Invalid bootloader state %02X != %02X\n",
429 val, state); 496 val, state);
430 return -EINVAL; 497 return -EINVAL;
431 } 498 }
@@ -433,28 +500,17 @@ recheck:
433 return 0; 500 return 0;
434} 501}
435 502
436static int mxt_unlock_bootloader(struct i2c_client *client) 503static int mxt_unlock_bootloader(struct mxt_data *data)
437{ 504{
505 int ret;
438 u8 buf[2]; 506 u8 buf[2];
439 507
440 buf[0] = MXT_UNLOCK_CMD_LSB; 508 buf[0] = MXT_UNLOCK_CMD_LSB;
441 buf[1] = MXT_UNLOCK_CMD_MSB; 509 buf[1] = MXT_UNLOCK_CMD_MSB;
442 510
443 if (i2c_master_send(client, buf, 2) != 2) { 511 ret = mxt_bootloader_write(data, buf, 2);
444 dev_err(&client->dev, "%s: i2c send failed\n", __func__); 512 if (ret)
445 return -EIO; 513 return ret;
446 }
447
448 return 0;
449}
450
451static int mxt_fw_write(struct i2c_client *client,
452 const u8 *data, unsigned int frame_size)
453{
454 if (i2c_master_send(client, data, frame_size) != frame_size) {
455 dev_err(&client->dev, "%s: i2c send failed\n", __func__);
456 return -EIO;
457 }
458 514
459 return 0; 515 return 0;
460} 516}
@@ -1102,7 +1158,6 @@ done:
1102static int mxt_load_fw(struct device *dev, const char *fn) 1158static int mxt_load_fw(struct device *dev, const char *fn)
1103{ 1159{
1104 struct mxt_data *data = dev_get_drvdata(dev); 1160 struct mxt_data *data = dev_get_drvdata(dev);
1105 struct i2c_client *client = data->client;
1106 const struct firmware *fw = NULL; 1161 const struct firmware *fw = NULL;
1107 unsigned int frame_size; 1162 unsigned int frame_size;
1108 unsigned int pos = 0; 1163 unsigned int pos = 0;
@@ -1114,6 +1169,10 @@ static int mxt_load_fw(struct device *dev, const char *fn)
1114 return ret; 1169 return ret;
1115 } 1170 }
1116 1171
1172 ret = mxt_lookup_bootloader_address(data);
1173 if (ret)
1174 goto release_firmware;
1175
1117 /* Change to the bootloader mode */ 1176 /* Change to the bootloader mode */
1118 data->in_bootloader = true; 1177 data->in_bootloader = true;
1119 1178
@@ -1123,12 +1182,6 @@ static int mxt_load_fw(struct device *dev, const char *fn)
1123 1182
1124 msleep(MXT_RESET_TIME); 1183 msleep(MXT_RESET_TIME);
1125 1184
1126 /* Change to slave address of bootloader */
1127 if (client->addr == MXT_APP_LOW)
1128 client->addr = MXT_BOOT_LOW;
1129 else
1130 client->addr = MXT_BOOT_HIGH;
1131
1132 reinit_completion(&data->bl_completion); 1185 reinit_completion(&data->bl_completion);
1133 1186
1134 ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD); 1187 ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD);
@@ -1136,7 +1189,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
1136 goto disable_irq; 1189 goto disable_irq;
1137 1190
1138 /* Unlock bootloader */ 1191 /* Unlock bootloader */
1139 mxt_unlock_bootloader(client); 1192 mxt_unlock_bootloader(data);
1140 1193
1141 while (pos < fw->size) { 1194 while (pos < fw->size) {
1142 ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA); 1195 ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA);
@@ -1151,7 +1204,9 @@ static int mxt_load_fw(struct device *dev, const char *fn)
1151 frame_size += 2; 1204 frame_size += 2;
1152 1205
1153 /* Write one frame to device */ 1206 /* Write one frame to device */
1154 mxt_fw_write(client, fw->data + pos, frame_size); 1207 ret = mxt_bootloader_write(data, fw->data + pos, frame_size);
1208 if (ret)
1209 goto disable_irq;
1155 1210
1156 ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS); 1211 ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS);
1157 if (ret) 1212 if (ret)
@@ -1181,13 +1236,6 @@ disable_irq:
1181 disable_irq(data->irq); 1236 disable_irq(data->irq);
1182release_firmware: 1237release_firmware:
1183 release_firmware(fw); 1238 release_firmware(fw);
1184
1185 /* Change to slave address of application */
1186 if (client->addr == MXT_BOOT_LOW)
1187 client->addr = MXT_APP_LOW;
1188 else
1189 client->addr = MXT_APP_HIGH;
1190
1191 return ret; 1239 return ret;
1192} 1240}
1193 1241