1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #ifndef _DEVICE_I2C_SIMPLE_H_
4 #define _DEVICE_I2C_SIMPLE_H_
6 #include <commonlib/helpers.h>
7 #include <device/i2c.h>
10 int platform_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
,
13 #define SOFTWARE_I2C_MAX_BUS 10 /* increase as necessary */
15 struct software_i2c_ops
{
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
);
22 extern struct software_i2c_ops
*software_i2c
[];
24 int software_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
,
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
,
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
);
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.
42 static inline int i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
,
45 if (CONFIG(SOFTWARE_I2C
))
46 if (bus
< SOFTWARE_I2C_MAX_BUS
&& software_i2c
[bus
])
47 return software_i2c_transfer(bus
, segments
, count
);
49 return platform_i2c_transfer(bus
, segments
, count
);
53 * Read a raw chunk of data in one segment and one frame.
55 * [start][slave addr][r][data][stop]
57 static inline int i2c_read_raw(unsigned int bus
, uint8_t slave
, uint8_t *data
,
60 struct i2c_msg seg
= {
61 .flags
= I2C_M_RD
, .slave
= slave
, .buf
= data
, .len
= len
64 return i2c_transfer(bus
, &seg
, 1);
68 * Write a raw chunk of data in one segment and one frame.
70 * [start][slave addr][w][data][stop]
72 static inline int i2c_write_raw(unsigned int bus
, uint8_t slave
, uint8_t *data
,
75 struct i2c_msg seg
= {
76 .flags
= 0, .slave
= slave
, .buf
= data
, .len
= len
79 return i2c_transfer(bus
, &seg
, 1);
83 * Read multi-bytes with two segments in one frame
85 * [start][slave addr][w][register addr][start][slave addr][r][data...][stop]
87 static inline int i2c_read_bytes(unsigned int bus
, uint8_t slave
, uint8_t reg
,
88 uint8_t *data
, int len
)
90 struct i2c_msg seg
[2];
96 seg
[1].flags
= I2C_M_RD
;
101 return i2c_transfer(bus
, seg
, ARRAY_SIZE(seg
));
105 * Read a byte with two segments in one frame
107 * [start][slave addr][w][register addr][start][slave addr][r][data][stop]
109 static inline int i2c_readb(unsigned int bus
, uint8_t slave
, uint8_t reg
,
112 struct i2c_msg seg
[2];
115 seg
[0].slave
= slave
;
118 seg
[1].flags
= I2C_M_RD
;
119 seg
[1].slave
= slave
;
123 return i2c_transfer(bus
, seg
, ARRAY_SIZE(seg
));
127 * Write a byte with one segment in one frame.
129 * [start][slave addr][w][register addr][data][stop]
131 static inline int i2c_writeb(unsigned int bus
, uint8_t slave
, uint8_t reg
,
135 uint8_t buf
[] = {reg
, data
};
140 seg
.len
= ARRAY_SIZE(buf
);
142 return i2c_transfer(bus
, &seg
, 1);
146 * Read multi-bytes from an I2C device with two bytes register address/offset
147 * with two segments in one frame
149 * [start][slave addr][w][register high addr][register low addr]
150 * [start][slave addr][r][data...][stop]
152 static inline int i2c_2ba_read_bytes(unsigned int bus
, uint8_t slave
, uint16_t offset
,
153 uint8_t *data
, int len
)
155 struct i2c_msg seg
[2];
156 uint8_t eeprom_offset
[2];
158 eeprom_offset
[0] = offset
>> 8;
159 eeprom_offset
[1] = offset
& 0xff;
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
;
170 return i2c_transfer(bus
, seg
, ARRAY_SIZE(seg
));
173 #endif /* _DEVICE_I2C_SIMPLE_H_ */