/*
 *  Allwinner I2C Bus Serial Interface Emulation
 *
 *  Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
 *
 *  This file is derived from IMX I2C controller,
 *  by Jean-Christophe DUBOIS .
 *
 *  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/>.
 *
 * SPDX-License-Identifier: MIT
 */

#include "qemu/osdep.h"
#include "hw/i2c/allwinner-i2c.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "hw/i2c/i2c.h"
#include "qemu/log.h"
#include "trace.h"
#include "qemu/module.h"

/* Allwinner I2C memory map */
#define TWI_ADDR_REG            0x00  /* slave address register */
#define TWI_XADDR_REG           0x04  /* extended slave address register */
#define TWI_DATA_REG            0x08  /* data register */
#define TWI_CNTR_REG            0x0c  /* control register */
#define TWI_STAT_REG            0x10  /* status register */
#define TWI_CCR_REG             0x14  /* clock control register */
#define TWI_SRST_REG            0x18  /* software reset register */
#define TWI_EFR_REG             0x1c  /* enhance feature register */
#define TWI_LCR_REG             0x20  /* line control register */

/* Used only in slave mode, do not set */
#define TWI_ADDR_RESET          0
#define TWI_XADDR_RESET         0

/* Data register */
#define TWI_DATA_MASK           0xFF
#define TWI_DATA_RESET          0

/* Control register */
#define TWI_CNTR_INT_EN         (1 << 7)
#define TWI_CNTR_BUS_EN         (1 << 6)
#define TWI_CNTR_M_STA          (1 << 5)
#define TWI_CNTR_M_STP          (1 << 4)
#define TWI_CNTR_INT_FLAG       (1 << 3)
#define TWI_CNTR_A_ACK          (1 << 2)
#define TWI_CNTR_MASK           0xFC
#define TWI_CNTR_RESET          0

/* Status register */
#define TWI_STAT_MASK           0xF8
#define TWI_STAT_RESET          0xF8

/* Clock register */
#define TWI_CCR_CLK_M_MASK      0x78
#define TWI_CCR_CLK_N_MASK      0x07
#define TWI_CCR_MASK            0x7F
#define TWI_CCR_RESET           0

/* Soft reset */
#define TWI_SRST_MASK           0x01
#define TWI_SRST_RESET          0

/* Enhance feature */
#define TWI_EFR_MASK            0x03
#define TWI_EFR_RESET           0

/* Line control */
#define TWI_LCR_SCL_STATE       (1 << 5)
#define TWI_LCR_SDA_STATE       (1 << 4)
#define TWI_LCR_SCL_CTL         (1 << 3)
#define TWI_LCR_SCL_CTL_EN      (1 << 2)
#define TWI_LCR_SDA_CTL         (1 << 1)
#define TWI_LCR_SDA_CTL_EN      (1 << 0)
#define TWI_LCR_MASK            0x3F
#define TWI_LCR_RESET           0x3A

/* Status value in STAT register is shifted by 3 bits */
#define TWI_STAT_SHIFT      3
#define STAT_FROM_STA(x)    ((x) << TWI_STAT_SHIFT)
#define STAT_TO_STA(x)      ((x) >> TWI_STAT_SHIFT)

enum {
    STAT_BUS_ERROR = 0,
    /* Master mode */
    STAT_M_STA_TX,
    STAT_M_RSTA_TX,
    STAT_M_ADDR_WR_ACK,
    STAT_M_ADDR_WR_NACK,
    STAT_M_DATA_TX_ACK,
    STAT_M_DATA_TX_NACK,
    STAT_M_ARB_LOST,
    STAT_M_ADDR_RD_ACK,
    STAT_M_ADDR_RD_NACK,
    STAT_M_DATA_RX_ACK,
    STAT_M_DATA_RX_NACK,
    /* Slave mode */
    STAT_S_ADDR_WR_ACK,
    STAT_S_ARB_LOST_AW_ACK,
    STAT_S_GCA_ACK,
    STAT_S_ARB_LOST_GCA_ACK,
    STAT_S_DATA_RX_SA_ACK,
    STAT_S_DATA_RX_SA_NACK,
    STAT_S_DATA_RX_GCA_ACK,
    STAT_S_DATA_RX_GCA_NACK,
    STAT_S_STP_RSTA,
    STAT_S_ADDR_RD_ACK,
    STAT_S_ARB_LOST_AR_ACK,
    STAT_S_DATA_TX_ACK,
    STAT_S_DATA_TX_NACK,
    STAT_S_LB_TX_ACK,
    /* Master mode, 10-bit */
    STAT_M_2ND_ADDR_WR_ACK,
    STAT_M_2ND_ADDR_WR_NACK,
    /* Idle */
    STAT_IDLE = 0x1f
} TWI_STAT_STA;

static const char *allwinner_i2c_get_regname(unsigned offset)
{
    switch (offset) {
    case TWI_ADDR_REG:
        return "ADDR";
    case TWI_XADDR_REG:
        return "XADDR";
    case TWI_DATA_REG:
        return "DATA";
    case TWI_CNTR_REG:
        return "CNTR";
    case TWI_STAT_REG:
        return "STAT";
    case TWI_CCR_REG:
        return "CCR";
    case TWI_SRST_REG:
        return "SRST";
    case TWI_EFR_REG:
        return "EFR";
    case TWI_LCR_REG:
        return "LCR";
    default:
        return "[?]";
    }
}

static inline bool allwinner_i2c_is_reset(AWI2CState *s)
{
    return s->srst & TWI_SRST_MASK;
}

static inline bool allwinner_i2c_bus_is_enabled(AWI2CState *s)
{
    return s->cntr & TWI_CNTR_BUS_EN;
}

static inline bool allwinner_i2c_interrupt_is_enabled(AWI2CState *s)
{
    return s->cntr & TWI_CNTR_INT_EN;
}

static void allwinner_i2c_reset_hold(Object *obj)
{
    AWI2CState *s = AW_I2C(obj);

    if (STAT_TO_STA(s->stat) != STAT_IDLE) {
        i2c_end_transfer(s->bus);
    }

    s->addr  = TWI_ADDR_RESET;
    s->xaddr = TWI_XADDR_RESET;
    s->data  = TWI_DATA_RESET;
    s->cntr  = TWI_CNTR_RESET;
    s->stat  = TWI_STAT_RESET;
    s->ccr   = TWI_CCR_RESET;
    s->srst  = TWI_SRST_RESET;
    s->efr   = TWI_EFR_RESET;
    s->lcr   = TWI_LCR_RESET;
}

static inline void allwinner_i2c_raise_interrupt(AWI2CState *s)
{
    /*
     * Raise an interrupt if the device is not reset and it is configured
     * to generate some interrupts.
     */
    if (!allwinner_i2c_is_reset(s) && allwinner_i2c_bus_is_enabled(s)) {
        if (STAT_TO_STA(s->stat) != STAT_IDLE) {
            s->cntr |= TWI_CNTR_INT_FLAG;
            if (allwinner_i2c_interrupt_is_enabled(s)) {
                qemu_irq_raise(s->irq);
            }
        }
    }
}

static uint64_t allwinner_i2c_read(void *opaque, hwaddr offset,
                                   unsigned size)
{
    uint16_t value;
    AWI2CState *s = AW_I2C(opaque);

    switch (offset) {
    case TWI_ADDR_REG:
        value = s->addr;
        break;
    case TWI_XADDR_REG:
        value = s->xaddr;
        break;
    case TWI_DATA_REG:
        if ((STAT_TO_STA(s->stat) == STAT_M_ADDR_RD_ACK) ||
            (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_ACK) ||
            (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_NACK)) {
            /* Get the next byte */
            s->data = i2c_recv(s->bus);

            if (s->cntr & TWI_CNTR_A_ACK) {
                s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
            } else {
                s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
            }
            allwinner_i2c_raise_interrupt(s);
        }
        value = s->data;
        break;
    case TWI_CNTR_REG:
        value = s->cntr;
        break;
    case TWI_STAT_REG:
        value = s->stat;
        /*
         * If polling when reading then change state to indicate data
         * is available
         */
        if (STAT_TO_STA(s->stat) == STAT_M_ADDR_RD_ACK) {
            if (s->cntr & TWI_CNTR_A_ACK) {
                s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
            } else {
                s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
            }
            allwinner_i2c_raise_interrupt(s);
        }
        break;
    case TWI_CCR_REG:
        value = s->ccr;
        break;
    case TWI_SRST_REG:
        value = s->srst;
        break;
    case TWI_EFR_REG:
        value = s->efr;
        break;
    case TWI_LCR_REG:
        value = s->lcr;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset);
        value = 0;
        break;
    }

    trace_allwinner_i2c_read(allwinner_i2c_get_regname(offset), offset, value);

    return (uint64_t)value;
}

static void allwinner_i2c_write(void *opaque, hwaddr offset,
                                uint64_t value, unsigned size)
{
    AWI2CState *s = AW_I2C(opaque);

    value &= 0xff;

    trace_allwinner_i2c_write(allwinner_i2c_get_regname(offset), offset, value);

    switch (offset) {
    case TWI_ADDR_REG:
        s->addr = (uint8_t)value;
        break;
    case TWI_XADDR_REG:
        s->xaddr = (uint8_t)value;
        break;
    case TWI_DATA_REG:
        /* If the device is in reset or not enabled, nothing to do */
        if (allwinner_i2c_is_reset(s) || (!allwinner_i2c_bus_is_enabled(s))) {
            break;
        }

        s->data = value & TWI_DATA_MASK;

        switch (STAT_TO_STA(s->stat)) {
        case STAT_M_STA_TX:
        case STAT_M_RSTA_TX:
            /* Send address */
            if (i2c_start_transfer(s->bus, extract32(s->data, 1, 7),
                                extract32(s->data, 0, 1))) {
                /* If non zero is returned, the address is not valid */
                s->stat = STAT_FROM_STA(STAT_M_ADDR_WR_NACK);
            } else {
                /* Determine if read of write */
                if (extract32(s->data, 0, 1)) {
                    s->stat = STAT_FROM_STA(STAT_M_ADDR_RD_ACK);
                } else {
                    s->stat = STAT_FROM_STA(STAT_M_ADDR_WR_ACK);
                }
                allwinner_i2c_raise_interrupt(s);
            }
            break;
        case STAT_M_ADDR_WR_ACK:
        case STAT_M_DATA_TX_ACK:
            if (i2c_send(s->bus, s->data)) {
                /* If the target return non zero then end the transfer */
                s->stat = STAT_FROM_STA(STAT_M_DATA_TX_NACK);
                i2c_end_transfer(s->bus);
            } else {
                s->stat = STAT_FROM_STA(STAT_M_DATA_TX_ACK);
                allwinner_i2c_raise_interrupt(s);
            }
            break;
        default:
            break;
        }
        break;
    case TWI_CNTR_REG:
        if (!allwinner_i2c_is_reset(s)) {
            /* Do something only if not in software reset */
            s->cntr = value & TWI_CNTR_MASK;

            /* Check if start condition should be sent */
            if (s->cntr & TWI_CNTR_M_STA) {
                /* Update status */
                if (STAT_TO_STA(s->stat) == STAT_IDLE) {
                    /* Send start condition */
                    s->stat = STAT_FROM_STA(STAT_M_STA_TX);
                } else {
                    /* Send repeated start condition */
                    s->stat = STAT_FROM_STA(STAT_M_RSTA_TX);
                }
                /* Clear start condition */
                s->cntr &= ~TWI_CNTR_M_STA;
            }
            if (s->cntr & TWI_CNTR_M_STP) {
                /* Update status */
                i2c_end_transfer(s->bus);
                s->stat = STAT_FROM_STA(STAT_IDLE);
                s->cntr &= ~TWI_CNTR_M_STP;
            }

            if (!s->irq_clear_inverted && !(s->cntr & TWI_CNTR_INT_FLAG)) {
                /* Write 0 to clear this flag */
                qemu_irq_lower(s->irq);
            } else if (s->irq_clear_inverted && (s->cntr & TWI_CNTR_INT_FLAG)) {
                /* Write 1 to clear this flag */
                s->cntr &= ~TWI_CNTR_INT_FLAG;
                qemu_irq_lower(s->irq);
            }

            if ((s->cntr & TWI_CNTR_A_ACK) == 0) {
                if (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_ACK) {
                    s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
                }
            } else {
                if (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_NACK) {
                    s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
                }
            }
            allwinner_i2c_raise_interrupt(s);

        }
        break;
    case TWI_CCR_REG:
        s->ccr = value & TWI_CCR_MASK;
        break;
    case TWI_SRST_REG:
        if (((value & TWI_SRST_MASK) == 0) && (s->srst & TWI_SRST_MASK)) {
            /* Perform reset */
            allwinner_i2c_reset_hold(OBJECT(s));
        }
        s->srst = value & TWI_SRST_MASK;
        break;
    case TWI_EFR_REG:
        s->efr = value & TWI_EFR_MASK;
        break;
    case TWI_LCR_REG:
        s->lcr = value & TWI_LCR_MASK;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset);
        break;
    }
}

static const MemoryRegionOps allwinner_i2c_ops = {
    .read = allwinner_i2c_read,
    .write = allwinner_i2c_write,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static const VMStateDescription allwinner_i2c_vmstate = {
    .name = TYPE_AW_I2C,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(addr, AWI2CState),
        VMSTATE_UINT8(xaddr, AWI2CState),
        VMSTATE_UINT8(data, AWI2CState),
        VMSTATE_UINT8(cntr, AWI2CState),
        VMSTATE_UINT8(ccr, AWI2CState),
        VMSTATE_UINT8(srst, AWI2CState),
        VMSTATE_UINT8(efr, AWI2CState),
        VMSTATE_UINT8(lcr, AWI2CState),
        VMSTATE_END_OF_LIST()
    }
};

static void allwinner_i2c_realize(DeviceState *dev, Error **errp)
{
    AWI2CState *s = AW_I2C(dev);

    memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_i2c_ops, s,
                          TYPE_AW_I2C, AW_I2C_MEM_SIZE);
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
    s->bus = i2c_init_bus(dev, "i2c");
}

static void allwinner_i2c_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);

    rc->phases.hold = allwinner_i2c_reset_hold;
    dc->vmsd = &allwinner_i2c_vmstate;
    dc->realize = allwinner_i2c_realize;
    dc->desc = "Allwinner I2C Controller";
}

static const TypeInfo allwinner_i2c_type_info = {
    .name = TYPE_AW_I2C,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(AWI2CState),
    .class_init = allwinner_i2c_class_init,
};

static void allwinner_i2c_sun6i_init(Object *obj)
{
    AWI2CState *s = AW_I2C(obj);

    s->irq_clear_inverted = true;
}

static const TypeInfo allwinner_i2c_sun6i_type_info = {
    .name = TYPE_AW_I2C_SUN6I,
    .parent = TYPE_AW_I2C,
    .instance_init = allwinner_i2c_sun6i_init,
};

static void allwinner_i2c_register_types(void)
{
    type_register_static(&allwinner_i2c_type_info);
    type_register_static(&allwinner_i2c_sun6i_type_info);
}

type_init(allwinner_i2c_register_types)
