qemu/hw/audio/ac97.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006 InnoTek Systemberatung GmbH
   3 *
   4 * This file is part of VirtualBox Open Source Edition (OSE), as
   5 * available from http://www.virtualbox.org. This file is free software;
   6 * you can redistribute it and/or modify it under the terms of the GNU
   7 * General Public License as published by the Free Software Foundation,
   8 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
   9 * distribution. VirtualBox OSE is distributed in the hope that it will
  10 * be useful, but WITHOUT ANY WARRANTY of any kind.
  11 *
  12 * If you received this file as part of a commercial VirtualBox
  13 * distribution, then only the terms of your commercial VirtualBox
  14 * license agreement apply instead of the previous paragraph.
  15 *
  16 * Contributions after 2012-01-13 are licensed under the terms of the
  17 * GNU GPL, version 2 or (at your option) any later version.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "hw/audio/soundhw.h"
  22#include "audio/audio.h"
  23#include "hw/pci/pci.h"
  24#include "hw/qdev-properties.h"
  25#include "migration/vmstate.h"
  26#include "qemu/module.h"
  27#include "sysemu/dma.h"
  28#include "qom/object.h"
  29
  30enum {
  31    AC97_Reset                     = 0x00,
  32    AC97_Master_Volume_Mute        = 0x02,
  33    AC97_Headphone_Volume_Mute     = 0x04,
  34    AC97_Master_Volume_Mono_Mute   = 0x06,
  35    AC97_Master_Tone_RL            = 0x08,
  36    AC97_PC_BEEP_Volume_Mute       = 0x0A,
  37    AC97_Phone_Volume_Mute         = 0x0C,
  38    AC97_Mic_Volume_Mute           = 0x0E,
  39    AC97_Line_In_Volume_Mute       = 0x10,
  40    AC97_CD_Volume_Mute            = 0x12,
  41    AC97_Video_Volume_Mute         = 0x14,
  42    AC97_Aux_Volume_Mute           = 0x16,
  43    AC97_PCM_Out_Volume_Mute       = 0x18,
  44    AC97_Record_Select             = 0x1A,
  45    AC97_Record_Gain_Mute          = 0x1C,
  46    AC97_Record_Gain_Mic_Mute      = 0x1E,
  47    AC97_General_Purpose           = 0x20,
  48    AC97_3D_Control                = 0x22,
  49    AC97_AC_97_RESERVED            = 0x24,
  50    AC97_Powerdown_Ctrl_Stat       = 0x26,
  51    AC97_Extended_Audio_ID         = 0x28,
  52    AC97_Extended_Audio_Ctrl_Stat  = 0x2A,
  53    AC97_PCM_Front_DAC_Rate        = 0x2C,
  54    AC97_PCM_Surround_DAC_Rate     = 0x2E,
  55    AC97_PCM_LFE_DAC_Rate          = 0x30,
  56    AC97_PCM_LR_ADC_Rate           = 0x32,
  57    AC97_MIC_ADC_Rate              = 0x34,
  58    AC97_6Ch_Vol_C_LFE_Mute        = 0x36,
  59    AC97_6Ch_Vol_L_R_Surround_Mute = 0x38,
  60    AC97_Vendor_Reserved           = 0x58,
  61    AC97_Sigmatel_Analog           = 0x6c, /* We emulate a Sigmatel codec */
  62    AC97_Sigmatel_Dac2Invert       = 0x6e, /* We emulate a Sigmatel codec */
  63    AC97_Vendor_ID1                = 0x7c,
  64    AC97_Vendor_ID2                = 0x7e
  65};
  66
  67#define SOFT_VOLUME
  68#define SR_FIFOE 16             /* rwc */
  69#define SR_BCIS  8              /* rwc */
  70#define SR_LVBCI 4              /* rwc */
  71#define SR_CELV  2              /* ro */
  72#define SR_DCH   1              /* ro */
  73#define SR_VALID_MASK ((1 << 5) - 1)
  74#define SR_WCLEAR_MASK (SR_FIFOE | SR_BCIS | SR_LVBCI)
  75#define SR_RO_MASK (SR_DCH | SR_CELV)
  76#define SR_INT_MASK (SR_FIFOE | SR_BCIS | SR_LVBCI)
  77
  78#define CR_IOCE  16             /* rw */
  79#define CR_FEIE  8              /* rw */
  80#define CR_LVBIE 4              /* rw */
  81#define CR_RR    2              /* rw */
  82#define CR_RPBM  1              /* rw */
  83#define CR_VALID_MASK ((1 << 5) - 1)
  84#define CR_DONT_CLEAR_MASK (CR_IOCE | CR_FEIE | CR_LVBIE)
  85
  86#define GC_WR    4              /* rw */
  87#define GC_CR    2              /* rw */
  88#define GC_VALID_MASK ((1 << 6) - 1)
  89
  90#define GS_MD3   (1 << 17)      /* rw */
  91#define GS_AD3   (1 << 16)      /* rw */
  92#define GS_RCS   (1 << 15)      /* rwc */
  93#define GS_B3S12 (1 << 14)      /* ro */
  94#define GS_B2S12 (1 << 13)      /* ro */
  95#define GS_B1S12 (1 << 12)      /* ro */
  96#define GS_S1R1  (1 << 11)      /* rwc */
  97#define GS_S0R1  (1 << 10)      /* rwc */
  98#define GS_S1CR  (1 << 9)       /* ro */
  99#define GS_S0CR  (1 << 8)       /* ro */
 100#define GS_MINT  (1 << 7)       /* ro */
 101#define GS_POINT (1 << 6)       /* ro */
 102#define GS_PIINT (1 << 5)       /* ro */
 103#define GS_RSRVD ((1 << 4) | (1 << 3))
 104#define GS_MOINT (1 << 2)       /* ro */
 105#define GS_MIINT (1 << 1)       /* ro */
 106#define GS_GSCI  1              /* rwc */
 107#define GS_RO_MASK (GS_B3S12 | \
 108                    GS_B2S12 | \
 109                    GS_B1S12 | \
 110                    GS_S1CR  | \
 111                    GS_S0CR  | \
 112                    GS_MINT  | \
 113                    GS_POINT | \
 114                    GS_PIINT | \
 115                    GS_RSRVD | \
 116                    GS_MOINT | \
 117                    GS_MIINT)
 118#define GS_VALID_MASK ((1 << 18) - 1)
 119#define GS_WCLEAR_MASK (GS_RCS | GS_S1R1 | GS_S0R1 | GS_GSCI)
 120
 121#define BD_IOC (1 << 31)
 122#define BD_BUP (1 << 30)
 123
 124#define EACS_VRA 1
 125#define EACS_VRM 8
 126
 127#define MUTE_SHIFT 15
 128
 129#define TYPE_AC97 "AC97"
 130OBJECT_DECLARE_SIMPLE_TYPE(AC97LinkState, AC97)
 131
 132#define REC_MASK 7
 133enum {
 134    REC_MIC = 0,
 135    REC_CD,
 136    REC_VIDEO,
 137    REC_AUX,
 138    REC_LINE_IN,
 139    REC_STEREO_MIX,
 140    REC_MONO_MIX,
 141    REC_PHONE
 142};
 143
 144typedef struct BD {
 145    uint32_t addr;
 146    uint32_t ctl_len;
 147} BD;
 148
 149typedef struct AC97BusMasterRegs {
 150    uint32_t bdbar;             /* rw 0 */
 151    uint8_t civ;                /* ro 0 */
 152    uint8_t lvi;                /* rw 0 */
 153    uint16_t sr;                /* rw 1 */
 154    uint16_t picb;              /* ro 0 */
 155    uint8_t piv;                /* ro 0 */
 156    uint8_t cr;                 /* rw 0 */
 157    unsigned int bd_valid;
 158    BD bd;
 159} AC97BusMasterRegs;
 160
 161struct AC97LinkState {
 162    PCIDevice dev;
 163    QEMUSoundCard card;
 164    uint32_t glob_cnt;
 165    uint32_t glob_sta;
 166    uint32_t cas;
 167    uint32_t last_samp;
 168    AC97BusMasterRegs bm_regs[3];
 169    uint8_t mixer_data[256];
 170    SWVoiceIn *voice_pi;
 171    SWVoiceOut *voice_po;
 172    SWVoiceIn *voice_mc;
 173    int invalid_freq[3];
 174    uint8_t silence[128];
 175    int bup_flag;
 176    MemoryRegion io_nam;
 177    MemoryRegion io_nabm;
 178};
 179
 180enum {
 181    BUP_SET = 1,
 182    BUP_LAST = 2
 183};
 184
 185#ifdef DEBUG_AC97
 186#define dolog(...) AUD_log("ac97", __VA_ARGS__)
 187#else
 188#define dolog(...)
 189#endif
 190
 191#define MKREGS(prefix, start)                   \
 192enum {                                          \
 193    prefix ## _BDBAR = start,                   \
 194    prefix ## _CIV = start + 4,                 \
 195    prefix ## _LVI = start + 5,                 \
 196    prefix ## _SR = start + 6,                  \
 197    prefix ## _PICB = start + 8,                \
 198    prefix ## _PIV = start + 10,                \
 199    prefix ## _CR = start + 11                  \
 200}
 201
 202enum {
 203    PI_INDEX = 0,
 204    PO_INDEX,
 205    MC_INDEX,
 206    LAST_INDEX
 207};
 208
 209MKREGS(PI, PI_INDEX * 16);
 210MKREGS(PO, PO_INDEX * 16);
 211MKREGS(MC, MC_INDEX * 16);
 212
 213enum {
 214    GLOB_CNT = 0x2c,
 215    GLOB_STA = 0x30,
 216    CAS      = 0x34
 217};
 218
 219#define GET_BM(index) (((index) >> 4) & 3)
 220
 221static void po_callback(void *opaque, int free);
 222static void pi_callback(void *opaque, int avail);
 223static void mc_callback(void *opaque, int avail);
 224
 225static void fetch_bd(AC97LinkState *s, AC97BusMasterRegs *r)
 226{
 227    uint8_t b[8];
 228
 229    pci_dma_read(&s->dev, r->bdbar + r->civ * 8, b, 8);
 230    r->bd_valid = 1;
 231    r->bd.addr = le32_to_cpu(*(uint32_t *) &b[0]) & ~3;
 232    r->bd.ctl_len = le32_to_cpu(*(uint32_t *) &b[4]);
 233    r->picb = r->bd.ctl_len & 0xffff;
 234    dolog("bd %2d addr=0x%x ctl=0x%06x len=0x%x(%d bytes)\n",
 235          r->civ, r->bd.addr, r->bd.ctl_len >> 16,
 236          r->bd.ctl_len & 0xffff, (r->bd.ctl_len & 0xffff) << 1);
 237}
 238
 239static void update_sr(AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr)
 240{
 241    int event = 0;
 242    int level = 0;
 243    uint32_t new_mask = new_sr & SR_INT_MASK;
 244    uint32_t old_mask = r->sr & SR_INT_MASK;
 245    uint32_t masks[] = {GS_PIINT, GS_POINT, GS_MINT};
 246
 247    if (new_mask ^ old_mask) {
 248        /** @todo is IRQ deasserted when only one of status bits is cleared? */
 249        if (!new_mask) {
 250            event = 1;
 251            level = 0;
 252        } else {
 253            if ((new_mask & SR_LVBCI) && (r->cr & CR_LVBIE)) {
 254                event = 1;
 255                level = 1;
 256            }
 257            if ((new_mask & SR_BCIS) && (r->cr & CR_IOCE)) {
 258                event = 1;
 259                level = 1;
 260            }
 261        }
 262    }
 263
 264    r->sr = new_sr;
 265
 266    dolog("IOC%d LVB%d sr=0x%x event=%d level=%d\n",
 267          r->sr & SR_BCIS, r->sr & SR_LVBCI, r->sr, event, level);
 268
 269    if (!event) {
 270        return;
 271    }
 272
 273    if (level) {
 274        s->glob_sta |= masks[r - s->bm_regs];
 275        dolog("set irq level=1\n");
 276        pci_irq_assert(&s->dev);
 277    } else {
 278        s->glob_sta &= ~masks[r - s->bm_regs];
 279        dolog("set irq level=0\n");
 280        pci_irq_deassert(&s->dev);
 281    }
 282}
 283
 284static void voice_set_active(AC97LinkState *s, int bm_index, int on)
 285{
 286    switch (bm_index) {
 287    case PI_INDEX:
 288        AUD_set_active_in(s->voice_pi, on);
 289        break;
 290
 291    case PO_INDEX:
 292        AUD_set_active_out(s->voice_po, on);
 293        break;
 294
 295    case MC_INDEX:
 296        AUD_set_active_in(s->voice_mc, on);
 297        break;
 298
 299    default:
 300        AUD_log("ac97", "invalid bm_index(%d) in voice_set_active", bm_index);
 301        break;
 302    }
 303}
 304
 305static void reset_bm_regs(AC97LinkState *s, AC97BusMasterRegs *r)
 306{
 307    dolog("reset_bm_regs\n");
 308    r->bdbar = 0;
 309    r->civ = 0;
 310    r->lvi = 0;
 311    /** todo do we need to do that? */
 312    update_sr(s, r, SR_DCH);
 313    r->picb = 0;
 314    r->piv = 0;
 315    r->cr = r->cr & CR_DONT_CLEAR_MASK;
 316    r->bd_valid = 0;
 317
 318    voice_set_active(s, r - s->bm_regs, 0);
 319    memset(s->silence, 0, sizeof(s->silence));
 320}
 321
 322static void mixer_store(AC97LinkState *s, uint32_t i, uint16_t v)
 323{
 324    if (i + 2 > sizeof(s->mixer_data)) {
 325        dolog("mixer_store: index %d out of bounds %zd\n",
 326              i, sizeof(s->mixer_data));
 327        return;
 328    }
 329
 330    s->mixer_data[i + 0] = v & 0xff;
 331    s->mixer_data[i + 1] = v >> 8;
 332}
 333
 334static uint16_t mixer_load(AC97LinkState *s, uint32_t i)
 335{
 336    uint16_t val = 0xffff;
 337
 338    if (i + 2 > sizeof(s->mixer_data)) {
 339        dolog("mixer_load: index %d out of bounds %zd\n",
 340              i, sizeof(s->mixer_data));
 341    } else {
 342        val = s->mixer_data[i + 0] | (s->mixer_data[i + 1] << 8);
 343    }
 344
 345    return val;
 346}
 347
 348static void open_voice(AC97LinkState *s, int index, int freq)
 349{
 350    struct audsettings as;
 351
 352    as.freq = freq;
 353    as.nchannels = 2;
 354    as.fmt = AUDIO_FORMAT_S16;
 355    as.endianness = 0;
 356
 357    if (freq > 0) {
 358        s->invalid_freq[index] = 0;
 359        switch (index) {
 360        case PI_INDEX:
 361            s->voice_pi = AUD_open_in(
 362                &s->card,
 363                s->voice_pi,
 364                "ac97.pi",
 365                s,
 366                pi_callback,
 367                &as
 368                );
 369            break;
 370
 371        case PO_INDEX:
 372            s->voice_po = AUD_open_out(
 373                &s->card,
 374                s->voice_po,
 375                "ac97.po",
 376                s,
 377                po_callback,
 378                &as
 379                );
 380            break;
 381
 382        case MC_INDEX:
 383            s->voice_mc = AUD_open_in(
 384                &s->card,
 385                s->voice_mc,
 386                "ac97.mc",
 387                s,
 388                mc_callback,
 389                &as
 390                );
 391            break;
 392        }
 393    } else {
 394        s->invalid_freq[index] = freq;
 395        switch (index) {
 396        case PI_INDEX:
 397            AUD_close_in(&s->card, s->voice_pi);
 398            s->voice_pi = NULL;
 399            break;
 400
 401        case PO_INDEX:
 402            AUD_close_out(&s->card, s->voice_po);
 403            s->voice_po = NULL;
 404            break;
 405
 406        case MC_INDEX:
 407            AUD_close_in(&s->card, s->voice_mc);
 408            s->voice_mc = NULL;
 409            break;
 410        }
 411    }
 412}
 413
 414static void reset_voices(AC97LinkState *s, uint8_t active[LAST_INDEX])
 415{
 416    uint16_t freq;
 417
 418    freq = mixer_load(s, AC97_PCM_LR_ADC_Rate);
 419    open_voice(s, PI_INDEX, freq);
 420    AUD_set_active_in(s->voice_pi, active[PI_INDEX]);
 421
 422    freq = mixer_load(s, AC97_PCM_Front_DAC_Rate);
 423    open_voice(s, PO_INDEX, freq);
 424    AUD_set_active_out(s->voice_po, active[PO_INDEX]);
 425
 426    freq = mixer_load(s, AC97_MIC_ADC_Rate);
 427    open_voice(s, MC_INDEX, freq);
 428    AUD_set_active_in(s->voice_mc, active[MC_INDEX]);
 429}
 430
 431static void get_volume(uint16_t vol, uint16_t mask, int inverse,
 432                       int *mute, uint8_t *lvol, uint8_t *rvol)
 433{
 434    *mute = (vol >> MUTE_SHIFT) & 1;
 435    *rvol = (255 * (vol & mask)) / mask;
 436    *lvol = (255 * ((vol >> 8) & mask)) / mask;
 437
 438    if (inverse) {
 439        *rvol = 255 - *rvol;
 440        *lvol = 255 - *lvol;
 441    }
 442}
 443
 444static void update_combined_volume_out(AC97LinkState *s)
 445{
 446    uint8_t lvol, rvol, plvol, prvol;
 447    int mute, pmute;
 448
 449    get_volume(mixer_load(s, AC97_Master_Volume_Mute), 0x3f, 1,
 450               &mute, &lvol, &rvol);
 451    get_volume(mixer_load(s, AC97_PCM_Out_Volume_Mute), 0x1f, 1,
 452               &pmute, &plvol, &prvol);
 453
 454    mute = mute | pmute;
 455    lvol = (lvol * plvol) / 255;
 456    rvol = (rvol * prvol) / 255;
 457
 458    AUD_set_volume_out(s->voice_po, mute, lvol, rvol);
 459}
 460
 461static void update_volume_in(AC97LinkState *s)
 462{
 463    uint8_t lvol, rvol;
 464    int mute;
 465
 466    get_volume(mixer_load(s, AC97_Record_Gain_Mute), 0x0f, 0,
 467               &mute, &lvol, &rvol);
 468
 469    AUD_set_volume_in(s->voice_pi, mute, lvol, rvol);
 470}
 471
 472static void set_volume(AC97LinkState *s, int index, uint32_t val)
 473{
 474    switch (index) {
 475    case AC97_Master_Volume_Mute:
 476        val &= 0xbf3f;
 477        mixer_store(s, index, val);
 478        update_combined_volume_out(s);
 479        break;
 480    case AC97_PCM_Out_Volume_Mute:
 481        val &= 0x9f1f;
 482        mixer_store(s, index, val);
 483        update_combined_volume_out(s);
 484        break;
 485    case AC97_Record_Gain_Mute:
 486        val &= 0x8f0f;
 487        mixer_store(s, index, val);
 488        update_volume_in(s);
 489        break;
 490    }
 491}
 492
 493static void record_select(AC97LinkState *s, uint32_t val)
 494{
 495    uint8_t rs = val & REC_MASK;
 496    uint8_t ls = (val >> 8) & REC_MASK;
 497    mixer_store(s, AC97_Record_Select, rs | (ls << 8));
 498}
 499
 500static void mixer_reset(AC97LinkState *s)
 501{
 502    uint8_t active[LAST_INDEX];
 503
 504    dolog("mixer_reset\n");
 505    memset(s->mixer_data, 0, sizeof(s->mixer_data));
 506    memset(active, 0, sizeof(active));
 507    mixer_store(s, AC97_Reset, 0x0000); /* 6940 */
 508    mixer_store(s, AC97_Headphone_Volume_Mute, 0x0000);
 509    mixer_store(s, AC97_Master_Volume_Mono_Mute, 0x0000);
 510    mixer_store(s, AC97_Master_Tone_RL, 0x0000);
 511    mixer_store(s, AC97_PC_BEEP_Volume_Mute, 0x0000);
 512    mixer_store(s, AC97_Phone_Volume_Mute, 0x0000);
 513    mixer_store(s, AC97_Mic_Volume_Mute, 0x0000);
 514    mixer_store(s, AC97_Line_In_Volume_Mute, 0x0000);
 515    mixer_store(s, AC97_CD_Volume_Mute, 0x0000);
 516    mixer_store(s, AC97_Video_Volume_Mute, 0x0000);
 517    mixer_store(s, AC97_Aux_Volume_Mute, 0x0000);
 518    mixer_store(s, AC97_Record_Gain_Mic_Mute, 0x0000);
 519    mixer_store(s, AC97_General_Purpose, 0x0000);
 520    mixer_store(s, AC97_3D_Control, 0x0000);
 521    mixer_store(s, AC97_Powerdown_Ctrl_Stat, 0x000f);
 522
 523    /*
 524     * Sigmatel 9700 (STAC9700)
 525     */
 526    mixer_store(s, AC97_Vendor_ID1, 0x8384);
 527    mixer_store(s, AC97_Vendor_ID2, 0x7600); /* 7608 */
 528
 529    mixer_store(s, AC97_Extended_Audio_ID, 0x0809);
 530    mixer_store(s, AC97_Extended_Audio_Ctrl_Stat, 0x0009);
 531    mixer_store(s, AC97_PCM_Front_DAC_Rate, 0xbb80);
 532    mixer_store(s, AC97_PCM_Surround_DAC_Rate, 0xbb80);
 533    mixer_store(s, AC97_PCM_LFE_DAC_Rate, 0xbb80);
 534    mixer_store(s, AC97_PCM_LR_ADC_Rate, 0xbb80);
 535    mixer_store(s, AC97_MIC_ADC_Rate, 0xbb80);
 536
 537    record_select(s, 0);
 538    set_volume(s, AC97_Master_Volume_Mute, 0x8000);
 539    set_volume(s, AC97_PCM_Out_Volume_Mute, 0x8808);
 540    set_volume(s, AC97_Record_Gain_Mute, 0x8808);
 541
 542    reset_voices(s, active);
 543}
 544
 545/**
 546 * Native audio mixer
 547 * I/O Reads
 548 */
 549static uint32_t nam_readb(void *opaque, uint32_t addr)
 550{
 551    AC97LinkState *s = opaque;
 552    dolog("U nam readb 0x%x\n", addr);
 553    s->cas = 0;
 554    return ~0U;
 555}
 556
 557static uint32_t nam_readw(void *opaque, uint32_t addr)
 558{
 559    AC97LinkState *s = opaque;
 560    s->cas = 0;
 561    return mixer_load(s, addr);
 562}
 563
 564static uint32_t nam_readl(void *opaque, uint32_t addr)
 565{
 566    AC97LinkState *s = opaque;
 567    dolog("U nam readl 0x%x\n", addr);
 568    s->cas = 0;
 569    return ~0U;
 570}
 571
 572/**
 573 * Native audio mixer
 574 * I/O Writes
 575 */
 576static void nam_writeb(void *opaque, uint32_t addr, uint32_t val)
 577{
 578    AC97LinkState *s = opaque;
 579    dolog("U nam writeb 0x%x <- 0x%x\n", addr, val);
 580    s->cas = 0;
 581}
 582
 583static void nam_writew(void *opaque, uint32_t addr, uint32_t val)
 584{
 585    AC97LinkState *s = opaque;
 586
 587    s->cas = 0;
 588    switch (addr) {
 589    case AC97_Reset:
 590        mixer_reset(s);
 591        break;
 592    case AC97_Powerdown_Ctrl_Stat:
 593        val &= ~0x800f;
 594        val |= mixer_load(s, addr) & 0xf;
 595        mixer_store(s, addr, val);
 596        break;
 597    case AC97_PCM_Out_Volume_Mute:
 598    case AC97_Master_Volume_Mute:
 599    case AC97_Record_Gain_Mute:
 600        set_volume(s, addr, val);
 601        break;
 602    case AC97_Record_Select:
 603        record_select(s, val);
 604        break;
 605    case AC97_Vendor_ID1:
 606    case AC97_Vendor_ID2:
 607        dolog("Attempt to write vendor ID to 0x%x\n", val);
 608        break;
 609    case AC97_Extended_Audio_ID:
 610        dolog("Attempt to write extended audio ID to 0x%x\n", val);
 611        break;
 612    case AC97_Extended_Audio_Ctrl_Stat:
 613        if (!(val & EACS_VRA)) {
 614            mixer_store(s, AC97_PCM_Front_DAC_Rate, 0xbb80);
 615            mixer_store(s, AC97_PCM_LR_ADC_Rate,    0xbb80);
 616            open_voice(s, PI_INDEX, 48000);
 617            open_voice(s, PO_INDEX, 48000);
 618        }
 619        if (!(val & EACS_VRM)) {
 620            mixer_store(s, AC97_MIC_ADC_Rate, 0xbb80);
 621            open_voice(s, MC_INDEX, 48000);
 622        }
 623        dolog("Setting extended audio control to 0x%x\n", val);
 624        mixer_store(s, AC97_Extended_Audio_Ctrl_Stat, val);
 625        break;
 626    case AC97_PCM_Front_DAC_Rate:
 627        if (mixer_load(s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) {
 628            mixer_store(s, addr, val);
 629            dolog("Set front DAC rate to %d\n", val);
 630            open_voice(s, PO_INDEX, val);
 631        } else {
 632            dolog("Attempt to set front DAC rate to %d, but VRA is not set\n",
 633                  val);
 634        }
 635        break;
 636    case AC97_MIC_ADC_Rate:
 637        if (mixer_load(s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM) {
 638            mixer_store(s, addr, val);
 639            dolog("Set MIC ADC rate to %d\n", val);
 640            open_voice(s, MC_INDEX, val);
 641        } else {
 642            dolog("Attempt to set MIC ADC rate to %d, but VRM is not set\n",
 643                  val);
 644        }
 645        break;
 646    case AC97_PCM_LR_ADC_Rate:
 647        if (mixer_load(s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) {
 648            mixer_store(s, addr, val);
 649            dolog("Set front LR ADC rate to %d\n", val);
 650            open_voice(s, PI_INDEX, val);
 651        } else {
 652            dolog("Attempt to set LR ADC rate to %d, but VRA is not set\n",
 653                  val);
 654        }
 655        break;
 656    case AC97_Headphone_Volume_Mute:
 657    case AC97_Master_Volume_Mono_Mute:
 658    case AC97_Master_Tone_RL:
 659    case AC97_PC_BEEP_Volume_Mute:
 660    case AC97_Phone_Volume_Mute:
 661    case AC97_Mic_Volume_Mute:
 662    case AC97_Line_In_Volume_Mute:
 663    case AC97_CD_Volume_Mute:
 664    case AC97_Video_Volume_Mute:
 665    case AC97_Aux_Volume_Mute:
 666    case AC97_Record_Gain_Mic_Mute:
 667    case AC97_General_Purpose:
 668    case AC97_3D_Control:
 669    case AC97_Sigmatel_Analog:
 670    case AC97_Sigmatel_Dac2Invert:
 671        /* None of the features in these regs are emulated, so they are RO */
 672        break;
 673    default:
 674        dolog("U nam writew 0x%x <- 0x%x\n", addr, val);
 675        mixer_store(s, addr, val);
 676        break;
 677    }
 678}
 679
 680static void nam_writel(void *opaque, uint32_t addr, uint32_t val)
 681{
 682    AC97LinkState *s = opaque;
 683    dolog("U nam writel 0x%x <- 0x%x\n", addr, val);
 684    s->cas = 0;
 685}
 686
 687/**
 688 * Native audio bus master
 689 * I/O Reads
 690 */
 691static uint32_t nabm_readb(void *opaque, uint32_t addr)
 692{
 693    AC97LinkState *s = opaque;
 694    AC97BusMasterRegs *r = NULL;
 695    uint32_t val = ~0U;
 696
 697    switch (addr) {
 698    case CAS:
 699        dolog("CAS %d\n", s->cas);
 700        val = s->cas;
 701        s->cas = 1;
 702        break;
 703    case PI_CIV:
 704    case PO_CIV:
 705    case MC_CIV:
 706        r = &s->bm_regs[GET_BM(addr)];
 707        val = r->civ;
 708        dolog("CIV[%d] -> 0x%x\n", GET_BM(addr), val);
 709        break;
 710    case PI_LVI:
 711    case PO_LVI:
 712    case MC_LVI:
 713        r = &s->bm_regs[GET_BM(addr)];
 714        val = r->lvi;
 715        dolog("LVI[%d] -> 0x%x\n", GET_BM(addr), val);
 716        break;
 717    case PI_PIV:
 718    case PO_PIV:
 719    case MC_PIV:
 720        r = &s->bm_regs[GET_BM(addr)];
 721        val = r->piv;
 722        dolog("PIV[%d] -> 0x%x\n", GET_BM(addr), val);
 723        break;
 724    case PI_CR:
 725    case PO_CR:
 726    case MC_CR:
 727        r = &s->bm_regs[GET_BM(addr)];
 728        val = r->cr;
 729        dolog("CR[%d] -> 0x%x\n", GET_BM(addr), val);
 730        break;
 731    case PI_SR:
 732    case PO_SR:
 733    case MC_SR:
 734        r = &s->bm_regs[GET_BM(addr)];
 735        val = r->sr & 0xff;
 736        dolog("SRb[%d] -> 0x%x\n", GET_BM(addr), val);
 737        break;
 738    default:
 739        dolog("U nabm readb 0x%x -> 0x%x\n", addr, val);
 740        break;
 741    }
 742    return val;
 743}
 744
 745static uint32_t nabm_readw(void *opaque, uint32_t addr)
 746{
 747    AC97LinkState *s = opaque;
 748    AC97BusMasterRegs *r = NULL;
 749    uint32_t val = ~0U;
 750
 751    switch (addr) {
 752    case PI_SR:
 753    case PO_SR:
 754    case MC_SR:
 755        r = &s->bm_regs[GET_BM(addr)];
 756        val = r->sr;
 757        dolog("SR[%d] -> 0x%x\n", GET_BM(addr), val);
 758        break;
 759    case PI_PICB:
 760    case PO_PICB:
 761    case MC_PICB:
 762        r = &s->bm_regs[GET_BM(addr)];
 763        val = r->picb;
 764        dolog("PICB[%d] -> 0x%x\n", GET_BM(addr), val);
 765        break;
 766    default:
 767        dolog("U nabm readw 0x%x -> 0x%x\n", addr, val);
 768        break;
 769    }
 770    return val;
 771}
 772
 773static uint32_t nabm_readl(void *opaque, uint32_t addr)
 774{
 775    AC97LinkState *s = opaque;
 776    AC97BusMasterRegs *r = NULL;
 777    uint32_t val = ~0U;
 778
 779    switch (addr) {
 780    case PI_BDBAR:
 781    case PO_BDBAR:
 782    case MC_BDBAR:
 783        r = &s->bm_regs[GET_BM(addr)];
 784        val = r->bdbar;
 785        dolog("BMADDR[%d] -> 0x%x\n", GET_BM(addr), val);
 786        break;
 787    case PI_CIV:
 788    case PO_CIV:
 789    case MC_CIV:
 790        r = &s->bm_regs[GET_BM(addr)];
 791        val = r->civ | (r->lvi << 8) | (r->sr << 16);
 792        dolog("CIV LVI SR[%d] -> 0x%x, 0x%x, 0x%x\n", GET_BM(addr),
 793               r->civ, r->lvi, r->sr);
 794        break;
 795    case PI_PICB:
 796    case PO_PICB:
 797    case MC_PICB:
 798        r = &s->bm_regs[GET_BM(addr)];
 799        val = r->picb | (r->piv << 16) | (r->cr << 24);
 800        dolog("PICB PIV CR[%d] -> 0x%x 0x%x 0x%x 0x%x\n", GET_BM(addr),
 801               val, r->picb, r->piv, r->cr);
 802        break;
 803    case GLOB_CNT:
 804        val = s->glob_cnt;
 805        dolog("glob_cnt -> 0x%x\n", val);
 806        break;
 807    case GLOB_STA:
 808        val = s->glob_sta | GS_S0CR;
 809        dolog("glob_sta -> 0x%x\n", val);
 810        break;
 811    default:
 812        dolog("U nabm readl 0x%x -> 0x%x\n", addr, val);
 813        break;
 814    }
 815    return val;
 816}
 817
 818/**
 819 * Native audio bus master
 820 * I/O Writes
 821 */
 822static void nabm_writeb(void *opaque, uint32_t addr, uint32_t val)
 823{
 824    AC97LinkState *s = opaque;
 825    AC97BusMasterRegs *r = NULL;
 826
 827    switch (addr) {
 828    case PI_LVI:
 829    case PO_LVI:
 830    case MC_LVI:
 831        r = &s->bm_regs[GET_BM(addr)];
 832        if ((r->cr & CR_RPBM) && (r->sr & SR_DCH)) {
 833            r->sr &= ~(SR_DCH | SR_CELV);
 834            r->civ = r->piv;
 835            r->piv = (r->piv + 1) % 32;
 836            fetch_bd(s, r);
 837        }
 838        r->lvi = val % 32;
 839        dolog("LVI[%d] <- 0x%x\n", GET_BM(addr), val);
 840        break;
 841    case PI_CR:
 842    case PO_CR:
 843    case MC_CR:
 844        r = &s->bm_regs[GET_BM(addr)];
 845        if (val & CR_RR) {
 846            reset_bm_regs(s, r);
 847        } else {
 848            r->cr = val & CR_VALID_MASK;
 849            if (!(r->cr & CR_RPBM)) {
 850                voice_set_active(s, r - s->bm_regs, 0);
 851                r->sr |= SR_DCH;
 852            } else {
 853                r->civ = r->piv;
 854                r->piv = (r->piv + 1) % 32;
 855                fetch_bd(s, r);
 856                r->sr &= ~SR_DCH;
 857                voice_set_active(s, r - s->bm_regs, 1);
 858            }
 859        }
 860        dolog("CR[%d] <- 0x%x (cr 0x%x)\n", GET_BM(addr), val, r->cr);
 861        break;
 862    case PI_SR:
 863    case PO_SR:
 864    case MC_SR:
 865        r = &s->bm_regs[GET_BM(addr)];
 866        r->sr |= val & ~(SR_RO_MASK | SR_WCLEAR_MASK);
 867        update_sr(s, r, r->sr & ~(val & SR_WCLEAR_MASK));
 868        dolog("SR[%d] <- 0x%x (sr 0x%x)\n", GET_BM(addr), val, r->sr);
 869        break;
 870    default:
 871        dolog("U nabm writeb 0x%x <- 0x%x\n", addr, val);
 872        break;
 873    }
 874}
 875
 876static void nabm_writew(void *opaque, uint32_t addr, uint32_t val)
 877{
 878    AC97LinkState *s = opaque;
 879    AC97BusMasterRegs *r = NULL;
 880
 881    switch (addr) {
 882    case PI_SR:
 883    case PO_SR:
 884    case MC_SR:
 885        r = &s->bm_regs[GET_BM(addr)];
 886        r->sr |= val & ~(SR_RO_MASK | SR_WCLEAR_MASK);
 887        update_sr(s, r, r->sr & ~(val & SR_WCLEAR_MASK));
 888        dolog("SR[%d] <- 0x%x (sr 0x%x)\n", GET_BM(addr), val, r->sr);
 889        break;
 890    default:
 891        dolog("U nabm writew 0x%x <- 0x%x\n", addr, val);
 892        break;
 893    }
 894}
 895
 896static void nabm_writel(void *opaque, uint32_t addr, uint32_t val)
 897{
 898    AC97LinkState *s = opaque;
 899    AC97BusMasterRegs *r = NULL;
 900
 901    switch (addr) {
 902    case PI_BDBAR:
 903    case PO_BDBAR:
 904    case MC_BDBAR:
 905        r = &s->bm_regs[GET_BM(addr)];
 906        r->bdbar = val & ~3;
 907        dolog("BDBAR[%d] <- 0x%x (bdbar 0x%x)\n", GET_BM(addr), val, r->bdbar);
 908        break;
 909    case GLOB_CNT:
 910        /* TODO: Handle WR or CR being set (warm/cold reset requests) */
 911        if (!(val & (GC_WR | GC_CR))) {
 912            s->glob_cnt = val & GC_VALID_MASK;
 913        }
 914        dolog("glob_cnt <- 0x%x (glob_cnt 0x%x)\n", val, s->glob_cnt);
 915        break;
 916    case GLOB_STA:
 917        s->glob_sta &= ~(val & GS_WCLEAR_MASK);
 918        s->glob_sta |= (val & ~(GS_WCLEAR_MASK | GS_RO_MASK)) & GS_VALID_MASK;
 919        dolog("glob_sta <- 0x%x (glob_sta 0x%x)\n", val, s->glob_sta);
 920        break;
 921    default:
 922        dolog("U nabm writel 0x%x <- 0x%x\n", addr, val);
 923        break;
 924    }
 925}
 926
 927static int write_audio(AC97LinkState *s, AC97BusMasterRegs *r,
 928                       int max, int *stop)
 929{
 930    uint8_t tmpbuf[4096];
 931    uint32_t addr = r->bd.addr;
 932    uint32_t temp = r->picb << 1;
 933    uint32_t written = 0;
 934    int to_copy = 0;
 935    temp = MIN(temp, max);
 936
 937    if (!temp) {
 938        *stop = 1;
 939        return 0;
 940    }
 941
 942    while (temp) {
 943        int copied;
 944        to_copy = MIN(temp, sizeof(tmpbuf));
 945        pci_dma_read(&s->dev, addr, tmpbuf, to_copy);
 946        copied = AUD_write(s->voice_po, tmpbuf, to_copy);
 947        dolog("write_audio max=%x to_copy=%x copied=%x\n",
 948              max, to_copy, copied);
 949        if (!copied) {
 950            *stop = 1;
 951            break;
 952        }
 953        temp -= copied;
 954        addr += copied;
 955        written += copied;
 956    }
 957
 958    if (!temp) {
 959        if (to_copy < 4) {
 960            dolog("whoops\n");
 961            s->last_samp = 0;
 962        } else {
 963            s->last_samp = *(uint32_t *)&tmpbuf[to_copy - 4];
 964        }
 965    }
 966
 967    r->bd.addr = addr;
 968    return written;
 969}
 970
 971static void write_bup(AC97LinkState *s, int elapsed)
 972{
 973    dolog("write_bup\n");
 974    if (!(s->bup_flag & BUP_SET)) {
 975        if (s->bup_flag & BUP_LAST) {
 976            int i;
 977            uint8_t *p = s->silence;
 978            for (i = 0; i < sizeof(s->silence) / 4; i++, p += 4) {
 979                *(uint32_t *) p = s->last_samp;
 980            }
 981        } else {
 982            memset(s->silence, 0, sizeof(s->silence));
 983        }
 984        s->bup_flag |= BUP_SET;
 985    }
 986
 987    while (elapsed) {
 988        int temp = MIN(elapsed, sizeof(s->silence));
 989        while (temp) {
 990            int copied = AUD_write(s->voice_po, s->silence, temp);
 991            if (!copied) {
 992                return;
 993            }
 994            temp -= copied;
 995            elapsed -= copied;
 996        }
 997    }
 998}
 999
1000static int read_audio(AC97LinkState *s, AC97BusMasterRegs *r,
1001                      int max, int *stop)
1002{
1003    uint8_t tmpbuf[4096];
1004    uint32_t addr = r->bd.addr;
1005    uint32_t temp = r->picb << 1;
1006    uint32_t nread = 0;
1007    int to_copy = 0;
1008    SWVoiceIn *voice = (r - s->bm_regs) == MC_INDEX ? s->voice_mc : s->voice_pi;
1009
1010    temp = MIN(temp, max);
1011
1012    if (!temp) {
1013        *stop = 1;
1014        return 0;
1015    }
1016
1017    while (temp) {
1018        int acquired;
1019        to_copy = MIN(temp, sizeof(tmpbuf));
1020        acquired = AUD_read(voice, tmpbuf, to_copy);
1021        if (!acquired) {
1022            *stop = 1;
1023            break;
1024        }
1025        pci_dma_write(&s->dev, addr, tmpbuf, acquired);
1026        temp -= acquired;
1027        addr += acquired;
1028        nread += acquired;
1029    }
1030
1031    r->bd.addr = addr;
1032    return nread;
1033}
1034
1035static void transfer_audio(AC97LinkState *s, int index, int elapsed)
1036{
1037    AC97BusMasterRegs *r = &s->bm_regs[index];
1038    int stop = 0;
1039
1040    if (s->invalid_freq[index]) {
1041        AUD_log("ac97", "attempt to use voice %d with invalid frequency %d\n",
1042                index, s->invalid_freq[index]);
1043        return;
1044    }
1045
1046    if (r->sr & SR_DCH) {
1047        if (r->cr & CR_RPBM) {
1048            switch (index) {
1049            case PO_INDEX:
1050                write_bup(s, elapsed);
1051                break;
1052            }
1053        }
1054        return;
1055    }
1056
1057    while ((elapsed >> 1) && !stop) {
1058        int temp;
1059
1060        if (!r->bd_valid) {
1061            dolog("invalid bd\n");
1062            fetch_bd(s, r);
1063        }
1064
1065        if (!r->picb) {
1066            dolog("fresh bd %d is empty 0x%x 0x%x\n",
1067                  r->civ, r->bd.addr, r->bd.ctl_len);
1068            if (r->civ == r->lvi) {
1069                r->sr |= SR_DCH; /* CELV? */
1070                s->bup_flag = 0;
1071                break;
1072            }
1073            r->sr &= ~SR_CELV;
1074            r->civ = r->piv;
1075            r->piv = (r->piv + 1) % 32;
1076            fetch_bd(s, r);
1077            return;
1078        }
1079
1080        switch (index) {
1081        case PO_INDEX:
1082            temp = write_audio(s, r, elapsed, &stop);
1083            elapsed -= temp;
1084            r->picb -= (temp >> 1);
1085            break;
1086
1087        case PI_INDEX:
1088        case MC_INDEX:
1089            temp = read_audio(s, r, elapsed, &stop);
1090            elapsed -= temp;
1091            r->picb -= (temp >> 1);
1092            break;
1093        }
1094
1095        if (!r->picb) {
1096            uint32_t new_sr = r->sr & ~SR_CELV;
1097
1098            if (r->bd.ctl_len & BD_IOC) {
1099                new_sr |= SR_BCIS;
1100            }
1101
1102            if (r->civ == r->lvi) {
1103                dolog("Underrun civ (%d) == lvi (%d)\n", r->civ, r->lvi);
1104
1105                new_sr |= SR_LVBCI | SR_DCH | SR_CELV;
1106                stop = 1;
1107                s->bup_flag = (r->bd.ctl_len & BD_BUP) ? BUP_LAST : 0;
1108            } else {
1109                r->civ = r->piv;
1110                r->piv = (r->piv + 1) % 32;
1111                fetch_bd(s, r);
1112            }
1113
1114            update_sr(s, r, new_sr);
1115        }
1116    }
1117}
1118
1119static void pi_callback(void *opaque, int avail)
1120{
1121    transfer_audio(opaque, PI_INDEX, avail);
1122}
1123
1124static void mc_callback(void *opaque, int avail)
1125{
1126    transfer_audio(opaque, MC_INDEX, avail);
1127}
1128
1129static void po_callback(void *opaque, int free)
1130{
1131    transfer_audio(opaque, PO_INDEX, free);
1132}
1133
1134static const VMStateDescription vmstate_ac97_bm_regs = {
1135    .name = "ac97_bm_regs",
1136    .version_id = 1,
1137    .minimum_version_id = 1,
1138    .fields = (VMStateField[]) {
1139        VMSTATE_UINT32(bdbar, AC97BusMasterRegs),
1140        VMSTATE_UINT8(civ, AC97BusMasterRegs),
1141        VMSTATE_UINT8(lvi, AC97BusMasterRegs),
1142        VMSTATE_UINT16(sr, AC97BusMasterRegs),
1143        VMSTATE_UINT16(picb, AC97BusMasterRegs),
1144        VMSTATE_UINT8(piv, AC97BusMasterRegs),
1145        VMSTATE_UINT8(cr, AC97BusMasterRegs),
1146        VMSTATE_UINT32(bd_valid, AC97BusMasterRegs),
1147        VMSTATE_UINT32(bd.addr, AC97BusMasterRegs),
1148        VMSTATE_UINT32(bd.ctl_len, AC97BusMasterRegs),
1149        VMSTATE_END_OF_LIST()
1150    }
1151};
1152
1153static int ac97_post_load(void *opaque, int version_id)
1154{
1155    uint8_t active[LAST_INDEX];
1156    AC97LinkState *s = opaque;
1157
1158    record_select(s, mixer_load(s, AC97_Record_Select));
1159    set_volume(s, AC97_Master_Volume_Mute,
1160               mixer_load(s, AC97_Master_Volume_Mute));
1161    set_volume(s, AC97_PCM_Out_Volume_Mute,
1162               mixer_load(s, AC97_PCM_Out_Volume_Mute));
1163    set_volume(s, AC97_Record_Gain_Mute,
1164               mixer_load(s, AC97_Record_Gain_Mute));
1165
1166    active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM);
1167    active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM);
1168    active[MC_INDEX] = !!(s->bm_regs[MC_INDEX].cr & CR_RPBM);
1169    reset_voices(s, active);
1170
1171    s->bup_flag = 0;
1172    s->last_samp = 0;
1173    return 0;
1174}
1175
1176static bool is_version_2(void *opaque, int version_id)
1177{
1178    return version_id == 2;
1179}
1180
1181static const VMStateDescription vmstate_ac97 = {
1182    .name = "ac97",
1183    .version_id = 3,
1184    .minimum_version_id = 2,
1185    .post_load = ac97_post_load,
1186    .fields = (VMStateField[]) {
1187        VMSTATE_PCI_DEVICE(dev, AC97LinkState),
1188        VMSTATE_UINT32(glob_cnt, AC97LinkState),
1189        VMSTATE_UINT32(glob_sta, AC97LinkState),
1190        VMSTATE_UINT32(cas, AC97LinkState),
1191        VMSTATE_STRUCT_ARRAY(bm_regs, AC97LinkState, 3, 1,
1192                             vmstate_ac97_bm_regs, AC97BusMasterRegs),
1193        VMSTATE_BUFFER(mixer_data, AC97LinkState),
1194        VMSTATE_UNUSED_TEST(is_version_2, 3),
1195        VMSTATE_END_OF_LIST()
1196    }
1197};
1198
1199static uint64_t nam_read(void *opaque, hwaddr addr, unsigned size)
1200{
1201    if ((addr / size) > 256) {
1202        return -1;
1203    }
1204
1205    switch (size) {
1206    case 1:
1207        return nam_readb(opaque, addr);
1208    case 2:
1209        return nam_readw(opaque, addr);
1210    case 4:
1211        return nam_readl(opaque, addr);
1212    default:
1213        return -1;
1214    }
1215}
1216
1217static void nam_write(void *opaque, hwaddr addr, uint64_t val,
1218                      unsigned size)
1219{
1220    if ((addr / size) > 256) {
1221        return;
1222    }
1223
1224    switch (size) {
1225    case 1:
1226        nam_writeb(opaque, addr, val);
1227        break;
1228    case 2:
1229        nam_writew(opaque, addr, val);
1230        break;
1231    case 4:
1232        nam_writel(opaque, addr, val);
1233        break;
1234    }
1235}
1236
1237static const MemoryRegionOps ac97_io_nam_ops = {
1238    .read = nam_read,
1239    .write = nam_write,
1240    .impl = {
1241        .min_access_size = 1,
1242        .max_access_size = 4,
1243    },
1244    .endianness = DEVICE_LITTLE_ENDIAN,
1245};
1246
1247static uint64_t nabm_read(void *opaque, hwaddr addr, unsigned size)
1248{
1249    if ((addr / size) > 64) {
1250        return -1;
1251    }
1252
1253    switch (size) {
1254    case 1:
1255        return nabm_readb(opaque, addr);
1256    case 2:
1257        return nabm_readw(opaque, addr);
1258    case 4:
1259        return nabm_readl(opaque, addr);
1260    default:
1261        return -1;
1262    }
1263}
1264
1265static void nabm_write(void *opaque, hwaddr addr, uint64_t val,
1266                       unsigned size)
1267{
1268    if ((addr / size) > 64) {
1269        return;
1270    }
1271
1272    switch (size) {
1273    case 1:
1274        nabm_writeb(opaque, addr, val);
1275        break;
1276    case 2:
1277        nabm_writew(opaque, addr, val);
1278        break;
1279    case 4:
1280        nabm_writel(opaque, addr, val);
1281        break;
1282    }
1283}
1284
1285
1286static const MemoryRegionOps ac97_io_nabm_ops = {
1287    .read = nabm_read,
1288    .write = nabm_write,
1289    .impl = {
1290        .min_access_size = 1,
1291        .max_access_size = 4,
1292    },
1293    .endianness = DEVICE_LITTLE_ENDIAN,
1294};
1295
1296static void ac97_on_reset(DeviceState *dev)
1297{
1298    AC97LinkState *s = container_of(dev, AC97LinkState, dev.qdev);
1299
1300    reset_bm_regs(s, &s->bm_regs[0]);
1301    reset_bm_regs(s, &s->bm_regs[1]);
1302    reset_bm_regs(s, &s->bm_regs[2]);
1303
1304    /*
1305     * Reset the mixer too. The Windows XP driver seems to rely on
1306     * this. At least it wants to read the vendor id before it resets
1307     * the codec manually.
1308     */
1309    mixer_reset(s);
1310}
1311
1312static void ac97_realize(PCIDevice *dev, Error **errp)
1313{
1314    AC97LinkState *s = AC97(dev);
1315    uint8_t *c = s->dev.config;
1316
1317    /* TODO: no need to override */
1318    c[PCI_COMMAND] = 0x00;      /* pcicmd pci command rw, ro */
1319    c[PCI_COMMAND + 1] = 0x00;
1320
1321    /* TODO: */
1322    c[PCI_STATUS] = PCI_STATUS_FAST_BACK;      /* pcists pci status rwc, ro */
1323    c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
1324
1325    c[PCI_CLASS_PROG] = 0x00;      /* pi programming interface ro */
1326
1327    /* TODO set when bar is registered. no need to override. */
1328    /* nabmar native audio mixer base address rw */
1329    c[PCI_BASE_ADDRESS_0] = PCI_BASE_ADDRESS_SPACE_IO;
1330    c[PCI_BASE_ADDRESS_0 + 1] = 0x00;
1331    c[PCI_BASE_ADDRESS_0 + 2] = 0x00;
1332    c[PCI_BASE_ADDRESS_0 + 3] = 0x00;
1333
1334    /* TODO set when bar is registered. no need to override. */
1335      /* nabmbar native audio bus mastering base address rw */
1336    c[PCI_BASE_ADDRESS_0 + 4] = PCI_BASE_ADDRESS_SPACE_IO;
1337    c[PCI_BASE_ADDRESS_0 + 5] = 0x00;
1338    c[PCI_BASE_ADDRESS_0 + 6] = 0x00;
1339    c[PCI_BASE_ADDRESS_0 + 7] = 0x00;
1340
1341    c[PCI_INTERRUPT_LINE] = 0x00;      /* intr_ln interrupt line rw */
1342    c[PCI_INTERRUPT_PIN] = 0x01;      /* intr_pn interrupt pin ro */
1343
1344    memory_region_init_io(&s->io_nam, OBJECT(s), &ac97_io_nam_ops, s,
1345                          "ac97-nam", 1024);
1346    memory_region_init_io(&s->io_nabm, OBJECT(s), &ac97_io_nabm_ops, s,
1347                          "ac97-nabm", 256);
1348    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
1349    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
1350    AUD_register_card("ac97", &s->card);
1351    ac97_on_reset(DEVICE(s));
1352}
1353
1354static void ac97_exit(PCIDevice *dev)
1355{
1356    AC97LinkState *s = AC97(dev);
1357
1358    AUD_close_in(&s->card, s->voice_pi);
1359    AUD_close_out(&s->card, s->voice_po);
1360    AUD_close_in(&s->card, s->voice_mc);
1361    AUD_remove_card(&s->card);
1362}
1363
1364static Property ac97_properties[] = {
1365    DEFINE_AUDIO_PROPERTIES(AC97LinkState, card),
1366    DEFINE_PROP_END_OF_LIST(),
1367};
1368
1369static void ac97_class_init(ObjectClass *klass, void *data)
1370{
1371    DeviceClass *dc = DEVICE_CLASS(klass);
1372    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1373
1374    k->realize = ac97_realize;
1375    k->exit = ac97_exit;
1376    k->vendor_id = PCI_VENDOR_ID_INTEL;
1377    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
1378    k->revision = 0x01;
1379    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
1380    set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
1381    dc->desc = "Intel 82801AA AC97 Audio";
1382    dc->vmsd = &vmstate_ac97;
1383    device_class_set_props(dc, ac97_properties);
1384    dc->reset = ac97_on_reset;
1385}
1386
1387static const TypeInfo ac97_info = {
1388    .name          = TYPE_AC97,
1389    .parent        = TYPE_PCI_DEVICE,
1390    .instance_size = sizeof(AC97LinkState),
1391    .class_init    = ac97_class_init,
1392    .interfaces = (InterfaceInfo[]) {
1393        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
1394        { },
1395    },
1396};
1397
1398static void ac97_register_types(void)
1399{
1400    type_register_static(&ac97_info);
1401    deprecated_register_soundhw("ac97", "Intel 82801AA AC97 Audio",
1402                                0, TYPE_AC97);
1403}
1404
1405type_init(ac97_register_types)
1406