diff options
author | 2015-08-28 09:58:54 +0800 | |
---|---|---|
committer | 2015-09-01 12:44:00 +0800 | |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/include/hw/i2c | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/include/hw/i2c')
-rw-r--r-- | qemu/include/hw/i2c/i2c.h | 86 | ||||
-rw-r--r-- | qemu/include/hw/i2c/pm_smbus.h | 20 | ||||
-rw-r--r-- | qemu/include/hw/i2c/smbus.h | 83 |
3 files changed, 189 insertions, 0 deletions
diff --git a/qemu/include/hw/i2c/i2c.h b/qemu/include/hw/i2c/i2c.h new file mode 100644 index 000000000..4986ebc73 --- /dev/null +++ b/qemu/include/hw/i2c/i2c.h @@ -0,0 +1,86 @@ +#ifndef QEMU_I2C_H +#define QEMU_I2C_H + +#include "hw/qdev.h" + +/* The QEMU I2C implementation only supports simple transfers that complete + immediately. It does not support slave devices that need to be able to + defer their response (eg. CPU slave interfaces where the data is supplied + by the device driver in response to an interrupt). */ + +enum i2c_event { + I2C_START_RECV, + I2C_START_SEND, + I2C_FINISH, + I2C_NACK /* Masker NACKed a receive byte. */ +}; + +typedef struct I2CSlave I2CSlave; + +#define TYPE_I2C_SLAVE "i2c-slave" +#define I2C_SLAVE(obj) \ + OBJECT_CHECK(I2CSlave, (obj), TYPE_I2C_SLAVE) +#define I2C_SLAVE_CLASS(klass) \ + OBJECT_CLASS_CHECK(I2CSlaveClass, (klass), TYPE_I2C_SLAVE) +#define I2C_SLAVE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE) + +typedef struct I2CSlaveClass +{ + DeviceClass parent_class; + + /* Callbacks provided by the device. */ + int (*init)(I2CSlave *dev); + + /* Master to slave. */ + int (*send)(I2CSlave *s, uint8_t data); + + /* Slave to master. */ + int (*recv)(I2CSlave *s); + + /* Notify the slave of a bus state change. */ + void (*event)(I2CSlave *s, enum i2c_event event); +} I2CSlaveClass; + +struct I2CSlave +{ + DeviceState qdev; + + /* Remaining fields for internal use by the I2C code. */ + uint8_t address; +}; + +I2CBus *i2c_init_bus(DeviceState *parent, const char *name); +void i2c_set_slave_address(I2CSlave *dev, uint8_t address); +int i2c_bus_busy(I2CBus *bus); +int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv); +void i2c_end_transfer(I2CBus *bus); +void i2c_nack(I2CBus *bus); +int i2c_send(I2CBus *bus, uint8_t data); +int i2c_recv(I2CBus *bus); + +DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr); + +/* wm8750.c */ +void wm8750_data_req_set(DeviceState *dev, + void (*data_req)(void *, int, int), void *opaque); +void wm8750_dac_dat(void *opaque, uint32_t sample); +uint32_t wm8750_adc_dat(void *opaque); +void *wm8750_dac_buffer(void *opaque, int samples); +void wm8750_dac_commit(void *opaque); +void wm8750_set_bclk_in(void *opaque, int new_hz); + +/* lm832x.c */ +void lm832x_key_event(DeviceState *dev, int key, int state); + +extern const VMStateDescription vmstate_i2c_slave; + +#define VMSTATE_I2C_SLAVE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(I2CSlave), \ + .vmsd = &vmstate_i2c_slave, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, I2CSlave), \ +} + +#endif diff --git a/qemu/include/hw/i2c/pm_smbus.h b/qemu/include/hw/i2c/pm_smbus.h new file mode 100644 index 000000000..926603fdf --- /dev/null +++ b/qemu/include/hw/i2c/pm_smbus.h @@ -0,0 +1,20 @@ +#ifndef PM_SMBUS_H +#define PM_SMBUS_H + +typedef struct PMSMBus { + I2CBus *smbus; + MemoryRegion io; + + uint8_t smb_stat; + uint8_t smb_ctl; + uint8_t smb_cmd; + uint8_t smb_addr; + uint8_t smb_data0; + uint8_t smb_data1; + uint8_t smb_data[32]; + uint8_t smb_index; +} PMSMBus; + +void pm_smbus_init(DeviceState *parent, PMSMBus *smb); + +#endif /* !PM_SMBUS_H */ diff --git a/qemu/include/hw/i2c/smbus.h b/qemu/include/hw/i2c/smbus.h new file mode 100644 index 000000000..544bbc195 --- /dev/null +++ b/qemu/include/hw/i2c/smbus.h @@ -0,0 +1,83 @@ +#ifndef QEMU_SMBUS_H +#define QEMU_SMBUS_H + +/* + * QEMU SMBus API + * + * Copyright (c) 2007 Arastra, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "hw/i2c/i2c.h" + +#define TYPE_SMBUS_DEVICE "smbus-device" +#define SMBUS_DEVICE(obj) \ + OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE) +#define SMBUS_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE) +#define SMBUS_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE) + +typedef struct SMBusDeviceClass +{ + I2CSlaveClass parent_class; + int (*init)(SMBusDevice *dev); + void (*quick_cmd)(SMBusDevice *dev, uint8_t read); + void (*send_byte)(SMBusDevice *dev, uint8_t val); + uint8_t (*receive_byte)(SMBusDevice *dev); + /* We can't distinguish between a word write and a block write with + length 1, so pass the whole data block including the length byte + (if present). The device is responsible figuring out what type of + command this is. */ + void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len); + /* Likewise we can't distinguish between different reads, or even know + the length of the read until the read is complete, so read data a + byte at a time. The device is responsible for adding the length + byte on block reads. */ + uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n); +} SMBusDeviceClass; + +struct SMBusDevice { + /* The SMBus protocol is implemented on top of I2C. */ + I2CSlave i2c; + + /* Remaining fields for internal use only. */ + int mode; + int data_len; + uint8_t data_buf[34]; /* command + len + 32 bytes of data. */ + uint8_t command; +}; + +/* Master device commands. */ +int smbus_quick_command(I2CBus *bus, uint8_t addr, int read); +int smbus_receive_byte(I2CBus *bus, uint8_t addr); +int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data); +int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command); +int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data); +int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command); +int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data); +int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data); +int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data, + int len); + +void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, + const uint8_t *eeprom_spd, int size); + +#endif |