i2c: Split smbus into parts

smbus.c and smbus.h had device side code, master side code, and
smbus.h has some smbus_eeprom.c definitions.  Split them into
separate files.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
This commit is contained in:
Corey Minyard 2018-11-13 18:31:27 -06:00
parent 86c7e2f4a9
commit 93198b6cad
18 changed files with 288 additions and 196 deletions

View file

@ -1,4 +1,4 @@
common-obj-$(CONFIG_I2C) += core.o smbus.o
common-obj-$(CONFIG_I2C) += core.o smbus_slave.o smbus_master.o
common-obj-$(CONFIG_SMBUS_EEPROM) += smbus_eeprom.o
common-obj-$(CONFIG_DDC) += i2c-ddc.o
common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o

View file

@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/i2c/pm_smbus.h"
#include "hw/i2c/smbus.h"
#include "hw/i2c/smbus_master.h"
#define SMBHSTSTS 0x00
#define SMBHSTCNT 0x02

View file

@ -27,7 +27,8 @@
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/smbus.h"
#include "hw/i2c/smbus_slave.h"
#include "hw/i2c/smbus_eeprom.h"
//#define DEBUG

View file

@ -29,8 +29,6 @@
#include "hw/i2c/pm_smbus.h"
#include "hw/pci/pci.h"
#include "sysemu/sysemu.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/smbus.h"
#include "hw/i386/ich9.h"

165
hw/i2c/smbus_master.c Normal file
View file

@ -0,0 +1,165 @@
/*
* QEMU SMBus host (master) emulation.
*
* This code emulates SMBus transactions from the master point of view,
* it runs the individual I2C transaction to do the SMBus protocol
* over I2C.
*
* Copyright (c) 2007 CodeSourcery.
* Written by Paul Brook
*
* This code is licensed under the LGPL.
*/
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/smbus_master.h"
/* Master device commands. */
int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
{
if (i2c_start_transfer(bus, addr, read)) {
return -1;
}
i2c_end_transfer(bus);
return 0;
}
int smbus_receive_byte(I2CBus *bus, uint8_t addr)
{
uint8_t data;
if (i2c_start_transfer(bus, addr, 1)) {
return -1;
}
data = i2c_recv(bus);
i2c_nack(bus);
i2c_end_transfer(bus);
return data;
}
int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
{
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, data);
i2c_end_transfer(bus);
return 0;
}
int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
{
uint8_t data;
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
i2c_end_transfer(bus);
return -1;
}
data = i2c_recv(bus);
i2c_nack(bus);
i2c_end_transfer(bus);
return data;
}
int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
{
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
i2c_send(bus, data);
i2c_end_transfer(bus);
return 0;
}
int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
{
uint16_t data;
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
i2c_end_transfer(bus);
return -1;
}
data = i2c_recv(bus);
data |= i2c_recv(bus) << 8;
i2c_nack(bus);
i2c_end_transfer(bus);
return data;
}
int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
{
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
i2c_send(bus, data & 0xff);
i2c_send(bus, data >> 8);
i2c_end_transfer(bus);
return 0;
}
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len, bool recv_len, bool send_cmd)
{
int rlen;
int i;
if (send_cmd) {
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
}
if (i2c_start_transfer(bus, addr, 1)) {
if (send_cmd) {
i2c_end_transfer(bus);
}
return -1;
}
if (recv_len) {
rlen = i2c_recv(bus);
} else {
rlen = len;
}
if (rlen > len) {
rlen = 0;
}
for (i = 0; i < rlen; i++) {
data[i] = i2c_recv(bus);
}
i2c_nack(bus);
i2c_end_transfer(bus);
return rlen;
}
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len, bool send_len)
{
int i;
if (len > 32) {
len = 32;
}
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
if (send_len) {
i2c_send(bus, len);
}
for (i = 0; i < len; i++) {
i2c_send(bus, data[i]);
}
i2c_end_transfer(bus);
return 0;
}

View file

@ -1,6 +1,10 @@
/*
* QEMU SMBus device emulation.
*
* This code is a helper for SMBus device emulation. It implements an
* I2C device inteface and runs the SMBus protocol from the device
* point of view and maps those to simple calls to emulate.
*
* Copyright (c) 2007 CodeSourcery.
* Written by Paul Brook
*
@ -12,7 +16,7 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/smbus.h"
#include "hw/i2c/smbus_slave.h"
//#define DEBUG_SMBUS 1
@ -206,153 +210,6 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
return 0;
}
/* Master device commands. */
int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
{
if (i2c_start_transfer(bus, addr, read)) {
return -1;
}
i2c_end_transfer(bus);
return 0;
}
int smbus_receive_byte(I2CBus *bus, uint8_t addr)
{
uint8_t data;
if (i2c_start_transfer(bus, addr, 1)) {
return -1;
}
data = i2c_recv(bus);
i2c_nack(bus);
i2c_end_transfer(bus);
return data;
}
int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
{
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, data);
i2c_end_transfer(bus);
return 0;
}
int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
{
uint8_t data;
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
i2c_end_transfer(bus);
return -1;
}
data = i2c_recv(bus);
i2c_nack(bus);
i2c_end_transfer(bus);
return data;
}
int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
{
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
i2c_send(bus, data);
i2c_end_transfer(bus);
return 0;
}
int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
{
uint16_t data;
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
i2c_end_transfer(bus);
return -1;
}
data = i2c_recv(bus);
data |= i2c_recv(bus) << 8;
i2c_nack(bus);
i2c_end_transfer(bus);
return data;
}
int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
{
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
i2c_send(bus, data & 0xff);
i2c_send(bus, data >> 8);
i2c_end_transfer(bus);
return 0;
}
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len, bool recv_len, bool send_cmd)
{
int rlen;
int i;
if (send_cmd) {
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
}
if (i2c_start_transfer(bus, addr, 1)) {
if (send_cmd) {
i2c_end_transfer(bus);
}
return -1;
}
if (recv_len) {
rlen = i2c_recv(bus);
} else {
rlen = len;
}
if (rlen > len) {
rlen = 0;
}
for (i = 0; i < rlen; i++) {
data[i] = i2c_recv(bus);
}
i2c_nack(bus);
i2c_end_transfer(bus);
return rlen;
}
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len, bool send_len)
{
int i;
if (len > 32)
len = 32;
if (i2c_start_transfer(bus, addr, 0)) {
return -1;
}
i2c_send(bus, command);
if (send_len) {
i2c_send(bus, len);
}
for (i = 0; i < len; i++) {
i2c_send(bus, data[i]);
}
i2c_end_transfer(bus);
return 0;
}
static void smbus_device_class_init(ObjectClass *klass, void *data)
{
I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);