GNU Linux-libre 4.14.332-gnu1
[releases.git] / drivers / platform / chrome / cros_ec_proto.c
1 /*
2  * ChromeOS EC communication protocol helper functions
3  *
4  * Copyright (C) 2015 Google, Inc
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/mfd/cros_ec.h>
18 #include <linux/delay.h>
19 #include <linux/device.h>
20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <asm/unaligned.h>
23
24 #define EC_COMMAND_RETRIES      50
25
26 static int prepare_packet(struct cros_ec_device *ec_dev,
27                           struct cros_ec_command *msg)
28 {
29         struct ec_host_request *request;
30         u8 *out;
31         int i;
32         u8 csum = 0;
33
34         BUG_ON(ec_dev->proto_version != EC_HOST_REQUEST_VERSION);
35         BUG_ON(msg->outsize + sizeof(*request) > ec_dev->dout_size);
36
37         out = ec_dev->dout;
38         request = (struct ec_host_request *)out;
39         request->struct_version = EC_HOST_REQUEST_VERSION;
40         request->checksum = 0;
41         request->command = msg->command;
42         request->command_version = msg->version;
43         request->reserved = 0;
44         request->data_len = msg->outsize;
45
46         for (i = 0; i < sizeof(*request); i++)
47                 csum += out[i];
48
49         /* Copy data and update checksum */
50         memcpy(out + sizeof(*request), msg->data, msg->outsize);
51         for (i = 0; i < msg->outsize; i++)
52                 csum += msg->data[i];
53
54         request->checksum = -csum;
55
56         return sizeof(*request) + msg->outsize;
57 }
58
59 static int send_command(struct cros_ec_device *ec_dev,
60                         struct cros_ec_command *msg)
61 {
62         int ret;
63         int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
64
65         if (ec_dev->proto_version > 2)
66                 xfer_fxn = ec_dev->pkt_xfer;
67         else
68                 xfer_fxn = ec_dev->cmd_xfer;
69
70         if (!xfer_fxn) {
71                 /*
72                  * This error can happen if a communication error happened and
73                  * the EC is trying to use protocol v2, on an underlying
74                  * communication mechanism that does not support v2.
75                  */
76                 dev_err_once(ec_dev->dev,
77                              "missing EC transfer API, cannot send command\n");
78                 return -EIO;
79         }
80
81         ret = (*xfer_fxn)(ec_dev, msg);
82         if (msg->result == EC_RES_IN_PROGRESS) {
83                 int i;
84                 struct cros_ec_command *status_msg;
85                 struct ec_response_get_comms_status *status;
86
87                 status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
88                                      GFP_KERNEL);
89                 if (!status_msg)
90                         return -ENOMEM;
91
92                 status_msg->version = 0;
93                 status_msg->command = EC_CMD_GET_COMMS_STATUS;
94                 status_msg->insize = sizeof(*status);
95                 status_msg->outsize = 0;
96
97                 /*
98                  * Query the EC's status until it's no longer busy or
99                  * we encounter an error.
100                  */
101                 for (i = 0; i < EC_COMMAND_RETRIES; i++) {
102                         usleep_range(10000, 11000);
103
104                         ret = (*xfer_fxn)(ec_dev, status_msg);
105                         if (ret < 0)
106                                 break;
107
108                         msg->result = status_msg->result;
109                         if (status_msg->result != EC_RES_SUCCESS)
110                                 break;
111
112                         status = (struct ec_response_get_comms_status *)
113                                  status_msg->data;
114                         if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
115                                 break;
116                 }
117
118                 kfree(status_msg);
119         }
120
121         return ret;
122 }
123
124 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
125                        struct cros_ec_command *msg)
126 {
127         u8 *out;
128         u8 csum;
129         int i;
130
131         if (ec_dev->proto_version > 2)
132                 return prepare_packet(ec_dev, msg);
133
134         BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
135         out = ec_dev->dout;
136         out[0] = EC_CMD_VERSION0 + msg->version;
137         out[1] = msg->command;
138         out[2] = msg->outsize;
139         csum = out[0] + out[1] + out[2];
140         for (i = 0; i < msg->outsize; i++)
141                 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
142         out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
143
144         return EC_MSG_TX_PROTO_BYTES + msg->outsize;
145 }
146 EXPORT_SYMBOL(cros_ec_prepare_tx);
147
148 int cros_ec_check_result(struct cros_ec_device *ec_dev,
149                          struct cros_ec_command *msg)
150 {
151         switch (msg->result) {
152         case EC_RES_SUCCESS:
153                 return 0;
154         case EC_RES_IN_PROGRESS:
155                 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
156                         msg->command);
157                 return -EAGAIN;
158         default:
159                 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
160                         msg->command, msg->result);
161                 return 0;
162         }
163 }
164 EXPORT_SYMBOL(cros_ec_check_result);
165
166 /*
167  * cros_ec_get_host_event_wake_mask
168  *
169  * Get the mask of host events that cause wake from suspend.
170  *
171  * @ec_dev: EC device to call
172  * @msg: message structure to use
173  * @mask: result when function returns >=0.
174  *
175  * LOCKING:
176  * the caller has ec_dev->lock mutex, or the caller knows there is
177  * no other command in progress.
178  */
179 static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev,
180                                             struct cros_ec_command *msg,
181                                             uint32_t *mask)
182 {
183         struct ec_response_host_event_mask *r;
184         int ret;
185
186         msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
187         msg->version = 0;
188         msg->outsize = 0;
189         msg->insize = sizeof(*r);
190
191         ret = send_command(ec_dev, msg);
192         if (ret > 0) {
193                 r = (struct ec_response_host_event_mask *)msg->data;
194                 *mask = r->mask;
195         }
196
197         return ret;
198 }
199
200 static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
201                                             int devidx,
202                                             struct cros_ec_command *msg)
203 {
204         /*
205          * Try using v3+ to query for supported protocols. If this
206          * command fails, fall back to v2. Returns the highest protocol
207          * supported by the EC.
208          * Also sets the max request/response/passthru size.
209          */
210         int ret;
211
212         if (!ec_dev->pkt_xfer)
213                 return -EPROTONOSUPPORT;
214
215         memset(msg, 0, sizeof(*msg));
216         msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
217         msg->insize = sizeof(struct ec_response_get_protocol_info);
218
219         ret = send_command(ec_dev, msg);
220         /*
221          * Send command once again when timeout occurred.
222          * Fingerprint MCU (FPMCU) is restarted during system boot which
223          * introduces small window in which FPMCU won't respond for any
224          * messages sent by kernel. There is no need to wait before next
225          * attempt because we waited at least EC_MSG_DEADLINE_MS.
226          */
227         if (ret == -ETIMEDOUT)
228                 ret = send_command(ec_dev, msg);
229
230         if (ret < 0) {
231                 dev_dbg(ec_dev->dev,
232                         "failed to check for EC[%d] protocol version: %d\n",
233                         devidx, ret);
234                 return ret;
235         }
236
237         if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND)
238                 return -ENODEV;
239         else if (msg->result != EC_RES_SUCCESS)
240                 return msg->result;
241
242         return 0;
243 }
244
245 static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)
246 {
247         struct cros_ec_command *msg;
248         struct ec_params_hello *hello_params;
249         struct ec_response_hello *hello_response;
250         int ret;
251         int len = max(sizeof(*hello_params), sizeof(*hello_response));
252
253         msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
254         if (!msg)
255                 return -ENOMEM;
256
257         msg->version = 0;
258         msg->command = EC_CMD_HELLO;
259         hello_params = (struct ec_params_hello *)msg->data;
260         msg->outsize = sizeof(*hello_params);
261         hello_response = (struct ec_response_hello *)msg->data;
262         msg->insize = sizeof(*hello_response);
263
264         hello_params->in_data = 0xa0b0c0d0;
265
266         ret = send_command(ec_dev, msg);
267
268         if (ret < 0) {
269                 dev_dbg(ec_dev->dev,
270                         "EC failed to respond to v2 hello: %d\n",
271                         ret);
272                 goto exit;
273         } else if (msg->result != EC_RES_SUCCESS) {
274                 dev_err(ec_dev->dev,
275                         "EC responded to v2 hello with error: %d\n",
276                         msg->result);
277                 ret = msg->result;
278                 goto exit;
279         } else if (hello_response->out_data != 0xa1b2c3d4) {
280                 dev_err(ec_dev->dev,
281                         "EC responded to v2 hello with bad result: %u\n",
282                         hello_response->out_data);
283                 ret = -EBADMSG;
284                 goto exit;
285         }
286
287         ret = 0;
288
289  exit:
290         kfree(msg);
291         return ret;
292 }
293
294 /*
295  * cros_ec_get_host_command_version_mask
296  *
297  * Get the version mask of a given command.
298  *
299  * @ec_dev: EC device to call
300  * @msg: message structure to use
301  * @cmd: command to get the version of.
302  * @mask: result when function returns 0.
303  *
304  * @return 0 on success, error code otherwise
305  *
306  * LOCKING:
307  * the caller has ec_dev->lock mutex or the caller knows there is
308  * no other command in progress.
309  */
310 static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev,
311         u16 cmd, u32 *mask)
312 {
313         struct ec_params_get_cmd_versions *pver;
314         struct ec_response_get_cmd_versions *rver;
315         struct cros_ec_command *msg;
316         int ret;
317
318         msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
319                       GFP_KERNEL);
320         if (!msg)
321                 return -ENOMEM;
322
323         msg->version = 0;
324         msg->command = EC_CMD_GET_CMD_VERSIONS;
325         msg->insize = sizeof(*rver);
326         msg->outsize = sizeof(*pver);
327
328         pver = (struct ec_params_get_cmd_versions *)msg->data;
329         pver->cmd = cmd;
330
331         ret = send_command(ec_dev, msg);
332         if (ret > 0) {
333                 rver = (struct ec_response_get_cmd_versions *)msg->data;
334                 *mask = rver->version_mask;
335         }
336
337         kfree(msg);
338
339         return ret;
340 }
341
342 int cros_ec_query_all(struct cros_ec_device *ec_dev)
343 {
344         struct device *dev = ec_dev->dev;
345         struct cros_ec_command *proto_msg;
346         struct ec_response_get_protocol_info *proto_info;
347         u32 ver_mask = 0;
348         int ret;
349
350         proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
351                             GFP_KERNEL);
352         if (!proto_msg)
353                 return -ENOMEM;
354
355         /* First try sending with proto v3. */
356         ec_dev->proto_version = 3;
357         ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);
358
359         if (ret == 0) {
360                 proto_info = (struct ec_response_get_protocol_info *)
361                         proto_msg->data;
362                 ec_dev->max_request = proto_info->max_request_packet_size -
363                         sizeof(struct ec_host_request);
364                 ec_dev->max_response = proto_info->max_response_packet_size -
365                         sizeof(struct ec_host_response);
366                 ec_dev->proto_version =
367                         min(EC_HOST_REQUEST_VERSION,
368                                         fls(proto_info->protocol_versions) - 1);
369                 dev_dbg(ec_dev->dev,
370                         "using proto v%u\n",
371                         ec_dev->proto_version);
372
373                 ec_dev->din_size = ec_dev->max_response +
374                         sizeof(struct ec_host_response) +
375                         EC_MAX_RESPONSE_OVERHEAD;
376                 ec_dev->dout_size = ec_dev->max_request +
377                         sizeof(struct ec_host_request) +
378                         EC_MAX_REQUEST_OVERHEAD;
379
380                 /*
381                  * Check for PD
382                  */
383                 ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);
384
385                 if (ret) {
386                         dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
387                         ec_dev->max_passthru = 0;
388                 } else {
389                         dev_dbg(ec_dev->dev, "found PD chip\n");
390                         ec_dev->max_passthru =
391                                 proto_info->max_request_packet_size -
392                                 sizeof(struct ec_host_request);
393                 }
394         } else {
395                 /* Try querying with a v2 hello message. */
396                 ec_dev->proto_version = 2;
397                 ret = cros_ec_host_command_proto_query_v2(ec_dev);
398
399                 if (ret == 0) {
400                         /* V2 hello succeeded. */
401                         dev_dbg(ec_dev->dev, "falling back to proto v2\n");
402
403                         ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
404                         ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
405                         ec_dev->max_passthru = 0;
406                         ec_dev->pkt_xfer = NULL;
407                         ec_dev->din_size = EC_PROTO2_MSG_BYTES;
408                         ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
409                 } else {
410                         /*
411                          * It's possible for a test to occur too early when
412                          * the EC isn't listening. If this happens, we'll
413                          * test later when the first command is run.
414                          */
415                         ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
416                         dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
417                         goto exit;
418                 }
419         }
420
421         devm_kfree(dev, ec_dev->din);
422         devm_kfree(dev, ec_dev->dout);
423
424         ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
425         if (!ec_dev->din) {
426                 ret = -ENOMEM;
427                 goto exit;
428         }
429
430         ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
431         if (!ec_dev->dout) {
432                 devm_kfree(dev, ec_dev->din);
433                 ret = -ENOMEM;
434                 goto exit;
435         }
436
437         /* Probe if MKBP event is supported */
438         ret = cros_ec_get_host_command_version_mask(ec_dev,
439                                                     EC_CMD_GET_NEXT_EVENT,
440                                                     &ver_mask);
441         if (ret < 0 || ver_mask == 0)
442                 ec_dev->mkbp_event_supported = 0;
443         else
444                 ec_dev->mkbp_event_supported = 1;
445
446         /*
447          * Get host event wake mask, assume all events are wake events
448          * if unavailable.
449          */
450         ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg,
451                                                &ec_dev->host_event_wake_mask);
452         if (ret < 0)
453                 ec_dev->host_event_wake_mask = U32_MAX;
454
455         ret = 0;
456
457 exit:
458         kfree(proto_msg);
459         return ret;
460 }
461 EXPORT_SYMBOL(cros_ec_query_all);
462
463 int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
464                      struct cros_ec_command *msg)
465 {
466         int ret;
467
468         mutex_lock(&ec_dev->lock);
469         if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) {
470                 ret = cros_ec_query_all(ec_dev);
471                 if (ret) {
472                         dev_err(ec_dev->dev,
473                                 "EC version unknown and query failed; aborting command\n");
474                         mutex_unlock(&ec_dev->lock);
475                         return ret;
476                 }
477         }
478
479         if (msg->insize > ec_dev->max_response) {
480                 dev_dbg(ec_dev->dev, "clamping message receive buffer\n");
481                 msg->insize = ec_dev->max_response;
482         }
483
484         if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {
485                 if (msg->outsize > ec_dev->max_request) {
486                         dev_err(ec_dev->dev,
487                                 "request of size %u is too big (max: %u)\n",
488                                 msg->outsize,
489                                 ec_dev->max_request);
490                         mutex_unlock(&ec_dev->lock);
491                         return -EMSGSIZE;
492                 }
493         } else {
494                 if (msg->outsize > ec_dev->max_passthru) {
495                         dev_err(ec_dev->dev,
496                                 "passthru rq of size %u is too big (max: %u)\n",
497                                 msg->outsize,
498                                 ec_dev->max_passthru);
499                         mutex_unlock(&ec_dev->lock);
500                         return -EMSGSIZE;
501                 }
502         }
503         ret = send_command(ec_dev, msg);
504         mutex_unlock(&ec_dev->lock);
505
506         return ret;
507 }
508 EXPORT_SYMBOL(cros_ec_cmd_xfer);
509
510 int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
511                             struct cros_ec_command *msg)
512 {
513         int ret;
514
515         ret = cros_ec_cmd_xfer(ec_dev, msg);
516         if (ret < 0) {
517                 dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret);
518         } else if (msg->result != EC_RES_SUCCESS) {
519                 dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result);
520                 return -EPROTO;
521         }
522
523         return ret;
524 }
525 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
526
527 static int get_next_event(struct cros_ec_device *ec_dev)
528 {
529         u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
530         struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
531         int ret;
532
533         if (ec_dev->suspended) {
534                 dev_dbg(ec_dev->dev, "Device suspended.\n");
535                 return -EHOSTDOWN;
536         }
537
538         msg->version = 0;
539         msg->command = EC_CMD_GET_NEXT_EVENT;
540         msg->insize = sizeof(ec_dev->event_data);
541         msg->outsize = 0;
542
543         ret = cros_ec_cmd_xfer(ec_dev, msg);
544         if (ret > 0) {
545                 ec_dev->event_size = ret - 1;
546                 memcpy(&ec_dev->event_data, msg->data,
547                        sizeof(ec_dev->event_data));
548         }
549
550         return ret;
551 }
552
553 static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
554 {
555         u8 buffer[sizeof(struct cros_ec_command) +
556                   sizeof(ec_dev->event_data.data)];
557         struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
558
559         msg->version = 0;
560         msg->command = EC_CMD_MKBP_STATE;
561         msg->insize = sizeof(ec_dev->event_data.data);
562         msg->outsize = 0;
563
564         ec_dev->event_size = cros_ec_cmd_xfer(ec_dev, msg);
565         ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX;
566         memcpy(&ec_dev->event_data.data, msg->data,
567                sizeof(ec_dev->event_data.data));
568
569         return ec_dev->event_size;
570 }
571
572 int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event)
573 {
574         u8 event_type;
575         u32 host_event;
576         int ret;
577
578         if (!ec_dev->mkbp_event_supported) {
579                 ret = get_keyboard_state_event(ec_dev);
580                 if (ret < 0)
581                         return ret;
582
583                 if (wake_event)
584                         *wake_event = true;
585
586                 return ret;
587         }
588
589         ret = get_next_event(ec_dev);
590         if (ret < 0)
591                 return ret;
592
593         if (wake_event) {
594                 event_type = ec_dev->event_data.event_type;
595                 host_event = cros_ec_get_host_event(ec_dev);
596
597                 /*
598                  * Sensor events need to be parsed by the sensor sub-device.
599                  * Defer them, and don't report the wakeup here.
600                  */
601                 if (event_type == EC_MKBP_EVENT_SENSOR_FIFO)
602                         *wake_event = false;
603                 /* Masked host-events should not count as wake events. */
604                 else if (host_event &&
605                          !(host_event & ec_dev->host_event_wake_mask))
606                         *wake_event = false;
607                 /* Consider all other events as wake events. */
608                 else
609                         *wake_event = true;
610         }
611
612         return ret;
613 }
614 EXPORT_SYMBOL(cros_ec_get_next_event);
615
616 u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev)
617 {
618         u32 host_event;
619
620         BUG_ON(!ec_dev->mkbp_event_supported);
621
622         if (ec_dev->event_data.event_type != EC_MKBP_EVENT_HOST_EVENT)
623                 return 0;
624
625         if (ec_dev->event_size != sizeof(host_event)) {
626                 dev_warn(ec_dev->dev, "Invalid host event size\n");
627                 return 0;
628         }
629
630         host_event = get_unaligned_le32(&ec_dev->event_data.data.host_event);
631
632         return host_event;
633 }
634 EXPORT_SYMBOL(cros_ec_get_host_event);