Statistics
| Branch: | Revision:

root / hw / audio / hda-codec.c @ 47b43a1f

History | View | Annotate | Download (31 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/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)