coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
software_i2c.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <timer.h>
5 #include <console/console.h>
6 #include <device/i2c_simple.h>
7 
8 /*
9  * The implementation is based on Wikipedia.
10  */
11 
12 #define DEBUG 0 /* Set to 1 for per-byte output */
13 #define SPEW 0 /* Set to 1 for verbose bitwise/line-state output */
14 #define DELAY_US 5 /* Default setup delay: 4us (+1 for timer inaccuracy) */
15 #define TIMEOUT_US 50000 /* Maximum clock stretching time we want to allow */
16 
17 #define spew(...) do { if (SPEW) printk(BIOS_SPEW, ##__VA_ARGS__); } while (0)
18 
19 #define ERR_NACK -2
20 #define ERR_TIMEOUT -3
21 #define ERR_ARB -4
22 #define ERR_WEDGE -5
23 
25 
26 /*
27  * Waits until either timeout_us have passed or (iff for_scl is set) until SCL
28  * goes high. Will report random line changes during the wait and return SCL.
29  */
30 static int __wait(unsigned int bus, int timeout_us, int for_scl)
31 {
32  int us;
33  int sda = software_i2c[bus]->get_sda(bus);
34  int scl = software_i2c[bus]->get_scl(bus);
35  struct stopwatch sw;
36 
37  stopwatch_init_usecs_expire(&sw, timeout_us);
38 
39  do {
40  int old_sda = sda;
41  int old_scl = scl;
42 
43  us = stopwatch_duration_usecs(&sw);
44 
45  if (old_sda != (sda = software_i2c[bus]->get_sda(bus)))
46  spew("[SDA transitioned to %d after %dus] ", sda, us);
47  if (old_scl != (scl = software_i2c[bus]->get_scl(bus)))
48  spew("[SCL transitioned to %d after %dus] ", scl, us);
49  } while (!stopwatch_expired(&sw) && (!for_scl || !scl));
50 
51  return scl;
52 }
53 
54 /* Waits the default DELAY_US to allow line state to stabilize. */
55 static void wait(unsigned int bus)
56 {
57  __wait(bus, DELAY_US, 0);
58 }
59 
60 /* Waits until SCL goes high. Prints a contextual error message on timeout. */
61 static int wait_for_scl(unsigned int bus, const char *error_context)
62 {
63  if (!__wait(bus, TIMEOUT_US, 1)) {
64  printk(BIOS_ERR, "software_i2c(%d): ERROR: Clock stretching "
65  "timeout %s!\n", bus, error_context);
66  return ERR_TIMEOUT;
67  }
68 
69  return 0;
70 }
71 
72 static int start_cond(unsigned int bus)
73 {
74  spew("software_i2c(%d): Sending start condition... ", bus);
75 
76  /* SDA might not yet be high if repeated start. */
78  wait(bus);
79 
80  /* Might need to wait for clock stretching if repeated start. */
82  if (wait_for_scl(bus, "before start condition"))
83  return ERR_TIMEOUT;
84  wait(bus); /* Repeated start setup time, minimum 4.7us */
85 
86  if (!software_i2c[bus]->get_sda(bus)) {
87  printk(BIOS_ERR, "software_i2c(%d): Arbitration lost trying "
88  "to send start condition!\n", bus);
89  return ERR_ARB;
90  }
91 
92  /* SCL is high, transition SDA low as first part of start condition. */
94  wait(bus);
96 
97  /* Pull SCL low to finish start condition (next pulse will be data). */
99 
100  spew("Start condition transmitted!\n");
101  return 0;
102 }
103 
104 static int stop_cond(unsigned int bus)
105 {
106  spew("software_i2c(%d): Sending stop condition... ", bus);
107 
108  /* SDA is unknown, set it to low. SCL must be low. */
109  software_i2c[bus]->set_sda(bus, 0);
110  wait(bus);
111 
112  /* Clock stretching */
114  software_i2c[bus]->set_scl(bus, 1);
115  if (wait_for_scl(bus, "before stop condition"))
116  return ERR_TIMEOUT;
117  wait(bus); /* Stop bit setup time, minimum 4us */
118 
119  /* SCL is high, transition SDA high to signal stop condition. */
120  software_i2c[bus]->set_sda(bus, 1);
121  wait(bus);
122  if (!software_i2c[bus]->get_sda(bus)) {
123  printk(BIOS_WARNING, "software_i2c(%d): WARNING: SDA low after "
124  "stop condition... access by another master or line "
125  "stuck from faulty slave?\n", bus);
126  /* Could theoretically happen with multi-master, so no -1. */
127  }
128 
129  spew("Stop condition transmitted\n");
130  return 0;
131 }
132 
133 static int out_bit(unsigned int bus, int bit)
134 {
135  spew("software_i2c(%d): Sending a %d bit... ", bus, bit);
136 
137  software_i2c[bus]->set_sda(bus, bit);
138  wait(bus);
139 
140  if (bit && !software_i2c[bus]->get_sda(bus)) {
141  printk(BIOS_ERR, "software_i2c(%d): ERROR: SDA wedged low "
142  "by slave before clock pulse on transmit!\n", bus);
143  return ERR_WEDGE;
144  }
145 
146  /* Clock stretching */
148  software_i2c[bus]->set_scl(bus, 1);
149  if (wait_for_scl(bus, "on transmit"))
150  return ERR_TIMEOUT;
151  wait(bus);
152 
153  if (bit && !software_i2c[bus]->get_sda(bus)) {
154  printk(BIOS_ERR, "software_i2c(%d): ERROR: SDA wedged low "
155  "by slave after clock pulse on transmit!\n", bus);
156  return ERR_WEDGE;
157  }
158 
160  software_i2c[bus]->set_scl(bus, 0);
161 
162  spew("%d bit sent!\n", bit);
163  return 0;
164 }
165 
166 static int in_bit(unsigned int bus)
167 {
168  int bit;
169 
170  spew("software_i2c(%d): Receiving a bit... ", bus);
171 
172  /* Let the slave drive data */
173  software_i2c[bus]->set_sda(bus, 1);
174  wait(bus);
175 
176  /* Clock stretching */
178  software_i2c[bus]->set_scl(bus, 1);
179  if (wait_for_scl(bus, "on receive"))
180  return ERR_TIMEOUT;
181 
182  /* SCL is high, now data is valid */
183  bit = software_i2c[bus]->get_sda(bus);
184  wait(bus);
186  software_i2c[bus]->set_scl(bus, 0);
187 
188  spew("Received a %d!\n", bit);
189 
190  return bit;
191 }
192 
193 /* Write a byte to I2C bus. Return 0 if ack by the slave. */
194 static int out_byte(unsigned int bus, u8 byte)
195 {
196  unsigned int bit;
197  int nack, ret;
198 
199  for (bit = 0; bit < 8; bit++)
200  if ((ret = out_bit(bus, (byte >> (7 - bit)) & 0x1)) < 0)
201  return ret;
202 
203  nack = in_bit(bus);
204 
205  if (DEBUG && nack >= 0)
206  printk(BIOS_DEBUG, "software_i2c(%d): wrote byte 0x%02x, "
207  "received %s\n", bus, byte, nack ? "NAK" : "ACK");
208 
209  return nack > 0 ? ERR_NACK : nack;
210 }
211 
212 static int in_byte(unsigned int bus, int ack)
213 {
214  u8 byte = 0;
215  int i, ret;
216  for (i = 0; i < 8; ++i) {
217  int bit = in_bit(bus);
218  if (bit < 0)
219  return bit;
220  byte = (byte << 1) | bit;
221  }
222 
223  if ((ret = out_bit(bus, !ack)) < 0)
224  return ret;
225 
226  if (DEBUG)
227  printk(BIOS_DEBUG, "software_i2c(%d): read byte 0x%02x, "
228  "sent %s\n", bus, byte, ack ? "ACK" : "NAK");
229 
230  return byte;
231 }
232 
233 int software_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
234 {
235  int i, ret;
236  struct i2c_msg *seg;
237 
238  for (seg = segments; seg - segments < count; seg++) {
239  if ((ret = start_cond(bus)) < 0)
240  return ret;
241  const u8 addr_dir = seg->slave << 1 | !!(seg->flags & I2C_M_RD);
242  if ((ret = out_byte(bus, addr_dir)) < 0)
243  return ret;
244  for (i = 0; i < seg->len; i++) {
245  if (seg->flags & I2C_M_RD) {
246  ret = in_byte(bus, i < seg->len - 1);
247  seg->buf[i] = (u8)ret;
248  } else {
249  ret = out_byte(bus, seg->buf[i]);
250  }
251  if (ret < 0)
252  return ret;
253  }
254  }
255  if ((ret = stop_cond(bus)) < 0)
256  return ret;
257 
258  return 0;
259 }
260 
261 void software_i2c_wedge_ack(unsigned int bus, u8 chip)
262 {
263  int i;
264 
265  /* Start a command to 'chip'... */
266  start_cond(bus);
267 
268  /* Send the address bits but don't yet read the ACK. */
269  chip <<= 1;
270  for (i = 0; i < 8; ++i)
271  out_bit(bus, (chip >> (7 - i)) & 0x1);
272 
273  /* Let the slave drive it's ACK but keep the clock high forever. */
274  software_i2c[bus]->set_sda(bus, 1);
275  wait(bus);
276  software_i2c[bus]->set_scl(bus, 1);
277  wait_for_scl(bus, "on wedge_ack()");
278 
279  printk(BIOS_INFO, "software_i2c(%d): wedged address write on slave "
280  "ACK. SDA %d, SCL %d\n", bus, software_i2c[bus]->get_sda(bus),
282 }
283 
284 void software_i2c_wedge_read(unsigned int bus, u8 chip, u8 reg, int bits)
285 {
286  int i;
287 
288  /* Start a command to 'chip'... */
289  start_cond(bus);
290  out_byte(bus, chip << 1);
291  /* ...for register 'reg'. */
292  out_byte(bus, reg);
293 
294  /* Start a read command... */
295  start_cond(bus);
296  out_byte(bus, chip << 1 | 1);
297 
298  /* Read bit_count bits and stop */
299  for (i = 0; i < bits; ++i)
300  in_bit(bus);
301 
302  /* Let the slave drive SDA but keep the clock high forever. */
303  software_i2c[bus]->set_sda(bus, 1);
304  wait(bus);
305  software_i2c[bus]->set_scl(bus, 1);
306  wait_for_scl(bus, "on wedge_read()");
307 
308  printk(BIOS_INFO, "software_i2c(%d): wedged data read after %d bits. "
309  "SDA %d, SCL %d\n", bus, bits, software_i2c[bus]->get_sda(bus),
311 }
312 
313 void software_i2c_wedge_write(unsigned int bus, u8 chip, u8 reg, int bits)
314 {
315  int i;
316 
317  /* Start a command to 'chip'... */
318  start_cond(bus);
319  out_byte(bus, chip << 1);
320 
321  /* Write bit_count register bits and stop */
322  for (i = 0; i < bits; ++i)
323  out_bit(bus, (reg >> (7 - i)) & 0x1);
324 
325  /* Pretend to write another 1 bit but keep the clock high forever. */
326  software_i2c[bus]->set_sda(bus, 1);
327  wait(bus);
328  software_i2c[bus]->set_scl(bus, 1);
329  wait_for_scl(bus, "on wedge_write()");
330 
331  printk(BIOS_INFO, "software_i2c(%d): wedged data write after %d bits. "
332  "SDA %d, SCL %d\n", bus, bits, software_i2c[bus]->get_sda(bus),
334 }
#define assert(statement)
Definition: assert.h:74
#define printk(level,...)
Definition: stdlib.h:16
static int stop_cond(unsigned int bus)
Definition: software_i2c.c:104
void software_i2c_wedge_ack(unsigned int bus, u8 chip)
Definition: software_i2c.c:261
#define DELAY_US
Definition: software_i2c.c:14
void software_i2c_wedge_read(unsigned int bus, u8 chip, u8 reg, int bits)
Definition: software_i2c.c:284
#define ERR_ARB
Definition: software_i2c.c:21
static int out_byte(unsigned int bus, u8 byte)
Definition: software_i2c.c:194
int software_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Definition: software_i2c.c:233
static int __wait(unsigned int bus, int timeout_us, int for_scl)
Definition: software_i2c.c:30
static int in_bit(unsigned int bus)
Definition: software_i2c.c:166
struct software_i2c_ops * software_i2c[SOFTWARE_I2C_MAX_BUS]
Definition: software_i2c.c:24
static int wait_for_scl(unsigned int bus, const char *error_context)
Definition: software_i2c.c:61
#define TIMEOUT_US
Definition: software_i2c.c:15
static void wait(unsigned int bus)
Definition: software_i2c.c:55
static int out_bit(unsigned int bus, int bit)
Definition: software_i2c.c:133
static int in_byte(unsigned int bus, int ack)
Definition: software_i2c.c:212
#define ERR_NACK
Definition: software_i2c.c:19
#define ERR_WEDGE
Definition: software_i2c.c:22
#define DEBUG
Definition: software_i2c.c:12
static int start_cond(unsigned int bus)
Definition: software_i2c.c:72
#define ERR_TIMEOUT
Definition: software_i2c.c:20
#define spew(...)
Definition: software_i2c.c:17
void software_i2c_wedge_write(unsigned int bus, u8 chip, u8 reg, int bits)
Definition: software_i2c.c:313
static struct tpm_chip chip
Definition: tis.c:17
#define SOFTWARE_I2C_MAX_BUS
Definition: i2c_simple.h:13
#define I2C_M_RD
Definition: i2c.h:34
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static long stopwatch_duration_usecs(struct stopwatch *sw)
Definition: timer.h:170
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
gpio_t sda
Definition: software_i2c.c:11
gpio_t scl
Definition: software_i2c.c:12
static int get_scl(unsigned int bus)
Definition: software_i2c.c:23
static int get_sda(unsigned int bus)
Definition: software_i2c.c:28
uint8_t u8
Definition: stdint.h:45
Definition: device.h:76
struct i2c_msg - an I2C transaction segment beginning with START @addr: Slave address,...
Definition: i2c.h:32
uint16_t len
Definition: i2c.h:39
uint16_t slave
Definition: i2c.h:38
uint16_t flags
Definition: i2c.h:33
uint8_t * buf
Definition: i2c.h:40
int(* get_scl)(unsigned int bus)
Definition: i2c_simple.h:19
void(* set_scl)(unsigned int bus, int high)
Definition: i2c_simple.h:17
int(* get_sda)(unsigned int bus)
Definition: i2c_simple.h:18
void(* set_sda)(unsigned int bus, int high)
Definition: i2c_simple.h:16
#define count