VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DevCodec.cpp@ 31294

Last change on this file since 31294 was 31294, checked in by vboxsync, 14 years ago

Audio/HDA: spdif{in,out} needs F06/706 verb support.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.4 KB
Line 
1/* $Id: DevCodec.cpp 31294 2010-08-02 12:54:31Z vboxsync $ */
2/** @file
3 * DevCodec - VBox ICH Intel HD Audio Codec.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Oracle Corporation
8 *
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.
16 */
17#define LOG_GROUP LOG_GROUP_DEV_AUDIO
18#include <VBox/pdmdev.h>
19#include <iprt/assert.h>
20#include <iprt/uuid.h>
21#include <iprt/string.h>
22#include <iprt/mem.h>
23#include <iprt/asm.h>
24
25#include "../Builtins.h"
26extern "C" {
27#include "audio.h"
28}
29#include "DevCodec.h"
30
31#define CODEC_CAD_MASK 0xF0000000
32#define CODEC_CAD_SHIFT 28
33#define CODEC_DIRECT_MASK RT_BIT(27)
34#define CODEC_NID_MASK 0x07F00000
35#define CODEC_NID_SHIFT 20
36#define CODEC_VERBDATA_MASK 0x000FFFFF
37#define CODEC_VERB_4BIT_CMD 0x000FFFF0
38#define CODEC_VERB_4BIT_DATA 0x0000000F
39#define CODEC_VERB_8BIT_CMD 0x000FFF00
40#define CODEC_VERB_8BIT_DATA 0x000000FF
41#define CODEC_VERB_16BIT_CMD 0x000F0000
42#define CODEC_VERB_16BIT_DATA 0x0000FFFF
43
44#define CODEC_CAD(cmd) ((cmd) & CODEC_CAD_MASK)
45#define CODEC_DIRECT(cmd) ((cmd) & CODEC_DIRECT_MASK)
46#define CODEC_NID(cmd) ((((cmd) & CODEC_NID_MASK)) >> CODEC_NID_SHIFT)
47#define CODEC_VERBDATA(cmd) ((cmd) & CODEC_VERBDATA_MASK)
48#define CODEC_VERB_CMD(cmd, mask, x) (((cmd) & (mask)) >> (x))
49#define CODEC_VERB_CMD4(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_4BIT_CMD, 4))
50#define CODEC_VERB_CMD8(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_8BIT_CMD, 8))
51#define CODEC_VERB_CMD16(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_16BIT_CMD, 16))
52
53#define CODEC_VERB_B_DIRECTION RT_BIT(15)
54#define CODEC_VERB_B_SIDE RT_BIT(13)
55#define CODEC_VERB_B_INDEX 0x7
56
57#define CODEC_B_DIRECTION(cmd) (((cmd) & CODEC_VERB_B_DIRECTION) >> 15)
58#define CODEC_B_SIDE(cmd) (((cmd) & CODEC_VERB_B_SIDE) >> 13)
59#define CODEC_B_INDEX(cmd) ((cmd) & CODEC_VERB_B_INDEX)
60
61
62#define STAC9220_NODE_COUNT 0x1C
63
64#define STAC9220_IS_AFG_CMD(cmd) ( \
65 CODEC_NID(cmd) == 0x1)
66
67#define STAC9220_IS_PORT_CMD(cmd) ( \
68 CODEC_NID(cmd) == 0xA \
69 || CODEC_NID(cmd) == 0xB \
70 || CODEC_NID(cmd) == 0xC \
71 || CODEC_NID(cmd) == 0xD \
72 || CODEC_NID(cmd) == 0xE \
73 || CODEC_NID(cmd) == 0xF)
74
75#define STAC9220_IS_DAC_CMD(cmd) ( \
76 CODEC_NID(cmd) == 0x2 \
77 || CODEC_NID(cmd) == 0x3 \
78 || CODEC_NID(cmd) == 0x4 \
79 || CODEC_NID(cmd) == 0x5)
80
81#define STAC9220_IS_ADCVOL_CMD(cmd) ( \
82 CODEC_NID(cmd) == 0x17 \
83 || CODEC_NID(cmd) == 0x18)
84
85#define STAC9220_IS_ADC_CMD(cmd) ( \
86 CODEC_NID(cmd) == 0x6 \
87 || CODEC_NID(cmd) == 0x7)
88
89#define STAC9220_IS_ADCMUX_CMD(cmd) ( \
90 CODEC_NID(cmd) == 0x12 \
91 || CODEC_NID(cmd) == 0x13)
92
93#define STAC9220_IS_PCBEEP_CMD(cmd) (CODEC_NID((cmd)) == 0x14)
94#define STAC9220_IS_SPDIFOUT_CMD(cmd) (CODEC_NID((cmd)) == 0x8)
95#define STAC9220_IS_SPDIFIN_CMD(cmd) (CODEC_NID((cmd)) == 0x9)
96
97#define STAC9220_IS_DIGINPIN_CMD(cmd) (CODEC_NID((cmd)) == 0x11)
98#define STAC9220_IS_DIGOUTPIN_CMD(cmd) (CODEC_NID((cmd)) == 0x10)
99
100#define STAC9220_IS_CD_CMD(cmd) (CODEC_NID((cmd)) == 0x15)
101
102#define STAC9220_IS_VOLKNOB_CMD(cmd) (CODEC_NID((cmd)) == 0x16)
103
104/* STAC9220 6.2 & 6.12 */
105#define STAC9220_IS_RESERVED_CMD(cmd) ( \
106 CODEC_NID((cmd)) == 0x19 \
107 || CODEC_NID((cmd)) == 0x1A \
108 || CODEC_NID((cmd)) == 0x1B)
109
110static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
111
112
113static int codecUnimplemented(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
114{
115 Log(("codecUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
116 CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
117 *pResp = 0;
118 return VINF_SUCCESS;
119}
120
121static int codecBreak(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
122{
123 int rc;
124 rc = codecUnimplemented(pState, cmd, pResp);
125 *pResp |= CODEC_RESPONSE_UNSOLICITED;
126 return rc;
127}
128/* B-- */
129static int codecGetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
130{
131 Assert((CODEC_CAD(cmd) == pState->id));
132 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
133 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
134 {
135 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
136 return VINF_SUCCESS;
137 }
138 *pResp = 0;
139 PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
140 if (STAC9220_IS_DAC_CMD(cmd))
141 *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params,
142 CODEC_B_DIRECTION(cmd),
143 CODEC_B_SIDE(cmd),
144 CODEC_B_INDEX(cmd));
145 else if (STAC9220_IS_ADCVOL_CMD(cmd))
146 *pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params,
147 CODEC_B_DIRECTION(cmd),
148 CODEC_B_SIDE(cmd),
149 CODEC_B_INDEX(cmd));
150 else if (STAC9220_IS_ADCMUX_CMD(cmd))
151 *pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params,
152 CODEC_B_DIRECTION(cmd),
153 CODEC_B_SIDE(cmd),
154 CODEC_B_INDEX(cmd));
155 else if (STAC9220_IS_PCBEEP_CMD(cmd))
156 *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
157 CODEC_B_DIRECTION(cmd),
158 CODEC_B_SIDE(cmd),
159 CODEC_B_INDEX(cmd));
160 else{
161 AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
162 }
163 return VINF_SUCCESS;
164}
165/* 3-- */
166static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
167{
168 uint32_t *pu32Bparam = NULL;
169 Assert((CODEC_CAD(cmd) == pState->id));
170 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
171 {
172 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
173 return VINF_SUCCESS;
174 }
175 *pResp = 0;
176 PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
177 if (STAC9220_IS_DAC_CMD(cmd))
178 pu32Bparam = &AMPLIFIER_REGISTER(pNode->dac.B_params,
179 CODEC_B_DIRECTION(cmd),
180 CODEC_B_SIDE(cmd),
181 CODEC_B_INDEX(cmd));
182 else if (STAC9220_IS_ADCVOL_CMD(cmd))
183 pu32Bparam = &AMPLIFIER_REGISTER(pNode->adcvol.B_params,
184 CODEC_B_DIRECTION(cmd),
185 CODEC_B_SIDE(cmd),
186 CODEC_B_INDEX(cmd));
187 else if (STAC9220_IS_ADCMUX_CMD(cmd))
188 pu32Bparam = &AMPLIFIER_REGISTER(pNode->adcmux.B_params,
189 CODEC_B_DIRECTION(cmd),
190 CODEC_B_SIDE(cmd),
191 CODEC_B_INDEX(cmd));
192 else if (STAC9220_IS_PCBEEP_CMD(cmd))
193 pu32Bparam = &AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
194 CODEC_B_DIRECTION(cmd),
195 CODEC_B_SIDE(cmd),
196 CODEC_B_INDEX(cmd));
197 Assert(pu32Bparam);
198 if (pu32Bparam)
199 {
200 *pu32Bparam = (*pu32Bparam) & ~CODEC_VERB_8BIT_DATA;
201 *pu32Bparam = (*pu32Bparam) | (cmd & CODEC_VERB_8BIT_DATA);
202 }
203 return VINF_SUCCESS;
204}
205
206static int codecGetParameter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
207{
208 Assert((CODEC_CAD(cmd) == pState->id));
209 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
210 {
211 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
212 return VINF_SUCCESS;
213 }
214 Assert(((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F0_PARAM_LENGTH));
215 if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F0_PARAM_LENGTH)
216 {
217 Log(("HDAcodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
218 return VINF_SUCCESS;
219 }
220 *pResp = 0;
221 *pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA];
222 return VINF_SUCCESS;
223}
224
225/* F01 */
226static int codecGetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
227{
228 Assert((CODEC_CAD(cmd) == pState->id));
229 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
230 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
231 {
232 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
233 return VINF_SUCCESS;
234 }
235 *pResp = 0;
236 if (STAC9220_IS_ADCMUX_CMD(cmd))
237 *pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
238 else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
239 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
240 return VINF_SUCCESS;
241}
242
243/* 701 */
244static int codecSetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
245{
246 uint32_t *pu32Reg = NULL;
247 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
248 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
249 {
250 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
251 return VINF_SUCCESS;
252 }
253 *pResp = 0;
254 if (STAC9220_IS_ADCMUX_CMD(cmd))
255 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param;
256 else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
257 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param;
258 Assert((pu32Reg));
259 if (!pu32Reg)
260 return VINF_SUCCESS;
261 *pu32Reg = (*pu32Reg) & ~CODEC_VERB_8BIT_DATA;
262 *pu32Reg = (*pu32Reg) | (cmd & CODEC_VERB_8BIT_DATA);
263 return VINF_SUCCESS;
264}
265
266/* F07 */
267static int codecGetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
268{
269 Assert((CODEC_CAD(cmd) == pState->id));
270 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
271 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
272 {
273 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
274 return VINF_SUCCESS;
275 }
276 *pResp = 0;
277 if (STAC9220_IS_PORT_CMD(cmd))
278 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
279 else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
280 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
281 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
282 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
283 else if (STAC9220_IS_CD_CMD(cmd))
284 *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
285 else
286 AssertMsgFailed(("Unsupported"));
287 return VINF_SUCCESS;
288}
289
290/* 707 */
291static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
292{
293 Assert((CODEC_CAD(cmd) == pState->id));
294 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
295 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
296 {
297 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
298 return VINF_SUCCESS;
299 }
300 *pResp = 0;
301 uint32_t *pu32Reg = NULL;
302 if (STAC9220_IS_PORT_CMD(cmd))
303 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F07_param;
304 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
305 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param;
306 else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
307 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param;
308 else if (STAC9220_IS_CD_CMD(cmd))
309 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param;
310 Assert((pu32Reg));
311 if (!pu32Reg)
312 return VINF_SUCCESS;
313 *pu32Reg = (*pu32Reg) & ~CODEC_VERB_8BIT_DATA;
314 *pu32Reg = (*pu32Reg) | (cmd & CODEC_VERB_8BIT_DATA);
315 return VINF_SUCCESS;
316}
317
318/* F08 */
319static int codecGetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
320{
321 Assert((CODEC_CAD(cmd) == pState->id));
322 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
323 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
324 {
325 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
326 return VINF_SUCCESS;
327 }
328 *pResp = 0;
329 if (STAC9220_IS_PORT_CMD(cmd))
330 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
331 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
332 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
333 else if (STAC9220_IS_AFG_CMD(cmd))
334 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
335 else if (STAC9220_IS_VOLKNOB_CMD(cmd))
336 *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
337 else
338 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
339 return VINF_SUCCESS;
340}
341
342/* 708 */
343static int codecSetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
344{
345 Assert((CODEC_CAD(cmd) == pState->id));
346 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
347 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
348 {
349 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
350 return VINF_SUCCESS;
351 }
352 *pResp = 0;
353 uint32_t *pu32Reg = NULL;
354 if (STAC9220_IS_PORT_CMD(cmd))
355 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
356 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
357 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
358 else if (STAC9220_IS_AFG_CMD(cmd))
359 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param;
360 else if (STAC9220_IS_VOLKNOB_CMD(cmd))
361 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param;
362 else
363 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
364 Assert(pu32Reg);
365 if(!pu32Reg)
366 return VINF_SUCCESS;
367 *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
368 *pu32Reg |= cmd & CODEC_VERB_8BIT_DATA;
369 return VINF_SUCCESS;
370}
371
372/* F09 */
373static int codecGetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
374{
375 Assert((CODEC_CAD(cmd) == pState->id));
376 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
377 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
378 {
379 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
380 return VINF_SUCCESS;
381 }
382 *pResp = 0;
383 if (STAC9220_IS_PORT_CMD(cmd))
384 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F09_param;
385 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
386 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param;
387 else
388 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd)));
389 return VINF_SUCCESS;
390}
391
392/* 709 */
393static int codecSetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
394{
395 Assert((CODEC_CAD(cmd) == pState->id));
396 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
397 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
398 {
399 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
400 return VINF_SUCCESS;
401 }
402 *pResp = 0;
403 uint32_t *pu32Reg = NULL;
404 if (STAC9220_IS_PORT_CMD(cmd))
405 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param;
406 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
407 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param;
408 Assert(pu32Reg);
409 if(!pu32Reg)
410 return VINF_SUCCESS;
411 *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
412 *pu32Reg |= cmd & CODEC_VERB_8BIT_DATA;
413 return VINF_SUCCESS;
414}
415
416static int codecGetConnectionListEntry(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
417{
418 Assert((CODEC_CAD(cmd) == pState->id));
419 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
420 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
421 {
422 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
423 return VINF_SUCCESS;
424 }
425 Assert((cmd & CODEC_VERB_8BIT_DATA) < 16);
426 if ((cmd & CODEC_VERB_8BIT_DATA) >= 16)
427 {
428 Log(("HDAcodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
429 }
430 *pResp = *(uint32_t *)&pState->pNodes[CODEC_NID(cmd)].node.au8F02_param[cmd & CODEC_VERB_8BIT_DATA];
431 return VINF_SUCCESS;
432}
433/* F03 */
434static int codecGetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
435{
436 Assert((CODEC_CAD(cmd) == pState->id));
437 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
438 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
439 {
440 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
441 return VINF_SUCCESS;
442 }
443 *pResp = 0;
444 if (STAC9220_IS_ADC_CMD(cmd))
445 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param;
446 return VINF_SUCCESS;
447}
448/* 703 */
449static int codecSetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
450{
451 Assert((CODEC_CAD(cmd) == pState->id));
452 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
453 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
454 {
455 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
456 return VINF_SUCCESS;
457 }
458 *pResp = 0;
459 if (STAC9220_IS_ADC_CMD(cmd))
460 {
461 pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param &= ~CODEC_VERB_8BIT_DATA;
462 pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param |= cmd & CODEC_VERB_8BIT_DATA;
463 }
464 return VINF_SUCCESS;
465}
466/* F0D */
467static int codecGetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
468{
469 Assert((CODEC_CAD(cmd) == pState->id));
470 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
471 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
472 {
473 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
474 return VINF_SUCCESS;
475 }
476 *pResp = 0;
477 if (STAC9220_IS_SPDIFOUT_CMD(cmd))
478 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param;
479 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
480 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param;
481 return VINF_SUCCESS;
482}
483/* 70D */
484static int codecSetDigitalConverter1(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
485{
486 Assert((CODEC_CAD(cmd) == pState->id));
487 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
488 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
489 {
490 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
491 return VINF_SUCCESS;
492 }
493 *pResp = 0;
494 if (STAC9220_IS_SPDIFOUT_CMD(cmd))
495 {
496 pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param &= ~CODEC_VERB_8BIT_DATA;
497 pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param |= cmd & CODEC_VERB_8BIT_DATA;
498 }
499 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
500 {
501 pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param &= ~CODEC_VERB_8BIT_DATA;
502 pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param |= cmd & CODEC_VERB_8BIT_DATA;
503 }
504 return VINF_SUCCESS;
505}
506/* 70E */
507static int codecSetDigitalConverter2(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
508{
509 Assert((CODEC_CAD(cmd) == pState->id));
510 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
511 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
512 {
513 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
514 return VINF_SUCCESS;
515 }
516 *pResp = 0;
517 if (STAC9220_IS_SPDIFOUT_CMD(cmd))
518 {
519 pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param &= ~(CODEC_VERB_8BIT_DATA << 8);
520 pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param |= cmd & (CODEC_VERB_8BIT_DATA << 8);
521 }
522 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
523 {
524 pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param &= ~(CODEC_VERB_8BIT_DATA << 8);
525 pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param |= cmd & (CODEC_VERB_8BIT_DATA << 8);
526 }
527 return VINF_SUCCESS;
528}
529
530static int codecGetSubId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
531{
532 Assert((CODEC_CAD(cmd) == pState->id));
533 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
534 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
535 {
536 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
537 return VINF_SUCCESS;
538 }
539 *pResp = 0;
540 if (STAC9220_IS_AFG_CMD(cmd))
541 {
542 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param;
543 }
544 return VINF_SUCCESS;
545}
546
547static int codecReset(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
548{
549 Assert((CODEC_CAD(cmd) == pState->id));
550 Assert(STAC9220_IS_AFG_CMD(cmd));
551 if(STAC9220_IS_AFG_CMD(cmd))
552 {
553 uint8_t i;
554 Log(("HDAcodec: enters reset\n"));
555 for (i = 0; i < STAC9220_NODE_COUNT; ++i)
556 {
557 stac9220ResetNode(pState, i, &pState->pNodes[i]);
558 }
559 pState->pfnReset(pState);
560 Log(("HDAcodec: exits reset\n"));
561 }
562 *pResp = 0;
563 return VINF_SUCCESS;
564}
565
566/* F05 */
567static int codecGetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
568{
569 Assert((CODEC_CAD(cmd) == pState->id));
570 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
571 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
572 {
573 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
574 return VINF_SUCCESS;
575 }
576 *pResp = 0;
577 if (STAC9220_IS_AFG_CMD(cmd))
578 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
579 else if (STAC9220_IS_DAC_CMD(cmd))
580 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
581 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
582 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
583 else if (STAC9220_IS_ADC_CMD(cmd))
584 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
585 return VINF_SUCCESS;
586}
587
588/* 705 */
589static int codecSetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
590{
591 Assert((CODEC_CAD(cmd) == pState->id));
592 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
593 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
594 {
595 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
596 return VINF_SUCCESS;
597 }
598 uint32_t *pu32Reg = NULL;
599 *pResp = 0;
600 if (STAC9220_IS_AFG_CMD(cmd))
601 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param;
602 else if (STAC9220_IS_DAC_CMD(cmd))
603 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param;
604 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
605 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param;
606 else if (STAC9220_IS_ADC_CMD(cmd))
607 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param;
608 Assert((pu32Reg));
609 if (!pu32Reg)
610 return VINF_SUCCESS;
611 *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
612 *pu32Reg |= cmd & CODEC_VERB_4BIT_DATA;
613 *pu32Reg |= (cmd & CODEC_VERB_4BIT_DATA) << 4;
614 return VINF_SUCCESS;
615}
616
617static int codecGetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
618{
619 Assert((CODEC_CAD(cmd) == pState->id));
620 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
621 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
622 {
623 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
624 return VINF_SUCCESS;
625 }
626 *pResp = 0;
627 if (STAC9220_IS_DAC_CMD(cmd))
628 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
629 else if (STAC9220_IS_ADC_CMD(cmd))
630 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
631 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
632 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
633 else if (STAC9220_IS_SPDIFOUT_CMD(cmd))
634 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
635 return VINF_SUCCESS;
636}
637static int codecSetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
638{
639 Assert((CODEC_CAD(cmd) == pState->id));
640 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
641 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
642 {
643 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
644 return VINF_SUCCESS;
645 }
646 *pResp = 0;
647 uint32_t *pu32addr = NULL;
648 *pResp = 0;
649 if (STAC9220_IS_DAC_CMD(cmd))
650 pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param;
651 else if (STAC9220_IS_ADC_CMD(cmd))
652 pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param;
653 else if (STAC9220_IS_SPDIFOUT_CMD(cmd))
654 pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param;
655 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
656 pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param;
657 Assert((pu32addr));
658 if (pu32addr)
659 {
660 *pu32addr &= ~CODEC_VERB_8BIT_DATA;
661 *pu32addr |= cmd & CODEC_VERB_8BIT_DATA;
662 }
663 return VINF_SUCCESS;
664}
665static int codecGetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
666{
667 Assert((CODEC_CAD(cmd) == pState->id));
668 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
669 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
670 {
671 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
672 return VINF_SUCCESS;
673 }
674 *pResp = 0;
675 if (STAC9220_IS_DAC_CMD(cmd))
676 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32A_param;
677 else if (STAC9220_IS_ADC_CMD(cmd))
678 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32A_param;
679 else if (STAC9220_IS_SPDIFOUT_CMD(cmd))
680 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param;
681 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
682 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param;
683 return VINF_SUCCESS;
684}
685
686static int codecSetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
687{
688 Assert((CODEC_CAD(cmd) == pState->id));
689 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
690 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
691 {
692 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
693 return VINF_SUCCESS;
694 }
695 *pResp = 0;
696 if (STAC9220_IS_DAC_CMD(cmd))
697 {
698 pState->pNodes[CODEC_NID(cmd)].dac.u32A_param &= ~CODEC_VERB_16BIT_DATA;
699 pState->pNodes[CODEC_NID(cmd)].dac.u32A_param |= cmd & CODEC_VERB_16BIT_DATA;
700 }
701 else if (STAC9220_IS_ADC_CMD(cmd))
702 {
703 pState->pNodes[CODEC_NID(cmd)].adc.u32A_param &= ~CODEC_VERB_16BIT_DATA;
704 pState->pNodes[CODEC_NID(cmd)].adc.u32A_param |= cmd & CODEC_VERB_16BIT_DATA;
705 }
706 else if (STAC9220_IS_SPDIFOUT_CMD(cmd))
707 {
708 pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param &= ~CODEC_VERB_16BIT_DATA;
709 pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param |= cmd & CODEC_VERB_16BIT_DATA;
710 }
711 else if (STAC9220_IS_SPDIFIN_CMD(cmd))
712 {
713 pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param &= ~CODEC_VERB_16BIT_DATA;
714 pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param |= cmd & CODEC_VERB_16BIT_DATA;
715 }
716 return VINF_SUCCESS;
717}
718
719/* F0C */
720static int codecGetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
721{
722 Assert((CODEC_CAD(cmd) == pState->id));
723 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
724 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
725 {
726 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
727 return VINF_SUCCESS;
728 }
729 *pResp = 0;
730 if (STAC9220_IS_ADCVOL_CMD(cmd))
731 *pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
732 else if (STAC9220_IS_DAC_CMD(cmd))
733 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
734 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
735 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
736 return VINF_SUCCESS;
737}
738
739/* 70C */
740static int codecSetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
741{
742 Assert((CODEC_CAD(cmd) == pState->id));
743 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
744 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
745 {
746 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
747 return VINF_SUCCESS;
748 }
749 *pResp = 0;
750 uint32_t *pu32Reg = NULL;
751 if (STAC9220_IS_ADCVOL_CMD(cmd))
752 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param;
753 else if (STAC9220_IS_DAC_CMD(cmd))
754 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param;
755 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
756 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param;
757 *pResp = 0;
758 Assert((pu32Reg));
759 if (pu32Reg)
760 {
761 *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
762 *pu32Reg |= cmd & CODEC_VERB_8BIT_DATA;
763 }
764 return VINF_SUCCESS;
765}
766
767/* F0F */
768static int codecGetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
769{
770 Assert((CODEC_CAD(cmd) == pState->id));
771 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
772 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
773 {
774 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
775 return VINF_SUCCESS;
776 }
777 *pResp = 0;
778 if (STAC9220_IS_VOLKNOB_CMD(cmd))
779 *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
780 return VINF_SUCCESS;
781}
782
783/* 70F */
784static int codecSetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
785{
786 Assert((CODEC_CAD(cmd) == pState->id));
787 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
788 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
789 {
790 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
791 return VINF_SUCCESS;
792 }
793 uint32_t *pu32Reg = NULL;
794 *pResp = 0;
795 if (STAC9220_IS_VOLKNOB_CMD(cmd))
796 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
797 Assert((pu32Reg));
798 if (pu32Reg)
799 {
800 *pu32Reg &= ~CODEC_VERB_8BIT_DATA;
801 *pu32Reg |= cmd & CODEC_VERB_8BIT_DATA;
802 }
803 return VINF_SUCCESS;
804}
805
806/* F1C */
807static int codecGetConfig (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
808{
809 Assert((CODEC_CAD(cmd) == pState->id));
810 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
811 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
812 {
813 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
814 return VINF_SUCCESS;
815 }
816 *pResp = 0;
817 if (STAC9220_IS_PORT_CMD(cmd))
818 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
819 else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
820 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
821 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
822 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
823 else if (STAC9220_IS_CD_CMD(cmd))
824 *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
825 return VINF_SUCCESS;
826}
827static int codecSetConfigX(struct CODECState *pState, uint32_t cmd, uint32_t mask)
828{
829 Assert((CODEC_CAD(cmd) == pState->id));
830 Assert((CODEC_NID(cmd) < STAC9220_NODE_COUNT));
831 if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
832 {
833 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
834 return VINF_SUCCESS;
835 }
836 uint32_t *pu32Reg = NULL;
837 if (STAC9220_IS_PORT_CMD(cmd))
838 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param;
839 else if (STAC9220_IS_DIGINPIN_CMD(cmd))
840 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param;
841 else if (STAC9220_IS_DIGOUTPIN_CMD(cmd))
842 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param;
843 else if (STAC9220_IS_CD_CMD(cmd))
844 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param;
845 Assert((pu32Reg));
846 if (pu32Reg)
847 {
848 *pu32Reg &= ~mask;
849 *pu32Reg |= cmd & mask;
850 }
851 return VINF_SUCCESS;
852}
853/* 71C */
854static int codecSetConfig0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
855{
856 uint32_t mask = CODEC_VERB_8BIT_DATA;
857 *pResp = 0;
858 return codecSetConfigX(pState, cmd, mask);
859}
860/* 71D */
861static int codecSetConfig1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
862{
863 uint32_t mask = CODEC_VERB_8BIT_DATA << 8;
864 *pResp = 0;
865 return codecSetConfigX(pState, cmd, mask);
866}
867/* 71E */
868static int codecSetConfig2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
869{
870 uint32_t mask = CODEC_VERB_8BIT_DATA << 16;
871 *pResp = 0;
872 return codecSetConfigX(pState, cmd, mask);
873}
874/* 71E */
875static int codecSetConfig3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
876{
877 uint32_t mask = CODEC_VERB_8BIT_DATA << 24;
878 *pResp = 0;
879 return codecSetConfigX(pState, cmd, mask);
880}
881
882static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode)
883{
884 pNode->node.id = nodenum;
885 pNode->node.au32F00_param[0xF] = RT_BIT(3)|RT_BIT(0); /* Power statest Supported: D0-yes, D1, D2, D3-no*/
886 switch (nodenum)
887 {
888 /* Root Node*/
889 case 0:
890 pNode->root.node.name = "Root";
891 //** @todo r=michaln: I fear the use of RT_MAKE_U32_FROM_U8() here makes the
892 // code much harder to read, not easier.
893 pNode->node.au32F00_param[0] = RT_MAKE_U32_FROM_U8(0x80, 0x76, 0x84, 0x83); /* VendorID = STAC9220/ DevId = 0x7680 */
894 pNode->node.au32F00_param[2] = RT_MAKE_U32_FROM_U8(0x1, 0x34, 0x10, 0x00); /* rev id */
895 pNode->node.au32F00_param[4] = RT_MAKE_U32_FROM_U8(0x1, 0x00, 0x01, 0x00); /* node info (start node: 1, start id = 1) */
896 break;
897 case 1:
898 pNode->afg.node.name = "AFG";
899 pNode->node.au32F00_param[4] = 2 << 16 | 0x17; /* starting node - 2; total numbers of nodes 0x17 */
900 pNode->node.au32F00_param[5] = RT_BIT(8)|RT_BIT(0);
901 pNode->node.au32F00_param[8] = RT_MAKE_U32_FROM_U8(0x0d, 0x0d, 0x01, 0x0); /* Capabilities */
902 //pNode->node.au32F00_param[0xa] = RT_BIT(19)|RT_BIT(18)|RT_BIT(17)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(7)|RT_BIT(6)|RT_BIT(5);
903 pNode->node.au32F00_param[0xa] = RT_BIT(17)|RT_BIT(5);
904 pNode->node.au32F00_param[0xc] = (17 << 8)|RT_BIT(6)|RT_BIT(5)|RT_BIT(2)|RT_BIT(1)|RT_BIT(0);
905 pNode->node.au32F00_param[0xb] = RT_BIT(0);
906 pNode->node.au32F00_param[0xd] = RT_BIT(31)|(0x5 << 16)|(0xE)<<8;
907 pNode->node.au32F00_param[0x12] = RT_BIT(31)|(0x2 << 16)|(0x7f << 8)|0x7f;
908 pNode->node.au32F00_param[0x11] = 0;
909 pNode->node.au32F00_param[0xF] = RT_BIT(30)|RT_BIT(3)|RT_BIT(0); /* Power statest Supported: D0-yes, D1, D2, D3-no*/
910 pNode->afg.u32F05_param = 0x3 << 4| 0x3; /* PS-Act: D3, PS->Set D3 */
911 pNode->afg.u32F20_param = 0x83847882;
912 pNode->afg.u32F08_param = 0;
913 break;
914 case 2:
915 pNode->dac.node.name = "DAC0";
916 goto dac_init;
917 case 3:
918 pNode->dac.node.name = "DAC1";
919 goto dac_init;
920 case 4:
921 pNode->dac.node.name = "DAC2";
922 goto dac_init;
923 case 5:
924 pNode->dac.node.name = "DAC3";
925 dac_init:
926 memset(pNode->dac.B_params, 0, AMPLIFIER_SIZE);
927 pNode->dac.u32A_param = RT_BIT(14)|(0x1 << 4)|0x2; /* 441000Hz/16bit/2ch */
928
929 AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) = 0x7F | RT_BIT(7);
930 AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) = 0x7F | RT_BIT(7);
931
932 pNode->dac.node.au32F00_param[9] = (0xd << 16) | RT_BIT(11) | RT_BIT(10) | RT_BIT(2) | RT_BIT(0);
933 pNode->dac.node.au32F00_param[5] = (0x3 << 4) | 0x3;
934 pNode->dac.u32F0c_param = 0;
935 pNode->dac.u32F05_param = 0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3 */
936 break;
937 case 6:
938 pNode->adc.node.name = "ADC0";
939 pNode->node.au8F02_param[0] = 0x17;
940 goto adc_init;
941 case 7:
942 pNode->adc.node.name = "ADC1";
943 pNode->node.au8F02_param[0] = 0x18;
944 adc_init:
945 pNode->adc.u32A_param = RT_BIT(14)|(0x1 << 3)|0x2; /* 441000Hz/16bit/2ch */
946 pNode->adc.node.au32F00_param[0xE] = RT_BIT(0);
947 pNode->adc.u32F03_param = RT_BIT(0);
948 pNode->adc.u32F05_param = 0x3 << 4 | 0x3; /* PS-Act: D3 Set: D3 */
949 pNode->adc.u32F06_param = 0;
950 pNode->adc.node.au32F00_param[9] = RT_BIT(20)| (0xd << 16) | RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0);
951 break;
952 case 8:
953 pNode->spdifout.node.name = "SPDIFOut";
954 pNode->spdifout.u32A_param = (1<<14)|(0x1<<4) | 0x1;
955 pNode->spdifout.node.au32F00_param[9] = (4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
956 pNode->node.au32F00_param[0xa] = RT_BIT(17)|RT_BIT(5);
957 pNode->spdifout.node.au32F00_param[0xB] = RT_BIT(2)|RT_BIT(0);
958 pNode->spdifout.u32F06_param = 0;
959 pNode->spdifout.u32F0d_param = 0;
960 //pNode->spdifout.node.au32F00_param[0xA] = RT_BIT(19)|RT_BIT(18)|RT_BIT(17)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(7)|RT_BIT(6);
961 break;
962 case 9:
963 pNode->node.name = "Reserved_0";
964 pNode->spdifin.u32A_param = (0x1<<4) | 0x1;
965 pNode->spdifin.node.au32F00_param[9] = (0x1 << 20)|(4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
966 pNode->node.au32F00_param[0xa] = RT_BIT(17)|RT_BIT(5);
967 pNode->spdifin.node.au32F00_param[0xB] = RT_BIT(2)|RT_BIT(0);
968 pNode->spdifin.u32F06_param = 0;
969 pNode->spdifin.u32F0d_param = 0;
970 break;
971 case 0xA:
972 pNode->node.name = "PortA";
973 pNode->node.au32F00_param[0xC] = 0x173f;
974 *(uint32_t *)pNode->node.au8F02_param = 0x2;
975 pNode->port.u32F07_param = RT_BIT(6);
976 pNode->port.u32F08_param = 0;
977 pNode->port.u32F09_param = RT_BIT(31)|RT_BIT(30); /* 39.2 kOm */
978 pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02);
979 goto port_init;
980 case 0xB:
981 pNode->node.name = "PortB";
982 pNode->node.au32F00_param[0xC] = 0x1737;
983 *(uint32_t *)pNode->node.au8F02_param = 0x4;
984 pNode->port.u32F09_param = 0;
985 pNode->port.u32F07_param = RT_BIT(5);
986 pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x11, 0x60, 0x11, 0x01);
987 goto port_init;
988 case 0xC:
989 pNode->node.name = "PortC";
990 *(uint32_t *)pNode->node.au8F02_param = 0x3;
991 pNode->node.au32F00_param[0xC] = 0x1737;
992 pNode->port.u32F09_param = 0;
993 pNode->port.u32F07_param = RT_BIT(5);
994 pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x10, 0x40, 0x11, 0x01);
995 goto port_init;
996 case 0xD:
997 pNode->node.name = "PortD";
998 pNode->port.u32F09_param = 0;
999 pNode->node.au32F00_param[0xC] = 0x173f;
1000 *(uint32_t *)pNode->node.au8F02_param = 0x2;
1001 port_init:
1002 pNode->port.u32F08_param = 0;
1003 pNode->node.au32F00_param[9] = (4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(0);
1004 pNode->node.au32F00_param[0xE] = 0x1;
1005 break;
1006 case 0xE:
1007 pNode->node.name = "PortE";
1008 pNode->node.au32F00_param[9] = (4 << 20)|RT_BIT(7)|RT_BIT(0);
1009 pNode->port.u32F08_param = 0;
1010 pNode->node.au32F00_param[0xC] = RT_BIT(5)|RT_BIT(2);
1011 pNode->port.u32F07_param = RT_BIT(5);
1012 pNode->port.u32F09_param = 0;
1013 pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x51, 0x30, 0x81, 0x01);
1014 break;
1015 case 0xF:
1016 pNode->node.name = "PortF";
1017 pNode->node.au32F00_param[9] = (4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(0);
1018 pNode->node.au32F00_param[0xC] = 0x37;
1019 pNode->node.au32F00_param[0xE] = 0x1;
1020 pNode->port.u32F08_param = 0;
1021 pNode->port.u32F07_param = 0;
1022 pNode->port.u32F1c_param = RT_MAKE_U32_FROM_U8(0x12, 0x60, 0x11, 0x01);
1023 pNode->node.au8F02_param[0] = 0x5;
1024 pNode->port.u32F09_param = 0;
1025 break;
1026 case 0x10:
1027 pNode->node.name = "DigOut_0";
1028 pNode->node.au32F00_param[9] = (4<<20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
1029 pNode->node.au32F00_param[0xC] = RT_BIT(4);
1030 pNode->node.au32F00_param[0xE] = 0x2;
1031 pNode->digout.u32F01_param = 0;
1032 /* STAC9220 spec defines default connection list containing reserved nodes, that confuses some drivers. */
1033 *(uint32_t *)pNode->node.au8F02_param = RT_MAKE_U32_FROM_U8(0x08, 0x17, 0x0, 0);
1034 pNode->digout.u32F07_param = 0;
1035 pNode->digout.u32F1c_param = RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01);
1036 break;
1037 case 0x11:
1038 pNode->node.name = "DigIn_0";
1039 pNode->node.au32F00_param[9] = (4 << 20)|(3<<16)|RT_BIT(10)|RT_BIT(9)|RT_BIT(7)|RT_BIT(0);
1040 pNode->node.au32F00_param[0xC] = /* RT_BIT(16)|*/ RT_BIT(5)|RT_BIT(2);
1041 pNode->digin.u32F05_param = 0x3 << 4 | 0x3; /* PS-Act: D3 -> D3 */
1042 pNode->digin.u32F07_param = 0;
1043 pNode->digin.u32F08_param = 0;
1044 pNode->digin.u32F09_param = 0;
1045 pNode->digin.u32F0c_param = 0;
1046 pNode->digin.u32F1c_param = (0x1 << 24) | (0xc5 << 16) | (0x10 << 8) | 0x60;
1047 break;
1048 case 0x12:
1049 pNode->node.name = "ADCMux_0";
1050 pNode->adcmux.u32F01_param = 0;
1051 goto adcmux_init;
1052 case 0x13:
1053 pNode->node.name = "ADCMux_1";
1054 pNode->adcmux.u32F01_param = 1;
1055 adcmux_init:
1056 pNode->node.au32F00_param[9] = (3<<20)|RT_BIT(8)|RT_BIT(3)|RT_BIT(2)|RT_BIT(0);
1057 pNode->node.au32F00_param[0xe] = 0x7;
1058 pNode->node.au32F00_param[0x12] = (0x27 << 16)|(0x4 << 8);
1059 /* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplefiers inited with 0*/
1060 memset(pNode->adcmux.B_params, 0, AMPLIFIER_SIZE);
1061 *(uint32_t *)&pNode->node.au8F02_param[0] = RT_MAKE_U32_FROM_U8(0xe, 0x15, 0xf, 0xb);
1062 *(uint32_t *)&pNode->node.au8F02_param[4] = RT_MAKE_U32_FROM_U8(0xc, 0xd, 0xa, 0x0);
1063 break;
1064 case 0x14:
1065 pNode->node.name = "PCBEEP";
1066 pNode->node.au32F00_param[9] = (7 << 20) | RT_BIT(3) | RT_BIT(2);
1067 pNode->node.au32F00_param[0x12] = (0x17 << 16)|(0x3 << 8)| 0x3;
1068 pNode->pcbeep.u32F0a_param = 0;
1069 memset(pNode->pcbeep.B_params, 0, AMPLIFIER_SIZE);
1070 break;
1071 case 0x15:
1072 pNode->node.name = "CD";
1073 pNode->node.au32F00_param[0x9] = (4 << 20)|RT_BIT(0);
1074 pNode->node.au32F00_param[0xc] = RT_BIT(5);
1075 pNode->cdnode.u32F07_param = 0;
1076 pNode->cdnode.u32F1c_param = RT_MAKE_U32_FROM_U8(0x52, 0x0, 0x33, 0x90);
1077 break;
1078 case 0x16:
1079 pNode->node.name = "VolumeKnob";
1080 pNode->node.au32F00_param[0x9] = (0x6 << 20);
1081 pNode->node.au32F00_param[0x13] = RT_BIT(7)| 0x7F;
1082 pNode->node.au32F00_param[0xe] = 0x4;
1083 *(uint32_t *)pNode->node.au8F02_param = RT_MAKE_U32_FROM_U8(0x2, 0x3, 0x4, 0x5);
1084 pNode->volumeKnob.u32F08_param = 0;
1085 pNode->volumeKnob.u32F0f_param = 0x7f;
1086 break;
1087 case 0x17:
1088 pNode->node.name = "ADC0Vol";
1089 *(uint32_t *)pNode->node.au8F02_param = 0x12;
1090 goto adcvol_init;
1091 case 0x18:
1092 pNode->node.name = "ADC1Vol";
1093 *(uint32_t *)pNode->node.au8F02_param = 0x13;
1094 adcvol_init:
1095 memset(pNode->adcvol.B_params, 0, AMPLIFIER_SIZE);
1096
1097 pNode->node.au32F00_param[0x9] = (0x3 << 20)|RT_BIT(11)|RT_BIT(8)|RT_BIT(1)|RT_BIT(0);
1098 pNode->node.au32F00_param[0xe] = 0x1;
1099 AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(7);
1100 AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(7);
1101 pNode->adcvol.u32F0c_param = 0;
1102 default:
1103 break;
1104 }
1105 return VINF_SUCCESS;
1106}
1107
1108static CODECVERB STAC9220VERB[] =
1109{
1110/* verb | verb mask | callback */
1111/* ----------- -------------------- ----------------------- */
1112 {0x000F0000, CODEC_VERB_8BIT_CMD , codecGetParameter },
1113 {0x000F0100, CODEC_VERB_8BIT_CMD , codecGetConSelectCtrl },
1114 {0x00070100, CODEC_VERB_8BIT_CMD , codecSetConSelectCtrl },
1115 {0x000F0600, CODEC_VERB_8BIT_CMD , codecGetStreamId },
1116 {0x00070600, CODEC_VERB_8BIT_CMD , codecSetStreamId },
1117 {0x000F0700, CODEC_VERB_8BIT_CMD , codecGetPinCtrl },
1118 {0x00070700, CODEC_VERB_8BIT_CMD , codecSetPinCtrl },
1119 {0x000F0800, CODEC_VERB_8BIT_CMD , codecGetUnsolicitedEnabled },
1120 {0x00070800, CODEC_VERB_8BIT_CMD , codecSetUnsolicitedEnabled },
1121 {0x000F0900, CODEC_VERB_8BIT_CMD , codecGetPinSense },
1122 {0x00070900, CODEC_VERB_8BIT_CMD , codecSetPinSense },
1123 {0x000F0200, CODEC_VERB_8BIT_CMD , codecGetConnectionListEntry },
1124 {0x000F0300, CODEC_VERB_8BIT_CMD , codecGetProcessingState },
1125 {0x00070300, CODEC_VERB_8BIT_CMD , codecSetProcessingState },
1126 {0x000F0D00, CODEC_VERB_8BIT_CMD , codecGetDigitalConverter },
1127 {0x00070D00, CODEC_VERB_8BIT_CMD , codecSetDigitalConverter1 },
1128 {0x00070E00, CODEC_VERB_8BIT_CMD , codecSetDigitalConverter2 },
1129 {0x000F2000, CODEC_VERB_8BIT_CMD , codecGetSubId },
1130 {0x0007FF00, CODEC_VERB_8BIT_CMD , codecReset },
1131 {0x000F0500, CODEC_VERB_8BIT_CMD , codecGetPowerState },
1132 {0x00070500, CODEC_VERB_8BIT_CMD , codecSetPowerState },
1133 {0x000F0C00, CODEC_VERB_8BIT_CMD , codecGetEAPD_BTLEnabled },
1134 {0x00070C00, CODEC_VERB_8BIT_CMD , codecSetEAPD_BTLEnabled },
1135 {0x000F0F00, CODEC_VERB_8BIT_CMD , codecGetVolumeKnobCtrl },
1136 {0x00070F00, CODEC_VERB_8BIT_CMD , codecSetVolumeKnobCtrl },
1137 {0x000F1C00, CODEC_VERB_8BIT_CMD , codecGetConfig },
1138 {0x00071C00, CODEC_VERB_8BIT_CMD , codecSetConfig0 },
1139 {0x00071D00, CODEC_VERB_8BIT_CMD , codecSetConfig1 },
1140 {0x00071E00, CODEC_VERB_8BIT_CMD , codecSetConfig2 },
1141 {0x00071F00, CODEC_VERB_8BIT_CMD , codecSetConfig3 },
1142 {0x000A0000, CODEC_VERB_16BIT_CMD, codecGetConverterFormat },
1143 {0x00020000, CODEC_VERB_16BIT_CMD, codecSetConverterFormat },
1144 {0x000B0000, CODEC_VERB_16BIT_CMD, codecGetAmplifier },
1145 {0x00030000, CODEC_VERB_16BIT_CMD, codecSetAmplifier },
1146};
1147
1148static int codecLookup(CODECState *pState, uint32_t cmd, PPFNCODECVERBPROCESSOR pfn)
1149{
1150 int rc = VINF_SUCCESS;
1151 Assert(CODEC_CAD(cmd) == pState->id);
1152 if ( CODEC_VERBDATA(cmd) == 0
1153 || CODEC_NID(cmd) >= STAC9220_NODE_COUNT
1154 || STAC9220_IS_RESERVED_CMD(cmd))
1155 {
1156 *pfn = codecUnimplemented;
1157 //** @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp)
1158 LogRel(("HDAcodec: cmd %x was ignored\n", cmd));
1159 return VINF_SUCCESS;
1160 }
1161 for (int i = 0; i < pState->cVerbs; ++i)
1162 {
1163 if ((CODEC_VERBDATA(cmd) & pState->pVerbs[i].mask) == pState->pVerbs[i].verb)
1164 {
1165 *pfn = pState->pVerbs[i].pfn;
1166 return VINF_SUCCESS;
1167 }
1168 }
1169 *pfn = codecUnimplemented;
1170 LogRel(("HDAcodec: callback for %x wasn't found\n", CODEC_VERBDATA(cmd)));
1171 return rc;
1172}
1173#define CODEC_FMT_BASE_FRQ_SHIFT (14)
1174#define CODEC_FMT_BASE_FRQ_MASK (RT_BIT(CODEC_FMT_BASE_FRQ_SHIFT))
1175#define CODEC_FMT_DIV_FRQ_SHIFT 8
1176#define CODEC_FMT_DIV_FRQ_MASK ((0x7) << CODEC_FMT_DIV_FRQ_SHIFT)
1177#define CODEC_FMT_MUL_FRQ_SHIFT 11
1178#define CODEC_FMT_MUL_FRQ_MASK ((0x7) << CODEC_FMT_MUL_FRQ_SHIFT)
1179#define CODEC_FMT_BASE_FRQ(fmt) ((fmt & CODEC_FMT_BASE_FRQ_MASK) >> CODEC_FMT_BASE_FRQ_SHIFT)
1180#define CODEC_FMT_DIV_FRQ(fmt) ((fmt & CODEC_FMT_DIV_FRQ_MASK) >> CODEC_FMT_DIV_FRQ_SHIFT)
1181#define CODEC_FMT_MUL_FRQ(fmt) ((fmt & CODEC_FMT_MUL_FRQ_MASK) >> CODEC_FMT_MUL_FRQ_SHIFT)
1182#define CODEC_DAC_CHANELS(reg) (1 << ((reg) & 0x3))
1183static int codecFrequencyCalculate(uint32_t dacFmt)
1184{
1185 uint32_t baseFrq = CODEC_FMT_BASE_FRQ(dacFmt);
1186 uint32_t divFrq = CODEC_FMT_DIV_FRQ(dacFmt);
1187 uint32_t multFrq = CODEC_FMT_MUL_FRQ(dacFmt);
1188 switch (baseFrq)
1189 {
1190 case 0: baseFrq = 48000; break;
1191 case 0x1: baseFrq = 44100; break;
1192 default:
1193 AssertMsgFailed(("Unsupported Freq."));
1194 }
1195 switch(multFrq)
1196 {
1197 case 0: multFrq = 1; break;
1198 case 0x1: multFrq = 2; break;
1199 case 0x3: multFrq = 4; break;
1200 default:
1201 AssertMsgFailed(("Unsupported Freq. multiplier"));
1202 }
1203 switch(divFrq)
1204 {
1205 case 0: divFrq = 1; break;
1206 case 0x1: divFrq = 2; break;
1207 case 0x2: divFrq = 3; break;
1208 case 0x3: divFrq = 4; break;
1209 case 0x4: divFrq = 5; break;
1210 case 0x5: divFrq = 6; break;
1211 case 0x6: divFrq = 7; break;
1212 case 0x7: divFrq = 8; break;
1213 }
1214 return baseFrq * multFrq / divFrq;
1215}
1216static int codec_dac_to_aud(CODECState *pState, int dacnum, audsettings_t *paud)
1217{
1218 uint32_t dacfmt = pState->pNodes[dacnum].dac.u32A_param;
1219 paud->freq = 44100;//codecFrequencyCalculate(dacfmt);
1220 paud->nchannels = 2;//CODEC_DAC_CHANELS(dacfmt);
1221 paud->fmt = AUD_FMT_U16;
1222
1223 paud->endianness = 0;
1224 return VINF_SUCCESS;
1225}
1226
1227static void pi_callback (void *opaque, int avail)
1228{
1229 CODECState *pState = (CODECState *)opaque;
1230 pState->pfnTransfer(pState, PI_INDEX, avail);
1231}
1232
1233static void po_callback (void *opaque, int avail)
1234{
1235 CODECState *pState = (CODECState *)opaque;
1236 pState->pfnTransfer(pState, PO_INDEX, avail);
1237}
1238
1239static void mc_callback (void *opaque, int avail)
1240{
1241 CODECState *pState = (CODECState *)opaque;
1242 pState->pfnTransfer(pState, MC_INDEX, avail);
1243}
1244#define STAC9220_DAC_PI (0x2)
1245#define STAC9220_DAC_MC (0x3)
1246#define STAC9220_DAC_PO (0x4)
1247int stac9220Construct(CODECState *pState)
1248{
1249 audsettings_t as;
1250 pState->pVerbs = (CODECVERB *)&STAC9220VERB;
1251 pState->cVerbs = sizeof(STAC9220VERB)/sizeof(CODECVERB);
1252 pState->pfnLookup = codecLookup;
1253 pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * STAC9220_NODE_COUNT);
1254 uint8_t i;
1255 for (i = 0; i < STAC9220_NODE_COUNT; ++i)
1256 {
1257 stac9220ResetNode(pState, i, &pState->pNodes[i]);
1258 }
1259 //** @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
1260 AUD_register_card ("ICH0", &pState->card);
1261
1262
1263 codec_dac_to_aud(pState, STAC9220_DAC_PI, &as);
1264 pState->voice_pi = AUD_open_in(&pState->card, pState->voice_pi, "hda.in", pState, pi_callback, &as);
1265 codec_dac_to_aud(pState, STAC9220_DAC_PO, &as);
1266 pState->voice_po = AUD_open_out(&pState->card, pState->voice_po, "hda.out", pState, po_callback, &as);
1267 codec_dac_to_aud(pState, STAC9220_DAC_MC, &as);
1268 pState->voice_mc = AUD_open_in(&pState->card, pState->voice_mc, "hda.mc", pState, mc_callback, &as);
1269 if (!pState->voice_pi)
1270 LogRel (("HDAcodec: WARNING: Unable to open PCM IN!\n"));
1271 if (!pState->voice_mc)
1272 LogRel (("HDAcodec: WARNING: Unable to open PCM MC!\n"));
1273 if (!pState->voice_po)
1274 LogRel (("HDAcodec: WARNING: Unable to open PCM OUT!\n"));
1275 int mute = 0;
1276 uint8_t lvol = 0x7f;
1277 uint8_t rvol = 0x7f;
1278 AUD_set_volume_out(pState->voice_po, mute, lvol, rvol);
1279 return VINF_SUCCESS;
1280}
1281int stac9220Destruct(CODECState *pCodecState)
1282{
1283 RTMemFree(pCodecState->pNodes);
1284 return VINF_SUCCESS;
1285}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette