1
/* $Id: DevCodec.cpp 35515 2011-01-13 07:35:07Z vboxsync $ */
3
* DevCodec - VBox ICH Intel HD Audio Codec.
7
* Copyright (C) 2006-2008 Oracle Corporation
9
* This file is part of VirtualBox Open Source Edition (OSE), as
10
* available from http://www.virtualbox.org. This file is free software;
11
* you can redistribute it and/or modify it under the terms of the GNU
12
* General Public License (GPL) as published by the Free Software
13
* Foundation, in version 2 as it comes in the "COPYING" file of the
14
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17
#define LOG_GROUP LOG_GROUP_DEV_AUDIO
18
#include <VBox/vmm/pdmdev.h>
19
#include <iprt/assert.h>
20
#include <iprt/uuid.h>
21
#include <iprt/string.h>
24
#include <iprt/cpp/utils.h>
32
#define CODECNODE_F0_PARAM_LENGTH 0x14
33
#define CODECNODE_F02_PARAM_LENGTH 16
34
typedef struct CODECCOMMONNODE
36
uint8_t id; /* 7 - bit format */
39
uint32_t au32F00_param[CODECNODE_F0_PARAM_LENGTH];
40
uint32_t au32F02_param[CODECNODE_F02_PARAM_LENGTH];
41
} CODECCOMMONNODE, *PCODECCOMMONNODE;
43
typedef struct ROOTCODECNODE
46
}ROOTCODECNODE, *PROOTCODECNODE;
48
#define AMPLIFIER_SIZE 60
49
typedef uint32_t AMPLIFIER[AMPLIFIER_SIZE];
50
#define AMPLIFIER_IN 0
51
#define AMPLIFIER_OUT 1
52
#define AMPLIFIER_LEFT 1
53
#define AMPLIFIER_RIGHT 0
54
#define AMPLIFIER_REGISTER(amp, inout, side, index) ((amp)[30*(inout) + 15*(side) + (index)])
55
typedef struct DACNODE
58
uint32_t u32F0d_param;
59
uint32_t u32F04_param;
60
uint32_t u32F05_param;
61
uint32_t u32F06_param;
62
uint32_t u32F0c_param;
69
typedef struct ADCNODE
72
uint32_t u32F03_param;
73
uint32_t u32F05_param;
74
uint32_t u32F06_param;
75
uint32_t u32F09_param;
78
uint32_t u32F01_param;
82
typedef struct SPDIFOUTNODE
85
uint32_t u32F05_param;
86
uint32_t u32F06_param;
87
uint32_t u32F09_param;
88
uint32_t u32F0d_param;
92
} SPDIFOUTNODE, *PSPDIFOUTNODE;
94
typedef struct SPDIFINNODE
97
uint32_t u32F05_param;
98
uint32_t u32F06_param;
99
uint32_t u32F09_param;
100
uint32_t u32F0d_param;
104
} SPDIFINNODE, *PSPDIFINNODE;
106
typedef struct AFGCODECNODE
108
CODECCOMMONNODE node;
109
uint32_t u32F05_param;
110
uint32_t u32F08_param;
111
uint32_t u32F20_param;
112
uint32_t u32F17_param;
113
} AFGCODECNODE, *PAFGCODECNODE;
115
typedef struct PORTNODE
117
CODECCOMMONNODE node;
118
uint32_t u32F07_param;
119
uint32_t u32F08_param;
120
uint32_t u32F09_param;
121
uint32_t u32F01_param;
122
uint32_t u32F1c_param;
124
} PORTNODE, *PPORTNODE;
126
typedef struct DIGOUTNODE
128
CODECCOMMONNODE node;
129
uint32_t u32F01_param;
130
uint32_t u32F08_param;
131
uint32_t u32F07_param;
132
uint32_t u32F09_param;
133
uint32_t u32F1c_param;
134
} DIGOUTNODE, *PDIGOUTNODE;
136
typedef struct DIGINNODE
138
CODECCOMMONNODE node;
139
uint32_t u32F05_param;
140
uint32_t u32F07_param;
141
uint32_t u32F08_param;
142
uint32_t u32F09_param;
143
uint32_t u32F0c_param;
144
uint32_t u32F1c_param;
145
uint32_t u32F1e_param;
146
} DIGINNODE, *PDIGINNODE;
148
typedef struct ADCMUXNODE
150
CODECCOMMONNODE node;
151
uint32_t u32F01_param;
155
} ADCMUXNODE, *PADCMUXNODE;
157
typedef struct PCBEEPNODE
159
CODECCOMMONNODE node;
160
uint32_t u32F07_param;
161
uint32_t u32F0a_param;
165
uint32_t u32F1c_param;
166
} PCBEEPNODE, *PPCBEEPNODE;
168
typedef struct CDNODE
170
CODECCOMMONNODE node;
171
uint32_t u32F07_param;
172
uint32_t u32F1c_param;
175
typedef struct VOLUMEKNOBNODE
177
CODECCOMMONNODE node;
178
uint32_t u32F08_param;
179
uint32_t u32F0f_param;
180
} VOLUMEKNOBNODE, *PVOLUMEKNOBNODE;
182
typedef struct ADCVOLNODE
184
CODECCOMMONNODE node;
185
uint32_t u32F0c_param;
186
uint32_t u32F01_param;
187
uint32_t u32A_params;
189
} ADCVOLNODE, *PADCVOLNODE;
191
typedef struct RESNODE
193
CODECCOMMONNODE node;
194
uint32_t u32F05_param;
195
uint32_t u32F06_param;
196
uint32_t u32F07_param;
197
uint32_t u32F1c_param;
198
} RESNODE, *PRESNODE;
200
typedef union CODECNODE
202
CODECCOMMONNODE node;
207
SPDIFOUTNODE spdifout;
215
VOLUMEKNOBNODE volumeKnob;
218
} CODECNODE, *PCODECNODE;
221
const static uint8_t au8Stac9220Ports[] = { 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0};
222
const static uint8_t au8Stac9220Dacs[] = { 0x2, 0x3, 0x4, 0x5, 0};
223
const static uint8_t au8Stac9220Adcs[] = { 0x6, 0x7, 0};
224
const static uint8_t au8Stac9220SpdifOuts[] = { 0x8, 0 };
225
const static uint8_t au8Stac9220SpdifIns[] = { 0x9, 0 };
226
const static uint8_t au8Stac9220DigOutPins[] = { 0x10, 0 };
227
const static uint8_t au8Stac9220DigInPins[] = { 0x11, 0 };
228
const static uint8_t au8Stac9220AdcVols[] = { 0x17, 0x18, 0};
229
const static uint8_t au8Stac9220AdcMuxs[] = { 0x12, 0x13, 0};
230
const static uint8_t au8Stac9220Pcbeeps[] = { 0x14, 0 };
231
const static uint8_t au8Stac9220Cds[] = { 0x15, 0 };
232
const static uint8_t au8Stac9220VolKnobs[] = { 0x16, 0 };
233
const static uint8_t au8Stac9220Reserveds[] = { 0x9, 0x19, 0x1a, 0x1b, 0 };
235
static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
237
static int stac9220Construct(CODECState *pState)
239
unconst(pState->cTotalNodes) = 0x1C;
240
pState->pfnCodecNodeReset = stac9220ResetNode;
241
pState->u16VendorId = 0x8384;
242
pState->u16DeviceId = 0x7680;
243
pState->u8BSKU = 0x76;
244
pState->u8AssemblyId = 0x80;
245
pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes);
246
pState->fInReset = false;
247
#define STAC9220WIDGET(type) pState->au8##type##s = au8Stac9220##type##s
248
STAC9220WIDGET(Port);
251
STAC9220WIDGET(AdcVol);
252
STAC9220WIDGET(AdcMux);
253
STAC9220WIDGET(Pcbeep);
254
STAC9220WIDGET(SpdifIn);
255
STAC9220WIDGET(SpdifOut);
256
STAC9220WIDGET(DigInPin);
257
STAC9220WIDGET(DigOutPin);
259
STAC9220WIDGET(VolKnob);
260
STAC9220WIDGET(Reserved);
261
#undef STAC9220WIDGET
262
unconst(pState->u8AdcVolsLineIn) = 0x17;
263
unconst(pState->u8DacLineOut) = 0x2;
268
static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode)
270
pNode->node.id = nodenum;
271
pNode->node.au32F00_param[0xF] = 0; /* Power statest Supported: are the same as AFG reports */
276
pNode->root.node.name = "Root";
277
pNode->node.au32F00_param[2] = CODEC_MAKE_F00_02(0x1, 0x0, 0x34, 0x1); /* rev id */
280
pNode->afg.node.name = "AFG";
281
pNode->node.au32F00_param[8] = CODEC_MAKE_F00_08(CODEC_F00_08_BEEP_GEN, 0xd, 0xd);
282
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
283
| CODEC_F00_0C_CAP_BALANCED_IO
284
| CODEC_F00_0C_CAP_INPUT
285
| CODEC_F00_0C_CAP_PRESENSE_DETECT
286
| CODEC_F00_0C_CAP_TRIGGER_REQUIRED
287
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//(17 << 8)|RT_BIT(6)|RT_BIT(5)|RT_BIT(2)|RT_BIT(1)|RT_BIT(0);
288
pNode->node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
289
pNode->node.au32F00_param[0xD] = CODEC_MAKE_F00_0D(1, 0x5, 0xE, 0);//RT_BIT(31)|(0x5 << 16)|(0xE)<<8;
290
pNode->node.au32F00_param[0x12] = RT_BIT(31)|(0x2 << 16)|(0x7f << 8)|0x7f;
291
pNode->node.au32F00_param[0x11] = CODEC_MAKE_F00_11(1, 1, 0, 0, 4);//0xc0000004;
292
pNode->node.au32F00_param[0xF] = CODEC_F00_0F_D3|CODEC_F00_0F_D2|CODEC_F00_0F_D1|CODEC_F00_0F_D0;
293
pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2);//0x2 << 4| 0x2; /* PS-Act: D3, PS->Set D3 */
294
pNode->afg.u32F08_param = 0;
295
pNode->afg.u32F17_param = 0;
298
pNode->dac.node.name = "DAC0";
301
pNode->dac.node.name = "DAC1";
304
pNode->dac.node.name = "DAC2";
307
pNode->dac.node.name = "DAC3";
309
memset(pNode->dac.B_params, 0, AMPLIFIER_SIZE);
310
pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 4)|0x1; /* 441000Hz/16bit/2ch */
312
AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) = 0x7F | RT_BIT(7);
313
AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) = 0x7F | RT_BIT(7);
315
pNode->dac.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0xD, 0)
316
| CODEC_F00_09_CAP_L_R_SWAP
317
| CODEC_F00_09_CAP_POWER_CTRL
318
| CODEC_F00_09_CAP_OUT_AMP_PRESENT
319
| CODEC_F00_09_CAP_LSB;//(0xD << 16) | RT_BIT(11) | RT_BIT(10) | RT_BIT(2) | RT_BIT(0);
320
pNode->dac.u32F0c_param = 0;
321
pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3 */
324
pNode->adc.node.name = "ADC0";
325
pNode->node.au32F02_param[0] = 0x17;
328
pNode->adc.node.name = "ADC1";
329
pNode->node.au32F02_param[0] = 0x18;
331
pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 3)|0x1; /* 441000Hz/16bit/2ch */
332
pNode->adc.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//RT_BIT(0);
333
pNode->adc.u32F03_param = RT_BIT(0);
334
pNode->adc.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 Set: D3 */
335
pNode->adc.u32F06_param = 0;
336
pNode->adc.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0xD, 0)
337
| CODEC_F00_09_CAP_POWER_CTRL
338
| CODEC_F00_09_CAP_CONNECTION_LIST
339
| CODEC_F00_09_CAP_PROC_WIDGET
340
| CODEC_F00_09_CAP_LSB;//RT_BIT(20)| (0xd << 16) | RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0);
343
pNode->spdifout.node.name = "SPDIFOut";
344
pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
345
pNode->spdifout.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x4, 0)
346
| CODEC_F00_09_CAP_DIGITAL
347
| CODEC_F00_09_CAP_FMT_OVERRIDE
348
| CODEC_F00_09_CAP_LSB;//(4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
349
pNode->node.au32F00_param[0xa] = pState->pNodes[1].node.au32F00_param[0xA];
350
pNode->spdifout.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
351
pNode->spdifout.u32F06_param = 0;
352
pNode->spdifout.u32F0d_param = 0;
355
pNode->node.name = "Reserved_0";
356
pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(0x1<<4) | 0x1;
357
pNode->spdifin.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0x4, 0)
358
| CODEC_F00_09_CAP_DIGITAL
359
| CODEC_F00_09_CAP_CONNECTION_LIST
360
| CODEC_F00_09_CAP_FMT_OVERRIDE
361
| CODEC_F00_09_CAP_LSB;//(0x1 << 20)|(4 << 16) | RT_BIT(9)| RT_BIT(8)|RT_BIT(4)|0x1;
362
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
363
pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//RT_BIT(0);
364
pNode->node.au32F02_param[0] = 0x11;
365
pNode->spdifin.node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
366
pNode->spdifin.u32F06_param = 0;
367
pNode->spdifin.u32F0d_param = 0;
370
pNode->node.name = "PortA";
371
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
372
| CODEC_F00_0C_CAP_INPUT
373
| CODEC_F00_0C_CAP_OUTPUT
374
| CODEC_F00_0C_CAP_HP
375
| CODEC_F00_0C_CAP_PRESENSE_DETECT
376
| CODEC_F00_0C_CAP_TRIGGER_REQUIRED
377
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x173f;
378
pNode->node.au32F02_param[0] = 0x2;
379
pNode->port.u32F07_param = CODEC_F07_IN_ENABLE
380
| CODEC_F07_OUT_ENABLE;
381
pNode->port.u32F08_param = 0;
382
if (!pState->fInReset)
383
pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
384
CODEC_F1C_LOCATION_FRONT,
386
CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
387
CODEC_F1C_COLOR_GREEN,
388
CODEC_F1C_MISC_JACK_DETECT,
389
0x2, 0);//RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02);
392
pNode->node.name = "PortB";
393
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
394
| CODEC_F00_0C_CAP_INPUT
395
| CODEC_F00_0C_CAP_OUTPUT
396
| CODEC_F00_0C_CAP_PRESENSE_DETECT
397
| CODEC_F00_0C_CAP_TRIGGER_REQUIRED
398
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
399
pNode->node.au32F02_param[0] = 0x4;
400
pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
401
if (!pState->fInReset)
402
pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
403
CODEC_F1C_LOCATION_INTERNAL|CODEC_F1C_LOCATION_REAR,
404
CODEC_F1C_DEVICE_SPEAKER,
405
CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
406
CODEC_F1C_COLOR_BLACK,
407
CODEC_F1C_MISC_JACK_DETECT,
408
0x1, 0x1);//RT_MAKE_U32_FROM_U8(0x11, 0x60, 0x11, 0x01);
411
pNode->node.name = "PortC";
412
pNode->node.au32F02_param[0] = 0x3;
413
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
414
| CODEC_F00_0C_CAP_INPUT
415
| CODEC_F00_0C_CAP_OUTPUT
416
| CODEC_F00_0C_CAP_PRESENSE_DETECT
417
| CODEC_F00_0C_CAP_TRIGGER_REQUIRED
418
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
419
pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
420
if (!pState->fInReset)
421
pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
422
CODEC_F1C_LOCATION_REAR,
423
CODEC_F1C_DEVICE_SPEAKER,
424
CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
425
CODEC_F1C_COLOR_GREEN,
426
0x0, 0x1, 0x0);//RT_MAKE_U32_FROM_U8(0x10, 0x40, 0x11, 0x01);
429
pNode->node.name = "PortD";
430
pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17)
431
| CODEC_F00_0C_CAP_INPUT
432
| CODEC_F00_0C_CAP_OUTPUT
433
| CODEC_F00_0C_CAP_PRESENSE_DETECT
434
| CODEC_F00_0C_CAP_TRIGGER_REQUIRED
435
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
436
pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
437
pNode->node.au32F02_param[0] = 0x2;
438
if (!pState->fInReset)
439
pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
440
CODEC_F1C_LOCATION_FRONT,
441
CODEC_F1C_DEVICE_MIC,
442
CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
443
CODEC_F1C_COLOR_PINK,
444
0x0, 0x5, 0x0);//RT_MAKE_U32_FROM_U8(0x50, 0x90, 0xA1, 0x02); /* Microphone */
446
pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff;
447
pNode->port.u32F08_param = 0;
448
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0)
449
| CODEC_F00_09_CAP_CONNECTION_LIST
450
| CODEC_F00_09_CAP_UNSOL
451
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(0);
452
pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1;
455
pNode->node.name = "PortE";
456
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0)
457
| CODEC_F00_09_CAP_UNSOL
458
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(7)|RT_BIT(0);
459
pNode->port.u32F08_param = 0;
460
pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT
461
| CODEC_F00_0C_CAP_OUTPUT
462
| CODEC_F00_0C_CAP_PRESENSE_DETECT;//0x34;
463
pNode->port.u32F07_param = CODEC_F07_IN_ENABLE;
464
pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff;
465
if (!pState->fInReset)
466
pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
467
CODEC_F1C_LOCATION_REAR,
468
CODEC_F1C_DEVICE_LINE_OUT,
469
CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
470
CODEC_F1C_COLOR_BLUE,
471
0x0, 0x4, 0x0);//0x01013040; /* Line Out */
474
pNode->node.name = "PortF";
475
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0)
476
| CODEC_F00_09_CAP_CONNECTION_LIST
477
| CODEC_F00_09_CAP_UNSOL
478
| CODEC_F00_09_CAP_OUT_AMP_PRESENT
479
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(2)|RT_BIT(0);
480
pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT
481
| CODEC_F00_0C_CAP_OUTPUT
482
| CODEC_F00_0C_CAP_PRESENSE_DETECT
483
/* | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
484
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE */;//0x37;
485
pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1;
486
pNode->port.u32F08_param = 0;
487
pNode->port.u32F07_param = CODEC_F07_OUT_ENABLE
488
| CODEC_F07_IN_ENABLE;
489
if (!pState->fInReset)
490
pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
491
CODEC_F1C_LOCATION_INTERNAL,
492
CODEC_F1C_DEVICE_SPEAKER,
493
CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
494
CODEC_F1C_COLOR_ORANGE,
495
0x0, 0x1, 0x2);//RT_MAKE_U32_FROM_U8(0x12, 0x60, 0x11, 0x01);
496
pNode->node.au32F02_param[0] = 0x5;
497
pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff;
500
pNode->node.name = "DigOut_0";
501
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0)
502
| CODEC_F00_09_CAP_DIGITAL
503
| CODEC_F00_09_CAP_CONNECTION_LIST
504
| CODEC_F00_09_CAP_LSB;//(4<<20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
505
pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;//RT_BIT(4);
506
pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 0x3);
507
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x08, 0x17, 0x19, 0);
508
if (!pState->fInReset)
509
pNode->digout.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
510
CODEC_F1C_LOCATION_REAR,
511
CODEC_F1C_DEVICE_SPDIF_OUT,
512
CODEC_F1C_CONNECTION_TYPE_DIN,
513
CODEC_F1C_COLOR_BLACK,
514
0x0, 0x3, 0x0);//RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01);
517
pNode->node.name = "DigIn_0";
518
pNode->node.au32F00_param[9] = (4 << 20)|(3<<16)|RT_BIT(10)|RT_BIT(9)|RT_BIT(7)|RT_BIT(0);
519
pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_EAPD
520
| CODEC_F00_0C_CAP_INPUT
521
| CODEC_F00_0C_CAP_PRESENSE_DETECT;//RT_BIT(16)| RT_BIT(5)|RT_BIT(2);
522
pNode->digin.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 -> D3 */
523
pNode->digin.u32F07_param = 0;
524
pNode->digin.u32F08_param = 0;
525
pNode->digin.u32F09_param = 0;
526
pNode->digin.u32F0c_param = 0;
527
if (!pState->fInReset)
528
pNode->digin.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
529
CODEC_F1C_LOCATION_REAR,
530
CODEC_F1C_DEVICE_SPDIF_IN,
531
CODEC_F1C_CONNECTION_TYPE_OTHER_DIGITAL,
532
CODEC_F1C_COLOR_BLACK,
533
0x0, 0x6, 0x0);//(0x1 << 24) | (0xc5 << 16) | (0x10 << 8) | 0x60;
536
pNode->node.name = "ADCMux_0";
537
pNode->adcmux.u32F01_param = 0;
540
pNode->node.name = "ADCMux_1";
541
pNode->adcmux.u32F01_param = 1;
543
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0x0, 0)
544
| CODEC_F00_09_CAP_CONNECTION_LIST
545
| CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
546
| CODEC_F00_09_CAP_OUT_AMP_PRESENT
547
| CODEC_F00_09_CAP_LSB;//(3<<20)|RT_BIT(8)|RT_BIT(3)|RT_BIT(2)|RT_BIT(0);
548
pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x7);
549
pNode->node.au32F00_param[0x12] = (0x27 << 16)|(0x4 << 8);
550
/* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplefiers inited with 0*/
551
memset(pNode->adcmux.B_params, 0, AMPLIFIER_SIZE);
552
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xe, 0x15, 0xf, 0xb);
553
pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0xc, 0xd, 0xa, 0x0);
556
pNode->node.name = "PCBEEP";
557
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0)
558
| CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
559
| CODEC_F00_09_CAP_OUT_AMP_PRESENT;//(7 << 20) | RT_BIT(3) | RT_BIT(2);
560
pNode->node.au32F00_param[0x12] = (0x17 << 16)|(0x3 << 8)| 0x3;
561
pNode->pcbeep.u32F0a_param = 0;
562
memset(pNode->pcbeep.B_params, 0, AMPLIFIER_SIZE);
565
pNode->node.name = "CD";
566
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
567
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(0);
568
pNode->node.au32F00_param[0xc] = CODEC_F00_0C_CAP_INPUT;//RT_BIT(5);
569
if (!pState->fInReset)
570
pNode->cdnode.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_FIXED,
571
CODEC_F1C_LOCATION_INTERNAL,
573
CODEC_F1C_CONNECTION_TYPE_ATAPI,
574
CODEC_F1C_COLOR_UNKNOWN,
575
0x0, 0x7, 0x0);//RT_MAKE_U32_FROM_U8(0x70, 0x0, 0x33, 0x90);
578
pNode->node.name = "VolumeKnob";
579
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0x0, 0x0);//(0x6 << 20);
580
pNode->node.au32F00_param[0x13] = RT_BIT(7)| 0x7F;
581
pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x4);
582
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x2, 0x3, 0x4, 0x5);
583
pNode->volumeKnob.u32F08_param = 0;
584
pNode->volumeKnob.u32F0f_param = 0x7f;
587
pNode->node.name = "ADC0Vol";
588
pNode->node.au32F02_param[0] = 0x12;
591
pNode->node.name = "ADC1Vol";
592
pNode->node.au32F02_param[0] = 0x13;
594
memset(pNode->adcvol.B_params, 0, AMPLIFIER_SIZE);
596
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0)
597
| CODEC_F00_09_CAP_L_R_SWAP
598
| CODEC_F00_09_CAP_CONNECTION_LIST
599
| CODEC_F00_09_CAP_IN_AMP_PRESENT
600
| CODEC_F00_09_CAP_LSB;//(0x3 << 20)|RT_BIT(11)|RT_BIT(8)|RT_BIT(1)|RT_BIT(0);
601
pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x1);
602
AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(7);
603
AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(7);
604
pNode->adcvol.u32F0c_param = 0;
607
pNode->node.name = "Reserved_1";
608
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VENDOR_DEFINED, 0x3, 0)
609
| CODEC_F00_09_CAP_DIGITAL
610
| CODEC_F00_09_CAP_LSB;//(0xF << 20)|(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
613
pNode->node.name = "Reserved_2";
614
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x3, 0)
615
| CODEC_F00_09_CAP_DIGITAL
616
| CODEC_F00_09_CAP_LSB;//(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
619
pNode->node.name = "Reserved_3";
620
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
621
| CODEC_F00_09_CAP_DIGITAL
622
| CODEC_F00_09_CAP_CONNECTION_LIST
623
| CODEC_F00_09_CAP_LSB;//(0x4 << 20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
624
pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 0x1);
625
pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;//0x10;
626
pNode->node.au32F02_param[0] = 0x1a;
627
pNode->reserved.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_NO_PHYS,
628
CODEC_F1C_LOCATION_NA,
629
CODEC_F1C_DEVICE_LINE_OUT,
630
CODEC_F1C_CONNECTION_TYPE_UNKNOWN,
631
CODEC_F1C_COLOR_UNKNOWN,
632
0x0, 0x0, 0xf);//0x4000000f;
641
const static uint8_t au8Alc885Ports[] = { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0};
642
const static uint8_t au8Alc885Dacs[] = { 0x2, 0x3, 0x4, 0x5, 0x25, 0};
643
const static uint8_t au8Alc885Adcs[] = { 0x7, 0x8, 0x9, 0};
644
const static uint8_t au8Alc885SpdifOuts[] = { 0x6, 0 };
645
const static uint8_t au8Alc885SpdifIns[] = { 0xA, 0 };
646
const static uint8_t au8Alc885DigOutPins[] = { 0x1E, 0 };
647
const static uint8_t au8Alc885DigInPins[] = { 0x1F, 0 };
648
const static uint8_t au8Alc885AdcVols[] = { 0xE, 0xF, 0xD, 0xC, 0x26, 0xB, 0};
649
const static uint8_t au8Alc885AdcMuxs[] = { 0x22, 0x23, 0x24, 0};
650
const static uint8_t au8Alc885Pcbeeps[] = { 0x1D, 0 };
651
const static uint8_t au8Alc885Cds[] = { 0x1C, 0 };
652
const static uint8_t au8Alc885VolKnobs[] = { 0x21, 0 };
653
const static uint8_t au8Alc885Reserveds[] = { 0x10, 0x11, 0x12, 0x13, 0 };
656
static int alc885ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
658
static int alc885Construct(CODECState *pState)
660
unconst(pState->cTotalNodes) = 0x27;
661
pState->u16VendorId = 0x10ec;
662
pState->u16DeviceId = 0x0885;
663
pState->u8BSKU = 0x08;
664
pState->u8AssemblyId = 0x85;
665
pState->pfnCodecNodeReset = alc885ResetNode;
666
pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes);
667
pState->fInReset = false;
668
#define ALC885WIDGET(type) pState->au8##type##s = au8Alc885##type##s
672
ALC885WIDGET(AdcVol);
673
ALC885WIDGET(AdcMux);
674
ALC885WIDGET(Pcbeep);
675
ALC885WIDGET(SpdifIn);
676
ALC885WIDGET(SpdifOut);
677
ALC885WIDGET(DigInPin);
678
ALC885WIDGET(DigOutPin);
680
ALC885WIDGET(VolKnob);
681
ALC885WIDGET(Reserved);
683
/* @todo: test more */
684
unconst(pState->u8AdcVolsLineIn) = 0x1a;
685
unconst(pState->u8DacLineOut) = 0x0d;
690
static int alc885ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode)
692
pNode->node.id = nodenum;
696
pNode->node.au32F00_param[2] = CODEC_MAKE_F00_02(0x1, 0x0, 0x0, 0x0); /* Realtek 889 (8.1.9)*/
697
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
701
pNode->node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
702
pNode->node.au32F00_param[0x11] = RT_BIT(30)|0x2;
706
pNode->node.name = "DAC-0";
709
pNode->node.name = "DAC-1";
712
pNode->node.name = "DAC-2";
715
pNode->node.name = "DAC-3";
718
pNode->node.name = "DAC-4";
720
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
721
pNode->node.au32F00_param[0x9] = 0x11;
722
pNode->node.au32F00_param[0xB] = CODEC_F00_0B_PCM;
723
pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
727
pNode->node.name = "SPDIFOUT-0";
728
pNode->node.au32F00_param[0x9] = 0x211;
729
pNode->node.au32F00_param[0xB] = 0x1;
730
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
731
pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
734
pNode->node.name = "SPDIFIN-0";
735
pNode->node.au32F00_param[0x9] = 0x100391;
736
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
737
pNode->node.au32F00_param[0xB] = 0x1;
738
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
739
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
740
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
741
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x1F, 0, 0, 0);
742
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
743
pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
747
pNode->node.name = "VENDEF-0";
748
goto vendor_define_init;
750
pNode->node.name = "VENDEF-1";
751
goto vendor_define_init;
753
pNode->node.name = "VENDEF-2";
754
goto vendor_define_init;
756
pNode->node.name = "VENDEF-3";
757
goto vendor_define_init;
759
pNode->node.name = "VENDEF-4";
761
pNode->node.au32F00_param[0x9] = 0xf00000;
766
pNode->node.name = "DIGOUT-1";
767
pNode->node.au32F00_param[0x9] = 0x400300;
768
pNode->node.au32F00_param[0xE] = 0x1;
769
pNode->port.u32F1c_param = 0x14be060;
770
pNode->node.au32F00_param[0xC] = RT_BIT(4);
772
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
773
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
774
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
775
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x6, 0x0, 0x0, 0x0);
778
pNode->node.name = "DIGIN-0";
779
pNode->node.au32F00_param[9] = 0x400200;
781
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
782
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
783
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
784
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0xA, 0x0, 0x0, 0x0);
788
pNode->node.name = "ADC-0";
789
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
790
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
791
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
792
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x23, 0, 0, 0);
796
pNode->node.name = "ADC-1";
797
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
798
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
799
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
800
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x24, 0, 0, 0);
804
pNode->node.name = "ADC-2";
805
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
806
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
807
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
808
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x22, 0, 0, 0);
810
pNode->node.au32F00_param[0xB] = 0x1;
811
pNode->node.au32F00_param[0x9] = 0x10011b;
812
pNode->node.au32F00_param[0xD] = 0x80032e10;
813
pNode->node.au32F00_param[0xE] = 0x1;
814
pNode->node.au32F00_param[0xA] = pState->pNodes[1].node.au32F00_param[0xA];
815
pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
819
pNode->node.name = "PORT-D";
820
pNode->port.u32F1c_param = 0x12b4050;
821
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
825
pNode->node.name = "PORT-A";
826
pNode->port.u32F1c_param = 0x18b3020;
827
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
831
pNode->node.name = "PORT-G";
832
pNode->port.u32F1c_param = 0x400000f0;
833
pNode->node.au32F00_param[0xC] = RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
837
pNode->node.name = "PORT-H";
838
pNode->port.u32F1c_param = 0x400000f0;
839
pNode->node.au32F00_param[0xC] = RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
843
pNode->node.name = "PORT-B";
844
pNode->port.u32F1c_param = 0x90100140;
845
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
849
pNode->node.name = "PORT-F";
850
pNode->port.u32F1c_param = 0x90a00110;
851
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
855
pNode->node.name = "PORT-C";
856
pNode->port.u32F1c_param = 0x90100141;
857
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
861
pNode->node.name = "PORT-E";
862
pNode->port.u32F1c_param = 0x400000f0;
863
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
865
pNode->node.au32F00_param[0x9] = 0x40018f;
866
pNode->node.au32F00_param[0xD] = 0x270300;
867
pNode->node.au32F00_param[0xE] = 0x5;
869
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
870
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
871
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
872
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0xC, 0xD, 0xE, 0xF);
874
pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
875
pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
876
pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
877
pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x26, 0, 0, 0);
881
pNode->node.name = "AdcVol-0";
882
pNode->node.au32F00_param[0x9] = 0x20010f;
883
pNode->node.au32F00_param[0xD] = 0x80000000;
884
pNode->node.au32F00_param[0xE] = 0x2;
885
pNode->node.au32F00_param[0x12] = 0x34040;
886
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
887
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
888
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
889
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x25, 0xB, 0, 0);
892
pNode->node.name = "AdcVol-1";
893
pNode->node.au32F00_param[0x9] = 0x20010f;
894
pNode->node.au32F00_param[0xE] = 0x2;
895
pNode->node.au32F00_param[0x12] = 0x34040;
896
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
897
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
898
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
899
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x5, 0xB, 0, 0);
902
pNode->node.name = "AdcVol-2";
903
pNode->node.au32F00_param[0x9] = 0x20010f;
904
pNode->node.au32F00_param[0xE] = 0x2;
905
pNode->node.au32F00_param[0xD] = 0x80000000;
906
pNode->node.au32F00_param[0x12] = 0x34040;
907
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
908
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
909
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
910
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x4, 0xB, 0, 0);
913
pNode->node.name = "AdcVol-3";
914
pNode->node.au32F00_param[0x9] = 0x20010f;
915
pNode->node.au32F00_param[0xE] = 0x2;
916
pNode->node.au32F00_param[0xD] = 0x80000000;
917
pNode->node.au32F00_param[0x12] = 0x34040;
918
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
919
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
920
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
921
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x3, 0xB, 0, 0);
924
pNode->node.name = "AdcVol-4";
925
pNode->node.au32F00_param[0x9] = 0x20010f;
926
pNode->node.au32F00_param[0xE] = 0x2;
927
pNode->node.au32F00_param[0xD] = 0x80000000;
928
pNode->node.au32F00_param[0x12] = 0x34040;
929
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
930
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
931
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
932
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x2, 0xB, 0, 0);
935
pNode->node.name = "AdcVol-5";
936
pNode->node.au32F00_param[0x9] = 0x20010b;
937
pNode->node.au32F00_param[0xD] = 0x80051f17;
939
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
940
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
941
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
942
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
944
pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
945
pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
946
pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
947
pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
949
pNode->node.au32F02_param[8] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
950
pNode->node.au32F02_param[9] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
951
pNode->node.au32F02_param[10] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
952
pNode->node.au32F02_param[11] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0, 0);
956
pNode->node.name = "AdcMux-0";
957
pNode->node.au32F00_param[0x9] = 0x20010b;
958
pNode->node.au32F00_param[0xD] = 0x80000000;
959
pNode->node.au32F00_param[0xE] = 0xb;
962
pNode->node.name = "AdcMux-1";
963
pNode->node.au32F00_param[0x9] = 0x20010b;
964
pNode->node.au32F00_param[0xD] = 0x80000000;
965
pNode->node.au32F00_param[0xE] = 0xb;
968
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
969
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
970
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
971
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
973
pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
974
pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
975
pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
976
pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
978
pNode->node.au32F02_param[8] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
979
pNode->node.au32F02_param[9] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
980
pNode->node.au32F02_param[10] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
981
pNode->node.au32F02_param[11] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0);
984
pNode->node.name = "AdcMux-2";
985
pNode->node.au32F00_param[0x9] = 0x20010b;
986
pNode->node.au32F00_param[0xD] = 0x80000000;
987
pNode->node.au32F00_param[0xE] = 0xb;
989
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
990
pNode->node.au32F02_param[1] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
991
pNode->node.au32F02_param[2] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
992
pNode->node.au32F02_param[3] = RT_MAKE_U32_FROM_U8(0x18, 0x19, 0x1A, 0x1B);
994
pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
995
pNode->node.au32F02_param[5] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
996
pNode->node.au32F02_param[6] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
997
pNode->node.au32F02_param[7] = RT_MAKE_U32_FROM_U8(0x1C, 0x1D, 0x14, 0x15);
999
pNode->node.au32F02_param[8] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
1000
pNode->node.au32F02_param[9] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
1001
pNode->node.au32F02_param[10] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
1002
pNode->node.au32F02_param[11] = RT_MAKE_U32_FROM_U8(0x16, 0x17, 0xB, 0x12);
1006
pNode->node.name = "PCBEEP";
1007
pNode->node.au32F00_param[0x9] = 0x400000;
1008
pNode->port.u32F1c_param = 0x400000f0;
1009
pNode->node.au32F00_param[0xC] = RT_BIT(5);
1013
pNode->node.name = "CD";
1014
pNode->node.au32F00_param[0x9] = 0x400001;
1015
pNode->port.u32F1c_param = 0x400000f0;
1016
pNode->node.au32F00_param[0xC] = RT_BIT(5);
1019
pNode->node.name = "VolumeKnob";
1020
pNode->node.au32F00_param[0x9] = (0x6 << 20)|RT_BIT(7);
1023
AssertMsgFailed(("Unsupported Node"));
1025
return VINF_SUCCESS;
1031
#define DECLISNODEOFTYPE(type) \
1032
static inline int codecIs##type##Node(struct CODECState *pState, uint8_t cNode) \
1034
Assert(pState->au8##type##s); \
1035
for(int i = 0; pState->au8##type##s[i] != 0; ++i) \
1036
if (pState->au8##type##s[i] == cNode) \
1040
/* codecIsPortNode */
1041
DECLISNODEOFTYPE(Port)
1042
/* codecIsDacNode */
1043
DECLISNODEOFTYPE(Dac)
1044
/* codecIsAdcVolNode */
1045
DECLISNODEOFTYPE(AdcVol)
1046
/* codecIsAdcNode */
1047
DECLISNODEOFTYPE(Adc)
1048
/* codecIsAdcMuxNode */
1049
DECLISNODEOFTYPE(AdcMux)
1050
/* codecIsPcbeepNode */
1051
DECLISNODEOFTYPE(Pcbeep)
1052
/* codecIsSpdifOutNode */
1053
DECLISNODEOFTYPE(SpdifOut)
1054
/* codecIsSpdifInNode */
1055
DECLISNODEOFTYPE(SpdifIn)
1056
/* codecIsDigInPinNode */
1057
DECLISNODEOFTYPE(DigInPin)
1058
/* codecIsDigOutPinNode */
1059
DECLISNODEOFTYPE(DigOutPin)
1061
DECLISNODEOFTYPE(Cd)
1062
/* codecIsVolKnobNode */
1063
DECLISNODEOFTYPE(VolKnob)
1064
/* codecIsReservedNode */
1065
DECLISNODEOFTYPE(Reserved)
1067
static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt);
1069
static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask)
1071
Assert((pu32Reg && u8Offset < 32));
1072
*pu32Reg &= ~(mask << u8Offset);
1073
*pu32Reg |= (u32Cmd & mask) << u8Offset;
1075
static inline void codecSetRegisterU8(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
1077
codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_8BIT_DATA);
1080
static inline void codecSetRegisterU16(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
1082
codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_16BIT_DATA);
1086
static int codecUnimplemented(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1088
Log(("codecUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
1089
CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
1091
return VINF_SUCCESS;
1094
static int codecBreak(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1097
rc = codecUnimplemented(pState, cmd, pResp);
1098
*pResp |= CODEC_RESPONSE_UNSOLICITED;
1102
static int codecGetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1104
Assert((CODEC_CAD(cmd) == pState->id));
1105
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1106
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1108
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1109
return VINF_SUCCESS;
1112
/* HDA spec 7.3.3.7 Note A */
1113
/* @todo: if index out of range response should be 0 */
1114
uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT? 0 : CODEC_GET_AMP_INDEX(cmd);
1116
PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
1117
if (codecIsDacNode(pState, CODEC_NID(cmd)))
1118
*pResp = AMPLIFIER_REGISTER(pNode->dac.B_params,
1119
CODEC_GET_AMP_DIRECTION(cmd),
1120
CODEC_GET_AMP_SIDE(cmd),
1122
else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
1123
*pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params,
1124
CODEC_GET_AMP_DIRECTION(cmd),
1125
CODEC_GET_AMP_SIDE(cmd),
1127
else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
1128
*pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params,
1129
CODEC_GET_AMP_DIRECTION(cmd),
1130
CODEC_GET_AMP_SIDE(cmd),
1132
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
1133
*pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
1134
CODEC_GET_AMP_DIRECTION(cmd),
1135
CODEC_GET_AMP_SIDE(cmd),
1137
else if (codecIsPortNode(pState, CODEC_NID(cmd)))
1138
*pResp = AMPLIFIER_REGISTER(pNode->port.B_params,
1139
CODEC_GET_AMP_DIRECTION(cmd),
1140
CODEC_GET_AMP_SIDE(cmd),
1142
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1143
*pResp = AMPLIFIER_REGISTER(pNode->adc.B_params,
1144
CODEC_GET_AMP_DIRECTION(cmd),
1145
CODEC_GET_AMP_SIDE(cmd),
1148
AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
1150
return VINF_SUCCESS;
1153
static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1155
AMPLIFIER *pAmplifier = NULL;
1156
bool fIsLeft = false;
1157
bool fIsRight = false;
1158
bool fIsOut = false;
1160
uint8_t u8Index = 0;
1161
Assert((CODEC_CAD(cmd) == pState->id));
1162
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1164
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1165
return VINF_SUCCESS;
1168
PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
1169
if (codecIsDacNode(pState, CODEC_NID(cmd)))
1170
pAmplifier = &pNode->dac.B_params;
1171
else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
1172
pAmplifier = &pNode->adcvol.B_params;
1173
else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
1174
pAmplifier = &pNode->adcmux.B_params;
1175
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
1176
pAmplifier = &pNode->pcbeep.B_params;
1177
else if (codecIsPortNode(pState, CODEC_NID(cmd)))
1178
pAmplifier = &pNode->port.B_params;
1179
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1180
pAmplifier = &pNode->adc.B_params;
1184
fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
1185
fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
1186
fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
1187
fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
1188
u8Index = CODEC_SET_AMP_INDEX(cmd);
1189
if ( (!fIsLeft && !fIsRight)
1190
|| (!fIsOut && !fIsIn))
1191
return VINF_SUCCESS;
1195
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
1197
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
1202
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
1204
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
1206
if (CODEC_NID(cmd) == pState->u8DacLineOut)
1207
codecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
1208
if (CODEC_NID(cmd) == pState->u8AdcVolsLineIn) /* Microphone */
1209
codecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
1211
return VINF_SUCCESS;
1214
static int codecGetParameter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1216
Assert((CODEC_CAD(cmd) == pState->id));
1217
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1219
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1220
return VINF_SUCCESS;
1222
Assert(((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F0_PARAM_LENGTH));
1223
if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F0_PARAM_LENGTH)
1225
Log(("HDAcodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
1226
return VINF_SUCCESS;
1229
*pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA];
1230
return VINF_SUCCESS;
1234
static int codecGetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1236
Assert((CODEC_CAD(cmd) == pState->id));
1237
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1238
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1240
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1241
return VINF_SUCCESS;
1244
if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
1245
*pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
1246
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1247
*pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
1248
else if (codecIsPortNode(pState, CODEC_NID(cmd)))
1249
*pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F01_param;
1250
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1251
*pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F01_param;
1252
else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
1253
*pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
1254
return VINF_SUCCESS;
1258
static int codecSetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1260
uint32_t *pu32Reg = NULL;
1261
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1262
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1264
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1265
return VINF_SUCCESS;
1268
if (codecIsAdcMuxNode(pState, CODEC_NID(cmd)))
1269
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
1270
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1271
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
1272
else if (codecIsPortNode(pState, CODEC_NID(cmd)))
1273
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F01_param;
1274
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1275
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F01_param;
1276
else if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
1277
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
1280
codecSetRegisterU8(pu32Reg, cmd, 0);
1281
return VINF_SUCCESS;
1285
static int codecGetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1287
Assert((CODEC_CAD(cmd) == pState->id));
1288
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1289
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1291
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1292
return VINF_SUCCESS;
1295
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1296
*pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
1297
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1298
*pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
1299
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1300
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
1301
else if (codecIsCdNode(pState, CODEC_NID(cmd)))
1302
*pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
1303
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
1304
*pResp = pState->pNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
1305
else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
1306
*pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
1308
AssertMsgFailed(("Unsupported"));
1309
return VINF_SUCCESS;
1313
static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1315
Assert((CODEC_CAD(cmd) == pState->id));
1316
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1317
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1319
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1320
return VINF_SUCCESS;
1323
uint32_t *pu32Reg = NULL;
1324
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1325
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
1326
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1327
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
1328
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1329
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
1330
else if (codecIsCdNode(pState, CODEC_NID(cmd)))
1331
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
1332
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
1333
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].pcbeep.u32F07_param;
1334
else if ( codecIsReservedNode(pState, CODEC_NID(cmd))
1335
&& CODEC_NID(cmd) == 0x1b
1336
&& pState->enmCodec == STAC9220_CODEC)
1337
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param;
1340
codecSetRegisterU8(pu32Reg, cmd, 0);
1341
return VINF_SUCCESS;
1345
static int codecGetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1347
Assert((CODEC_CAD(cmd) == pState->id));
1348
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1349
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1351
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1352
return VINF_SUCCESS;
1355
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1356
*pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
1357
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1358
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
1359
else if ((cmd) == 1 /* AFG */)
1360
*pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
1361
else if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
1362
*pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
1363
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1364
*pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F08_param;
1365
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1366
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
1368
AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
1369
return VINF_SUCCESS;
1373
static int codecSetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1375
Assert((CODEC_CAD(cmd) == pState->id));
1376
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1377
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1379
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1380
return VINF_SUCCESS;
1383
uint32_t *pu32Reg = NULL;
1384
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1385
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
1386
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1387
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
1388
else if (CODEC_NID(cmd) == 1 /* AFG */)
1389
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
1390
else if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
1391
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
1392
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1393
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
1394
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1395
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F08_param;
1397
AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
1400
codecSetRegisterU8(pu32Reg, cmd, 0);
1401
return VINF_SUCCESS;
1405
static int codecGetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1407
Assert((CODEC_CAD(cmd) == pState->id));
1408
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1409
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1411
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1412
return VINF_SUCCESS;
1415
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1416
*pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F09_param;
1417
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1418
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param;
1420
AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
1421
return VINF_SUCCESS;
1425
static int codecSetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1427
Assert((CODEC_CAD(cmd) == pState->id));
1428
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1429
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1431
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1432
return VINF_SUCCESS;
1435
uint32_t *pu32Reg = NULL;
1436
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1437
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F09_param;
1438
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1439
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param;
1442
codecSetRegisterU8(pu32Reg, cmd, 0);
1443
return VINF_SUCCESS;
1446
static int codecGetConnectionListEntry(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1448
Assert((CODEC_CAD(cmd) == pState->id));
1449
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1451
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1453
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1454
return VINF_SUCCESS;
1456
Assert((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F02_PARAM_LENGTH);
1457
if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F02_PARAM_LENGTH)
1459
Log(("HDAcodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
1460
return VINF_SUCCESS;
1462
*pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F02_param[cmd & CODEC_VERB_8BIT_DATA];
1463
return VINF_SUCCESS;
1466
static int codecGetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1468
Assert((CODEC_CAD(cmd) == pState->id));
1469
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1470
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1472
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1473
return VINF_SUCCESS;
1476
if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1477
*pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param;
1478
return VINF_SUCCESS;
1482
static int codecSetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1484
Assert((CODEC_CAD(cmd) == pState->id));
1485
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1486
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1488
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1489
return VINF_SUCCESS;
1492
if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1494
codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0);
1496
return VINF_SUCCESS;
1500
static int codecGetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1502
Assert((CODEC_CAD(cmd) == pState->id));
1503
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1504
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1506
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1507
return VINF_SUCCESS;
1510
if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1511
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
1512
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1513
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
1514
return VINF_SUCCESS;
1517
static int codecSetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset, uint64_t *pResp)
1519
Assert((CODEC_CAD(cmd) == pState->id));
1520
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1521
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1523
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1524
return VINF_SUCCESS;
1527
if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1528
codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset);
1529
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1530
codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset);
1531
return VINF_SUCCESS;
1535
static int codecSetDigitalConverter1(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1537
return codecSetDigitalConverter(pState, cmd, 0, pResp);
1541
static int codecSetDigitalConverter2(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1543
return codecSetDigitalConverter(pState, cmd, 8, pResp);
1547
static int codecGetSubId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1549
Assert((CODEC_CAD(cmd) == pState->id));
1550
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1551
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1553
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1554
return VINF_SUCCESS;
1557
if (CODEC_NID(cmd) == 1 /* AFG */)
1559
*pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param;
1561
return VINF_SUCCESS;
1564
static int codecSetSubIdX(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset)
1566
Assert((CODEC_CAD(cmd) == pState->id));
1567
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1568
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1570
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1571
return VINF_SUCCESS;
1573
uint32_t *pu32Reg = NULL;
1574
if (CODEC_NID(cmd) == 0x1 /* AFG */)
1575
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param;
1578
codecSetRegisterU8(pu32Reg, cmd, u8Offset);
1579
return VINF_SUCCESS;
1582
static int codecSetSubId0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1585
return codecSetSubIdX(pState, cmd, 0);
1589
static int codecSetSubId1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1592
return codecSetSubIdX(pState, cmd, 8);
1595
static int codecSetSubId2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1598
return codecSetSubIdX(pState, cmd, 16);
1601
static int codecSetSubId3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1604
return codecSetSubIdX(pState, cmd, 24);
1607
static int codecReset(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1609
Assert((CODEC_CAD(cmd) == pState->id));
1610
Assert(CODEC_NID(cmd) == 1 /* AFG */);
1611
if(CODEC_NID(cmd) == 1 /* AFG */)
1614
Log(("HDAcodec: enters reset\n"));
1615
Assert(pState->pfnCodecNodeReset);
1616
for (i = 0; i < pState->cTotalNodes; ++i)
1618
pState->pfnCodecNodeReset(pState, i, &pState->pNodes[i]);
1620
pState->fInReset = false;
1621
Log(("HDAcodec: exits reset\n"));
1624
return VINF_SUCCESS;
1628
static int codecGetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1630
Assert((CODEC_CAD(cmd) == pState->id));
1631
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1632
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1634
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1635
return VINF_SUCCESS;
1638
if (CODEC_NID(cmd) == 1 /* AFG */)
1639
*pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
1640
else if (codecIsDacNode(pState, CODEC_NID(cmd)))
1641
*pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
1642
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1643
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
1644
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1645
*pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
1646
else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1647
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
1648
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1649
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
1650
else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
1651
*pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F05_param;
1652
return VINF_SUCCESS;
1657
static inline void codecPropogatePowerState(uint32_t *pu32F05_param)
1659
Assert(pu32F05_param);
1662
bool fReset = CODEC_F05_IS_RESET(*pu32F05_param);
1663
bool fStopOk = CODEC_F05_IS_STOPOK(*pu32F05_param);
1664
uint8_t u8SetPowerState = CODEC_F05_SET(*pu32F05_param);
1665
*pu32F05_param = CODEC_MAKE_F05(fReset, fStopOk, 0, u8SetPowerState, u8SetPowerState);
1668
static int codecSetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1670
Assert((CODEC_CAD(cmd) == pState->id));
1671
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1672
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1674
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1675
return VINF_SUCCESS;
1677
uint32_t *pu32Reg = NULL;
1679
if (CODEC_NID(cmd) == 1 /* AFG */)
1680
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
1681
else if (codecIsDacNode(pState, CODEC_NID(cmd)))
1682
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
1683
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1684
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
1685
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1686
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
1687
else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1688
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F05_param;
1689
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1690
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F05_param;
1691
else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
1692
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F05_param;
1695
return VINF_SUCCESS;
1697
bool fReset = CODEC_F05_IS_RESET(*pu32Reg);
1698
bool fStopOk = CODEC_F05_IS_STOPOK(*pu32Reg);
1700
if (CODEC_NID(cmd) != 1 /* AFG */)
1703
* We shouldn't propogate actual power state, which actual for AFG
1705
*pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0,
1706
CODEC_F05_ACT(pState->pNodes[1].afg.u32F05_param),
1707
CODEC_F05_SET(cmd));
1710
/* Propagate next power state only if AFG is on or verb modifies AFG power state */
1711
if ( CODEC_NID(cmd) == 1 /* AFG */
1712
|| !CODEC_F05_ACT(pState->pNodes[1].afg.u32F05_param))
1714
*pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, CODEC_F05_SET(cmd), CODEC_F05_SET(cmd));
1715
if ( CODEC_NID(cmd) == 1 /* AFG */
1716
&& (CODEC_F05_SET(cmd)) == CODEC_F05_D0)
1718
/* now we're powered on AFG and may propogate power states on nodes */
1719
const uint8_t *pu8NodeIndex = &pState->au8Dacs[0];
1720
while (*(++pu8NodeIndex))
1721
codecPropogatePowerState(&pState->pNodes[*pu8NodeIndex].dac.u32F05_param);
1723
pu8NodeIndex = &pState->au8Adcs[0];
1724
while (*(++pu8NodeIndex))
1725
codecPropogatePowerState(&pState->pNodes[*pu8NodeIndex].adc.u32F05_param);
1727
pu8NodeIndex = &pState->au8DigInPins[0];
1728
while (*(++pu8NodeIndex))
1729
codecPropogatePowerState(&pState->pNodes[*pu8NodeIndex].digin.u32F05_param);
1732
return VINF_SUCCESS;
1735
static int codecGetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1737
Assert((CODEC_CAD(cmd) == pState->id));
1738
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1739
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1741
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1742
return VINF_SUCCESS;
1745
if (codecIsDacNode(pState, CODEC_NID(cmd)))
1746
*pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
1747
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1748
*pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
1749
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1750
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
1751
else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1752
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
1753
else if (CODEC_NID(cmd) == 0x1A)
1754
*pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param;
1755
return VINF_SUCCESS;
1757
static int codecSetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1759
Assert((CODEC_CAD(cmd) == pState->id));
1760
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1761
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1763
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1764
return VINF_SUCCESS;
1767
uint32_t *pu32addr = NULL;
1769
if (codecIsDacNode(pState, CODEC_NID(cmd)))
1770
pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
1771
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1772
pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
1773
else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1774
pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
1775
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1776
pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
1777
else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
1778
pu32addr = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param;
1781
codecSetRegisterU8(pu32addr, cmd, 0);
1782
return VINF_SUCCESS;
1785
static int codecGetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1787
Assert((CODEC_CAD(cmd) == pState->id));
1788
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1789
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1791
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1792
return VINF_SUCCESS;
1795
if (codecIsDacNode(pState, CODEC_NID(cmd)))
1796
*pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32A_param;
1797
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1798
*pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32A_param;
1799
else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1800
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param;
1801
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1802
*pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param;
1803
return VINF_SUCCESS;
1806
static int codecSetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1808
Assert((CODEC_CAD(cmd) == pState->id));
1809
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1810
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1812
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1813
return VINF_SUCCESS;
1816
if (codecIsDacNode(pState, CODEC_NID(cmd)))
1817
codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0);
1818
else if (codecIsAdcNode(pState, CODEC_NID(cmd)))
1819
codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0);
1820
else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd)))
1821
codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0);
1822
else if (codecIsSpdifInNode(pState, CODEC_NID(cmd)))
1823
codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
1824
return VINF_SUCCESS;
1828
static int codecGetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1830
Assert((CODEC_CAD(cmd) == pState->id));
1831
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1832
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1834
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1835
return VINF_SUCCESS;
1838
if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
1839
*pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
1840
else if (codecIsDacNode(pState, CODEC_NID(cmd)))
1841
*pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
1842
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1843
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
1844
return VINF_SUCCESS;
1848
static int codecSetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1850
Assert((CODEC_CAD(cmd) == pState->id));
1851
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1852
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1854
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1855
return VINF_SUCCESS;
1858
uint32_t *pu32Reg = NULL;
1859
if (codecIsAdcVolNode(pState, CODEC_NID(cmd)))
1860
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
1861
else if (codecIsDacNode(pState, CODEC_NID(cmd)))
1862
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
1863
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1864
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
1868
codecSetRegisterU8(pu32Reg, cmd, 0);
1869
return VINF_SUCCESS;
1873
static int codecGetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1875
Assert((CODEC_CAD(cmd) == pState->id));
1876
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1877
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1879
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1880
return VINF_SUCCESS;
1883
if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
1884
*pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
1885
return VINF_SUCCESS;
1889
static int codecSetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1891
Assert((CODEC_CAD(cmd) == pState->id));
1892
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1893
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1895
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1896
return VINF_SUCCESS;
1898
uint32_t *pu32Reg = NULL;
1900
if (codecIsVolKnobNode(pState, CODEC_NID(cmd)))
1901
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
1904
codecSetRegisterU8(pu32Reg, cmd, 0);
1905
return VINF_SUCCESS;
1909
static int codecGetGPIOUnsolisted (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1911
Assert((CODEC_CAD(cmd) == pState->id));
1912
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1913
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1915
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1916
return VINF_SUCCESS;
1919
/* note: this is true for ALC885 */
1920
if (CODEC_NID(cmd) == 0x1 /* AFG */)
1921
*pResp = pState->pNodes[1].afg.u32F17_param;
1922
return VINF_SUCCESS;
1926
static int codecSetGPIOUnsolisted (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1928
Assert((CODEC_CAD(cmd) == pState->id));
1929
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1930
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1932
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1933
return VINF_SUCCESS;
1935
uint32_t *pu32Reg = NULL;
1937
if (CODEC_NID(cmd) == 1 /* AFG */)
1938
pu32Reg = &pState->pNodes[1].afg.u32F17_param;
1941
codecSetRegisterU8(pu32Reg, cmd, 0);
1942
return VINF_SUCCESS;
1946
static int codecGetConfig (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
1948
Assert((CODEC_CAD(cmd) == pState->id));
1949
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1950
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1952
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1953
return VINF_SUCCESS;
1956
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1957
*pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
1958
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1959
*pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
1960
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1961
*pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
1962
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
1963
*pResp = pState->pNodes[CODEC_NID(cmd)].pcbeep.u32F1c_param;
1964
else if (codecIsCdNode(pState, CODEC_NID(cmd)))
1965
*pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
1966
else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
1967
*pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
1968
return VINF_SUCCESS;
1970
static int codecSetConfigX(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset)
1972
Assert((CODEC_CAD(cmd) == pState->id));
1973
Assert((CODEC_NID(cmd) < pState->cTotalNodes));
1974
if (CODEC_NID(cmd) >= pState->cTotalNodes)
1976
Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
1977
return VINF_SUCCESS;
1979
uint32_t *pu32Reg = NULL;
1980
if (codecIsPortNode(pState, CODEC_NID(cmd)))
1981
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
1982
else if (codecIsDigInPinNode(pState, CODEC_NID(cmd)))
1983
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
1984
else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd)))
1985
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
1986
else if (codecIsCdNode(pState, CODEC_NID(cmd)))
1987
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
1988
else if (codecIsPcbeepNode(pState, CODEC_NID(cmd)))
1989
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].pcbeep.u32F1c_param;
1990
else if (codecIsReservedNode(pState, CODEC_NID(cmd)))
1991
pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
1994
codecSetRegisterU8(pu32Reg, cmd, u8Offset);
1995
return VINF_SUCCESS;
1998
static int codecSetConfig0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
2001
return codecSetConfigX(pState, cmd, 0);
2004
static int codecSetConfig1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
2007
return codecSetConfigX(pState, cmd, 8);
2010
static int codecSetConfig2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
2013
return codecSetConfigX(pState, cmd, 16);
2016
static int codecSetConfig3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
2019
return codecSetConfigX(pState, cmd, 24);
2023
static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt)
2025
uint32_t dir = AMPLIFIER_OUT;
2028
case AUD_MIXER_VOLUME:
2030
dir = AMPLIFIER_OUT;
2032
case AUD_MIXER_LINE_IN:
2036
int mute = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & RT_BIT(7);
2037
mute |= AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
2040
uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f;
2041
uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f;
2042
AUD_set_volume(mt, &mute, &lVol, &rVol);
2043
return VINF_SUCCESS;
2046
static CODECVERB CODECVERBS[] =
2048
/* verb | verb mask | callback */
2049
/* ----------- -------------------- ----------------------- */
2050
{0x000F0000, CODEC_VERB_8BIT_CMD , codecGetParameter },
2051
{0x000F0100, CODEC_VERB_8BIT_CMD , codecGetConSelectCtrl },
2052
{0x00070100, CODEC_VERB_8BIT_CMD , codecSetConSelectCtrl },
2053
{0x000F0600, CODEC_VERB_8BIT_CMD , codecGetStreamId },
2054
{0x00070600, CODEC_VERB_8BIT_CMD , codecSetStreamId },
2055
{0x000F0700, CODEC_VERB_8BIT_CMD , codecGetPinCtrl },
2056
{0x00070700, CODEC_VERB_8BIT_CMD , codecSetPinCtrl },
2057
{0x000F0800, CODEC_VERB_8BIT_CMD , codecGetUnsolicitedEnabled },
2058
{0x00070800, CODEC_VERB_8BIT_CMD , codecSetUnsolicitedEnabled },
2059
{0x000F0900, CODEC_VERB_8BIT_CMD , codecGetPinSense },
2060
{0x00070900, CODEC_VERB_8BIT_CMD , codecSetPinSense },
2061
{0x000F0200, CODEC_VERB_8BIT_CMD , codecGetConnectionListEntry },
2062
{0x000F0300, CODEC_VERB_8BIT_CMD , codecGetProcessingState },
2063
{0x00070300, CODEC_VERB_8BIT_CMD , codecSetProcessingState },
2064
{0x000F0D00, CODEC_VERB_8BIT_CMD , codecGetDigitalConverter },
2065
{0x00070D00, CODEC_VERB_8BIT_CMD , codecSetDigitalConverter1 },
2066
{0x00070E00, CODEC_VERB_8BIT_CMD , codecSetDigitalConverter2 },
2067
{0x000F2000, CODEC_VERB_8BIT_CMD , codecGetSubId },
2068
{0x00072000, CODEC_VERB_8BIT_CMD , codecSetSubId0 },
2069
{0x00072100, CODEC_VERB_8BIT_CMD , codecSetSubId1 },
2070
{0x00072200, CODEC_VERB_8BIT_CMD , codecSetSubId2 },
2071
{0x00072300, CODEC_VERB_8BIT_CMD , codecSetSubId3 },
2072
{0x0007FF00, CODEC_VERB_8BIT_CMD , codecReset },
2073
{0x000F0500, CODEC_VERB_8BIT_CMD , codecGetPowerState },
2074
{0x00070500, CODEC_VERB_8BIT_CMD , codecSetPowerState },
2075
{0x000F0C00, CODEC_VERB_8BIT_CMD , codecGetEAPD_BTLEnabled },
2076
{0x00070C00, CODEC_VERB_8BIT_CMD , codecSetEAPD_BTLEnabled },
2077
{0x000F0F00, CODEC_VERB_8BIT_CMD , codecGetVolumeKnobCtrl },
2078
{0x00070F00, CODEC_VERB_8BIT_CMD , codecSetVolumeKnobCtrl },
2079
{0x000F1700, CODEC_VERB_8BIT_CMD , codecGetGPIOUnsolisted },
2080
{0x00071700, CODEC_VERB_8BIT_CMD , codecSetGPIOUnsolisted },
2081
{0x000F1C00, CODEC_VERB_8BIT_CMD , codecGetConfig },
2082
{0x00071C00, CODEC_VERB_8BIT_CMD , codecSetConfig0 },
2083
{0x00071D00, CODEC_VERB_8BIT_CMD , codecSetConfig1 },
2084
{0x00071E00, CODEC_VERB_8BIT_CMD , codecSetConfig2 },
2085
{0x00071F00, CODEC_VERB_8BIT_CMD , codecSetConfig3 },
2086
{0x000A0000, CODEC_VERB_16BIT_CMD, codecGetConverterFormat },
2087
{0x00020000, CODEC_VERB_16BIT_CMD, codecSetConverterFormat },
2088
{0x000B0000, CODEC_VERB_16BIT_CMD, codecGetAmplifier },
2089
{0x00030000, CODEC_VERB_16BIT_CMD, codecSetAmplifier },
2092
static int codecLookup(CODECState *pState, uint32_t cmd, PPFNCODECVERBPROCESSOR pfn)
2094
int rc = VINF_SUCCESS;
2095
Assert(CODEC_CAD(cmd) == pState->id);
2096
if (codecIsReservedNode(pState, CODEC_NID(cmd)))
2098
Log(("HDAcodec: cmd %x was addressed to reserved node\n", cmd));
2100
if ( CODEC_VERBDATA(cmd) == 0
2101
|| CODEC_NID(cmd) >= pState->cTotalNodes)
2103
*pfn = codecUnimplemented;
2104
//** @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp)
2105
Log(("HDAcodec: cmd %x was ignored\n", cmd));
2106
return VINF_SUCCESS;
2108
for (int i = 0; i < pState->cVerbs; ++i)
2110
if ((CODEC_VERBDATA(cmd) & pState->pVerbs[i].mask) == pState->pVerbs[i].verb)
2112
*pfn = pState->pVerbs[i].pfn;
2113
return VINF_SUCCESS;
2116
*pfn = codecUnimplemented;
2117
Log(("HDAcodec: callback for %x wasn't found\n", CODEC_VERBDATA(cmd)));
2121
static void pi_callback (void *opaque, int avail)
2123
CODECState *pState = (CODECState *)opaque;
2124
pState->pfnTransfer(pState, PI_INDEX, avail);
2127
static void po_callback (void *opaque, int avail)
2129
CODECState *pState = (CODECState *)opaque;
2130
pState->pfnTransfer(pState, PO_INDEX, avail);
2135
* routines open one of the voices (IN, OUT) with corresponding parameters.
2136
* this routine could be called from HDA on setting/resseting sound format.
2138
* @todo: probably passed settings should be verified (if AFG's declared proposed format) before enabling.
2140
int codecOpenVoice(CODECState *pState, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings)
2143
Assert((pState && pAudioSettings));
2147
switch (enmSoundSource)
2150
pState->SwVoiceIn = AUD_open_in(&pState->card, pState->SwVoiceIn, "hda.in", pState, pi_callback, pAudioSettings);
2151
rc = pState->SwVoiceIn ? 0 : 1;
2154
pState->SwVoiceOut = AUD_open_out(&pState->card, pState->SwVoiceOut, "hda.out", pState, po_callback, pAudioSettings);
2155
rc = pState->SwVoiceOut ? 0 : 1;
2161
LogRel(("HDAcodec: can't open %s fmt(freq: %d)\n",
2162
enmSoundSource == PI_INDEX? "in" : "out",
2163
pAudioSettings->freq));
2167
int codecConstruct(PPDMDEVINS pDevIns, CODECState *pState, ENMCODEC enmCodec)
2171
pState->pVerbs = (CODECVERB *)&CODECVERBS;
2172
pState->cVerbs = sizeof(CODECVERBS)/sizeof(CODECVERB);
2173
pState->pfnLookup = codecLookup;
2174
pState->enmCodec = enmCodec;
2177
case STAC9220_CODEC:
2178
rc = stac9220Construct(pState);
2182
rc = alc885Construct(pState);
2186
AssertMsgFailed(("Unsupported Codec"));
2188
/* common root node initializers */
2189
pState->pNodes[0].node.au32F00_param[0] = CODEC_MAKE_F00_00(pState->u16VendorId, pState->u16DeviceId);
2190
pState->pNodes[0].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1);
2191
/* common AFG node initializers */
2192
pState->pNodes[1].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x2, pState->cTotalNodes - 2);
2193
pState->pNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(CODEC_F00_05_UNSOL, CODEC_F00_05_AFG);
2194
pState->pNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pState->u16VendorId, pState->u8BSKU, pState->u8AssemblyId);
2196
//** @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
2197
AUD_register_card ("ICH0", &pState->card);
2202
as.fmt = AUD_FMT_S16;
2205
pState->pNodes[1].node.au32F00_param[0xA] = CODEC_F00_0A_16_BIT;
2206
codecOpenVoice(pState, PI_INDEX, &as);
2207
codecOpenVoice(pState, PO_INDEX, &as);
2208
pState->pNodes[1].node.au32F00_param[0xA] |= CODEC_F00_0A_44_1KHZ;
2211
Assert(pState->pNodes);
2212
Assert(pState->pfnCodecNodeReset);
2213
for (i = 0; i < pState->cTotalNodes; ++i)
2215
pState->pfnCodecNodeReset(pState, i, &pState->pNodes[i]);
2218
codecToAudVolume(&pState->pNodes[pState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
2219
codecToAudVolume(&pState->pNodes[pState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
2221
/* If no host voices were created, then fallback to nul audio. */
2222
if (!AUD_is_host_voice_in_ok(pState->SwVoiceIn))
2223
LogRel (("HDA: WARNING: Unable to open PCM IN!\n"));
2224
if (!AUD_is_host_voice_out_ok(pState->SwVoiceOut))
2225
LogRel (("HDA: WARNING: Unable to open PCM OUT!\n"));
2227
if ( !AUD_is_host_voice_in_ok(pState->SwVoiceIn)
2228
&& !AUD_is_host_voice_out_ok(pState->SwVoiceOut))
2230
/* Was not able initialize *any* voice. Select the NULL audio driver instead */
2231
AUD_close_in (&pState->card, pState->SwVoiceIn);
2232
AUD_close_out (&pState->card, pState->SwVoiceOut);
2233
pState->SwVoiceOut = NULL;
2234
pState->SwVoiceIn = NULL;
2237
PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
2238
N_ ("No audio devices could be opened. Selecting the NULL audio backend "
2239
"with the consequence that no sound is audible"));
2241
else if ( !AUD_is_host_voice_in_ok(pState->SwVoiceIn)
2242
|| !AUD_is_host_voice_out_ok(pState->SwVoiceOut))
2244
char szMissingVoices[128];
2246
if (!AUD_is_host_voice_in_ok(pState->SwVoiceIn))
2247
len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in");
2248
if (!AUD_is_host_voice_out_ok(pState->SwVoiceOut))
2249
len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
2251
PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
2252
N_ ("Some audio devices (%s) could not be opened. Guest applications generating audio "
2253
"output or depending on audio input may hang. Make sure your host audio device "
2254
"is working properly. Check the logfile for error messages of the audio "
2255
"subsystem"), szMissingVoices);
2258
return VINF_SUCCESS;
2260
int codecDestruct(CODECState *pCodecState)
2262
RTMemFree(pCodecState->pNodes);
2263
return VINF_SUCCESS;
2266
int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
2268
SSMR3PutMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes);
2269
return VINF_SUCCESS;
2272
int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)
2274
SSMR3GetMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes);
2275
if (codecIsDacNode(pCodecState, pCodecState->u8DacLineOut))
2276
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
2277
else if (codecIsSpdifOutNode(pCodecState, pCodecState->u8DacLineOut))
2278
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
2279
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
2280
return VINF_SUCCESS;