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

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

    AUD_register_card ("via-ac97", &s->card);
}

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)
