Commit e3b425361b3787ac1bfc6fec8f7ebae8c37d5d13
1 parent
2d9401aa
PXA2xx I2C slave qdev conversion
Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
1 changed file
with
42 additions
and
13 deletions
hw/pxa2xx.c
| ... | ... | @@ -1256,8 +1256,13 @@ static int pxa2xx_rtc_load(QEMUFile *f, void *opaque, int version_id) |
| 1256 | 1256 | } |
| 1257 | 1257 | |
| 1258 | 1258 | /* I2C Interface */ |
| 1259 | +typedef struct { | |
| 1260 | + i2c_slave i2c; | |
| 1261 | + PXA2xxI2CState *host; | |
| 1262 | +} PXA2xxI2CSlaveState; | |
| 1263 | + | |
| 1259 | 1264 | struct PXA2xxI2CState { |
| 1260 | - i2c_slave slave; | |
| 1265 | + PXA2xxI2CSlaveState *slave; | |
| 1261 | 1266 | i2c_bus *bus; |
| 1262 | 1267 | qemu_irq irq; |
| 1263 | 1268 | target_phys_addr_t offset; |
| ... | ... | @@ -1287,7 +1292,8 @@ static void pxa2xx_i2c_update(PXA2xxI2CState *s) |
| 1287 | 1292 | /* These are only stubs now. */ |
| 1288 | 1293 | static void pxa2xx_i2c_event(i2c_slave *i2c, enum i2c_event event) |
| 1289 | 1294 | { |
| 1290 | - PXA2xxI2CState *s = (PXA2xxI2CState *) i2c; | |
| 1295 | + PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c); | |
| 1296 | + PXA2xxI2CState *s = slave->host; | |
| 1291 | 1297 | |
| 1292 | 1298 | switch (event) { |
| 1293 | 1299 | case I2C_START_SEND: |
| ... | ... | @@ -1310,7 +1316,8 @@ static void pxa2xx_i2c_event(i2c_slave *i2c, enum i2c_event event) |
| 1310 | 1316 | |
| 1311 | 1317 | static int pxa2xx_i2c_rx(i2c_slave *i2c) |
| 1312 | 1318 | { |
| 1313 | - PXA2xxI2CState *s = (PXA2xxI2CState *) i2c; | |
| 1319 | + PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c); | |
| 1320 | + PXA2xxI2CState *s = slave->host; | |
| 1314 | 1321 | if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) |
| 1315 | 1322 | return 0; |
| 1316 | 1323 | |
| ... | ... | @@ -1324,7 +1331,8 @@ static int pxa2xx_i2c_rx(i2c_slave *i2c) |
| 1324 | 1331 | |
| 1325 | 1332 | static int pxa2xx_i2c_tx(i2c_slave *i2c, uint8_t data) |
| 1326 | 1333 | { |
| 1327 | - PXA2xxI2CState *s = (PXA2xxI2CState *) i2c; | |
| 1334 | + PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c); | |
| 1335 | + PXA2xxI2CState *s = slave->host; | |
| 1328 | 1336 | if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) |
| 1329 | 1337 | return 1; |
| 1330 | 1338 | |
| ... | ... | @@ -1348,7 +1356,7 @@ static uint32_t pxa2xx_i2c_read(void *opaque, target_phys_addr_t addr) |
| 1348 | 1356 | case ISR: |
| 1349 | 1357 | return s->status | (i2c_bus_busy(s->bus) << 2); |
| 1350 | 1358 | case ISAR: |
| 1351 | - return s->slave.address; | |
| 1359 | + return s->slave->i2c.address; | |
| 1352 | 1360 | case IDBR: |
| 1353 | 1361 | return s->data; |
| 1354 | 1362 | case IBMR: |
| ... | ... | @@ -1422,7 +1430,7 @@ static void pxa2xx_i2c_write(void *opaque, target_phys_addr_t addr, |
| 1422 | 1430 | break; |
| 1423 | 1431 | |
| 1424 | 1432 | case ISAR: |
| 1425 | - i2c_set_slave_address(&s->slave, value & 0x7f); | |
| 1433 | + i2c_set_slave_address(&s->slave->i2c, value & 0x7f); | |
| 1426 | 1434 | break; |
| 1427 | 1435 | |
| 1428 | 1436 | case IDBR: |
| ... | ... | @@ -1455,7 +1463,7 @@ static void pxa2xx_i2c_save(QEMUFile *f, void *opaque) |
| 1455 | 1463 | qemu_put_8s(f, &s->ibmr); |
| 1456 | 1464 | qemu_put_8s(f, &s->data); |
| 1457 | 1465 | |
| 1458 | - i2c_slave_save(f, &s->slave); | |
| 1466 | + i2c_slave_save(f, &s->slave->i2c); | |
| 1459 | 1467 | } |
| 1460 | 1468 | |
| 1461 | 1469 | static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id) |
| ... | ... | @@ -1470,22 +1478,35 @@ static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id) |
| 1470 | 1478 | qemu_get_8s(f, &s->ibmr); |
| 1471 | 1479 | qemu_get_8s(f, &s->data); |
| 1472 | 1480 | |
| 1473 | - i2c_slave_load(f, &s->slave); | |
| 1481 | + i2c_slave_load(f, &s->slave->i2c); | |
| 1474 | 1482 | return 0; |
| 1475 | 1483 | } |
| 1476 | 1484 | |
| 1485 | +static void pxa2xx_i2c_slave_init(i2c_slave *i2c) | |
| 1486 | +{ | |
| 1487 | + /* Nothing to do. */ | |
| 1488 | +} | |
| 1489 | + | |
| 1490 | +static I2CSlaveInfo pxa2xx_i2c_slave_info = { | |
| 1491 | + .init = pxa2xx_i2c_slave_init, | |
| 1492 | + .event = pxa2xx_i2c_event, | |
| 1493 | + .recv = pxa2xx_i2c_rx, | |
| 1494 | + .send = pxa2xx_i2c_tx | |
| 1495 | +}; | |
| 1496 | + | |
| 1477 | 1497 | PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base, |
| 1478 | 1498 | qemu_irq irq, uint32_t region_size) |
| 1479 | 1499 | { |
| 1480 | 1500 | int iomemtype; |
| 1501 | + DeviceState *dev; | |
| 1502 | + PXA2xxI2CState *s = qemu_mallocz(sizeof(PXA2xxI2CState)); | |
| 1503 | + | |
| 1481 | 1504 | /* FIXME: Should the slave device really be on a separate bus? */ |
| 1482 | - PXA2xxI2CState *s = (PXA2xxI2CState *) | |
| 1483 | - i2c_slave_init(i2c_init_bus(), 0, sizeof(PXA2xxI2CState)); | |
| 1505 | + dev = i2c_create_slave(i2c_init_bus(), "pxa2xx-i2c-slave", 0); | |
| 1506 | + s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE_FROM_QDEV(dev)); | |
| 1507 | + s->slave->host = s; | |
| 1484 | 1508 | |
| 1485 | 1509 | s->irq = irq; |
| 1486 | - s->slave.event = pxa2xx_i2c_event; | |
| 1487 | - s->slave.recv = pxa2xx_i2c_rx; | |
| 1488 | - s->slave.send = pxa2xx_i2c_tx; | |
| 1489 | 1510 | s->bus = i2c_init_bus(); |
| 1490 | 1511 | s->offset = base - (base & (~region_size) & TARGET_PAGE_MASK); |
| 1491 | 1512 | |
| ... | ... | @@ -2257,3 +2278,11 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) |
| 2257 | 2278 | pxa2xx_gpio_out_set(s->gpio, 1, s->reset); |
| 2258 | 2279 | return s; |
| 2259 | 2280 | } |
| 2281 | + | |
| 2282 | +static void pxa2xx_register_devices(void) | |
| 2283 | +{ | |
| 2284 | + i2c_register_slave("pxa2xx-i2c-slave", sizeof(PXA2xxI2CSlaveState), | |
| 2285 | + &pxa2xx_i2c_slave_info); | |
| 2286 | +} | |
| 2287 | + | |
| 2288 | +device_init(pxa2xx_register_devices) | ... | ... |