/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** 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.
*/
#include "hw/hw.h"
#include "audio/audio.h"
#include "hw/sysbus.h"
#include "qemu/error-report.h"
#include "trace.h"

#define TYPE_GOLDFISH_AUDIO "goldfish_audio"
#define GOLDFISH_AUDIO(obj) OBJECT_CHECK(struct goldfish_audio_state, (obj), TYPE_GOLDFISH_AUDIO)

enum {
	/* audio status register */
	AUDIO_INT_STATUS	= 0x00,
	/* set this to enable IRQ */
	AUDIO_INT_ENABLE	= 0x04,
	/* set these to specify buffer addresses */
	AUDIO_SET_WRITE_BUFFER_1 = 0x08,
	AUDIO_SET_WRITE_BUFFER_2 = 0x0C,
	/* set number of bytes in buffer to write */
	AUDIO_WRITE_BUFFER_1  = 0x10,
	AUDIO_WRITE_BUFFER_2  = 0x14,

	/* true if audio input is supported */
	AUDIO_READ_SUPPORTED = 0x18,
	/* buffer to use for audio input */
	AUDIO_SET_READ_BUFFER = 0x1C,

	/* driver writes number of bytes to read */
	AUDIO_START_READ  = 0x20,

	/* number of bytes available in read buffer */
	AUDIO_READ_BUFFER_AVAILABLE  = 0x24,

	/* AUDIO_INT_STATUS bits */

	/* this bit set when it is safe to write more bytes to the buffer */
	AUDIO_INT_WRITE_BUFFER_1_EMPTY	= 1U << 0,
	AUDIO_INT_WRITE_BUFFER_2_EMPTY	= 1U << 1,
	AUDIO_INT_READ_BUFFER_FULL      = 1U << 2,
};

struct goldfish_audio_buff {
    uint32_t  address;
    uint32_t  length;
    uint8*    data;
    uint32_t  capacity;
    uint32_t  offset;
};


struct goldfish_audio_state {
    SysBusDevice parent;

    bool input;
    bool output;

    MemoryRegion iomem;
    qemu_irq irq;

    // buffer flags
    uint32_t int_status;
    // irq enable mask for int_status
    uint32_t int_enable;

    // number of bytes available in the read buffer
    uint32_t read_buffer_available;

    // set to 0 or 1 to indicate which buffer we are writing from, or -1 if both buffers are empty
    int8_t current_buffer;

    // current data to write
    struct goldfish_audio_buff  out_buffs[2];
    struct goldfish_audio_buff  in_buff;

    // for QEMU sound output
    QEMUSoundCard card;
    SWVoiceOut *voice;
    SWVoiceIn*  voicein;
};

static void
goldfish_audio_buff_init( struct goldfish_audio_buff*  b )
{
    b->address  = 0;
    b->length   = 0;
    b->data     = NULL;
    b->capacity = 0;
    b->offset   = 0;
}

static void
goldfish_audio_buff_reset( struct goldfish_audio_buff*  b )
{
    b->offset = 0;
    b->length = 0;
}

static uint32_t
goldfish_audio_buff_length( struct goldfish_audio_buff*  b )
{
    return b->length;
}

static void
goldfish_audio_buff_ensure( struct goldfish_audio_buff*  b, uint32_t  size )
{
    if (b->capacity < size) {
        b->data     = g_realloc(b->data, size);
        b->capacity = size;
    }
}

static void
goldfish_audio_buff_set_address( struct goldfish_audio_buff*  b, uint32_t  addr )
{
    b->address = addr;
}

static void
goldfish_audio_buff_set_length( struct goldfish_audio_buff*  b, uint32_t  len )
{
    b->length = len;
    b->offset = 0;
    goldfish_audio_buff_ensure(b, len);
}

static void
goldfish_audio_buff_read( struct goldfish_audio_buff*  b )
{
    cpu_physical_memory_read(b->address, b->data, b->length);
}

static void
goldfish_audio_buff_write( struct goldfish_audio_buff*  b )
{
    cpu_physical_memory_write(b->address, b->data, b->length);
}

static int
goldfish_audio_buff_available( struct goldfish_audio_buff*  b )
{
    return b->length - b->offset;
}

static int
goldfish_audio_buff_recv( struct goldfish_audio_buff*  b, int  avail, struct goldfish_audio_state*  s )
{
    int     missing = b->length - b->offset;
    int     avail2 = (avail > missing) ? missing : avail;
    int     read;

    read = AUD_read(s->voicein, b->data + b->offset, avail2 );
    if (read == 0)
        return 0;

    if (avail2 > 0)
        trace_goldfish_audio_buff_recv(avail2, read);

    cpu_physical_memory_write( b->address + b->offset, b->data, read );
    b->offset += read;

    return read;
}

/* update this whenever you change the goldfish_audio_state structure */
#define  AUDIO_STATE_SAVE_VERSION  3

static const VMStateDescription goldfish_audio_buff_vmsd = {
    .name = "goldfish_audio_buff",
    .version_id = AUDIO_STATE_SAVE_VERSION,
    .minimum_version_id = AUDIO_STATE_SAVE_VERSION,
    .minimum_version_id_old = AUDIO_STATE_SAVE_VERSION,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(address, struct goldfish_audio_buff),
        VMSTATE_UINT32(length, struct goldfish_audio_buff),
        VMSTATE_UINT32(offset, struct goldfish_audio_buff),
        VMSTATE_VARRAY_UINT32(data, struct goldfish_audio_buff, length,
                0, vmstate_info_uint8, uint8_t),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription goldfish_audio_vmsd = {
    .name = "goldfish_audio",
    .version_id = AUDIO_STATE_SAVE_VERSION,
    .minimum_version_id = AUDIO_STATE_SAVE_VERSION,
    .minimum_version_id_old = AUDIO_STATE_SAVE_VERSION,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(int_status, struct goldfish_audio_state),
        VMSTATE_UINT32(int_enable, struct goldfish_audio_state),
        VMSTATE_UINT32(read_buffer_available, struct goldfish_audio_state),
        VMSTATE_INT8(current_buffer, struct goldfish_audio_state),
        VMSTATE_STRUCT_ARRAY(out_buffs, struct goldfish_audio_state, 2, 0,
                goldfish_audio_buff_vmsd, struct goldfish_audio_buff),
        VMSTATE_STRUCT(in_buff, struct goldfish_audio_state, 0,
                goldfish_audio_buff_vmsd, struct goldfish_audio_buff),
        VMSTATE_END_OF_LIST()
    }
};

static void enable_audio(struct goldfish_audio_state *s, int enable)
{
    if (s->voice != NULL) {
        goldfish_audio_buff_reset( &s->out_buffs[0] );
        goldfish_audio_buff_reset( &s->out_buffs[1] );
    }

    if (s->voicein) {
        AUD_set_active_in (s->voicein, (enable & AUDIO_INT_READ_BUFFER_FULL) != 0);
        goldfish_audio_buff_reset( &s->in_buff );
    }
    s->current_buffer = -1;
}

static void start_read(struct goldfish_audio_state *s, uint32_t count)
{
    //printf( "... goldfish audio start_read, count=%d\n", count );
    goldfish_audio_buff_set_length( &s->in_buff, count );
    s->read_buffer_available = count;
}

static uint64_t goldfish_audio_read(void *opaque, hwaddr offset, unsigned size)
{
    uint64_t ret;
    struct goldfish_audio_state *s = opaque;
    switch(offset) {
        case AUDIO_INT_STATUS:
            // return current buffer status flags
            ret = s->int_status & s->int_enable;
            if(ret) {
                qemu_irq_lower(s->irq);
            }
            return ret;

	case AUDIO_READ_SUPPORTED:
            trace_goldfish_audio_memory_read("AUDIO_READ_SUPPORTED",
              (s->voicein != NULL));
            return (s->voicein != NULL);

	case AUDIO_READ_BUFFER_AVAILABLE:
            trace_goldfish_audio_memory_read("AUDIO_READ_BUFFER_AVAILABLE",
               s->read_buffer_available);
            goldfish_audio_buff_write( &s->in_buff );
	    return s->read_buffer_available;

        default:
            error_report ("goldfish_audio_read: Bad offset 0x" TARGET_FMT_plx,
                    offset);
            return 0;
    }
}

static void goldfish_audio_write_buffer(struct goldfish_audio_state *s,
        unsigned int buf, uint32_t length)
{
    if (s->current_buffer == -1)
        s->current_buffer = buf;
    goldfish_audio_buff_set_length(&s->out_buffs[buf], length);
    goldfish_audio_buff_read(&s->out_buffs[buf]);
    AUD_set_active_out(s->voice, 1);
}

static void goldfish_audio_write(void *opaque, hwaddr offset, uint64_t val,
        unsigned size)
{
    struct goldfish_audio_state *s = opaque;

    switch(offset) {
        case AUDIO_INT_ENABLE:
            /* enable buffer empty interrupts */
            trace_goldfish_audio_memory_write("AUDIO_INT_ENABLE", val);
            enable_audio(s, val);
            s->int_enable = val;
            s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
            qemu_set_irq(s->irq, s->int_status & s->int_enable);
            break;
        case AUDIO_SET_WRITE_BUFFER_1:
            /* save pointer to buffer 1 */
            trace_goldfish_audio_memory_write("AUDIO_SET_WRITE_BUFFER_1", val);
            goldfish_audio_buff_set_address( &s->out_buffs[0], val );
            break;
        case AUDIO_SET_WRITE_BUFFER_2:
            /* save pointer to buffer 2 */
            trace_goldfish_audio_memory_write("AUDIO_SET_WRITE_BUFFER_2", val);
            goldfish_audio_buff_set_address( &s->out_buffs[1], val );
            break;
        case AUDIO_WRITE_BUFFER_1:
            /* record that data in buffer 1 is ready to write */
            trace_goldfish_audio_memory_write("AUDIO_WRITE_BUFFER_1", val);
            goldfish_audio_write_buffer(s, 0, val);
            s->int_status &= ~AUDIO_INT_WRITE_BUFFER_1_EMPTY;
            break;
        case AUDIO_WRITE_BUFFER_2:
            /* record that data in buffer 2 is ready to write */
            trace_goldfish_audio_memory_write("AUDIO_WRITE_BUFFER_2", val);
            goldfish_audio_write_buffer(s, 1, val);
            s->int_status &= ~AUDIO_INT_WRITE_BUFFER_2_EMPTY;
            break;

        case AUDIO_SET_READ_BUFFER:
            /* save pointer to the read buffer */
            goldfish_audio_buff_set_address( &s->in_buff, val );
            trace_goldfish_audio_memory_write("AUDIO_SET_READ_BUFFER", val);
            break;

        case AUDIO_START_READ:
            trace_goldfish_audio_memory_write("AUDIO_START_READ", val);
            start_read(s, val);
            s->int_status &= ~AUDIO_INT_READ_BUFFER_FULL;
            qemu_set_irq(s->irq, s->int_status & s->int_enable);
            break;

        default:
            error_report ("goldfish_audio_write: Bad offset 0x" TARGET_FMT_plx,
                    offset);
    }
}

static bool goldfish_audio_flush(struct goldfish_audio_state *s, int buf,
        int *free, uint32_t *new_status)
{
    struct goldfish_audio_buff *b = &s->out_buffs[buf];
    int to_write = audio_MIN(b->length, *free);

    if (!to_write)
        return false;

    int written = AUD_write(s->voice, b->data + b->offset, to_write);
    if (!written)
        return false;

    b->offset += written;
    b->length -= written;
    *free -= written;
    trace_goldfish_audio_buff_send(written, buf + 1);

    if (!goldfish_audio_buff_length(b) == 0)
        *new_status |= buf ? AUDIO_INT_WRITE_BUFFER_1_EMPTY :
                AUDIO_INT_WRITE_BUFFER_2_EMPTY;

    return true;
}

static void goldfish_audio_callback(void *opaque, int free)
{
    struct goldfish_audio_state *s = opaque;
    uint32_t new_status = 0;

    if (s->current_buffer != -1) {
        int8_t i = s->current_buffer;
        int8_t j = (i + 1) % 2;

        goldfish_audio_flush(s, i, &free, &new_status);
        goldfish_audio_flush(s, j, &free, &new_status);

        if (!goldfish_audio_buff_length(&s->out_buffs[i])) {
            if (goldfish_audio_buff_length(&s->out_buffs[j])) {
                s->current_buffer = j;
            } else {
                s->current_buffer = -1;
            }
        }
    }

    if (free) /* out of samples, pause playback */
        AUD_set_active_out(s->voice, 0);

    if (new_status && new_status != s->int_status) {
        s->int_status |= new_status;
        qemu_set_irq(s->irq, s->int_status & s->int_enable);
    }
}

static void
goldfish_audio_in_callback(void *opaque, int avail)
{
    struct goldfish_audio_state *s = opaque;
    int new_status = 0;

    if (goldfish_audio_buff_available( &s->in_buff ) == 0 )
        return;

    while (avail > 0) {
        int  read = goldfish_audio_buff_recv( &s->in_buff, avail, s );
        if (read == 0)
            break;

        avail -= read;

        if (goldfish_audio_buff_available( &s->in_buff) == 0) {
            new_status |= AUDIO_INT_READ_BUFFER_FULL;
            trace_goldfish_audio_buff_full(
              goldfish_audio_buff_length( &s->in_buff ));
            break;
        }
    }

    if (new_status && new_status != s->int_status) {
        s->int_status |= new_status;
        qemu_set_irq(s->irq, s->int_status & s->int_enable);
    }
}

static const MemoryRegionOps goldfish_audio_iomem_ops = {
    .read = goldfish_audio_read,
    .write = goldfish_audio_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl.min_access_size = 4,
    .impl.max_access_size = 4,
};

static void goldfish_audio_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);
    struct goldfish_audio_state *s = GOLDFISH_AUDIO(dev);
    struct audsettings as;

    sysbus_init_irq(sbdev, &s->irq);

    AUD_register_card( "goldfish_audio", &s->card);

    as.freq = 44100;
    as.nchannels = 2;
    as.fmt = AUD_FMT_S16;
    as.endianness = AUDIO_HOST_ENDIANNESS;

    if (s->output) {
        s->voice = AUD_open_out (
            &s->card,
            NULL,
            "goldfish_audio",
            s,
            goldfish_audio_callback,
            &as
            );
        if (!s->voice) {
            error_setg(errp, "opening audio output failed");
            return;
        }
    }

    as.freq       = 8000;
    as.nchannels  = 1;
    as.fmt        = AUD_FMT_S16;
    as.endianness = AUDIO_HOST_ENDIANNESS;

    if (s->input) {
        s->voicein = AUD_open_in (
            &s->card,
            NULL,
            "goldfish_audio_in",
            s,
            goldfish_audio_in_callback,
            &as
            );
        if (!s->voicein) {
            error_report("warning: opening audio input failed");
        }
    }

    goldfish_audio_buff_init( &s->out_buffs[0] );
    goldfish_audio_buff_init( &s->out_buffs[1] );
    goldfish_audio_buff_init( &s->in_buff );

    memory_region_init_io(&s->iomem, OBJECT(s), &goldfish_audio_iomem_ops, s,
            "goldfish_audio", 0x100);
    sysbus_init_mmio(sbdev, &s->iomem);
}

static Property goldfish_audio_properties[] = {
    DEFINE_PROP_BOOL("input", struct goldfish_audio_state, input, true),
    DEFINE_PROP_BOOL("output", struct goldfish_audio_state, output, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void goldfish_audio_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = goldfish_audio_realize;
    dc->desc = "goldfish audio";
    dc->props = goldfish_audio_properties;
}

static const TypeInfo goldfish_audio_info = {
    .name          = TYPE_GOLDFISH_AUDIO,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(struct goldfish_audio_state),
    .class_init    = goldfish_audio_class_init,
};

static void goldfish_audio_register(void)
{
    type_register_static(&goldfish_audio_info);
}

type_init(goldfish_audio_register);
