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