1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <device/smbus.h>
6 #include <device/i2c_bus.h>
7 #include <commonlib/endian.h>
9 struct bus
*i2c_link(struct device
*const dev
)
11 if (!dev
|| !dev
->bus
)
14 struct bus
*link
= dev
->bus
;
16 struct device
*const parent
= link
->dev
;
18 if (parent
&& parent
->ops
&&
19 (parent
->ops
->ops_i2c_bus
|| parent
->ops
->ops_smbus_bus
))
22 if (parent
&& parent
->bus
)
29 printk(BIOS_ALERT
, "%s Cannot find I2C or SMBus bus operations",
36 int i2c_dev_readb(struct device
*const dev
)
38 struct device
*const busdev
= i2c_busdev(dev
);
42 if (busdev
->ops
->ops_i2c_bus
) {
44 const struct i2c_msg msg
= {
46 .slave
= dev
->path
.i2c
.device
,
51 const int ret
= busdev
->ops
->ops_i2c_bus
->
52 transfer(busdev
, &msg
, 1);
57 } else if (busdev
->ops
->ops_smbus_bus
->recv_byte
) {
58 return busdev
->ops
->ops_smbus_bus
->recv_byte(dev
);
60 printk(BIOS_ERR
, "%s Missing ops_smbus_bus->recv_byte",
66 int i2c_dev_writeb(struct device
*const dev
, uint8_t val
)
68 struct device
*const busdev
= i2c_busdev(dev
);
72 if (busdev
->ops
->ops_i2c_bus
) {
73 const struct i2c_msg msg
= {
75 .slave
= dev
->path
.i2c
.device
,
79 return busdev
->ops
->ops_i2c_bus
->transfer(busdev
, &msg
, 1);
80 } else if (busdev
->ops
->ops_smbus_bus
->send_byte
) {
81 return busdev
->ops
->ops_smbus_bus
->send_byte(dev
, val
);
83 printk(BIOS_ERR
, "%s Missing ops_smbus_bus->send_byte",
89 int i2c_dev_readb_at(struct device
*const dev
, uint8_t off
)
91 struct device
*const busdev
= i2c_busdev(dev
);
95 if (busdev
->ops
->ops_i2c_bus
) {
97 const struct i2c_msg msg
[] = {
100 .slave
= dev
->path
.i2c
.device
,
106 .slave
= dev
->path
.i2c
.device
,
112 const int ret
= busdev
->ops
->ops_i2c_bus
->
113 transfer(busdev
, msg
, ARRAY_SIZE(msg
));
118 } else if (busdev
->ops
->ops_smbus_bus
->read_byte
) {
119 return busdev
->ops
->ops_smbus_bus
->read_byte(dev
, off
);
121 printk(BIOS_ERR
, "%s Missing ops_smbus_bus->read_byte",
127 int i2c_dev_writeb_at(struct device
*const dev
,
128 const uint8_t off
, const uint8_t val
)
130 struct device
*const busdev
= i2c_busdev(dev
);
134 if (busdev
->ops
->ops_i2c_bus
) {
135 uint8_t buf
[] = { off
, val
};
136 const struct i2c_msg msg
= {
138 .slave
= dev
->path
.i2c
.device
,
142 return busdev
->ops
->ops_i2c_bus
->transfer(busdev
, &msg
, 1);
143 } else if (busdev
->ops
->ops_smbus_bus
->write_byte
) {
144 return busdev
->ops
->ops_smbus_bus
->write_byte(dev
, off
, val
);
146 printk(BIOS_ERR
, "%s Missing ops_smbus_bus->write_byte",
152 int i2c_dev_read_at16(struct device
*const dev
,
153 uint8_t *const buf
, const size_t len
, uint16_t off
)
155 struct device
*const busdev
= i2c_busdev(dev
);
159 if (busdev
->ops
->ops_i2c_bus
) {
160 const struct i2c_msg msg
[] = {
163 .slave
= dev
->path
.i2c
.device
,
164 .buf
= (uint8_t *)&off
,
169 .slave
= dev
->path
.i2c
.device
,
175 write_be16(&off
, off
);
176 const int ret
= busdev
->ops
->ops_i2c_bus
->transfer(
177 busdev
, msg
, ARRAY_SIZE(msg
));
183 printk(BIOS_ERR
, "%s Missing ops_i2c_bus->transfer", dev_path(busdev
));