tegra124: Add Rx frame header support to SPI code

This adds support for finding a frame header in the input stream.

If a frame header is enabled, then the input buffer is scanned after
each iteration of the outer loop. If the header is found, the bytes
are shifted to the beginning of the buffer and the counter is
decremented so that if necessary another iteration can take place
with the remaining byte count.

This allows us to always transfer the maximum number of bytes.

BUG=none
BRANCH=none
TEST=tested on nyan, querying EC actually works now
Signed-off-by: David Hendricks <dhendrix@chromium.org>

Change-Id: I5827b386fc372ee6768403f5a8bb86f7c680e523
Reviewed-on: https://chromium-review.googlesource.com/174711
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Commit-Queue: David Hendricks <dhendrix@chromium.org>
Tested-by: David Hendricks <dhendrix@chromium.org>
This commit is contained in:
David Hendricks 2013-10-24 21:58:13 -07:00 committed by chrome-internal-fetch
commit 1d1630e770

View file

@ -673,13 +673,18 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
u8 *out_buf = (u8 *)dout;
u8 *in_buf = (u8 *)din;
unsigned int todo;
int ret = 0;
int ret = 0, frame_started = 1;
ASSERT(bitsout % 8 == 0 && bitsin % 8 == 0);
/* tegra bus numbers start at 1 */
ASSERT(slave->bus >= 1 && slave->bus <= ARRAY_SIZE(tegra_spi_channels));
if (spi->rx_frame_header_enable) {
memset(in_buf, ~spi->frame_header, in_bytes);
frame_started = 0;
}
while (out_bytes || in_bytes) {
int x = 0;
@ -715,6 +720,11 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
}
}
/*
* Note: Some devices (such as Chrome EC) are sensitive to
* delays, so be careful when adding debug prints not to
* cause timeouts between transfers.
*/
xfer_start(spi);
xfer_wait(spi);
if (xfer_finish(spi)) {
@ -726,14 +736,37 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
* Post-processing. For output, we only need to increment
* the buffer and decrement the counter. Same for input if
* there is no frame header to be concerned with.
*
* If a frame header is used and is found, the input buffer
* is shifted so that the header starts at offset 0, and
* in_bytes and in_buf are incremented/decremented according
* to the offset where the header was originally found.
*/
if (out_bytes) {
out_bytes -= x;
out_buf += x;
}
if (in_bytes) {
in_bytes -= x;
in_buf += x;
if (spi->rx_frame_header_enable && !frame_started) {
int i;
for (i = 0; i < x; i++) {
if (in_buf[i] == spi->frame_header) {
frame_started = 1;
i++; /* discard frame header */
break;
}
}
if (frame_started) {
memmove(&in_buf[0], &in_buf[i], x - i);
in_bytes -= x - i;
in_buf += x - i;
}
} else {
in_bytes -= x;
in_buf += x;
}
}
}