/*
 * Marvell 88w8618 audio emulation extracted from
 * Marvell MV88w8618 / Freecom MusicPal emulation.
 *
 * Copyright (c) 2008 Jan Kiszka
 *
 * This code is licenced under the GNU GPL v2.
 */
#include "sysbus.h"
#include "hw.h"
#include "i2c.h"
#include "sysbus.h"
#include "audio/audio.h"

#define MP_AUDIO_SIZE           0x00001000

/* Audio register offsets */
#define MP_AUDIO_PLAYBACK_MODE  0x00
#define MP_AUDIO_CLOCK_DIV      0x18
#define MP_AUDIO_IRQ_STATUS     0x20
#define MP_AUDIO_IRQ_ENABLE     0x24
#define MP_AUDIO_TX_START_LO    0x28
#define MP_AUDIO_TX_THRESHOLD   0x2C
#define MP_AUDIO_TX_STATUS      0x38
#define MP_AUDIO_TX_START_HI    0x40

/* Status register and IRQ enable bits */
#define MP_AUDIO_TX_HALF        (1 << 6)
#define MP_AUDIO_TX_FULL        (1 << 7)

/* Playback mode bits */
#define MP_AUDIO_16BIT_SAMPLE   (1 << 0)
#define MP_AUDIO_PLAYBACK_EN    (1 << 7)
#define MP_AUDIO_CLOCK_24MHZ    (1 << 9)
#define MP_AUDIO_MONO           (1 << 14)

#ifdef HAS_AUDIO
typedef struct mv88w8618_audio_state {
    SysBusDevice busdev;
    qemu_irq irq;
    uint32_t playback_mode;
    uint32_t status;
    uint32_t irq_enable;
    uint32_t phys_buf;
    uint32_t target_buffer;
    uint32_t threshold;
    uint32_t play_pos;
    uint32_t last_free;
    uint32_t clock_div;
    DeviceState *wm;
} mv88w8618_audio_state;

static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)
{
    mv88w8618_audio_state *s = opaque;
    int16_t *codec_buffer;
    int8_t buf[4096];
    int8_t *mem_buffer;
    int pos, block_size;

    if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) {
        return;
    }
    if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
        free_out <<= 1;
    }
    if (!(s->playback_mode & MP_AUDIO_MONO)) {
        free_out <<= 1;
    }
    block_size = s->threshold / 2;
    if (free_out - s->last_free < block_size) {
        return;
    }
    if (block_size > 4096) {
        return;
    }
    cpu_physical_memory_read(s->target_buffer + s->play_pos, (void *)buf,
                             block_size);
    mem_buffer = buf;
    if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
        if (s->playback_mode & MP_AUDIO_MONO) {
            codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1);
            for (pos = 0; pos < block_size; pos += 2) {
                *codec_buffer++ = *(int16_t *)mem_buffer;
                *codec_buffer++ = *(int16_t *)mem_buffer;
                mem_buffer += 2;
            }
        } else {
            memcpy(wm8750_dac_buffer(s->wm, block_size >> 2),
                   (uint32_t *)mem_buffer, block_size);
        }
    } else {
        if (s->playback_mode & MP_AUDIO_MONO) {
            codec_buffer = wm8750_dac_buffer(s->wm, block_size);
            for (pos = 0; pos < block_size; pos++) {
                *codec_buffer++ = cpu_to_le16(256 * *mem_buffer);
                *codec_buffer++ = cpu_to_le16(256 * *mem_buffer++);
            }
        } else {
            codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1);
            for (pos = 0; pos < block_size; pos += 2) {
                *codec_buffer++ = cpu_to_le16(256 * *mem_buffer++);
                *codec_buffer++ = cpu_to_le16(256 * *mem_buffer++);
            }
        }
    }
    wm8750_dac_commit(s->wm);

    s->last_free = free_out - block_size;

    if (s->play_pos == 0) {
        s->status |= MP_AUDIO_TX_HALF;
        s->play_pos = block_size;
    } else {
        s->status |= MP_AUDIO_TX_FULL;
        s->play_pos = 0;
    }

    if (s->status & s->irq_enable) {
        qemu_irq_raise(s->irq);
    }
}

static void mv88w8618_audio_clock_update(mv88w8618_audio_state *s)
{
    int rate;

    if (s->playback_mode & MP_AUDIO_CLOCK_24MHZ) {
        rate = 24576000 / 64; /* 24.576MHz */
    } else {
        rate = 11289600 / 64; /* 11.2896MHz */
    }
    rate /= ((s->clock_div >> 8) & 0xff) + 1;

    wm8750_set_bclk_in(s->wm, rate);
}

static uint32_t mv88w8618_audio_read(void *opaque, target_phys_addr_t offset)
{
    mv88w8618_audio_state *s = opaque;

    switch (offset) {
    case MP_AUDIO_PLAYBACK_MODE:
        return s->playback_mode;

    case MP_AUDIO_CLOCK_DIV:
        return s->clock_div;

    case MP_AUDIO_IRQ_STATUS:
        return s->status;

    case MP_AUDIO_IRQ_ENABLE:
        return s->irq_enable;

    case MP_AUDIO_TX_STATUS:
        return s->play_pos >> 2;

    default:
        return 0;
    }
}

static void mv88w8618_audio_write(void *opaque, target_phys_addr_t offset,
                                 uint32_t value)
{
    mv88w8618_audio_state *s = opaque;

    switch (offset) {
    case MP_AUDIO_PLAYBACK_MODE:
        if (value & MP_AUDIO_PLAYBACK_EN &&
            !(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) {
            s->status = 0;
            s->last_free = 0;
            s->play_pos = 0;
        }
        s->playback_mode = value;
        mv88w8618_audio_clock_update(s);
        break;

    case MP_AUDIO_CLOCK_DIV:
        s->clock_div = value;
        s->last_free = 0;
        s->play_pos = 0;
        mv88w8618_audio_clock_update(s);
        break;

    case MP_AUDIO_IRQ_STATUS:
        s->status &= ~value;
        break;

    case MP_AUDIO_IRQ_ENABLE:
        s->irq_enable = value;
        if (s->status & s->irq_enable) {
            qemu_irq_raise(s->irq);
        }
        break;

    case MP_AUDIO_TX_START_LO:
        s->phys_buf = (s->phys_buf & 0xFFFF0000) | (value & 0xFFFF);
        s->target_buffer = s->phys_buf;
        s->play_pos = 0;
        s->last_free = 0;
        break;

    case MP_AUDIO_TX_THRESHOLD:
        s->threshold = (value + 1) * 4;
        break;

    case MP_AUDIO_TX_START_HI:
        s->phys_buf = (s->phys_buf & 0xFFFF) | (value << 16);
        s->target_buffer = s->phys_buf;
        s->play_pos = 0;
        s->last_free = 0;
        break;
    }
}

static void mv88w8618_audio_reset(DeviceState *d)
{
    mv88w8618_audio_state *s = FROM_SYSBUS(mv88w8618_audio_state,
                                           sysbus_from_qdev(d));

    s->playback_mode = 0;
    s->status = 0;
    s->irq_enable = 0;
    s->clock_div = 0;
    s->threshold = 0;
    s->phys_buf = 0;
}

static CPUReadMemoryFunc * const mv88w8618_audio_readfn[] = {
    mv88w8618_audio_read,
    mv88w8618_audio_read,
    mv88w8618_audio_read
};

static CPUWriteMemoryFunc * const mv88w8618_audio_writefn[] = {
    mv88w8618_audio_write,
    mv88w8618_audio_write,
    mv88w8618_audio_write
};

static int mv88w8618_audio_init(SysBusDevice *dev)
{
    mv88w8618_audio_state *s = FROM_SYSBUS(mv88w8618_audio_state, dev);
    int iomemtype;

    sysbus_init_irq(dev, &s->irq);

    wm8750_data_req_set(s->wm, mv88w8618_audio_callback, s);

    iomemtype = cpu_register_io_memory(mv88w8618_audio_readfn,
                                       mv88w8618_audio_writefn, s);
    sysbus_init_mmio(dev, MP_AUDIO_SIZE, iomemtype);

    return 0;
}

static const VMStateDescription mv88w8618_audio_vmsd = {
    .name = "mv88w8618_audio",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(playback_mode, mv88w8618_audio_state),
        VMSTATE_UINT32(status, mv88w8618_audio_state),
        VMSTATE_UINT32(irq_enable, mv88w8618_audio_state),
        VMSTATE_UINT32(phys_buf, mv88w8618_audio_state),
        VMSTATE_UINT32(target_buffer, mv88w8618_audio_state),
        VMSTATE_UINT32(threshold, mv88w8618_audio_state),
        VMSTATE_UINT32(play_pos, mv88w8618_audio_state),
        VMSTATE_UINT32(last_free, mv88w8618_audio_state),
        VMSTATE_UINT32(clock_div, mv88w8618_audio_state),
        VMSTATE_END_OF_LIST()
    }
};

static SysBusDeviceInfo mv88w8618_audio_info = {
    .init = mv88w8618_audio_init,
    .qdev.name  = "mv88w8618_audio",
    .qdev.size  = sizeof(mv88w8618_audio_state),
    .qdev.reset = mv88w8618_audio_reset,
    .qdev.vmsd  = &mv88w8618_audio_vmsd,
    .qdev.props = (Property[]) {
        {
            .name   = "wm8750",
            .info   = &qdev_prop_ptr,
            .offset = offsetof(mv88w8618_audio_state, wm),
        },
        {/* end of list */}
    }
};
#endif

static void mv88w8618_register_devices(void)
{
#ifdef HAS_AUDIO
    sysbus_register_withprop(&mv88w8618_audio_info);
#endif
}

device_init(mv88w8618_register_devices)
