mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
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:
parent
86c7e2f4a9
commit
93198b6cad
18 changed files with 288 additions and 196 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
165
hw/i2c/smbus_master.c
Normal 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;
|
||||
}
|
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue