aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Waddel <matt.waddel@ubuntu.com>2013-02-18 16:58:26 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-05-03 21:22:13 +0100
commitec5e16d79f87edcb4af17b6fecf28ddfbd9ae9c6 (patch)
tree0fb6655bd52ec8a6892430c41529042d734165af
parent0463a8b80804291cd4a139d28241e8b36ae0f15b (diff)
omap_i2c.c: Support byte reads to registers
Added support for the byte read of the omap i2c system. Handling is similar to the way i2c_write and i2c_writeb work.
-rw-r--r--hw/i2c/omap_i2c.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index bff069653..0bd7d853a 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -330,6 +330,61 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
return 0;
}
+static uint32_t omap_i2c_readb(void *opaque, hwaddr addr)
+{
+ OMAPI2CState *s = opaque;
+ int offset = addr & OMAP_MPUI_REG_MASK;
+ uint8_t ret;
+
+ switch (offset) {
+ case 0x1c: /* I2C_DATA */
+ ret = 0;
+ if (s->fifolen) {
+ if (s->revision < OMAP3_INTR_REV) {
+ if (s->control & (1 << 14)) /* BE */
+ ret = (((uint8_t)s->fifo[s->fifostart]) << 8)
+ | s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK];
+ else
+ ret = (((uint8_t)s->fifo[(s->fifostart + 1) & I2C_FIFO_SIZE_MASK]) << 8)
+ | s->fifo[s->fifostart];
+ s->fifostart = (s->fifostart + 2) & I2C_FIFO_SIZE_MASK;
+ if (s->fifolen == 1) {
+ s->stat |= 1 << 15; /* SBD */
+ s->fifolen = 0;
+ } else
+ s->fifolen -= 2;
+ if (!s->fifolen) {
+ s->stat &= ~(1 << 3); /* RRDY */
+ s->stat |= 1 << 2; /* ARDY */
+ }
+ } else {
+ s->stat &= ~(1 << 7); /* AERR */
+ ret = (uint8_t)s->fifo[s->fifostart++];
+ s->fifostart &= I2C_FIFO_SIZE_MASK;
+ if (--s->fifolen) {
+ if (s->fifolen <= ((s->dma >> 8) & 0x3f)) {
+ s->stat &= ~(1 << 3); /* RRDY */
+ s->stat |= 1 << 13; /* RDR */
+ }
+ } else {
+ s->stat &= ~((1 << 3) | (1 << 13)); /* RRDY | RDR */
+ s->stat |= 1 << 2; /* ARDY */
+ }
+ }
+ s->stat &= ~(1 << 11); /* ROVR */
+ } else if (s->revision >= OMAP3_INTR_REV)
+ s->stat |= (1 << 7); /* AERR */
+ omap_i2c_fifo_run(s);
+ omap_i2c_interrupts_update(s);
+ return ret;
+ default:
+ break;
+ }
+
+ OMAP_BAD_REG(addr);
+ return 0;
+}
+
static void omap_i2c_write(void *opaque, hwaddr addr,
uint32_t value)
{
@@ -593,7 +648,7 @@ static void omap_i2c_writeb(void *opaque, hwaddr addr,
static const MemoryRegionOps omap_i2c_ops = {
.old_mmio = {
.read = {
- omap_badwidth_read16,
+ omap_i2c_readb,
omap_i2c_read,
omap_badwidth_read16,
},