/*
 * TI OMAP on-chip I2C controller.  Only "new I2C" mode supported.
 *
 * Copyright (C) 2007 Andrzej Zaborowski  <balrog@zabor.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/i2c/i2c.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/arm/omap.h"
#include "hw/sysbus.h"
#include "qemu/error-report.h"
#include "qapi/error.h"

struct OMAPI2CState {
    SysBusDevice parent_obj;

    MemoryRegion iomem;
    qemu_irq irq;
    qemu_irq drq[2];
    I2CBus *bus;

    uint8_t revision;
    void *iclk;
    void *fclk;

    uint8_t mask;
    uint16_t stat;
    uint16_t dma;
    uint16_t count;
    int count_cur;
    uint32_t fifo;
    int rxlen;
    int txlen;
    uint16_t control;
    uint16_t addr[2];
    uint8_t divider;
    uint8_t times[2];
    uint16_t test;
};

#define OMAP2_INTR_REV  0x34
#define OMAP2_GC_REV    0x34

static void omap_i2c_interrupts_update(OMAPI2CState *s)
{
    qemu_set_irq(s->irq, s->stat & s->mask);
    if ((s->dma >> 15) & 1)                             /* RDMA_EN */
        qemu_set_irq(s->drq[0], (s->stat >> 3) & 1);    /* RRDY */
    if ((s->dma >> 7) & 1)                              /* XDMA_EN */
        qemu_set_irq(s->drq[1], (s->stat >> 4) & 1);    /* XRDY */
}

static void omap_i2c_fifo_run(OMAPI2CState *s)
{
    int ack = 1;

    if (!i2c_bus_busy(s->bus))
        return;

    if ((s->control >> 2) & 1) {                /* RM */
        if ((s->control >> 1) & 1) {            /* STP */
            i2c_end_transfer(s->bus);
            s->control &= ~(1 << 1);            /* STP */
            s->count_cur = s->count;
            s->txlen = 0;
        } else if ((s->control >> 9) & 1) {     /* TRX */
            while (ack && s->txlen)
                ack = (i2c_send(s->bus,
                                        (s->fifo >> ((-- s->txlen) << 3)) &
                                        0xff) >= 0);
            s->stat |= 1 << 4;                  /* XRDY */
        } else {
            while (s->rxlen < 4)
                s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
            s->stat |= 1 << 3;                  /* RRDY */
        }
    } else {
        if ((s->control >> 9) & 1) {            /* TRX */
            while (ack && s->count_cur && s->txlen) {
                ack = (i2c_send(s->bus,
                                        (s->fifo >> ((-- s->txlen) << 3)) &
                                        0xff) >= 0);
                s->count_cur --;
            }
            if (ack && s->count_cur)
                s->stat |= 1 << 4;              /* XRDY */
            else
                s->stat &= ~(1 << 4);           /* XRDY */
            if (!s->count_cur) {
                s->stat |= 1 << 2;              /* ARDY */
                s->control &= ~(1 << 10);       /* MST */
            }
        } else {
            while (s->count_cur && s->rxlen < 4) {
                s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
                s->count_cur --;
            }
            if (s->rxlen)
                s->stat |= 1 << 3;              /* RRDY */
            else
                s->stat &= ~(1 << 3);           /* RRDY */
        }
        if (!s->count_cur) {
            if ((s->control >> 1) & 1) {        /* STP */
                i2c_end_transfer(s->bus);
                s->control &= ~(1 << 1);        /* STP */
                s->count_cur = s->count;
                s->txlen = 0;
            } else {
                s->stat |= 1 << 2;              /* ARDY */
                s->control &= ~(1 << 10);       /* MST */
            }
        }
    }

    s->stat |= (!ack) << 1;                     /* NACK */
    if (!ack)
        s->control &= ~(1 << 1);                /* STP */
}

static void omap_i2c_reset(DeviceState *dev)
{
    OMAPI2CState *s = OMAP_I2C(dev);

    s->mask = 0;
    s->stat = 0;
    s->dma = 0;
    s->count = 0;
    s->count_cur = 0;
    s->fifo = 0;
    s->rxlen = 0;
    s->txlen = 0;
    s->control = 0;
    s->addr[0] = 0;
    s->addr[1] = 0;
    s->divider = 0;
    s->times[0] = 0;
    s->times[1] = 0;
    s->test = 0;
}

static uint32_t omap_i2c_read(void *opaque, hwaddr addr)
{
    OMAPI2CState *s = opaque;
    int offset = addr & OMAP_MPUI_REG_MASK;
    uint16_t ret;

    switch (offset) {
    case 0x00:  /* I2C_REV */
        return s->revision;                     /* REV */

    case 0x04:  /* I2C_IE */
        return s->mask;

    case 0x08:  /* I2C_STAT */
        return s->stat | (i2c_bus_busy(s->bus) << 12);

    case 0x0c:  /* I2C_IV */
        if (s->revision >= OMAP2_INTR_REV)
            break;
        ret = ctz32(s->stat & s->mask);
        if (ret != 32) {
            s->stat ^= 1 << ret;
            ret++;
        } else {
            ret = 0;
        }
        omap_i2c_interrupts_update(s);
        return ret;

    case 0x10:  /* I2C_SYSS */
        return (s->control >> 15) & 1;  /* I2C_EN */

    case 0x14:  /* I2C_BUF */
        return s->dma;

    case 0x18:  /* I2C_CNT */
        return s->count_cur;    /* DCOUNT */

    case 0x1c:  /* I2C_DATA */
        ret = 0;
        if (s->control & (1 << 14)) {   /* BE */
            ret |= ((s->fifo >> 0) & 0xff) << 8;
            ret |= ((s->fifo >> 8) & 0xff) << 0;
        } else {
            ret |= ((s->fifo >> 8) & 0xff) << 8;
            ret |= ((s->fifo >> 0) & 0xff) << 0;
        }
        if (s->rxlen == 1) {
            s->stat |= 1 << 15;                 /* SBD */
            s->rxlen = 0;
        } else if (s->rxlen > 1) {
            if (s->rxlen > 2)
                s->fifo >>= 16;
            s->rxlen -= 2;
        } else {
            /* XXX: remote access (qualifier) error - what's that?  */
        }
        if (!s->rxlen) {
            s->stat &= ~(1 << 3);                           /* RRDY */
            if (((s->control >> 10) & 1) &&                 /* MST */
                            ((~s->control >> 9) & 1)) {     /* TRX */
                s->stat |= 1 << 2;                          /* ARDY */
                s->control &= ~(1 << 10);                   /* MST */
            }
        }
        s->stat &= ~(1 << 11);                              /* ROVR */
        omap_i2c_fifo_run(s);
        omap_i2c_interrupts_update(s);
        return ret;

    case 0x20:  /* I2C_SYSC */
        return 0;

    case 0x24:  /* I2C_CON */
        return s->control;

    case 0x28:  /* I2C_OA */
        return s->addr[0];

    case 0x2c:  /* I2C_SA */
        return s->addr[1];

    case 0x30:  /* I2C_PSC */
        return s->divider;

    case 0x34:  /* I2C_SCLL */
        return s->times[0];

    case 0x38:  /* I2C_SCLH */
        return s->times[1];

    case 0x3c:  /* I2C_SYSTEST */
        if (s->test & (1 << 15)) {              /* ST_EN */
            s->test ^= 0xa;
            return s->test;
        } else
            return s->test & ~0x300f;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap_i2c_write(void *opaque, hwaddr addr,
                uint32_t value)
{
    OMAPI2CState *s = opaque;
    int offset = addr & OMAP_MPUI_REG_MASK;
    int nack;

    switch (offset) {
    case 0x00:  /* I2C_REV */
    case 0x0c:  /* I2C_IV */
    case 0x10:  /* I2C_SYSS */
        OMAP_RO_REG(addr);
        return;

    case 0x04:  /* I2C_IE */
        s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
        break;

    case 0x08:  /* I2C_STAT */
        if (s->revision < OMAP2_INTR_REV) {
            OMAP_RO_REG(addr);
            return;
        }

        /* RRDY and XRDY are reset by hardware. (in all versions???) */
        s->stat &= ~(value & 0x27);
        omap_i2c_interrupts_update(s);
        break;

    case 0x14:  /* I2C_BUF */
        s->dma = value & 0x8080;
        if (value & (1 << 15))                  /* RDMA_EN */
            s->mask &= ~(1 << 3);               /* RRDY_IE */
        if (value & (1 << 7))                   /* XDMA_EN */
            s->mask &= ~(1 << 4);               /* XRDY_IE */
        break;

    case 0x18:  /* I2C_CNT */
        s->count = value;                   /* DCOUNT */
        break;

    case 0x1c:  /* I2C_DATA */
        if (s->txlen > 2) {
            /* XXX: remote access (qualifier) error - what's that?  */
            break;
        }
        s->fifo <<= 16;
        s->txlen += 2;
        if (s->control & (1 << 14)) {           /* BE */
            s->fifo |= ((value >> 8) & 0xff) << 8;
            s->fifo |= ((value >> 0) & 0xff) << 0;
        } else {
            s->fifo |= ((value >> 0) & 0xff) << 8;
            s->fifo |= ((value >> 8) & 0xff) << 0;
        }
        s->stat &= ~(1 << 10);                  /* XUDF */
        if (s->txlen > 2)
            s->stat &= ~(1 << 4);               /* XRDY */
        omap_i2c_fifo_run(s);
        omap_i2c_interrupts_update(s);
        break;

    case 0x20:  /* I2C_SYSC */
        if (s->revision < OMAP2_INTR_REV) {
            OMAP_BAD_REG(addr);
            return;
        }

        if (value & 2) {
            omap_i2c_reset(DEVICE(s));
        }
        break;

    case 0x24:  /* I2C_CON */
        s->control = value & 0xcf87;
        if (~value & (1 << 15)) {               /* I2C_EN */
            if (s->revision < OMAP2_INTR_REV) {
                omap_i2c_reset(DEVICE(s));
            }
            break;
        }
        if ((value & (1 << 15)) && !(value & (1 << 10))) {    /* MST */
            qemu_log_mask(LOG_UNIMP, "%s: I^2C slave mode not supported\n",
                          __func__);
            break;
        }
        if ((value & (1 << 15)) && value & (1 << 8)) {        /* XA */
            qemu_log_mask(LOG_UNIMP,
                          "%s: 10-bit addressing mode not supported\n",
                          __func__);
            break;
        }
        if ((value & (1 << 15)) && value & (1 << 0)) {      /* STT */
            nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */
                            (~value >> 9) & 1);             /* TRX */
            s->stat |= nack << 1;                           /* NACK */
            s->control &= ~(1 << 0);                        /* STT */
            s->fifo = 0;
            if (nack)
                s->control &= ~(1 << 1);                    /* STP */
            else {
                s->count_cur = s->count;
                omap_i2c_fifo_run(s);
            }
            omap_i2c_interrupts_update(s);
        }
        break;

    case 0x28:  /* I2C_OA */
        s->addr[0] = value & 0x3ff;
        break;

    case 0x2c:  /* I2C_SA */
        s->addr[1] = value & 0x3ff;
        break;

    case 0x30:  /* I2C_PSC */
        s->divider = value;
        break;

    case 0x34:  /* I2C_SCLL */
        s->times[0] = value;
        break;

    case 0x38:  /* I2C_SCLH */
        s->times[1] = value;
        break;

    case 0x3c:  /* I2C_SYSTEST */
        s->test = value & 0xf80f;
        if (value & (1 << 11))                  /* SBB */
            if (s->revision >= OMAP2_INTR_REV) {
                s->stat |= 0x3f;
                omap_i2c_interrupts_update(s);
            }
        if (value & (1 << 15)) {                /* ST_EN */
            qemu_log_mask(LOG_UNIMP,
                          "%s: System Test not supported\n", __func__);
        }
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

static void omap_i2c_writeb(void *opaque, hwaddr addr,
                uint32_t value)
{
    OMAPI2CState *s = opaque;
    int offset = addr & OMAP_MPUI_REG_MASK;

    switch (offset) {
    case 0x1c:  /* I2C_DATA */
        if (s->txlen > 2) {
            /* XXX: remote access (qualifier) error - what's that?  */
            break;
        }
        s->fifo <<= 8;
        s->txlen += 1;
        s->fifo |= value & 0xff;
        s->stat &= ~(1 << 10);                  /* XUDF */
        if (s->txlen > 2)
            s->stat &= ~(1 << 4);               /* XRDY */
        omap_i2c_fifo_run(s);
        omap_i2c_interrupts_update(s);
        break;

    default:
        OMAP_BAD_REG(addr);
        return;
    }
}

static uint64_t omap_i2c_readfn(void *opaque, hwaddr addr,
                                unsigned size)
{
    switch (size) {
    case 2:
        return omap_i2c_read(opaque, addr);
    default:
        return omap_badwidth_read16(opaque, addr);
    }
}

static void omap_i2c_writefn(void *opaque, hwaddr addr,
                             uint64_t value, unsigned size)
{
    switch (size) {
    case 1:
        /* Only the last fifo write can be 8 bit. */
        omap_i2c_writeb(opaque, addr, value);
        break;
    case 2:
        omap_i2c_write(opaque, addr, value);
        break;
    default:
        omap_badwidth_write16(opaque, addr, value);
        break;
    }
}

static const MemoryRegionOps omap_i2c_ops = {
    .read = omap_i2c_readfn,
    .write = omap_i2c_writefn,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void omap_i2c_init(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
    OMAPI2CState *s = OMAP_I2C(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    sysbus_init_irq(sbd, &s->irq);
    sysbus_init_irq(sbd, &s->drq[0]);
    sysbus_init_irq(sbd, &s->drq[1]);
    sysbus_init_mmio(sbd, &s->iomem);
    s->bus = i2c_init_bus(dev, NULL);
}

static void omap_i2c_realize(DeviceState *dev, Error **errp)
{
    OMAPI2CState *s = OMAP_I2C(dev);

    memory_region_init_io(&s->iomem, OBJECT(dev), &omap_i2c_ops, s, "omap.i2c",
                          (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);

    if (!s->fclk) {
        error_setg(errp, "omap_i2c: fclk not connected");
        return;
    }
    if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
        /* Note that OMAP1 doesn't have a separate interface clock */
        error_setg(errp, "omap_i2c: iclk not connected");
        return;
    }
}

void omap_i2c_set_iclk(OMAPI2CState *i2c, omap_clk clk)
{
    i2c->iclk = clk;
}

void omap_i2c_set_fclk(OMAPI2CState *i2c, omap_clk clk)
{
    i2c->fclk = clk;
}

static const Property omap_i2c_properties[] = {
    DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
};

static void omap_i2c_class_init(ObjectClass *klass, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    device_class_set_props(dc, omap_i2c_properties);
    device_class_set_legacy_reset(dc, omap_i2c_reset);
    /* Reason: pointer properties "iclk", "fclk" */
    dc->user_creatable = false;
    dc->realize = omap_i2c_realize;
}

static const TypeInfo omap_i2c_info = {
    .name = TYPE_OMAP_I2C,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(OMAPI2CState),
    .instance_init = omap_i2c_init,
    .class_init = omap_i2c_class_init,
};

static void omap_i2c_register_types(void)
{
    type_register_static(&omap_i2c_info);
}

I2CBus *omap_i2c_bus(DeviceState *omap_i2c)
{
    OMAPI2CState *s = OMAP_I2C(omap_i2c);
    return s->bus;
}

type_init(omap_i2c_register_types)
