xref: /openbmc/qemu/hw/audio/hda-codec.c (revision 47b43a1f)
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 "hw/hw.h"
21 #include "hw/pci/pci.h"
22 #include "intel-hda.h"
23 #include "intel-hda-defs.h"
24 #include "audio/audio.h"
25 
26 /* -------------------------------------------------------------------------- */
27 
28 typedef struct desc_param {
29     uint32_t id;
30     uint32_t val;
31 } desc_param;
32 
33 typedef struct desc_node {
34     uint32_t nid;
35     const char *name;
36     const desc_param *params;
37     uint32_t nparams;
38     uint32_t config;
39     uint32_t pinctl;
40     uint32_t *conn;
41     uint32_t stindex;
42 } desc_node;
43 
44 typedef struct desc_codec {
45     const char *name;
46     uint32_t iid;
47     const desc_node *nodes;
48     uint32_t nnodes;
49 } desc_codec;
50 
51 static const desc_param* hda_codec_find_param(const desc_node *node, uint32_t id)
52 {
53     int i;
54 
55     for (i = 0; i < node->nparams; i++) {
56         if (node->params[i].id == id) {
57             return &node->params[i];
58         }
59     }
60     return NULL;
61 }
62 
63 static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t nid)
64 {
65     int i;
66 
67     for (i = 0; i < codec->nnodes; i++) {
68         if (codec->nodes[i].nid == nid) {
69             return &codec->nodes[i];
70         }
71     }
72     return NULL;
73 }
74 
75 static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
76 {
77     if (format & AC_FMT_TYPE_NON_PCM) {
78         return;
79     }
80 
81     as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000;
82 
83     switch ((format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT) {
84     case 1: as->freq *= 2; break;
85     case 2: as->freq *= 3; break;
86     case 3: as->freq *= 4; break;
87     }
88 
89     switch ((format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT) {
90     case 1: as->freq /= 2; break;
91     case 2: as->freq /= 3; break;
92     case 3: as->freq /= 4; break;
93     case 4: as->freq /= 5; break;
94     case 5: as->freq /= 6; break;
95     case 6: as->freq /= 7; break;
96     case 7: as->freq /= 8; break;
97     }
98 
99     switch (format & AC_FMT_BITS_MASK) {
100     case AC_FMT_BITS_8:  as->fmt = AUD_FMT_S8;  break;
101     case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break;
102     case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break;
103     }
104 
105     as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1;
106 }
107 
108 /* -------------------------------------------------------------------------- */
109 /*
110  * HDA codec descriptions
111  */
112 
113 /* some defines */
114 
115 #define QEMU_HDA_ID_VENDOR  0x1af4
116 #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 |       \
117                               0x1fc /* 16 -> 96 kHz */)
118 #define QEMU_HDA_AMP_NONE    (0)
119 #define QEMU_HDA_AMP_STEPS   0x4a
120 
121 #ifdef CONFIG_MIXEMU
122 # define QEMU_HDA_ID_OUTPUT  ((QEMU_HDA_ID_VENDOR << 16) | 0x12)
123 # define QEMU_HDA_ID_DUPLEX  ((QEMU_HDA_ID_VENDOR << 16) | 0x22)
124 # define QEMU_HDA_ID_MICRO   ((QEMU_HDA_ID_VENDOR << 16) | 0x32)
125 # define QEMU_HDA_AMP_CAPS                                              \
126     (AC_AMPCAP_MUTE |                                                   \
127      (QEMU_HDA_AMP_STEPS << AC_AMPCAP_OFFSET_SHIFT)    |                \
128      (QEMU_HDA_AMP_STEPS << AC_AMPCAP_NUM_STEPS_SHIFT) |                \
129      (3                  << AC_AMPCAP_STEP_SIZE_SHIFT))
130 #else
131 # define QEMU_HDA_ID_OUTPUT  ((QEMU_HDA_ID_VENDOR << 16) | 0x11)
132 # define QEMU_HDA_ID_DUPLEX  ((QEMU_HDA_ID_VENDOR << 16) | 0x21)
133 # define QEMU_HDA_ID_MICRO   ((QEMU_HDA_ID_VENDOR << 16) | 0x31)
134 # define QEMU_HDA_AMP_CAPS   QEMU_HDA_AMP_NONE
135 #endif
136 
137 /* common: audio output widget */
138 static const desc_param common_params_audio_dac[] = {
139     {
140         .id  = AC_PAR_AUDIO_WIDGET_CAP,
141         .val = ((AC_WID_AUD_OUT << AC_WCAP_TYPE_SHIFT) |
142                 AC_WCAP_FORMAT_OVRD |
143                 AC_WCAP_AMP_OVRD |
144                 AC_WCAP_OUT_AMP |
145                 AC_WCAP_STEREO),
146     },{
147         .id  = AC_PAR_PCM,
148         .val = QEMU_HDA_PCM_FORMATS,
149     },{
150         .id  = AC_PAR_STREAM,
151         .val = AC_SUPFMT_PCM,
152     },{
153         .id  = AC_PAR_AMP_IN_CAP,
154         .val = QEMU_HDA_AMP_NONE,
155     },{
156         .id  = AC_PAR_AMP_OUT_CAP,
157         .val = QEMU_HDA_AMP_CAPS,
158     },
159 };
160 
161 /* common: audio input widget */
162 static const desc_param common_params_audio_adc[] = {
163     {
164         .id  = AC_PAR_AUDIO_WIDGET_CAP,
165         .val = ((AC_WID_AUD_IN << AC_WCAP_TYPE_SHIFT) |
166                 AC_WCAP_CONN_LIST |
167                 AC_WCAP_FORMAT_OVRD |
168                 AC_WCAP_AMP_OVRD |
169                 AC_WCAP_IN_AMP |
170                 AC_WCAP_STEREO),
171     },{
172         .id  = AC_PAR_CONNLIST_LEN,
173         .val = 1,
174     },{
175         .id  = AC_PAR_PCM,
176         .val = QEMU_HDA_PCM_FORMATS,
177     },{
178         .id  = AC_PAR_STREAM,
179         .val = AC_SUPFMT_PCM,
180     },{
181         .id  = AC_PAR_AMP_IN_CAP,
182         .val = QEMU_HDA_AMP_CAPS,
183     },{
184         .id  = AC_PAR_AMP_OUT_CAP,
185         .val = QEMU_HDA_AMP_NONE,
186     },
187 };
188 
189 /* common: pin widget (line-out) */
190 static const desc_param common_params_audio_lineout[] = {
191     {
192         .id  = AC_PAR_AUDIO_WIDGET_CAP,
193         .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
194                 AC_WCAP_CONN_LIST |
195                 AC_WCAP_STEREO),
196     },{
197         .id  = AC_PAR_PIN_CAP,
198         .val = AC_PINCAP_OUT,
199     },{
200         .id  = AC_PAR_CONNLIST_LEN,
201         .val = 1,
202     },{
203         .id  = AC_PAR_AMP_IN_CAP,
204         .val = QEMU_HDA_AMP_NONE,
205     },{
206         .id  = AC_PAR_AMP_OUT_CAP,
207         .val = QEMU_HDA_AMP_NONE,
208     },
209 };
210 
211 /* common: pin widget (line-in) */
212 static const desc_param common_params_audio_linein[] = {
213     {
214         .id  = AC_PAR_AUDIO_WIDGET_CAP,
215         .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
216                 AC_WCAP_STEREO),
217     },{
218         .id  = AC_PAR_PIN_CAP,
219         .val = AC_PINCAP_IN,
220     },{
221         .id  = AC_PAR_AMP_IN_CAP,
222         .val = QEMU_HDA_AMP_NONE,
223     },{
224         .id  = AC_PAR_AMP_OUT_CAP,
225         .val = QEMU_HDA_AMP_NONE,
226     },
227 };
228 
229 /* output: root node */
230 static const desc_param output_params_root[] = {
231     {
232         .id  = AC_PAR_VENDOR_ID,
233         .val = QEMU_HDA_ID_OUTPUT,
234     },{
235         .id  = AC_PAR_SUBSYSTEM_ID,
236         .val = QEMU_HDA_ID_OUTPUT,
237     },{
238         .id  = AC_PAR_REV_ID,
239         .val = 0x00100101,
240     },{
241         .id  = AC_PAR_NODE_COUNT,
242         .val = 0x00010001,
243     },
244 };
245 
246 /* output: audio function */
247 static const desc_param output_params_audio_func[] = {
248     {
249         .id  = AC_PAR_FUNCTION_TYPE,
250         .val = AC_GRP_AUDIO_FUNCTION,
251     },{
252         .id  = AC_PAR_SUBSYSTEM_ID,
253         .val = QEMU_HDA_ID_OUTPUT,
254     },{
255         .id  = AC_PAR_NODE_COUNT,
256         .val = 0x00020002,
257     },{
258         .id  = AC_PAR_PCM,
259         .val = QEMU_HDA_PCM_FORMATS,
260     },{
261         .id  = AC_PAR_STREAM,
262         .val = AC_SUPFMT_PCM,
263     },{
264         .id  = AC_PAR_AMP_IN_CAP,
265         .val = QEMU_HDA_AMP_NONE,
266     },{
267         .id  = AC_PAR_AMP_OUT_CAP,
268         .val = QEMU_HDA_AMP_NONE,
269     },{
270         .id  = AC_PAR_GPIO_CAP,
271         .val = 0,
272     },{
273         .id  = AC_PAR_AUDIO_FG_CAP,
274         .val = 0x00000808,
275     },{
276         .id  = AC_PAR_POWER_STATE,
277         .val = 0,
278     },
279 };
280 
281 /* output: nodes */
282 static const desc_node output_nodes[] = {
283     {
284         .nid     = AC_NODE_ROOT,
285         .name    = "root",
286         .params  = output_params_root,
287         .nparams = ARRAY_SIZE(output_params_root),
288     },{
289         .nid     = 1,
290         .name    = "func",
291         .params  = output_params_audio_func,
292         .nparams = ARRAY_SIZE(output_params_audio_func),
293     },{
294         .nid     = 2,
295         .name    = "dac",
296         .params  = common_params_audio_dac,
297         .nparams = ARRAY_SIZE(common_params_audio_dac),
298         .stindex = 0,
299     },{
300         .nid     = 3,
301         .name    = "out",
302         .params  = common_params_audio_lineout,
303         .nparams = ARRAY_SIZE(common_params_audio_lineout),
304         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
305                     (AC_JACK_LINE_OUT     << AC_DEFCFG_DEVICE_SHIFT)    |
306                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
307                     (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
308                     0x10),
309         .pinctl  = AC_PINCTL_OUT_EN,
310         .conn    = (uint32_t[]) { 2 },
311     }
312 };
313 
314 /* output: codec */
315 static const desc_codec output = {
316     .name   = "output",
317     .iid    = QEMU_HDA_ID_OUTPUT,
318     .nodes  = output_nodes,
319     .nnodes = ARRAY_SIZE(output_nodes),
320 };
321 
322 /* duplex: root node */
323 static const desc_param duplex_params_root[] = {
324     {
325         .id  = AC_PAR_VENDOR_ID,
326         .val = QEMU_HDA_ID_DUPLEX,
327     },{
328         .id  = AC_PAR_SUBSYSTEM_ID,
329         .val = QEMU_HDA_ID_DUPLEX,
330     },{
331         .id  = AC_PAR_REV_ID,
332         .val = 0x00100101,
333     },{
334         .id  = AC_PAR_NODE_COUNT,
335         .val = 0x00010001,
336     },
337 };
338 
339 /* duplex: audio function */
340 static const desc_param duplex_params_audio_func[] = {
341     {
342         .id  = AC_PAR_FUNCTION_TYPE,
343         .val = AC_GRP_AUDIO_FUNCTION,
344     },{
345         .id  = AC_PAR_SUBSYSTEM_ID,
346         .val = QEMU_HDA_ID_DUPLEX,
347     },{
348         .id  = AC_PAR_NODE_COUNT,
349         .val = 0x00020004,
350     },{
351         .id  = AC_PAR_PCM,
352         .val = QEMU_HDA_PCM_FORMATS,
353     },{
354         .id  = AC_PAR_STREAM,
355         .val = AC_SUPFMT_PCM,
356     },{
357         .id  = AC_PAR_AMP_IN_CAP,
358         .val = QEMU_HDA_AMP_NONE,
359     },{
360         .id  = AC_PAR_AMP_OUT_CAP,
361         .val = QEMU_HDA_AMP_NONE,
362     },{
363         .id  = AC_PAR_GPIO_CAP,
364         .val = 0,
365     },{
366         .id  = AC_PAR_AUDIO_FG_CAP,
367         .val = 0x00000808,
368     },{
369         .id  = AC_PAR_POWER_STATE,
370         .val = 0,
371     },
372 };
373 
374 /* duplex: nodes */
375 static const desc_node duplex_nodes[] = {
376     {
377         .nid     = AC_NODE_ROOT,
378         .name    = "root",
379         .params  = duplex_params_root,
380         .nparams = ARRAY_SIZE(duplex_params_root),
381     },{
382         .nid     = 1,
383         .name    = "func",
384         .params  = duplex_params_audio_func,
385         .nparams = ARRAY_SIZE(duplex_params_audio_func),
386     },{
387         .nid     = 2,
388         .name    = "dac",
389         .params  = common_params_audio_dac,
390         .nparams = ARRAY_SIZE(common_params_audio_dac),
391         .stindex = 0,
392     },{
393         .nid     = 3,
394         .name    = "out",
395         .params  = common_params_audio_lineout,
396         .nparams = ARRAY_SIZE(common_params_audio_lineout),
397         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
398                     (AC_JACK_LINE_OUT     << AC_DEFCFG_DEVICE_SHIFT)    |
399                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
400                     (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
401                     0x10),
402         .pinctl  = AC_PINCTL_OUT_EN,
403         .conn    = (uint32_t[]) { 2 },
404     },{
405         .nid     = 4,
406         .name    = "adc",
407         .params  = common_params_audio_adc,
408         .nparams = ARRAY_SIZE(common_params_audio_adc),
409         .stindex = 1,
410         .conn    = (uint32_t[]) { 5 },
411     },{
412         .nid     = 5,
413         .name    = "in",
414         .params  = common_params_audio_linein,
415         .nparams = ARRAY_SIZE(common_params_audio_linein),
416         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
417                     (AC_JACK_LINE_IN      << AC_DEFCFG_DEVICE_SHIFT)    |
418                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
419                     (AC_JACK_COLOR_RED    << AC_DEFCFG_COLOR_SHIFT)     |
420                     0x20),
421         .pinctl  = AC_PINCTL_IN_EN,
422     }
423 };
424 
425 /* duplex: codec */
426 static const desc_codec duplex = {
427     .name   = "duplex",
428     .iid    = QEMU_HDA_ID_DUPLEX,
429     .nodes  = duplex_nodes,
430     .nnodes = ARRAY_SIZE(duplex_nodes),
431 };
432 
433 /* micro: root node */
434 static const desc_param micro_params_root[] = {
435     {
436         .id  = AC_PAR_VENDOR_ID,
437         .val = QEMU_HDA_ID_MICRO,
438     },{
439         .id  = AC_PAR_SUBSYSTEM_ID,
440         .val = QEMU_HDA_ID_MICRO,
441     },{
442         .id  = AC_PAR_REV_ID,
443         .val = 0x00100101,
444     },{
445         .id  = AC_PAR_NODE_COUNT,
446         .val = 0x00010001,
447     },
448 };
449 
450 /* micro: audio function */
451 static const desc_param micro_params_audio_func[] = {
452     {
453         .id  = AC_PAR_FUNCTION_TYPE,
454         .val = AC_GRP_AUDIO_FUNCTION,
455     },{
456         .id  = AC_PAR_SUBSYSTEM_ID,
457         .val = QEMU_HDA_ID_MICRO,
458     },{
459         .id  = AC_PAR_NODE_COUNT,
460         .val = 0x00020004,
461     },{
462         .id  = AC_PAR_PCM,
463         .val = QEMU_HDA_PCM_FORMATS,
464     },{
465         .id  = AC_PAR_STREAM,
466         .val = AC_SUPFMT_PCM,
467     },{
468         .id  = AC_PAR_AMP_IN_CAP,
469         .val = QEMU_HDA_AMP_NONE,
470     },{
471         .id  = AC_PAR_AMP_OUT_CAP,
472         .val = QEMU_HDA_AMP_NONE,
473     },{
474         .id  = AC_PAR_GPIO_CAP,
475         .val = 0,
476     },{
477         .id  = AC_PAR_AUDIO_FG_CAP,
478         .val = 0x00000808,
479     },{
480         .id  = AC_PAR_POWER_STATE,
481         .val = 0,
482     },
483 };
484 
485 /* micro: nodes */
486 static const desc_node micro_nodes[] = {
487     {
488         .nid     = AC_NODE_ROOT,
489         .name    = "root",
490         .params  = micro_params_root,
491         .nparams = ARRAY_SIZE(micro_params_root),
492     },{
493         .nid     = 1,
494         .name    = "func",
495         .params  = micro_params_audio_func,
496         .nparams = ARRAY_SIZE(micro_params_audio_func),
497     },{
498         .nid     = 2,
499         .name    = "dac",
500         .params  = common_params_audio_dac,
501         .nparams = ARRAY_SIZE(common_params_audio_dac),
502         .stindex = 0,
503     },{
504         .nid     = 3,
505         .name    = "out",
506         .params  = common_params_audio_lineout,
507         .nparams = ARRAY_SIZE(common_params_audio_lineout),
508         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
509                     (AC_JACK_SPEAKER      << AC_DEFCFG_DEVICE_SHIFT)    |
510                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
511                     (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
512                     0x10),
513         .pinctl  = AC_PINCTL_OUT_EN,
514         .conn    = (uint32_t[]) { 2 },
515     },{
516         .nid     = 4,
517         .name    = "adc",
518         .params  = common_params_audio_adc,
519         .nparams = ARRAY_SIZE(common_params_audio_adc),
520         .stindex = 1,
521         .conn    = (uint32_t[]) { 5 },
522     },{
523         .nid     = 5,
524         .name    = "in",
525         .params  = common_params_audio_linein,
526         .nparams = ARRAY_SIZE(common_params_audio_linein),
527         .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
528                     (AC_JACK_MIC_IN       << AC_DEFCFG_DEVICE_SHIFT)    |
529                     (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
530                     (AC_JACK_COLOR_RED    << AC_DEFCFG_COLOR_SHIFT)     |
531                     0x20),
532         .pinctl  = AC_PINCTL_IN_EN,
533     }
534 };
535 
536 /* micro: codec */
537 static const desc_codec micro = {
538     .name   = "micro",
539     .iid    = QEMU_HDA_ID_MICRO,
540     .nodes  = micro_nodes,
541     .nnodes = ARRAY_SIZE(micro_nodes),
542 };
543 
544 /* -------------------------------------------------------------------------- */
545 
546 static const char *fmt2name[] = {
547     [ AUD_FMT_U8  ] = "PCM-U8",
548     [ AUD_FMT_S8  ] = "PCM-S8",
549     [ AUD_FMT_U16 ] = "PCM-U16",
550     [ AUD_FMT_S16 ] = "PCM-S16",
551     [ AUD_FMT_U32 ] = "PCM-U32",
552     [ AUD_FMT_S32 ] = "PCM-S32",
553 };
554 
555 typedef struct HDAAudioState HDAAudioState;
556 typedef struct HDAAudioStream HDAAudioStream;
557 
558 struct HDAAudioStream {
559     HDAAudioState *state;
560     const desc_node *node;
561     bool output, running;
562     uint32_t stream;
563     uint32_t channel;
564     uint32_t format;
565     uint32_t gain_left, gain_right;
566     bool mute_left, mute_right;
567     struct audsettings as;
568     union {
569         SWVoiceIn *in;
570         SWVoiceOut *out;
571     } voice;
572     uint8_t buf[HDA_BUFFER_SIZE];
573     uint32_t bpos;
574 };
575 
576 struct HDAAudioState {
577     HDACodecDevice hda;
578     const char *name;
579 
580     QEMUSoundCard card;
581     const desc_codec *desc;
582     HDAAudioStream st[4];
583     bool running_compat[16];
584     bool running_real[2 * 16];
585 
586     /* properties */
587     uint32_t debug;
588 };
589 
590 static void hda_audio_input_cb(void *opaque, int avail)
591 {
592     HDAAudioStream *st = opaque;
593     int recv = 0;
594     int len;
595     bool rc;
596 
597     while (avail - recv >= sizeof(st->buf)) {
598         if (st->bpos != sizeof(st->buf)) {
599             len = AUD_read(st->voice.in, st->buf + st->bpos,
600                            sizeof(st->buf) - st->bpos);
601             st->bpos += len;
602             recv += len;
603             if (st->bpos != sizeof(st->buf)) {
604                 break;
605             }
606         }
607         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
608                             st->buf, sizeof(st->buf));
609         if (!rc) {
610             break;
611         }
612         st->bpos = 0;
613     }
614 }
615 
616 static void hda_audio_output_cb(void *opaque, int avail)
617 {
618     HDAAudioStream *st = opaque;
619     int sent = 0;
620     int len;
621     bool rc;
622 
623     while (avail - sent >= sizeof(st->buf)) {
624         if (st->bpos == sizeof(st->buf)) {
625             rc = hda_codec_xfer(&st->state->hda, st->stream, true,
626                                 st->buf, sizeof(st->buf));
627             if (!rc) {
628                 break;
629             }
630             st->bpos = 0;
631         }
632         len = AUD_write(st->voice.out, st->buf + st->bpos,
633                         sizeof(st->buf) - st->bpos);
634         st->bpos += len;
635         sent += len;
636         if (st->bpos != sizeof(st->buf)) {
637             break;
638         }
639     }
640 }
641 
642 static void hda_audio_set_running(HDAAudioStream *st, bool running)
643 {
644     if (st->node == NULL) {
645         return;
646     }
647     if (st->running == running) {
648         return;
649     }
650     st->running = running;
651     dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name,
652            st->running ? "on" : "off", st->stream);
653     if (st->output) {
654         AUD_set_active_out(st->voice.out, st->running);
655     } else {
656         AUD_set_active_in(st->voice.in, st->running);
657     }
658 }
659 
660 static void hda_audio_set_amp(HDAAudioStream *st)
661 {
662     bool muted;
663     uint32_t left, right;
664 
665     if (st->node == NULL) {
666         return;
667     }
668 
669     muted = st->mute_left && st->mute_right;
670     left  = st->mute_left  ? 0 : st->gain_left;
671     right = st->mute_right ? 0 : st->gain_right;
672 
673     left = left * 255 / QEMU_HDA_AMP_STEPS;
674     right = right * 255 / QEMU_HDA_AMP_STEPS;
675 
676     if (st->output) {
677         AUD_set_volume_out(st->voice.out, muted, left, right);
678     } else {
679         AUD_set_volume_in(st->voice.in, muted, left, right);
680     }
681 }
682 
683 static void hda_audio_setup(HDAAudioStream *st)
684 {
685     if (st->node == NULL) {
686         return;
687     }
688 
689     dprint(st->state, 1, "%s: format: %d x %s @ %d Hz\n",
690            st->node->name, st->as.nchannels,
691            fmt2name[st->as.fmt], st->as.freq);
692 
693     if (st->output) {
694         st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
695                                      st->node->name, st,
696                                      hda_audio_output_cb, &st->as);
697     } else {
698         st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
699                                    st->node->name, st,
700                                    hda_audio_input_cb, &st->as);
701     }
702 }
703 
704 static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
705 {
706     HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
707     HDAAudioStream *st;
708     const desc_node *node = NULL;
709     const desc_param *param;
710     uint32_t verb, payload, response, count, shift;
711 
712     if ((data & 0x70000) == 0x70000) {
713         /* 12/8 id/payload */
714         verb = (data >> 8) & 0xfff;
715         payload = data & 0x00ff;
716     } else {
717         /* 4/16 id/payload */
718         verb = (data >> 8) & 0xf00;
719         payload = data & 0xffff;
720     }
721 
722     node = hda_codec_find_node(a->desc, nid);
723     if (node == NULL) {
724         goto fail;
725     }
726     dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
727            __FUNCTION__, nid, node->name, verb, payload);
728 
729     switch (verb) {
730     /* all nodes */
731     case AC_VERB_PARAMETERS:
732         param = hda_codec_find_param(node, payload);
733         if (param == NULL) {
734             goto fail;
735         }
736         hda_codec_response(hda, true, param->val);
737         break;
738     case AC_VERB_GET_SUBSYSTEM_ID:
739         hda_codec_response(hda, true, a->desc->iid);
740         break;
741 
742     /* all functions */
743     case AC_VERB_GET_CONNECT_LIST:
744         param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);
745         count = param ? param->val : 0;
746         response = 0;
747         shift = 0;
748         while (payload < count && shift < 32) {
749             response |= node->conn[payload] << shift;
750             payload++;
751             shift += 8;
752         }
753         hda_codec_response(hda, true, response);
754         break;
755 
756     /* pin widget */
757     case AC_VERB_GET_CONFIG_DEFAULT:
758         hda_codec_response(hda, true, node->config);
759         break;
760     case AC_VERB_GET_PIN_WIDGET_CONTROL:
761         hda_codec_response(hda, true, node->pinctl);
762         break;
763     case AC_VERB_SET_PIN_WIDGET_CONTROL:
764         if (node->pinctl != payload) {
765             dprint(a, 1, "unhandled pin control bit\n");
766         }
767         hda_codec_response(hda, true, 0);
768         break;
769 
770     /* audio in/out widget */
771     case AC_VERB_SET_CHANNEL_STREAMID:
772         st = a->st + node->stindex;
773         if (st->node == NULL) {
774             goto fail;
775         }
776         hda_audio_set_running(st, false);
777         st->stream = (payload >> 4) & 0x0f;
778         st->channel = payload & 0x0f;
779         dprint(a, 2, "%s: stream %d, channel %d\n",
780                st->node->name, st->stream, st->channel);
781         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
782         hda_codec_response(hda, true, 0);
783         break;
784     case AC_VERB_GET_CONV:
785         st = a->st + node->stindex;
786         if (st->node == NULL) {
787             goto fail;
788         }
789         response = st->stream << 4 | st->channel;
790         hda_codec_response(hda, true, response);
791         break;
792     case AC_VERB_SET_STREAM_FORMAT:
793         st = a->st + node->stindex;
794         if (st->node == NULL) {
795             goto fail;
796         }
797         st->format = payload;
798         hda_codec_parse_fmt(st->format, &st->as);
799         hda_audio_setup(st);
800         hda_codec_response(hda, true, 0);
801         break;
802     case AC_VERB_GET_STREAM_FORMAT:
803         st = a->st + node->stindex;
804         if (st->node == NULL) {
805             goto fail;
806         }
807         hda_codec_response(hda, true, st->format);
808         break;
809     case AC_VERB_GET_AMP_GAIN_MUTE:
810         st = a->st + node->stindex;
811         if (st->node == NULL) {
812             goto fail;
813         }
814         if (payload & AC_AMP_GET_LEFT) {
815             response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
816         } else {
817             response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);
818         }
819         hda_codec_response(hda, true, response);
820         break;
821     case AC_VERB_SET_AMP_GAIN_MUTE:
822         st = a->st + node->stindex;
823         if (st->node == NULL) {
824             goto fail;
825         }
826         dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
827                st->node->name,
828                (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
829                (payload & AC_AMP_SET_INPUT)  ? "i" : "-",
830                (payload & AC_AMP_SET_LEFT)   ? "l" : "-",
831                (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",
832                (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
833                (payload & AC_AMP_GAIN),
834                (payload & AC_AMP_MUTE) ? "muted" : "");
835         if (payload & AC_AMP_SET_LEFT) {
836             st->gain_left = payload & AC_AMP_GAIN;
837             st->mute_left = payload & AC_AMP_MUTE;
838         }
839         if (payload & AC_AMP_SET_RIGHT) {
840             st->gain_right = payload & AC_AMP_GAIN;
841             st->mute_right = payload & AC_AMP_MUTE;
842         }
843         hda_audio_set_amp(st);
844         hda_codec_response(hda, true, 0);
845         break;
846 
847     /* not supported */
848     case AC_VERB_SET_POWER_STATE:
849     case AC_VERB_GET_POWER_STATE:
850     case AC_VERB_GET_SDI_SELECT:
851         hda_codec_response(hda, true, 0);
852         break;
853     default:
854         goto fail;
855     }
856     return;
857 
858 fail:
859     dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
860            __FUNCTION__, nid, node ? node->name : "?", verb, payload);
861     hda_codec_response(hda, true, 0);
862 }
863 
864 static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
865 {
866     HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
867     int s;
868 
869     a->running_compat[stnr] = running;
870     a->running_real[output * 16 + stnr] = running;
871     for (s = 0; s < ARRAY_SIZE(a->st); s++) {
872         if (a->st[s].node == NULL) {
873             continue;
874         }
875         if (a->st[s].output != output) {
876             continue;
877         }
878         if (a->st[s].stream != stnr) {
879             continue;
880         }
881         hda_audio_set_running(&a->st[s], running);
882     }
883 }
884 
885 static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
886 {
887     HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
888     HDAAudioStream *st;
889     const desc_node *node;
890     const desc_param *param;
891     uint32_t i, type;
892 
893     a->desc = desc;
894     a->name = object_get_typename(OBJECT(a));
895     dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
896 
897     AUD_register_card("hda", &a->card);
898     for (i = 0; i < a->desc->nnodes; i++) {
899         node = a->desc->nodes + i;
900         param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
901         if (NULL == param)
902             continue;
903         type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
904         switch (type) {
905         case AC_WID_AUD_OUT:
906         case AC_WID_AUD_IN:
907             assert(node->stindex < ARRAY_SIZE(a->st));
908             st = a->st + node->stindex;
909             st->state = a;
910             st->node = node;
911             if (type == AC_WID_AUD_OUT) {
912                 /* unmute output by default */
913                 st->gain_left = QEMU_HDA_AMP_STEPS;
914                 st->gain_right = QEMU_HDA_AMP_STEPS;
915                 st->bpos = sizeof(st->buf);
916                 st->output = true;
917             } else {
918                 st->output = false;
919             }
920             st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
921                 (1 << AC_FMT_CHAN_SHIFT);
922             hda_codec_parse_fmt(st->format, &st->as);
923             hda_audio_setup(st);
924             break;
925         }
926     }
927     return 0;
928 }
929 
930 static int hda_audio_exit(HDACodecDevice *hda)
931 {
932     HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
933     HDAAudioStream *st;
934     int i;
935 
936     dprint(a, 1, "%s\n", __FUNCTION__);
937     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
938         st = a->st + i;
939         if (st->node == NULL) {
940             continue;
941         }
942         if (st->output) {
943             AUD_close_out(&a->card, st->voice.out);
944         } else {
945             AUD_close_in(&a->card, st->voice.in);
946         }
947     }
948     AUD_remove_card(&a->card);
949     return 0;
950 }
951 
952 static int hda_audio_post_load(void *opaque, int version)
953 {
954     HDAAudioState *a = opaque;
955     HDAAudioStream *st;
956     int i;
957 
958     dprint(a, 1, "%s\n", __FUNCTION__);
959     if (version == 1) {
960         /* assume running_compat[] is for output streams */
961         for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
962             a->running_real[16 + i] = a->running_compat[i];
963     }
964 
965     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
966         st = a->st + i;
967         if (st->node == NULL)
968             continue;
969         hda_codec_parse_fmt(st->format, &st->as);
970         hda_audio_setup(st);
971         hda_audio_set_amp(st);
972         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
973     }
974     return 0;
975 }
976 
977 static const VMStateDescription vmstate_hda_audio_stream = {
978     .name = "hda-audio-stream",
979     .version_id = 1,
980     .fields = (VMStateField []) {
981         VMSTATE_UINT32(stream, HDAAudioStream),
982         VMSTATE_UINT32(channel, HDAAudioStream),
983         VMSTATE_UINT32(format, HDAAudioStream),
984         VMSTATE_UINT32(gain_left, HDAAudioStream),
985         VMSTATE_UINT32(gain_right, HDAAudioStream),
986         VMSTATE_BOOL(mute_left, HDAAudioStream),
987         VMSTATE_BOOL(mute_right, HDAAudioStream),
988         VMSTATE_UINT32(bpos, HDAAudioStream),
989         VMSTATE_BUFFER(buf, HDAAudioStream),
990         VMSTATE_END_OF_LIST()
991     }
992 };
993 
994 static const VMStateDescription vmstate_hda_audio = {
995     .name = "hda-audio",
996     .version_id = 2,
997     .post_load = hda_audio_post_load,
998     .fields = (VMStateField []) {
999         VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
1000                              vmstate_hda_audio_stream,
1001                              HDAAudioStream),
1002         VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
1003         VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
1004         VMSTATE_END_OF_LIST()
1005     }
1006 };
1007 
1008 static Property hda_audio_properties[] = {
1009     DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
1010     DEFINE_PROP_END_OF_LIST(),
1011 };
1012 
1013 static int hda_audio_init_output(HDACodecDevice *hda)
1014 {
1015     return hda_audio_init(hda, &output);
1016 }
1017 
1018 static int hda_audio_init_duplex(HDACodecDevice *hda)
1019 {
1020     return hda_audio_init(hda, &duplex);
1021 }
1022 
1023 static int hda_audio_init_micro(HDACodecDevice *hda)
1024 {
1025     return hda_audio_init(hda, &micro);
1026 }
1027 
1028 static void hda_audio_output_class_init(ObjectClass *klass, void *data)
1029 {
1030     DeviceClass *dc = DEVICE_CLASS(klass);
1031     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
1032 
1033     k->init = hda_audio_init_output;
1034     k->exit = hda_audio_exit;
1035     k->command = hda_audio_command;
1036     k->stream = hda_audio_stream;
1037     dc->desc = "HDA Audio Codec, output-only (line-out)";
1038     dc->vmsd = &vmstate_hda_audio;
1039     dc->props = hda_audio_properties;
1040 }
1041 
1042 static const TypeInfo hda_audio_output_info = {
1043     .name          = "hda-output",
1044     .parent        = TYPE_HDA_CODEC_DEVICE,
1045     .instance_size = sizeof(HDAAudioState),
1046     .class_init    = hda_audio_output_class_init,
1047 };
1048 
1049 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
1050 {
1051     DeviceClass *dc = DEVICE_CLASS(klass);
1052     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
1053 
1054     k->init = hda_audio_init_duplex;
1055     k->exit = hda_audio_exit;
1056     k->command = hda_audio_command;
1057     k->stream = hda_audio_stream;
1058     dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
1059     dc->vmsd = &vmstate_hda_audio;
1060     dc->props = hda_audio_properties;
1061 }
1062 
1063 static const TypeInfo hda_audio_duplex_info = {
1064     .name          = "hda-duplex",
1065     .parent        = TYPE_HDA_CODEC_DEVICE,
1066     .instance_size = sizeof(HDAAudioState),
1067     .class_init    = hda_audio_duplex_class_init,
1068 };
1069 
1070 static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
1071 {
1072     DeviceClass *dc = DEVICE_CLASS(klass);
1073     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
1074 
1075     k->init = hda_audio_init_micro;
1076     k->exit = hda_audio_exit;
1077     k->command = hda_audio_command;
1078     k->stream = hda_audio_stream;
1079     dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
1080     dc->vmsd = &vmstate_hda_audio;
1081     dc->props = hda_audio_properties;
1082 }
1083 
1084 static const TypeInfo hda_audio_micro_info = {
1085     .name          = "hda-micro",
1086     .parent        = TYPE_HDA_CODEC_DEVICE,
1087     .instance_size = sizeof(HDAAudioState),
1088     .class_init    = hda_audio_micro_class_init,
1089 };
1090 
1091 static void hda_audio_register_types(void)
1092 {
1093     type_register_static(&hda_audio_output_info);
1094     type_register_static(&hda_audio_duplex_info);
1095     type_register_static(&hda_audio_micro_info);
1096 }
1097 
1098 type_init(hda_audio_register_types)
1099