coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
twsi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
5  */
6 
7 #include <console/console.h>
8 #include <soc/twsi.h>
9 #include <soc/clock.h>
10 #include <device/i2c.h>
11 #include <device/i2c_simple.h>
12 #include <delay.h>
13 #include <device/mmio.h>
14 #include <soc/addressmap.h>
15 #include <timer.h>
16 
17 #define TWSI_THP 24
18 
19 #define TWSI_SW_TWSI 0x1000
20 #define TWSI_TWSI_SW 0x1008
21 #define TWSI_INT 0x1010
22 #define TWSI_SW_TWSI_EXT 0x1018
23 
24 union twsx_sw_twsi {
25  u64 u;
26  struct {
27  u64 data:32;
29  u64 ia:5;
30  u64 addr:10;
31  u64 scr:2;
32  u64 size:3;
33  u64 sovr:1;
34  u64 r:1;
35  u64 op:4;
36  u64 eia:1;
38  u64 v:1;
39  } s;
40 };
41 
43  u64 u;
44  struct {
45  u64 data:32;
46  u64 ia:8;
47  u64 :24;
48  } s;
49 };
50 
51 union twsx_int {
52  u64 u;
53  struct {
54  u64 st_int:1; /** TWSX_SW_TWSI register update int */
55  u64 ts_int:1; /** TWSX_TWSI_SW register update int */
56  u64 core_int:1; /** TWSI core interrupt, ignored for HLC */
57  u64 :5; /** Reserved */
58  u64 sda_ovr:1; /** SDA testing override */
59  u64 scl_ovr:1; /** SCL testing override */
60  u64 sda:1; /** SDA signal */
61  u64 scl:1; /** SCL signal */
62  u64 :52; /** Reserved */
63  } s;
64 };
65 
66 enum {
69 };
70 
71 enum {
75 };
76 
77 enum {
79  TWSI_DATA = 1,
80  TWSI_CTL = 2,
82  TWSI_STAT = 3,
84  TWSI_RST = 7,
85 };
86 
87 enum {
88  TWSI_CTL_AAK = (1 << 2),
89  TWSI_CTL_IFLG = (1 << 3),
90  TWSI_CTL_STP = (1 << 4),
91  TWSI_CTL_STA = (1 << 5),
92  TWSI_CTL_ENAB = (1 << 6),
93  TWSI_CTL_CE = (1 << 7),
94 };
95 
96 enum {
97  /** Bus error */
99  /** Start condition transmitted */
101  /** Repeat start condition transmitted */
103  /** Address + write bit transmitted, ACK received */
105  /** Address + write bit transmitted, /ACK received */
107  /** Data byte transmitted in master mode, ACK received */
109  /** Data byte transmitted in master mode, ACK received */
111  /** Arbitration lost in address or data byte */
113  /** Address + read bit transmitted, ACK received */
115  /** Address + read bit transmitted, /ACK received */
117  /** Data byte received in master mode, ACK transmitted */
119  /** Data byte received, NACK transmitted */
121  /** Slave address received, sent ACK */
123  /**
124  * Arbitration lost in address as master, slave address + write bit
125  * received, ACK transmitted
126  */
128  /** General call address received, ACK transmitted */
130  /**
131  * Arbitration lost in address as master, general call address
132  * received, ACK transmitted
133  */
135  /** Data byte received after slave address received, ACK transmitted */
137  /** Data byte received after slave address received, /ACK transmitted */
139  /**
140  * Data byte received after general call address received, ACK
141  * transmitted
142  */
144  /**
145  * Data byte received after general call address received, /ACK
146  * transmitted
147  */
149  /** STOP or repeated START condition received in slave mode */
151  /** Slave address + read bit received, ACK transmitted */
153  /**
154  * Arbitration lost in address as master, slave address + read bit
155  * received, ACK transmitted
156  */
158  /** Data byte transmitted in slave mode, ACK received */
160  /** Data byte transmitted in slave mode, /ACK received */
162  /** Last byte transmitted in slave mode, ACK received */
164  /** Second address byte + write bit transmitted, ACK received */
166  /** Second address byte + write bit transmitted, /ACK received */
168  /** No relevant status information */
169  TWSI_STAT_IDLE = 0xF8
170 };
171 
172 /**
173  * Returns true if we lost arbitration
174  *
175  * @param code status code
176  * @param final_read true if this is the final read operation
177  *
178  * @return true if arbitration has been lost, false if it hasn't been lost.
179  */
180 static int twsi_i2c_lost_arb(u8 code, int final_read)
181 {
182  switch (code) {
183  /* Arbitration lost */
188  return -1;
189 
190  /* Being addressed as slave, should back off and listen */
195  return -1;
196 
197  /* Core busy as slave */
205  return -1;
206 
207  /* Ack allowed on pre-terminal bytes only */
209  if (!final_read)
210  return 0;
211  return -1;
212 
213  /* NAK allowed on terminal byte only */
215  if (!final_read)
216  return 0;
217  return -1;
218 
223  return -1;
224  }
225  return 0;
226 }
227 
228 #define RST_BOOT_PNR_MUL(Val) ((Val >> 33) & 0x1F)
229 
230 /**
231  * Writes to the MIO_TWS(0..5)_SW_TWSI register
232  *
233  * @param baseaddr Base address of i2c registers
234  * @param sw_twsi value to write
235  *
236  * @return 0 for success, otherwise error
237  */
238 static u64 twsi_write_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
239 {
240  unsigned long timeout = 500000;
241 
242  sw_twsi.s.r = 0;
243  sw_twsi.s.v = 1;
244 
245  printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
246  write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
247  do {
248  sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
249  timeout--;
250  } while (sw_twsi.s.v != 0 && timeout > 0);
251 
252  if (sw_twsi.s.v)
253  printk(BIOS_ERR, "%s: timed out\n", __func__);
254  return sw_twsi.u;
255 }
256 
257 /**
258  * Reads the MIO_TWS(0..5)_SW_TWSI register
259  *
260  * @param baseaddr Base address of i2c registers
261  * @param sw_twsi value for eia and op, etc. to read
262  *
263  * @return value of the register
264  */
265 static u64 twsi_read_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
266 {
267  unsigned long timeout = 500000;
268  sw_twsi.s.r = 1;
269  sw_twsi.s.v = 1;
270 
271  printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
272  write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
273 
274  do {
275  sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
276  timeout--;
277  } while (sw_twsi.s.v != 0 && timeout > 0);
278 
279  if (sw_twsi.s.v)
280  printk(BIOS_ERR, "%s: Error writing 0x%llx\n", __func__,
281  sw_twsi.u);
282 
283  printk(BIOS_SPEW, "%s: Returning 0x%llx\n", __func__, sw_twsi.u);
284  return sw_twsi.u;
285 }
286 
287 /**
288  * Write control register
289  *
290  * @param baseaddr Base address for i2c registers
291  * @param data data to write
292  */
293 static void twsi_write_ctl(void *baseaddr, const u8 data)
294 {
295  union twsx_sw_twsi twsi_sw;
296 
297  printk(BIOS_SPEW, "%s(%p, 0x%x)\n", __func__, baseaddr, data);
298  twsi_sw.u = 0;
299 
300  twsi_sw.s.op = TWSI_SW_EOP_IA;
301  twsi_sw.s.eop_ia = TWSI_CTL;
302  twsi_sw.s.data = data;
303 
304  twsi_write_sw(baseaddr, twsi_sw);
305 }
306 
307 /**
308  * Reads the TWSI Control Register
309  *
310  * @param[in] baseaddr Base address for i2c
311  *
312  * @return 8-bit TWSI control register
313  */
314 static u32 twsi_read_ctl(void *baseaddr)
315 {
316  union twsx_sw_twsi sw_twsi;
317 
318  sw_twsi.u = 0;
319  sw_twsi.s.op = TWSI_SW_EOP_IA;
320  sw_twsi.s.eop_ia = TWSI_CTL;
321 
322  sw_twsi.u = twsi_read_sw(baseaddr, sw_twsi);
323  printk(BIOS_SPEW, "%s(%p): 0x%x\n", __func__, baseaddr, sw_twsi.s.data);
324  return sw_twsi.s.data;
325 }
326 
327 /**
328  * Read i2c status register
329  *
330  * @param baseaddr Base address of i2c registers
331  *
332  * @return value of status register
333  */
334 static u8 twsi_read_status(void *baseaddr)
335 {
336  union twsx_sw_twsi twsi_sw;
337 
338  twsi_sw.u = 0;
339  twsi_sw.s.op = TWSI_SW_EOP_IA;
340  twsi_sw.s.eop_ia = TWSI_STAT;
341 
342  return twsi_read_sw(baseaddr, twsi_sw);
343 }
344 
345 /**
346  * Waits for an i2c operation to complete
347  *
348  * @param baseaddr Base address of registers
349  *
350  * @return 0 for success, 1 if timeout
351  */
352 static int twsi_wait(void *baseaddr, struct stopwatch *timeout)
353 {
354  u8 twsi_ctl;
355 
356  printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
357  do {
358  twsi_ctl = twsi_read_ctl(baseaddr);
359  twsi_ctl &= TWSI_CTL_IFLG;
360  } while (!twsi_ctl && !stopwatch_expired(timeout));
361 
362  printk(BIOS_SPEW, " return: %u\n", !twsi_ctl);
363  return !twsi_ctl;
364 }
365 
366 /**
367  * Sends an i2c stop condition
368  *
369  * @param baseaddr register base address
370  *
371  * @return 0 for success, -1 if error
372  */
373 static int twsi_stop(void *baseaddr)
374 {
375  u8 stat;
377 
378  stat = twsi_read_status(baseaddr);
379  if (stat != TWSI_STAT_IDLE) {
380  printk(BIOS_ERR, "%s: Bad status on bus@%p\n", __func__,
381  baseaddr);
382  return -1;
383  }
384  return 0;
385 }
386 
387 /**
388  * Manually clear the I2C bus and send a stop
389  */
390 static void twsi_unblock(void *baseaddr)
391 {
392  int i;
393  union twsx_int int_reg;
394 
395  int_reg.u = 0;
396  for (i = 0; i < 9; i++) {
397  int_reg.s.scl_ovr = 0;
398  write64(baseaddr + TWSI_INT, int_reg.u);
399  udelay(5);
400  int_reg.s.scl_ovr = 1;
401  write64(baseaddr + TWSI_INT, int_reg.u);
402  udelay(5);
403  }
404  int_reg.s.sda_ovr = 1;
405  write64(baseaddr + TWSI_INT, int_reg.u);
406  udelay(5);
407  int_reg.s.scl_ovr = 0;
408  write64(baseaddr + TWSI_INT, int_reg.u);
409  udelay(5);
410  int_reg.u = 0;
411  write64(baseaddr + TWSI_INT, int_reg.u);
412  udelay(5);
413 }
414 
415 /**
416  * Unsticks the i2c bus
417  *
418  * @param baseaddr base address of registers
419  */
420 static int twsi_start_unstick(void *baseaddr)
421 {
422  twsi_stop(baseaddr);
423 
424  twsi_unblock(baseaddr);
425 
426  return 0;
427 }
428 
429 /**
430  * Sends an i2c start condition
431  *
432  * @param baseaddr base address of registers
433  *
434  * @return 0 for success, otherwise error
435  */
436 static int twsi_start(void *baseaddr)
437 {
438  int result;
439  u8 stat;
440  struct stopwatch timeout;
441 
442  printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
443  stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
445  result = twsi_wait(baseaddr, &timeout);
446  if (result) {
447  stat = twsi_read_status(baseaddr);
448  printk(BIOS_SPEW, "%s: result: 0x%x, status: 0x%x\n", __func__,
449  result, stat);
450  switch (stat) {
451  case TWSI_STAT_START:
452  case TWSI_STAT_RSTART:
453  return 0;
455  default:
456  return twsi_start_unstick(baseaddr);
457  }
458  }
459  printk(BIOS_SPEW, "%s: success\n", __func__);
460  return 0;
461 }
462 
463 /**
464  * Writes data to the i2c bus
465  *
466  * @param baseraddr register base address
467  * @param slave_addr address of slave to write to
468  * @param buffer Pointer to buffer to write
469  * @param length Number of bytes in buffer to write
470  *
471  * @return 0 for success, otherwise error
472  */
473 static int twsi_write_data(void *baseaddr, const u8 slave_addr,
474  const u8 *buffer, const unsigned int length)
475 {
476  union twsx_sw_twsi twsi_sw;
477  unsigned int curr = 0;
478  int result;
479  struct stopwatch timeout;
480 
481  printk(BIOS_SPEW, "%s(%p, 0x%x, %p, 0x%x)\n", __func__, baseaddr,
482  slave_addr, buffer, length);
483  stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
484  result = twsi_start(baseaddr);
485  if (result) {
486  printk(BIOS_ERR, "%s: Could not start BUS transaction\n",
487  __func__);
488  return -1;
489  }
490 
491  result = twsi_wait(baseaddr, &timeout);
492  if (result) {
493  printk(BIOS_ERR, "%s: wait failed\n", __func__);
494  return result;
495  }
496 
497  twsi_sw.u = 0;
498  twsi_sw.s.op = TWSI_SW_EOP_IA;
499  twsi_sw.s.eop_ia = TWSI_DATA;
500  twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_WRITE;
501 
502  twsi_write_sw(baseaddr, twsi_sw);
503  twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
504 
505  printk(BIOS_SPEW, "%s: Waiting\n", __func__);
506  result = twsi_wait(baseaddr, &timeout);
507  if (result) {
508  printk(BIOS_ERR, "%s: Timed out writing slave address 0x%x\n",
509  __func__, slave_addr);
510  return result;
511  }
512  result = twsi_read_status(baseaddr);
513  if ((result = twsi_read_status(baseaddr)) != TWSI_STAT_TXADDR_ACK) {
514  twsi_stop(baseaddr);
515  return twsi_i2c_lost_arb(result, 0);
516  }
517 
518  while (curr < length) {
519  twsi_sw.u = 0;
520  twsi_sw.s.op = TWSI_SW_EOP_IA;
521  twsi_sw.s.eop_ia = TWSI_DATA;
522  twsi_sw.s.data = buffer[curr++];
523 
524  twsi_write_sw(baseaddr, twsi_sw);
525  twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
526 
527  result = twsi_wait(baseaddr, &timeout);
528  if (result) {
529  printk(BIOS_ERR, "%s: Timed out writing data to 0x%x\n",
530  __func__, slave_addr);
531  return result;
532  }
533  }
534 
535  printk(BIOS_SPEW, "%s: Stopping\n", __func__);
536  return twsi_stop(baseaddr);
537 }
538 
539 /**
540  * Performs a read transaction on the i2c bus
541  *
542  * @param baseaddr Base address of twsi registers
543  * @param slave_addr i2c bus address to read from
544  * @param buffer buffer to read into
545  * @param length number of bytes to read
546  *
547  * @return 0 for success, otherwise error
548  */
549 static int twsi_read_data(void *baseaddr, const u8 slave_addr,
550  u8 *buffer, const unsigned int length)
551 {
552  union twsx_sw_twsi twsi_sw;
553  unsigned int curr = 0;
554  int result;
555  struct stopwatch timeout;
556 
557  printk(BIOS_SPEW, "%s(%p, 0x%x, %p, %u)\n", __func__, baseaddr,
558  slave_addr, buffer, length);
559  stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
560  result = twsi_start(baseaddr);
561  if (result) {
562  printk(BIOS_ERR, "%s: start failed\n", __func__);
563  return result;
564  }
565 
566  result = twsi_wait(baseaddr, &timeout);
567  if (result) {
568  printk(BIOS_ERR, "%s: wait failed\n", __func__);
569  return result;
570  }
571 
572  twsi_sw.u = 0;
573 
574  twsi_sw.s.op = TWSI_SW_EOP_IA;
575  twsi_sw.s.eop_ia = TWSI_DATA;
576 
577  twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_READ;
578 
579  twsi_write_sw(baseaddr, twsi_sw);
580  twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
581 
582  result = twsi_wait(baseaddr, &timeout);
583  if (result) {
584  printk(BIOS_ERR, "%s: waiting for sending addr failed\n", __func__);
585  return result;
586  }
587 
588  result = twsi_read_status(baseaddr);
589  if (result != TWSI_STAT_RXADDR_ACK) {
590  twsi_stop(baseaddr);
591  return twsi_i2c_lost_arb(result, 0);
592  }
593 
594  while (curr < length) {
595  twsi_write_ctl(baseaddr, TWSI_CTL_ENAB |
596  ((curr < length - 1) ? TWSI_CTL_AAK : 0));
597 
598  result = twsi_wait(baseaddr, &timeout);
599  if (result) {
600  printk(BIOS_ERR, "%s: waiting for data failed\n",
601  __func__);
602  return result;
603  }
604 
605  twsi_sw.u = twsi_read_sw(baseaddr, twsi_sw);
606  buffer[curr++] = twsi_sw.s.data;
607  }
608 
609  twsi_stop(baseaddr);
610 
611  return 0;
612 }
613 
614 static int twsi_set_speed(void *baseaddr, const unsigned int speed)
615 {
616  u64 io_clock_hz;
617  int n_div;
618  int m_div;
619  union twsx_sw_twsi sw_twsi;
620 
621  io_clock_hz = thunderx_get_io_clock();
622 
623  /* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the
624  * clocks M divider based on the SCLK.
625  * TWSI freq = (core freq) / (20 x (M+1) x (thp+1) x 2^N)
626  * M = ((core freq) / (20 x (TWSI freq) x (thp+1) x 2^N)) - 1
627  */
628  for (n_div = 0; n_div < 8; n_div++) {
629  m_div = io_clock_hz / (20 * speed * (TWSI_THP + 1));
630  m_div /= 1 << n_div;
631  m_div -= 1;
632  if (m_div < 16)
633  break;
634  }
635  if (m_div >= 16)
636  return -1;
637 
638  sw_twsi.u = 0;
639  sw_twsi.s.v = 1;
640  sw_twsi.s.op = 0x6; /* See EOP field */
641  sw_twsi.s.r = 0; /* Select CLKCTL when R = 0 */
642  sw_twsi.s.eop_ia = 3; /* R=0 selects CLKCTL, R=1 selects STAT */
643  sw_twsi.s.data = ((m_div & 0xf) << 3) | ((n_div & 0x7) << 0);
644 
645  twsi_write_sw(baseaddr, sw_twsi);
646  return 0;
647 }
648 
649 int twsi_init(unsigned int bus, enum i2c_speed hz)
650 {
651  void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
652  if (!baseaddr)
653  return -1;
654 
655  if (twsi_set_speed(baseaddr, hz) < 0)
656  return -1;
657 
658  /* Enable TWSI, HLC disable, STOP, NAK */
659  twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
660 
661  return 0;
662 }
663 
664 int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
665  int seg_count)
666 {
667  int result;
668  void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
669  if (!baseaddr)
670  return -1;
671 
672  printk(BIOS_SPEW, "%s: %d messages\n", __func__, seg_count);
673  for (; seg_count > 0; seg_count--, segments++) {
674  if (segments->flags & I2C_M_RD) {
675  result = twsi_read_data(baseaddr, segments->slave,
676  segments->buf, segments->len);
677  } else {
678  result = twsi_write_data(baseaddr, segments->slave,
679  segments->buf, segments->len);
680  }
681  if (result) {
682  printk(BIOS_ERR, "%s: error transmitting data\n",
683  __func__);
684  return -1;
685  }
686  }
687 
688  return 0;
689 }
void write64(void *addr, uint64_t val)
uint64_t read64(const void *addr)
#define printk(level,...)
Definition: stdlib.h:16
uint64_t length
Definition: fw_cfg_if.h:1
i2c_speed
Definition: i2c.h:43
#define I2C_M_RD
Definition: i2c.h:34
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
result
Definition: mrc_cache.c:35
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
u64 thunderx_get_io_clock(void)
Returns the I/O clock speed in Hz.
Definition: clock.c:45
#define MIO_TWSx_PF_BAR0(x)
Definition: addressmap.h:104
uint64_t u64
Definition: stdint.h:54
uint32_t u32
Definition: stdint.h:51
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
static void twsi_unblock(void *baseaddr)
Manually clear the I2C bus and send a stop.
Definition: twsi.c:390
static int twsi_i2c_lost_arb(u8 code, int final_read)
Returns true if we lost arbitration.
Definition: twsi.c:180
int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int seg_count)
Definition: twsi.c:664
@ TWSI_SW_EOP_IA
Definition: twsi.c:74
@ TWSI_EOP_SLAVE_ADDR
Definition: twsi.c:72
@ TWSI_EOP_CLK_CTL
Definition: twsi.c:73
static u8 twsi_read_status(void *baseaddr)
Read i2c status register.
Definition: twsi.c:334
static u32 twsi_read_ctl(void *baseaddr)
Reads the TWSI Control Register.
Definition: twsi.c:314
static int twsi_stop(void *baseaddr)
Sends an i2c stop condition.
Definition: twsi.c:373
#define TWSI_INT
Definition: twsi.c:21
static int twsi_start_unstick(void *baseaddr)
Unsticks the i2c bus.
Definition: twsi.c:420
int twsi_init(unsigned int bus, enum i2c_speed hz)
Definition: twsi.c:649
@ TWSI_STAT_TXDATA_ACK
Data byte transmitted in master mode, ACK received.
Definition: twsi.c:108
@ TWSI_STAT_SLAVE_TXDATA_NAK
Data byte transmitted in slave mode, /ACK received.
Definition: twsi.c:161
@ TWSI_STAT_TXADDR2DATA_NAK
Second address byte + write bit transmitted, /ACK received.
Definition: twsi.c:167
@ TWSI_STAT_TXADDR_NAK
Address + write bit transmitted, /ACK received.
Definition: twsi.c:106
@ TWSI_STAT_RXDATA_NAK_SENT
Data byte received, NACK transmitted.
Definition: twsi.c:120
@ TWSI_STAT_RX_GEN_ADDR_ARB_LOST
Arbitration lost in address as master, general call address received, ACK transmitted.
Definition: twsi.c:134
@ TWSI_STAT_RXADDR_NAK
Address + read bit transmitted, /ACK received.
Definition: twsi.c:116
@ TWSI_STAT_TX_ACK_ARB_LOST
Arbitration lost in address as master, slave address + write bit received, ACK transmitted.
Definition: twsi.c:127
@ TWSI_STAT_TXADDR2DATA_ACK
Second address byte + write bit transmitted, ACK received.
Definition: twsi.c:165
@ TWSI_STAT_RX_GEN_ADDR_ACK
General call address received, ACK transmitted.
Definition: twsi.c:129
@ TWSI_STAT_SLAVE_RXADDR2_ACK
Slave address + read bit received, ACK transmitted.
Definition: twsi.c:152
@ TWSI_STAT_BUS_ERROR
Bus error.
Definition: twsi.c:98
@ TWSI_STAT_RSTART
Repeat start condition transmitted.
Definition: twsi.c:102
@ TWSI_STAT_SLAVE_TXDATA_ACK
Data byte transmitted in slave mode, ACK received.
Definition: twsi.c:159
@ TWSI_STAT_SLAVE_RXDATA_NAK
Data byte received after slave address received, /ACK transmitted.
Definition: twsi.c:138
@ TWSI_STAT_RXDATA_ACK_SENT
Data byte received in master mode, ACK transmitted.
Definition: twsi.c:118
@ TWSI_STAT_GEN_RXADDR_ACK
Data byte received after general call address received, ACK transmitted.
Definition: twsi.c:143
@ TWSI_STAT_TXADDR_ACK
Address + write bit transmitted, ACK received.
Definition: twsi.c:104
@ TWSI_STAT_SLAVE_RXDATA_ACK
Data byte received after slave address received, ACK transmitted.
Definition: twsi.c:136
@ TWSI_STAT_TXDATA_NAK
Data byte transmitted in master mode, ACK received.
Definition: twsi.c:110
@ TWSI_STAT_TX_ARB_LOST
Arbitration lost in address or data byte.
Definition: twsi.c:112
@ TWSI_STAT_SLAVE_TXDATA_END_ACK
Last byte transmitted in slave mode, ACK received.
Definition: twsi.c:163
@ TWSI_STAT_IDLE
No relevant status information.
Definition: twsi.c:169
@ TWSI_STAT_SLAVE_RXADDR_ACK
Slave address received, sent ACK.
Definition: twsi.c:122
@ TWSI_STAT_RXADDR_ACK
Address + read bit transmitted, ACK received.
Definition: twsi.c:114
@ TWSI_STAT_STOP_MULTI_START
STOP or repeated START condition received in slave mode.
Definition: twsi.c:150
@ TWSI_STAT_GEN_RXADDR_NAK
Data byte received after general call address received, /ACK transmitted.
Definition: twsi.c:148
@ TWSI_STAT_RXDATA_ACK_ARB_LOST
Arbitration lost in address as master, slave address + read bit received, ACK transmitted.
Definition: twsi.c:157
@ TWSI_STAT_START
Start condition transmitted.
Definition: twsi.c:100
static int twsi_set_speed(void *baseaddr, const unsigned int speed)
Definition: twsi.c:614
static u64 twsi_read_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
Reads the MIO_TWS(0..5)_SW_TWSI register.
Definition: twsi.c:265
static int twsi_start(void *baseaddr)
Sends an i2c start condition.
Definition: twsi.c:436
@ TWSI_CTL_AAK
Definition: twsi.c:88
@ TWSI_CTL_IFLG
Definition: twsi.c:89
@ TWSI_CTL_CE
Definition: twsi.c:93
@ TWSI_CTL_ENAB
Definition: twsi.c:92
@ TWSI_CTL_STP
Definition: twsi.c:90
@ TWSI_CTL_STA
Definition: twsi.c:91
static u64 twsi_write_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
Writes to the MIO_TWS(0..5)_SW_TWSI register.
Definition: twsi.c:238
static int twsi_read_data(void *baseaddr, const u8 slave_addr, u8 *buffer, const unsigned int length)
Performs a read transaction on the i2c bus.
Definition: twsi.c:549
#define TWSI_SW_TWSI
Definition: twsi.c:19
@ TWSI_OP_READ
Definition: twsi.c:68
@ TWSI_OP_WRITE
Definition: twsi.c:67
static void twsi_write_ctl(void *baseaddr, const u8 data)
Write control register.
Definition: twsi.c:293
static int twsi_write_data(void *baseaddr, const u8 slave_addr, const u8 *buffer, const unsigned int length)
Writes data to the i2c bus.
Definition: twsi.c:473
static int twsi_wait(void *baseaddr, struct stopwatch *timeout)
Waits for an i2c operation to complete.
Definition: twsi.c:352
@ TWSI_CLKCTL
Definition: twsi.c:81
@ TWSI_CTL
Definition: twsi.c:80
@ TWSI_STAT
Definition: twsi.c:82
@ TWSI_DATA
Definition: twsi.c:79
@ TWSI_RST
Definition: twsi.c:84
@ TWSI_SLAVEADD
Definition: twsi.c:78
@ TWSI_SLAVEADD_EXT
Definition: twsi.c:83
#define TWSI_THP
Definition: twsi.c:17
void udelay(uint32_t us)
Definition: udelay.c:15
Definition: twsi.c:51
u64 scl_ovr
SDA testing override.
Definition: twsi.c:59
struct twsx_int::@444 s
u64 sda_ovr
Reserved.
Definition: twsi.c:58
u64 core_int
TWSX_TWSI_SW register update int.
Definition: twsi.c:56
u64 u
Definition: twsi.c:52
u64 ts_int
TWSX_SW_TWSI register update int.
Definition: twsi.c:55
u64 sda
SCL testing override.
Definition: twsi.c:60
u64 st_int
Definition: twsi.c:54
u64 scl
SDA signal.
Definition: twsi.c:61
struct twsx_sw_twsi_ext::@443 s
u64 ia
Definition: twsi.c:29
u64 slonly
Definition: twsi.c:37
u64 r
Definition: twsi.c:34
u64 size
Definition: twsi.c:32
u64 addr
Definition: twsi.c:30
struct twsx_sw_twsi::@442 s
u64 eop_ia
Definition: twsi.c:28
u64 data
Definition: twsi.c:27
u64 op
Definition: twsi.c:35
u64 sovr
Definition: twsi.c:33
u64 scr
Definition: twsi.c:31
u64 u
Definition: twsi.c:25
u64 eia
Definition: twsi.c:36
u64 v
Definition: twsi.c:38