1657fae25SBALATON Zoltan /* 2657fae25SBALATON Zoltan * VIA south bridges sound support 3657fae25SBALATON Zoltan * 4*eb604411SBALATON Zoltan * Copyright (c) 2022-2023 BALATON Zoltan 5*eb604411SBALATON Zoltan * 6657fae25SBALATON Zoltan * This work is licensed under the GNU GPL license version 2 or later. 7657fae25SBALATON Zoltan */ 8657fae25SBALATON Zoltan 9657fae25SBALATON Zoltan /* 10*eb604411SBALATON Zoltan * TODO: This is only a basic implementation of one audio playback channel 11*eb604411SBALATON Zoltan * more functionality should be added here. 12657fae25SBALATON Zoltan */ 13657fae25SBALATON Zoltan 14657fae25SBALATON Zoltan #include "qemu/osdep.h" 15*eb604411SBALATON Zoltan #include "qemu/log.h" 16657fae25SBALATON Zoltan #include "hw/isa/vt82c686.h" 17*eb604411SBALATON Zoltan #include "ac97.h" 18*eb604411SBALATON Zoltan #include "trace.h" 19*eb604411SBALATON Zoltan 20*eb604411SBALATON Zoltan #define CLEN_IS_EOL(x) ((x)->clen & BIT(31)) 21*eb604411SBALATON Zoltan #define CLEN_IS_FLAG(x) ((x)->clen & BIT(30)) 22*eb604411SBALATON Zoltan #define CLEN_IS_STOP(x) ((x)->clen & BIT(29)) 23*eb604411SBALATON Zoltan #define CLEN_LEN(x) ((x)->clen & 0xffffff) 24*eb604411SBALATON Zoltan 25*eb604411SBALATON Zoltan #define STAT_ACTIVE BIT(7) 26*eb604411SBALATON Zoltan #define STAT_PAUSED BIT(6) 27*eb604411SBALATON Zoltan #define STAT_TRIG BIT(3) 28*eb604411SBALATON Zoltan #define STAT_STOP BIT(2) 29*eb604411SBALATON Zoltan #define STAT_EOL BIT(1) 30*eb604411SBALATON Zoltan #define STAT_FLAG BIT(0) 31*eb604411SBALATON Zoltan 32*eb604411SBALATON Zoltan #define CNTL_START BIT(7) 33*eb604411SBALATON Zoltan #define CNTL_TERM BIT(6) 34*eb604411SBALATON Zoltan #define CNTL_PAUSE BIT(3) 35*eb604411SBALATON Zoltan 36*eb604411SBALATON Zoltan static void open_voice_out(ViaAC97State *s); 37*eb604411SBALATON Zoltan 38*eb604411SBALATON Zoltan static uint16_t codec_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 39*eb604411SBALATON Zoltan 48000 }; 40*eb604411SBALATON Zoltan 41*eb604411SBALATON Zoltan #define CODEC_REG(s, o) ((s)->codec_regs[(o) / 2]) 42*eb604411SBALATON Zoltan #define CODEC_VOL(vol, mask) ((255 * ((vol) & mask)) / mask) 43*eb604411SBALATON Zoltan 44*eb604411SBALATON Zoltan static void codec_volume_set_out(ViaAC97State *s) 45*eb604411SBALATON Zoltan { 46*eb604411SBALATON Zoltan int lvol, rvol, mute; 47*eb604411SBALATON Zoltan 48*eb604411SBALATON Zoltan lvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute) >> 8, 0x1f); 49*eb604411SBALATON Zoltan lvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> 8, 0x1f); 50*eb604411SBALATON Zoltan lvol /= 255; 51*eb604411SBALATON Zoltan rvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute), 0x1f); 52*eb604411SBALATON Zoltan rvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute), 0x1f); 53*eb604411SBALATON Zoltan rvol /= 255; 54*eb604411SBALATON Zoltan mute = CODEC_REG(s, AC97_Master_Volume_Mute) >> MUTE_SHIFT; 55*eb604411SBALATON Zoltan mute |= CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> MUTE_SHIFT; 56*eb604411SBALATON Zoltan AUD_set_volume_out(s->vo, mute, lvol, rvol); 57*eb604411SBALATON Zoltan } 58*eb604411SBALATON Zoltan 59*eb604411SBALATON Zoltan static void codec_reset(ViaAC97State *s) 60*eb604411SBALATON Zoltan { 61*eb604411SBALATON Zoltan memset(s->codec_regs, 0, sizeof(s->codec_regs)); 62*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Reset) = 0x6a90; 63*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Master_Volume_Mute) = 0x8000; 64*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Headphone_Volume_Mute) = 0x8000; 65*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Master_Volume_Mono_Mute) = 0x8000; 66*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Phone_Volume_Mute) = 0x8008; 67*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Mic_Volume_Mute) = 0x8008; 68*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Line_In_Volume_Mute) = 0x8808; 69*eb604411SBALATON Zoltan CODEC_REG(s, AC97_CD_Volume_Mute) = 0x8808; 70*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Video_Volume_Mute) = 0x8808; 71*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Aux_Volume_Mute) = 0x8808; 72*eb604411SBALATON Zoltan CODEC_REG(s, AC97_PCM_Out_Volume_Mute) = 0x8808; 73*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Record_Gain_Mute) = 0x8000; 74*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Powerdown_Ctrl_Stat) = 0x000f; 75*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Extended_Audio_ID) = 0x0a05; 76*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) = 0x0400; 77*eb604411SBALATON Zoltan CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000; 78*eb604411SBALATON Zoltan CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000; 79*eb604411SBALATON Zoltan /* Sigmatel 9766 (STAC9766) */ 80*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Vendor_ID1) = 0x8384; 81*eb604411SBALATON Zoltan CODEC_REG(s, AC97_Vendor_ID2) = 0x7666; 82*eb604411SBALATON Zoltan } 83*eb604411SBALATON Zoltan 84*eb604411SBALATON Zoltan static uint16_t codec_read(ViaAC97State *s, uint8_t addr) 85*eb604411SBALATON Zoltan { 86*eb604411SBALATON Zoltan return CODEC_REG(s, addr); 87*eb604411SBALATON Zoltan } 88*eb604411SBALATON Zoltan 89*eb604411SBALATON Zoltan static void codec_write(ViaAC97State *s, uint8_t addr, uint16_t val) 90*eb604411SBALATON Zoltan { 91*eb604411SBALATON Zoltan trace_via_ac97_codec_write(addr, val); 92*eb604411SBALATON Zoltan switch (addr) { 93*eb604411SBALATON Zoltan case AC97_Reset: 94*eb604411SBALATON Zoltan codec_reset(s); 95*eb604411SBALATON Zoltan return; 96*eb604411SBALATON Zoltan case AC97_Master_Volume_Mute: 97*eb604411SBALATON Zoltan case AC97_PCM_Out_Volume_Mute: 98*eb604411SBALATON Zoltan if (addr == AC97_Master_Volume_Mute) { 99*eb604411SBALATON Zoltan if (val & BIT(13)) { 100*eb604411SBALATON Zoltan val |= 0x1f00; 101*eb604411SBALATON Zoltan } 102*eb604411SBALATON Zoltan if (val & BIT(5)) { 103*eb604411SBALATON Zoltan val |= 0x1f; 104*eb604411SBALATON Zoltan } 105*eb604411SBALATON Zoltan } 106*eb604411SBALATON Zoltan CODEC_REG(s, addr) = val & 0x9f1f; 107*eb604411SBALATON Zoltan codec_volume_set_out(s); 108*eb604411SBALATON Zoltan return; 109*eb604411SBALATON Zoltan case AC97_Extended_Audio_Ctrl_Stat: 110*eb604411SBALATON Zoltan CODEC_REG(s, addr) &= ~EACS_VRA; 111*eb604411SBALATON Zoltan CODEC_REG(s, addr) |= val & EACS_VRA; 112*eb604411SBALATON Zoltan if (!(val & EACS_VRA)) { 113*eb604411SBALATON Zoltan CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000; 114*eb604411SBALATON Zoltan CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000; 115*eb604411SBALATON Zoltan open_voice_out(s); 116*eb604411SBALATON Zoltan } 117*eb604411SBALATON Zoltan return; 118*eb604411SBALATON Zoltan case AC97_PCM_Front_DAC_Rate: 119*eb604411SBALATON Zoltan case AC97_PCM_LR_ADC_Rate: 120*eb604411SBALATON Zoltan if (CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) { 121*eb604411SBALATON Zoltan int i; 122*eb604411SBALATON Zoltan uint16_t rate = val; 123*eb604411SBALATON Zoltan 124*eb604411SBALATON Zoltan for (i = 0; i < ARRAY_SIZE(codec_rates) - 1; i++) { 125*eb604411SBALATON Zoltan if (rate < codec_rates[i] + 126*eb604411SBALATON Zoltan (codec_rates[i + 1] - codec_rates[i]) / 2) { 127*eb604411SBALATON Zoltan rate = codec_rates[i]; 128*eb604411SBALATON Zoltan break; 129*eb604411SBALATON Zoltan } 130*eb604411SBALATON Zoltan } 131*eb604411SBALATON Zoltan if (rate > 48000) { 132*eb604411SBALATON Zoltan rate = 48000; 133*eb604411SBALATON Zoltan } 134*eb604411SBALATON Zoltan CODEC_REG(s, addr) = rate; 135*eb604411SBALATON Zoltan open_voice_out(s); 136*eb604411SBALATON Zoltan } 137*eb604411SBALATON Zoltan return; 138*eb604411SBALATON Zoltan case AC97_Powerdown_Ctrl_Stat: 139*eb604411SBALATON Zoltan CODEC_REG(s, addr) = (val & 0xff00) | (CODEC_REG(s, addr) & 0xff); 140*eb604411SBALATON Zoltan return; 141*eb604411SBALATON Zoltan case AC97_Extended_Audio_ID: 142*eb604411SBALATON Zoltan case AC97_Vendor_ID1: 143*eb604411SBALATON Zoltan case AC97_Vendor_ID2: 144*eb604411SBALATON Zoltan /* Read only registers */ 145*eb604411SBALATON Zoltan return; 146*eb604411SBALATON Zoltan default: 147*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, 148*eb604411SBALATON Zoltan "via-ac97: Unimplemented codec register 0x%x\n", addr); 149*eb604411SBALATON Zoltan CODEC_REG(s, addr) = val; 150*eb604411SBALATON Zoltan } 151*eb604411SBALATON Zoltan } 152*eb604411SBALATON Zoltan 153*eb604411SBALATON Zoltan static void fetch_sgd(ViaAC97SGDChannel *c, PCIDevice *d) 154*eb604411SBALATON Zoltan { 155*eb604411SBALATON Zoltan uint32_t b[2]; 156*eb604411SBALATON Zoltan 157*eb604411SBALATON Zoltan if (c->curr < c->base) { 158*eb604411SBALATON Zoltan c->curr = c->base; 159*eb604411SBALATON Zoltan } 160*eb604411SBALATON Zoltan if (unlikely(pci_dma_read(d, c->curr, b, sizeof(b)) != MEMTX_OK)) { 161*eb604411SBALATON Zoltan qemu_log_mask(LOG_GUEST_ERROR, 162*eb604411SBALATON Zoltan "via-ac97: DMA error reading SGD table\n"); 163*eb604411SBALATON Zoltan return; 164*eb604411SBALATON Zoltan } 165*eb604411SBALATON Zoltan c->addr = le32_to_cpu(b[0]); 166*eb604411SBALATON Zoltan c->clen = le32_to_cpu(b[1]); 167*eb604411SBALATON Zoltan trace_via_ac97_sgd_fetch(c->curr, c->addr, CLEN_IS_STOP(c) ? 'S' : '-', 168*eb604411SBALATON Zoltan CLEN_IS_EOL(c) ? 'E' : '-', 169*eb604411SBALATON Zoltan CLEN_IS_FLAG(c) ? 'F' : '-', CLEN_LEN(c)); 170*eb604411SBALATON Zoltan } 171*eb604411SBALATON Zoltan 172*eb604411SBALATON Zoltan static void out_cb(void *opaque, int avail) 173*eb604411SBALATON Zoltan { 174*eb604411SBALATON Zoltan ViaAC97State *s = opaque; 175*eb604411SBALATON Zoltan ViaAC97SGDChannel *c = &s->aur; 176*eb604411SBALATON Zoltan int temp, to_copy, copied; 177*eb604411SBALATON Zoltan bool stop = false; 178*eb604411SBALATON Zoltan uint8_t tmpbuf[4096]; 179*eb604411SBALATON Zoltan 180*eb604411SBALATON Zoltan if (c->stat & STAT_PAUSED) { 181*eb604411SBALATON Zoltan return; 182*eb604411SBALATON Zoltan } 183*eb604411SBALATON Zoltan c->stat |= STAT_ACTIVE; 184*eb604411SBALATON Zoltan while (avail && !stop) { 185*eb604411SBALATON Zoltan if (!c->clen) { 186*eb604411SBALATON Zoltan fetch_sgd(c, &s->dev); 187*eb604411SBALATON Zoltan } 188*eb604411SBALATON Zoltan temp = MIN(CLEN_LEN(c), avail); 189*eb604411SBALATON Zoltan while (temp) { 190*eb604411SBALATON Zoltan to_copy = MIN(temp, sizeof(tmpbuf)); 191*eb604411SBALATON Zoltan pci_dma_read(&s->dev, c->addr, tmpbuf, to_copy); 192*eb604411SBALATON Zoltan copied = AUD_write(s->vo, tmpbuf, to_copy); 193*eb604411SBALATON Zoltan if (!copied) { 194*eb604411SBALATON Zoltan stop = true; 195*eb604411SBALATON Zoltan break; 196*eb604411SBALATON Zoltan } 197*eb604411SBALATON Zoltan temp -= copied; 198*eb604411SBALATON Zoltan avail -= copied; 199*eb604411SBALATON Zoltan c->addr += copied; 200*eb604411SBALATON Zoltan c->clen -= copied; 201*eb604411SBALATON Zoltan } 202*eb604411SBALATON Zoltan if (CLEN_LEN(c) == 0) { 203*eb604411SBALATON Zoltan c->curr += 8; 204*eb604411SBALATON Zoltan if (CLEN_IS_EOL(c)) { 205*eb604411SBALATON Zoltan c->stat |= STAT_EOL; 206*eb604411SBALATON Zoltan if (c->type & CNTL_START) { 207*eb604411SBALATON Zoltan c->curr = c->base; 208*eb604411SBALATON Zoltan c->stat |= STAT_PAUSED; 209*eb604411SBALATON Zoltan } else { 210*eb604411SBALATON Zoltan c->stat &= ~STAT_ACTIVE; 211*eb604411SBALATON Zoltan AUD_set_active_out(s->vo, 0); 212*eb604411SBALATON Zoltan } 213*eb604411SBALATON Zoltan if (c->type & STAT_EOL) { 214*eb604411SBALATON Zoltan pci_set_irq(&s->dev, 1); 215*eb604411SBALATON Zoltan } 216*eb604411SBALATON Zoltan } 217*eb604411SBALATON Zoltan if (CLEN_IS_FLAG(c)) { 218*eb604411SBALATON Zoltan c->stat |= STAT_FLAG; 219*eb604411SBALATON Zoltan c->stat |= STAT_PAUSED; 220*eb604411SBALATON Zoltan if (c->type & STAT_FLAG) { 221*eb604411SBALATON Zoltan pci_set_irq(&s->dev, 1); 222*eb604411SBALATON Zoltan } 223*eb604411SBALATON Zoltan } 224*eb604411SBALATON Zoltan if (CLEN_IS_STOP(c)) { 225*eb604411SBALATON Zoltan c->stat |= STAT_STOP; 226*eb604411SBALATON Zoltan c->stat |= STAT_PAUSED; 227*eb604411SBALATON Zoltan } 228*eb604411SBALATON Zoltan c->clen = 0; 229*eb604411SBALATON Zoltan stop = true; 230*eb604411SBALATON Zoltan } 231*eb604411SBALATON Zoltan } 232*eb604411SBALATON Zoltan } 233*eb604411SBALATON Zoltan 234*eb604411SBALATON Zoltan static void open_voice_out(ViaAC97State *s) 235*eb604411SBALATON Zoltan { 236*eb604411SBALATON Zoltan struct audsettings as = { 237*eb604411SBALATON Zoltan .freq = CODEC_REG(s, AC97_PCM_Front_DAC_Rate), 238*eb604411SBALATON Zoltan .nchannels = s->aur.type & BIT(4) ? 2 : 1, 239*eb604411SBALATON Zoltan .fmt = s->aur.type & BIT(5) ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_S8, 240*eb604411SBALATON Zoltan .endianness = 0, 241*eb604411SBALATON Zoltan }; 242*eb604411SBALATON Zoltan s->vo = AUD_open_out(&s->card, s->vo, "via-ac97.out", s, out_cb, &as); 243*eb604411SBALATON Zoltan } 244*eb604411SBALATON Zoltan 245*eb604411SBALATON Zoltan static uint64_t sgd_read(void *opaque, hwaddr addr, unsigned size) 246*eb604411SBALATON Zoltan { 247*eb604411SBALATON Zoltan ViaAC97State *s = opaque; 248*eb604411SBALATON Zoltan uint64_t val = 0; 249*eb604411SBALATON Zoltan 250*eb604411SBALATON Zoltan switch (addr) { 251*eb604411SBALATON Zoltan case 0: 252*eb604411SBALATON Zoltan val = s->aur.stat; 253*eb604411SBALATON Zoltan if (s->aur.type & CNTL_START) { 254*eb604411SBALATON Zoltan val |= STAT_TRIG; 255*eb604411SBALATON Zoltan } 256*eb604411SBALATON Zoltan break; 257*eb604411SBALATON Zoltan case 1: 258*eb604411SBALATON Zoltan val = s->aur.stat & STAT_PAUSED ? BIT(3) : 0; 259*eb604411SBALATON Zoltan break; 260*eb604411SBALATON Zoltan case 2: 261*eb604411SBALATON Zoltan val = s->aur.type; 262*eb604411SBALATON Zoltan break; 263*eb604411SBALATON Zoltan case 4: 264*eb604411SBALATON Zoltan val = s->aur.curr; 265*eb604411SBALATON Zoltan break; 266*eb604411SBALATON Zoltan case 0xc: 267*eb604411SBALATON Zoltan val = CLEN_LEN(&s->aur); 268*eb604411SBALATON Zoltan break; 269*eb604411SBALATON Zoltan case 0x10: 270*eb604411SBALATON Zoltan /* silence unimplemented log message that happens at every IRQ */ 271*eb604411SBALATON Zoltan break; 272*eb604411SBALATON Zoltan case 0x80: 273*eb604411SBALATON Zoltan val = s->ac97_cmd; 274*eb604411SBALATON Zoltan break; 275*eb604411SBALATON Zoltan case 0x84: 276*eb604411SBALATON Zoltan val = s->aur.stat & STAT_FLAG; 277*eb604411SBALATON Zoltan if (s->aur.stat & STAT_EOL) { 278*eb604411SBALATON Zoltan val |= BIT(4); 279*eb604411SBALATON Zoltan } 280*eb604411SBALATON Zoltan if (s->aur.stat & STAT_STOP) { 281*eb604411SBALATON Zoltan val |= BIT(8); 282*eb604411SBALATON Zoltan } 283*eb604411SBALATON Zoltan if (s->aur.stat & STAT_ACTIVE) { 284*eb604411SBALATON Zoltan val |= BIT(12); 285*eb604411SBALATON Zoltan } 286*eb604411SBALATON Zoltan break; 287*eb604411SBALATON Zoltan default: 288*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, "via-ac97: Unimplemented register read 0x%" 289*eb604411SBALATON Zoltan HWADDR_PRIx"\n", addr); 290*eb604411SBALATON Zoltan } 291*eb604411SBALATON Zoltan trace_via_ac97_sgd_read(addr, size, val); 292*eb604411SBALATON Zoltan return val; 293*eb604411SBALATON Zoltan } 294*eb604411SBALATON Zoltan 295*eb604411SBALATON Zoltan static void sgd_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) 296*eb604411SBALATON Zoltan { 297*eb604411SBALATON Zoltan ViaAC97State *s = opaque; 298*eb604411SBALATON Zoltan 299*eb604411SBALATON Zoltan trace_via_ac97_sgd_write(addr, size, val); 300*eb604411SBALATON Zoltan switch (addr) { 301*eb604411SBALATON Zoltan case 0: 302*eb604411SBALATON Zoltan if (val & STAT_STOP) { 303*eb604411SBALATON Zoltan s->aur.stat &= ~STAT_PAUSED; 304*eb604411SBALATON Zoltan } 305*eb604411SBALATON Zoltan if (val & STAT_EOL) { 306*eb604411SBALATON Zoltan s->aur.stat &= ~(STAT_EOL | STAT_PAUSED); 307*eb604411SBALATON Zoltan if (s->aur.type & STAT_EOL) { 308*eb604411SBALATON Zoltan pci_set_irq(&s->dev, 0); 309*eb604411SBALATON Zoltan } 310*eb604411SBALATON Zoltan } 311*eb604411SBALATON Zoltan if (val & STAT_FLAG) { 312*eb604411SBALATON Zoltan s->aur.stat &= ~(STAT_FLAG | STAT_PAUSED); 313*eb604411SBALATON Zoltan if (s->aur.type & STAT_FLAG) { 314*eb604411SBALATON Zoltan pci_set_irq(&s->dev, 0); 315*eb604411SBALATON Zoltan } 316*eb604411SBALATON Zoltan } 317*eb604411SBALATON Zoltan break; 318*eb604411SBALATON Zoltan case 1: 319*eb604411SBALATON Zoltan if (val & CNTL_START) { 320*eb604411SBALATON Zoltan AUD_set_active_out(s->vo, 1); 321*eb604411SBALATON Zoltan s->aur.stat = STAT_ACTIVE; 322*eb604411SBALATON Zoltan } 323*eb604411SBALATON Zoltan if (val & CNTL_TERM) { 324*eb604411SBALATON Zoltan AUD_set_active_out(s->vo, 0); 325*eb604411SBALATON Zoltan s->aur.stat &= ~(STAT_ACTIVE | STAT_PAUSED); 326*eb604411SBALATON Zoltan s->aur.clen = 0; 327*eb604411SBALATON Zoltan } 328*eb604411SBALATON Zoltan if (val & CNTL_PAUSE) { 329*eb604411SBALATON Zoltan AUD_set_active_out(s->vo, 0); 330*eb604411SBALATON Zoltan s->aur.stat &= ~STAT_ACTIVE; 331*eb604411SBALATON Zoltan s->aur.stat |= STAT_PAUSED; 332*eb604411SBALATON Zoltan } else if (!(val & CNTL_PAUSE) && (s->aur.stat & STAT_PAUSED)) { 333*eb604411SBALATON Zoltan AUD_set_active_out(s->vo, 1); 334*eb604411SBALATON Zoltan s->aur.stat |= STAT_ACTIVE; 335*eb604411SBALATON Zoltan s->aur.stat &= ~STAT_PAUSED; 336*eb604411SBALATON Zoltan } 337*eb604411SBALATON Zoltan break; 338*eb604411SBALATON Zoltan case 2: 339*eb604411SBALATON Zoltan { 340*eb604411SBALATON Zoltan uint32_t oldval = s->aur.type; 341*eb604411SBALATON Zoltan s->aur.type = val; 342*eb604411SBALATON Zoltan if ((oldval & 0x30) != (val & 0x30)) { 343*eb604411SBALATON Zoltan open_voice_out(s); 344*eb604411SBALATON Zoltan } 345*eb604411SBALATON Zoltan break; 346*eb604411SBALATON Zoltan } 347*eb604411SBALATON Zoltan case 4: 348*eb604411SBALATON Zoltan s->aur.base = val & ~1ULL; 349*eb604411SBALATON Zoltan s->aur.curr = s->aur.base; 350*eb604411SBALATON Zoltan break; 351*eb604411SBALATON Zoltan case 0x80: 352*eb604411SBALATON Zoltan if (val >> 30) { 353*eb604411SBALATON Zoltan /* we only have primary codec */ 354*eb604411SBALATON Zoltan break; 355*eb604411SBALATON Zoltan } 356*eb604411SBALATON Zoltan if (val & BIT(23)) { /* read reg */ 357*eb604411SBALATON Zoltan s->ac97_cmd = val & 0xc0ff0000ULL; 358*eb604411SBALATON Zoltan s->ac97_cmd |= codec_read(s, (val >> 16) & 0x7f); 359*eb604411SBALATON Zoltan s->ac97_cmd |= BIT(25); /* data valid */ 360*eb604411SBALATON Zoltan } else { 361*eb604411SBALATON Zoltan s->ac97_cmd = val & 0xc0ffffffULL; 362*eb604411SBALATON Zoltan codec_write(s, (val >> 16) & 0x7f, val); 363*eb604411SBALATON Zoltan } 364*eb604411SBALATON Zoltan break; 365*eb604411SBALATON Zoltan case 0xc: 366*eb604411SBALATON Zoltan case 0x84: 367*eb604411SBALATON Zoltan /* Read only */ 368*eb604411SBALATON Zoltan break; 369*eb604411SBALATON Zoltan default: 370*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, "via-ac97: Unimplemented register write 0x%" 371*eb604411SBALATON Zoltan HWADDR_PRIx"\n", addr); 372*eb604411SBALATON Zoltan } 373*eb604411SBALATON Zoltan } 374*eb604411SBALATON Zoltan 375*eb604411SBALATON Zoltan static const MemoryRegionOps sgd_ops = { 376*eb604411SBALATON Zoltan .read = sgd_read, 377*eb604411SBALATON Zoltan .write = sgd_write, 378*eb604411SBALATON Zoltan .endianness = DEVICE_LITTLE_ENDIAN, 379*eb604411SBALATON Zoltan }; 380*eb604411SBALATON Zoltan 381*eb604411SBALATON Zoltan static uint64_t fm_read(void *opaque, hwaddr addr, unsigned size) 382*eb604411SBALATON Zoltan { 383*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d\n", __func__, addr, size); 384*eb604411SBALATON Zoltan return 0; 385*eb604411SBALATON Zoltan } 386*eb604411SBALATON Zoltan 387*eb604411SBALATON Zoltan static void fm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) 388*eb604411SBALATON Zoltan { 389*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d <= 0x%"PRIX64"\n", 390*eb604411SBALATON Zoltan __func__, addr, size, val); 391*eb604411SBALATON Zoltan } 392*eb604411SBALATON Zoltan 393*eb604411SBALATON Zoltan static const MemoryRegionOps fm_ops = { 394*eb604411SBALATON Zoltan .read = fm_read, 395*eb604411SBALATON Zoltan .write = fm_write, 396*eb604411SBALATON Zoltan .endianness = DEVICE_LITTLE_ENDIAN, 397*eb604411SBALATON Zoltan }; 398*eb604411SBALATON Zoltan 399*eb604411SBALATON Zoltan static uint64_t midi_read(void *opaque, hwaddr addr, unsigned size) 400*eb604411SBALATON Zoltan { 401*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d\n", __func__, addr, size); 402*eb604411SBALATON Zoltan return 0; 403*eb604411SBALATON Zoltan } 404*eb604411SBALATON Zoltan 405*eb604411SBALATON Zoltan static void midi_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) 406*eb604411SBALATON Zoltan { 407*eb604411SBALATON Zoltan qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d <= 0x%"PRIX64"\n", 408*eb604411SBALATON Zoltan __func__, addr, size, val); 409*eb604411SBALATON Zoltan } 410*eb604411SBALATON Zoltan 411*eb604411SBALATON Zoltan static const MemoryRegionOps midi_ops = { 412*eb604411SBALATON Zoltan .read = midi_read, 413*eb604411SBALATON Zoltan .write = midi_write, 414*eb604411SBALATON Zoltan .endianness = DEVICE_LITTLE_ENDIAN, 415*eb604411SBALATON Zoltan }; 416*eb604411SBALATON Zoltan 417*eb604411SBALATON Zoltan static void via_ac97_reset(DeviceState *dev) 418*eb604411SBALATON Zoltan { 419*eb604411SBALATON Zoltan ViaAC97State *s = VIA_AC97(dev); 420*eb604411SBALATON Zoltan 421*eb604411SBALATON Zoltan codec_reset(s); 422*eb604411SBALATON Zoltan } 423657fae25SBALATON Zoltan 424a250e1c6SBALATON Zoltan static void via_ac97_realize(PCIDevice *pci_dev, Error **errp) 425657fae25SBALATON Zoltan { 426*eb604411SBALATON Zoltan ViaAC97State *s = VIA_AC97(pci_dev); 427*eb604411SBALATON Zoltan Object *o = OBJECT(s); 428*eb604411SBALATON Zoltan 429*eb604411SBALATON Zoltan /* 430*eb604411SBALATON Zoltan * Command register Bus Master bit is documented to be fixed at 0 but it's 431*eb604411SBALATON Zoltan * needed for PCI DMA to work in QEMU. The pegasos2 firmware writes 0 here 432*eb604411SBALATON Zoltan * and the AmigaOS driver writes 1 only enabling IO bit which works on 433*eb604411SBALATON Zoltan * real hardware. So set it here and fix it to 1 to allow DMA. 434*eb604411SBALATON Zoltan */ 435*eb604411SBALATON Zoltan pci_set_word(pci_dev->config + PCI_COMMAND, PCI_COMMAND_MASTER); 436*eb604411SBALATON Zoltan pci_set_word(pci_dev->wmask + PCI_COMMAND, PCI_COMMAND_IO); 437a250e1c6SBALATON Zoltan pci_set_word(pci_dev->config + PCI_STATUS, 438a250e1c6SBALATON Zoltan PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM); 439a250e1c6SBALATON Zoltan pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); 440*eb604411SBALATON Zoltan pci_set_byte(pci_dev->config + 0x40, 1); /* codec ready */ 441*eb604411SBALATON Zoltan 442*eb604411SBALATON Zoltan memory_region_init_io(&s->sgd, o, &sgd_ops, s, "via-ac97.sgd", 256); 443*eb604411SBALATON Zoltan pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->sgd); 444*eb604411SBALATON Zoltan memory_region_init_io(&s->fm, o, &fm_ops, s, "via-ac97.fm", 4); 445*eb604411SBALATON Zoltan pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->fm); 446*eb604411SBALATON Zoltan memory_region_init_io(&s->midi, o, &midi_ops, s, "via-ac97.midi", 4); 447*eb604411SBALATON Zoltan pci_register_bar(pci_dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->midi); 448*eb604411SBALATON Zoltan 449*eb604411SBALATON Zoltan AUD_register_card ("via-ac97", &s->card); 450657fae25SBALATON Zoltan } 451657fae25SBALATON Zoltan 452*eb604411SBALATON Zoltan static void via_ac97_exit(PCIDevice *dev) 453*eb604411SBALATON Zoltan { 454*eb604411SBALATON Zoltan ViaAC97State *s = VIA_AC97(dev); 455*eb604411SBALATON Zoltan 456*eb604411SBALATON Zoltan AUD_close_out(&s->card, s->vo); 457*eb604411SBALATON Zoltan AUD_remove_card(&s->card); 458*eb604411SBALATON Zoltan } 459*eb604411SBALATON Zoltan 460*eb604411SBALATON Zoltan static Property via_ac97_properties[] = { 461*eb604411SBALATON Zoltan DEFINE_AUDIO_PROPERTIES(ViaAC97State, card), 462*eb604411SBALATON Zoltan DEFINE_PROP_END_OF_LIST(), 463*eb604411SBALATON Zoltan }; 464*eb604411SBALATON Zoltan 465657fae25SBALATON Zoltan static void via_ac97_class_init(ObjectClass *klass, void *data) 466657fae25SBALATON Zoltan { 467657fae25SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(klass); 468657fae25SBALATON Zoltan PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 469657fae25SBALATON Zoltan 470657fae25SBALATON Zoltan k->realize = via_ac97_realize; 471*eb604411SBALATON Zoltan k->exit = via_ac97_exit; 472657fae25SBALATON Zoltan k->vendor_id = PCI_VENDOR_ID_VIA; 473657fae25SBALATON Zoltan k->device_id = PCI_DEVICE_ID_VIA_AC97; 474657fae25SBALATON Zoltan k->revision = 0x50; 475657fae25SBALATON Zoltan k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; 476*eb604411SBALATON Zoltan device_class_set_props(dc, via_ac97_properties); 477657fae25SBALATON Zoltan set_bit(DEVICE_CATEGORY_SOUND, dc->categories); 478a250e1c6SBALATON Zoltan dc->desc = "VIA AC97"; 479*eb604411SBALATON Zoltan dc->reset = via_ac97_reset; 480a250e1c6SBALATON Zoltan /* Reason: Part of a south bridge chip */ 481a250e1c6SBALATON Zoltan dc->user_creatable = false; 482657fae25SBALATON Zoltan } 483657fae25SBALATON Zoltan 484657fae25SBALATON Zoltan static const TypeInfo via_ac97_info = { 485657fae25SBALATON Zoltan .name = TYPE_VIA_AC97, 486657fae25SBALATON Zoltan .parent = TYPE_PCI_DEVICE, 487*eb604411SBALATON Zoltan .instance_size = sizeof(ViaAC97State), 488657fae25SBALATON Zoltan .class_init = via_ac97_class_init, 489657fae25SBALATON Zoltan .interfaces = (InterfaceInfo[]) { 490657fae25SBALATON Zoltan { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 491657fae25SBALATON Zoltan { }, 492657fae25SBALATON Zoltan }, 493657fae25SBALATON Zoltan }; 494657fae25SBALATON Zoltan 495a250e1c6SBALATON Zoltan static void via_mc97_realize(PCIDevice *pci_dev, Error **errp) 496657fae25SBALATON Zoltan { 497a250e1c6SBALATON Zoltan pci_set_word(pci_dev->config + PCI_COMMAND, 498a250e1c6SBALATON Zoltan PCI_COMMAND_INVALIDATE | PCI_COMMAND_VGA_PALETTE); 499a250e1c6SBALATON Zoltan pci_set_word(pci_dev->config + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); 500a250e1c6SBALATON Zoltan pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); 501657fae25SBALATON Zoltan } 502657fae25SBALATON Zoltan 503657fae25SBALATON Zoltan static void via_mc97_class_init(ObjectClass *klass, void *data) 504657fae25SBALATON Zoltan { 505657fae25SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(klass); 506657fae25SBALATON Zoltan PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 507657fae25SBALATON Zoltan 508657fae25SBALATON Zoltan k->realize = via_mc97_realize; 509657fae25SBALATON Zoltan k->vendor_id = PCI_VENDOR_ID_VIA; 510657fae25SBALATON Zoltan k->device_id = PCI_DEVICE_ID_VIA_MC97; 511657fae25SBALATON Zoltan k->class_id = PCI_CLASS_COMMUNICATION_OTHER; 512657fae25SBALATON Zoltan k->revision = 0x30; 513657fae25SBALATON Zoltan set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); 514a250e1c6SBALATON Zoltan dc->desc = "VIA MC97"; 515a250e1c6SBALATON Zoltan /* Reason: Part of a south bridge chip */ 516a250e1c6SBALATON Zoltan dc->user_creatable = false; 517657fae25SBALATON Zoltan } 518657fae25SBALATON Zoltan 519657fae25SBALATON Zoltan static const TypeInfo via_mc97_info = { 520657fae25SBALATON Zoltan .name = TYPE_VIA_MC97, 521657fae25SBALATON Zoltan .parent = TYPE_PCI_DEVICE, 522a250e1c6SBALATON Zoltan .instance_size = sizeof(PCIDevice), 523657fae25SBALATON Zoltan .class_init = via_mc97_class_init, 524657fae25SBALATON Zoltan .interfaces = (InterfaceInfo[]) { 525657fae25SBALATON Zoltan { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 526657fae25SBALATON Zoltan { }, 527657fae25SBALATON Zoltan }, 528657fae25SBALATON Zoltan }; 529657fae25SBALATON Zoltan 530657fae25SBALATON Zoltan static void via_ac97_register_types(void) 531657fae25SBALATON Zoltan { 532657fae25SBALATON Zoltan type_register_static(&via_ac97_info); 533657fae25SBALATON Zoltan type_register_static(&via_mc97_info); 534657fae25SBALATON Zoltan } 535657fae25SBALATON Zoltan 536657fae25SBALATON Zoltan type_init(via_ac97_register_types) 537