/*
 * QTest i.MX I2C driver
 *
 * Copyright (c) 2013 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/>.
 */

#include "libqos/i2c.h"

#include <glib.h>
#include <string.h>

#include "qemu/osdep.h"
#include "libqtest.h"

#include "hw/i2c/imx_i2c.h"

enum IMXI2CDirection {
    IMX_I2C_READ,
    IMX_I2C_WRITE,
};

typedef struct IMXI2C {
    I2CAdapter parent;

    uint64_t addr;
} IMXI2C;


static void imx_i2c_set_slave_addr(IMXI2C *s, uint8_t addr,
                                   enum IMXI2CDirection direction)
{
    writeb(s->addr + I2DR_ADDR, (addr << 1) |
           (direction == IMX_I2C_READ ? 1 : 0));
}

static void imx_i2c_send(I2CAdapter *i2c, uint8_t addr,
                         const uint8_t *buf, uint16_t len)
{
    IMXI2C *s = (IMXI2C *)i2c;
    uint8_t data;
    uint8_t status;
    uint16_t size = 0;

    if (!len) {
        return;
    }

    /* set the bus for write */
    data = I2CR_IEN |
           I2CR_IIEN |
           I2CR_MSTA |
           I2CR_MTX |
           I2CR_TXAK;

    writeb(s->addr + I2CR_ADDR, data);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IBB) != 0);

    /* set the slave address */
    imx_i2c_set_slave_addr(s, addr, IMX_I2C_WRITE);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IIF) != 0);
    g_assert((status & I2SR_RXAK) == 0);

    /* ack the interrupt */
    writeb(s->addr + I2SR_ADDR, 0);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IIF) == 0);

    while (size < len) {
        /* check we are still busy */
        status = readb(s->addr + I2SR_ADDR);
        g_assert((status & I2SR_IBB) != 0);

        /* write the data */
        writeb(s->addr + I2DR_ADDR, buf[size]);
        status = readb(s->addr + I2SR_ADDR);
        g_assert((status & I2SR_IIF) != 0);
        g_assert((status & I2SR_RXAK) == 0);

        /* ack the interrupt */
        writeb(s->addr + I2SR_ADDR, 0);
        status = readb(s->addr + I2SR_ADDR);
        g_assert((status & I2SR_IIF) == 0);

        size++;
    }

    /* release the bus */
    data &= ~(I2CR_MSTA | I2CR_MTX);
    writeb(s->addr + I2CR_ADDR, data);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IBB) == 0);
}

static void imx_i2c_recv(I2CAdapter *i2c, uint8_t addr,
                         uint8_t *buf, uint16_t len)
{
    IMXI2C *s = (IMXI2C *)i2c;
    uint8_t data;
    uint8_t status;
    uint16_t size = 0;

    if (!len) {
        return;
    }

    /* set the bus for write */
    data = I2CR_IEN |
           I2CR_IIEN |
           I2CR_MSTA |
           I2CR_MTX |
           I2CR_TXAK;

    writeb(s->addr + I2CR_ADDR, data);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IBB) != 0);

    /* set the slave address */
    imx_i2c_set_slave_addr(s, addr, IMX_I2C_READ);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IIF) != 0);
    g_assert((status & I2SR_RXAK) == 0);

    /* ack the interrupt */
    writeb(s->addr + I2SR_ADDR, 0);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IIF) == 0);

    /* set the bus for read */
    data &= ~I2CR_MTX;
    /* if only one byte don't ack */
    if (len != 1) {
        data &= ~I2CR_TXAK;
    }
    writeb(s->addr + I2CR_ADDR, data);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IBB) != 0);

    /* dummy read */
    readb(s->addr + I2DR_ADDR);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IIF) != 0);

    /* ack the interrupt */
    writeb(s->addr + I2SR_ADDR, 0);
    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IIF) == 0);

    while (size < len) {
        /* check we are still busy */
        status = readb(s->addr + I2SR_ADDR);
        g_assert((status & I2SR_IBB) != 0);

        if (size == (len - 1)) {
            /* stop the read transaction */
            data &= ~(I2CR_MSTA | I2CR_MTX);
        } else {
            /* ack the data read */
            data |= I2CR_TXAK;
        }
        writeb(s->addr + I2CR_ADDR, data);

        /* read the data */
        buf[size] = readb(s->addr + I2DR_ADDR);

        if (size != (len - 1)) {
            status = readb(s->addr + I2SR_ADDR);
            g_assert((status & I2SR_IIF) != 0);

            /* ack the interrupt */
            writeb(s->addr + I2SR_ADDR, 0);
        }

        status = readb(s->addr + I2SR_ADDR);
        g_assert((status & I2SR_IIF) == 0);

        size++;
    }

    status = readb(s->addr + I2SR_ADDR);
    g_assert((status & I2SR_IBB) == 0);
}

I2CAdapter *imx_i2c_create(uint64_t addr)
{
    IMXI2C *s = g_malloc0(sizeof(*s));
    I2CAdapter *i2c = (I2CAdapter *)s;

    s->addr = addr;

    i2c->send = imx_i2c_send;
    i2c->recv = imx_i2c_recv;

    return i2c;
}
