Statistics
| Branch: | Revision:

root / hw / hda-audio.c @ 03f48b07

History | View | Annotate | Download (26.7 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_compat[16];
470
    bool running_real[2 * 16];
471

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
755
    a->running_compat[stnr] = running;
756
    a->running_real[output * 16 + stnr] = running;
757
    for (s = 0; s < ARRAY_SIZE(a->st); s++) {
758
        if (a->st[s].node == NULL) {
759
            continue;
760
        }
761
        if (a->st[s].output != output) {
762
            continue;
763
        }
764
        if (a->st[s].stream != stnr) {
765
            continue;
766
        }
767
        hda_audio_set_running(&a->st[s], running);
768
    }
769
}
770

    
771
static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
772
{
773
    HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
774
    HDAAudioStream *st;
775
    const desc_node *node;
776
    const desc_param *param;
777
    uint32_t i, type;
778

    
779
    a->desc = desc;
780
    a->name = object_get_typename(OBJECT(a));
781
    dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
782

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

    
816
static int hda_audio_exit(HDACodecDevice *hda)
817
{
818
    HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
819
    HDAAudioStream *st;
820
    int i;
821

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

    
838
static int hda_audio_post_load(void *opaque, int version)
839
{
840
    HDAAudioState *a = opaque;
841
    HDAAudioStream *st;
842
    int i;
843

    
844
    dprint(a, 1, "%s\n", __FUNCTION__);
845
    if (version == 1) {
846
        /* assume running_compat[] is for output streams */
847
        for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
848
            a->running_real[16 + i] = a->running_compat[i];
849
    }
850

    
851
    for (i = 0; i < ARRAY_SIZE(a->st); i++) {
852
        st = a->st + i;
853
        if (st->node == NULL)
854
            continue;
855
        hda_codec_parse_fmt(st->format, &st->as);
856
        hda_audio_setup(st);
857
        hda_audio_set_amp(st);
858
        hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
859
    }
860
    return 0;
861
}
862

    
863
static const VMStateDescription vmstate_hda_audio_stream = {
864
    .name = "hda-audio-stream",
865
    .version_id = 1,
866
    .fields = (VMStateField []) {
867
        VMSTATE_UINT32(stream, HDAAudioStream),
868
        VMSTATE_UINT32(channel, HDAAudioStream),
869
        VMSTATE_UINT32(format, HDAAudioStream),
870
        VMSTATE_UINT32(gain_left, HDAAudioStream),
871
        VMSTATE_UINT32(gain_right, HDAAudioStream),
872
        VMSTATE_BOOL(mute_left, HDAAudioStream),
873
        VMSTATE_BOOL(mute_right, HDAAudioStream),
874
        VMSTATE_UINT32(bpos, HDAAudioStream),
875
        VMSTATE_BUFFER(buf, HDAAudioStream),
876
        VMSTATE_END_OF_LIST()
877
    }
878
};
879

    
880
static const VMStateDescription vmstate_hda_audio = {
881
    .name = "hda-audio",
882
    .version_id = 2,
883
    .post_load = hda_audio_post_load,
884
    .fields = (VMStateField []) {
885
        VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
886
                             vmstate_hda_audio_stream,
887
                             HDAAudioStream),
888
        VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
889
        VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
890
        VMSTATE_END_OF_LIST()
891
    }
892
};
893

    
894
static Property hda_audio_properties[] = {
895
    DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
896
    DEFINE_PROP_END_OF_LIST(),
897
};
898

    
899
static int hda_audio_init_output(HDACodecDevice *hda)
900
{
901
    return hda_audio_init(hda, &output);
902
}
903

    
904
static int hda_audio_init_duplex(HDACodecDevice *hda)
905
{
906
    return hda_audio_init(hda, &duplex);
907
}
908

    
909
static void hda_audio_output_class_init(ObjectClass *klass, void *data)
910
{
911
    DeviceClass *dc = DEVICE_CLASS(klass);
912
    HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
913

    
914
    k->init = hda_audio_init_output;
915
    k->exit = hda_audio_exit;
916
    k->command = hda_audio_command;
917
    k->stream = hda_audio_stream;
918
    dc->desc = "HDA Audio Codec, output-only";
919
    dc->vmsd = &vmstate_hda_audio;
920
    dc->props = hda_audio_properties;
921
}
922

    
923
static TypeInfo hda_audio_output_info = {
924
    .name          = "hda-output",
925
    .parent        = TYPE_HDA_CODEC_DEVICE,
926
    .instance_size = sizeof(HDAAudioState),
927
    .class_init    = hda_audio_output_class_init,
928
};
929

    
930
static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
931
{
932
    DeviceClass *dc = DEVICE_CLASS(klass);
933
    HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
934

    
935
    k->init = hda_audio_init_duplex;
936
    k->exit = hda_audio_exit;
937
    k->command = hda_audio_command;
938
    k->stream = hda_audio_stream;
939
    dc->desc = "HDA Audio Codec, duplex";
940
    dc->vmsd = &vmstate_hda_audio;
941
    dc->props = hda_audio_properties;
942
}
943

    
944
static TypeInfo hda_audio_duplex_info = {
945
    .name          = "hda-duplex",
946
    .parent        = TYPE_HDA_CODEC_DEVICE,
947
    .instance_size = sizeof(HDAAudioState),
948
    .class_init    = hda_audio_duplex_class_init,
949
};
950

    
951
static void hda_audio_register_types(void)
952
{
953
    type_register_static(&hda_audio_output_info);
954
    type_register_static(&hda_audio_duplex_info);
955
}
956

    
957
type_init(hda_audio_register_types)