2 * QEMU SMBus host (master) emulation.
4 * This code emulates SMBus transactions from the master point of view,
5 * it runs the individual I2C transaction to do the SMBus protocol
8 * Copyright (c) 2007 CodeSourcery.
9 * Written by Paul Brook
11 * This code is licensed under the LGPL.
14 #include "qemu/osdep.h"
15 #include "hw/i2c/i2c.h"
16 #include "hw/i2c/smbus_master.h"
18 /* Master device commands. */
19 int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
21 if (i2c_start_transfer(bus, addr, read)) {
24 i2c_end_transfer(bus);
28 int smbus_receive_byte(I2CBus *bus, uint8_t addr)
32 if (i2c_start_recv(bus, addr)) {
37 i2c_end_transfer(bus);
41 int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
43 if (i2c_start_send(bus, addr)) {
47 i2c_end_transfer(bus);
51 int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
54 if (i2c_start_send(bus, addr)) {
57 i2c_send(bus, command);
58 if (i2c_start_recv(bus, addr)) {
59 i2c_end_transfer(bus);
64 i2c_end_transfer(bus);
68 int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
70 if (i2c_start_send(bus, addr)) {
73 i2c_send(bus, command);
75 i2c_end_transfer(bus);
79 int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
82 if (i2c_start_send(bus, addr)) {
85 i2c_send(bus, command);
86 if (i2c_start_recv(bus, addr)) {
87 i2c_end_transfer(bus);
91 data |= i2c_recv(bus) << 8;
93 i2c_end_transfer(bus);
97 int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
99 if (i2c_start_send(bus, addr)) {
102 i2c_send(bus, command);
103 i2c_send(bus, data & 0xff);
104 i2c_send(bus, data >> 8);
105 i2c_end_transfer(bus);
109 int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
110 int len, bool recv_len, bool send_cmd)
116 if (i2c_start_send(bus, addr)) {
119 i2c_send(bus, command);
121 if (i2c_start_recv(bus, addr)) {
123 i2c_end_transfer(bus);
128 rlen = i2c_recv(bus);
135 for (i = 0; i < rlen; i++) {
136 data[i] = i2c_recv(bus);
139 i2c_end_transfer(bus);
143 int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
144 int len, bool send_len)
152 if (i2c_start_send(bus, addr)) {
155 i2c_send(bus, command);
159 for (i = 0; i < len; i++) {
160 i2c_send(bus, data[i]);
162 i2c_end_transfer(bus);