/
0008-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch
174 lines (150 loc) · 5.06 KB
/
0008-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
From 373cef24fff688fe9d3c94896ef8440938e31e13 Mon Sep 17 00:00:00 2001
From: Benson Leung <bleung@chromium.org>
Date: Wed, 25 Apr 2012 23:08:12 -0700
Subject: [PATCH 08/57] CHROMIUM: Input: atmel_mxt_ts - wait for CHG assert in
mxt_check_bootloader
The driver should not immediately read bootloader status when
in Application Update Mode. The CHG line will assert when the device
has made a state transition and is ready to report a new status
via i2c.
This change adds a wait for completion in mxt_check_bootloader,
and changes the mxt_interrupt handler to signal the completion.
This will allow this commit in the intel_i2c driver to be reverted,
as the time is no longer spent waiting for i2c read:
3414f39 CHROMIUM: drm/i915/intel_i2c: Increase bitbang fallback timeout for atmel_mx
Signed-off-by: Benson Leung <bleung@chromium.org>
BUG=chrome-os-partner:8730
TEST=(a) Verify when device not in BL (normal case), no functional change.
TEST=(b) Verify fw update works, and device is initialized properly
after.
Change-Id: I5d20a9d63361fb91cb59aa7351e581f55422b924
Reviewed-on: https://gerrit.chromium.org/gerrit/21173
v3.7 rebase:
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 63 ++++++++++++++++++++++++++++----
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index be96be3..d0f91ff 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
@@ -251,6 +252,9 @@ struct mxt_data {
u8 T6_reportid;
u8 T9_reportid_min;
u8 T9_reportid_max;
+
+ /* for fw update in bootloader */
+ struct completion bl_completion;
};
static void mxt_free_object_table(struct mxt_data *data);
@@ -381,19 +385,58 @@ static int mxt_i2c_transfer(struct i2c_client *client, struct i2c_msg *msgs,
return ret;
}
-static int mxt_check_bootloader(struct i2c_client *client,
- unsigned int state)
+static int mxt_wait_for_chg(struct mxt_data *data, unsigned int timeout_ms)
{
+ struct device *dev = &data->client->dev;
+ struct completion *comp = &data->bl_completion;
+ unsigned long timeout = msecs_to_jiffies(timeout_ms);
+ long ret;
+
+ ret = wait_for_completion_interruptible_timeout(comp, timeout);
+ if (ret < 0) {
+ dev_err(dev, "Wait for completion interrupted.\n");
+ /*
+ * TODO: handle -EINTR better by terminating fw update process
+ * before returning to userspace by writing length 0x000 to
+ * device (iff we are in WAITING_FRAME_DATA state).
+ */
+ return -EINTR;
+ } else if (ret == 0) {
+ dev_err(dev, "Wait for completion timed out.\n");
+ return -ETIMEDOUT;
+ }
+ return 0;
+}
+
+static int mxt_check_bootloader(struct mxt_data *data, unsigned int state)
+{
+ struct i2c_client *client = data->client;
u8 val;
int ret;
recheck:
+ if (state != MXT_WAITING_BOOTLOAD_CMD) {
+ /*
+ * In application update mode, the interrupt
+ * line signals state transitions. We must wait for the
+ * CHG assertion before reading the status byte.
+ * Once the status byte has been read, the line is deasserted.
+ */
+ int ret = mxt_wait_for_chg(data, 300);
+ if (ret) {
+ dev_err(&client->dev, "Update wait error %d\n", ret);
+ return ret;
+ }
+ }
+
ret = mxt_i2c_recv(client, &val, 1);
if (ret)
return ret;
switch (state) {
case MXT_WAITING_BOOTLOAD_CMD:
+ dev_info(&client->dev, "bootloader version: %d\n",
+ val & MXT_BOOT_STATUS_MASK);
case MXT_WAITING_FRAME_DATA:
val &= ~MXT_BOOT_STATUS_MASK;
break;
@@ -672,8 +715,11 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
u8 reportid;
bool update_input = false;
- if (mxt_in_bootloader(data))
+ if (mxt_in_bootloader(data)) {
+ /* bootloader state transition completion */
+ complete(&data->bl_completion);
goto end;
+ }
do {
if (mxt_read_message(data, &message)) {
@@ -1072,18 +1118,18 @@ static int mxt_load_fw(struct device *dev, const char *fn)
goto out;
}
- ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD);
+ ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD);
if (ret)
goto out;
+ INIT_COMPLETION(data->bl_completion);
/* Unlock bootloader */
ret = mxt_unlock_bootloader(client);
if (ret)
goto out;
while (pos < fw->size) {
- ret = mxt_check_bootloader(client,
- MXT_WAITING_FRAME_DATA);
+ ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA);
if (ret)
goto out;
@@ -1099,8 +1145,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
if (ret)
goto out;
- ret = mxt_check_bootloader(client,
- MXT_FRAME_CRC_PASS);
+ ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS);
if (ret)
goto out;
@@ -1264,6 +1309,8 @@ static int __devinit mxt_probe(struct i2c_client *client,
data->pdata = pdata;
data->irq = client->irq;
+ init_completion(&data->bl_completion);
+
mxt_calc_resolution(data);
if (mxt_in_bootloader(data)) {
--
1.8.2.1