/*
 * PC SMBus implementation
 * splitted from acpi.c
 *
 * Copyright (c) 2006 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2 as published by the Free Software Foundation.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see
 * <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/boards.h"
#include "hw/i2c/pm_smbus.h"
#include "hw/i2c/smbus_master.h"
#include "migration/vmstate.h"

#define SMBHSTSTS       0x00
#define SMBHSTCNT       0x02
#define SMBHSTCMD       0x03
#define SMBHSTADD       0x04
#define SMBHSTDAT0      0x05
#define SMBHSTDAT1      0x06
#define SMBBLKDAT       0x07
#define SMBAUXCTL       0x0d

#define STS_HOST_BUSY   (1 << 0)
#define STS_INTR        (1 << 1)
#define STS_DEV_ERR     (1 << 2)
#define STS_BUS_ERR     (1 << 3)
#define STS_FAILED      (1 << 4)
#define STS_SMBALERT    (1 << 5)
#define STS_INUSE_STS   (1 << 6)
#define STS_BYTE_DONE   (1 << 7)
/* Signs of successfully transaction end :
*  ByteDoneStatus = 1 (STS_BYTE_DONE) and INTR = 1 (STS_INTR )
*/

#define CTL_INTREN      (1 << 0)
#define CTL_KILL        (1 << 1)
#define CTL_LAST_BYTE   (1 << 5)
#define CTL_START       (1 << 6)
#define CTL_PEC_EN      (1 << 7)
#define CTL_RETURN_MASK 0x1f

#define PROT_QUICK          0
#define PROT_BYTE           1
#define PROT_BYTE_DATA      2
#define PROT_WORD_DATA      3
#define PROT_PROC_CALL      4
#define PROT_BLOCK_DATA     5
#define PROT_I2C_BLOCK_READ 6

#define AUX_PEC       (1 << 0)
#define AUX_BLK       (1 << 1)
#define AUX_MASK      0x3

/*#define DEBUG*/

#ifdef DEBUG
# define SMBUS_DPRINTF(format, ...)     printf(format, ## __VA_ARGS__)
#else
# define SMBUS_DPRINTF(format, ...)     do { } while (0)
#endif


static void smb_transaction(PMSMBus *s)
{
    uint8_t prot = (s->smb_ctl >> 2) & 0x07;
    uint8_t read = s->smb_addr & 0x01;
    uint8_t cmd = s->smb_cmd;
    uint8_t addr = s->smb_addr >> 1;
    I2CBus *bus = s->smbus;
    int ret;

    SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
    /* Transaction isn't exec if STS_DEV_ERR bit set */
    if ((s->smb_stat & STS_DEV_ERR) != 0)  {
        goto error;
    }

    switch(prot) {
    case PROT_QUICK:
        ret = smbus_quick_command(bus, addr, read);
        goto done;
    case PROT_BYTE:
        if (read) {
            ret = smbus_receive_byte(bus, addr);
            goto data8;
        } else {
            ret = smbus_send_byte(bus, addr, cmd);
            goto done;
        }
    case PROT_BYTE_DATA:
        if (read) {
            ret = smbus_read_byte(bus, addr, cmd);
            goto data8;
        } else {
            ret = smbus_write_byte(bus, addr, cmd, s->smb_data0);
            goto done;
        }
        break;
    case PROT_WORD_DATA:
        if (read) {
            ret = smbus_read_word(bus, addr, cmd);
            goto data16;
        } else {
            ret = smbus_write_word(bus, addr, cmd,
                                   (s->smb_data1 << 8) | s->smb_data0);
            goto done;
        }
        break;
    case PROT_I2C_BLOCK_READ:
        /* According to the Linux i2c-i801 driver:
         *   NB: page 240 of ICH5 datasheet shows that the R/#W
         *   bit should be cleared here, even when reading.
         *   However if SPD Write Disable is set (Lynx Point and later),
         *   the read will fail if we don't set the R/#W bit.
         * So at least Linux may or may not set the read bit here.
         * So just ignore the read bit for this command.
         */
        if (i2c_start_transfer(bus, addr, 0)) {
            goto error;
        }
        ret = i2c_send(bus, s->smb_data1);
        if (ret) {
            goto error;
        }
        if (i2c_start_transfer(bus, addr, 1)) {
            goto error;
        }
        s->in_i2c_block_read = true;
        s->smb_blkdata = i2c_recv(s->smbus);
        s->op_done = false;
        s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
        goto out;

    case PROT_BLOCK_DATA:
        if (read) {
            ret = smbus_read_block(bus, addr, cmd, s->smb_data,
                                   sizeof(s->smb_data), !s->i2c_enable,
                                   !s->i2c_enable);
            if (ret < 0) {
                goto error;
            }
            s->smb_index = 0;
            s->op_done = false;
            if (s->smb_auxctl & AUX_BLK) {
                s->smb_stat |= STS_INTR;
            } else {
                s->smb_blkdata = s->smb_data[0];
                s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
            }
            s->smb_data0 = ret;
            goto out;
        } else {
            if (s->smb_auxctl & AUX_BLK) {
                if (s->smb_index != s->smb_data0) {
                    s->smb_index = 0;
                    goto error;
                }
                /* Data is already all written to the queue, just do
                   the operation. */
                s->smb_index = 0;
                ret = smbus_write_block(bus, addr, cmd, s->smb_data,
                                        s->smb_data0, !s->i2c_enable);
                if (ret < 0) {
                    goto error;
                }
                s->op_done = true;
                s->smb_stat |= STS_INTR;
                s->smb_stat &= ~STS_HOST_BUSY;
            } else {
                s->op_done = false;
                s->smb_stat |= STS_HOST_BUSY | STS_BYTE_DONE;
                s->smb_data[0] = s->smb_blkdata;
                s->smb_index = 0;
                ret = 0;
            }
            goto out;
        }
        break;
    default:
        goto error;
    }
    abort();

data16:
    if (ret < 0) {
        goto error;
    }
    s->smb_data1 = ret >> 8;
data8:
    if (ret < 0) {
        goto error;
    }
    s->smb_data0 = ret;
done:
    if (ret < 0) {
        goto error;
    }
    s->smb_stat |= STS_INTR;
out:
    return;

error:
    s->smb_stat |= STS_DEV_ERR;
    return;
}

static void smb_transaction_start(PMSMBus *s)
{
    if (s->smb_ctl & CTL_INTREN) {
        smb_transaction(s);
        s->start_transaction_on_status_read = false;
    } else {
        /* Do not execute immediately the command; it will be
         * executed when guest will read SMB_STAT register.  This
         * is to work around a bug in AMIBIOS (that is working
         * around another bug in some specific hardware) where
         * it waits for STS_HOST_BUSY to be set before waiting
         * checking for status.  If STS_HOST_BUSY doesn't get
         * set, it gets stuck. */
        s->smb_stat |= STS_HOST_BUSY;
        s->start_transaction_on_status_read = true;
    }
}

static bool
smb_irq_value(PMSMBus *s)
{
    return ((s->smb_stat & ~STS_HOST_BUSY) != 0) && (s->smb_ctl & CTL_INTREN);
}

static bool
smb_byte_by_byte(PMSMBus *s)
{
    if (s->op_done) {
        return false;
    }
    if (s->in_i2c_block_read) {
        return true;
    }
    return !(s->smb_auxctl & AUX_BLK);
}

static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
                              unsigned width)
{
    PMSMBus *s = opaque;
    uint8_t clear_byte_done;

    SMBUS_DPRINTF("SMB writeb port=0x%04" HWADDR_PRIx
                  " val=0x%02" PRIx64 "\n", addr, val);
    switch(addr) {
    case SMBHSTSTS:
        clear_byte_done = s->smb_stat & val & STS_BYTE_DONE;
        s->smb_stat &= ~(val & ~STS_HOST_BUSY);
        if (clear_byte_done && smb_byte_by_byte(s)) {
            uint8_t read = s->smb_addr & 0x01;

            if (s->in_i2c_block_read) {
                /* See comment below PROT_I2C_BLOCK_READ above. */
                read = 1;
            }

            s->smb_index++;
            if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
                s->smb_index = 0;
            }
            if (!read && s->smb_index == s->smb_data0) {
                uint8_t prot = (s->smb_ctl >> 2) & 0x07;
                uint8_t cmd = s->smb_cmd;
                uint8_t addr = s->smb_addr >> 1;
                int ret;

                if (prot == PROT_I2C_BLOCK_READ) {
                    s->smb_stat |= STS_DEV_ERR;
                    goto out;
                }

                ret = smbus_write_block(s->smbus, addr, cmd, s->smb_data,
                                        s->smb_data0, !s->i2c_enable);
                if (ret < 0) {
                    s->smb_stat |= STS_DEV_ERR;
                    goto out;
                }
                s->op_done = true;
                s->smb_stat |= STS_INTR;
                s->smb_stat &= ~STS_HOST_BUSY;
            } else if (!read) {
                s->smb_data[s->smb_index] = s->smb_blkdata;
                s->smb_stat |= STS_BYTE_DONE;
            } else if (s->smb_ctl & CTL_LAST_BYTE) {
                s->op_done = true;
                if (s->in_i2c_block_read) {
                    s->in_i2c_block_read = false;
                    s->smb_blkdata = i2c_recv(s->smbus);
                    i2c_nack(s->smbus);
                    i2c_end_transfer(s->smbus);
                } else {
                    s->smb_blkdata = s->smb_data[s->smb_index];
                }
                s->smb_index = 0;
                s->smb_stat |= STS_INTR;
                s->smb_stat &= ~STS_HOST_BUSY;
            } else {
                if (s->in_i2c_block_read) {
                    s->smb_blkdata = i2c_recv(s->smbus);
                } else {
                    s->smb_blkdata = s->smb_data[s->smb_index];
                }
                s->smb_stat |= STS_BYTE_DONE;
            }
        }
        break;
    case SMBHSTCNT:
        s->smb_ctl = val & ~CTL_START; /* CTL_START always reads 0 */
        if (val & CTL_START) {
            if (!s->op_done) {
                s->smb_index = 0;
                s->op_done = true;
                if (s->in_i2c_block_read) {
                    s->in_i2c_block_read = false;
                    i2c_end_transfer(s->smbus);
                }
            }
            smb_transaction_start(s);
        }
        if (s->smb_ctl & CTL_KILL) {
            s->op_done = true;
            s->smb_index = 0;
            s->smb_stat |= STS_FAILED;
            s->smb_stat &= ~STS_HOST_BUSY;
        }
        break;
    case SMBHSTCMD:
        s->smb_cmd = val;
        break;
    case SMBHSTADD:
        s->smb_addr = val;
        break;
    case SMBHSTDAT0:
        s->smb_data0 = val;
        break;
    case SMBHSTDAT1:
        s->smb_data1 = val;
        break;
    case SMBBLKDAT:
        if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
            s->smb_index = 0;
        }
        if (s->smb_auxctl & AUX_BLK) {
            s->smb_data[s->smb_index++] = val;
        } else {
            s->smb_blkdata = val;
        }
        break;
    case SMBAUXCTL:
        s->smb_auxctl = val & AUX_MASK;
        break;
    default:
        break;
    }

 out:
    if (s->set_irq) {
        s->set_irq(s, smb_irq_value(s));
    }
}

static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
{
    PMSMBus *s = opaque;
    uint32_t val;

    switch(addr) {
    case SMBHSTSTS:
        val = s->smb_stat;
        if (s->start_transaction_on_status_read) {
            /* execute command now */
            s->start_transaction_on_status_read = false;
            s->smb_stat &= ~STS_HOST_BUSY;
            smb_transaction(s);
        }
        break;
    case SMBHSTCNT:
        val = s->smb_ctl & CTL_RETURN_MASK;
        break;
    case SMBHSTCMD:
        val = s->smb_cmd;
        break;
    case SMBHSTADD:
        val = s->smb_addr;
        break;
    case SMBHSTDAT0:
        val = s->smb_data0;
        break;
    case SMBHSTDAT1:
        val = s->smb_data1;
        break;
    case SMBBLKDAT:
        if (s->smb_auxctl & AUX_BLK && !s->in_i2c_block_read) {
            if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
                s->smb_index = 0;
            }
            val = s->smb_data[s->smb_index++];
            if (!s->op_done && s->smb_index == s->smb_data0) {
                s->op_done = true;
                s->smb_index = 0;
                s->smb_stat &= ~STS_HOST_BUSY;
            }
        } else {
            val = s->smb_blkdata;
        }
        break;
    case SMBAUXCTL:
        val = s->smb_auxctl;
        break;
    default:
        val = 0;
        break;
    }
    SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n",
                  addr, val);

    if (s->set_irq) {
        s->set_irq(s, smb_irq_value(s));
    }

    return val;
}

static void pm_smbus_reset(PMSMBus *s)
{
    s->op_done = true;
    s->smb_index = 0;
    s->smb_stat = 0;
}

static const MemoryRegionOps pm_smbus_ops = {
    .read = smb_ioport_readb,
    .write = smb_ioport_writeb,
    .valid.min_access_size = 1,
    .valid.max_access_size = 1,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

bool pm_smbus_vmstate_needed(void)
{
    MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());

    return !mc->smbus_no_migration_support;
}

const VMStateDescription pmsmb_vmstate = {
    .name = "pmsmb",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(smb_stat, PMSMBus),
        VMSTATE_UINT8(smb_ctl, PMSMBus),
        VMSTATE_UINT8(smb_cmd, PMSMBus),
        VMSTATE_UINT8(smb_addr, PMSMBus),
        VMSTATE_UINT8(smb_data0, PMSMBus),
        VMSTATE_UINT8(smb_data1, PMSMBus),
        VMSTATE_UINT32(smb_index, PMSMBus),
        VMSTATE_UINT8_ARRAY(smb_data, PMSMBus, PM_SMBUS_MAX_MSG_SIZE),
        VMSTATE_UINT8(smb_auxctl, PMSMBus),
        VMSTATE_UINT8(smb_blkdata, PMSMBus),
        VMSTATE_BOOL(i2c_enable, PMSMBus),
        VMSTATE_BOOL(op_done, PMSMBus),
        VMSTATE_BOOL(in_i2c_block_read, PMSMBus),
        VMSTATE_BOOL(start_transaction_on_status_read, PMSMBus),
        VMSTATE_END_OF_LIST()
    }
};

void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk)
{
    smb->op_done = true;
    smb->reset = pm_smbus_reset;
    smb->smbus = i2c_init_bus(parent, "i2c");
    if (force_aux_blk) {
        smb->smb_auxctl |= AUX_BLK;
    }
    memory_region_init_io(&smb->io, OBJECT(parent), &pm_smbus_ops, smb,
                          "pm-smbus", 64);
}
