mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
i2c: pm_smbus: Fix the semantics of block I2C transfers
The I2C block transfer commands was not implemented correctly, it read a length byte and such like it was an smbus transfer. So fix the smbus_read_block() and smbus_write_block() functions so they can properly handle I2C transfers, and normal SMBus transfers (for upcoming changes). Pass in a transfer size and a bool to know whether to use the size byte (like SMBus) or use the length given (like I2C). Signed-off-by: Corey Minyard <cminyard@mvista.com> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <1534796770-10295-3-git-send-email-minyard@acm.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
b8fb9043eb
commit
4b615be540
3 changed files with 47 additions and 17 deletions
|
@ -293,33 +293,42 @@ int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
|
||||
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
|
||||
int len, bool recv_len, bool send_cmd)
|
||||
{
|
||||
int len;
|
||||
int rlen;
|
||||
int i;
|
||||
|
||||
if (i2c_start_transfer(bus, addr, 0)) {
|
||||
return -1;
|
||||
if (send_cmd) {
|
||||
if (i2c_start_transfer(bus, addr, 0)) {
|
||||
return -1;
|
||||
}
|
||||
i2c_send(bus, command);
|
||||
}
|
||||
i2c_send(bus, command);
|
||||
if (i2c_start_transfer(bus, addr, 1)) {
|
||||
i2c_end_transfer(bus);
|
||||
if (send_cmd) {
|
||||
i2c_end_transfer(bus);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
len = i2c_recv(bus);
|
||||
if (len > 32) {
|
||||
len = 0;
|
||||
if (recv_len) {
|
||||
rlen = i2c_recv(bus);
|
||||
} else {
|
||||
rlen = len;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
if (rlen > len) {
|
||||
rlen = 0;
|
||||
}
|
||||
for (i = 0; i < rlen; i++) {
|
||||
data[i] = i2c_recv(bus);
|
||||
}
|
||||
i2c_nack(bus);
|
||||
i2c_end_transfer(bus);
|
||||
return len;
|
||||
return rlen;
|
||||
}
|
||||
|
||||
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
|
||||
int len)
|
||||
int len, bool send_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -330,7 +339,9 @@ int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
|
|||
return -1;
|
||||
}
|
||||
i2c_send(bus, command);
|
||||
i2c_send(bus, len);
|
||||
if (send_len) {
|
||||
i2c_send(bus, len);
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
i2c_send(bus, data[i]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue