Changeset 32804 in vbox
- Timestamp:
- Sep 29, 2010 5:39:06 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 66254
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevCodec.cpp
r32803 r32804 74 74 #define CODEC_SET_AMP_INDEX(cmd) (((cmd) & CODEC_VERB_SET_AMP_INDEX) >> 7) 75 75 76 /* STAC9220 */ 76 77 const static uint8_t au8Stac9220Ports[] = { 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0}; 77 78 const static uint8_t au8Stac9220Dacs[] = { 0x2, 0x3, 0x4, 0x5, 0}; … … 88 89 const static uint8_t au8Stac9220Reserveds[] = { 0x9, 0x19, 0x1a, 0x1b, 0 }; 89 90 90 #define CODEC_POWER_MASK 0x391 #define CODEC_POWER_ACT_SHIFT (4)92 #define CODEC_POWER_SET_SHIFT (0)93 #define CODEC_POWER_D0 (0)94 #define CODEC_POWER_D1 (1)95 #define CODEC_POWER_D2 (2)96 #define CODEC_POWER_D3 (3)97 #define CODEC_POWER_PROPOGATE_STATE(node) \98 do { \99 node.u32F05_param &= (CODEC_POWER_MASK); \100 node.u32F05_param |= (node.u32F05_param & CODEC_POWER_MASK) << CODEC_POWER_ACT_SHIFT; \101 }while(0)102 103 #define DECLISNODEOFTYPE(type) \104 static inline int codecIs##type##Node(struct CODECState *pState, uint8_t cNode) \105 { \106 Assert(pState->au8##type##s); \107 for(int i = 0; pState->au8##type##s[i] != 0; ++i) \108 if (pState->au8##type##s[i] == cNode) \109 return 1; \110 return 0; \111 }112 /* codecIsPortNode */113 DECLISNODEOFTYPE(Port)114 /* codecIsDacNode */115 DECLISNODEOFTYPE(Dac)116 /* codecIsAdcVolNode */117 DECLISNODEOFTYPE(AdcVol)118 /* codecIsAdcNode */119 DECLISNODEOFTYPE(Adc)120 /* codecIsAdcMuxNode */121 DECLISNODEOFTYPE(AdcMux)122 /* codecIsPcbeepNode */123 DECLISNODEOFTYPE(Pcbeep)124 /* codecIsSpdifOutNode */125 DECLISNODEOFTYPE(SpdifOut)126 /* codecIsSpdifInNode */127 DECLISNODEOFTYPE(SpdifIn)128 /* codecIsDigInPinNode */129 DECLISNODEOFTYPE(DigInPin)130 /* codecIsDigOutPinNode */131 DECLISNODEOFTYPE(DigOutPin)132 /* codecIsCdNode */133 DECLISNODEOFTYPE(Cd)134 /* codecIsVolKnobNode */135 DECLISNODEOFTYPE(VolKnob)136 /* codecIsReservedNode */137 DECLISNODEOFTYPE(Reserved)138 139 91 static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode); 140 static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt); 141 142 static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask) 143 { 144 Assert((pu32Reg && u8Offset < 32)); 145 *pu32Reg &= ~(mask << u8Offset); 146 *pu32Reg |= (u32Cmd & mask) << u8Offset; 147 } 148 static inline void codecSetRegisterU8(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset) 149 { 150 codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_8BIT_DATA); 151 } 152 153 static inline void codecSetRegisterU16(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset) 154 { 155 codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_16BIT_DATA); 156 } 157 158 159 static int codecUnimplemented(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 160 { 161 Log(("codecUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd, 162 CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd))); 163 *pResp = 0; 164 return VINF_SUCCESS; 165 } 166 167 static int codecBreak(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 168 { 169 int rc; 170 rc = codecUnimplemented(pState, cmd, pResp); 171 *pResp |= CODEC_RESPONSE_UNSOLICITED; 172 return rc; 173 } 174 /* B-- */ 175 static int codecGetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 176 { 177 Assert((CODEC_CAD(cmd) == pState->id)); 178 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 179 if (CODEC_NID(cmd) >= pState->cTotalNodes) 180 { 181 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 182 return VINF_SUCCESS; 183 } 184 *pResp = 0; 185 /* HDA spec 7.3.3.7 Note A */ 186 /* @todo: if index out of range response should be 0 */ 187 uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT? 0 : CODEC_GET_AMP_INDEX(cmd); 188 189 PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)]; 190 if (codecIsDacNode(pState, CODEC_NID(cmd))) 191 *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params, 192 CODEC_GET_AMP_DIRECTION(cmd), 193 CODEC_GET_AMP_SIDE(cmd), 194 u8Index); 195 else if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 196 *pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params, 197 CODEC_GET_AMP_DIRECTION(cmd), 198 CODEC_GET_AMP_SIDE(cmd), 199 u8Index); 200 else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 201 *pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params, 202 CODEC_GET_AMP_DIRECTION(cmd), 203 CODEC_GET_AMP_SIDE(cmd), 204 u8Index); 205 else if (codecIsPcbeepNode(pState, CODEC_NID(cmd))) 206 *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params, 207 CODEC_GET_AMP_DIRECTION(cmd), 208 CODEC_GET_AMP_SIDE(cmd), 209 u8Index); 210 else{ 211 AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS); 212 } 213 return VINF_SUCCESS; 214 } 215 /* 3-- */ 216 static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 217 { 218 AMPLIFIER *pAmplifier = NULL; 219 bool fIsLeft = false; 220 bool fIsRight = false; 221 bool fIsOut = false; 222 bool fIsIn = false; 223 uint8_t u8Index = 0; 224 Assert((CODEC_CAD(cmd) == pState->id)); 225 if (CODEC_NID(cmd) >= pState->cTotalNodes) 226 { 227 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 228 return VINF_SUCCESS; 229 } 230 *pResp = 0; 231 PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)]; 232 if (codecIsDacNode(pState, CODEC_NID(cmd))) 233 pAmplifier = &pNode->dac.B_params; 234 else if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 235 pAmplifier = &pNode->adcvol.B_params; 236 else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 237 pAmplifier = &pNode->adcmux.B_params; 238 else if (codecIsPcbeepNode(pState, CODEC_NID(cmd))) 239 pAmplifier = &pNode->pcbeep.B_params; 240 Assert(pAmplifier); 241 if (pAmplifier) 242 { 243 fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd); 244 fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd); 245 fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd); 246 fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd); 247 u8Index = CODEC_SET_AMP_INDEX(cmd); 248 if ( (!fIsLeft && !fIsRight) 249 || (!fIsOut && !fIsIn)) 250 return VINF_SUCCESS; 251 if (fIsIn) 252 { 253 if (fIsLeft) 254 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0); 255 if (fIsRight) 256 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0); 257 } 258 if (fIsOut) 259 { 260 if (fIsLeft) 261 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0); 262 if (fIsRight) 263 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0); 264 } 265 if (CODEC_NID(cmd) == 2) 266 codecToAudVolume(pAmplifier, AUD_MIXER_VOLUME); 267 if (CODEC_NID(cmd) == 0x17) /* Microphone */ 268 codecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN); 269 } 270 return VINF_SUCCESS; 271 } 272 273 static int codecGetParameter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 274 { 275 Assert((CODEC_CAD(cmd) == pState->id)); 276 if (CODEC_NID(cmd) >= pState->cTotalNodes) 277 { 278 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 279 return VINF_SUCCESS; 280 } 281 Assert(((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F0_PARAM_LENGTH)); 282 if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F0_PARAM_LENGTH) 283 { 284 Log(("HDAcodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA))); 285 return VINF_SUCCESS; 286 } 287 *pResp = 0; 288 *pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA]; 289 return VINF_SUCCESS; 290 } 291 292 /* F01 */ 293 static int codecGetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 294 { 295 Assert((CODEC_CAD(cmd) == pState->id)); 296 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 297 if (CODEC_NID(cmd) >= pState->cTotalNodes) 298 { 299 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 300 return VINF_SUCCESS; 301 } 302 *pResp = 0; 303 if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 304 *pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param; 305 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 306 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param; 307 return VINF_SUCCESS; 308 } 309 310 /* 701 */ 311 static int codecSetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 312 { 313 uint32_t *pu32Reg = NULL; 314 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 315 if (CODEC_NID(cmd) >= pState->cTotalNodes) 316 { 317 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 318 return VINF_SUCCESS; 319 } 320 *pResp = 0; 321 if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 322 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param; 323 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 324 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param; 325 Assert((pu32Reg)); 326 if (pu32Reg) 327 codecSetRegisterU8(pu32Reg, cmd, 0); 328 return VINF_SUCCESS; 329 } 330 331 /* F07 */ 332 static int codecGetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 333 { 334 Assert((CODEC_CAD(cmd) == pState->id)); 335 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 336 if (CODEC_NID(cmd) >= pState->cTotalNodes) 337 { 338 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 339 return VINF_SUCCESS; 340 } 341 *pResp = 0; 342 if (codecIsPortNode(pState, CODEC_NID(cmd))) 343 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F07_param; 344 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 345 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param; 346 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 347 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param; 348 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 349 *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param; 350 else if ( codecIsReservedNode(pState, CODEC_NID(cmd)) 351 && CODEC_NID(cmd) == 0x1b) 352 *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param; 353 else 354 AssertMsgFailed(("Unsupported")); 355 return VINF_SUCCESS; 356 } 357 358 /* 707 */ 359 static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 360 { 361 Assert((CODEC_CAD(cmd) == pState->id)); 362 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 363 if (CODEC_NID(cmd) >= pState->cTotalNodes) 364 { 365 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 366 return VINF_SUCCESS; 367 } 368 *pResp = 0; 369 uint32_t *pu32Reg = NULL; 370 if (codecIsPortNode(pState, CODEC_NID(cmd))) 371 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F07_param; 372 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 373 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param; 374 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 375 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param; 376 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 377 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param; 378 else if ( codecIsReservedNode(pState, CODEC_NID(cmd)) 379 && CODEC_NID(cmd) == 0x1b) 380 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param; 381 Assert((pu32Reg)); 382 if (pu32Reg) 383 codecSetRegisterU8(pu32Reg, cmd, 0); 384 return VINF_SUCCESS; 385 } 386 387 /* F08 */ 388 static int codecGetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 389 { 390 Assert((CODEC_CAD(cmd) == pState->id)); 391 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 392 if (CODEC_NID(cmd) >= pState->cTotalNodes) 393 { 394 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 395 return VINF_SUCCESS; 396 } 397 *pResp = 0; 398 if (codecIsPortNode(pState, CODEC_NID(cmd))) 399 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F08_param; 400 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 401 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param; 402 else if ((cmd) == 1 /* AFG */) 403 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param; 404 else if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 405 *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param; 406 else 407 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd))); 408 return VINF_SUCCESS; 409 } 410 411 /* 708 */ 412 static int codecSetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 413 { 414 Assert((CODEC_CAD(cmd) == pState->id)); 415 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 416 if (CODEC_NID(cmd) >= pState->cTotalNodes) 417 { 418 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 419 return VINF_SUCCESS; 420 } 421 *pResp = 0; 422 uint32_t *pu32Reg = NULL; 423 if (codecIsPortNode(pState, CODEC_NID(cmd))) 424 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param; 425 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 426 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param; 427 else if (CODEC_NID(cmd) == 1 /* AFG */) 428 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param; 429 else if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 430 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param; 431 else 432 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd))); 433 Assert(pu32Reg); 434 if(pu32Reg) 435 codecSetRegisterU8(pu32Reg, cmd, 0); 436 return VINF_SUCCESS; 437 } 438 439 /* F09 */ 440 static int codecGetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 441 { 442 Assert((CODEC_CAD(cmd) == pState->id)); 443 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 444 if (CODEC_NID(cmd) >= pState->cTotalNodes) 445 { 446 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 447 return VINF_SUCCESS; 448 } 449 *pResp = 0; 450 if (codecIsPortNode(pState, CODEC_NID(cmd))) 451 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F09_param; 452 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 453 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param; 454 else 455 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd))); 456 return VINF_SUCCESS; 457 } 458 459 /* 709 */ 460 static int codecSetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 461 { 462 Assert((CODEC_CAD(cmd) == pState->id)); 463 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 464 if (CODEC_NID(cmd) >= pState->cTotalNodes) 465 { 466 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 467 return VINF_SUCCESS; 468 } 469 *pResp = 0; 470 uint32_t *pu32Reg = NULL; 471 //** @todo r=michaln: Copy/paste bug? This can't be F08_parm! 472 if (codecIsPortNode(pState, CODEC_NID(cmd))) 473 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param; 474 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 475 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param; 476 Assert(pu32Reg); 477 if(pu32Reg) 478 codecSetRegisterU8(pu32Reg, cmd, 0); 479 return VINF_SUCCESS; 480 } 481 482 static int codecGetConnectionListEntry(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 483 { 484 Assert((CODEC_CAD(cmd) == pState->id)); 485 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 486 if (CODEC_NID(cmd) >= pState->cTotalNodes) 487 { 488 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 489 return VINF_SUCCESS; 490 } 491 Assert((cmd & CODEC_VERB_8BIT_DATA) < 16); 492 if ((cmd & CODEC_VERB_8BIT_DATA) >= 16) 493 { 494 Log(("HDAcodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA))); 495 } 496 *pResp = *(uint32_t *)&pState->pNodes[CODEC_NID(cmd)].node.au8F02_param[cmd & CODEC_VERB_8BIT_DATA]; 497 return VINF_SUCCESS; 498 } 499 /* F03 */ 500 static int codecGetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 501 { 502 Assert((CODEC_CAD(cmd) == pState->id)); 503 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 504 if (CODEC_NID(cmd) >= pState->cTotalNodes) 505 { 506 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 507 return VINF_SUCCESS; 508 } 509 *pResp = 0; 510 if (codecIsAdcNode(pState, CODEC_NID(cmd))) 511 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param; 512 return VINF_SUCCESS; 513 } 514 515 /* 703 */ 516 static int codecSetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 517 { 518 Assert((CODEC_CAD(cmd) == pState->id)); 519 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 520 if (CODEC_NID(cmd) >= pState->cTotalNodes) 521 { 522 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 523 return VINF_SUCCESS; 524 } 525 *pResp = 0; 526 if (codecIsAdcNode(pState, CODEC_NID(cmd))) 527 { 528 codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0); 529 } 530 return VINF_SUCCESS; 531 } 532 533 /* F0D */ 534 static int codecGetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 535 { 536 Assert((CODEC_CAD(cmd) == pState->id)); 537 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 538 if (CODEC_NID(cmd) >= pState->cTotalNodes) 539 { 540 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 541 return VINF_SUCCESS; 542 } 543 *pResp = 0; 544 if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 545 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param; 546 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 547 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param; 548 return VINF_SUCCESS; 549 } 550 551 static int codecSetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset, uint64_t *pResp) 552 { 553 Assert((CODEC_CAD(cmd) == pState->id)); 554 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 555 if (CODEC_NID(cmd) >= pState->cTotalNodes) 556 { 557 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 558 return VINF_SUCCESS; 559 } 560 *pResp = 0; 561 if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 562 codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset); 563 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 564 codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset); 565 return VINF_SUCCESS; 566 } 567 568 /* 70D */ 569 static int codecSetDigitalConverter1(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 570 { 571 return codecSetDigitalConverter(pState, cmd, 0, pResp); 572 } 573 574 /* 70E */ 575 static int codecSetDigitalConverter2(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 576 { 577 return codecSetDigitalConverter(pState, cmd, 8, pResp); 578 } 579 580 static int codecGetSubId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 581 { 582 Assert((CODEC_CAD(cmd) == pState->id)); 583 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 584 if (CODEC_NID(cmd) >= pState->cTotalNodes) 585 { 586 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 587 return VINF_SUCCESS; 588 } 589 *pResp = 0; 590 if (CODEC_NID(cmd) == 1 /* AFG */) 591 { 592 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param; 593 } 594 return VINF_SUCCESS; 595 } 596 597 static int codecReset(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 598 { 599 Assert((CODEC_CAD(cmd) == pState->id)); 600 Assert(CODEC_NID(cmd) == 1 /* AFG */); 601 if(CODEC_NID(cmd) == 1 /* AFG */) 602 { 603 uint8_t i; 604 Log(("HDAcodec: enters reset\n")); 605 for (i = 0; i < pState->cTotalNodes; ++i) 606 { 607 stac9220ResetNode(pState, i, &pState->pNodes[i]); 608 } 609 pState->fInReset = false; 610 Log(("HDAcodec: exits reset\n")); 611 } 612 *pResp = 0; 613 return VINF_SUCCESS; 614 } 615 616 /* F05 */ 617 static int codecGetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 618 { 619 Assert((CODEC_CAD(cmd) == pState->id)); 620 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 621 if (CODEC_NID(cmd) >= pState->cTotalNodes) 622 { 623 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 624 return VINF_SUCCESS; 625 } 626 *pResp = 0; 627 if (CODEC_NID(cmd) == 1 /* AFG */) 628 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param; 629 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 630 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param; 631 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 632 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param; 633 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 634 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param; 635 return VINF_SUCCESS; 636 } 637 638 /* 705 */ 639 static int codecSetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 640 { 641 Assert((CODEC_CAD(cmd) == pState->id)); 642 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 643 if (CODEC_NID(cmd) >= pState->cTotalNodes) 644 { 645 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 646 return VINF_SUCCESS; 647 } 648 uint32_t *pu32Reg = NULL; 649 *pResp = 0; 650 if (CODEC_NID(cmd) == 1 /* AFG */) 651 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param; 652 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 653 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param; 654 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 655 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param; 656 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 657 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param; 658 Assert((pu32Reg)); 659 if (!pu32Reg) 660 return VINF_SUCCESS; 661 662 if (!CODEC_NID(cmd) == 1 /* AFG */) 663 { 664 *pu32Reg &= ~CODEC_VERB_8BIT_DATA; 665 *pu32Reg |= (pState->pNodes[1].afg.u32F05_param & (CODEC_VERB_4BIT_DATA << 4)); 666 } 667 else 668 *pu32Reg &= ~CODEC_VERB_4BIT_DATA; 669 670 *pu32Reg |= cmd & CODEC_VERB_4BIT_DATA; 671 /* Propogate next power state only if AFG is on or verb modifies AFG power state */ 672 if ( CODEC_NID(cmd) == 1 /* AFG */ 673 || !pState->pNodes[1].afg.u32F05_param) 674 { 675 *pu32Reg &= ~(CODEC_POWER_MASK << CODEC_POWER_ACT_SHIFT); 676 *pu32Reg |= (cmd & CODEC_VERB_4BIT_DATA) << 4; 677 if ( CODEC_NID(cmd) == 1 /* AFG */ 678 && (cmd & CODEC_POWER_MASK) == CODEC_POWER_D0) 679 { 680 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[2].dac); 681 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[3].dac); 682 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[4].dac); 683 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[5].dac); 684 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[6].dac); 685 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[7].dac); 686 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[0x11].dac); 687 } 688 } 689 return VINF_SUCCESS; 690 } 691 692 static int codecGetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 693 { 694 Assert((CODEC_CAD(cmd) == pState->id)); 695 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 696 if (CODEC_NID(cmd) >= pState->cTotalNodes) 697 { 698 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 699 return VINF_SUCCESS; 700 } 701 *pResp = 0; 702 if (codecIsDacNode(pState, CODEC_NID(cmd))) 703 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param; 704 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 705 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param; 706 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 707 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param; 708 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 709 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param; 710 else if (CODEC_NID(cmd) == 0x1A) 711 *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param; 712 return VINF_SUCCESS; 713 } 714 static int codecSetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 715 { 716 Assert((CODEC_CAD(cmd) == pState->id)); 717 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 718 if (CODEC_NID(cmd) >= pState->cTotalNodes) 719 { 720 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 721 return VINF_SUCCESS; 722 } 723 *pResp = 0; 724 uint32_t *pu32addr = NULL; 725 *pResp = 0; 726 if (codecIsDacNode(pState, CODEC_NID(cmd))) 727 pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param; 728 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 729 pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param; 730 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 731 pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param; 732 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 733 pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param; 734 else if (codecIsReservedNode(pState, CODEC_NID(cmd))) 735 pu32addr = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param; 736 Assert((pu32addr)); 737 if (pu32addr) 738 codecSetRegisterU8(pu32addr, cmd, 0); 739 return VINF_SUCCESS; 740 } 741 static int codecGetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 742 { 743 Assert((CODEC_CAD(cmd) == pState->id)); 744 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 745 if (CODEC_NID(cmd) >= pState->cTotalNodes) 746 { 747 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 748 return VINF_SUCCESS; 749 } 750 *pResp = 0; 751 if (codecIsDacNode(pState, CODEC_NID(cmd))) 752 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32A_param; 753 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 754 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32A_param; 755 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 756 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param; 757 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 758 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param; 759 return VINF_SUCCESS; 760 } 761 762 static int codecSetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 763 { 764 Assert((CODEC_CAD(cmd) == pState->id)); 765 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 766 if (CODEC_NID(cmd) >= pState->cTotalNodes) 767 { 768 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 769 return VINF_SUCCESS; 770 } 771 *pResp = 0; 772 if (codecIsDacNode(pState, CODEC_NID(cmd))) 773 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0); 774 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 775 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0); 776 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 777 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0); 778 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 779 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0); 780 return VINF_SUCCESS; 781 } 782 783 /* F0C */ 784 static int codecGetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 785 { 786 Assert((CODEC_CAD(cmd) == pState->id)); 787 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 788 if (CODEC_NID(cmd) >= pState->cTotalNodes) 789 { 790 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 791 return VINF_SUCCESS; 792 } 793 *pResp = 0; 794 if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 795 *pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param; 796 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 797 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param; 798 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 799 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param; 800 return VINF_SUCCESS; 801 } 802 803 /* 70C */ 804 static int codecSetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 805 { 806 Assert((CODEC_CAD(cmd) == pState->id)); 807 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 808 if (CODEC_NID(cmd) >= pState->cTotalNodes) 809 { 810 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 811 return VINF_SUCCESS; 812 } 813 *pResp = 0; 814 uint32_t *pu32Reg = NULL; 815 if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 816 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param; 817 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 818 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param; 819 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 820 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param; 821 *pResp = 0; 822 Assert((pu32Reg)); 823 if (pu32Reg) 824 codecSetRegisterU8(pu32Reg, cmd, 0); 825 return VINF_SUCCESS; 826 } 827 828 /* F0F */ 829 static int codecGetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 830 { 831 Assert((CODEC_CAD(cmd) == pState->id)); 832 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 833 if (CODEC_NID(cmd) >= pState->cTotalNodes) 834 { 835 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 836 return VINF_SUCCESS; 837 } 838 *pResp = 0; 839 if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 840 *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param; 841 return VINF_SUCCESS; 842 } 843 844 /* 70F */ 845 static int codecSetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 846 { 847 Assert((CODEC_CAD(cmd) == pState->id)); 848 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 849 if (CODEC_NID(cmd) >= pState->cTotalNodes) 850 { 851 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 852 return VINF_SUCCESS; 853 } 854 uint32_t *pu32Reg = NULL; 855 *pResp = 0; 856 if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 857 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param; 858 Assert((pu32Reg)); 859 if (pu32Reg) 860 codecSetRegisterU8(pu32Reg, cmd, 0); 861 return VINF_SUCCESS; 862 } 863 864 /* F1C */ 865 static int codecGetConfig (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 866 { 867 Assert((CODEC_CAD(cmd) == pState->id)); 868 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 869 if (CODEC_NID(cmd) >= pState->cTotalNodes) 870 { 871 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 872 return VINF_SUCCESS; 873 } 874 *pResp = 0; 875 if (codecIsPortNode(pState, CODEC_NID(cmd))) 876 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param; 877 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 878 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param; 879 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 880 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param; 881 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 882 *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param; 883 return VINF_SUCCESS; 884 } 885 static int codecSetConfigX(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset) 886 { 887 Assert((CODEC_CAD(cmd) == pState->id)); 888 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 889 if (CODEC_NID(cmd) >= pState->cTotalNodes) 890 { 891 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 892 return VINF_SUCCESS; 893 } 894 uint32_t *pu32Reg = NULL; 895 if (codecIsPortNode(pState, CODEC_NID(cmd))) 896 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param; 897 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 898 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param; 899 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 900 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param; 901 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 902 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param; 903 else if (CODEC_NID(cmd) == 0x1B) 904 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F1c_param; 905 Assert((pu32Reg)); 906 if (pu32Reg) 907 codecSetRegisterU8(pu32Reg, cmd, u8Offset); 908 return VINF_SUCCESS; 909 } 910 /* 71C */ 911 static int codecSetConfig0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 912 { 913 *pResp = 0; 914 return codecSetConfigX(pState, cmd, 0); 915 } 916 /* 71D */ 917 static int codecSetConfig1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 918 { 919 *pResp = 0; 920 return codecSetConfigX(pState, cmd, 8); 921 } 922 /* 71E */ 923 static int codecSetConfig2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 924 { 925 *pResp = 0; 926 return codecSetConfigX(pState, cmd, 16); 927 } 928 /* 71E */ 929 static int codecSetConfig3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 930 { 931 *pResp = 0; 932 return codecSetConfigX(pState, cmd, 24); 92 93 static int stac9220Construct(CODECState *pState) 94 { 95 unconst(pState->cTotalNodes) = 0x1C; 96 pState->pfnCodecNodeReset = stac9220ResetNode; 97 pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes); 98 pState->fInReset = false; 99 #define STAC9220WIDGET(type) pState->au8##type##s = au8Stac9220##type##s 100 STAC9220WIDGET(Port); 101 STAC9220WIDGET(Dac); 102 STAC9220WIDGET(Adc); 103 STAC9220WIDGET(AdcVol); 104 STAC9220WIDGET(AdcMux); 105 STAC9220WIDGET(Pcbeep); 106 STAC9220WIDGET(SpdifIn); 107 STAC9220WIDGET(SpdifOut); 108 STAC9220WIDGET(DigInPin); 109 STAC9220WIDGET(DigOutPin); 110 STAC9220WIDGET(Cd); 111 STAC9220WIDGET(VolKnob); 112 STAC9220WIDGET(Reserved); 113 #undef STAC9220WIDGET 114 unconst(pState->u8AdcVolsLineIn) = 0x17; 115 unconst(pState->u8DacLineOut) = 0x2; 116 117 return VINF_SUCCESS; 933 118 } 934 119 … … 1188 373 } 1189 374 375 /* generic */ 376 377 #define CODEC_POWER_MASK 0x3 378 #define CODEC_POWER_ACT_SHIFT (4) 379 #define CODEC_POWER_SET_SHIFT (0) 380 #define CODEC_POWER_D0 (0) 381 #define CODEC_POWER_D1 (1) 382 #define CODEC_POWER_D2 (2) 383 #define CODEC_POWER_D3 (3) 384 #define CODEC_POWER_PROPOGATE_STATE(node) \ 385 do { \ 386 node.u32F05_param &= (CODEC_POWER_MASK); \ 387 node.u32F05_param |= (node.u32F05_param & CODEC_POWER_MASK) << CODEC_POWER_ACT_SHIFT; \ 388 }while(0) 389 390 #define DECLISNODEOFTYPE(type) \ 391 static inline int codecIs##type##Node(struct CODECState *pState, uint8_t cNode) \ 392 { \ 393 Assert(pState->au8##type##s); \ 394 for(int i = 0; pState->au8##type##s[i] != 0; ++i) \ 395 if (pState->au8##type##s[i] == cNode) \ 396 return 1; \ 397 return 0; \ 398 } 399 /* codecIsPortNode */ 400 DECLISNODEOFTYPE(Port) 401 /* codecIsDacNode */ 402 DECLISNODEOFTYPE(Dac) 403 /* codecIsAdcVolNode */ 404 DECLISNODEOFTYPE(AdcVol) 405 /* codecIsAdcNode */ 406 DECLISNODEOFTYPE(Adc) 407 /* codecIsAdcMuxNode */ 408 DECLISNODEOFTYPE(AdcMux) 409 /* codecIsPcbeepNode */ 410 DECLISNODEOFTYPE(Pcbeep) 411 /* codecIsSpdifOutNode */ 412 DECLISNODEOFTYPE(SpdifOut) 413 /* codecIsSpdifInNode */ 414 DECLISNODEOFTYPE(SpdifIn) 415 /* codecIsDigInPinNode */ 416 DECLISNODEOFTYPE(DigInPin) 417 /* codecIsDigOutPinNode */ 418 DECLISNODEOFTYPE(DigOutPin) 419 /* codecIsCdNode */ 420 DECLISNODEOFTYPE(Cd) 421 /* codecIsVolKnobNode */ 422 DECLISNODEOFTYPE(VolKnob) 423 /* codecIsReservedNode */ 424 DECLISNODEOFTYPE(Reserved) 425 426 static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt); 427 428 static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask) 429 { 430 Assert((pu32Reg && u8Offset < 32)); 431 *pu32Reg &= ~(mask << u8Offset); 432 *pu32Reg |= (u32Cmd & mask) << u8Offset; 433 } 434 static inline void codecSetRegisterU8(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset) 435 { 436 codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_8BIT_DATA); 437 } 438 439 static inline void codecSetRegisterU16(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset) 440 { 441 codecSetRegister(pu32Reg, u32Cmd, u8Offset, CODEC_VERB_16BIT_DATA); 442 } 443 444 445 static int codecUnimplemented(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 446 { 447 Log(("codecUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd, 448 CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd))); 449 *pResp = 0; 450 return VINF_SUCCESS; 451 } 452 453 static int codecBreak(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 454 { 455 int rc; 456 rc = codecUnimplemented(pState, cmd, pResp); 457 *pResp |= CODEC_RESPONSE_UNSOLICITED; 458 return rc; 459 } 460 /* B-- */ 461 static int codecGetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 462 { 463 Assert((CODEC_CAD(cmd) == pState->id)); 464 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 465 if (CODEC_NID(cmd) >= pState->cTotalNodes) 466 { 467 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 468 return VINF_SUCCESS; 469 } 470 *pResp = 0; 471 /* HDA spec 7.3.3.7 Note A */ 472 /* @todo: if index out of range response should be 0 */ 473 uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT? 0 : CODEC_GET_AMP_INDEX(cmd); 474 475 PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)]; 476 if (codecIsDacNode(pState, CODEC_NID(cmd))) 477 *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params, 478 CODEC_GET_AMP_DIRECTION(cmd), 479 CODEC_GET_AMP_SIDE(cmd), 480 u8Index); 481 else if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 482 *pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params, 483 CODEC_GET_AMP_DIRECTION(cmd), 484 CODEC_GET_AMP_SIDE(cmd), 485 u8Index); 486 else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 487 *pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params, 488 CODEC_GET_AMP_DIRECTION(cmd), 489 CODEC_GET_AMP_SIDE(cmd), 490 u8Index); 491 else if (codecIsPcbeepNode(pState, CODEC_NID(cmd))) 492 *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params, 493 CODEC_GET_AMP_DIRECTION(cmd), 494 CODEC_GET_AMP_SIDE(cmd), 495 u8Index); 496 else{ 497 AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS); 498 } 499 return VINF_SUCCESS; 500 } 501 /* 3-- */ 502 static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 503 { 504 AMPLIFIER *pAmplifier = NULL; 505 bool fIsLeft = false; 506 bool fIsRight = false; 507 bool fIsOut = false; 508 bool fIsIn = false; 509 uint8_t u8Index = 0; 510 Assert((CODEC_CAD(cmd) == pState->id)); 511 if (CODEC_NID(cmd) >= pState->cTotalNodes) 512 { 513 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 514 return VINF_SUCCESS; 515 } 516 *pResp = 0; 517 PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)]; 518 if (codecIsDacNode(pState, CODEC_NID(cmd))) 519 pAmplifier = &pNode->dac.B_params; 520 else if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 521 pAmplifier = &pNode->adcvol.B_params; 522 else if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 523 pAmplifier = &pNode->adcmux.B_params; 524 else if (codecIsPcbeepNode(pState, CODEC_NID(cmd))) 525 pAmplifier = &pNode->pcbeep.B_params; 526 Assert(pAmplifier); 527 if (pAmplifier) 528 { 529 fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd); 530 fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd); 531 fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd); 532 fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd); 533 u8Index = CODEC_SET_AMP_INDEX(cmd); 534 if ( (!fIsLeft && !fIsRight) 535 || (!fIsOut && !fIsIn)) 536 return VINF_SUCCESS; 537 if (fIsIn) 538 { 539 if (fIsLeft) 540 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0); 541 if (fIsRight) 542 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0); 543 } 544 if (fIsOut) 545 { 546 if (fIsLeft) 547 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0); 548 if (fIsRight) 549 codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0); 550 } 551 if (CODEC_NID(cmd) == 2) 552 codecToAudVolume(pAmplifier, AUD_MIXER_VOLUME); 553 if (CODEC_NID(cmd) == 0x17) /* Microphone */ 554 codecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN); 555 } 556 return VINF_SUCCESS; 557 } 558 559 static int codecGetParameter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 560 { 561 Assert((CODEC_CAD(cmd) == pState->id)); 562 if (CODEC_NID(cmd) >= pState->cTotalNodes) 563 { 564 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 565 return VINF_SUCCESS; 566 } 567 Assert(((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F0_PARAM_LENGTH)); 568 if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F0_PARAM_LENGTH) 569 { 570 Log(("HDAcodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA))); 571 return VINF_SUCCESS; 572 } 573 *pResp = 0; 574 *pResp = pState->pNodes[CODEC_NID(cmd)].node.au32F00_param[cmd & CODEC_VERB_8BIT_DATA]; 575 return VINF_SUCCESS; 576 } 577 578 /* F01 */ 579 static int codecGetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 580 { 581 Assert((CODEC_CAD(cmd) == pState->id)); 582 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 583 if (CODEC_NID(cmd) >= pState->cTotalNodes) 584 { 585 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 586 return VINF_SUCCESS; 587 } 588 *pResp = 0; 589 if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 590 *pResp = pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param; 591 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 592 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param; 593 return VINF_SUCCESS; 594 } 595 596 /* 701 */ 597 static int codecSetConSelectCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 598 { 599 uint32_t *pu32Reg = NULL; 600 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 601 if (CODEC_NID(cmd) >= pState->cTotalNodes) 602 { 603 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 604 return VINF_SUCCESS; 605 } 606 *pResp = 0; 607 if (codecIsAdcMuxNode(pState, CODEC_NID(cmd))) 608 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcmux.u32F01_param; 609 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 610 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F01_param; 611 Assert((pu32Reg)); 612 if (pu32Reg) 613 codecSetRegisterU8(pu32Reg, cmd, 0); 614 return VINF_SUCCESS; 615 } 616 617 /* F07 */ 618 static int codecGetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 619 { 620 Assert((CODEC_CAD(cmd) == pState->id)); 621 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 622 if (CODEC_NID(cmd) >= pState->cTotalNodes) 623 { 624 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 625 return VINF_SUCCESS; 626 } 627 *pResp = 0; 628 if (codecIsPortNode(pState, CODEC_NID(cmd))) 629 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F07_param; 630 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 631 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param; 632 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 633 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param; 634 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 635 *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param; 636 else if ( codecIsReservedNode(pState, CODEC_NID(cmd)) 637 && CODEC_NID(cmd) == 0x1b) 638 *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param; 639 else 640 AssertMsgFailed(("Unsupported")); 641 return VINF_SUCCESS; 642 } 643 644 /* 707 */ 645 static int codecSetPinCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 646 { 647 Assert((CODEC_CAD(cmd) == pState->id)); 648 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 649 if (CODEC_NID(cmd) >= pState->cTotalNodes) 650 { 651 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 652 return VINF_SUCCESS; 653 } 654 *pResp = 0; 655 uint32_t *pu32Reg = NULL; 656 if (codecIsPortNode(pState, CODEC_NID(cmd))) 657 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F07_param; 658 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 659 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F07_param; 660 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 661 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F07_param; 662 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 663 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F07_param; 664 else if ( codecIsReservedNode(pState, CODEC_NID(cmd)) 665 && CODEC_NID(cmd) == 0x1b) 666 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F07_param; 667 Assert((pu32Reg)); 668 if (pu32Reg) 669 codecSetRegisterU8(pu32Reg, cmd, 0); 670 return VINF_SUCCESS; 671 } 672 673 /* F08 */ 674 static int codecGetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 675 { 676 Assert((CODEC_CAD(cmd) == pState->id)); 677 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 678 if (CODEC_NID(cmd) >= pState->cTotalNodes) 679 { 680 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 681 return VINF_SUCCESS; 682 } 683 *pResp = 0; 684 if (codecIsPortNode(pState, CODEC_NID(cmd))) 685 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F08_param; 686 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 687 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param; 688 else if ((cmd) == 1 /* AFG */) 689 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param; 690 else if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 691 *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param; 692 else 693 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd))); 694 return VINF_SUCCESS; 695 } 696 697 /* 708 */ 698 static int codecSetUnsolicitedEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 699 { 700 Assert((CODEC_CAD(cmd) == pState->id)); 701 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 702 if (CODEC_NID(cmd) >= pState->cTotalNodes) 703 { 704 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 705 return VINF_SUCCESS; 706 } 707 *pResp = 0; 708 uint32_t *pu32Reg = NULL; 709 if (codecIsPortNode(pState, CODEC_NID(cmd))) 710 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param; 711 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 712 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param; 713 else if (CODEC_NID(cmd) == 1 /* AFG */) 714 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F08_param; 715 else if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 716 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F08_param; 717 else 718 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd))); 719 Assert(pu32Reg); 720 if(pu32Reg) 721 codecSetRegisterU8(pu32Reg, cmd, 0); 722 return VINF_SUCCESS; 723 } 724 725 /* F09 */ 726 static int codecGetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 727 { 728 Assert((CODEC_CAD(cmd) == pState->id)); 729 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 730 if (CODEC_NID(cmd) >= pState->cTotalNodes) 731 { 732 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 733 return VINF_SUCCESS; 734 } 735 *pResp = 0; 736 if (codecIsPortNode(pState, CODEC_NID(cmd))) 737 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F09_param; 738 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 739 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F09_param; 740 else 741 AssertMsgFailed(("unsupported operation %x on node: %x\n", CODEC_VERB_CMD8(cmd), CODEC_NID(cmd))); 742 return VINF_SUCCESS; 743 } 744 745 /* 709 */ 746 static int codecSetPinSense(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 747 { 748 Assert((CODEC_CAD(cmd) == pState->id)); 749 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 750 if (CODEC_NID(cmd) >= pState->cTotalNodes) 751 { 752 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 753 return VINF_SUCCESS; 754 } 755 *pResp = 0; 756 uint32_t *pu32Reg = NULL; 757 //** @todo r=michaln: Copy/paste bug? This can't be F08_parm! 758 if (codecIsPortNode(pState, CODEC_NID(cmd))) 759 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F08_param; 760 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 761 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F08_param; 762 Assert(pu32Reg); 763 if(pu32Reg) 764 codecSetRegisterU8(pu32Reg, cmd, 0); 765 return VINF_SUCCESS; 766 } 767 768 static int codecGetConnectionListEntry(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 769 { 770 Assert((CODEC_CAD(cmd) == pState->id)); 771 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 772 if (CODEC_NID(cmd) >= pState->cTotalNodes) 773 { 774 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 775 return VINF_SUCCESS; 776 } 777 Assert((cmd & CODEC_VERB_8BIT_DATA) < 16); 778 if ((cmd & CODEC_VERB_8BIT_DATA) >= 16) 779 { 780 Log(("HDAcodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA))); 781 } 782 *pResp = *(uint32_t *)&pState->pNodes[CODEC_NID(cmd)].node.au8F02_param[cmd & CODEC_VERB_8BIT_DATA]; 783 return VINF_SUCCESS; 784 } 785 /* F03 */ 786 static int codecGetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 787 { 788 Assert((CODEC_CAD(cmd) == pState->id)); 789 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 790 if (CODEC_NID(cmd) >= pState->cTotalNodes) 791 { 792 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 793 return VINF_SUCCESS; 794 } 795 *pResp = 0; 796 if (codecIsAdcNode(pState, CODEC_NID(cmd))) 797 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param; 798 return VINF_SUCCESS; 799 } 800 801 /* 703 */ 802 static int codecSetProcessingState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 803 { 804 Assert((CODEC_CAD(cmd) == pState->id)); 805 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 806 if (CODEC_NID(cmd) >= pState->cTotalNodes) 807 { 808 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 809 return VINF_SUCCESS; 810 } 811 *pResp = 0; 812 if (codecIsAdcNode(pState, CODEC_NID(cmd))) 813 { 814 codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].adc.u32F03_param, cmd, 0); 815 } 816 return VINF_SUCCESS; 817 } 818 819 /* F0D */ 820 static int codecGetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 821 { 822 Assert((CODEC_CAD(cmd) == pState->id)); 823 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 824 if (CODEC_NID(cmd) >= pState->cTotalNodes) 825 { 826 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 827 return VINF_SUCCESS; 828 } 829 *pResp = 0; 830 if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 831 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param; 832 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 833 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param; 834 return VINF_SUCCESS; 835 } 836 837 static int codecSetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset, uint64_t *pResp) 838 { 839 Assert((CODEC_CAD(cmd) == pState->id)); 840 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 841 if (CODEC_NID(cmd) >= pState->cTotalNodes) 842 { 843 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 844 return VINF_SUCCESS; 845 } 846 *pResp = 0; 847 if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 848 codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32F0d_param, cmd, u8Offset); 849 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 850 codecSetRegisterU8(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32F0d_param, cmd, u8Offset); 851 return VINF_SUCCESS; 852 } 853 854 /* 70D */ 855 static int codecSetDigitalConverter1(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 856 { 857 return codecSetDigitalConverter(pState, cmd, 0, pResp); 858 } 859 860 /* 70E */ 861 static int codecSetDigitalConverter2(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 862 { 863 return codecSetDigitalConverter(pState, cmd, 8, pResp); 864 } 865 866 static int codecGetSubId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 867 { 868 Assert((CODEC_CAD(cmd) == pState->id)); 869 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 870 if (CODEC_NID(cmd) >= pState->cTotalNodes) 871 { 872 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 873 return VINF_SUCCESS; 874 } 875 *pResp = 0; 876 if (CODEC_NID(cmd) == 1 /* AFG */) 877 { 878 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F20_param; 879 } 880 return VINF_SUCCESS; 881 } 882 883 static int codecReset(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 884 { 885 Assert((CODEC_CAD(cmd) == pState->id)); 886 Assert(CODEC_NID(cmd) == 1 /* AFG */); 887 if(CODEC_NID(cmd) == 1 /* AFG */) 888 { 889 uint8_t i; 890 Log(("HDAcodec: enters reset\n")); 891 Assert(pState->pfnCodecNodeReset); 892 for (i = 0; i < pState->cTotalNodes; ++i) 893 { 894 pState->pfnCodecNodeReset(pState, i, &pState->pNodes[i]); 895 } 896 pState->fInReset = false; 897 Log(("HDAcodec: exits reset\n")); 898 } 899 *pResp = 0; 900 return VINF_SUCCESS; 901 } 902 903 /* F05 */ 904 static int codecGetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 905 { 906 Assert((CODEC_CAD(cmd) == pState->id)); 907 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 908 if (CODEC_NID(cmd) >= pState->cTotalNodes) 909 { 910 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 911 return VINF_SUCCESS; 912 } 913 *pResp = 0; 914 if (CODEC_NID(cmd) == 1 /* AFG */) 915 *pResp = pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param; 916 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 917 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param; 918 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 919 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param; 920 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 921 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param; 922 return VINF_SUCCESS; 923 } 924 925 /* 705 */ 926 static int codecSetPowerState(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 927 { 928 Assert((CODEC_CAD(cmd) == pState->id)); 929 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 930 if (CODEC_NID(cmd) >= pState->cTotalNodes) 931 { 932 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 933 return VINF_SUCCESS; 934 } 935 uint32_t *pu32Reg = NULL; 936 *pResp = 0; 937 if (CODEC_NID(cmd) == 1 /* AFG */) 938 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].afg.u32F05_param; 939 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 940 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F05_param; 941 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 942 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F05_param; 943 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 944 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adc.u32F05_param; 945 Assert((pu32Reg)); 946 if (!pu32Reg) 947 return VINF_SUCCESS; 948 949 if (!CODEC_NID(cmd) == 1 /* AFG */) 950 { 951 *pu32Reg &= ~CODEC_VERB_8BIT_DATA; 952 *pu32Reg |= (pState->pNodes[1].afg.u32F05_param & (CODEC_VERB_4BIT_DATA << 4)); 953 } 954 else 955 *pu32Reg &= ~CODEC_VERB_4BIT_DATA; 956 957 *pu32Reg |= cmd & CODEC_VERB_4BIT_DATA; 958 /* Propogate next power state only if AFG is on or verb modifies AFG power state */ 959 if ( CODEC_NID(cmd) == 1 /* AFG */ 960 || !pState->pNodes[1].afg.u32F05_param) 961 { 962 *pu32Reg &= ~(CODEC_POWER_MASK << CODEC_POWER_ACT_SHIFT); 963 *pu32Reg |= (cmd & CODEC_VERB_4BIT_DATA) << 4; 964 if ( CODEC_NID(cmd) == 1 /* AFG */ 965 && (cmd & CODEC_POWER_MASK) == CODEC_POWER_D0) 966 { 967 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[2].dac); 968 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[3].dac); 969 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[4].dac); 970 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[5].dac); 971 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[6].dac); 972 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[7].dac); 973 CODEC_POWER_PROPOGATE_STATE(pState->pNodes[0x11].dac); 974 } 975 } 976 return VINF_SUCCESS; 977 } 978 979 static int codecGetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 980 { 981 Assert((CODEC_CAD(cmd) == pState->id)); 982 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 983 if (CODEC_NID(cmd) >= pState->cTotalNodes) 984 { 985 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 986 return VINF_SUCCESS; 987 } 988 *pResp = 0; 989 if (codecIsDacNode(pState, CODEC_NID(cmd))) 990 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param; 991 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 992 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param; 993 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 994 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param; 995 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 996 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param; 997 else if (CODEC_NID(cmd) == 0x1A) 998 *pResp = pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param; 999 return VINF_SUCCESS; 1000 } 1001 static int codecSetStreamId(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1002 { 1003 Assert((CODEC_CAD(cmd) == pState->id)); 1004 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1005 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1006 { 1007 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1008 return VINF_SUCCESS; 1009 } 1010 *pResp = 0; 1011 uint32_t *pu32addr = NULL; 1012 *pResp = 0; 1013 if (codecIsDacNode(pState, CODEC_NID(cmd))) 1014 pu32addr = &pState->pNodes[CODEC_NID(cmd)].dac.u32F06_param; 1015 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 1016 pu32addr = &pState->pNodes[CODEC_NID(cmd)].adc.u32F06_param; 1017 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 1018 pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifout.u32F06_param; 1019 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 1020 pu32addr = &pState->pNodes[CODEC_NID(cmd)].spdifin.u32F06_param; 1021 else if (codecIsReservedNode(pState, CODEC_NID(cmd))) 1022 pu32addr = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F06_param; 1023 Assert((pu32addr)); 1024 if (pu32addr) 1025 codecSetRegisterU8(pu32addr, cmd, 0); 1026 return VINF_SUCCESS; 1027 } 1028 static int codecGetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1029 { 1030 Assert((CODEC_CAD(cmd) == pState->id)); 1031 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1032 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1033 { 1034 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1035 return VINF_SUCCESS; 1036 } 1037 *pResp = 0; 1038 if (codecIsDacNode(pState, CODEC_NID(cmd))) 1039 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32A_param; 1040 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 1041 *pResp = pState->pNodes[CODEC_NID(cmd)].adc.u32A_param; 1042 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 1043 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param; 1044 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 1045 *pResp = pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param; 1046 return VINF_SUCCESS; 1047 } 1048 1049 static int codecSetConverterFormat(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1050 { 1051 Assert((CODEC_CAD(cmd) == pState->id)); 1052 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1053 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1054 { 1055 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1056 return VINF_SUCCESS; 1057 } 1058 *pResp = 0; 1059 if (codecIsDacNode(pState, CODEC_NID(cmd))) 1060 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].dac.u32A_param, cmd, 0); 1061 else if (codecIsAdcNode(pState, CODEC_NID(cmd))) 1062 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].adc.u32A_param, cmd, 0); 1063 else if (codecIsSpdifOutNode(pState, CODEC_NID(cmd))) 1064 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifout.u32A_param, cmd, 0); 1065 else if (codecIsSpdifInNode(pState, CODEC_NID(cmd))) 1066 codecSetRegisterU16(&pState->pNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0); 1067 return VINF_SUCCESS; 1068 } 1069 1070 /* F0C */ 1071 static int codecGetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1072 { 1073 Assert((CODEC_CAD(cmd) == pState->id)); 1074 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1075 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1076 { 1077 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1078 return VINF_SUCCESS; 1079 } 1080 *pResp = 0; 1081 if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 1082 *pResp = pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param; 1083 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 1084 *pResp = pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param; 1085 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 1086 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param; 1087 return VINF_SUCCESS; 1088 } 1089 1090 /* 70C */ 1091 static int codecSetEAPD_BTLEnabled(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1092 { 1093 Assert((CODEC_CAD(cmd) == pState->id)); 1094 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1095 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1096 { 1097 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1098 return VINF_SUCCESS; 1099 } 1100 *pResp = 0; 1101 uint32_t *pu32Reg = NULL; 1102 if (codecIsAdcVolNode(pState, CODEC_NID(cmd))) 1103 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].adcvol.u32F0c_param; 1104 else if (codecIsDacNode(pState, CODEC_NID(cmd))) 1105 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].dac.u32F0c_param; 1106 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 1107 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F0c_param; 1108 *pResp = 0; 1109 Assert((pu32Reg)); 1110 if (pu32Reg) 1111 codecSetRegisterU8(pu32Reg, cmd, 0); 1112 return VINF_SUCCESS; 1113 } 1114 1115 /* F0F */ 1116 static int codecGetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1117 { 1118 Assert((CODEC_CAD(cmd) == pState->id)); 1119 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1120 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1121 { 1122 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1123 return VINF_SUCCESS; 1124 } 1125 *pResp = 0; 1126 if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 1127 *pResp = pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param; 1128 return VINF_SUCCESS; 1129 } 1130 1131 /* 70F */ 1132 static int codecSetVolumeKnobCtrl(struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1133 { 1134 Assert((CODEC_CAD(cmd) == pState->id)); 1135 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1136 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1137 { 1138 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1139 return VINF_SUCCESS; 1140 } 1141 uint32_t *pu32Reg = NULL; 1142 *pResp = 0; 1143 if (codecIsVolKnobNode(pState, CODEC_NID(cmd))) 1144 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param; 1145 Assert((pu32Reg)); 1146 if (pu32Reg) 1147 codecSetRegisterU8(pu32Reg, cmd, 0); 1148 return VINF_SUCCESS; 1149 } 1150 1151 /* F1C */ 1152 static int codecGetConfig (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1153 { 1154 Assert((CODEC_CAD(cmd) == pState->id)); 1155 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1156 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1157 { 1158 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1159 return VINF_SUCCESS; 1160 } 1161 *pResp = 0; 1162 if (codecIsPortNode(pState, CODEC_NID(cmd))) 1163 *pResp = pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param; 1164 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 1165 *pResp = pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param; 1166 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 1167 *pResp = pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param; 1168 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 1169 *pResp = pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param; 1170 return VINF_SUCCESS; 1171 } 1172 static int codecSetConfigX(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset) 1173 { 1174 Assert((CODEC_CAD(cmd) == pState->id)); 1175 Assert((CODEC_NID(cmd) < pState->cTotalNodes)); 1176 if (CODEC_NID(cmd) >= pState->cTotalNodes) 1177 { 1178 Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd))); 1179 return VINF_SUCCESS; 1180 } 1181 uint32_t *pu32Reg = NULL; 1182 if (codecIsPortNode(pState, CODEC_NID(cmd))) 1183 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].port.u32F1c_param; 1184 else if (codecIsDigInPinNode(pState, CODEC_NID(cmd))) 1185 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digin.u32F1c_param; 1186 else if (codecIsDigOutPinNode(pState, CODEC_NID(cmd))) 1187 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].digout.u32F1c_param; 1188 else if (codecIsCdNode(pState, CODEC_NID(cmd))) 1189 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].cdnode.u32F1c_param; 1190 else if (CODEC_NID(cmd) == 0x1B) 1191 pu32Reg = &pState->pNodes[CODEC_NID(cmd)].reserved.u32F1c_param; 1192 Assert((pu32Reg)); 1193 if (pu32Reg) 1194 codecSetRegisterU8(pu32Reg, cmd, u8Offset); 1195 return VINF_SUCCESS; 1196 } 1197 /* 71C */ 1198 static int codecSetConfig0 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1199 { 1200 *pResp = 0; 1201 return codecSetConfigX(pState, cmd, 0); 1202 } 1203 /* 71D */ 1204 static int codecSetConfig1 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1205 { 1206 *pResp = 0; 1207 return codecSetConfigX(pState, cmd, 8); 1208 } 1209 /* 71E */ 1210 static int codecSetConfig2 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1211 { 1212 *pResp = 0; 1213 return codecSetConfigX(pState, cmd, 16); 1214 } 1215 /* 71E */ 1216 static int codecSetConfig3 (struct CODECState *pState, uint32_t cmd, uint64_t *pResp) 1217 { 1218 *pResp = 0; 1219 return codecSetConfigX(pState, cmd, 24); 1220 } 1221 1222 1190 1223 static int codecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt) 1191 1224 { … … 1211 1244 } 1212 1245 1213 static CODECVERB STAC9220VERB[] =1246 static CODECVERB CODECVERBS[] = 1214 1247 { 1215 1248 /* verb | verb mask | callback */ … … 1280 1313 } 1281 1314 1282 static int codec_dac_to_aud(CODECState *pState, int dacnum,audsettings_t *paud)1315 static int codec_dac_to_aud(CODECState *pState, audsettings_t *paud) 1283 1316 { 1284 1317 paud->freq = 44100; … … 1307 1340 pState->pfnTransfer(pState, MC_INDEX, avail); 1308 1341 } 1309 #define STAC9220_DAC_PI (0x2) 1310 #define STAC9220_DAC_MC (0x3) 1311 #define STAC9220_DAC_PO (0x4) 1312 int stac9220Construct(CODECState *pState) 1342 1343 int codecConstruct(CODECState *pState, ENMCODEC enmCodec) 1313 1344 { 1314 1345 audsettings_t as; 1315 pState->pVerbs = (CODECVERB *)&STAC9220VERB; 1316 pState->cVerbs = sizeof(STAC9220VERB)/sizeof(CODECVERB); 1346 int rc; 1347 pState->pVerbs = (CODECVERB *)&CODECVERBS; 1348 pState->cVerbs = sizeof(CODECVERBS)/sizeof(CODECVERB); 1317 1349 pState->pfnLookup = codecLookup; 1318 unconst(pState->cTotalNodes) = 0x1C; 1319 pState->pNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pState->cTotalNodes); 1320 pState->fInReset = false; 1321 #define STAC9220WIDGET(type) pState->au8##type##s = au8Stac9220##type##s 1322 STAC9220WIDGET(Port); 1323 STAC9220WIDGET(Dac); 1324 STAC9220WIDGET(Adc); 1325 STAC9220WIDGET(AdcVol); 1326 STAC9220WIDGET(AdcMux); 1327 STAC9220WIDGET(Pcbeep); 1328 STAC9220WIDGET(SpdifIn); 1329 STAC9220WIDGET(SpdifOut); 1330 STAC9220WIDGET(DigInPin); 1331 STAC9220WIDGET(DigOutPin); 1332 STAC9220WIDGET(Cd); 1333 STAC9220WIDGET(VolKnob); 1334 STAC9220WIDGET(Reserved); 1335 #undef STAC9220WIDGET 1336 1350 pState->enmCodec = enmCodec; 1351 if (enmCodec == STAC9220_CODEC) 1352 { 1353 rc = stac9220Construct(pState); 1354 AssertRC(rc); 1355 } 1337 1356 uint8_t i; 1357 Assert(pState->pNodes); 1358 Assert(pState->pfnCodecNodeReset); 1338 1359 for (i = 0; i < pState->cTotalNodes; ++i) 1339 1360 { 1340 stac9220ResetNode(pState, i, &pState->pNodes[i]);1361 pState->pfnCodecNodeReset(pState, i, &pState->pNodes[i]); 1341 1362 } 1342 1363 //** @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0) 1343 1364 AUD_register_card ("ICH0", &pState->card); 1344 1365 1345 1346 codec_dac_to_aud(pState, STAC9220_DAC_PI, &as); 1366 codec_dac_to_aud(pState, &as); 1347 1367 pState->voice_pi = AUD_open_in(&pState->card, pState->voice_pi, "hda.in", pState, pi_callback, &as); 1348 codec_dac_to_aud(pState, STAC9220_DAC_PO,&as);1368 codec_dac_to_aud(pState, &as); 1349 1369 pState->voice_po = AUD_open_out(&pState->card, pState->voice_po, "hda.out", pState, po_callback, &as); 1350 codec_dac_to_aud(pState, STAC9220_DAC_MC, &as);1351 pState->voice_mc = AUD_open_in(&pState->card, pState->voice_mc, "hda.mc", pState, mc_callback, &as);1352 1370 if (!pState->voice_pi) 1353 1371 LogRel (("HDAcodec: WARNING: Unable to open PCM IN!\n")); 1354 if (!pState->voice_mc)1355 LogRel (("HDAcodec: WARNING: Unable to open PCM MC!\n"));1356 1372 if (!pState->voice_po) 1357 1373 LogRel (("HDAcodec: WARNING: Unable to open PCM OUT!\n")); 1358 codecToAudVolume(&pState->pNodes[ 2].dac.B_params, AUD_MIXER_VOLUME);1359 codecToAudVolume(&pState->pNodes[ 0x17].adcvol.B_params, AUD_MIXER_LINE_IN);1360 1361 return VINF_SUCCESS; 1362 } 1363 int stac9220Destruct(CODECState *pCodecState)1374 codecToAudVolume(&pState->pNodes[pState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME); 1375 codecToAudVolume(&pState->pNodes[pState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN); 1376 1377 return VINF_SUCCESS; 1378 } 1379 int codecDestruct(CODECState *pCodecState) 1364 1380 { 1365 1381 RTMemFree(pCodecState->pNodes); … … 1367 1383 } 1368 1384 1369 int stac9220SaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle)1385 int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle) 1370 1386 { 1371 1387 SSMR3PutMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes); 1372 1388 return VINF_SUCCESS; 1373 1389 } 1374 int stac9220LoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle) 1390 1391 int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle) 1375 1392 { 1376 1393 SSMR3GetMem (pSSMHandle, pCodecState->pNodes, sizeof(CODECNODE) * pCodecState->cTotalNodes); 1377 codecToAudVolume(&pCodecState->pNodes[ 2].dac.B_params, AUD_MIXER_VOLUME);1378 codecToAudVolume(&pCodecState->pNodes[ 0x17].adcvol.B_params, AUD_MIXER_LINE_IN);1379 return VINF_SUCCESS; 1380 } 1394 codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME); 1395 codecToAudVolume(&pCodecState->pNodes[pCodecState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN); 1396 return VINF_SUCCESS; 1397 } -
trunk/src/VBox/Devices/Audio/DevCodec.h
r32803 r32804 219 219 } ENMSOUNDSOURCE; 220 220 221 typedef enum 222 { 223 STAC9220_CODEC 224 } ENMCODEC; 221 225 typedef struct CODECState 222 226 { … … 232 236 /** Mic in */ 233 237 SWVoiceIn *voice_mc; 238 ENMCODEC enmCodec; 234 239 void *pHDAState; 235 240 bool fInReset; … … 248 253 const uint8_t *au8VolKnobs; 249 254 const uint8_t *au8Reserveds; 255 const uint8_t u8AdcVolsLineIn; 256 const uint8_t u8DacLineOut; 250 257 DECLR3CALLBACKMEMBER(int, pfnProcess, (struct CODECState *)); 251 258 DECLR3CALLBACKMEMBER(int, pfnLookup, (struct CODECState *pState, uint32_t verb, PPFNCODECVERBPROCESSOR)); 252 259 DECLR3CALLBACKMEMBER(int, pfnReset, (struct CODECState *pState)); 253 260 DECLR3CALLBACKMEMBER(void, pfnTransfer, (struct CODECState *pState, ENMSOUNDSOURCE, int avail)); 261 DECLR3CALLBACKMEMBER(int, pfnCodecNodeReset, (struct CODECState *pState, uint8_t, PCODECNODE)); 254 262 255 263 } CODECState; 256 264 257 265 258 int stac9220Construct(CODECState *pCodecState);259 int stac9220Destruct(CODECState *pCodecState);260 int stac9220SaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);261 int stac9220LoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle);266 int codecConstruct(CODECState *pCodecState, ENMCODEC enmCodec); 267 int codecDestruct(CODECState *pCodecState); 268 int codecSaveState(CODECState *pCodecState, PSSMHANDLE pSSMHandle); 269 int codecLoadState(CODECState *pCodecState, PSSMHANDLE pSSMHandle); 262 270 263 271 #endif -
trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp
r32765 r32804 1499 1499 PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *); 1500 1500 /* Save Codec nodes states */ 1501 stac9220SaveState(&pThis->hda.Codec, pSSMHandle);1501 codecSaveState(&pThis->hda.Codec, pSSMHandle); 1502 1502 /* Save MMIO registers */ 1503 1503 SSMR3PutMem (pSSMHandle, pThis->hda.au32Regs, sizeof (pThis->hda.au32Regs)); … … 1527 1527 PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *); 1528 1528 /* Load Codec nodes states */ 1529 stac9220LoadState(&pThis->hda.Codec, pSSMHandle); 1529 AssertMsgReturn (uVersion == HDA_SSM_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION); 1530 Assert (uPass == SSM_PASS_FINAL); NOREF(uPass); 1531 1532 codecLoadState(&pThis->hda.Codec, pSSMHandle); 1530 1533 /* Load MMIO registers */ 1531 1534 SSMR3GetMem (pSSMHandle, pThis->hda.au32Regs, sizeof (pThis->hda.au32Regs)); … … 1779 1782 1780 1783 pThis->hda.Codec.pHDAState = (void *)&pThis->hda; 1781 rc = stac9220Construct(&pThis->hda.Codec);1784 rc = codecConstruct(&pThis->hda.Codec, STAC9220_CODEC); 1782 1785 if (RT_FAILURE(rc)) 1783 1786 AssertRCReturn(rc, rc); … … 1803 1806 PCIINTELHDLinkState *pThis = PDMINS_2_DATA(pDevIns, PCIINTELHDLinkState *); 1804 1807 1805 int rc = stac9220Destruct(&pThis->hda.Codec);1808 int rc = codecDestruct(&pThis->hda.Codec); 1806 1809 AssertRC(rc); 1807 1810 if (pThis->hda.pu32CorbBuf)
Note:
See TracChangeset
for help on using the changeset viewer.