coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
i2c_simple.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _DEVICE_I2C_SIMPLE_H_
4 #define _DEVICE_I2C_SIMPLE_H_
5 
6 #include <commonlib/helpers.h>
7 #include <device/i2c.h>
8 #include <stdint.h>
9 
10 int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
11  int count);
12 
13 #define SOFTWARE_I2C_MAX_BUS 10 /* increase as necessary */
14 
16  void (*set_sda)(unsigned int bus, int high);
17  void (*set_scl)(unsigned int bus, int high);
18  int (*get_sda)(unsigned int bus);
19  int (*get_scl)(unsigned int bus);
20 };
21 
22 extern struct software_i2c_ops *software_i2c[];
23 
24 int software_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
25  int count);
26 void software_i2c_wedge_ack(unsigned int bus, u8 slave);
27 void software_i2c_wedge_read(unsigned int bus, u8 slave, u8 reg, int bit_count);
28 void software_i2c_wedge_write(unsigned int bus, u8 slave, u8 reg,
29  int bit_count);
30 
31 int i2c_read_field(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t *data,
32  uint8_t mask, uint8_t shift);
33 int i2c_write_field(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t data,
34  uint8_t mask, uint8_t shift);
35 
36 /*
37  * software_i2c is supposed to be a debug feature. It's usually not compiled in,
38  * but when it is it can be dynamically enabled at runtime for certain buses.
39  * Need this ugly stub to arbitrate since I2C device drivers hardcode
40  * 'i2c_transfer()' as their entry point.
41  */
42 static inline int i2c_transfer(unsigned int bus, struct i2c_msg *segments,
43  int count)
44 {
45  if (CONFIG(SOFTWARE_I2C))
47  return software_i2c_transfer(bus, segments, count);
48 
49  return platform_i2c_transfer(bus, segments, count);
50 }
51 
52 /*
53  * Read a raw chunk of data in one segment and one frame.
54  *
55  * [start][slave addr][r][data][stop]
56  */
57 static inline int i2c_read_raw(unsigned int bus, uint8_t slave, uint8_t *data,
58  int len)
59 {
60  struct i2c_msg seg = {
61  .flags = I2C_M_RD, .slave = slave, .buf = data, .len = len
62  };
63 
64  return i2c_transfer(bus, &seg, 1);
65 }
66 
67 /*
68  * Write a raw chunk of data in one segment and one frame.
69  *
70  * [start][slave addr][w][data][stop]
71  */
72 static inline int i2c_write_raw(unsigned int bus, uint8_t slave, uint8_t *data,
73  int len)
74 {
75  struct i2c_msg seg = {
76  .flags = 0, .slave = slave, .buf = data, .len = len
77  };
78 
79  return i2c_transfer(bus, &seg, 1);
80 }
81 
82 /**
83  * Read multi-bytes with two segments in one frame
84  *
85  * [start][slave addr][w][register addr][start][slave addr][r][data...][stop]
86  */
87 static inline int i2c_read_bytes(unsigned int bus, uint8_t slave, uint8_t reg,
88  uint8_t *data, int len)
89 {
90  struct i2c_msg seg[2];
91 
92  seg[0].flags = 0;
93  seg[0].slave = slave;
94  seg[0].buf = &reg;
95  seg[0].len = 1;
96  seg[1].flags = I2C_M_RD;
97  seg[1].slave = slave;
98  seg[1].buf = data;
99  seg[1].len = len;
100 
101  return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
102 }
103 
104 /**
105  * Read a byte with two segments in one frame
106  *
107  * [start][slave addr][w][register addr][start][slave addr][r][data][stop]
108  */
109 static inline int i2c_readb(unsigned int bus, uint8_t slave, uint8_t reg,
110  uint8_t *data)
111 {
112  struct i2c_msg seg[2];
113 
114  seg[0].flags = 0;
115  seg[0].slave = slave;
116  seg[0].buf = &reg;
117  seg[0].len = 1;
118  seg[1].flags = I2C_M_RD;
119  seg[1].slave = slave;
120  seg[1].buf = data;
121  seg[1].len = 1;
122 
123  return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
124 }
125 
126 /**
127  * Write a byte with one segment in one frame.
128  *
129  * [start][slave addr][w][register addr][data][stop]
130  */
131 static inline int i2c_writeb(unsigned int bus, uint8_t slave, uint8_t reg,
132  uint8_t data)
133 {
134  struct i2c_msg seg;
135  uint8_t buf[] = {reg, data};
136 
137  seg.flags = 0;
138  seg.slave = slave;
139  seg.buf = buf;
140  seg.len = ARRAY_SIZE(buf);
141 
142  return i2c_transfer(bus, &seg, 1);
143 }
144 
145 /**
146  * Read multi-bytes from an I2C device with two bytes register address/offset
147  * with two segments in one frame
148  *
149  * [start][slave addr][w][register high addr][register low addr]
150  * [start][slave addr][r][data...][stop]
151  */
152 static inline int i2c_2ba_read_bytes(unsigned int bus, uint8_t slave, uint16_t offset,
153  uint8_t *data, int len)
154 {
155  struct i2c_msg seg[2];
156  uint8_t eeprom_offset[2];
157 
158  eeprom_offset[0] = offset >> 8;
159  eeprom_offset[1] = offset & 0xff;
160 
161  seg[0].flags = 0;
162  seg[0].slave = slave;
163  seg[0].buf = eeprom_offset;
164  seg[0].len = sizeof(eeprom_offset);
165  seg[1].flags = I2C_M_RD;
166  seg[1].slave = slave;
167  seg[1].buf = data;
168  seg[1].len = len;
169 
170  return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
171 }
172 
173 #endif /* _DEVICE_I2C_SIMPLE_H_ */
#define ARRAY_SIZE(a)
Definition: helpers.h:12
@ CONFIG
Definition: dsi_common.h:201
static size_t offset
Definition: flashconsole.c:16
static int i2c_writeb(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t data)
Write a byte with one segment in one frame.
Definition: i2c_simple.h:131
static int i2c_readb(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t *data)
Read a byte with two segments in one frame.
Definition: i2c_simple.h:109
int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Definition: dw_i2c.c:484
int i2c_write_field(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t data, uint8_t mask, uint8_t shift)
Definition: i2c.c:20
int software_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Definition: software_i2c.c:233
static int i2c_read_bytes(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t *data, int len)
Read multi-bytes with two segments in one frame.
Definition: i2c_simple.h:87
static int i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Definition: i2c_simple.h:42
static int i2c_write_raw(unsigned int bus, uint8_t slave, uint8_t *data, int len)
Definition: i2c_simple.h:72
struct software_i2c_ops * software_i2c[]
Definition: software_i2c.c:24
static int i2c_2ba_read_bytes(unsigned int bus, uint8_t slave, uint16_t offset, uint8_t *data, int len)
Read multi-bytes from an I2C device with two bytes register address/offset with two segments in one f...
Definition: i2c_simple.h:152
void software_i2c_wedge_ack(unsigned int bus, u8 slave)
Definition: software_i2c.c:261
int i2c_read_field(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t *data, uint8_t mask, uint8_t shift)
Definition: i2c.c:6
#define SOFTWARE_I2C_MAX_BUS
Definition: i2c_simple.h:13
void software_i2c_wedge_read(unsigned int bus, u8 slave, u8 reg, int bit_count)
Definition: software_i2c.c:284
void software_i2c_wedge_write(unsigned int bus, u8 slave, u8 reg, int bit_count)
Definition: software_i2c.c:313
static int i2c_read_raw(unsigned int bus, uint8_t slave, uint8_t *data, int len)
Definition: i2c_simple.h:57
#define I2C_M_RD
Definition: i2c.h:34
static uint8_t * buf
Definition: uart.c:7
static const int mask[4]
Definition: gpio.c:308
static struct spi_slave slave
Definition: spiconsole.c:7
unsigned short uint16_t
Definition: stdint.h:11
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
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
typedef void(X86APIP X86EMU_intrFuncs)(int num)