/*
 * Marvell 88w8618 audio emulation extracted from
 * Marvell MV88w8618 / Freecom MusicPal emulation.
 *
 * Copyright (c) 2008 Jan Kiszka
 *
 * This code is licensed 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)

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,
                                       DEVICE_NATIVE_ENDIAN);
    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 */}
    }
};

static void mv88w8618_register_devices(void)
{
    sysbus_register_withprop(&mv88w8618_audio_info);
}

device_init(mv88w8618_register_devices)
