Lines Matching +full:spi +full:- +full:cs +full:- +full:high
1 // SPDX-License-Identifier: GPL-2.0
2 // SPI interface for ChromeOS Embedded Controller
14 #include <linux/spi/spi.h>
24 * about 400-500us for the EC to respond there is not a lot of
28 * SPI transfer size is 256 bytes, so at 5MHz we need a response
50 * for this, clocking in at 2-3ms.
55 * Time between raising the SPI chip select (for the end of a
64 * struct cros_ec_spi - information about a SPI-connected EC
66 * @spi: SPI device we are connected to
69 * is sent when we want to turn on CS at the start of a transaction.
71 * is sent when we want to turn off CS at the end of a transaction.
72 * @high_pri_worker: Used to schedule high priority work.
75 struct spi_device *spi; member
86 * struct cros_ec_xfer_work_params - params for our high priority workers
119 struct cros_ec_spi *ec_spi = ec_dev->priv; in terminate_request()
125 * Turn off CS, possibly adding a delay to ensure the rising edge in terminate_request()
130 trans.delay.value = ec_spi->end_of_msg_delay; in terminate_request()
134 ret = spi_sync_locked(ec_spi->spi, &msg); in terminate_request()
136 /* Reset end-of-response timer */ in terminate_request()
137 ec_spi->last_transfer_ns = ktime_get_ns(); in terminate_request()
139 dev_err(ec_dev->dev, in terminate_request()
140 "cs-deassert spi transfer failed: %d\n", in terminate_request()
148 * receive_n_bytes - receive n bytes from the EC.
150 * Assumes buf is a pointer into the ec_dev->din buffer
158 struct cros_ec_spi *ec_spi = ec_dev->priv; in receive_n_bytes()
163 BUG_ON(buf - ec_dev->din + n > ec_dev->din_size); in receive_n_bytes()
172 ret = spi_sync_locked(ec_spi->spi, &msg); in receive_n_bytes()
174 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); in receive_n_bytes()
180 * cros_ec_spi_receive_packet - Receive a packet from the EC.
186 * The received data is placed into ec_dev->din.
200 BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT); in cros_ec_spi_receive_packet()
208 ec_dev->din, in cros_ec_spi_receive_packet()
213 ptr = ec_dev->din; in cros_ec_spi_receive_packet()
216 dev_dbg(ec_dev->dev, "msg found at %zd\n", in cros_ec_spi_receive_packet()
217 ptr - ec_dev->din); in cros_ec_spi_receive_packet()
230 dev_warn(ec_dev->dev, "EC failed to respond in time\n"); in cros_ec_spi_receive_packet()
231 return -ETIMEDOUT; in cros_ec_spi_receive_packet()
239 todo = end - ++ptr; in cros_ec_spi_receive_packet()
240 BUG_ON(todo < 0 || todo > ec_dev->din_size); in cros_ec_spi_receive_packet()
242 memmove(ec_dev->din, ptr, todo); in cros_ec_spi_receive_packet()
243 ptr = ec_dev->din + todo; in cros_ec_spi_receive_packet()
244 dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n", in cros_ec_spi_receive_packet()
246 need_len -= todo; in cros_ec_spi_receive_packet()
250 ret = receive_n_bytes(ec_dev, ptr, sizeof(*response) - todo); in cros_ec_spi_receive_packet()
252 return -EBADMSG; in cros_ec_spi_receive_packet()
253 ptr += (sizeof(*response) - todo); in cros_ec_spi_receive_packet()
257 response = (struct ec_host_response *)ec_dev->din; in cros_ec_spi_receive_packet()
260 if (response->data_len > ec_dev->din_size) in cros_ec_spi_receive_packet()
261 return -EMSGSIZE; in cros_ec_spi_receive_packet()
266 * We can't support transfers larger than the SPI FIFO size in cros_ec_spi_receive_packet()
267 * unless we have DMA. We don't have DMA on the ISP SPI ports in cros_ec_spi_receive_packet()
268 * for Exynos. We need a way of asking SPI driver for in cros_ec_spi_receive_packet()
269 * maximum-supported transfer size. in cros_ec_spi_receive_packet()
272 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", in cros_ec_spi_receive_packet()
273 todo, need_len, ptr - ec_dev->din); in cros_ec_spi_receive_packet()
280 need_len -= todo; in cros_ec_spi_receive_packet()
283 dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din); in cros_ec_spi_receive_packet()
289 * cros_ec_spi_receive_response - Receive a response from the EC.
295 * The received data is placed into ec_dev->din.
308 BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT); in cros_ec_spi_receive_response()
316 ec_dev->din, in cros_ec_spi_receive_response()
321 ptr = ec_dev->din; in cros_ec_spi_receive_response()
324 dev_dbg(ec_dev->dev, "msg found at %zd\n", in cros_ec_spi_receive_response()
325 ptr - ec_dev->din); in cros_ec_spi_receive_response()
338 dev_warn(ec_dev->dev, "EC failed to respond in time\n"); in cros_ec_spi_receive_response()
339 return -ETIMEDOUT; in cros_ec_spi_receive_response()
347 todo = end - ++ptr; in cros_ec_spi_receive_response()
348 BUG_ON(todo < 0 || todo > ec_dev->din_size); in cros_ec_spi_receive_response()
350 memmove(ec_dev->din, ptr, todo); in cros_ec_spi_receive_response()
351 ptr = ec_dev->din + todo; in cros_ec_spi_receive_response()
352 dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n", in cros_ec_spi_receive_response()
354 need_len -= todo; in cros_ec_spi_receive_response()
359 * We can't support transfers larger than the SPI FIFO size in cros_ec_spi_receive_response()
360 * unless we have DMA. We don't have DMA on the ISP SPI ports in cros_ec_spi_receive_response()
361 * for Exynos. We need a way of asking SPI driver for in cros_ec_spi_receive_response()
362 * maximum-supported transfer size. in cros_ec_spi_receive_response()
365 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", in cros_ec_spi_receive_response()
366 todo, need_len, ptr - ec_dev->din); in cros_ec_spi_receive_response()
372 debug_packet(ec_dev->dev, "interim", ptr, todo); in cros_ec_spi_receive_response()
374 need_len -= todo; in cros_ec_spi_receive_response()
377 dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din); in cros_ec_spi_receive_response()
383 * do_cros_ec_pkt_xfer_spi - Transfer a packet over SPI and receive the reply
392 struct cros_ec_spi *ec_spi = ec_dev->priv; in do_cros_ec_pkt_xfer_spi()
404 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); in do_cros_ec_pkt_xfer_spi()
407 delay = ktime_get_ns() - ec_spi->last_transfer_ns; in do_cros_ec_pkt_xfer_spi()
409 ndelay(EC_SPI_RECOVERY_TIME_NS - delay); in do_cros_ec_pkt_xfer_spi()
413 return -ENOMEM; in do_cros_ec_pkt_xfer_spi()
415 spi_bus_lock(ec_spi->spi->master); in do_cros_ec_pkt_xfer_spi()
418 * Leave a gap between CS assertion and clocking of data to allow the in do_cros_ec_pkt_xfer_spi()
422 if (ec_spi->start_of_msg_delay) { in do_cros_ec_pkt_xfer_spi()
424 trans_delay.delay.value = ec_spi->start_of_msg_delay; in do_cros_ec_pkt_xfer_spi()
429 /* Transmit phase - send our message */ in do_cros_ec_pkt_xfer_spi()
431 trans.tx_buf = ec_dev->dout; in do_cros_ec_pkt_xfer_spi()
436 ret = spi_sync_locked(ec_spi->spi, &msg); in do_cros_ec_pkt_xfer_spi()
448 * clocks out EC_SPI_PAST_END from its SPI hardware in do_cros_ec_pkt_xfer_spi()
450 * too slow to clock out data after asserting CS -- the in do_cros_ec_pkt_xfer_spi()
455 * Report -EAGAIN and let the caller decide what to do in do_cros_ec_pkt_xfer_spi()
461 ret = -EAGAIN; in do_cros_ec_pkt_xfer_spi()
469 ec_msg->insize + sizeof(*response)); in do_cros_ec_pkt_xfer_spi()
470 else if (ret != -EAGAIN) in do_cros_ec_pkt_xfer_spi()
471 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); in do_cros_ec_pkt_xfer_spi()
475 spi_bus_unlock(ec_spi->spi->master); in do_cros_ec_pkt_xfer_spi()
482 ptr = ec_dev->din; in do_cros_ec_pkt_xfer_spi()
486 ec_msg->result = response->result; in do_cros_ec_pkt_xfer_spi()
492 len = response->data_len; in do_cros_ec_pkt_xfer_spi()
494 if (len > ec_msg->insize) { in do_cros_ec_pkt_xfer_spi()
495 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", in do_cros_ec_pkt_xfer_spi()
496 len, ec_msg->insize); in do_cros_ec_pkt_xfer_spi()
497 ret = -EMSGSIZE; in do_cros_ec_pkt_xfer_spi()
505 memcpy(ec_msg->data, ptr + sizeof(*response), len); in do_cros_ec_pkt_xfer_spi()
507 sum += ec_msg->data[i]; in do_cros_ec_pkt_xfer_spi()
510 dev_err(ec_dev->dev, in do_cros_ec_pkt_xfer_spi()
513 ret = -EBADMSG; in do_cros_ec_pkt_xfer_spi()
520 if (ec_msg->command == EC_CMD_REBOOT_EC) in do_cros_ec_pkt_xfer_spi()
527 * do_cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply
535 struct cros_ec_spi *ec_spi = ec_dev->priv; in do_cros_ec_cmd_xfer_spi()
547 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); in do_cros_ec_cmd_xfer_spi()
550 delay = ktime_get_ns() - ec_spi->last_transfer_ns; in do_cros_ec_cmd_xfer_spi()
552 ndelay(EC_SPI_RECOVERY_TIME_NS - delay); in do_cros_ec_cmd_xfer_spi()
556 return -ENOMEM; in do_cros_ec_cmd_xfer_spi()
558 spi_bus_lock(ec_spi->spi->master); in do_cros_ec_cmd_xfer_spi()
560 /* Transmit phase - send our message */ in do_cros_ec_cmd_xfer_spi()
561 debug_packet(ec_dev->dev, "out", ec_dev->dout, len); in do_cros_ec_cmd_xfer_spi()
563 trans.tx_buf = ec_dev->dout; in do_cros_ec_cmd_xfer_spi()
569 ret = spi_sync_locked(ec_spi->spi, &msg); in do_cros_ec_cmd_xfer_spi()
580 ret = -EAGAIN; in do_cros_ec_cmd_xfer_spi()
588 ec_msg->insize + EC_MSG_TX_PROTO_BYTES); in do_cros_ec_cmd_xfer_spi()
589 else if (ret != -EAGAIN) in do_cros_ec_cmd_xfer_spi()
590 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); in do_cros_ec_cmd_xfer_spi()
594 spi_bus_unlock(ec_spi->spi->master); in do_cros_ec_cmd_xfer_spi()
601 ptr = ec_dev->din; in do_cros_ec_cmd_xfer_spi()
604 ec_msg->result = ptr[0]; in do_cros_ec_cmd_xfer_spi()
611 if (len > ec_msg->insize) { in do_cros_ec_cmd_xfer_spi()
612 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", in do_cros_ec_cmd_xfer_spi()
613 len, ec_msg->insize); in do_cros_ec_cmd_xfer_spi()
614 ret = -ENOSPC; in do_cros_ec_cmd_xfer_spi()
621 if (ec_msg->insize) in do_cros_ec_cmd_xfer_spi()
622 ec_msg->data[i] = ptr[i + 2]; in do_cros_ec_cmd_xfer_spi()
626 debug_packet(ec_dev->dev, "in", ptr, len + 3); in do_cros_ec_cmd_xfer_spi()
629 dev_err(ec_dev->dev, in do_cros_ec_cmd_xfer_spi()
632 ret = -EBADMSG; in do_cros_ec_cmd_xfer_spi()
639 if (ec_msg->command == EC_CMD_REBOOT_EC) in do_cros_ec_cmd_xfer_spi()
650 params->ret = params->fn(params->ec_dev, params->ec_msg); in cros_ec_xfer_high_pri_work()
657 struct cros_ec_spi *ec_spi = ec_dev->priv; in cros_ec_xfer_high_pri()
670 * running at high priority but the calling context might not in cros_ec_xfer_high_pri()
671 * be. We need to be at high priority to avoid getting in cros_ec_xfer_high_pri()
675 kthread_queue_work(ec_spi->high_pri_worker, ¶ms.work); in cros_ec_xfer_high_pri()
695 struct device_node *np = dev->of_node; in cros_ec_spi_dt_probe()
699 ret = of_property_read_u32(np, "google,cros-ec-spi-pre-delay", &val); in cros_ec_spi_dt_probe()
701 ec_spi->start_of_msg_delay = val; in cros_ec_spi_dt_probe()
703 ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val); in cros_ec_spi_dt_probe()
705 ec_spi->end_of_msg_delay = val; in cros_ec_spi_dt_probe()
718 ec_spi->high_pri_worker = in cros_ec_spi_devm_high_pri_alloc()
721 if (IS_ERR(ec_spi->high_pri_worker)) { in cros_ec_spi_devm_high_pri_alloc()
722 err = PTR_ERR(ec_spi->high_pri_worker); in cros_ec_spi_devm_high_pri_alloc()
723 dev_err(dev, "Can't create cros_ec high pri worker: %d\n", err); in cros_ec_spi_devm_high_pri_alloc()
728 ec_spi->high_pri_worker); in cros_ec_spi_devm_high_pri_alloc()
732 sched_set_fifo(ec_spi->high_pri_worker->task); in cros_ec_spi_devm_high_pri_alloc()
737 static int cros_ec_spi_probe(struct spi_device *spi) in cros_ec_spi_probe() argument
739 struct device *dev = &spi->dev; in cros_ec_spi_probe()
744 spi->bits_per_word = 8; in cros_ec_spi_probe()
745 spi->mode = SPI_MODE_0; in cros_ec_spi_probe()
746 spi->rt = true; in cros_ec_spi_probe()
747 err = spi_setup(spi); in cros_ec_spi_probe()
753 return -ENOMEM; in cros_ec_spi_probe()
754 ec_spi->spi = spi; in cros_ec_spi_probe()
757 return -ENOMEM; in cros_ec_spi_probe()
762 spi_set_drvdata(spi, ec_dev); in cros_ec_spi_probe()
763 ec_dev->dev = dev; in cros_ec_spi_probe()
764 ec_dev->priv = ec_spi; in cros_ec_spi_probe()
765 ec_dev->irq = spi->irq; in cros_ec_spi_probe()
766 ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi; in cros_ec_spi_probe()
767 ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi; in cros_ec_spi_probe()
768 ec_dev->phys_name = dev_name(&ec_spi->spi->dev); in cros_ec_spi_probe()
769 ec_dev->din_size = EC_MSG_PREAMBLE_COUNT + in cros_ec_spi_probe()
772 ec_dev->dout_size = sizeof(struct ec_host_request); in cros_ec_spi_probe()
774 ec_spi->last_transfer_ns = ktime_get_ns(); in cros_ec_spi_probe()
786 device_init_wakeup(&spi->dev, true); in cros_ec_spi_probe()
791 static int cros_ec_spi_remove(struct spi_device *spi) in cros_ec_spi_remove() argument
793 struct cros_ec_device *ec_dev = spi_get_drvdata(spi); in cros_ec_spi_remove()
818 { .compatible = "google,cros-ec-spi", },
824 { "cros-ec-spi", 0 },
827 MODULE_DEVICE_TABLE(spi, cros_ec_spi_id);
831 .name = "cros-ec-spi",
843 MODULE_DESCRIPTION("SPI interface for ChromeOS Embedded Controller");