xref: /openbmc/qemu/hw/audio/ac97.c (revision 856a6fe4)
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"
89 OBJECT_DECLARE_SIMPLE_TYPE(AC97LinkState, AC97)
90 
91 #define REC_MASK 7
92 enum {
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 
103 typedef struct BD {
104     uint32_t addr;
105     uint32_t ctl_len;
106 } BD;
107 
108 typedef 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 
120 struct 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 
139 enum {
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)                   \
151 enum {                                          \
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 
161 enum {
162     PI_INDEX = 0,
163     PO_INDEX,
164     MC_INDEX,
165     LAST_INDEX
166 };
167 
168 MKREGS(PI, PI_INDEX * 16);
169 MKREGS(PO, PO_INDEX * 16);
170 MKREGS(MC, MC_INDEX * 16);
171 
172 enum {
173     GLOB_CNT = 0x2c,
174     GLOB_STA = 0x30,
175     CAS      = 0x34
176 };
177 
178 #define GET_BM(index) (((index) >> 4) & 3)
179 
180 static void po_callback(void *opaque, int free);
181 static void pi_callback(void *opaque, int avail);
182 static void mc_callback(void *opaque, int avail);
183 
fetch_bd(AC97LinkState * s,AC97BusMasterRegs * r)184 static 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 
update_sr(AC97LinkState * s,AC97BusMasterRegs * r,uint32_t new_sr)198 static 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 
voice_set_active(AC97LinkState * s,int bm_index,int on)243 static 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 
reset_bm_regs(AC97LinkState * s,AC97BusMasterRegs * r)264 static 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 
mixer_store(AC97LinkState * s,uint32_t i,uint16_t v)281 static 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 
mixer_load(AC97LinkState * s,uint32_t i)293 static 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 
open_voice(AC97LinkState * s,int index,int freq)307 static 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 
reset_voices(AC97LinkState * s,uint8_t active[LAST_INDEX])373 static 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 
get_volume(uint16_t vol,uint16_t mask,int inverse,int * mute,uint8_t * lvol,uint8_t * rvol)390 static 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 
update_combined_volume_out(AC97LinkState * s)403 static 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 
update_volume_in(AC97LinkState * s)420 static 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 
set_volume(AC97LinkState * s,int index,uint32_t val)431 static 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 
record_select(AC97LinkState * s,uint32_t val)452 static 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 
mixer_reset(AC97LinkState * s)459 static 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  */
nam_readb(void * opaque,uint32_t addr)508 static 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 
nam_readw(void * opaque,uint32_t addr)516 static 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 
nam_readl(void * opaque,uint32_t addr)523 static 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  */
nam_writeb(void * opaque,uint32_t addr,uint32_t val)535 static 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 
nam_writew(void * opaque,uint32_t addr,uint32_t val)542 static 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 
nam_writel(void * opaque,uint32_t addr,uint32_t val)639 static 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  */
nabm_readb(void * opaque,uint32_t addr)650 static 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 
nabm_readw(void * opaque,uint32_t addr)704 static 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 
nabm_readl(void * opaque,uint32_t addr)732 static 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  */
nabm_writeb(void * opaque,uint32_t addr,uint32_t val)781 static 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 
nabm_writew(void * opaque,uint32_t addr,uint32_t val)835 static 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 
nabm_writel(void * opaque,uint32_t addr,uint32_t val)855 static 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 
write_audio(AC97LinkState * s,AC97BusMasterRegs * r,int max,int * stop)886 static 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 
write_bup(AC97LinkState * s,int elapsed)930 static 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 
read_audio(AC97LinkState * s,AC97BusMasterRegs * r,int max,int * stop)959 static 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 
transfer_audio(AC97LinkState * s,int index,int elapsed)994 static 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 
pi_callback(void * opaque,int avail)1078 static void pi_callback(void *opaque, int avail)
1079 {
1080     transfer_audio(opaque, PI_INDEX, avail);
1081 }
1082 
mc_callback(void * opaque,int avail)1083 static void mc_callback(void *opaque, int avail)
1084 {
1085     transfer_audio(opaque, MC_INDEX, avail);
1086 }
1087 
po_callback(void * opaque,int free)1088 static void po_callback(void *opaque, int free)
1089 {
1090     transfer_audio(opaque, PO_INDEX, free);
1091 }
1092 
1093 static const VMStateDescription vmstate_ac97_bm_regs = {
1094     .name = "ac97_bm_regs",
1095     .version_id = 1,
1096     .minimum_version_id = 1,
1097     .fields = (const 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 
ac97_post_load(void * opaque,int version_id)1112 static 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 
is_version_2(void * opaque,int version_id)1135 static bool is_version_2(void *opaque, int version_id)
1136 {
1137     return version_id == 2;
1138 }
1139 
1140 static const VMStateDescription vmstate_ac97 = {
1141     .name = "ac97",
1142     .version_id = 3,
1143     .minimum_version_id = 2,
1144     .post_load = ac97_post_load,
1145     .fields = (const 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 
nam_read(void * opaque,hwaddr addr,unsigned size)1158 static 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 
nam_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)1176 static 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 
1196 static 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 
nabm_read(void * opaque,hwaddr addr,unsigned size)1206 static 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 
nabm_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)1224 static 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 
1245 static 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 
ac97_on_reset(DeviceState * dev)1255 static 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 
ac97_realize(PCIDevice * dev,Error ** errp)1271 static void ac97_realize(PCIDevice *dev, Error **errp)
1272 {
1273     AC97LinkState *s = AC97(dev);
1274     uint8_t *c = s->dev.config;
1275 
1276     if (!AUD_register_card ("ac97", &s->card, errp)) {
1277         return;
1278     }
1279 
1280     /* TODO: no need to override */
1281     c[PCI_COMMAND] = 0x00;      /* pcicmd pci command rw, ro */
1282     c[PCI_COMMAND + 1] = 0x00;
1283 
1284     /* TODO: */
1285     c[PCI_STATUS] = PCI_STATUS_FAST_BACK;      /* pcists pci status rwc, ro */
1286     c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
1287 
1288     c[PCI_CLASS_PROG] = 0x00;      /* pi programming interface ro */
1289 
1290     /* TODO set when bar is registered. no need to override. */
1291     /* nabmar native audio mixer base address rw */
1292     c[PCI_BASE_ADDRESS_0] = PCI_BASE_ADDRESS_SPACE_IO;
1293     c[PCI_BASE_ADDRESS_0 + 1] = 0x00;
1294     c[PCI_BASE_ADDRESS_0 + 2] = 0x00;
1295     c[PCI_BASE_ADDRESS_0 + 3] = 0x00;
1296 
1297     /* TODO set when bar is registered. no need to override. */
1298       /* nabmbar native audio bus mastering base address rw */
1299     c[PCI_BASE_ADDRESS_0 + 4] = PCI_BASE_ADDRESS_SPACE_IO;
1300     c[PCI_BASE_ADDRESS_0 + 5] = 0x00;
1301     c[PCI_BASE_ADDRESS_0 + 6] = 0x00;
1302     c[PCI_BASE_ADDRESS_0 + 7] = 0x00;
1303 
1304     c[PCI_INTERRUPT_LINE] = 0x00;      /* intr_ln interrupt line rw */
1305     c[PCI_INTERRUPT_PIN] = 0x01;      /* intr_pn interrupt pin ro */
1306 
1307     memory_region_init_io(&s->io_nam, OBJECT(s), &ac97_io_nam_ops, s,
1308                           "ac97-nam", 1024);
1309     memory_region_init_io(&s->io_nabm, OBJECT(s), &ac97_io_nabm_ops, s,
1310                           "ac97-nabm", 256);
1311     pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
1312     pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
1313 
1314     ac97_on_reset(DEVICE(s));
1315 }
1316 
ac97_exit(PCIDevice * dev)1317 static void ac97_exit(PCIDevice *dev)
1318 {
1319     AC97LinkState *s = AC97(dev);
1320 
1321     AUD_close_in(&s->card, s->voice_pi);
1322     AUD_close_out(&s->card, s->voice_po);
1323     AUD_close_in(&s->card, s->voice_mc);
1324     AUD_remove_card(&s->card);
1325 }
1326 
1327 static Property ac97_properties[] = {
1328     DEFINE_AUDIO_PROPERTIES(AC97LinkState, card),
1329     DEFINE_PROP_END_OF_LIST(),
1330 };
1331 
ac97_class_init(ObjectClass * klass,void * data)1332 static void ac97_class_init(ObjectClass *klass, void *data)
1333 {
1334     DeviceClass *dc = DEVICE_CLASS(klass);
1335     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1336 
1337     k->realize = ac97_realize;
1338     k->exit = ac97_exit;
1339     k->vendor_id = PCI_VENDOR_ID_INTEL;
1340     k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
1341     k->revision = 0x01;
1342     k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
1343     set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
1344     dc->desc = "Intel 82801AA AC97 Audio";
1345     dc->vmsd = &vmstate_ac97;
1346     device_class_set_props(dc, ac97_properties);
1347     dc->reset = ac97_on_reset;
1348 }
1349 
1350 static const TypeInfo ac97_info = {
1351     .name          = TYPE_AC97,
1352     .parent        = TYPE_PCI_DEVICE,
1353     .instance_size = sizeof(AC97LinkState),
1354     .class_init    = ac97_class_init,
1355     .interfaces = (InterfaceInfo[]) {
1356         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
1357         { },
1358     },
1359 };
1360 
ac97_register_types(void)1361 static void ac97_register_types(void)
1362 {
1363     type_register_static(&ac97_info);
1364     deprecated_register_soundhw("ac97", "Intel 82801AA AC97 Audio",
1365                                 0, TYPE_AC97);
1366 }
1367 
1368 type_init(ac97_register_types)
1369