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