Statistics
| Branch: | Revision:

root / hw / hda-audio.c @ 129dcd2c

History | View | Annotate | Download (25.8 kB)

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.h"
21
#include "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_ID_OUTPUT  ((QEMU_HDA_ID_VENDOR << 16) | 0x10)
117
#define QEMU_HDA_ID_DUPLEX  ((QEMU_HDA_ID_VENDOR << 16) | 0x20)
118

    
119
#define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 |       \
120
                              0x1fc /* 16 -> 96 kHz */)
121
#define QEMU_HDA_AMP_NONE    (0)
122
#define QEMU_HDA_AMP_STEPS   0x4a
123

    
124
#ifdef CONFIG_MIXEMU
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_AMP_CAPS    QEMU_HDA_AMP_NONE
132
#endif
133

    
134
/* common: audio output widget */
135
static const desc_param common_params_audio_dac[] = {
136
    {
137
        .id  = AC_PAR_AUDIO_WIDGET_CAP,
138
        .val = ((AC_WID_AUD_OUT << AC_WCAP_TYPE_SHIFT) |
139
                AC_WCAP_FORMAT_OVRD |
140
                AC_WCAP_AMP_OVRD |
141
                AC_WCAP_OUT_AMP |
142
                AC_WCAP_STEREO),
143
    },{
144
        .id  = AC_PAR_PCM,
145
        .val = QEMU_HDA_PCM_FORMATS,
146
    },{
147
        .id  = AC_PAR_STREAM,
148
        .val = AC_SUPFMT_PCM,
149
    },{
150
        .id  = AC_PAR_AMP_IN_CAP,
151
        .val = QEMU_HDA_AMP_NONE,
152
    },{
153
        .id  = AC_PAR_AMP_OUT_CAP,
154
        .val = QEMU_HDA_AMP_CAPS,
155
    },
156
};
157

    
158
/* common: pin widget (line-out) */
159
static const desc_param common_params_audio_lineout[] = {
160
    {
161
        .id  = AC_PAR_AUDIO_WIDGET_CAP,
162
        .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
163
                AC_WCAP_CONN_LIST |
164
                AC_WCAP_STEREO),
165
    },{
166
        .id  = AC_PAR_PIN_CAP,
167
        .val = AC_PINCAP_OUT,
168
    },{
169
        .id  = AC_PAR_CONNLIST_LEN,
170
        .val = 1,
171
    },{
172
        .id  = AC_PAR_AMP_IN_CAP,
173
        .val = QEMU_HDA_AMP_NONE,
174
    },{
175
        .id  = AC_PAR_AMP_OUT_CAP,
176
        .val = QEMU_HDA_AMP_NONE,
177
    },
178
};
179

    
180
/* output: root node */
181
static const desc_param output_params_root[] = {
182
    {
183
        .id  = AC_PAR_VENDOR_ID,
184
        .val = QEMU_HDA_ID_OUTPUT,
185
    },{
186
        .id  = AC_PAR_SUBSYSTEM_ID,
187
        .val = QEMU_HDA_ID_OUTPUT,
188
    },{
189
        .id  = AC_PAR_REV_ID,
190
        .val = 0x00100101,
191
    },{
192
        .id  = AC_PAR_NODE_COUNT,
193
        .val = 0x00010001,
194
    },
195
};
196

    
197
/* output: audio function */
198
static const desc_param output_params_audio_func[] = {
199
    {
200
        .id  = AC_PAR_FUNCTION_TYPE,
201
        .val = AC_GRP_AUDIO_FUNCTION,
202
    },{
203
        .id  = AC_PAR_SUBSYSTEM_ID,
204
        .val = QEMU_HDA_ID_OUTPUT,
205
    },{
206
        .id  = AC_PAR_NODE_COUNT,
207
        .val = 0x00020002,
208
    },{
209
        .id  = AC_PAR_PCM,
210
        .val = QEMU_HDA_PCM_FORMATS,
211
    },{
212
        .id  = AC_PAR_STREAM,
213
        .val = AC_SUPFMT_PCM,
214
    },{
215
        .id  = AC_PAR_AMP_IN_CAP,
216
        .val = QEMU_HDA_AMP_NONE,
217
    },{
218
        .id  = AC_PAR_AMP_OUT_CAP,
219
        .val = QEMU_HDA_AMP_NONE,
220
    },{
221
        .id  = AC_PAR_GPIO_CAP,
222
        .val = 0,
223
    },{
224
        .id  = AC_PAR_AUDIO_FG_CAP,
225
        .val = 0x00000808,
226
    },{
227
        .id  = AC_PAR_POWER_STATE,
228
        .val = 0,
229
    },
230
};
231

    
232
/* output: nodes */
233
static const desc_node output_nodes[] = {
234
    {
235
        .nid     = AC_NODE_ROOT,
236
        .name    = "root",
237
        .params  = output_params_root,
238
        .nparams = ARRAY_SIZE(output_params_root),
239
    },{
240
        .nid     = 1,
241
        .name    = "func",
242
        .params  = output_params_audio_func,
243
        .nparams = ARRAY_SIZE(output_params_audio_func),
244
    },{
245
        .nid     = 2,
246
        .name    = "dac",
247
        .params  = common_params_audio_dac,
248
        .nparams = ARRAY_SIZE(common_params_audio_dac),
249
        .stindex = 0,
250
    },{
251
        .nid     = 3,
252
        .name    = "out",
253
        .params  = common_params_audio_lineout,
254
        .nparams = ARRAY_SIZE(common_params_audio_lineout),
255
        .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
256
                    (AC_JACK_LINE_OUT     << AC_DEFCFG_DEVICE_SHIFT)    |
257
                    (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
258
                    (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
259
                    0x10),
260
        .pinctl  = AC_PINCTL_OUT_EN,
261
        .conn    = (uint32_t[]) { 2 },
262
    }
263
};
264

    
265
/* output: codec */
266
static const desc_codec output = {
267
    .name   = "output",
268
    .iid    = QEMU_HDA_ID_OUTPUT,
269
    .nodes  = output_nodes,
270
    .nnodes = ARRAY_SIZE(output_nodes),
271
};
272

    
273
/* duplex: root node */
274
static const desc_param duplex_params_root[] = {
275
    {
276
        .id  = AC_PAR_VENDOR_ID,
277
        .val = QEMU_HDA_ID_DUPLEX,
278
    },{
279
        .id  = AC_PAR_SUBSYSTEM_ID,
280
        .val = QEMU_HDA_ID_DUPLEX,
281
    },{
282
        .id  = AC_PAR_REV_ID,
283
        .val = 0x00100101,
284
    },{
285
        .id  = AC_PAR_NODE_COUNT,
286
        .val = 0x00010001,
287
    },
288
};
289

    
290
/* duplex: audio input widget */
291
static const desc_param duplex_params_audio_adc[] = {
292
    {
293
        .id  = AC_PAR_AUDIO_WIDGET_CAP,
294
        .val = ((AC_WID_AUD_IN << AC_WCAP_TYPE_SHIFT) |
295
                AC_WCAP_CONN_LIST |
296
                AC_WCAP_FORMAT_OVRD |
297
                AC_WCAP_AMP_OVRD |
298
                AC_WCAP_IN_AMP |
299
                AC_WCAP_STEREO),
300
    },{
301
        .id  = AC_PAR_CONNLIST_LEN,
302
        .val = 1,
303
    },{
304
        .id  = AC_PAR_PCM,
305
        .val = QEMU_HDA_PCM_FORMATS,
306
    },{
307
        .id  = AC_PAR_STREAM,
308
        .val = AC_SUPFMT_PCM,
309
    },{
310
        .id  = AC_PAR_AMP_IN_CAP,
311
        .val = QEMU_HDA_AMP_CAPS,
312
    },{
313
        .id  = AC_PAR_AMP_OUT_CAP,
314
        .val = QEMU_HDA_AMP_NONE,
315
    },
316
};
317

    
318
/* duplex: pin widget (line-in) */
319
static const desc_param duplex_params_audio_linein[] = {
320
    {
321
        .id  = AC_PAR_AUDIO_WIDGET_CAP,
322
        .val = ((AC_WID_PIN << AC_WCAP_TYPE_SHIFT) |
323
                AC_WCAP_STEREO),
324
    },{
325
        .id  = AC_PAR_PIN_CAP,
326
        .val = AC_PINCAP_IN,
327
    },{
328
        .id  = AC_PAR_AMP_IN_CAP,
329
        .val = QEMU_HDA_AMP_NONE,
330
    },{
331
        .id  = AC_PAR_AMP_OUT_CAP,
332
        .val = QEMU_HDA_AMP_NONE,
333
    },
334
};
335

    
336
/* duplex: audio function */
337
static const desc_param duplex_params_audio_func[] = {
338
    {
339
        .id  = AC_PAR_FUNCTION_TYPE,
340
        .val = AC_GRP_AUDIO_FUNCTION,
341
    },{
342
        .id  = AC_PAR_SUBSYSTEM_ID,
343
        .val = QEMU_HDA_ID_DUPLEX,
344
    },{
345
        .id  = AC_PAR_NODE_COUNT,
346
        .val = 0x00020004,
347
    },{
348
        .id  = AC_PAR_PCM,
349
        .val = QEMU_HDA_PCM_FORMATS,
350
    },{
351
        .id  = AC_PAR_STREAM,
352
        .val = AC_SUPFMT_PCM,
353
    },{
354
        .id  = AC_PAR_AMP_IN_CAP,
355
        .val = QEMU_HDA_AMP_NONE,
356
    },{
357
        .id  = AC_PAR_AMP_OUT_CAP,
358
        .val = QEMU_HDA_AMP_NONE,
359
    },{
360
        .id  = AC_PAR_GPIO_CAP,
361
        .val = 0,
362
    },{
363
        .id  = AC_PAR_AUDIO_FG_CAP,
364
        .val = 0x00000808,
365
    },{
366
        .id  = AC_PAR_POWER_STATE,
367
        .val = 0,
368
    },
369
};
370

    
371
/* duplex: nodes */
372
static const desc_node duplex_nodes[] = {
373
    {
374
        .nid     = AC_NODE_ROOT,
375
        .name    = "root",
376
        .params  = duplex_params_root,
377
        .nparams = ARRAY_SIZE(duplex_params_root),
378
    },{
379
        .nid     = 1,
380
        .name    = "func",
381
        .params  = duplex_params_audio_func,
382
        .nparams = ARRAY_SIZE(duplex_params_audio_func),
383
    },{
384
        .nid     = 2,
385
        .name    = "dac",
386
        .params  = common_params_audio_dac,
387
        .nparams = ARRAY_SIZE(common_params_audio_dac),
388
        .stindex = 0,
389
    },{
390
        .nid     = 3,
391
        .name    = "out",
392
        .params  = common_params_audio_lineout,
393
        .nparams = ARRAY_SIZE(common_params_audio_lineout),
394
        .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
395
                    (AC_JACK_LINE_OUT     << AC_DEFCFG_DEVICE_SHIFT)    |
396
                    (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
397
                    (AC_JACK_COLOR_GREEN  << AC_DEFCFG_COLOR_SHIFT)     |
398
                    0x10),
399
        .pinctl  = AC_PINCTL_OUT_EN,
400
        .conn    = (uint32_t[]) { 2 },
401
    },{
402
        .nid     = 4,
403
        .name    = "adc",
404
        .params  = duplex_params_audio_adc,
405
        .nparams = ARRAY_SIZE(duplex_params_audio_adc),
406
        .stindex = 1,
407
        .conn    = (uint32_t[]) { 5 },
408
    },{
409
        .nid     = 5,
410
        .name    = "in",
411
        .params  = duplex_params_audio_linein,
412
        .nparams = ARRAY_SIZE(duplex_params_audio_linein),
413
        .config  = ((AC_JACK_PORT_COMPLEX << AC_DEFCFG_PORT_CONN_SHIFT) |
414
                    (AC_JACK_LINE_IN      << AC_DEFCFG_DEVICE_SHIFT)    |
415
                    (AC_JACK_CONN_UNKNOWN << AC_DEFCFG_CONN_TYPE_SHIFT) |
416
                    (AC_JACK_COLOR_RED    << AC_DEFCFG_COLOR_SHIFT)     |
417
                    0x20),
418
        .pinctl  = AC_PINCTL_IN_EN,
419
    }
420
};
421

    
422
/* duplex: codec */
423
static const desc_codec duplex = {
424
    .name   = "duplex",
425
    .iid    = QEMU_HDA_ID_DUPLEX,
426
    .nodes  = duplex_nodes,
427
    .nnodes = ARRAY_SIZE(duplex_nodes),
428
};
429

    
430
/* -------------------------------------------------------------------------- */
431

    
432
static const char *fmt2name[] = {
433
    [ AUD_FMT_U8  ] = "PCM-U8",
434
    [ AUD_FMT_S8  ] = "PCM-S8",
435
    [ AUD_FMT_U16 ] = "PCM-U16",
436
    [ AUD_FMT_S16 ] = "PCM-S16",
437
    [ AUD_FMT_U32 ] = "PCM-U32",
438
    [ AUD_FMT_S32 ] = "PCM-S32",
439
};
440

    
441
typedef struct HDAAudioState HDAAudioState;
442
typedef struct HDAAudioStream HDAAudioStream;
443

    
444
struct HDAAudioStream {
445
    HDAAudioState *state;
446
    const desc_node *node;
447
    bool output, running;
448
    uint32_t stream;
449
    uint32_t channel;
450
    uint32_t format;
451
    uint32_t gain_left, gain_right;
452
    bool mute_left, mute_right;
453
    struct audsettings as;
454
    union {
455
        SWVoiceIn *in;
456
        SWVoiceOut *out;
457
    } voice;
458
    uint8_t buf[HDA_BUFFER_SIZE];
459
    uint32_t bpos;
460
};
461

    
462
struct HDAAudioState {
463
    HDACodecDevice hda;
464
    const char *name;
465

    
466
    QEMUSoundCard card;
467
    const desc_codec *desc;
468
    HDAAudioStream st[4];
469
    bool running[16];
470

    
471
    /* properties */
472
    uint32_t debug;
473
};
474

    
475
static void hda_audio_input_cb(void *opaque, int avail)
476
{
477
    HDAAudioStream *st = opaque;
478
    int recv = 0;
479
    int len;
480
    bool rc;
481

    
482
    while (avail - recv >= sizeof(st->buf)) {
483
        if (st->bpos != sizeof(st->buf)) {
484
            len = AUD_read(st->voice.in, st->buf + st->bpos,
485
                           sizeof(st->buf) - st->bpos);
486
            st->bpos += len;
487
            recv += len;
488
            if (st->bpos != sizeof(st->buf)) {
489
                break;
490
            }
491
        }
492
        rc = hda_codec_xfer(&st->state->hda, st->stream, false,
493
                            st->buf, sizeof(st->buf));
494
        if (!rc) {
495
            break;
496
        }
497
        st->bpos = 0;
498
    }
499
}
500

    
501
static void hda_audio_output_cb(void *opaque, int avail)
502
{
503
    HDAAudioStream *st = opaque;
504
    int sent = 0;
505
    int len;
506
    bool rc;
507

    
508
    while (avail - sent >= sizeof(st->buf)) {
509
        if (st->bpos == sizeof(st->buf)) {
510
            rc = hda_codec_xfer(&st->state->hda, st->stream, true,
511
                                st->buf, sizeof(st->buf));
512
            if (!rc) {
513
                break;
514
            }
515
            st->bpos = 0;
516
        }
517
        len = AUD_write(st->voice.out, st->buf + st->bpos,
518
                        sizeof(st->buf) - st->bpos);
519
        st->bpos += len;
520
        sent += len;
521
        if (st->bpos != sizeof(st->buf)) {
522
            break;
523
        }
524
    }
525
}
526

    
527
static void hda_audio_set_running(HDAAudioStream *st, bool running)
528
{
529
    if (st->node == NULL) {
530
        return;
531
    }
532
    if (st->running == running) {
533
        return;
534
    }
535
    st->running = running;
536
    dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name,
537
           st->running ? "on" : "off", st->stream);
538
    if (st->output) {
539
        AUD_set_active_out(st->voice.out, st->running);
540
    } else {
541
        AUD_set_active_in(st->voice.in, st->running);
542
    }
543
}
544

    
545
static void hda_audio_set_amp(HDAAudioStream *st)
546
{
547
    bool muted;
548
    uint32_t left, right;
549

    
550
    if (st->node == NULL) {
551
        return;
552
    }
553

    
554
    muted = st->mute_left && st->mute_right;
555
    left  = st->mute_left  ? 0 : st->gain_left;
556
    right = st->mute_right ? 0 : st->gain_right;
557

    
558
    left = left * 255 / QEMU_HDA_AMP_STEPS;
559
    right = right * 255 / QEMU_HDA_AMP_STEPS;
560

    
561
    if (st->output) {
562
        AUD_set_volume_out(st->voice.out, muted, left, right);
563
    } else {
564
        AUD_set_volume_in(st->voice.in, muted, left, right);
565
    }
566
}
567

    
568
static void hda_audio_setup(HDAAudioStream *st)
569
{
570
    if (st->node == NULL) {
571
        return;
572
    }
573

    
574
    dprint(st->state, 1, "%s: format: %d x %s @ %d Hz\n",
575
           st->node->name, st->as.nchannels,
576
           fmt2name[st->as.fmt], st->as.freq);
577

    
578
    if (st->output) {
579
        st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
580
                                     st->node->name, st,
581
                                     hda_audio_output_cb, &st->as);
582
    } else {
583
        st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
584
                                   st->node->name, st,
585
                                   hda_audio_input_cb, &st->as);
586
    }
587
}
588

    
589
static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
590
{
591
    HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
592
    HDAAudioStream *st;
593
    const desc_node *node = NULL;
594
    const desc_param *param;
595
    uint32_t verb, payload, response, count, shift;
596

    
597
    if ((data & 0x70000) == 0x70000) {
598
        /* 12/8 id/payload */
599
        verb = (data >> 8) & 0xfff;
600
        payload = data & 0x00ff;
601
    } else {
602
        /* 4/16 id/payload */
603
        verb = (data >> 8) & 0xf00;
604
        payload = data & 0xffff;
605
    }
606

    
607
    node = hda_codec_find_node(a->desc, nid);
608
    if (node == NULL) {
609
        goto fail;
610
    }
611
    dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
612
           __FUNCTION__, nid, node->name, verb, payload);
613

    
614
    switch (verb) {
615
    /* all nodes */
616
    case AC_VERB_PARAMETERS:
617
        param = hda_codec_find_param(node, payload);
618
        if (param == NULL) {
619
            goto fail;
620
        }
621
        hda_codec_response(hda, true, param->val);
622
        break;
623
    case AC_VERB_GET_SUBSYSTEM_ID:
624
        hda_codec_response(hda, true, a->desc->iid);
625
        break;
626

    
627
    /* all functions */
628
    case AC_VERB_GET_CONNECT_LIST:
629
        param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);
630
        count = param ? param->val : 0;
631
        response = 0;
632
        shift = 0;
633
        while (payload < count && shift < 32) {
634
            response |= node->conn[payload] << shift;
635
            payload++;
636
            shift += 8;
637
        }
638
        hda_codec_response(hda, true, response);
639
        break;
640

    
641
    /* pin widget */
642
    case AC_VERB_GET_CONFIG_DEFAULT:
643
        hda_codec_response(hda, true, node->config);
644
        break;
645
    case AC_VERB_GET_PIN_WIDGET_CONTROL:
646
        hda_codec_response(hda, true, node->pinctl);
647
        break;
648
    case AC_VERB_SET_PIN_WIDGET_CONTROL:
649
        if (node->pinctl != payload) {
650
            dprint(a, 1, "unhandled pin control bit\n");
651
        }
652
        hda_codec_response(hda, true, 0);
653
        break;
654

    
655
    /* audio in/out widget */
656
    case AC_VERB_SET_CHANNEL_STREAMID:
657
        st = a->st + node->stindex;
658
        if (st->node == NULL) {
659
            goto fail;
660
        }
661
        hda_audio_set_running(st, false);
662
        st->stream = (payload >> 4) & 0x0f;
663
        st->channel = payload & 0x0f;
664
        dprint(a, 2, "%s: stream %d, channel %d\n",
665
               st->node->name, st->stream, st->channel);
666
        hda_audio_set_running(st, a->running[st->stream]);
667
        hda_codec_response(hda, true, 0);
668
        break;
669
    case AC_VERB_GET_CONV:
670
        st = a->st + node->stindex;
671
        if (st->node == NULL) {
672
            goto fail;
673
        }
674
        response = st->stream << 4 | st->channel;
675
        hda_codec_response(hda, true, response);
676
        break;
677
    case AC_VERB_SET_STREAM_FORMAT:
678
        st = a->st + node->stindex;
679
        if (st->node == NULL) {
680
            goto fail;
681
        }
682
        st->format = payload;
683
        hda_codec_parse_fmt(st->format, &st->as);
684
        hda_audio_setup(st);
685
        hda_codec_response(hda, true, 0);
686
        break;
687
    case AC_VERB_GET_STREAM_FORMAT:
688
        st = a->st + node->stindex;
689
        if (st->node == NULL) {
690
            goto fail;
691
        }
692
        hda_codec_response(hda, true, st->format);
693
        break;
694
    case AC_VERB_GET_AMP_GAIN_MUTE:
695
        st = a->st + node->stindex;
696
        if (st->node == NULL) {
697
            goto fail;
698
        }
699
        if (payload & AC_AMP_GET_LEFT) {
700
            response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
701
        } else {
702
            response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);
703
        }
704
        hda_codec_response(hda, true, response);
705
        break;
706
    case AC_VERB_SET_AMP_GAIN_MUTE:
707
        st = a->st + node->stindex;
708
        if (st->node == NULL) {
709
            goto fail;
710
        }
711
        dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
712
               st->node->name,
713
               (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
714
               (payload & AC_AMP_SET_INPUT)  ? "i" : "-",
715
               (payload & AC_AMP_SET_LEFT)   ? "l" : "-",
716
               (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",
717
               (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
718
               (payload & AC_AMP_GAIN),
719
               (payload & AC_AMP_MUTE) ? "muted" : "");
720
        if (payload & AC_AMP_SET_LEFT) {
721
            st->gain_left = payload & AC_AMP_GAIN;
722
            st->mute_left = payload & AC_AMP_MUTE;
723
        }
724
        if (payload & AC_AMP_SET_RIGHT) {
725
            st->gain_right = payload & AC_AMP_GAIN;
726
            st->mute_right = payload & AC_AMP_MUTE;
727
        }
728
        hda_audio_set_amp(st);
729
        hda_codec_response(hda, true, 0);
730
        break;
731

    
732
    /* not supported */
733
    case AC_VERB_SET_POWER_STATE:
734
    case AC_VERB_GET_POWER_STATE:
735
    case AC_VERB_GET_SDI_SELECT:
736
        hda_codec_response(hda, true, 0);
737
        break;
738
    default:
739
        goto fail;
740
    }
741
    return;
742

    
743
fail:
744
    dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
745
           __FUNCTION__, nid, node ? node->name : "?", verb, payload);
746
    hda_codec_response(hda, true, 0);
747
}
748

    
749
static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running)
750
{
751
    HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
752
    int s;
753

    
754
    a->running[stnr] = running;
755
    for (s = 0; s < ARRAY_SIZE(a->st); s++) {
756
        if (a->st[s].node == NULL) {
757
            continue;
758
        }
759
        if (a->st[s].stream != stnr) {
760
            continue;
761
        }
762
        hda_audio_set_running(&a->st[s], running);
763
    }
764
}
765

    
766
static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
767
{
768
    HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
769
    HDAAudioStream *st;
770
    const desc_node *node;
771
    const desc_param *param;
772
    uint32_t i, type;
773

    
774
    a->desc = desc;
775
    a->name = a->hda.qdev.info->name;
776
    dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
777

    
778
    AUD_register_card("hda", &a->card);
779
    for (i = 0; i < a->desc->nnodes; i++) {
780
        node = a->desc->nodes + i;
781
        param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
782
        if (NULL == param)
783
            continue;
784
        type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
785
        switch (type) {
786
        case AC_WID_AUD_OUT:
787
        case AC_WID_AUD_IN:
788
            assert(node->stindex < ARRAY_SIZE(a->st));
789
            st = a->st + node->stindex;
790
            st->state = a;
791
            st->node = node;
792
            if (type == AC_WID_AUD_OUT) {
793
                /* unmute output by default */
794
                st->gain_left = QEMU_HDA_AMP_STEPS;
795
                st->gain_right = QEMU_HDA_AMP_STEPS;
796
                st->bpos = sizeof(st->buf);
797
                st->output = true;
798
            } else {
799
                st->output = false;
800
            }
801
            st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
802
                (1 << AC_FMT_CHAN_SHIFT);
803
            hda_codec_parse_fmt(st->format, &st->as);
804
            hda_audio_setup(st);
805
            break;
806
        }
807
    }
808
    return 0;
809
}
810

    
811
static int hda_audio_exit(HDACodecDevice *hda)
812
{
813
    HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
814
    HDAAudioStream *st;
815
    int i;
816

    
817
    dprint(a, 1, "%s\n", __FUNCTION__);
818
    for (i = 0; i < ARRAY_SIZE(a->st); i++) {
819
        st = a->st + i;
820
        if (st->node == NULL) {
821
            continue;
822
        }
823
        if (st->output) {
824
            AUD_close_out(&a->card, st->voice.out);
825
        } else {
826
            AUD_close_in(&a->card, st->voice.in);
827
        }
828
    }
829
    AUD_remove_card(&a->card);
830
    return 0;
831
}
832

    
833
static int hda_audio_post_load(void *opaque, int version)
834
{
835
    HDAAudioState *a = opaque;
836
    HDAAudioStream *st;
837
    int i;
838

    
839
    dprint(a, 1, "%s\n", __FUNCTION__);
840
    for (i = 0; i < ARRAY_SIZE(a->st); i++) {
841
        st = a->st + i;
842
        if (st->node == NULL)
843
            continue;
844
        hda_codec_parse_fmt(st->format, &st->as);
845
        hda_audio_setup(st);
846
        hda_audio_set_amp(st);
847
        hda_audio_set_running(st, a->running[st->stream]);
848
    }
849
    return 0;
850
}
851

    
852
static const VMStateDescription vmstate_hda_audio_stream = {
853
    .name = "hda-audio-stream",
854
    .version_id = 1,
855
    .fields = (VMStateField []) {
856
        VMSTATE_UINT32(stream, HDAAudioStream),
857
        VMSTATE_UINT32(channel, HDAAudioStream),
858
        VMSTATE_UINT32(format, HDAAudioStream),
859
        VMSTATE_UINT32(gain_left, HDAAudioStream),
860
        VMSTATE_UINT32(gain_right, HDAAudioStream),
861
        VMSTATE_BOOL(mute_left, HDAAudioStream),
862
        VMSTATE_BOOL(mute_right, HDAAudioStream),
863
        VMSTATE_UINT32(bpos, HDAAudioStream),
864
        VMSTATE_BUFFER(buf, HDAAudioStream),
865
        VMSTATE_END_OF_LIST()
866
    }
867
};
868

    
869
static const VMStateDescription vmstate_hda_audio = {
870
    .name = "hda-audio",
871
    .version_id = 1,
872
    .post_load = hda_audio_post_load,
873
    .fields = (VMStateField []) {
874
        VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
875
                             vmstate_hda_audio_stream,
876
                             HDAAudioStream),
877
        VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16),
878
        VMSTATE_END_OF_LIST()
879
    }
880
};
881

    
882
static Property hda_audio_properties[] = {
883
    DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
884
    DEFINE_PROP_END_OF_LIST(),
885
};
886

    
887
static int hda_audio_init_output(HDACodecDevice *hda)
888
{
889
    return hda_audio_init(hda, &output);
890
}
891

    
892
static int hda_audio_init_duplex(HDACodecDevice *hda)
893
{
894
    return hda_audio_init(hda, &duplex);
895
}
896

    
897
static HDACodecDeviceInfo hda_audio_info_output = {
898
    .qdev.name    = "hda-output",
899
    .qdev.desc    = "HDA Audio Codec, output-only",
900
    .qdev.size    = sizeof(HDAAudioState),
901
    .qdev.vmsd    = &vmstate_hda_audio,
902
    .qdev.props   = hda_audio_properties,
903
    .init         = hda_audio_init_output,
904
    .exit         = hda_audio_exit,
905
    .command      = hda_audio_command,
906
    .stream       = hda_audio_stream,
907
};
908

    
909
static HDACodecDeviceInfo hda_audio_info_duplex = {
910
    .qdev.name    = "hda-duplex",
911
    .qdev.desc    = "HDA Audio Codec, duplex",
912
    .qdev.size    = sizeof(HDAAudioState),
913
    .qdev.vmsd    = &vmstate_hda_audio,
914
    .qdev.props   = hda_audio_properties,
915
    .init         = hda_audio_init_duplex,
916
    .exit         = hda_audio_exit,
917
    .command      = hda_audio_command,
918
    .stream       = hda_audio_stream,
919
};
920

    
921
static void hda_audio_register(void)
922
{
923
    hda_codec_register(&hda_audio_info_output);
924
    hda_codec_register(&hda_audio_info_duplex);
925
}
926
device_init(hda_audio_register);