Lines Matching +full:cros +full:- +full:ec +full:- +full:spi

1 // SPDX-License-Identifier: GPL-2.0
2 // SPI interface for ChromeOS Embedded Controller
14 #include <linux/spi/spi.h>
23 * Number of EC preamble bytes we read at a time. Since it takes
24 * about 400-500us for the EC to respond there is not a lot of
25 * point in tuning this. If the EC could respond faster then
28 * SPI transfer size is 256 bytes, so at 5MHz we need a response
34 * Allow for a long time for the EC to respond. We support i2c
50 * for this, clocking in at 2-3ms.
55 * Time between raising the SPI chip select (for the end of a
57 * If we go too fast, the EC will miss the transaction. We know that we
58 * need at least 70 us with the 16 MHz STM32 EC, so go with 200 us to be
64 * struct cros_ec_spi - information about a SPI-connected EC
66 * @spi: SPI device we are connected to
75 struct spi_device *spi; member
86 * struct cros_ec_xfer_work_params - params for our high priority workers
90 * @ec_dev: ChromeOS EC device
113 struct cros_ec_spi *ec_spi = ec_dev->priv; in terminate_request()
124 trans.delay.value = ec_spi->end_of_msg_delay; in terminate_request()
128 ret = spi_sync_locked(ec_spi->spi, &msg); in terminate_request()
130 /* Reset end-of-response timer */ in terminate_request()
131 ec_spi->last_transfer_ns = ktime_get_ns(); in terminate_request()
133 dev_err(ec_dev->dev, in terminate_request()
134 "cs-deassert spi transfer failed: %d\n", in terminate_request()
142 * receive_n_bytes - receive n bytes from the EC.
144 * Assumes buf is a pointer into the ec_dev->din buffer
146 * @ec_dev: ChromeOS EC device.
152 struct cros_ec_spi *ec_spi = ec_dev->priv; in receive_n_bytes()
157 if (buf - ec_dev->din + n > ec_dev->din_size) in receive_n_bytes()
158 return -EINVAL; in receive_n_bytes()
167 ret = spi_sync_locked(ec_spi->spi, &msg); in receive_n_bytes()
169 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); in receive_n_bytes()
175 * cros_ec_spi_receive_packet - Receive a packet from the EC.
178 * data from the EC before it is ready to send, we just get preamble) and
181 * The received data is placed into ec_dev->din.
183 * @ec_dev: ChromeOS EC device
195 if (ec_dev->din_size < EC_MSG_PREAMBLE_COUNT) in cros_ec_spi_receive_packet()
196 return -EINVAL; in cros_ec_spi_receive_packet()
204 ec_dev->din, in cros_ec_spi_receive_packet()
209 ptr = ec_dev->din; in cros_ec_spi_receive_packet()
212 dev_dbg(ec_dev->dev, "msg found at %zd\n", in cros_ec_spi_receive_packet()
213 ptr - ec_dev->din); in cros_ec_spi_receive_packet()
226 dev_warn(ec_dev->dev, "EC failed to respond in time\n"); in cros_ec_spi_receive_packet()
227 return -ETIMEDOUT; in cros_ec_spi_receive_packet()
235 todo = end - ++ptr; in cros_ec_spi_receive_packet()
237 memmove(ec_dev->din, ptr, todo); in cros_ec_spi_receive_packet()
238 ptr = ec_dev->din + todo; in cros_ec_spi_receive_packet()
239 dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n", in cros_ec_spi_receive_packet()
241 need_len -= todo; in cros_ec_spi_receive_packet()
245 ret = receive_n_bytes(ec_dev, ptr, sizeof(*response) - todo); in cros_ec_spi_receive_packet()
247 return -EBADMSG; in cros_ec_spi_receive_packet()
248 ptr += (sizeof(*response) - todo); in cros_ec_spi_receive_packet()
252 response = (struct ec_host_response *)ec_dev->din; in cros_ec_spi_receive_packet()
255 if (response->data_len > ec_dev->din_size) in cros_ec_spi_receive_packet()
256 return -EMSGSIZE; in cros_ec_spi_receive_packet()
261 * We can't support transfers larger than the SPI FIFO size in cros_ec_spi_receive_packet()
262 * unless we have DMA. We don't have DMA on the ISP SPI ports in cros_ec_spi_receive_packet()
263 * for Exynos. We need a way of asking SPI driver for in cros_ec_spi_receive_packet()
264 * maximum-supported transfer size. in cros_ec_spi_receive_packet()
267 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", in cros_ec_spi_receive_packet()
268 todo, need_len, ptr - ec_dev->din); in cros_ec_spi_receive_packet()
275 need_len -= todo; in cros_ec_spi_receive_packet()
278 dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din); in cros_ec_spi_receive_packet()
284 * cros_ec_spi_receive_response - Receive a response from the EC.
287 * data from the EC before it is ready to send, we just get preamble) and
290 * The received data is placed into ec_dev->din.
292 * @ec_dev: ChromeOS EC device
303 if (ec_dev->din_size < EC_MSG_PREAMBLE_COUNT) in cros_ec_spi_receive_response()
304 return -EINVAL; in cros_ec_spi_receive_response()
312 ec_dev->din, in cros_ec_spi_receive_response()
317 ptr = ec_dev->din; in cros_ec_spi_receive_response()
320 dev_dbg(ec_dev->dev, "msg found at %zd\n", in cros_ec_spi_receive_response()
321 ptr - ec_dev->din); in cros_ec_spi_receive_response()
334 dev_warn(ec_dev->dev, "EC failed to respond in time\n"); in cros_ec_spi_receive_response()
335 return -ETIMEDOUT; in cros_ec_spi_receive_response()
343 todo = end - ++ptr; in cros_ec_spi_receive_response()
345 memmove(ec_dev->din, ptr, todo); in cros_ec_spi_receive_response()
346 ptr = ec_dev->din + todo; in cros_ec_spi_receive_response()
347 dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n", in cros_ec_spi_receive_response()
349 need_len -= todo; in cros_ec_spi_receive_response()
354 * We can't support transfers larger than the SPI FIFO size in cros_ec_spi_receive_response()
355 * unless we have DMA. We don't have DMA on the ISP SPI ports in cros_ec_spi_receive_response()
356 * for Exynos. We need a way of asking SPI driver for in cros_ec_spi_receive_response()
357 * maximum-supported transfer size. in cros_ec_spi_receive_response()
360 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", in cros_ec_spi_receive_response()
361 todo, need_len, ptr - ec_dev->din); in cros_ec_spi_receive_response()
367 debug_packet(ec_dev->dev, "interim", ptr, todo); in cros_ec_spi_receive_response()
369 need_len -= todo; in cros_ec_spi_receive_response()
372 dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din); in cros_ec_spi_receive_response()
378 * do_cros_ec_pkt_xfer_spi - Transfer a packet over SPI and receive the reply
380 * @ec_dev: ChromeOS EC device
387 struct cros_ec_spi *ec_spi = ec_dev->priv; in do_cros_ec_pkt_xfer_spi()
401 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); in do_cros_ec_pkt_xfer_spi()
404 delay = ktime_get_ns() - ec_spi->last_transfer_ns; in do_cros_ec_pkt_xfer_spi()
406 ndelay(EC_SPI_RECOVERY_TIME_NS - delay); in do_cros_ec_pkt_xfer_spi()
410 return -ENOMEM; in do_cros_ec_pkt_xfer_spi()
412 spi_bus_lock(ec_spi->spi->controller); in do_cros_ec_pkt_xfer_spi()
416 * EC time to wakeup. in do_cros_ec_pkt_xfer_spi()
419 if (ec_spi->start_of_msg_delay) { in do_cros_ec_pkt_xfer_spi()
421 trans_delay.delay.value = ec_spi->start_of_msg_delay; in do_cros_ec_pkt_xfer_spi()
426 /* Transmit phase - send our message */ in do_cros_ec_pkt_xfer_spi()
428 trans.tx_buf = ec_dev->dout; in do_cros_ec_pkt_xfer_spi()
433 ret = spi_sync_locked(ec_spi->spi, &msg); in do_cros_ec_pkt_xfer_spi()
437 /* Verify that EC can process command */ in do_cros_ec_pkt_xfer_spi()
442 * markers are all signs that the EC didn't fully in do_cros_ec_pkt_xfer_spi()
443 * receive our command. e.g., if the EC is flashing in do_cros_ec_pkt_xfer_spi()
445 * clocks out EC_SPI_PAST_END from its SPI hardware in do_cros_ec_pkt_xfer_spi()
447 * too slow to clock out data after asserting CS -- the in do_cros_ec_pkt_xfer_spi()
448 * EC will abort and fill its buffer with in do_cros_ec_pkt_xfer_spi()
452 * Report -EAGAIN and let the caller decide what to do in do_cros_ec_pkt_xfer_spi()
458 ret = -EAGAIN; in do_cros_ec_pkt_xfer_spi()
466 ec_msg->insize + sizeof(*response)); in do_cros_ec_pkt_xfer_spi()
467 else if (ret != -EAGAIN) in do_cros_ec_pkt_xfer_spi()
468 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); in do_cros_ec_pkt_xfer_spi()
472 spi_bus_unlock(ec_spi->spi->controller); in do_cros_ec_pkt_xfer_spi()
479 ptr = ec_dev->din; in do_cros_ec_pkt_xfer_spi()
483 ec_msg->result = response->result; in do_cros_ec_pkt_xfer_spi()
489 len = response->data_len; in do_cros_ec_pkt_xfer_spi()
491 if (len > ec_msg->insize) { in do_cros_ec_pkt_xfer_spi()
492 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", in do_cros_ec_pkt_xfer_spi()
493 len, ec_msg->insize); in do_cros_ec_pkt_xfer_spi()
494 ret = -EMSGSIZE; in do_cros_ec_pkt_xfer_spi()
502 memcpy(ec_msg->data, ptr + sizeof(*response), len); in do_cros_ec_pkt_xfer_spi()
504 sum += ec_msg->data[i]; in do_cros_ec_pkt_xfer_spi()
507 dev_err(ec_dev->dev, in do_cros_ec_pkt_xfer_spi()
510 ret = -EBADMSG; in do_cros_ec_pkt_xfer_spi()
517 if (ec_msg->command == EC_CMD_REBOOT_EC) in do_cros_ec_pkt_xfer_spi()
524 * do_cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply
526 * @ec_dev: ChromeOS EC device
532 struct cros_ec_spi *ec_spi = ec_dev->priv; in do_cros_ec_cmd_xfer_spi()
546 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); in do_cros_ec_cmd_xfer_spi()
549 delay = ktime_get_ns() - ec_spi->last_transfer_ns; in do_cros_ec_cmd_xfer_spi()
551 ndelay(EC_SPI_RECOVERY_TIME_NS - delay); in do_cros_ec_cmd_xfer_spi()
555 return -ENOMEM; in do_cros_ec_cmd_xfer_spi()
557 spi_bus_lock(ec_spi->spi->controller); in do_cros_ec_cmd_xfer_spi()
559 /* Transmit phase - send our message */ in do_cros_ec_cmd_xfer_spi()
560 debug_packet(ec_dev->dev, "out", ec_dev->dout, len); in do_cros_ec_cmd_xfer_spi()
562 trans.tx_buf = ec_dev->dout; in do_cros_ec_cmd_xfer_spi()
568 ret = spi_sync_locked(ec_spi->spi, &msg); in do_cros_ec_cmd_xfer_spi()
572 /* Verify that EC can process command */ in do_cros_ec_cmd_xfer_spi()
579 ret = -EAGAIN; in do_cros_ec_cmd_xfer_spi()
587 ec_msg->insize + EC_MSG_TX_PROTO_BYTES); in do_cros_ec_cmd_xfer_spi()
588 else if (ret != -EAGAIN) in do_cros_ec_cmd_xfer_spi()
589 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); in do_cros_ec_cmd_xfer_spi()
593 spi_bus_unlock(ec_spi->spi->controller); in do_cros_ec_cmd_xfer_spi()
600 ptr = ec_dev->din; in do_cros_ec_cmd_xfer_spi()
603 ec_msg->result = ptr[0]; in do_cros_ec_cmd_xfer_spi()
610 if (len > ec_msg->insize) { in do_cros_ec_cmd_xfer_spi()
611 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", in do_cros_ec_cmd_xfer_spi()
612 len, ec_msg->insize); in do_cros_ec_cmd_xfer_spi()
613 ret = -ENOSPC; in do_cros_ec_cmd_xfer_spi()
620 if (ec_msg->insize) in do_cros_ec_cmd_xfer_spi()
621 ec_msg->data[i] = ptr[i + 2]; in do_cros_ec_cmd_xfer_spi()
625 debug_packet(ec_dev->dev, "in", ptr, len + 3); in do_cros_ec_cmd_xfer_spi()
628 dev_err(ec_dev->dev, in do_cros_ec_cmd_xfer_spi()
631 ret = -EBADMSG; in do_cros_ec_cmd_xfer_spi()
638 if (ec_msg->command == EC_CMD_REBOOT_EC) in do_cros_ec_cmd_xfer_spi()
649 params->ret = params->fn(params->ec_dev, params->ec_msg); in cros_ec_xfer_high_pri_work()
656 struct cros_ec_spi *ec_spi = ec_dev->priv; in cros_ec_xfer_high_pri()
671 * context switched out for too long and the EC giving up on in cros_ec_xfer_high_pri()
674 kthread_queue_work(ec_spi->high_pri_worker, &params.work); in cros_ec_xfer_high_pri()
694 struct device_node *np = dev->of_node; in cros_ec_spi_dt_probe()
698 ret = of_property_read_u32(np, "google,cros-ec-spi-pre-delay", &val); in cros_ec_spi_dt_probe()
700 ec_spi->start_of_msg_delay = val; in cros_ec_spi_dt_probe()
702 ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val); in cros_ec_spi_dt_probe()
704 ec_spi->end_of_msg_delay = val; in cros_ec_spi_dt_probe()
717 ec_spi->high_pri_worker = in cros_ec_spi_devm_high_pri_alloc()
720 if (IS_ERR(ec_spi->high_pri_worker)) { in cros_ec_spi_devm_high_pri_alloc()
721 err = PTR_ERR(ec_spi->high_pri_worker); in cros_ec_spi_devm_high_pri_alloc()
727 ec_spi->high_pri_worker); in cros_ec_spi_devm_high_pri_alloc()
731 sched_set_fifo(ec_spi->high_pri_worker->task); in cros_ec_spi_devm_high_pri_alloc()
736 static int cros_ec_spi_probe(struct spi_device *spi) in cros_ec_spi_probe() argument
738 struct device *dev = &spi->dev; in cros_ec_spi_probe()
743 spi->rt = true; in cros_ec_spi_probe()
744 err = spi_setup(spi); in cros_ec_spi_probe()
750 return -ENOMEM; in cros_ec_spi_probe()
751 ec_spi->spi = spi; in cros_ec_spi_probe()
754 return -ENOMEM; in cros_ec_spi_probe()
759 spi_set_drvdata(spi, ec_dev); in cros_ec_spi_probe()
760 ec_dev->dev = dev; in cros_ec_spi_probe()
761 ec_dev->priv = ec_spi; in cros_ec_spi_probe()
762 ec_dev->irq = spi->irq; in cros_ec_spi_probe()
763 ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi; in cros_ec_spi_probe()
764 ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi; in cros_ec_spi_probe()
765 ec_dev->phys_name = dev_name(&ec_spi->spi->dev); in cros_ec_spi_probe()
766 ec_dev->din_size = EC_MSG_PREAMBLE_COUNT + in cros_ec_spi_probe()
769 ec_dev->dout_size = sizeof(struct ec_host_request); in cros_ec_spi_probe()
771 ec_spi->last_transfer_ns = ktime_get_ns(); in cros_ec_spi_probe()
779 dev_err(dev, "cannot register EC\n"); in cros_ec_spi_probe()
783 device_init_wakeup(&spi->dev, true); in cros_ec_spi_probe()
788 static void cros_ec_spi_remove(struct spi_device *spi) in cros_ec_spi_remove() argument
790 struct cros_ec_device *ec_dev = spi_get_drvdata(spi); in cros_ec_spi_remove()
815 { .compatible = "google,cros-ec-spi", },
821 { "cros-ec-spi", 0 },
824 MODULE_DEVICE_TABLE(spi, cros_ec_spi_id);
828 .name = "cros-ec-spi",
841 MODULE_DESCRIPTION("SPI interface for ChromeOS Embedded Controller");