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