/*
 * VIA south bridges sound support
 *
 * Copyright (c) 2022-2023 BALATON Zoltan
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 */

/*
 * TODO: This is only a basic implementation of one audio playback channel
 *       more functionality should be added here.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/isa/vt82c686.h"
#include "ac97.h"
#include "trace.h"

#define CLEN_IS_EOL(x)  ((x)->clen & BIT(31))
#define CLEN_IS_FLAG(x) ((x)->clen & BIT(30))
#define CLEN_IS_STOP(x) ((x)->clen & BIT(29))
#define CLEN_LEN(x)     ((x)->clen & 0xffffff)

#define STAT_ACTIVE BIT(7)
#define STAT_PAUSED BIT(6)
#define STAT_TRIG   BIT(3)
#define STAT_STOP   BIT(2)
#define STAT_EOL    BIT(1)
#define STAT_FLAG   BIT(0)

#define CNTL_START  BIT(7)
#define CNTL_TERM   BIT(6)
#define CNTL_PAUSE  BIT(3)

static void open_voice_out(ViaAC97State *s);

static uint16_t codec_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100,
                                  48000 };

#define CODEC_REG(s, o)  ((s)->codec_regs[(o) / 2])
#define CODEC_VOL(vol, mask)  ((255 * ((vol) & mask)) / mask)

static void codec_volume_set_out(ViaAC97State *s)
{
    int lvol, rvol, mute;

    lvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute) >> 8, 0x1f);
    lvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> 8, 0x1f);
    lvol /= 255;
    rvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute), 0x1f);
    rvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute), 0x1f);
    rvol /= 255;
    mute = CODEC_REG(s, AC97_Master_Volume_Mute) >> MUTE_SHIFT;
    mute |= CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> MUTE_SHIFT;
    AUD_set_volume_out(s->vo, mute, lvol, rvol);
}

static void codec_reset(ViaAC97State *s)
{
    memset(s->codec_regs, 0, sizeof(s->codec_regs));
    CODEC_REG(s, AC97_Reset) = 0x6a90;
    CODEC_REG(s, AC97_Master_Volume_Mute) = 0x8000;
    CODEC_REG(s, AC97_Headphone_Volume_Mute) = 0x8000;
    CODEC_REG(s, AC97_Master_Volume_Mono_Mute) = 0x8000;
    CODEC_REG(s, AC97_Phone_Volume_Mute) = 0x8008;
    CODEC_REG(s, AC97_Mic_Volume_Mute) = 0x8008;
    CODEC_REG(s, AC97_Line_In_Volume_Mute) = 0x8808;
    CODEC_REG(s, AC97_CD_Volume_Mute) = 0x8808;
    CODEC_REG(s, AC97_Video_Volume_Mute) = 0x8808;
    CODEC_REG(s, AC97_Aux_Volume_Mute) = 0x8808;
    CODEC_REG(s, AC97_PCM_Out_Volume_Mute) = 0x8808;
    CODEC_REG(s, AC97_Record_Gain_Mute) = 0x8000;
    CODEC_REG(s, AC97_Powerdown_Ctrl_Stat) = 0x000f;
    CODEC_REG(s, AC97_Extended_Audio_ID) = 0x0a05;
    CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) = 0x0400;
    CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000;
    CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000;
    /* Sigmatel 9766 (STAC9766) */
    CODEC_REG(s, AC97_Vendor_ID1) = 0x8384;
    CODEC_REG(s, AC97_Vendor_ID2) = 0x7666;
}

static uint16_t codec_read(ViaAC97State *s, uint8_t addr)
{
    return CODEC_REG(s, addr);
}

static void codec_write(ViaAC97State *s, uint8_t addr, uint16_t val)
{
    trace_via_ac97_codec_write(addr, val);
    switch (addr) {
    case AC97_Reset:
        codec_reset(s);
        return;
    case AC97_Master_Volume_Mute:
    case AC97_PCM_Out_Volume_Mute:
        if (addr == AC97_Master_Volume_Mute) {
            if (val & BIT(13)) {
                val |= 0x1f00;
            }
            if (val & BIT(5)) {
                val |= 0x1f;
            }
        }
        CODEC_REG(s, addr) = val & 0x9f1f;
        codec_volume_set_out(s);
        return;
    case AC97_Extended_Audio_Ctrl_Stat:
        CODEC_REG(s, addr) &= ~EACS_VRA;
        CODEC_REG(s, addr) |= val & EACS_VRA;
        if (!(val & EACS_VRA)) {
            CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000;
            CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000;
            open_voice_out(s);
        }
        return;
    case AC97_PCM_Front_DAC_Rate:
    case AC97_PCM_LR_ADC_Rate:
        if (CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) {
            int i;
            uint16_t rate = val;

            for (i = 0; i < ARRAY_SIZE(codec_rates) - 1; i++) {
                if (rate < codec_rates[i] +
                    (codec_rates[i + 1] - codec_rates[i]) / 2) {
                    rate = codec_rates[i];
                    break;
                }
            }
            if (rate > 48000) {
                rate = 48000;
            }
            CODEC_REG(s, addr) = rate;
            open_voice_out(s);
        }
        return;
    case AC97_Powerdown_Ctrl_Stat:
        CODEC_REG(s, addr) = (val & 0xff00) | (CODEC_REG(s, addr) & 0xff);
        return;
    case AC97_Extended_Audio_ID:
    case AC97_Vendor_ID1:
    case AC97_Vendor_ID2:
        /* Read only registers */
        return;
    default:
        qemu_log_mask(LOG_UNIMP,
                      "via-ac97: Unimplemented codec register 0x%x\n", addr);
        CODEC_REG(s, addr) = val;
    }
}

static void fetch_sgd(ViaAC97SGDChannel *c, PCIDevice *d)
{
    uint32_t b[2];

    if (c->curr < c->base) {
        c->curr = c->base;
    }
    if (unlikely(pci_dma_read(d, c->curr, b, sizeof(b)) != MEMTX_OK)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "via-ac97: DMA error reading SGD table\n");
        return;
    }
    c->addr = le32_to_cpu(b[0]);
    c->clen = le32_to_cpu(b[1]);
    trace_via_ac97_sgd_fetch(c->curr, c->addr, CLEN_IS_STOP(c) ? 'S' : '-',
                             CLEN_IS_EOL(c) ? 'E' : '-',
                             CLEN_IS_FLAG(c) ? 'F' : '-', CLEN_LEN(c));
}

static void out_cb(void *opaque, int avail)
{
    ViaAC97State *s = opaque;
    ViaAC97SGDChannel *c = &s->aur;
    int temp, to_copy, copied;
    bool stop = false;
    uint8_t tmpbuf[4096];

    if (c->stat & STAT_PAUSED) {
        return;
    }
    c->stat |= STAT_ACTIVE;
    while (avail && !stop) {
        if (!c->clen) {
            fetch_sgd(c, &s->dev);
        }
        temp = MIN(CLEN_LEN(c), avail);
        while (temp) {
            to_copy = MIN(temp, sizeof(tmpbuf));
            pci_dma_read(&s->dev, c->addr, tmpbuf, to_copy);
            copied = AUD_write(s->vo, tmpbuf, to_copy);
            if (!copied) {
                stop = true;
                break;
            }
            temp -= copied;
            avail -= copied;
            c->addr += copied;
            c->clen -= copied;
        }
        if (CLEN_LEN(c) == 0) {
            c->curr += 8;
            if (CLEN_IS_EOL(c)) {
                c->stat |= STAT_EOL;
                if (c->type & CNTL_START) {
                    c->curr = c->base;
                    c->stat |= STAT_PAUSED;
                } else {
                    c->stat &= ~STAT_ACTIVE;
                    AUD_set_active_out(s->vo, 0);
                }
                if (c->type & STAT_EOL) {
                    pci_set_irq(&s->dev, 1);
                }
            }
            if (CLEN_IS_FLAG(c)) {
                c->stat |= STAT_FLAG;
                c->stat |= STAT_PAUSED;
                if (c->type & STAT_FLAG) {
                    pci_set_irq(&s->dev, 1);
                }
            }
            if (CLEN_IS_STOP(c)) {
                c->stat |= STAT_STOP;
                c->stat |= STAT_PAUSED;
            }
            c->clen = 0;
            stop = true;
        }
    }
}

static void open_voice_out(ViaAC97State *s)
{
    struct audsettings as = {
        .freq = CODEC_REG(s, AC97_PCM_Front_DAC_Rate),
        .nchannels = s->aur.type & BIT(4) ? 2 : 1,
        .fmt = s->aur.type & BIT(5) ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_S8,
        .endianness = 0,
    };
    s->vo = AUD_open_out(&s->card, s->vo, "via-ac97.out", s, out_cb, &as);
}

static uint64_t sgd_read(void *opaque, hwaddr addr, unsigned size)
{
    ViaAC97State *s = opaque;
    uint64_t val = 0;

    switch (addr) {
    case 0:
        val = s->aur.stat;
        if (s->aur.type & CNTL_START) {
            val |= STAT_TRIG;
        }
        break;
    case 1:
        val = s->aur.stat & STAT_PAUSED ? BIT(3) : 0;
        break;
    case 2:
        val = s->aur.type;
        break;
    case 4:
        val = s->aur.curr;
        break;
    case 0xc:
        val = CLEN_LEN(&s->aur);
        break;
    case 0x10:
        /* silence unimplemented log message that happens at every IRQ */
        break;
    case 0x80:
        val = s->ac97_cmd;
        break;
    case 0x84:
        val = s->aur.stat & STAT_FLAG;
        if (s->aur.stat & STAT_EOL) {
            val |= BIT(4);
        }
        if (s->aur.stat & STAT_STOP) {
            val |= BIT(8);
        }
        if (s->aur.stat & STAT_ACTIVE) {
            val |= BIT(12);
        }
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "via-ac97: Unimplemented register read 0x%"
                      HWADDR_PRIx"\n", addr);
    }
    trace_via_ac97_sgd_read(addr, size, val);
    return val;
}

static void sgd_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
    ViaAC97State *s = opaque;

    trace_via_ac97_sgd_write(addr, size, val);
    switch (addr) {
    case 0:
        if (val & STAT_STOP) {
            s->aur.stat &= ~STAT_PAUSED;
        }
        if (val & STAT_EOL) {
            s->aur.stat &= ~(STAT_EOL | STAT_PAUSED);
            if (s->aur.type & STAT_EOL) {
                pci_set_irq(&s->dev, 0);
            }
        }
        if (val & STAT_FLAG) {
            s->aur.stat &= ~(STAT_FLAG | STAT_PAUSED);
            if (s->aur.type & STAT_FLAG) {
                pci_set_irq(&s->dev, 0);
            }
        }
        break;
    case 1:
        if (val & CNTL_START) {
            AUD_set_active_out(s->vo, 1);
            s->aur.stat = STAT_ACTIVE;
        }
        if (val & CNTL_TERM) {
            AUD_set_active_out(s->vo, 0);
            s->aur.stat &= ~(STAT_ACTIVE | STAT_PAUSED);
            s->aur.clen = 0;
        }
        if (val & CNTL_PAUSE) {
            AUD_set_active_out(s->vo, 0);
            s->aur.stat &= ~STAT_ACTIVE;
            s->aur.stat |= STAT_PAUSED;
        } else if (!(val & CNTL_PAUSE) && (s->aur.stat & STAT_PAUSED)) {
            AUD_set_active_out(s->vo, 1);
            s->aur.stat |= STAT_ACTIVE;
            s->aur.stat &= ~STAT_PAUSED;
        }
        break;
    case 2:
    {
        uint32_t oldval = s->aur.type;
        s->aur.type = val;
        if ((oldval & 0x30) != (val & 0x30)) {
            open_voice_out(s);
        }
        break;
    }
    case 4:
        s->aur.base = val & ~1ULL;
        s->aur.curr = s->aur.base;
        break;
    case 0x80:
        if (val >> 30) {
            /* we only have primary codec */
            break;
        }
        if (val & BIT(23)) { /* read reg */
            s->ac97_cmd = val & 0xc0ff0000ULL;
            s->ac97_cmd |= codec_read(s, (val >> 16) & 0x7f);
            s->ac97_cmd |= BIT(25); /* data valid */
        } else {
            s->ac97_cmd = val & 0xc0ffffffULL;
            codec_write(s, (val >> 16) & 0x7f, val);
        }
        break;
    case 0xc:
    case 0x84:
        /* Read only */
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "via-ac97: Unimplemented register write 0x%"
                      HWADDR_PRIx"\n", addr);
    }
}

static const MemoryRegionOps sgd_ops = {
    .read = sgd_read,
    .write = sgd_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static uint64_t fm_read(void *opaque, hwaddr addr, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d\n", __func__, addr, size);
    return 0;
}

static void fm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d <= 0x%"PRIX64"\n",
                  __func__, addr, size, val);
}

static const MemoryRegionOps fm_ops = {
    .read = fm_read,
    .write = fm_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static uint64_t midi_read(void *opaque, hwaddr addr, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d\n", __func__, addr, size);
    return 0;
}

static void midi_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d <= 0x%"PRIX64"\n",
                  __func__, addr, size, val);
}

static const MemoryRegionOps midi_ops = {
    .read = midi_read,
    .write = midi_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void via_ac97_reset(DeviceState *dev)
{
    ViaAC97State *s = VIA_AC97(dev);

    codec_reset(s);
}

static void via_ac97_realize(PCIDevice *pci_dev, Error **errp)
{
    ViaAC97State *s = VIA_AC97(pci_dev);
    Object *o = OBJECT(s);

    if (!AUD_register_card ("via-ac97", &s->card, errp)) {
        return;
    }

    /*
     * Command register Bus Master bit is documented to be fixed at 0 but it's
     * needed for PCI DMA to work in QEMU. The pegasos2 firmware writes 0 here
     * and the AmigaOS driver writes 1 only enabling IO bit which works on
     * real hardware. So set it here and fix it to 1 to allow DMA.
     */
    pci_set_word(pci_dev->config + PCI_COMMAND, PCI_COMMAND_MASTER);
    pci_set_word(pci_dev->wmask + PCI_COMMAND, PCI_COMMAND_IO);
    pci_set_word(pci_dev->config + PCI_STATUS,
                 PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM);
    pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03);
    pci_set_byte(pci_dev->config + 0x40, 1); /* codec ready */

    memory_region_init_io(&s->sgd, o, &sgd_ops, s, "via-ac97.sgd", 256);
    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->sgd);
    memory_region_init_io(&s->fm, o, &fm_ops, s, "via-ac97.fm", 4);
    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->fm);
    memory_region_init_io(&s->midi, o, &midi_ops, s, "via-ac97.midi", 4);
    pci_register_bar(pci_dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->midi);
}

static void via_ac97_exit(PCIDevice *dev)
{
    ViaAC97State *s = VIA_AC97(dev);

    AUD_close_out(&s->card, s->vo);
    AUD_remove_card(&s->card);
}

static Property via_ac97_properties[] = {
    DEFINE_AUDIO_PROPERTIES(ViaAC97State, card),
    DEFINE_PROP_END_OF_LIST(),
};

static void via_ac97_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = via_ac97_realize;
    k->exit = via_ac97_exit;
    k->vendor_id = PCI_VENDOR_ID_VIA;
    k->device_id = PCI_DEVICE_ID_VIA_AC97;
    k->revision = 0x50;
    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
    device_class_set_props(dc, via_ac97_properties);
    set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
    dc->desc = "VIA AC97";
    dc->reset = via_ac97_reset;
    /* Reason: Part of a south bridge chip */
    dc->user_creatable = false;
}

static const TypeInfo via_ac97_info = {
    .name          = TYPE_VIA_AC97,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(ViaAC97State),
    .class_init    = via_ac97_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void via_mc97_realize(PCIDevice *pci_dev, Error **errp)
{
    pci_set_word(pci_dev->config + PCI_COMMAND,
                 PCI_COMMAND_INVALIDATE | PCI_COMMAND_VGA_PALETTE);
    pci_set_word(pci_dev->config + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
    pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03);
}

static void via_mc97_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = via_mc97_realize;
    k->vendor_id = PCI_VENDOR_ID_VIA;
    k->device_id = PCI_DEVICE_ID_VIA_MC97;
    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
    k->revision = 0x30;
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
    dc->desc = "VIA MC97";
    /* Reason: Part of a south bridge chip */
    dc->user_creatable = false;
}

static const TypeInfo via_mc97_info = {
    .name          = TYPE_VIA_MC97,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(PCIDevice),
    .class_init    = via_mc97_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void via_ac97_register_types(void)
{
    type_register_static(&via_ac97_info);
    type_register_static(&via_mc97_info);
}

type_init(via_ac97_register_types)
