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