/*
 * Example I2C device using asynchronous I2C send.
 *
 * Copyright (C) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/timer.h"
#include "qemu/main-loop.h"
#include "block/aio.h"
#include "hw/i2c/i2c.h"

#define TYPE_I2C_ECHO "i2c-echo"
OBJECT_DECLARE_SIMPLE_TYPE(I2CEchoState, I2C_ECHO)

enum i2c_echo_state {
    I2C_ECHO_STATE_IDLE,
    I2C_ECHO_STATE_START_SEND,
    I2C_ECHO_STATE_ACK,
};

typedef struct I2CEchoState {
    I2CSlave parent_obj;

    I2CBus *bus;

    enum i2c_echo_state state;
    QEMUBH *bh;

    unsigned int pos;
    uint8_t data[3];
} I2CEchoState;

static void i2c_echo_bh(void *opaque)
{
    I2CEchoState *state = opaque;

    switch (state->state) {
    case I2C_ECHO_STATE_IDLE:
        return;

    case I2C_ECHO_STATE_START_SEND:
        if (i2c_start_send_async(state->bus, state->data[0])) {
            goto release_bus;
        }

        state->pos++;
        state->state = I2C_ECHO_STATE_ACK;
        return;

    case I2C_ECHO_STATE_ACK:
        if (state->pos > 2) {
            break;
        }

        if (i2c_send_async(state->bus, state->data[state->pos++])) {
            break;
        }

        return;
    }


    i2c_end_transfer(state->bus);
release_bus:
    i2c_bus_release(state->bus);

    state->state = I2C_ECHO_STATE_IDLE;
}

static int i2c_echo_event(I2CSlave *s, enum i2c_event event)
{
    I2CEchoState *state = I2C_ECHO(s);

    switch (event) {
    case I2C_START_RECV:
        state->pos = 0;

        break;

    case I2C_START_SEND:
        state->pos = 0;

        break;

    case I2C_FINISH:
        state->pos = 0;
        state->state = I2C_ECHO_STATE_START_SEND;
        i2c_bus_master(state->bus, state->bh);

        break;

    case I2C_NACK:
        break;

    default:
        return -1;
    }

    return 0;
}

static uint8_t i2c_echo_recv(I2CSlave *s)
{
    I2CEchoState *state = I2C_ECHO(s);

    if (state->pos > 2) {
        return 0xff;
    }

    return state->data[state->pos++];
}

static int i2c_echo_send(I2CSlave *s, uint8_t data)
{
    I2CEchoState *state = I2C_ECHO(s);

    if (state->pos > 2) {
        return -1;
    }

    state->data[state->pos++] = data;

    return 0;
}

static void i2c_echo_realize(DeviceState *dev, Error **errp)
{
    I2CEchoState *state = I2C_ECHO(dev);
    BusState *bus = qdev_get_parent_bus(dev);

    state->bus = I2C_BUS(bus);
    state->bh = qemu_bh_new(i2c_echo_bh, state);

    return;
}

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

    dc->realize = i2c_echo_realize;

    sc->event = i2c_echo_event;
    sc->recv = i2c_echo_recv;
    sc->send = i2c_echo_send;
}

static const TypeInfo i2c_echo = {
    .name = TYPE_I2C_ECHO,
    .parent = TYPE_I2C_SLAVE,
    .instance_size = sizeof(I2CEchoState),
    .class_init = i2c_echo_class_init,
};

static void register_types(void)
{
    type_register_static(&i2c_echo);
}

type_init(register_types);
