Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: cros_ec: spi: Add delay for asserting CS

Some ECs need a little time for waking up before they can accept
SPI data at a high speed. This is configurable via a DT property
"google,cros-ec-spi-pre-delay".

This patch makes the cros_ec_spi driver to cause a delay before
the beginning of a SPI transaction, to make sure that the EC has
already woken up, if the property has been defined in the DTS.

Signed-off-by: Alexandru M Stan <amstan@chromium.org>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Alexandru M Stan and committed by
Lee Jones
ff4378f4 f44c21ff

+19 -2
+19 -2
drivers/mfd/cros_ec_spi.c
··· 71 71 * @spi: SPI device we are connected to 72 72 * @last_transfer_ns: time that we last finished a transfer, or 0 if there 73 73 * if no record 74 + * @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that 75 + * is sent when we want to turn on CS at the start of a transaction. 74 76 * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that 75 77 * is sent when we want to turn off CS at the end of a transaction. 76 78 */ 77 79 struct cros_ec_spi { 78 80 struct spi_device *spi; 79 81 s64 last_transfer_ns; 82 + unsigned int start_of_msg_delay; 80 83 unsigned int end_of_msg_delay; 81 84 }; 82 85 ··· 369 366 struct ec_host_request *request; 370 367 struct ec_host_response *response; 371 368 struct cros_ec_spi *ec_spi = ec_dev->priv; 372 - struct spi_transfer trans; 369 + struct spi_transfer trans, trans_delay; 373 370 struct spi_message msg; 374 371 int i, len; 375 372 u8 *ptr; ··· 396 393 goto exit; 397 394 } 398 395 396 + /* 397 + * Leave a gap between CS assertion and clocking of data to allow the 398 + * EC time to wakeup. 399 + */ 400 + spi_message_init(&msg); 401 + if (ec_spi->start_of_msg_delay) { 402 + memset(&trans_delay, 0, sizeof(trans_delay)); 403 + trans_delay.delay_usecs = ec_spi->start_of_msg_delay; 404 + spi_message_add_tail(&trans_delay, &msg); 405 + } 406 + 399 407 /* Transmit phase - send our message */ 400 408 memset(&trans, 0, sizeof(trans)); 401 409 trans.tx_buf = ec_dev->dout; 402 410 trans.rx_buf = rx_buf; 403 411 trans.len = len; 404 412 trans.cs_change = 1; 405 - spi_message_init(&msg); 406 413 spi_message_add_tail(&trans, &msg); 407 414 ret = spi_sync(ec_spi->spi, &msg); 408 415 ··· 614 601 struct device_node *np = dev->of_node; 615 602 u32 val; 616 603 int ret; 604 + 605 + ret = of_property_read_u32(np, "google,cros-ec-spi-pre-delay", &val); 606 + if (!ret) 607 + ec_spi->start_of_msg_delay = val; 617 608 618 609 ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val); 619 610 if (!ret)