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