@@ -19,10 +19,25 @@ typedef struct {
uint8_t polarity;
uint8_t status;
uint8_t command;
+ uint8_t output;
qemu_irq handler[8];
qemu_irq *gpio_in;
} MAX7310State;
+/*this function to update outputports level*/
+static void max7310_update(MAX7310State *s)
+{
+ uint8_t diff = 0;
+ uint8_t line = 0;
+ for (diff = (s->output ^ s->level) & ~s->direction; diff;
+ diff &= ~(1 << line)) {
+ line = ffs(diff) - 1;
+ if (s->handler[line]) {
+ qemu_set_irq(s->handler[line], (s->output >> line) & 1);
+ }
+ }
+ s->level = (s->level & s->direction) | (s->level & ~s->direction);
+}
+
static void max7310_reset(DeviceState *dev)
{
MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, I2C_SLAVE(dev));
@@ -31,6 +46,8 @@ static void max7310_reset(DeviceState *dev)
s->polarity = 0xf0;
s->status = 0x01;
s->command = 0x00;
+ s->output = 0x00;
+ max7310_update(s);
}
static int max7310_rx(I2CSlave *i2c)
@@ -43,7 +60,7 @@ static int max7310_rx(I2CSlave *i2c)
break;
case 0x01: /* Output port */
- return s->level & ~s->direction;
+ return s->output;
break;
case 0x02: /* Polarity inversion */
@@ -71,8 +88,6 @@ static int max7310_rx(I2CSlave *i2c)
static int max7310_tx(I2CSlave *i2c, uint8_t data)
{
MAX7310State *s = (MAX7310State *) i2c;
- uint8_t diff;
- int line;
if (s->len ++ > 1) {
#ifdef VERBOSE
@@ -89,13 +104,8 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
switch (s->command) {
case 0x01: /* Output port */
- for (diff = (data ^ s->level) & ~s->direction; diff;
- diff &= ~(1 << line)) {
- line = ffs(diff) - 1;
- if (s->handler[line])
- qemu_set_irq(s->handler[line], (data >> line) & 1);
- }
- s->level = (s->level & s->direction) | (data & ~s->direction);
+ s->output = data;
+ max7310_update(s);
break;
case 0x02: /* Polarity inversion */
@@ -103,8 +113,8 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
break;
case 0x03: /* Configuration */
- s->level &= ~(s->direction ^ data);
s->direction = data;
+ max7310_update(s);
break;
case 0x04: /* Timeout */
@@ -156,6 +166,7 @@ static const VMStateDescription vmstate_max7310 = {
VMSTATE_UINT8(polarity, MAX7310State),
VMSTATE_UINT8(status, MAX7310State),
VMSTATE_UINT8(command, MAX7310State),
+ VMSTATE_UINT8(output, MAX7310State),
VMSTATE_I2C_SLAVE(i2c, MAX7310State),
VMSTATE_END_OF_LIST()
}