/* A simple I2C slave for returning monitor EDID data via DDC.
 *
 * Copyright (c) 2011 Linaro Limited
 * Written by Peter Maydell
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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-common.h"
#include "qemu/log.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/i2c-ddc.h"

#ifndef DEBUG_I2CDDC
#define DEBUG_I2CDDC 0
#endif

#define DPRINTF(fmt, ...) do {                                                 \
    if (DEBUG_I2CDDC) {                                                        \
        qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__);                            \
    }                                                                          \
} while (0)

static void i2c_ddc_reset(DeviceState *ds)
{
    I2CDDCState *s = I2CDDC(ds);

    s->firstbyte = false;
    s->reg = 0;
}

static int i2c_ddc_event(I2CSlave *i2c, enum i2c_event event)
{
    I2CDDCState *s = I2CDDC(i2c);

    if (event == I2C_START_SEND) {
        s->firstbyte = true;
    }

    return 0;
}

static int i2c_ddc_rx(I2CSlave *i2c)
{
    I2CDDCState *s = I2CDDC(i2c);

    int value;
    value = s->edid_blob[s->reg];
    s->reg++;
    return value;
}

static int i2c_ddc_tx(I2CSlave *i2c, uint8_t data)
{
    I2CDDCState *s = I2CDDC(i2c);
    if (s->firstbyte) {
        s->reg = data;
        s->firstbyte = false;
        DPRINTF("[EDID] Written new pointer: %u\n", data);
        return 0;
    }

    /* Ignore all writes */
    s->reg++;
    return 0;
}

static void i2c_ddc_init(Object *obj)
{
    I2CDDCState *s = I2CDDC(obj);

    qemu_edid_generate(s->edid_blob, sizeof(s->edid_blob), &s->edid_info);
}

static const VMStateDescription vmstate_i2c_ddc = {
    .name = TYPE_I2CDDC,
    .version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(firstbyte, I2CDDCState),
        VMSTATE_UINT8(reg, I2CDDCState),
        VMSTATE_END_OF_LIST()
    }
};

static Property i2c_ddc_properties[] = {
    DEFINE_EDID_PROPERTIES(I2CDDCState, edid_info),
    DEFINE_PROP_END_OF_LIST(),
};

static void i2c_ddc_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);

    dc->reset = i2c_ddc_reset;
    dc->vmsd = &vmstate_i2c_ddc;
    dc->props = i2c_ddc_properties;
    isc->event = i2c_ddc_event;
    isc->recv = i2c_ddc_rx;
    isc->send = i2c_ddc_tx;
}

static TypeInfo i2c_ddc_info = {
    .name = TYPE_I2CDDC,
    .parent = TYPE_I2C_SLAVE,
    .instance_size = sizeof(I2CDDCState),
    .instance_init = i2c_ddc_init,
    .class_init = i2c_ddc_class_init
};

static void ddc_register_devices(void)
{
    type_register_static(&i2c_ddc_info);
}

type_init(ddc_register_devices);
