summaryrefslogtreecommitdiff
path: root/src/ec/google/chromeec/ec_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ec/google/chromeec/ec_spi.c')
-rw-r--r--src/ec/google/chromeec/ec_spi.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/src/ec/google/chromeec/ec_spi.c b/src/ec/google/chromeec/ec_spi.c
index d6b7b0c4ea..f1bdd3caaa 100644
--- a/src/ec/google/chromeec/ec_spi.c
+++ b/src/ec/google/chromeec/ec_spi.c
@@ -18,28 +18,60 @@
*/
#include <console/console.h>
-#include <spi-generic.h>
-
#include "ec.h"
#include "ec_commands.h"
+#include <spi-generic.h>
+#include <timer.h>
+
+static const uint8_t EcFramingByte = 0xec;
static int crosec_spi_io(uint8_t *write_bytes, size_t write_size,
uint8_t *read_bytes, size_t read_size,
void *context)
{
struct spi_slave *slave = (struct spi_slave *)context;
- int rv;
spi_claim_bus(slave);
- rv = spi_xfer(slave, write_bytes, write_size, read_bytes,
- read_size);
- spi_release_bus(slave);
- if (rv != 0) {
- printk(BIOS_ERR, "%s: Cannot complete SPI I/O\n", __func__);
+ if (spi_xfer(slave, write_bytes, write_size, NULL, 0)) {
+ printk(BIOS_ERR, "%s: Failed to send request.\n", __func__);
+ spi_release_bus(slave);
return -1;
}
+ uint8_t byte;
+ struct mono_time start;
+ struct rela_time rt;
+ timer_monotonic_get(&start);
+ while (1) {
+ if (spi_xfer(slave, NULL, 0, &byte, sizeof(byte))) {
+ printk(BIOS_ERR, "%s: Failed to receive byte.\n",
+ __func__);
+ spi_release_bus(slave);
+ return -1;
+ }
+ if (byte == EcFramingByte)
+ break;
+
+ // Wait 1s for a framing byte.
+ rt = current_time_from(&start);
+ if (rela_time_in_microseconds(&rt) > 1000 * 1000) {
+ printk(BIOS_ERR,
+ "%s: Timeout waiting for framing byte.\n",
+ __func__);
+ spi_release_bus(slave);
+ return -1;
+ }
+ }
+
+ if (spi_xfer(slave, NULL, 0, read_bytes, read_size)) {
+ printk(BIOS_ERR, "%s: Failed to receive response.\n", __func__);
+ spi_release_bus(slave);
+ return -1;
+ }
+
+ spi_release_bus(slave);
+
return 0;
}