coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ec_spi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <delay.h>
5 #include "ec.h"
6 #include "ec_commands.h"
7 #include <spi-generic.h>
8 #include <timer.h>
9 
10 static struct stopwatch cs_cooldown_sw;
11 static const long cs_cooldown_us = 200;
12 
13 static const uint8_t EcFramingByte = 0xec;
14 
15 #define PROTO3_MAX_PACKET_SIZE 268
16 
19 
20 void *crosec_get_buffer(size_t size, int req)
21 {
22  if (size > PROTO3_MAX_PACKET_SIZE) {
23  printk(BIOS_DEBUG, "Proto v3 buffer request too large: %zu!\n",
24  size);
25  return NULL;
26  }
27 
28  if (req)
29  return req_buf;
30  else
31  return resp_buf;
32 }
33 
34 static int crosec_spi_io(size_t req_size, size_t resp_size, void *context)
35 {
36  struct spi_slave *slave = (struct spi_slave *)context;
37  int ret = 0;
38 
39  /* Wait minimum delay between CS assertions. */
41 
43 
44  /* Allow EC to ramp up clock after being awaken.
45  * See chrome-os-partner:32223 for more details. */
46  udelay(CONFIG_EC_GOOGLE_CHROMEEC_SPI_WAKEUP_DELAY_US);
47 
48  if (spi_xfer(slave, req_buf, req_size, NULL, 0)) {
49  printk(BIOS_ERR, "%s: Failed to send request.\n", __func__);
50  ret = -1;
51  goto out;
52  }
53 
54  uint8_t byte;
55  struct stopwatch sw;
56  // Wait 1s for a framing byte.
58  while (1) {
59  if (spi_xfer(slave, NULL, 0, &byte, sizeof(byte))) {
60  printk(BIOS_ERR, "%s: Failed to receive byte.\n",
61  __func__);
62  ret = -1;
63  goto out;
64  }
65  if (byte == EcFramingByte)
66  break;
67 
68  if (stopwatch_expired(&sw)) {
70  "%s: Timeout waiting for framing byte.\n",
71  __func__);
72  ret = -1;
73  goto out;
74  }
75  }
76 
77  if (spi_xfer(slave, NULL, 0, resp_buf, resp_size)) {
78  printk(BIOS_ERR, "%s: Failed to receive response.\n", __func__);
79  ret = -1;
80  }
81 
82 out:
85  return ret;
86 }
87 
89 {
90  static int done = 0;
91  static struct spi_slave slave;
92 
93  if (!done) {
94  if (spi_setup_slave(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS,
95  CONFIG_EC_GOOGLE_CHROMEEC_SPI_CHIP, &slave))
96  return -1;
98  done = 1;
99  }
101 }
102 
104 {
105  printk(BIOS_ERR, "%s: Not supported.\n", __func__);
106  return EC_HOST_EVENT_NONE;
107 }
#define printk(level,...)
Definition: stdlib.h:16
int crosec_command_proto(struct chromeec_command *cec_command, crosec_io_t crosec_io, void *context)
Definition: crosec_proto.c:240
host_event_code
Definition: ec_commands.h:653
@ EC_HOST_EVENT_NONE
Definition: ec_commands.h:654
cec_command
Definition: ec_commands.h:5071
int google_chromeec_command(struct chromeec_command *cec_command)
Send a command to a CrOS EC.
Definition: ec_spi.c:88
static uint8_t req_buf[PROTO3_MAX_PACKET_SIZE]
Definition: ec_spi.c:17
static uint8_t resp_buf[PROTO3_MAX_PACKET_SIZE]
Definition: ec_spi.c:18
static struct stopwatch cs_cooldown_sw
Definition: ec_spi.c:10
enum host_event_code google_chromeec_get_event(void)
Definition: ec_spi.c:103
static int crosec_spi_io(size_t req_size, size_t resp_size, void *context)
Definition: ec_spi.c:34
#define PROTO3_MAX_PACKET_SIZE
Definition: ec_spi.c:15
static const long cs_cooldown_us
Definition: ec_spi.c:11
static const uint8_t EcFramingByte
Definition: ec_spi.c:13
void * crosec_get_buffer(size_t size, int req)
Definition: ec_spi.c:20
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init(struct stopwatch *sw)
Definition: timer.h:117
static void stopwatch_wait_until_expired(struct stopwatch *sw)
Definition: timer.h:161
#define USECS_PER_SEC
Definition: timer.h:8
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
int spi_claim_bus(const struct spi_slave *slave)
Definition: spi-generic.c:9
int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin)
Definition: spi-generic.c:68
void spi_release_bus(const struct spi_slave *slave)
Definition: spi-generic.c:17
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
Definition: spi-generic.c:122
static struct spi_slave slave
Definition: spiconsole.c:7
#define NULL
Definition: stddef.h:19
unsigned char uint8_t
Definition: stdint.h:8
void udelay(uint32_t us)
Definition: udelay.c:15