@ -696,9 +696,7 @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
switch ( offset ) {
case A_I2CD_FUN_CTRL :
if ( SHARED_FIELD_EX32 ( value , SLAVE_EN ) ) {
qemu_log_mask ( LOG_UNIMP , " %s: slave mode not implemented \n " ,
__func__ ) ;
break ;
i2c_slave_set_address ( bus - > slave , bus - > regs [ R_I2CD_DEV_ADDR ] ) ;
}
bus - > regs [ R_I2CD_FUN_CTRL ] = value & 0x0071C3FF ;
break ;
@ -719,12 +717,15 @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
bus - > controller - > intr_status & = ~ ( 1 < < bus - > id ) ;
qemu_irq_lower ( aic - > bus_get_irq ( bus ) ) ;
}
if ( handle_rx & & ( SHARED_ARRAY_FIELD_EX32 ( bus - > regs , R_I2CD_CMD ,
M_RX_CMD ) | |
SHARED_ARRAY_FIELD_EX32 ( bus - > regs , R_I2CD_CMD ,
M_S_RX_CMD_LAST ) ) ) {
aspeed_i2c_handle_rx_cmd ( bus ) ;
aspeed_i2c_bus_raise_interrupt ( bus ) ;
if ( handle_rx ) {
if ( SHARED_ARRAY_FIELD_EX32 ( bus - > regs , R_I2CD_CMD , M_RX_CMD ) | |
SHARED_ARRAY_FIELD_EX32 ( bus - > regs , R_I2CD_CMD ,
M_S_RX_CMD_LAST ) ) {
aspeed_i2c_handle_rx_cmd ( bus ) ;
aspeed_i2c_bus_raise_interrupt ( bus ) ;
} else if ( aspeed_i2c_get_state ( bus ) = = I2CD_STXD ) {
i2c_ack ( bus - > bus ) ;
}
}
break ;
case A_I2CD_DEV_ADDR :
@ -1036,6 +1037,73 @@ static const TypeInfo aspeed_i2c_info = {
. abstract = true ,
} ;
static int aspeed_i2c_bus_slave_event ( I2CSlave * slave , enum i2c_event event )
{
BusState * qbus = qdev_get_parent_bus ( DEVICE ( slave ) ) ;
AspeedI2CBus * bus = ASPEED_I2C_BUS ( qbus - > parent ) ;
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset ( bus ) ;
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset ( bus ) ;
uint32_t value ;
switch ( event ) {
case I2C_START_SEND_ASYNC :
value = SHARED_ARRAY_FIELD_EX32 ( bus - > regs , reg_byte_buf , TX_BUF ) ;
SHARED_ARRAY_FIELD_DP32 ( bus - > regs , reg_byte_buf , RX_BUF , value < < 1 ) ;
ARRAY_FIELD_DP32 ( bus - > regs , I2CD_INTR_STS , SLAVE_ADDR_RX_MATCH , 1 ) ;
SHARED_ARRAY_FIELD_DP32 ( bus - > regs , reg_intr_sts , RX_DONE , 1 ) ;
aspeed_i2c_set_state ( bus , I2CD_STXD ) ;
break ;
case I2C_FINISH :
SHARED_ARRAY_FIELD_DP32 ( bus - > regs , reg_intr_sts , NORMAL_STOP , 1 ) ;
aspeed_i2c_set_state ( bus , I2CD_IDLE ) ;
break ;
default :
return - 1 ;
}
aspeed_i2c_bus_raise_interrupt ( bus ) ;
return 0 ;
}
static void aspeed_i2c_bus_slave_send_async ( I2CSlave * slave , uint8_t data )
{
BusState * qbus = qdev_get_parent_bus ( DEVICE ( slave ) ) ;
AspeedI2CBus * bus = ASPEED_I2C_BUS ( qbus - > parent ) ;
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset ( bus ) ;
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset ( bus ) ;
SHARED_ARRAY_FIELD_DP32 ( bus - > regs , reg_byte_buf , RX_BUF , data ) ;
SHARED_ARRAY_FIELD_DP32 ( bus - > regs , reg_intr_sts , RX_DONE , 1 ) ;
aspeed_i2c_bus_raise_interrupt ( bus ) ;
}
static void aspeed_i2c_bus_slave_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
I2CSlaveClass * sc = I2C_SLAVE_CLASS ( klass ) ;
dc - > desc = " Aspeed I2C Bus Slave " ;
sc - > event = aspeed_i2c_bus_slave_event ;
sc - > send_async = aspeed_i2c_bus_slave_send_async ;
}
static const TypeInfo aspeed_i2c_bus_slave_info = {
. name = TYPE_ASPEED_I2C_BUS_SLAVE ,
. parent = TYPE_I2C_SLAVE ,
. instance_size = sizeof ( AspeedI2CBusSlave ) ,
. class_init = aspeed_i2c_bus_slave_class_init ,
} ;
static void aspeed_i2c_bus_reset ( DeviceState * dev )
{
AspeedI2CBus * s = ASPEED_I2C_BUS ( dev ) ;
@ -1060,6 +1128,8 @@ static void aspeed_i2c_bus_realize(DeviceState *dev, Error **errp)
sysbus_init_irq ( SYS_BUS_DEVICE ( dev ) , & s - > irq ) ;
s - > bus = i2c_init_bus ( dev , name ) ;
s - > slave = i2c_slave_create_simple ( s - > bus , TYPE_ASPEED_I2C_BUS_SLAVE ,
0xff ) ;
memory_region_init_io ( & s - > mr , OBJECT ( s ) , & aspeed_i2c_bus_ops ,
s , name , aic - > reg_size ) ;
@ -1219,6 +1289,7 @@ static const TypeInfo aspeed_1030_i2c_info = {
static void aspeed_i2c_register_types ( void )
{
type_register_static ( & aspeed_i2c_bus_info ) ;
type_register_static ( & aspeed_i2c_bus_slave_info ) ;
type_register_static ( & aspeed_i2c_info ) ;
type_register_static ( & aspeed_2400_i2c_info ) ;
type_register_static ( & aspeed_2500_i2c_info ) ;