xref: /openbmc/qemu/hw/audio/hda-codec.c (revision 8e6fe6b8)
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 "hw/hw.h"
22 #include "hw/pci/pci.h"
23 #include "intel-hda.h"
24 #include "qemu/module.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 = AUDIO_FORMAT_S8;  break;
104     case AC_FMT_BITS_16: as->fmt = AUDIO_FORMAT_S16; break;
105     case AC_FMT_BITS_32: as->fmt = AUDIO_FORMAT_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     [ AUDIO_FORMAT_U8  ] = "PCM-U8",
139     [ AUDIO_FORMAT_S8  ] = "PCM-S8",
140     [ AUDIO_FORMAT_U16 ] = "PCM-U16",
141     [ AUDIO_FORMAT_S16 ] = "PCM-S16",
142     [ AUDIO_FORMAT_U32 ] = "PCM-U32",
143     [ AUDIO_FORMAT_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 2LL * 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 (target_pos < -(2 * limit)) {
208         corr = -(4 * HDA_TIMER_TICKS);
209     }
210     if (corr == 0) {
211         return;
212     }
213 
214     trace_hda_audio_adjust(st->node->name, target_pos);
215     st->buft_start += corr;
216 }
217 
218 static void hda_audio_input_timer(void *opaque)
219 {
220     HDAAudioStream *st = opaque;
221 
222     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
223 
224     int64_t buft_start = st->buft_start;
225     int64_t wpos = st->wpos;
226     int64_t rpos = st->rpos;
227 
228     int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
229                           / NANOSECONDS_PER_SECOND;
230     wanted_rpos &= -4; /* IMPORTANT! clip to frames */
231 
232     if (wanted_rpos <= rpos) {
233         /* we already transmitted the data */
234         goto out_timer;
235     }
236 
237     int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos);
238     while (to_transfer) {
239         uint32_t start = (rpos & B_MASK);
240         uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
241         int rc = hda_codec_xfer(
242                 &st->state->hda, st->stream, false, st->buf + start, chunk);
243         if (!rc) {
244             break;
245         }
246         rpos += chunk;
247         to_transfer -= chunk;
248         st->rpos += chunk;
249     }
250 
251 out_timer:
252 
253     if (st->running) {
254         timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
255     }
256 }
257 
258 static void hda_audio_input_cb(void *opaque, int avail)
259 {
260     HDAAudioStream *st = opaque;
261 
262     int64_t wpos = st->wpos;
263     int64_t rpos = st->rpos;
264 
265     int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail);
266 
267     hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
268 
269     while (to_transfer) {
270         uint32_t start = (uint32_t) (wpos & B_MASK);
271         uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
272         uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk);
273         wpos += read;
274         to_transfer -= read;
275         st->wpos += read;
276         if (chunk != read) {
277             break;
278         }
279     }
280 }
281 
282 static void hda_audio_output_timer(void *opaque)
283 {
284     HDAAudioStream *st = opaque;
285 
286     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
287 
288     int64_t buft_start = st->buft_start;
289     int64_t wpos = st->wpos;
290     int64_t rpos = st->rpos;
291 
292     int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
293                           / NANOSECONDS_PER_SECOND;
294     wanted_wpos &= -4; /* IMPORTANT! clip to frames */
295 
296     if (wanted_wpos <= wpos) {
297         /* we already received the data */
298         goto out_timer;
299     }
300 
301     int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos);
302     while (to_transfer) {
303         uint32_t start = (wpos & B_MASK);
304         uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
305         int rc = hda_codec_xfer(
306                 &st->state->hda, st->stream, true, st->buf + start, chunk);
307         if (!rc) {
308             break;
309         }
310         wpos += chunk;
311         to_transfer -= chunk;
312         st->wpos += chunk;
313     }
314 
315 out_timer:
316 
317     if (st->running) {
318         timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
319     }
320 }
321 
322 static void hda_audio_output_cb(void *opaque, int avail)
323 {
324     HDAAudioStream *st = opaque;
325 
326     int64_t wpos = st->wpos;
327     int64_t rpos = st->rpos;
328 
329     int64_t to_transfer = audio_MIN(wpos - rpos, avail);
330 
331     if (wpos - rpos == B_SIZE) {
332         /* drop buffer, reset timer adjust */
333         st->rpos = 0;
334         st->wpos = 0;
335         st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
336         trace_hda_audio_overrun(st->node->name);
337         return;
338     }
339 
340     hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
341 
342     while (to_transfer) {
343         uint32_t start = (uint32_t) (rpos & B_MASK);
344         uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
345         uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk);
346         rpos += written;
347         to_transfer -= written;
348         st->rpos += written;
349         if (chunk != written) {
350             break;
351         }
352     }
353 }
354 
355 static void hda_audio_compat_input_cb(void *opaque, int avail)
356 {
357     HDAAudioStream *st = opaque;
358     int recv = 0;
359     int len;
360     bool rc;
361 
362     while (avail - recv >= sizeof(st->compat_buf)) {
363         if (st->compat_bpos != sizeof(st->compat_buf)) {
364             len = AUD_read(st->voice.in, st->compat_buf + st->compat_bpos,
365                            sizeof(st->compat_buf) - st->compat_bpos);
366             st->compat_bpos += len;
367             recv += len;
368             if (st->compat_bpos != sizeof(st->compat_buf)) {
369                 break;
370             }
371         }
372         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
373                             st->compat_buf, sizeof(st->compat_buf));
374         if (!rc) {
375             break;
376         }
377         st->compat_bpos = 0;
378     }
379 }
380 
381 static void hda_audio_compat_output_cb(void *opaque, int avail)
382 {
383     HDAAudioStream *st = opaque;
384     int sent = 0;
385     int len;
386     bool rc;
387 
388     while (avail - sent >= sizeof(st->compat_buf)) {
389         if (st->compat_bpos == sizeof(st->compat_buf)) {
390             rc = hda_codec_xfer(&st->state->hda, st->stream, true,
391                                 st->compat_buf, sizeof(st->compat_buf));
392             if (!rc) {
393                 break;
394             }
395             st->compat_bpos = 0;
396         }
397         len = AUD_write(st->voice.out, st->compat_buf + st->compat_bpos,
398                         sizeof(st->compat_buf) - st->compat_bpos);
399         st->compat_bpos += len;
400         sent += len;
401         if (st->compat_bpos != sizeof(st->compat_buf)) {
402             break;
403         }
404     }
405 }
406 
407 static void hda_audio_set_running(HDAAudioStream *st, bool running)
408 {
409     if (st->node == NULL) {
410         return;
411     }
412     if (st->running == running) {
413         return;
414     }
415     st->running = running;
416     trace_hda_audio_running(st->node->name, st->stream, st->running);
417     if (st->state->use_timer) {
418         if (running) {
419             int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
420             st->rpos = 0;
421             st->wpos = 0;
422             st->buft_start = now;
423             timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
424         } else {
425             timer_del(st->buft);
426         }
427     }
428     if (st->output) {
429         AUD_set_active_out(st->voice.out, st->running);
430     } else {
431         AUD_set_active_in(st->voice.in, st->running);
432     }
433 }
434 
435 static void hda_audio_set_amp(HDAAudioStream *st)
436 {
437     bool muted;
438     uint32_t left, right;
439 
440     if (st->node == NULL) {
441         return;
442     }
443 
444     muted = st->mute_left && st->mute_right;
445     left  = st->mute_left  ? 0 : st->gain_left;
446     right = st->mute_right ? 0 : st->gain_right;
447 
448     left = left * 255 / QEMU_HDA_AMP_STEPS;
449     right = right * 255 / QEMU_HDA_AMP_STEPS;
450 
451     if (!st->state->mixer) {
452         return;
453     }
454     if (st->output) {
455         AUD_set_volume_out(st->voice.out, muted, left, right);
456     } else {
457         AUD_set_volume_in(st->voice.in, muted, left, right);
458     }
459 }
460 
461 static void hda_audio_setup(HDAAudioStream *st)
462 {
463     bool use_timer = st->state->use_timer;
464     audio_callback_fn cb;
465 
466     if (st->node == NULL) {
467         return;
468     }
469 
470     trace_hda_audio_format(st->node->name, st->as.nchannels,
471                            fmt2name[st->as.fmt], st->as.freq);
472 
473     if (st->output) {
474         if (use_timer) {
475             cb = hda_audio_output_cb;
476             st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
477                                     hda_audio_output_timer, st);
478         } else {
479             cb = hda_audio_compat_output_cb;
480         }
481         st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
482                                      st->node->name, st, cb, &st->as);
483     } else {
484         if (use_timer) {
485             cb = hda_audio_input_cb;
486             st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
487                                     hda_audio_input_timer, st);
488         } else {
489             cb = hda_audio_compat_input_cb;
490         }
491         st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
492                                    st->node->name, st, cb, &st->as);
493     }
494 }
495 
496 static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
497 {
498     HDAAudioState *a = HDA_AUDIO(hda);
499     HDAAudioStream *st;
500     const desc_node *node = NULL;
501     const desc_param *param;
502     uint32_t verb, payload, response, count, shift;
503 
504     if ((data & 0x70000) == 0x70000) {
505         /* 12/8 id/payload */
506         verb = (data >> 8) & 0xfff;
507         payload = data & 0x00ff;
508     } else {
509         /* 4/16 id/payload */
510         verb = (data >> 8) & 0xf00;
511         payload = data & 0xffff;
512     }
513 
514     node = hda_codec_find_node(a->desc, nid);
515     if (node == NULL) {
516         goto fail;
517     }
518     dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
519            __func__, nid, node->name, verb, payload);
520 
521     switch (verb) {
522     /* all nodes */
523     case AC_VERB_PARAMETERS:
524         param = hda_codec_find_param(node, payload);
525         if (param == NULL) {
526             goto fail;
527         }
528         hda_codec_response(hda, true, param->val);
529         break;
530     case AC_VERB_GET_SUBSYSTEM_ID:
531         hda_codec_response(hda, true, a->desc->iid);
532         break;
533 
534     /* all functions */
535     case AC_VERB_GET_CONNECT_LIST:
536         param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);
537         count = param ? param->val : 0;
538         response = 0;
539         shift = 0;
540         while (payload < count && shift < 32) {
541             response |= node->conn[payload] << shift;
542             payload++;
543             shift += 8;
544         }
545         hda_codec_response(hda, true, response);
546         break;
547 
548     /* pin widget */
549     case AC_VERB_GET_CONFIG_DEFAULT:
550         hda_codec_response(hda, true, node->config);
551         break;
552     case AC_VERB_GET_PIN_WIDGET_CONTROL:
553         hda_codec_response(hda, true, node->pinctl);
554         break;
555     case AC_VERB_SET_PIN_WIDGET_CONTROL:
556         if (node->pinctl != payload) {
557             dprint(a, 1, "unhandled pin control bit\n");
558         }
559         hda_codec_response(hda, true, 0);
560         break;
561 
562     /* audio in/out widget */
563     case AC_VERB_SET_CHANNEL_STREAMID:
564         st = a->st + node->stindex;
565         if (st->node == NULL) {
566             goto fail;
567         }
568         hda_audio_set_running(st, false);
569         st->stream = (payload >> 4) & 0x0f;
570         st->channel = payload & 0x0f;
571         dprint(a, 2, "%s: stream %d, channel %d\n",
572                st->node->name, st->stream, st->channel);
573         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
574         hda_codec_response(hda, true, 0);
575         break;
576     case AC_VERB_GET_CONV:
577         st = a->st + node->stindex;
578         if (st->node == NULL) {
579             goto fail;
580         }
581         response = st->stream << 4 | st->channel;
582         hda_codec_response(hda, true, response);
583         break;
584     case AC_VERB_SET_STREAM_FORMAT:
585         st = a->st + node->stindex;
586         if (st->node == NULL) {
587             goto fail;
588         }
589         st->format = payload;
590         hda_codec_parse_fmt(st->format, &st->as);
591         hda_audio_setup(st);
592         hda_codec_response(hda, true, 0);
593         break;
594     case AC_VERB_GET_STREAM_FORMAT:
595         st = a->st + node->stindex;
596         if (st->node == NULL) {
597             goto fail;
598         }
599         hda_codec_response(hda, true, st->format);
600         break;
601     case AC_VERB_GET_AMP_GAIN_MUTE:
602         st = a->st + node->stindex;
603         if (st->node == NULL) {
604             goto fail;
605         }
606         if (payload & AC_AMP_GET_LEFT) {
607             response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
608         } else {
609             response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);
610         }
611         hda_codec_response(hda, true, response);
612         break;
613     case AC_VERB_SET_AMP_GAIN_MUTE:
614         st = a->st + node->stindex;
615         if (st->node == NULL) {
616             goto fail;
617         }
618         dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
619                st->node->name,
620                (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
621                (payload & AC_AMP_SET_INPUT)  ? "i" : "-",
622                (payload & AC_AMP_SET_LEFT)   ? "l" : "-",
623                (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",
624                (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
625                (payload & AC_AMP_GAIN),
626                (payload & AC_AMP_MUTE) ? "muted" : "");
627         if (payload & AC_AMP_SET_LEFT) {
628             st->gain_left = payload & AC_AMP_GAIN;
629             st->mute_left = payload & AC_AMP_MUTE;
630         }
631         if (payload & AC_AMP_SET_RIGHT) {
632             st->gain_right = payload & AC_AMP_GAIN;
633             st->mute_right = payload & AC_AMP_MUTE;
634         }
635         hda_audio_set_amp(st);
636         hda_codec_response(hda, true, 0);
637         break;
638 
639     /* not supported */
640     case AC_VERB_SET_POWER_STATE:
641     case AC_VERB_GET_POWER_STATE:
642     case AC_VERB_GET_SDI_SELECT:
643         hda_codec_response(hda, true, 0);
644         break;
645     default:
646         goto fail;
647     }
648     return;
649 
650 fail:
651     dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
652            __func__, nid, node ? node->name : "?", verb, payload);
653     hda_codec_response(hda, true, 0);
654 }
655 
656 static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
657 {
658     HDAAudioState *a = HDA_AUDIO(hda);
659     int s;
660 
661     a->running_compat[stnr] = running;
662     a->running_real[output * 16 + stnr] = running;
663     for (s = 0; s < ARRAY_SIZE(a->st); s++) {
664         if (a->st[s].node == NULL) {
665             continue;
666         }
667         if (a->st[s].output != output) {
668             continue;
669         }
670         if (a->st[s].stream != stnr) {
671             continue;
672         }
673         hda_audio_set_running(&a->st[s], running);
674     }
675 }
676 
677 static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
678 {
679     HDAAudioState *a = HDA_AUDIO(hda);
680     HDAAudioStream *st;
681     const desc_node *node;
682     const desc_param *param;
683     uint32_t i, type;
684 
685     a->desc = desc;
686     a->name = object_get_typename(OBJECT(a));
687     dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad);
688 
689     AUD_register_card("hda", &a->card);
690     for (i = 0; i < a->desc->nnodes; i++) {
691         node = a->desc->nodes + i;
692         param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
693         if (param == NULL) {
694             continue;
695         }
696         type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
697         switch (type) {
698         case AC_WID_AUD_OUT:
699         case AC_WID_AUD_IN:
700             assert(node->stindex < ARRAY_SIZE(a->st));
701             st = a->st + node->stindex;
702             st->state = a;
703             st->node = node;
704             if (type == AC_WID_AUD_OUT) {
705                 /* unmute output by default */
706                 st->gain_left = QEMU_HDA_AMP_STEPS;
707                 st->gain_right = QEMU_HDA_AMP_STEPS;
708                 st->compat_bpos = sizeof(st->compat_buf);
709                 st->output = true;
710             } else {
711                 st->output = false;
712             }
713             st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
714                 (1 << AC_FMT_CHAN_SHIFT);
715             hda_codec_parse_fmt(st->format, &st->as);
716             hda_audio_setup(st);
717             break;
718         }
719     }
720     return 0;
721 }
722 
723 static void hda_audio_exit(HDACodecDevice *hda)
724 {
725     HDAAudioState *a = HDA_AUDIO(hda);
726     HDAAudioStream *st;
727     int i;
728 
729     dprint(a, 1, "%s\n", __func__);
730     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
731         st = a->st + i;
732         if (st->node == NULL) {
733             continue;
734         }
735         if (a->use_timer) {
736             timer_del(st->buft);
737         }
738         if (st->output) {
739             AUD_close_out(&a->card, st->voice.out);
740         } else {
741             AUD_close_in(&a->card, st->voice.in);
742         }
743     }
744     AUD_remove_card(&a->card);
745 }
746 
747 static int hda_audio_post_load(void *opaque, int version)
748 {
749     HDAAudioState *a = opaque;
750     HDAAudioStream *st;
751     int i;
752 
753     dprint(a, 1, "%s\n", __func__);
754     if (version == 1) {
755         /* assume running_compat[] is for output streams */
756         for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
757             a->running_real[16 + i] = a->running_compat[i];
758     }
759 
760     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
761         st = a->st + i;
762         if (st->node == NULL)
763             continue;
764         hda_codec_parse_fmt(st->format, &st->as);
765         hda_audio_setup(st);
766         hda_audio_set_amp(st);
767         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
768     }
769     return 0;
770 }
771 
772 static void hda_audio_reset(DeviceState *dev)
773 {
774     HDAAudioState *a = HDA_AUDIO(dev);
775     HDAAudioStream *st;
776     int i;
777 
778     dprint(a, 1, "%s\n", __func__);
779     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
780         st = a->st + i;
781         if (st->node != NULL) {
782             hda_audio_set_running(st, false);
783         }
784     }
785 }
786 
787 static bool vmstate_hda_audio_stream_buf_needed(void *opaque)
788 {
789     HDAAudioStream *st = opaque;
790     return st->state && st->state->use_timer;
791 }
792 
793 static const VMStateDescription vmstate_hda_audio_stream_buf = {
794     .name = "hda-audio-stream/buffer",
795     .version_id = 1,
796     .needed = vmstate_hda_audio_stream_buf_needed,
797     .fields = (VMStateField[]) {
798         VMSTATE_BUFFER(buf, HDAAudioStream),
799         VMSTATE_INT64(rpos, HDAAudioStream),
800         VMSTATE_INT64(wpos, HDAAudioStream),
801         VMSTATE_TIMER_PTR(buft, HDAAudioStream),
802         VMSTATE_INT64(buft_start, HDAAudioStream),
803         VMSTATE_END_OF_LIST()
804     }
805 };
806 
807 static const VMStateDescription vmstate_hda_audio_stream = {
808     .name = "hda-audio-stream",
809     .version_id = 1,
810     .fields = (VMStateField[]) {
811         VMSTATE_UINT32(stream, HDAAudioStream),
812         VMSTATE_UINT32(channel, HDAAudioStream),
813         VMSTATE_UINT32(format, HDAAudioStream),
814         VMSTATE_UINT32(gain_left, HDAAudioStream),
815         VMSTATE_UINT32(gain_right, HDAAudioStream),
816         VMSTATE_BOOL(mute_left, HDAAudioStream),
817         VMSTATE_BOOL(mute_right, HDAAudioStream),
818         VMSTATE_UINT32(compat_bpos, HDAAudioStream),
819         VMSTATE_BUFFER(compat_buf, HDAAudioStream),
820         VMSTATE_END_OF_LIST()
821     },
822     .subsections = (const VMStateDescription * []) {
823         &vmstate_hda_audio_stream_buf,
824         NULL
825     }
826 };
827 
828 static const VMStateDescription vmstate_hda_audio = {
829     .name = "hda-audio",
830     .version_id = 2,
831     .post_load = hda_audio_post_load,
832     .fields = (VMStateField[]) {
833         VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
834                              vmstate_hda_audio_stream,
835                              HDAAudioStream),
836         VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
837         VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
838         VMSTATE_END_OF_LIST()
839     }
840 };
841 
842 static Property hda_audio_properties[] = {
843     DEFINE_PROP_UINT32("debug", HDAAudioState, debug,   0),
844     DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer,  true),
845     DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer,  true),
846     DEFINE_PROP_END_OF_LIST(),
847 };
848 
849 static int hda_audio_init_output(HDACodecDevice *hda)
850 {
851     HDAAudioState *a = HDA_AUDIO(hda);
852 
853     if (!a->mixer) {
854         return hda_audio_init(hda, &output_nomixemu);
855     } else {
856         return hda_audio_init(hda, &output_mixemu);
857     }
858 }
859 
860 static int hda_audio_init_duplex(HDACodecDevice *hda)
861 {
862     HDAAudioState *a = HDA_AUDIO(hda);
863 
864     if (!a->mixer) {
865         return hda_audio_init(hda, &duplex_nomixemu);
866     } else {
867         return hda_audio_init(hda, &duplex_mixemu);
868     }
869 }
870 
871 static int hda_audio_init_micro(HDACodecDevice *hda)
872 {
873     HDAAudioState *a = HDA_AUDIO(hda);
874 
875     if (!a->mixer) {
876         return hda_audio_init(hda, &micro_nomixemu);
877     } else {
878         return hda_audio_init(hda, &micro_mixemu);
879     }
880 }
881 
882 static void hda_audio_base_class_init(ObjectClass *klass, void *data)
883 {
884     DeviceClass *dc = DEVICE_CLASS(klass);
885     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
886 
887     k->exit = hda_audio_exit;
888     k->command = hda_audio_command;
889     k->stream = hda_audio_stream;
890     set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
891     dc->reset = hda_audio_reset;
892     dc->vmsd = &vmstate_hda_audio;
893     dc->props = hda_audio_properties;
894 }
895 
896 static const TypeInfo hda_audio_info = {
897     .name          = TYPE_HDA_AUDIO,
898     .parent        = TYPE_HDA_CODEC_DEVICE,
899     .class_init    = hda_audio_base_class_init,
900     .abstract      = true,
901 };
902 
903 static void hda_audio_output_class_init(ObjectClass *klass, void *data)
904 {
905     DeviceClass *dc = DEVICE_CLASS(klass);
906     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
907 
908     k->init = hda_audio_init_output;
909     dc->desc = "HDA Audio Codec, output-only (line-out)";
910 }
911 
912 static const TypeInfo hda_audio_output_info = {
913     .name          = "hda-output",
914     .parent        = TYPE_HDA_AUDIO,
915     .instance_size = sizeof(HDAAudioState),
916     .class_init    = hda_audio_output_class_init,
917 };
918 
919 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
920 {
921     DeviceClass *dc = DEVICE_CLASS(klass);
922     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
923 
924     k->init = hda_audio_init_duplex;
925     dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
926 }
927 
928 static const TypeInfo hda_audio_duplex_info = {
929     .name          = "hda-duplex",
930     .parent        = TYPE_HDA_AUDIO,
931     .instance_size = sizeof(HDAAudioState),
932     .class_init    = hda_audio_duplex_class_init,
933 };
934 
935 static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
936 {
937     DeviceClass *dc = DEVICE_CLASS(klass);
938     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
939 
940     k->init = hda_audio_init_micro;
941     dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
942 }
943 
944 static const TypeInfo hda_audio_micro_info = {
945     .name          = "hda-micro",
946     .parent        = TYPE_HDA_AUDIO,
947     .instance_size = sizeof(HDAAudioState),
948     .class_init    = hda_audio_micro_class_init,
949 };
950 
951 static void hda_audio_register_types(void)
952 {
953     type_register_static(&hda_audio_info);
954     type_register_static(&hda_audio_output_info);
955     type_register_static(&hda_audio_duplex_info);
956     type_register_static(&hda_audio_micro_info);
957 }
958 
959 type_init(hda_audio_register_types)
960