/*
 * 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;
    unsigned long phys_buf;
    uint32_t target_buffer;
    unsigned int threshold;
    unsigned int play_pos;
    unsigned int 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, a_target_phys_addr 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, a_target_phys_addr 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(void *opaque)
{
    mv88w8618_audio_state *s = opaque;

    s->playback_mode = 0;
    s->status = 0;
    s->irq_enable = 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);

    qemu_register_reset(mv88w8618_audio_reset, s);

    return 0;
}

static SysBusDeviceInfo mv88w8618_audio_info = {
    .init = mv88w8618_audio_init,
    .qdev.name  = "mv88w8618_audio",
    .qdev.size  = sizeof(mv88w8618_audio_state),
    .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)
