xref: /openbmc/qemu/hw/audio/hda-codec.c (revision 55df6fcf)
1 /*
2  * Copyright (C) 2010 Red Hat, Inc.
3  *
4  * written by Gerd Hoffmann <kraxel@redhat.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 or
9  * (at your option) version 3 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "qemu/atomic.h"
22 #include "hw/hw.h"
23 #include "hw/pci/pci.h"
24 #include "intel-hda.h"
25 #include "intel-hda-defs.h"
26 #include "audio/audio.h"
27 #include "trace.h"
28 
29 /* -------------------------------------------------------------------------- */
30 
31 typedef struct desc_param {
32     uint32_t id;
33     uint32_t val;
34 } desc_param;
35 
36 typedef struct desc_node {
37     uint32_t nid;
38     const char *name;
39     const desc_param *params;
40     uint32_t nparams;
41     uint32_t config;
42     uint32_t pinctl;
43     uint32_t *conn;
44     uint32_t stindex;
45 } desc_node;
46 
47 typedef struct desc_codec {
48     const char *name;
49     uint32_t iid;
50     const desc_node *nodes;
51     uint32_t nnodes;
52 } desc_codec;
53 
54 static const desc_param* hda_codec_find_param(const desc_node *node, uint32_t id)
55 {
56     int i;
57 
58     for (i = 0; i < node->nparams; i++) {
59         if (node->params[i].id == id) {
60             return &node->params[i];
61         }
62     }
63     return NULL;
64 }
65 
66 static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t nid)
67 {
68     int i;
69 
70     for (i = 0; i < codec->nnodes; i++) {
71         if (codec->nodes[i].nid == nid) {
72             return &codec->nodes[i];
73         }
74     }
75     return NULL;
76 }
77 
78 static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
79 {
80     if (format & AC_FMT_TYPE_NON_PCM) {
81         return;
82     }
83 
84     as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000;
85 
86     switch ((format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT) {
87     case 1: as->freq *= 2; break;
88     case 2: as->freq *= 3; break;
89     case 3: as->freq *= 4; break;
90     }
91 
92     switch ((format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT) {
93     case 1: as->freq /= 2; break;
94     case 2: as->freq /= 3; break;
95     case 3: as->freq /= 4; break;
96     case 4: as->freq /= 5; break;
97     case 5: as->freq /= 6; break;
98     case 6: as->freq /= 7; break;
99     case 7: as->freq /= 8; break;
100     }
101 
102     switch (format & AC_FMT_BITS_MASK) {
103     case AC_FMT_BITS_8:  as->fmt = AUD_FMT_S8;  break;
104     case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break;
105     case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break;
106     }
107 
108     as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1;
109 }
110 
111 /* -------------------------------------------------------------------------- */
112 /*
113  * HDA codec descriptions
114  */
115 
116 /* some defines */
117 
118 #define QEMU_HDA_ID_VENDOR  0x1af4
119 #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 |       \
120                               0x1fc /* 16 -> 96 kHz */)
121 #define QEMU_HDA_AMP_NONE    (0)
122 #define QEMU_HDA_AMP_STEPS   0x4a
123 
124 #define   PARAM mixemu
125 #define   HDA_MIXER
126 #include "hda-codec-common.h"
127 
128 #define   PARAM nomixemu
129 #include  "hda-codec-common.h"
130 
131 #define HDA_TIMER_TICKS (SCALE_MS)
132 #define B_SIZE sizeof(st->buf)
133 #define B_MASK (sizeof(st->buf) - 1)
134 
135 /* -------------------------------------------------------------------------- */
136 
137 static const char *fmt2name[] = {
138     [ AUD_FMT_U8  ] = "PCM-U8",
139     [ AUD_FMT_S8  ] = "PCM-S8",
140     [ AUD_FMT_U16 ] = "PCM-U16",
141     [ AUD_FMT_S16 ] = "PCM-S16",
142     [ AUD_FMT_U32 ] = "PCM-U32",
143     [ AUD_FMT_S32 ] = "PCM-S32",
144 };
145 
146 typedef struct HDAAudioState HDAAudioState;
147 typedef struct HDAAudioStream HDAAudioStream;
148 
149 struct HDAAudioStream {
150     HDAAudioState *state;
151     const desc_node *node;
152     bool output, running;
153     uint32_t stream;
154     uint32_t channel;
155     uint32_t format;
156     uint32_t gain_left, gain_right;
157     bool mute_left, mute_right;
158     struct audsettings as;
159     union {
160         SWVoiceIn *in;
161         SWVoiceOut *out;
162     } voice;
163     uint8_t compat_buf[HDA_BUFFER_SIZE];
164     uint32_t compat_bpos;
165     uint8_t buf[8192]; /* size must be power of two */
166     int64_t rpos;
167     int64_t wpos;
168     QEMUTimer *buft;
169     int64_t buft_start;
170 };
171 
172 #define TYPE_HDA_AUDIO "hda-audio"
173 #define HDA_AUDIO(obj) OBJECT_CHECK(HDAAudioState, (obj), TYPE_HDA_AUDIO)
174 
175 struct HDAAudioState {
176     HDACodecDevice hda;
177     const char *name;
178 
179     QEMUSoundCard card;
180     const desc_codec *desc;
181     HDAAudioStream st[4];
182     bool running_compat[16];
183     bool running_real[2 * 16];
184 
185     /* properties */
186     uint32_t debug;
187     bool     mixer;
188     bool     use_timer;
189 };
190 
191 static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
192 {
193     return 2 * st->as.nchannels * st->as.freq;
194 }
195 
196 static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
197 {
198     int64_t limit = B_SIZE / 8;
199     int64_t corr = 0;
200 
201     if (target_pos > limit) {
202         corr = HDA_TIMER_TICKS;
203     }
204     if (target_pos < -limit) {
205         corr = -HDA_TIMER_TICKS;
206     }
207     if (corr == 0) {
208         return;
209     }
210 
211     trace_hda_audio_adjust(st->node->name, target_pos);
212     atomic_fetch_add(&st->buft_start, corr);
213 }
214 
215 static void hda_audio_input_timer(void *opaque)
216 {
217     HDAAudioStream *st = opaque;
218 
219     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
220 
221     int64_t buft_start = atomic_fetch_add(&st->buft_start, 0);
222     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
223     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
224 
225     int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
226                           / NANOSECONDS_PER_SECOND;
227     wanted_rpos &= -4; /* IMPORTANT! clip to frames */
228 
229     if (wanted_rpos <= rpos) {
230         /* we already transmitted the data */
231         goto out_timer;
232     }
233 
234     int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos);
235     while (to_transfer) {
236         uint32_t start = (rpos & B_MASK);
237         uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
238         int rc = hda_codec_xfer(
239                 &st->state->hda, st->stream, false, st->buf + start, chunk);
240         if (!rc) {
241             break;
242         }
243         rpos += chunk;
244         to_transfer -= chunk;
245         atomic_fetch_add(&st->rpos, chunk);
246     }
247 
248 out_timer:
249 
250     if (st->running) {
251         timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
252     }
253 }
254 
255 static void hda_audio_input_cb(void *opaque, int avail)
256 {
257     HDAAudioStream *st = opaque;
258 
259     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
260     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
261 
262     int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail);
263 
264     hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
265 
266     while (to_transfer) {
267         uint32_t start = (uint32_t) (wpos & B_MASK);
268         uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
269         uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk);
270         wpos += read;
271         to_transfer -= read;
272         atomic_fetch_add(&st->wpos, read);
273         if (chunk != read) {
274             break;
275         }
276     }
277 }
278 
279 static void hda_audio_output_timer(void *opaque)
280 {
281     HDAAudioStream *st = opaque;
282 
283     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
284 
285     int64_t buft_start = atomic_fetch_add(&st->buft_start, 0);
286     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
287     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
288 
289     int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
290                           / NANOSECONDS_PER_SECOND;
291     wanted_wpos &= -4; /* IMPORTANT! clip to frames */
292 
293     if (wanted_wpos <= wpos) {
294         /* we already received the data */
295         goto out_timer;
296     }
297 
298     int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos);
299     while (to_transfer) {
300         uint32_t start = (wpos & B_MASK);
301         uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
302         int rc = hda_codec_xfer(
303                 &st->state->hda, st->stream, true, st->buf + start, chunk);
304         if (!rc) {
305             break;
306         }
307         wpos += chunk;
308         to_transfer -= chunk;
309         atomic_fetch_add(&st->wpos, chunk);
310     }
311 
312 out_timer:
313 
314     if (st->running) {
315         timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
316     }
317 }
318 
319 static void hda_audio_output_cb(void *opaque, int avail)
320 {
321     HDAAudioStream *st = opaque;
322 
323     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
324     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
325 
326     int64_t to_transfer = audio_MIN(wpos - rpos, avail);
327 
328     if (wpos - rpos == B_SIZE) {
329         /* drop buffer, reset timer adjust */
330         st->rpos = 0;
331         st->wpos = 0;
332         st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
333         trace_hda_audio_overrun(st->node->name);
334         return;
335     }
336 
337     hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
338 
339     while (to_transfer) {
340         uint32_t start = (uint32_t) (rpos & B_MASK);
341         uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
342         uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk);
343         rpos += written;
344         to_transfer -= written;
345         atomic_fetch_add(&st->rpos, written);
346         if (chunk != written) {
347             break;
348         }
349     }
350 }
351 
352 static void hda_audio_compat_input_cb(void *opaque, int avail)
353 {
354     HDAAudioStream *st = opaque;
355     int recv = 0;
356     int len;
357     bool rc;
358 
359     while (avail - recv >= sizeof(st->compat_buf)) {
360         if (st->compat_bpos != sizeof(st->compat_buf)) {
361             len = AUD_read(st->voice.in, st->compat_buf + st->compat_bpos,
362                            sizeof(st->compat_buf) - st->compat_bpos);
363             st->compat_bpos += len;
364             recv += len;
365             if (st->compat_bpos != sizeof(st->compat_buf)) {
366                 break;
367             }
368         }
369         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
370                             st->compat_buf, sizeof(st->compat_buf));
371         if (!rc) {
372             break;
373         }
374         st->compat_bpos = 0;
375     }
376 }
377 
378 static void hda_audio_compat_output_cb(void *opaque, int avail)
379 {
380     HDAAudioStream *st = opaque;
381     int sent = 0;
382     int len;
383     bool rc;
384 
385     while (avail - sent >= sizeof(st->compat_buf)) {
386         if (st->compat_bpos == sizeof(st->compat_buf)) {
387             rc = hda_codec_xfer(&st->state->hda, st->stream, true,
388                                 st->compat_buf, sizeof(st->compat_buf));
389             if (!rc) {
390                 break;
391             }
392             st->compat_bpos = 0;
393         }
394         len = AUD_write(st->voice.out, st->compat_buf + st->compat_bpos,
395                         sizeof(st->compat_buf) - st->compat_bpos);
396         st->compat_bpos += len;
397         sent += len;
398         if (st->compat_bpos != sizeof(st->compat_buf)) {
399             break;
400         }
401     }
402 }
403 
404 static void hda_audio_set_running(HDAAudioStream *st, bool running)
405 {
406     if (st->node == NULL) {
407         return;
408     }
409     if (st->running == running) {
410         return;
411     }
412     st->running = running;
413     trace_hda_audio_running(st->node->name, st->stream, st->running);
414     if (st->state->use_timer) {
415         if (running) {
416             int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
417             st->rpos = 0;
418             st->wpos = 0;
419             st->buft_start = now;
420             timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
421         } else {
422             timer_del(st->buft);
423         }
424     }
425     if (st->output) {
426         AUD_set_active_out(st->voice.out, st->running);
427     } else {
428         AUD_set_active_in(st->voice.in, st->running);
429     }
430 }
431 
432 static void hda_audio_set_amp(HDAAudioStream *st)
433 {
434     bool muted;
435     uint32_t left, right;
436 
437     if (st->node == NULL) {
438         return;
439     }
440 
441     muted = st->mute_left && st->mute_right;
442     left  = st->mute_left  ? 0 : st->gain_left;
443     right = st->mute_right ? 0 : st->gain_right;
444 
445     left = left * 255 / QEMU_HDA_AMP_STEPS;
446     right = right * 255 / QEMU_HDA_AMP_STEPS;
447 
448     if (!st->state->mixer) {
449         return;
450     }
451     if (st->output) {
452         AUD_set_volume_out(st->voice.out, muted, left, right);
453     } else {
454         AUD_set_volume_in(st->voice.in, muted, left, right);
455     }
456 }
457 
458 static void hda_audio_setup(HDAAudioStream *st)
459 {
460     bool use_timer = st->state->use_timer;
461     audio_callback_fn cb;
462 
463     if (st->node == NULL) {
464         return;
465     }
466 
467     trace_hda_audio_format(st->node->name, st->as.nchannels,
468                            fmt2name[st->as.fmt], st->as.freq);
469 
470     if (st->output) {
471         if (use_timer) {
472             cb = hda_audio_output_cb;
473             st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
474                                     hda_audio_output_timer, st);
475         } else {
476             cb = hda_audio_compat_output_cb;
477         }
478         st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
479                                      st->node->name, st, cb, &st->as);
480     } else {
481         if (use_timer) {
482             cb = hda_audio_input_cb;
483             st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
484                                     hda_audio_input_timer, st);
485         } else {
486             cb = hda_audio_compat_input_cb;
487         }
488         st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
489                                    st->node->name, st, cb, &st->as);
490     }
491 }
492 
493 static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
494 {
495     HDAAudioState *a = HDA_AUDIO(hda);
496     HDAAudioStream *st;
497     const desc_node *node = NULL;
498     const desc_param *param;
499     uint32_t verb, payload, response, count, shift;
500 
501     if ((data & 0x70000) == 0x70000) {
502         /* 12/8 id/payload */
503         verb = (data >> 8) & 0xfff;
504         payload = data & 0x00ff;
505     } else {
506         /* 4/16 id/payload */
507         verb = (data >> 8) & 0xf00;
508         payload = data & 0xffff;
509     }
510 
511     node = hda_codec_find_node(a->desc, nid);
512     if (node == NULL) {
513         goto fail;
514     }
515     dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
516            __func__, nid, node->name, verb, payload);
517 
518     switch (verb) {
519     /* all nodes */
520     case AC_VERB_PARAMETERS:
521         param = hda_codec_find_param(node, payload);
522         if (param == NULL) {
523             goto fail;
524         }
525         hda_codec_response(hda, true, param->val);
526         break;
527     case AC_VERB_GET_SUBSYSTEM_ID:
528         hda_codec_response(hda, true, a->desc->iid);
529         break;
530 
531     /* all functions */
532     case AC_VERB_GET_CONNECT_LIST:
533         param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);
534         count = param ? param->val : 0;
535         response = 0;
536         shift = 0;
537         while (payload < count && shift < 32) {
538             response |= node->conn[payload] << shift;
539             payload++;
540             shift += 8;
541         }
542         hda_codec_response(hda, true, response);
543         break;
544 
545     /* pin widget */
546     case AC_VERB_GET_CONFIG_DEFAULT:
547         hda_codec_response(hda, true, node->config);
548         break;
549     case AC_VERB_GET_PIN_WIDGET_CONTROL:
550         hda_codec_response(hda, true, node->pinctl);
551         break;
552     case AC_VERB_SET_PIN_WIDGET_CONTROL:
553         if (node->pinctl != payload) {
554             dprint(a, 1, "unhandled pin control bit\n");
555         }
556         hda_codec_response(hda, true, 0);
557         break;
558 
559     /* audio in/out widget */
560     case AC_VERB_SET_CHANNEL_STREAMID:
561         st = a->st + node->stindex;
562         if (st->node == NULL) {
563             goto fail;
564         }
565         hda_audio_set_running(st, false);
566         st->stream = (payload >> 4) & 0x0f;
567         st->channel = payload & 0x0f;
568         dprint(a, 2, "%s: stream %d, channel %d\n",
569                st->node->name, st->stream, st->channel);
570         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
571         hda_codec_response(hda, true, 0);
572         break;
573     case AC_VERB_GET_CONV:
574         st = a->st + node->stindex;
575         if (st->node == NULL) {
576             goto fail;
577         }
578         response = st->stream << 4 | st->channel;
579         hda_codec_response(hda, true, response);
580         break;
581     case AC_VERB_SET_STREAM_FORMAT:
582         st = a->st + node->stindex;
583         if (st->node == NULL) {
584             goto fail;
585         }
586         st->format = payload;
587         hda_codec_parse_fmt(st->format, &st->as);
588         hda_audio_setup(st);
589         hda_codec_response(hda, true, 0);
590         break;
591     case AC_VERB_GET_STREAM_FORMAT:
592         st = a->st + node->stindex;
593         if (st->node == NULL) {
594             goto fail;
595         }
596         hda_codec_response(hda, true, st->format);
597         break;
598     case AC_VERB_GET_AMP_GAIN_MUTE:
599         st = a->st + node->stindex;
600         if (st->node == NULL) {
601             goto fail;
602         }
603         if (payload & AC_AMP_GET_LEFT) {
604             response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
605         } else {
606             response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);
607         }
608         hda_codec_response(hda, true, response);
609         break;
610     case AC_VERB_SET_AMP_GAIN_MUTE:
611         st = a->st + node->stindex;
612         if (st->node == NULL) {
613             goto fail;
614         }
615         dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
616                st->node->name,
617                (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
618                (payload & AC_AMP_SET_INPUT)  ? "i" : "-",
619                (payload & AC_AMP_SET_LEFT)   ? "l" : "-",
620                (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",
621                (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
622                (payload & AC_AMP_GAIN),
623                (payload & AC_AMP_MUTE) ? "muted" : "");
624         if (payload & AC_AMP_SET_LEFT) {
625             st->gain_left = payload & AC_AMP_GAIN;
626             st->mute_left = payload & AC_AMP_MUTE;
627         }
628         if (payload & AC_AMP_SET_RIGHT) {
629             st->gain_right = payload & AC_AMP_GAIN;
630             st->mute_right = payload & AC_AMP_MUTE;
631         }
632         hda_audio_set_amp(st);
633         hda_codec_response(hda, true, 0);
634         break;
635 
636     /* not supported */
637     case AC_VERB_SET_POWER_STATE:
638     case AC_VERB_GET_POWER_STATE:
639     case AC_VERB_GET_SDI_SELECT:
640         hda_codec_response(hda, true, 0);
641         break;
642     default:
643         goto fail;
644     }
645     return;
646 
647 fail:
648     dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
649            __func__, nid, node ? node->name : "?", verb, payload);
650     hda_codec_response(hda, true, 0);
651 }
652 
653 static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
654 {
655     HDAAudioState *a = HDA_AUDIO(hda);
656     int s;
657 
658     a->running_compat[stnr] = running;
659     a->running_real[output * 16 + stnr] = running;
660     for (s = 0; s < ARRAY_SIZE(a->st); s++) {
661         if (a->st[s].node == NULL) {
662             continue;
663         }
664         if (a->st[s].output != output) {
665             continue;
666         }
667         if (a->st[s].stream != stnr) {
668             continue;
669         }
670         hda_audio_set_running(&a->st[s], running);
671     }
672 }
673 
674 static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
675 {
676     HDAAudioState *a = HDA_AUDIO(hda);
677     HDAAudioStream *st;
678     const desc_node *node;
679     const desc_param *param;
680     uint32_t i, type;
681 
682     a->desc = desc;
683     a->name = object_get_typename(OBJECT(a));
684     dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad);
685 
686     AUD_register_card("hda", &a->card);
687     for (i = 0; i < a->desc->nnodes; i++) {
688         node = a->desc->nodes + i;
689         param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
690         if (param == NULL) {
691             continue;
692         }
693         type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
694         switch (type) {
695         case AC_WID_AUD_OUT:
696         case AC_WID_AUD_IN:
697             assert(node->stindex < ARRAY_SIZE(a->st));
698             st = a->st + node->stindex;
699             st->state = a;
700             st->node = node;
701             if (type == AC_WID_AUD_OUT) {
702                 /* unmute output by default */
703                 st->gain_left = QEMU_HDA_AMP_STEPS;
704                 st->gain_right = QEMU_HDA_AMP_STEPS;
705                 st->compat_bpos = sizeof(st->compat_buf);
706                 st->output = true;
707             } else {
708                 st->output = false;
709             }
710             st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
711                 (1 << AC_FMT_CHAN_SHIFT);
712             hda_codec_parse_fmt(st->format, &st->as);
713             hda_audio_setup(st);
714             break;
715         }
716     }
717     return 0;
718 }
719 
720 static void hda_audio_exit(HDACodecDevice *hda)
721 {
722     HDAAudioState *a = HDA_AUDIO(hda);
723     HDAAudioStream *st;
724     int i;
725 
726     dprint(a, 1, "%s\n", __func__);
727     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
728         st = a->st + i;
729         if (st->node == NULL) {
730             continue;
731         }
732         if (a->use_timer) {
733             timer_del(st->buft);
734         }
735         if (st->output) {
736             AUD_close_out(&a->card, st->voice.out);
737         } else {
738             AUD_close_in(&a->card, st->voice.in);
739         }
740     }
741     AUD_remove_card(&a->card);
742 }
743 
744 static int hda_audio_post_load(void *opaque, int version)
745 {
746     HDAAudioState *a = opaque;
747     HDAAudioStream *st;
748     int i;
749 
750     dprint(a, 1, "%s\n", __func__);
751     if (version == 1) {
752         /* assume running_compat[] is for output streams */
753         for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
754             a->running_real[16 + i] = a->running_compat[i];
755     }
756 
757     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
758         st = a->st + i;
759         if (st->node == NULL)
760             continue;
761         hda_codec_parse_fmt(st->format, &st->as);
762         hda_audio_setup(st);
763         hda_audio_set_amp(st);
764         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
765     }
766     return 0;
767 }
768 
769 static void hda_audio_reset(DeviceState *dev)
770 {
771     HDAAudioState *a = HDA_AUDIO(dev);
772     HDAAudioStream *st;
773     int i;
774 
775     dprint(a, 1, "%s\n", __func__);
776     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
777         st = a->st + i;
778         if (st->node != NULL) {
779             hda_audio_set_running(st, false);
780         }
781     }
782 }
783 
784 static bool vmstate_hda_audio_stream_buf_needed(void *opaque)
785 {
786     HDAAudioStream *st = opaque;
787     return st->state->use_timer;
788 }
789 
790 static const VMStateDescription vmstate_hda_audio_stream_buf = {
791     .name = "hda-audio-stream/buffer",
792     .version_id = 1,
793     .needed = vmstate_hda_audio_stream_buf_needed,
794     .fields = (VMStateField[]) {
795         VMSTATE_BUFFER(buf, HDAAudioStream),
796         VMSTATE_INT64(rpos, HDAAudioStream),
797         VMSTATE_INT64(wpos, HDAAudioStream),
798         VMSTATE_TIMER_PTR(buft, HDAAudioStream),
799         VMSTATE_INT64(buft_start, HDAAudioStream),
800         VMSTATE_END_OF_LIST()
801     }
802 };
803 
804 static const VMStateDescription vmstate_hda_audio_stream = {
805     .name = "hda-audio-stream",
806     .version_id = 1,
807     .fields = (VMStateField[]) {
808         VMSTATE_UINT32(stream, HDAAudioStream),
809         VMSTATE_UINT32(channel, HDAAudioStream),
810         VMSTATE_UINT32(format, HDAAudioStream),
811         VMSTATE_UINT32(gain_left, HDAAudioStream),
812         VMSTATE_UINT32(gain_right, HDAAudioStream),
813         VMSTATE_BOOL(mute_left, HDAAudioStream),
814         VMSTATE_BOOL(mute_right, HDAAudioStream),
815         VMSTATE_UINT32(compat_bpos, HDAAudioStream),
816         VMSTATE_BUFFER(compat_buf, HDAAudioStream),
817         VMSTATE_END_OF_LIST()
818     },
819     .subsections = (const VMStateDescription * []) {
820         &vmstate_hda_audio_stream_buf,
821         NULL
822     }
823 };
824 
825 static const VMStateDescription vmstate_hda_audio = {
826     .name = "hda-audio",
827     .version_id = 2,
828     .post_load = hda_audio_post_load,
829     .fields = (VMStateField[]) {
830         VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
831                              vmstate_hda_audio_stream,
832                              HDAAudioStream),
833         VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
834         VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
835         VMSTATE_END_OF_LIST()
836     }
837 };
838 
839 static Property hda_audio_properties[] = {
840     DEFINE_PROP_UINT32("debug", HDAAudioState, debug,   0),
841     DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer,  true),
842     DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer,  true),
843     DEFINE_PROP_END_OF_LIST(),
844 };
845 
846 static int hda_audio_init_output(HDACodecDevice *hda)
847 {
848     HDAAudioState *a = HDA_AUDIO(hda);
849 
850     if (!a->mixer) {
851         return hda_audio_init(hda, &output_nomixemu);
852     } else {
853         return hda_audio_init(hda, &output_mixemu);
854     }
855 }
856 
857 static int hda_audio_init_duplex(HDACodecDevice *hda)
858 {
859     HDAAudioState *a = HDA_AUDIO(hda);
860 
861     if (!a->mixer) {
862         return hda_audio_init(hda, &duplex_nomixemu);
863     } else {
864         return hda_audio_init(hda, &duplex_mixemu);
865     }
866 }
867 
868 static int hda_audio_init_micro(HDACodecDevice *hda)
869 {
870     HDAAudioState *a = HDA_AUDIO(hda);
871 
872     if (!a->mixer) {
873         return hda_audio_init(hda, &micro_nomixemu);
874     } else {
875         return hda_audio_init(hda, &micro_mixemu);
876     }
877 }
878 
879 static void hda_audio_base_class_init(ObjectClass *klass, void *data)
880 {
881     DeviceClass *dc = DEVICE_CLASS(klass);
882     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
883 
884     k->exit = hda_audio_exit;
885     k->command = hda_audio_command;
886     k->stream = hda_audio_stream;
887     set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
888     dc->reset = hda_audio_reset;
889     dc->vmsd = &vmstate_hda_audio;
890     dc->props = hda_audio_properties;
891 }
892 
893 static const TypeInfo hda_audio_info = {
894     .name          = TYPE_HDA_AUDIO,
895     .parent        = TYPE_HDA_CODEC_DEVICE,
896     .class_init    = hda_audio_base_class_init,
897     .abstract      = true,
898 };
899 
900 static void hda_audio_output_class_init(ObjectClass *klass, void *data)
901 {
902     DeviceClass *dc = DEVICE_CLASS(klass);
903     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
904 
905     k->init = hda_audio_init_output;
906     dc->desc = "HDA Audio Codec, output-only (line-out)";
907 }
908 
909 static const TypeInfo hda_audio_output_info = {
910     .name          = "hda-output",
911     .parent        = TYPE_HDA_AUDIO,
912     .instance_size = sizeof(HDAAudioState),
913     .class_init    = hda_audio_output_class_init,
914 };
915 
916 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
917 {
918     DeviceClass *dc = DEVICE_CLASS(klass);
919     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
920 
921     k->init = hda_audio_init_duplex;
922     dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
923 }
924 
925 static const TypeInfo hda_audio_duplex_info = {
926     .name          = "hda-duplex",
927     .parent        = TYPE_HDA_AUDIO,
928     .instance_size = sizeof(HDAAudioState),
929     .class_init    = hda_audio_duplex_class_init,
930 };
931 
932 static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
933 {
934     DeviceClass *dc = DEVICE_CLASS(klass);
935     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
936 
937     k->init = hda_audio_init_micro;
938     dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
939 }
940 
941 static const TypeInfo hda_audio_micro_info = {
942     .name          = "hda-micro",
943     .parent        = TYPE_HDA_AUDIO,
944     .instance_size = sizeof(HDAAudioState),
945     .class_init    = hda_audio_micro_class_init,
946 };
947 
948 static void hda_audio_register_types(void)
949 {
950     type_register_static(&hda_audio_info);
951     type_register_static(&hda_audio_output_info);
952     type_register_static(&hda_audio_duplex_info);
953     type_register_static(&hda_audio_micro_info);
954 }
955 
956 type_init(hda_audio_register_types)
957