diff options
author | Nick Dyer <nick.dyer@itdev.co.uk> | 2014-05-19 02:14:20 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-05-19 02:27:28 -0400 |
commit | f943c74ad8b0dcf6371b29ff0925f0e649b7826f (patch) | |
tree | 54a0a14ec7185dbfe041c022f6e77d50000e53bd /drivers/input | |
parent | e57a66aa85345baf54461189b185a24cdb0bd2fe (diff) |
Input: atmel_mxt_ts - implement bootloader frame retries
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>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 3b07627dd8a2..5fb5b2231b5f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -510,8 +510,12 @@ recheck: | |||
510 | val &= ~MXT_BOOT_STATUS_MASK; | 510 | val &= ~MXT_BOOT_STATUS_MASK; |
511 | break; | 511 | break; |
512 | case MXT_FRAME_CRC_PASS: | 512 | case MXT_FRAME_CRC_PASS: |
513 | if (val == MXT_FRAME_CRC_CHECK) | 513 | if (val == MXT_FRAME_CRC_CHECK) { |
514 | goto recheck; | 514 | goto recheck; |
515 | } else if (val == MXT_FRAME_CRC_FAIL) { | ||
516 | dev_err(dev, "Bootloader CRC fail\n"); | ||
517 | return -EINVAL; | ||
518 | } | ||
515 | break; | 519 | break; |
516 | default: | 520 | default: |
517 | return -EINVAL; | 521 | return -EINVAL; |
@@ -1187,6 +1191,7 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
1187 | const struct firmware *fw = NULL; | 1191 | const struct firmware *fw = NULL; |
1188 | unsigned int frame_size; | 1192 | unsigned int frame_size; |
1189 | unsigned int pos = 0; | 1193 | unsigned int pos = 0; |
1194 | unsigned int retry = 0; | ||
1190 | int ret; | 1195 | int ret; |
1191 | 1196 | ||
1192 | ret = request_firmware(&fw, fn, dev); | 1197 | ret = request_firmware(&fw, fn, dev); |
@@ -1224,9 +1229,7 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
1224 | 1229 | ||
1225 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | 1230 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); |
1226 | 1231 | ||
1227 | /* We should add 2 at frame size as the the firmware data is not | 1232 | /* Take account of CRC bytes */ |
1228 | * included the CRC bytes. | ||
1229 | */ | ||
1230 | frame_size += 2; | 1233 | frame_size += 2; |
1231 | 1234 | ||
1232 | /* Write one frame to device */ | 1235 | /* Write one frame to device */ |
@@ -1235,10 +1238,20 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
1235 | goto disable_irq; | 1238 | goto disable_irq; |
1236 | 1239 | ||
1237 | ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS); | 1240 | ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS); |
1238 | if (ret) | 1241 | if (ret) { |
1239 | goto disable_irq; | 1242 | retry++; |
1243 | |||
1244 | /* Back off by 20ms per retry */ | ||
1245 | msleep(retry * 20); | ||
1240 | 1246 | ||
1241 | pos += frame_size; | 1247 | if (retry > 20) { |
1248 | dev_err(dev, "Retry count exceeded\n"); | ||
1249 | goto disable_irq; | ||
1250 | } | ||
1251 | } else { | ||
1252 | retry = 0; | ||
1253 | pos += frame_size; | ||
1254 | } | ||
1242 | 1255 | ||
1243 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | 1256 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); |
1244 | } | 1257 | } |