aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorStephen Barber <smbarber@chromium.org>2015-06-09 07:04:46 -0400
committerLee Jones <lee.jones@linaro.org>2015-06-15 08:18:22 -0400
commitd365407079d33106f76bd486a863de05eb5ae95d (patch)
tree46cc169453a614fee690d5ce9df51ed992222c4c /drivers/mfd
parent2c7589af3c4dee844e6a4174f2aa8996cf837604 (diff)
mfd: cros_ec: add bus-specific proto v3 code
Add proto v3 support to the SPI, I2C, and LPC. Signed-off-by: Stephen Barber <smbarber@chromium.org> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Tested-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Gwendal Grignou <gwendal@chromium.org> Tested-by: Gwendal Grignou <gwendal@chromium.org> Acked-by: Lee Jones <lee.jones@linaro.org> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/cros_ec_i2c.c166
-rw-r--r--drivers/mfd/cros_ec_spi.c382
2 files changed, 491 insertions, 57 deletions
diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c
index b400bfa2772a..22e8a4ae1711 100644
--- a/drivers/mfd/cros_ec_i2c.c
+++ b/drivers/mfd/cros_ec_i2c.c
@@ -13,6 +13,7 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 */ 14 */
15 15
16#include <linux/delay.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
@@ -22,6 +23,32 @@
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24 25
26/**
27 * Request format for protocol v3
28 * byte 0 0xda (EC_COMMAND_PROTOCOL_3)
29 * byte 1-8 struct ec_host_request
30 * byte 10- response data
31 */
32struct ec_host_request_i2c {
33 /* Always 0xda to backward compatible with v2 struct */
34 uint8_t command_protocol;
35 struct ec_host_request ec_request;
36} __packed;
37
38
39/*
40 * Response format for protocol v3
41 * byte 0 result code
42 * byte 1 packet_length
43 * byte 2-9 struct ec_host_response
44 * byte 10- response data
45 */
46struct ec_host_response_i2c {
47 uint8_t result;
48 uint8_t packet_length;
49 struct ec_host_response ec_response;
50} __packed;
51
25static inline struct cros_ec_device *to_ec_dev(struct device *dev) 52static inline struct cros_ec_device *to_ec_dev(struct device *dev)
26{ 53{
27 struct i2c_client *client = to_i2c_client(dev); 54 struct i2c_client *client = to_i2c_client(dev);
@@ -29,6 +56,134 @@ static inline struct cros_ec_device *to_ec_dev(struct device *dev)
29 return i2c_get_clientdata(client); 56 return i2c_get_clientdata(client);
30} 57}
31 58
59static int cros_ec_pkt_xfer_i2c(struct cros_ec_device *ec_dev,
60 struct cros_ec_command *msg)
61{
62 struct i2c_client *client = ec_dev->priv;
63 int ret = -ENOMEM;
64 int i;
65 int packet_len;
66 u8 *out_buf = NULL;
67 u8 *in_buf = NULL;
68 u8 sum;
69 struct i2c_msg i2c_msg[2];
70 struct ec_host_response *ec_response;
71 struct ec_host_request_i2c *ec_request_i2c;
72 struct ec_host_response_i2c *ec_response_i2c;
73 int request_header_size = sizeof(struct ec_host_request_i2c);
74 int response_header_size = sizeof(struct ec_host_response_i2c);
75
76 i2c_msg[0].addr = client->addr;
77 i2c_msg[0].flags = 0;
78 i2c_msg[1].addr = client->addr;
79 i2c_msg[1].flags = I2C_M_RD;
80
81 packet_len = msg->insize + response_header_size;
82 BUG_ON(packet_len > ec_dev->din_size);
83 in_buf = ec_dev->din;
84 i2c_msg[1].len = packet_len;
85 i2c_msg[1].buf = (char *) in_buf;
86
87 packet_len = msg->outsize + request_header_size;
88 BUG_ON(packet_len > ec_dev->dout_size);
89 out_buf = ec_dev->dout;
90 i2c_msg[0].len = packet_len;
91 i2c_msg[0].buf = (char *) out_buf;
92
93 /* create request data */
94 ec_request_i2c = (struct ec_host_request_i2c *) out_buf;
95 ec_request_i2c->command_protocol = EC_COMMAND_PROTOCOL_3;
96
97 ec_dev->dout++;
98 ret = cros_ec_prepare_tx(ec_dev, msg);
99 ec_dev->dout--;
100
101 /* send command to EC and read answer */
102 ret = i2c_transfer(client->adapter, i2c_msg, 2);
103 if (ret < 0) {
104 dev_dbg(ec_dev->dev, "i2c transfer failed: %d\n", ret);
105 goto done;
106 } else if (ret != 2) {
107 dev_err(ec_dev->dev, "failed to get response: %d\n", ret);
108 ret = -EIO;
109 goto done;
110 }
111
112 ec_response_i2c = (struct ec_host_response_i2c *) in_buf;
113 msg->result = ec_response_i2c->result;
114 ec_response = &ec_response_i2c->ec_response;
115
116 switch (msg->result) {
117 case EC_RES_SUCCESS:
118 break;
119 case EC_RES_IN_PROGRESS:
120 ret = -EAGAIN;
121 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
122 msg->command);
123 goto done;
124
125 default:
126 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
127 msg->command, msg->result);
128 /*
129 * When we send v3 request to v2 ec, ec won't recognize the
130 * 0xda (EC_COMMAND_PROTOCOL_3) and will return with status
131 * EC_RES_INVALID_COMMAND with zero data length.
132 *
133 * In case of invalid command for v3 protocol the data length
134 * will be at least sizeof(struct ec_host_response)
135 */
136 if (ec_response_i2c->result == EC_RES_INVALID_COMMAND &&
137 ec_response_i2c->packet_length == 0) {
138 ret = -EPROTONOSUPPORT;
139 goto done;
140 }
141 }
142
143 if (ec_response_i2c->packet_length < sizeof(struct ec_host_response)) {
144 dev_err(ec_dev->dev,
145 "response of %u bytes too short; not a full header\n",
146 ec_response_i2c->packet_length);
147 ret = -EBADMSG;
148 goto done;
149 }
150
151 if (msg->insize < ec_response->data_len) {
152 dev_err(ec_dev->dev,
153 "response data size is too large: expected %u, got %u\n",
154 msg->insize,
155 ec_response->data_len);
156 ret = -EMSGSIZE;
157 goto done;
158 }
159
160 /* copy response packet payload and compute checksum */
161 sum = 0;
162 for (i = 0; i < sizeof(struct ec_host_response); i++)
163 sum += ((u8 *)ec_response)[i];
164
165 memcpy(msg->data,
166 in_buf + response_header_size,
167 ec_response->data_len);
168 for (i = 0; i < ec_response->data_len; i++)
169 sum += msg->data[i];
170
171 /* All bytes should sum to zero */
172 if (sum) {
173 dev_err(ec_dev->dev, "bad packet checksum\n");
174 ret = -EBADMSG;
175 goto done;
176 }
177
178 ret = ec_response->data_len;
179
180done:
181 if (msg->command == EC_CMD_REBOOT_EC)
182 msleep(EC_REBOOT_DELAY_MS);
183
184 return ret;
185}
186
32static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev, 187static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
33 struct cros_ec_command *msg) 188 struct cros_ec_command *msg)
34{ 189{
@@ -121,9 +276,12 @@ static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
121 } 276 }
122 277
123 ret = len; 278 ret = len;
124 done: 279done:
125 kfree(in_buf); 280 kfree(in_buf);
126 kfree(out_buf); 281 kfree(out_buf);
282 if (msg->command == EC_CMD_REBOOT_EC)
283 msleep(EC_REBOOT_DELAY_MS);
284
127 return ret; 285 return ret;
128} 286}
129 287
@@ -143,12 +301,12 @@ static int cros_ec_i2c_probe(struct i2c_client *client,
143 ec_dev->priv = client; 301 ec_dev->priv = client;
144 ec_dev->irq = client->irq; 302 ec_dev->irq = client->irq;
145 ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c; 303 ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c;
146 ec_dev->pkt_xfer = NULL; 304 ec_dev->pkt_xfer = cros_ec_pkt_xfer_i2c;
147 ec_dev->ec_name = client->name; 305 ec_dev->ec_name = client->name;
148 ec_dev->phys_name = client->adapter->name; 306 ec_dev->phys_name = client->adapter->name;
149 ec_dev->din_size = sizeof(struct ec_host_response) + 307 ec_dev->din_size = sizeof(struct ec_host_response_i2c) +
150 sizeof(struct ec_response_get_protocol_info); 308 sizeof(struct ec_response_get_protocol_info);
151 ec_dev->dout_size = sizeof(struct ec_host_request); 309 ec_dev->dout_size = sizeof(struct ec_host_request_i2c);
152 310
153 err = cros_ec_register(ec_dev); 311 err = cros_ec_register(ec_dev);
154 if (err) { 312 if (err) {
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index 04da2f288ef8..4e6f2f6b1095 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -65,12 +65,6 @@
65 */ 65 */
66#define EC_SPI_RECOVERY_TIME_NS (200 * 1000) 66#define EC_SPI_RECOVERY_TIME_NS (200 * 1000)
67 67
68/*
69 * The EC is unresponsive for a time after a reboot command. Add a
70 * simple delay to make sure that the bus stays locked.
71 */
72#define EC_REBOOT_DELAY_MS 50
73
74/** 68/**
75 * struct cros_ec_spi - information about a SPI-connected EC 69 * struct cros_ec_spi - information about a SPI-connected EC
76 * 70 *
@@ -87,7 +81,7 @@ struct cros_ec_spi {
87}; 81};
88 82
89static void debug_packet(struct device *dev, const char *name, u8 *ptr, 83static void debug_packet(struct device *dev, const char *name, u8 *ptr,
90 int len) 84 int len)
91{ 85{
92#ifdef DEBUG 86#ifdef DEBUG
93 int i; 87 int i;
@@ -100,6 +94,172 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr,
100#endif 94#endif
101} 95}
102 96
97static int terminate_request(struct cros_ec_device *ec_dev)
98{
99 struct cros_ec_spi *ec_spi = ec_dev->priv;
100 struct spi_message msg;
101 struct spi_transfer trans;
102 int ret;
103
104 /*
105 * Turn off CS, possibly adding a delay to ensure the rising edge
106 * doesn't come too soon after the end of the data.
107 */
108 spi_message_init(&msg);
109 memset(&trans, 0, sizeof(trans));
110 trans.delay_usecs = ec_spi->end_of_msg_delay;
111 spi_message_add_tail(&trans, &msg);
112
113 ret = spi_sync(ec_spi->spi, &msg);
114
115 /* Reset end-of-response timer */
116 ec_spi->last_transfer_ns = ktime_get_ns();
117 if (ret < 0) {
118 dev_err(ec_dev->dev,
119 "cs-deassert spi transfer failed: %d\n",
120 ret);
121 }
122
123 return ret;
124}
125
126/**
127 * receive_n_bytes - receive n bytes from the EC.
128 *
129 * Assumes buf is a pointer into the ec_dev->din buffer
130 */
131static int receive_n_bytes(struct cros_ec_device *ec_dev, u8 *buf, int n)
132{
133 struct cros_ec_spi *ec_spi = ec_dev->priv;
134 struct spi_transfer trans;
135 struct spi_message msg;
136 int ret;
137
138 BUG_ON(buf - ec_dev->din + n > ec_dev->din_size);
139
140 memset(&trans, 0, sizeof(trans));
141 trans.cs_change = 1;
142 trans.rx_buf = buf;
143 trans.len = n;
144
145 spi_message_init(&msg);
146 spi_message_add_tail(&trans, &msg);
147 ret = spi_sync(ec_spi->spi, &msg);
148 if (ret < 0)
149 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
150
151 return ret;
152}
153
154/**
155 * cros_ec_spi_receive_packet - Receive a packet from the EC.
156 *
157 * This function has two phases: reading the preamble bytes (since if we read
158 * data from the EC before it is ready to send, we just get preamble) and
159 * reading the actual message.
160 *
161 * The received data is placed into ec_dev->din.
162 *
163 * @ec_dev: ChromeOS EC device
164 * @need_len: Number of message bytes we need to read
165 */
166static int cros_ec_spi_receive_packet(struct cros_ec_device *ec_dev,
167 int need_len)
168{
169 struct ec_host_response *response;
170 u8 *ptr, *end;
171 int ret;
172 unsigned long deadline;
173 int todo;
174
175 BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size);
176
177 /* Receive data until we see the header byte */
178 deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
179 while (true) {
180 unsigned long start_jiffies = jiffies;
181
182 ret = receive_n_bytes(ec_dev,
183 ec_dev->din,
184 EC_MSG_PREAMBLE_COUNT);
185 if (ret < 0)
186 return ret;
187
188 ptr = ec_dev->din;
189 for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
190 if (*ptr == EC_SPI_FRAME_START) {
191 dev_dbg(ec_dev->dev, "msg found at %zd\n",
192 ptr - ec_dev->din);
193 break;
194 }
195 }
196 if (ptr != end)
197 break;
198
199 /*
200 * Use the time at the start of the loop as a timeout. This
201 * gives us one last shot at getting the transfer and is useful
202 * in case we got context switched out for a while.
203 */
204 if (time_after(start_jiffies, deadline)) {
205 dev_warn(ec_dev->dev, "EC failed to respond in time\n");
206 return -ETIMEDOUT;
207 }
208 }
209
210 /*
211 * ptr now points to the header byte. Copy any valid data to the
212 * start of our buffer
213 */
214 todo = end - ++ptr;
215 BUG_ON(todo < 0 || todo > ec_dev->din_size);
216 todo = min(todo, need_len);
217 memmove(ec_dev->din, ptr, todo);
218 ptr = ec_dev->din + todo;
219 dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n",
220 need_len, todo);
221 need_len -= todo;
222
223 /* If the entire response struct wasn't read, get the rest of it. */
224 if (todo < sizeof(*response)) {
225 ret = receive_n_bytes(ec_dev, ptr, sizeof(*response) - todo);
226 if (ret < 0)
227 return -EBADMSG;
228 ptr += (sizeof(*response) - todo);
229 todo = sizeof(*response);
230 }
231
232 response = (struct ec_host_response *)ec_dev->din;
233
234 /* Abort if data_len is too large. */
235 if (response->data_len > ec_dev->din_size)
236 return -EMSGSIZE;
237
238 /* Receive data until we have it all */
239 while (need_len > 0) {
240 /*
241 * We can't support transfers larger than the SPI FIFO size
242 * unless we have DMA. We don't have DMA on the ISP SPI ports
243 * for Exynos. We need a way of asking SPI driver for
244 * maximum-supported transfer size.
245 */
246 todo = min(need_len, 256);
247 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
248 todo, need_len, ptr - ec_dev->din);
249
250 ret = receive_n_bytes(ec_dev, ptr, todo);
251 if (ret < 0)
252 return ret;
253
254 ptr += todo;
255 need_len -= todo;
256 }
257
258 dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);
259
260 return 0;
261}
262
103/** 263/**
104 * cros_ec_spi_receive_response - Receive a response from the EC. 264 * cros_ec_spi_receive_response - Receive a response from the EC.
105 * 265 *
@@ -115,34 +275,27 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr,
115static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, 275static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
116 int need_len) 276 int need_len)
117{ 277{
118 struct cros_ec_spi *ec_spi = ec_dev->priv;
119 struct spi_transfer trans;
120 struct spi_message msg;
121 u8 *ptr, *end; 278 u8 *ptr, *end;
122 int ret; 279 int ret;
123 unsigned long deadline; 280 unsigned long deadline;
124 int todo; 281 int todo;
125 282
283 BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size);
284
126 /* Receive data until we see the header byte */ 285 /* Receive data until we see the header byte */
127 deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); 286 deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
128 while (true) { 287 while (true) {
129 unsigned long start_jiffies = jiffies; 288 unsigned long start_jiffies = jiffies;
130 289
131 memset(&trans, 0, sizeof(trans)); 290 ret = receive_n_bytes(ec_dev,
132 trans.cs_change = 1; 291 ec_dev->din,
133 trans.rx_buf = ptr = ec_dev->din; 292 EC_MSG_PREAMBLE_COUNT);
134 trans.len = EC_MSG_PREAMBLE_COUNT; 293 if (ret < 0)
135
136 spi_message_init(&msg);
137 spi_message_add_tail(&trans, &msg);
138 ret = spi_sync(ec_spi->spi, &msg);
139 if (ret < 0) {
140 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
141 return ret; 294 return ret;
142 }
143 295
296 ptr = ec_dev->din;
144 for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) { 297 for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
145 if (*ptr == EC_MSG_HEADER) { 298 if (*ptr == EC_SPI_FRAME_START) {
146 dev_dbg(ec_dev->dev, "msg found at %zd\n", 299 dev_dbg(ec_dev->dev, "msg found at %zd\n",
147 ptr - ec_dev->din); 300 ptr - ec_dev->din);
148 break; 301 break;
@@ -187,21 +340,9 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
187 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", 340 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
188 todo, need_len, ptr - ec_dev->din); 341 todo, need_len, ptr - ec_dev->din);
189 342
190 memset(&trans, 0, sizeof(trans)); 343 ret = receive_n_bytes(ec_dev, ptr, todo);
191 trans.cs_change = 1; 344 if (ret < 0)
192 trans.rx_buf = ptr;
193 trans.len = todo;
194 spi_message_init(&msg);
195 spi_message_add_tail(&trans, &msg);
196
197 /* send command to EC and read answer */
198 BUG_ON((u8 *)trans.rx_buf - ec_dev->din + todo >
199 ec_dev->din_size);
200 ret = spi_sync(ec_spi->spi, &msg);
201 if (ret < 0) {
202 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
203 return ret; 345 return ret;
204 }
205 346
206 debug_packet(ec_dev->dev, "interim", ptr, todo); 347 debug_packet(ec_dev->dev, "interim", ptr, todo);
207 ptr += todo; 348 ptr += todo;
@@ -214,6 +355,128 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
214} 355}
215 356
216/** 357/**
358 * cros_ec_pkt_xfer_spi - Transfer a packet over SPI and receive the reply
359 *
360 * @ec_dev: ChromeOS EC device
361 * @ec_msg: Message to transfer
362 */
363static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
364 struct cros_ec_command *ec_msg)
365{
366 struct ec_host_request *request;
367 struct ec_host_response *response;
368 struct cros_ec_spi *ec_spi = ec_dev->priv;
369 struct spi_transfer trans;
370 struct spi_message msg;
371 int i, len;
372 u8 *ptr;
373 u8 *rx_buf;
374 u8 sum;
375 int ret = 0, final_ret;
376
377 len = cros_ec_prepare_tx(ec_dev, ec_msg);
378 request = (struct ec_host_request *)ec_dev->dout;
379 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
380
381 /* If it's too soon to do another transaction, wait */
382 if (ec_spi->last_transfer_ns) {
383 unsigned long delay; /* The delay completed so far */
384
385 delay = ktime_get_ns() - ec_spi->last_transfer_ns;
386 if (delay < EC_SPI_RECOVERY_TIME_NS)
387 ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
388 }
389
390 rx_buf = kzalloc(len, GFP_KERNEL);
391 if (!rx_buf) {
392 ret = -ENOMEM;
393 goto exit;
394 }
395
396 /* Transmit phase - send our message */
397 memset(&trans, 0, sizeof(trans));
398 trans.tx_buf = ec_dev->dout;
399 trans.rx_buf = rx_buf;
400 trans.len = len;
401 trans.cs_change = 1;
402 spi_message_init(&msg);
403 spi_message_add_tail(&trans, &msg);
404 ret = spi_sync(ec_spi->spi, &msg);
405
406 /* Get the response */
407 if (!ret) {
408 /* Verify that EC can process command */
409 for (i = 0; i < len; i++) {
410 switch (rx_buf[i]) {
411 case EC_SPI_PAST_END:
412 case EC_SPI_RX_BAD_DATA:
413 case EC_SPI_NOT_READY:
414 ret = -EAGAIN;
415 ec_msg->result = EC_RES_IN_PROGRESS;
416 default:
417 break;
418 }
419 if (ret)
420 break;
421 }
422 if (!ret)
423 ret = cros_ec_spi_receive_packet(ec_dev,
424 ec_msg->insize + sizeof(*response));
425 } else {
426 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
427 }
428
429 final_ret = terminate_request(ec_dev);
430 if (!ret)
431 ret = final_ret;
432 if (ret < 0)
433 goto exit;
434
435 ptr = ec_dev->din;
436
437 /* check response error code */
438 response = (struct ec_host_response *)ptr;
439 ec_msg->result = response->result;
440
441 ret = cros_ec_check_result(ec_dev, ec_msg);
442 if (ret)
443 goto exit;
444
445 len = response->data_len;
446 sum = 0;
447 if (len > ec_msg->insize) {
448 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
449 len, ec_msg->insize);
450 ret = -EMSGSIZE;
451 goto exit;
452 }
453
454 for (i = 0; i < sizeof(*response); i++)
455 sum += ptr[i];
456
457 /* copy response packet payload and compute checksum */
458 memcpy(ec_msg->data, ptr + sizeof(*response), len);
459 for (i = 0; i < len; i++)
460 sum += ec_msg->data[i];
461
462 if (sum) {
463 dev_err(ec_dev->dev,
464 "bad packet checksum, calculated %x\n",
465 sum);
466 ret = -EBADMSG;
467 goto exit;
468 }
469
470 ret = len;
471exit:
472 kfree(rx_buf);
473 if (ec_msg->command == EC_CMD_REBOOT_EC)
474 msleep(EC_REBOOT_DELAY_MS);
475
476 return ret;
477}
478
479/**
217 * cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply 480 * cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply
218 * 481 *
219 * @ec_dev: ChromeOS EC device 482 * @ec_dev: ChromeOS EC device
@@ -227,6 +490,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
227 struct spi_message msg; 490 struct spi_message msg;
228 int i, len; 491 int i, len;
229 u8 *ptr; 492 u8 *ptr;
493 u8 *rx_buf;
230 int sum; 494 int sum;
231 int ret = 0, final_ret; 495 int ret = 0, final_ret;
232 496
@@ -242,10 +506,17 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
242 ndelay(EC_SPI_RECOVERY_TIME_NS - delay); 506 ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
243 } 507 }
244 508
509 rx_buf = kzalloc(len, GFP_KERNEL);
510 if (!rx_buf) {
511 ret = -ENOMEM;
512 goto exit;
513 }
514
245 /* Transmit phase - send our message */ 515 /* Transmit phase - send our message */
246 debug_packet(ec_dev->dev, "out", ec_dev->dout, len); 516 debug_packet(ec_dev->dev, "out", ec_dev->dout, len);
247 memset(&trans, 0, sizeof(trans)); 517 memset(&trans, 0, sizeof(trans));
248 trans.tx_buf = ec_dev->dout; 518 trans.tx_buf = ec_dev->dout;
519 trans.rx_buf = rx_buf;
249 trans.len = len; 520 trans.len = len;
250 trans.cs_change = 1; 521 trans.cs_change = 1;
251 spi_message_init(&msg); 522 spi_message_init(&msg);
@@ -254,29 +525,32 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
254 525
255 /* Get the response */ 526 /* Get the response */
256 if (!ret) { 527 if (!ret) {
257 ret = cros_ec_spi_receive_response(ec_dev, 528 /* Verify that EC can process command */
258 ec_msg->insize + EC_MSG_TX_PROTO_BYTES); 529 for (i = 0; i < len; i++) {
530 switch (rx_buf[i]) {
531 case EC_SPI_PAST_END:
532 case EC_SPI_RX_BAD_DATA:
533 case EC_SPI_NOT_READY:
534 ret = -EAGAIN;
535 ec_msg->result = EC_RES_IN_PROGRESS;
536 default:
537 break;
538 }
539 if (ret)
540 break;
541 }
542 if (!ret)
543 ret = cros_ec_spi_receive_response(ec_dev,
544 ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
259 } else { 545 } else {
260 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); 546 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
261 } 547 }
262 548
263 /* 549 final_ret = terminate_request(ec_dev);
264 * Turn off CS, possibly adding a delay to ensure the rising edge
265 * doesn't come too soon after the end of the data.
266 */
267 spi_message_init(&msg);
268 memset(&trans, 0, sizeof(trans));
269 trans.delay_usecs = ec_spi->end_of_msg_delay;
270 spi_message_add_tail(&trans, &msg);
271
272 final_ret = spi_sync(ec_spi->spi, &msg);
273 ec_spi->last_transfer_ns = ktime_get_ns();
274 if (!ret) 550 if (!ret)
275 ret = final_ret; 551 ret = final_ret;
276 if (ret < 0) { 552 if (ret < 0)
277 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
278 goto exit; 553 goto exit;
279 }
280 554
281 ptr = ec_dev->din; 555 ptr = ec_dev->din;
282 556
@@ -315,6 +589,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
315 589
316 ret = len; 590 ret = len;
317exit: 591exit:
592 kfree(rx_buf);
318 if (ec_msg->command == EC_CMD_REBOOT_EC) 593 if (ec_msg->command == EC_CMD_REBOOT_EC)
319 msleep(EC_REBOOT_DELAY_MS); 594 msleep(EC_REBOOT_DELAY_MS);
320 595
@@ -361,7 +636,7 @@ static int cros_ec_spi_probe(struct spi_device *spi)
361 ec_dev->priv = ec_spi; 636 ec_dev->priv = ec_spi;
362 ec_dev->irq = spi->irq; 637 ec_dev->irq = spi->irq;
363 ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi; 638 ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi;
364 ec_dev->pkt_xfer = NULL; 639 ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi;
365 ec_dev->ec_name = ec_spi->spi->modalias; 640 ec_dev->ec_name = ec_spi->spi->modalias;
366 ec_dev->phys_name = dev_name(&ec_spi->spi->dev); 641 ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
367 ec_dev->din_size = EC_MSG_PREAMBLE_COUNT + 642 ec_dev->din_size = EC_MSG_PREAMBLE_COUNT +
@@ -369,6 +644,7 @@ static int cros_ec_spi_probe(struct spi_device *spi)
369 sizeof(struct ec_response_get_protocol_info); 644 sizeof(struct ec_response_get_protocol_info);
370 ec_dev->dout_size = sizeof(struct ec_host_request); 645 ec_dev->dout_size = sizeof(struct ec_host_request);
371 646
647
372 err = cros_ec_register(ec_dev); 648 err = cros_ec_register(ec_dev);
373 if (err) { 649 if (err) {
374 dev_err(dev, "cannot register EC\n"); 650 dev_err(dev, "cannot register EC\n");