- Timestamp:
- Apr 6, 2016 11:54:39 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106428
- Location:
- trunk
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmaudioifs.h
r59987 r60353 109 109 } PDMAUDIOENDIANNESS; 110 110 111 /** 112 * Audio direction. 113 */ 114 typedef enum PDMAUDIODIR 115 { 116 PDMAUDIODIR_UNKNOWN = 0, 117 PDMAUDIODIR_IN = 1, 118 PDMAUDIODIR_OUT = 2, 119 PDMAUDIODIR_DUPLEX = 3, 120 /** Hack to blow the type up to 32-bit. */ 121 PDMAUDIODIR_32BIT_HACK = 0x7fffffff 122 } PDMAUDIODIR; 123 124 /** 125 * Audio playback destinations. 126 */ 127 typedef enum PDMAUDIOPLAYBACKDEST 128 { 129 PDMAUDIOPLAYBACKDEST_UNKNOWN = 0, 130 PDMAUDIOPLAYBACKDEST_FRONT, 131 PDMAUDIOPLAYBACKDEST_CENTER_LFE, 132 PDMAUDIOPLAYBACKDEST_REAR, 133 /** Hack to blow the type up to 32-bit. */ 134 PDMAUDIOPLAYBACKDEST_32BIT_HACK = 0x7fffffff 135 } PDMAUDIOPLAYBACKDEST; 136 137 /** 138 * Audio recording sources. 139 */ 140 typedef enum PDMAUDIORECSOURCE 141 { 142 PDMAUDIORECSOURCE_UNKNOWN = 0, 143 PDMAUDIORECSOURCE_MIC, 144 PDMAUDIORECSOURCE_CD, 145 PDMAUDIORECSOURCE_VIDEO, 146 PDMAUDIORECSOURCE_AUX, 147 PDMAUDIORECSOURCE_LINE, 148 PDMAUDIORECSOURCE_PHONE, 149 /** Hack to blow the type up to 32-bit. */ 150 PDMAUDIORECSOURCE_32BIT_HACK = 0x7fffffff 151 } PDMAUDIORECSOURCE; 152 153 /** 154 * Structure for keeping an audio stream configuration. 155 */ 111 156 typedef struct PDMAUDIOSTREAMCFG 112 157 { 158 /** Friendly name of the stream. */ 159 char *pszName; 160 /** Direction of the stream. */ 161 PDMAUDIODIR enmDir; 162 union 163 { 164 /** Desired playback destination (for an output stream). */ 165 PDMAUDIOPLAYBACKDEST Dest; 166 /** Desired recording source (for an input stream). */ 167 PDMAUDIORECSOURCE Source; 168 } DestSource; 113 169 /** Frequency in Hertz (Hz). */ 114 uint32_t uHz;115 /** Number of channels (2 for stereo ). */116 uint8_t cChannels;170 uint32_t uHz; 171 /** Number of channels (2 for stereo, 1 for mono). */ 172 uint8_t cChannels; 117 173 /** Audio format. */ 118 PDMAUDIOFMT enmFormat;174 PDMAUDIOFMT enmFormat; 119 175 /** @todo Use RT_LE2H_*? */ 120 PDMAUDIOENDIANNESS enmEndianness;176 PDMAUDIOENDIANNESS enmEndianness; 121 177 } PDMAUDIOSTREAMCFG, *PPDMAUDIOSTREAMCFG; 122 178 … … 130 186 131 187 /** 132 * Audio direction.133 */134 typedef enum PDMAUDIODIR135 {136 PDMAUDIODIR_UNKNOWN = 0,137 PDMAUDIODIR_IN = 1,138 PDMAUDIODIR_OUT = 2,139 PDMAUDIODIR_DUPLEX = 3,140 /** Hack to blow the type up to 32-bit. */141 PDMAUDIODIR_32BIT_HACK = 0x7fffffff142 } PDMAUDIODIR;143 144 /**145 188 * Audio mixer controls. 146 189 */ … … 149 192 PDMAUDIOMIXERCTL_UNKNOWN = 0, 150 193 PDMAUDIOMIXERCTL_VOLUME, 151 PDMAUDIOMIXERCTL_PCM, 194 PDMAUDIOMIXERCTL_FRONT, 195 PDMAUDIOMIXERCTL_CENTER_LFE, 196 PDMAUDIOMIXERCTL_REAR, 152 197 PDMAUDIOMIXERCTL_LINE_IN, 153 198 PDMAUDIOMIXERCTL_MIC_IN, … … 155 200 PDMAUDIOMIXERCTL_32BIT_HACK = 0x7fffffff 156 201 } PDMAUDIOMIXERCTL; 157 158 /**159 * Audio recording sources.160 */161 typedef enum PDMAUDIORECSOURCE162 {163 PDMAUDIORECSOURCE_UNKNOWN = 0,164 PDMAUDIORECSOURCE_MIC,165 PDMAUDIORECSOURCE_CD,166 PDMAUDIORECSOURCE_VIDEO,167 PDMAUDIORECSOURCE_AUX,168 PDMAUDIORECSOURCE_LINE_IN,169 PDMAUDIORECSOURCE_PHONE,170 /** Hack to blow the type up to 32-bit. */171 PDMAUDIORECSOURCE_32BIT_HACK = 0x7fffffff172 } PDMAUDIORECSOURCE;173 202 174 203 /** … … 586 615 * @returns VBox status code. 587 616 * @param pInterface Pointer to the interface structure containing the called function pointer. 588 * @param pszName Name of the audio channel. 589 * @param enmRecSource Specifies the type of recording source to be opened. 617 * @param pszName Friendly name of this input stream. 590 618 * @param pCfg Pointer to PDMAUDIOSTREAMCFG to use. 591 619 * @param ppGstStrmIn Pointer where to return the guest guest input stream on success. 592 620 */ 593 621 DECLR3CALLBACKMEMBER(int, pfnCreateIn, (PPDMIAUDIOCONNECTOR pInterface, const char *pszName, 594 PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg, 595 PPDMAUDIOGSTSTRMIN *ppGstStrmIn)); 622 PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMIN *ppGstStrmIn)); 596 623 /** 597 624 * Creates a guest output stream. … … 599 626 * @returns VBox status code. 600 627 * @param pInterface Pointer to the interface structure containing the called function pointer. 601 * @param pszName Name of the audio channel.628 * @param pszName Friendly name of this output stream. 602 629 * @param pCfg Pointer to PDMAUDIOSTREAMCFG to use. 603 630 * @param ppGstStrmOut Pointer where to return the guest guest input stream on success. … … 639 666 640 667 /** PDMIAUDIOCONNECTOR interface ID. */ 641 #define PDMIAUDIOCONNECTOR_IID " 8f8ca10e-9039-423c-9a77-0014aaa98626"668 #define PDMIAUDIOCONNECTOR_IID "f0ef4012-ae89-4528-9dad-4ef496894df8" 642 669 643 670 -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r57451 r60353 6 6 7 7 /* 8 * Copyright (C) 2014-201 5Oracle Corporation8 * Copyright (C) 2014-2016 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 #include <VBox/log.h> 20 20 21 #if 0 21 22 /* 22 23 * DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data … … 24 25 * to your needs before using this! 25 26 */ 26 #ifdef DEBUG 27 //# define DEBUG_DUMP_PCM_DATA 28 # define DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\" 27 # define AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA 28 # ifdef RT_OS_WINDOWS 29 # define AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\" 30 # else 31 # define AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "/tmp/" 32 # endif 33 /* Warning: Enabling this will generate *huge* logs! */ 34 //# define AUDIOMIXBUF_DEBUG_MACROS 29 35 #endif 30 36 31 37 #include <iprt/asm-math.h> 32 38 #include <iprt/assert.h> 33 #ifdef DEBUG_DUMP_PCM_DATA39 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA 34 40 # include <iprt/file.h> 35 41 #endif … … 37 43 #include <iprt/string.h> /* For RT_BZERO. */ 38 44 39 #ifdef TESTCASE45 #ifdef VBOX_AUDIO_TESTCASE 40 46 # define LOG_ENABLED 41 47 # include <iprt/stream.h> … … 45 51 #include "AudioMixBuffer.h" 46 52 47 #if 0 48 # define AUDMIXBUF_LOG(x) LogFlowFunc(x) 49 #else 50 # if defined(TESTCASE) 51 # define AUDMIXBUF_LOG(x) LogFunc(x) 53 #ifndef VBOX_AUDIO_TESTCASE 54 # ifdef DEBUG 55 # define AUDMIXBUF_LOG(x) LogFlowFunc(x) 52 56 # else 53 # 57 # define AUDMIXBUF_LOG(x) do {} while (0) 54 58 # endif 59 #else /* VBOX_AUDIO_TESTCASE */ 60 # define AUDMIXBUF_LOG(x) RTPrintf x 55 61 #endif 56 62 … … 144 150 * inlined + static. 145 151 */ 146 #ifdef TESTCASE152 #ifdef VBOX_AUDIO_TESTCASE 147 153 # define AUDMIXBUF_MACRO_FN 148 154 #else … … 404 410 } 405 411 406 /** Note: Enabling this will generate huge logs! */ 407 //#define DEBUG_MACROS 408 409 #ifdef DEBUG_MACROS 412 #ifdef AUDIOMIXBUF_DEBUG_MACROS 410 413 # define AUDMIXBUF_MACRO_LOG(x) AUDMIXBUF_LOG(x) 411 #elif defined( TESTCASE)414 #elif defined(VBOX_AUDIO_TESTCASE_VERBOSE) /* Warning: VBOX_AUDIO_TESTCASE_VERBOSE will generate huge logs! */ 412 415 # define AUDMIXBUF_MACRO_LOG(x) RTPrintf x 413 416 #else … … 449 452 _aType *pSrc = (_aType *)pvSrc; \ 450 453 uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \ 451 AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu), lVol=%RU32, rVol=%RU32\n", \454 AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, BpS=%zu, lVol=%RU32, rVol=%RU32\n", \ 452 455 pOpts->cSamples, sizeof(_aType), pOpts->Volume.uLeft, pOpts->Volume.uRight)); \ 453 456 for (uint32_t i = 0; i < cSamples; i++) \ 454 457 { \ 455 AUDMIXBUF_MACRO_LOG((" %p: l=%RI16, r=%RI16\n", paDst, *pSrc, *(pSrc + 1))); \458 AUDMIXBUF_MACRO_LOG(("l=%#5RI16 (0x%x), r=%#5RI16 (0x%x)", paDst, *pSrc, *pSrc, *(pSrc + 1), *(pSrc + 1))); \ 456 459 paDst->i64LSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->Volume.uLeft ) >> AUDIOMIXBUF_VOL_SHIFT; \ 457 460 paDst->i64RSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->Volume.uRight) >> AUDIOMIXBUF_VOL_SHIFT; \ 458 AUDMIXBUF_MACRO_LOG((" \t-> l=%RI64, r=%RI64\n", paDst->i64LSample, paDst->i64RSample)); \461 AUDMIXBUF_MACRO_LOG((" -> l=%#10RI64, r=%#10RI64\n", paDst->i64LSample, paDst->i64RSample)); \ 459 462 paDst++; \ 460 463 } \ … … 467 470 { \ 468 471 _aType *pSrc = (_aType *)pvSrc; \ 469 uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \470 AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu), lVol=%RU32, rVol=%RU32\n", \471 cSamples, sizeof(_aType), pOpts->Volume.uLeft , pOpts->Volume.uRight)); \472 const uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \ 473 AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, BpS=%zu, lVol=%RU32, rVol=%RU32\n", \ 474 cSamples, sizeof(_aType), pOpts->Volume.uLeft >> 14, pOpts->Volume.uRight)); \ 472 475 for (uint32_t i = 0; i < cSamples; i++) \ 473 476 { \ 474 AUDMIXBUF_MACRO_LOG(("%p: s=%RI16\n", paDst, *pSrc)); \475 477 paDst->i64LSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc), pOpts->Volume.uLeft) >> AUDIOMIXBUF_VOL_SHIFT; \ 476 478 paDst->i64RSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc), pOpts->Volume.uRight) >> AUDIOMIXBUF_VOL_SHIFT; \ 477 ++pSrc; \478 AUDMIXBUF_MACRO_LOG(("\t-> l=%RI64, r=%RI64\n", paDst->i64LSample, paDst->i64RSample)); \479 AUDMIXBUF_MACRO_LOG(("%#5RI16 (0x%x) -> l=%#10RI64, r=%#10RI64\n", *pSrc, *pSrc, paDst->i64LSample, paDst->i64RSample)); \ 480 pSrc++; \ 479 481 paDst++; \ 480 482 } \ … … 537 539 { \ 538 540 AUDMIXBUF_MACRO_LOG(("cSrcSamples=%RU32, cDstSamples=%RU32\n", cSrcSamples, cDstSamples)); \ 539 AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=0x%RX32 (%RU32), dstOffset=0x%RX32 (%RU32), dstInc=0x%RX64 (%RU64)\n", \ 540 pRate, pRate->srcOffset, pRate->srcOffset, \ 541 (uint32_t)(pRate->dstOffset >> 32), (uint32_t)(pRate->dstOffset >> 32), \ 542 pRate->dstInc, pRate->dstInc)); \ 541 AUDMIXBUF_MACRO_LOG(("Rate: srcOffset=%RU32, dstOffset=%RU32, dstInc=%RU32\n", \ 542 pRate->srcOffset, \ 543 (uint32_t)(pRate->dstOffset >> 32), (uint32_t)(pRate->dstInc >> 32))); \ 543 544 \ 544 545 if (pRate->dstInc == (UINT64_C(1) + UINT32_MAX)) /* No conversion needed? */ \ … … 563 564 PPDMAUDIOSAMPLE paDstStart = paDst; \ 564 565 PPDMAUDIOSAMPLE paDstEnd = paDst + cDstSamples; \ 565 PDMAUDIOSAMPLE samCur = { 0 }; \566 PDMAUDIOSAMPLE samCur = { 0 }; \ 566 567 PDMAUDIOSAMPLE samOut; \ 567 568 PDMAUDIOSAMPLE samLast = pRate->srcSampleLast; \ 568 uint64_t lDelta = 0; \569 \570 AUDMIXBUF_MACRO_LOG(("Start: paDstEnd=%p - paDstStart=%p -> %zu\n", paDstEnd, paDst, paDstEnd - paDstStart)); \571 AUDMIXBUF_MACRO_LOG(("Start: paSrcEnd=%p - paSrcStart=%p -> %zu\n", paSrcEnd, paSrc, paSrcEnd - paSrcStart)); \572 569 \ 573 570 while (paDst < paDstEnd) \ … … 575 572 Assert(paSrc <= paSrcEnd); \ 576 573 Assert(paDst <= paDstEnd); \ 577 if (paSrc == paSrcEnd) \574 if (paSrc >= paSrcEnd) \ 578 575 break; \ 579 576 \ 580 lDelta = 0; \581 577 while (pRate->srcOffset <= (pRate->dstOffset >> 32)) \ 582 578 { \ … … 584 580 samLast = *paSrc++; \ 585 581 pRate->srcOffset++; \ 586 lDelta++; \587 582 if (paSrc == paSrcEnd) \ 588 583 break; \ … … 604 599 paDst->i64RSample _aOp samOut.i64RSample; \ 605 600 \ 606 AUDMIXBUF_MACRO_LOG(("\t lDelta=0x%RX64 (%RU64), iDstOffInt=0x%RX64 (%RI64), l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \607 lDelta, lDelta, iDstOffInt,iDstOffInt, \608 paDst->i64LSample , paDst->i64RSample, \609 samCur.i64LSample , samCur.i64RSample)); \601 AUDMIXBUF_MACRO_LOG(("\tiDstOffInt=%RI64, l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \ 602 iDstOffInt, \ 603 paDst->i64LSample >> 32, paDst->i64RSample >> 32, \ 604 samCur.i64LSample >> 32, samCur.i64RSample >> 32)); \ 610 605 \ 611 606 paDst++; \ 612 607 pRate->dstOffset += pRate->dstInc; \ 613 608 \ 614 AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset= 0x%RX32 (%RU32)\n", pRate->dstOffset, pRate->dstOffset >> 32)); \609 AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=%RU32\n", pRate->dstOffset >> 32)); \ 615 610 \ 616 611 } \ 617 612 \ 618 AUDMIXBUF_MACRO_LOG(("End: paDst=%p - paDstStart=%p -> %zu\n", paDst, paDstStart, paDst - paDstStart)); \ 619 AUDMIXBUF_MACRO_LOG(("End: paSrc=%p - paSrcStart=%p -> %zu\n", paSrc, paSrcStart, paSrc - paSrcStart)); \ 613 AUDMIXBUF_MACRO_LOG(("%zu source samples -> %zu dest samples\n", paSrc - paSrcStart, paDst - paDstStart)); \ 620 614 \ 621 615 pRate->srcSampleLast = samLast; \ 622 616 \ 623 AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64 , lDelta=0x%RX64 (%RU64)\n", \624 pRate->srcSampleLast.i64LSample, pRate->srcSampleLast.i64RSample , lDelta, lDelta)); \617 AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64\n", \ 618 pRate->srcSampleLast.i64LSample, pRate->srcSampleLast.i64RSample)); \ 625 619 \ 626 620 if (pcDstWritten) \ … … 643 637 { 644 638 /* Internally zero always corresponds to silence. */ 645 memset(paDst, 0, pOpts->cSamples * sizeof(paDst[0]));639 RT_BZERO(paDst, pOpts->cSamples * sizeof(paDst[0])); 646 640 return pOpts->cSamples; 647 641 } … … 674 668 } 675 669 } 676 else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)670 else 677 671 { 678 672 switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt)) … … 697 691 } 698 692 } 699 else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)693 else 700 694 { 701 695 switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt)) … … 735 729 } 736 730 } 737 else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)731 else 738 732 { 739 733 switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt)) … … 758 752 } 759 753 } 760 else if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 1)754 else 761 755 { 762 756 switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt)) … … 856 850 * 857 851 * The audio format of each mixing buffer can vary; the internal mixing code 858 * then will aut iomatically do the (needed) conversion.852 * then will automatically do the (needed) conversion. 859 853 * 860 854 * @return IPRT status code. … … 996 990 * will not be needed, that is, are not needed in order to process the live 997 991 * samples of the source buffer. */ 998 uint32_t cDead = pDst->cSamples - cLive;999 1000 uint32_t cToReadTotal = (uint32_t)RT_MIN(cSamples, AUDIOMIXBUF_S2S_RATIO(pSrc, cDead));1001 uint32_t offRead = 0;1002 1003 uint32_t cReadTotal = 0;992 uint32_t cDead = pDst->cSamples - cLive; 993 994 uint32_t cToReadTotal = (uint32_t)RT_MIN(cSamples, AUDIOMIXBUF_S2S_RATIO(pSrc, cDead)); 995 uint32_t offRead = 0; 996 997 uint32_t cReadTotal = 0; 1004 998 uint32_t cWrittenTotal = 0; 1005 uint32_t offWrite = (pDst->offReadWrite + cLive) % pDst->cSamples; 1006 1007 AUDMIXBUF_LOG(("pSrc=%s (%RU32 samples), pDst=%s (%RU32 samples), cLive=%RU32, cDead=%RU32, cToReadTotal=%RU32, offWrite=%RU32\n", 1008 pSrc->pszName, pSrc->cSamples, pDst->pszName, pDst->cSamples, cLive, cDead, cToReadTotal, offWrite)); 999 uint32_t offWrite = (pDst->offReadWrite + cLive) % pDst->cSamples; 1000 1001 AUDMIXBUF_LOG(("pSrc=%s (%RU32 samples, %RU8 chan), pDst=%s (%RU32 samples, %RU8 chan), " \ 1002 "cLive=%RU32, cDead=%RU32, cToReadTotal=%RU32, offWrite=%RU32\n", 1003 pSrc->pszName, pSrc->cSamples, AUDMIXBUF_FMT_CHANNELS(pSrc->AudioFmt), 1004 pDst->pszName, pDst->cSamples, AUDMIXBUF_FMT_CHANNELS(pDst->AudioFmt), 1005 cLive, cDead, cToReadTotal, offWrite)); 1009 1006 1010 1007 uint32_t cToRead, cToWrite; … … 1030 1027 cDead, offWrite, cToWrite, offRead, cToRead)); 1031 1028 1032 audioMixBufOp Blend(pDst->pSamples + offWrite, cToWrite,1033 pSrc->pSamples + offRead, cToRead,1034 pSrc->pRate, &cWritten, &cRead);1029 audioMixBufOpAssign(pDst->pSamples + offWrite, cToWrite, 1030 pSrc->pSamples + offRead, cToRead, 1031 pSrc->pRate, &cWritten, &cRead); 1035 1032 1036 1033 AUDMIXBUF_LOG(("\t\tcWritten=%RU32, cRead=%RU32\n", cWritten, cRead)); … … 1138 1135 1139 1136 AUDMIXBUF_LOG(("********************************************\n")); 1140 AUDMIXBUF_LOG((" %s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n",1137 AUDMIXBUF_LOG(("[PARENT] %s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n", 1141 1138 pParent->pszName, 1142 1139 pParent->offReadWrite, pParent->cProcessed, pParent->cMixed, … … 1146 1143 RTListForEach(&pParent->lstBuffers, pIter, PDMAUDIOMIXBUF, Node) 1147 1144 { 1148 AUDMIXBUF_LOG(("\t %s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n",1145 AUDMIXBUF_LOG(("\t[CHILD] %s: offReadWrite=%RU32, cProcessed=%RU32, cMixed=%RU32 (BpS=%RU32)\n", 1149 1146 pIter->pszName, 1150 1147 pIter->offReadWrite, pIter->cProcessed, pIter->cMixed, … … 1363 1360 if (RT_SUCCESS(rc)) 1364 1361 { 1365 #ifdef DEBUG_DUMP_PCM_DATA1362 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA 1366 1363 RTFILE fh; 1367 rc = RTFileOpen(&fh, DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm",1364 rc = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm", 1368 1365 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1369 1366 if (RT_SUCCESS(rc)) … … 1507 1504 * @return IPRT status code. 1508 1505 * @param pMixBuf Pointer to mixing buffer to write to. 1509 * @param enmFmt Audio format supplied in the buffer.1510 1506 * @param offSamples Offset (in samples) starting to write at. 1511 1507 * @param pvBuf Pointer to audio buffer to be written. … … 1513 1509 * @param pcWritten Returns number of audio samples written. Optional. 1514 1510 */ 1515 int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, 1516 uint32_t offSamples, 1517 const void *pvBuf, uint32_t cbBuf, 1518 uint32_t *pcWritten) 1511 int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten) 1519 1512 { 1520 1513 return AudioMixBufWriteAtEx(pMixBuf, pMixBuf->AudioFmt, … … 1565 1558 uint32_t cWritten; 1566 1559 1567 #ifdef DEBUG_DUMP_PCM_DATA1560 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA 1568 1561 RTFILE fh; 1569 rc = RTFileOpen(&fh, DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeat.pcm",1562 rc = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeat.pcm", 1570 1563 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1571 1564 if (RT_SUCCESS(rc)) … … 1718 1711 } 1719 1712 1720 #ifdef DEBUG_DUMP_PCM_DATA1713 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA 1721 1714 RTFILE fh; 1722 RTFileOpen(&fh, DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeex.pcm",1715 RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writeex.pcm", 1723 1716 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1724 1717 RTFileWrite(fh, pSamplesDst1, AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), NULL); -
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r59275 r60353 310 310 RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node) 311 311 { 312 /** @todo Support output sinks as well! */313 312 if (!pStream->pConn->pfnIsActiveIn(pStream->pConn, pStream->pIn)) 314 313 continue; … … 327 326 break; 328 327 328 /** @todo Right now we only handle one stream (the last one added in fact). */ 329 329 330 AssertBreakStmt(cbRead <= cbToRead, rc = VERR_BUFFER_OVERFLOW); 330 331 cbToRead -= cbRead; -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r59987 r60353 616 616 pSink = pThis->pSinkMicIn; 617 617 break; 618 case PDMAUDIORECSOURCE_LINE _IN:618 case PDMAUDIORECSOURCE_LINE: 619 619 pSink = pThis->pSinkLineIn; 620 620 break; … … 642 642 pStrmIn = &pDrv->LineIn; 643 643 644 int rc2 = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, enmRecSource, pCfg, &pStrmIn->pStrmIn); 645 646 LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc)); 647 if (rc2 == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */ 644 int rc2 = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, pCfg, &pStrmIn->pStrmIn); 645 LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc2)); 646 if (RT_SUCCESS(rc2)) 648 647 { 649 648 AudioMixerRemoveStream(pSink, pStrmIn->phStrmIn); … … 653 652 } 654 653 654 if (RT_SUCCESS(rc)) 655 rc = rc2; 656 655 657 RTStrFree(pszDesc); 656 658 } … … 679 681 } 680 682 681 rc= pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pDrv->Out.pStrmOut);682 LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc ));683 if ( rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */683 int rc2 = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pDrv->Out.pStrmOut); 684 LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc2)); 685 if (RT_SUCCESS(rc2)) 684 686 { 685 687 AudioMixerRemoveStream(pThis->pSinkOutput, pDrv->Out.phStrmOut); 686 rc = AudioMixerAddStreamOut(pThis->pSinkOutput, 687 pDrv->pConnector, pDrv->Out.pStrmOut, 688 0 /* uFlags */, &pDrv->Out.phStrmOut); 689 } 688 rc2 = AudioMixerAddStreamOut(pThis->pSinkOutput, 689 pDrv->pConnector, pDrv->Out.pStrmOut, 690 0 /* uFlags */, &pDrv->Out.phStrmOut); 691 } 692 693 if (RT_SUCCESS(rc)) 694 rc = rc2; 690 695 691 696 RTStrFree(pszDesc); … … 712 717 { 713 718 case PI_INDEX: 714 rc = ichac97OpenIn(pThis, "ac97.pi", PDMAUDIORECSOURCE_LINE _IN, pCfg);719 rc = ichac97OpenIn(pThis, "ac97.pi", PDMAUDIORECSOURCE_LINE, pCfg); 715 720 break; 716 721 … … 820 825 break; 821 826 822 case PDMAUDIOMIXERCTL_ PCM:827 case PDMAUDIOMIXERCTL_FRONT: 823 828 rc = AudioMixerSetSinkVolume(pThis->pSinkOutput, &vol); 824 829 break; … … 875 880 case REC_VIDEO: return PDMAUDIORECSOURCE_VIDEO; 876 881 case REC_AUX: return PDMAUDIORECSOURCE_AUX; 877 case REC_LINE_IN: return PDMAUDIORECSOURCE_LINE _IN;882 case REC_LINE_IN: return PDMAUDIORECSOURCE_LINE; 878 883 case REC_PHONE: return PDMAUDIORECSOURCE_PHONE; 879 884 default: … … 893 898 case PDMAUDIORECSOURCE_VIDEO: return REC_VIDEO; 894 899 case PDMAUDIORECSOURCE_AUX: return REC_AUX; 895 case PDMAUDIORECSOURCE_LINE _IN: return REC_LINE_IN;900 case PDMAUDIORECSOURCE_LINE: return REC_LINE_IN; 896 901 case PDMAUDIORECSOURCE_PHONE: return REC_PHONE; 897 902 default: … … 969 974 970 975 ichac97MixerSetVolume(pThis, AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME, 0x8000); 971 ichac97MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_ PCM,0x8808);976 ichac97MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT, 0x8808); 972 977 ichac97MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, 0x8808); 973 978 … … 1806 1811 break; 1807 1812 case AC97_PCM_Out_Volume_Mute: 1808 ichac97MixerSetVolume(pThis, index, PDMAUDIOMIXERCTL_ PCM, u32Val);1813 ichac97MixerSetVolume(pThis, index, PDMAUDIOMIXERCTL_FRONT, u32Val); 1809 1814 break; 1810 1815 case AC97_Line_In_Volume_Mute: … … 2045 2050 # define V_(a, b) ichac97MixerSetVolume(pThis, a, b, ichac97MixerGet(pThis, a)) 2046 2051 V_(AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME); 2047 V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_ PCM);2052 V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT); 2048 2053 V_(AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN); 2049 2054 # undef V_ -
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r59987 r60353 33 33 #include <iprt/asm.h> 34 34 #include <iprt/asm-math.h> 35 #include <iprt/file.h> 35 36 #include <iprt/list.h> 36 37 #ifdef IN_RING3 … … 46 47 #include "AudioMixer.h" 47 48 #include "DevIchHdaCodec.h" 49 #include "DevIchHdaCommon.h" 48 50 #include "DrvAudio.h" 49 51 … … 85 87 #define BIRD_THINKS_CORBRP_IS_MOSTLY_RO 86 88 87 #define HDA_NREGS 114 88 #define HDA_NREGS_SAVED 112 89 /* Make sure that interleaving streams support is enabled if the 5.1 code 90 * is being used. */ 91 #ifdef VBOX_WITH_HDA_51_SURROUND 92 # define VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT 93 #endif 89 94 90 95 /** 91 * NB: Register values stored in memory (au32Regs[]) are indexed through 92 * the HDA_RMX_xxx macros (also HDA_MEM_IND_NAME()). On the other hand, the 93 * register descriptors in g_aHdaRegMap[] are indexed through the 94 * HDA_REG_xxx macros (also HDA_REG_IND_NAME()). 96 * At the moment we support 4 input + 4 output streams (for 7.1 support) max, 97 * which is 12 in total. Bidirectional streams are currently *not* supported. 95 98 * 96 * The au32Regs[] layout is kept unchanged for saved state 97 * compatibility. */ 99 * Note: When changing any of those values, be prepared for some saved state 100 * fixups / trouble! 101 */ 102 #define HDA_MAX_SDI 4 103 #define HDA_MAX_SDO 4 104 #define HDA_MAX_STREAMS (HDA_MAX_SDI + HDA_MAX_SDO) 105 AssertCompile(HDA_MAX_SDI <= HDA_MAX_SDO); 106 107 /** Number of general registers. */ 108 #define HDA_NUM_GENERAL_REGS 34 109 /** Number of total registers in the HDA's register map. */ 110 #define HDA_NUM_REGS (HDA_NUM_GENERAL_REGS + (HDA_MAX_STREAMS * 10 /* Each stream descriptor has 10 registers */)) 111 /** Total number of stream tags (channels). Index 0 is reserved / invalid. */ 112 #define HDA_MAX_TAGS 16 113 114 /** 115 * NB: Register values stored in memory (au32Regs[]) are indexed through 116 * the HDA_RMX_xxx macros (also HDA_MEM_IND_NAME()). On the other hand, the 117 * register descriptors in g_aHdaRegMap[] are indexed through the 118 * HDA_REG_xxx macros (also HDA_REG_IND_NAME()). 119 * 120 * The au32Regs[] layout is kept unchanged for saved state 121 * compatibility. 122 */ 98 123 99 124 /* Registers */ … … 114 139 * iss (11:8) - number of input streams supported 115 140 * bss (7:3) - number of bidirectional streams supported 116 * bds (2:1) - number of serial data out signals supported141 * bds (2:1) - number of serial data out (SDO) signals supported 117 142 * b64sup (0) - 64 bit addressing supported. 118 143 */ 119 144 #define HDA_MAKE_GCAP(oss, iss, bss, bds, b64sup) \ 120 ( (((oss) & 0xF) << 12)\121 | (((iss) & 0xF) << 8)\122 | (((bss) & 0x1F) << 3)\123 | (((bds) & 0x3) << 2)\145 ( (((oss) & 0xF) << 12) \ 146 | (((iss) & 0xF) << 8) \ 147 | (((bss) & 0xF) << 3) \ 148 | (((bds) & 0x3) << 1) \ 124 149 | ((b64sup) & 1)) 125 150 … … 187 212 #define HDA_INTSTS_S_MASK(num) RT_BIT(HDA_REG_FIELD_SHIFT(S##num)) 188 213 189 #define HDA_REG_WALCLK 13 /* 0x 24*/214 #define HDA_REG_WALCLK 13 /* 0x30 */ 190 215 #define HDA_RMX_WALCLK /* Not defined! */ 191 216 … … 194 219 * the datasheet. 195 220 */ 196 #define HDA_REG_SSYNC 14 /* 0x3 4*/221 #define HDA_REG_SSYNC 14 /* 0x38 */ 197 222 #define HDA_RMX_SSYNC 12 198 223 … … 290 315 #define HDA_SD_NUM_FROM_REG(pThis, func, reg) ((reg - HDA_STREAM_REG_DEF(func, 0)) / 10) 291 316 292 #define HDA_REG_SD0CTL 34 /* 0x80 */ 293 #define HDA_REG_SD1CTL (HDA_STREAM_REG_DEF(CTL, 0) + 10) /* 0xA0 */ 294 #define HDA_REG_SD2CTL (HDA_STREAM_REG_DEF(CTL, 0) + 20) /* 0xC0 */ 295 #define HDA_REG_SD3CTL (HDA_STREAM_REG_DEF(CTL, 0) + 30) /* 0xE0 */ 296 #define HDA_REG_SD4CTL (HDA_STREAM_REG_DEF(CTL, 0) + 40) /* 0x100 */ 297 #define HDA_REG_SD5CTL (HDA_STREAM_REG_DEF(CTL, 0) + 50) /* 0x120 */ 298 #define HDA_REG_SD6CTL (HDA_STREAM_REG_DEF(CTL, 0) + 60) /* 0x140 */ 299 #define HDA_REG_SD7CTL (HDA_STREAM_REG_DEF(CTL, 0) + 70) /* 0x160 */ 317 /** @todo Condense marcos! */ 318 319 #define HDA_REG_SD0CTL HDA_NUM_GENERAL_REGS /* 0x80 */ 320 #define HDA_REG_SD1CTL (HDA_STREAM_REG_DEF(CTL, 0) + 10) /* 0xA0 */ 321 #define HDA_REG_SD2CTL (HDA_STREAM_REG_DEF(CTL, 0) + 20) /* 0xC0 */ 322 #define HDA_REG_SD3CTL (HDA_STREAM_REG_DEF(CTL, 0) + 30) /* 0xE0 */ 323 #define HDA_REG_SD4CTL (HDA_STREAM_REG_DEF(CTL, 0) + 40) /* 0x100 */ 324 #define HDA_REG_SD5CTL (HDA_STREAM_REG_DEF(CTL, 0) + 50) /* 0x120 */ 325 #define HDA_REG_SD6CTL (HDA_STREAM_REG_DEF(CTL, 0) + 60) /* 0x140 */ 326 #define HDA_REG_SD7CTL (HDA_STREAM_REG_DEF(CTL, 0) + 70) /* 0x160 */ 300 327 #define HDA_RMX_SD0CTL 32 301 328 #define HDA_RMX_SD1CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 10) … … 471 498 #define HDA_RMX_SD7FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 70) 472 499 473 #define SDFMT(pThis, num) (HDA_REG((pThis), SD(FMT, num))) 474 #define HDA_SDFMT_BASE_RATE_SHIFT 14 475 #define HDA_SDFMT_MULT_SHIFT 11 476 #define HDA_SDFMT_MULT_MASK 0x7 477 #define HDA_SDFMT_DIV_SHIFT 8 478 #define HDA_SDFMT_DIV_MASK 0x7 479 #define HDA_SDFMT_BITS_SHIFT 4 480 #define HDA_SDFMT_BITS_MASK 0x7 481 #define SDFMT_BASE_RATE(pThis, num) ((SDFMT(pThis, num) & HDA_REG_FIELD_FLAG_MASK(SDFMT, BASE_RATE)) >> HDA_REG_FIELD_SHIFT(SDFMT, BASE_RATE)) 482 #define SDFMT_MULT(pThis, num) ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,MULT)) >> HDA_REG_FIELD_SHIFT(SDFMT, MULT)) 483 #define SDFMT_DIV(pThis, num) ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,DIV)) >> HDA_REG_FIELD_SHIFT(SDFMT, DIV)) 500 #define SDFMT(pThis, num) (HDA_REG((pThis), SD(FMT, num))) 501 #define HDA_SDFMT_BASE_RATE(pThis, num) ((SDFMT(pThis, num) & HDA_REG_FIELD_FLAG_MASK(SDFMT, BASE_RATE)) >> HDA_REG_FIELD_SHIFT(SDFMT, BASE_RATE)) 502 #define HDA_SDFMT_MULT(pThis, num) ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,MULT)) >> HDA_REG_FIELD_SHIFT(SDFMT, MULT)) 503 #define HDA_SDFMT_DIV(pThis, num) ((SDFMT((pThis), num) & HDA_REG_FIELD_MASK(SDFMT,DIV)) >> HDA_REG_FIELD_SHIFT(SDFMT, DIV)) 484 504 485 505 #define HDA_REG_SD0BDPL 42 /* 0x98 */ … … 585 605 /** Unused, padding. */ 586 606 bool fPadding; 607 /** Mutex semaphore handle to serialize access. */ 608 RTSEMMUTEX hMtx; 587 609 /** Event signalling that the stream's state has been changed. */ 588 610 RTSEMEVENT hStateChangedEvent; … … 599 621 typedef struct HDASTREAM 600 622 { 601 /** Stream number (SDn). */602 uint8_t u8Strm;603 uint8_t Padding0[7];623 /** Stream descriptor number (SDn). */ 624 uint8_t u8SD; 625 uint8_t Padding0[7]; 604 626 /** DMA base address (SDnBDPU - SDnBDPL). */ 605 uint64_t u64BDLBase;627 uint64_t u64BDLBase; 606 628 /** Cyclic Buffer Length (SDnCBL). 607 629 * Represents the size of the ring buffer. */ 608 uint32_t u32CBL;630 uint32_t u32CBL; 609 631 /** Format (SDnFMT). */ 610 uint16_t u16FMT;632 uint16_t u16FMT; 611 633 /** FIFO Size (FIFOS). 612 634 * Maximum number of bytes that may have been DMA'd into … … 614 636 * 615 637 * Must be a power of two. */ 616 uint16_t u16FIFOS;638 uint16_t u16FIFOS; 617 639 /** Last Valid Index (SDnLVI). */ 618 uint16_t u16LVI; 619 uint16_t Padding1[3]; 640 uint16_t u16LVI; 641 uint16_t Padding1[3]; 642 /** Pointer to mixer sink this stream is attached to. */ 643 R3PTRTYPE(PAUDMIXSINK) pSink; 620 644 /** Internal state of this stream. */ 621 HDASTREAMSTATE State;645 HDASTREAMSTATE State; 622 646 } HDASTREAM, *PHDASTREAM; 623 647 648 /** 649 * Structure for mapping a stream tag to 650 * an internal stream state. 651 */ 652 typedef struct HDATAG 653 { 654 /** Own Tag. */ 655 uint8_t uTag; 656 uint8_t Padding[7]; 657 /** Pointer to associated stream. */ 658 R3PTRTYPE(PHDASTREAM) pStrm; 659 } HDATAG, *PHDATAG; 660 624 661 typedef struct HDAINPUTSTREAM 625 662 { 626 /** P CM lineinput stream. */627 R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pStrmIn;628 /** Mixer handle for line input stream. */629 R3PTRTYPE(PAUDMIXSTREAM) phStrmIn;663 /** Pointer to guest input stream. */ 664 R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pGstStrm; 665 /** Associated mixer handle. */ 666 R3PTRTYPE(PAUDMIXSTREAM) pMixStrm; 630 667 } HDAINPUTSTREAM, *PHDAINPUTSTREAM; 631 668 632 669 typedef struct HDAOUTPUTSTREAM 633 670 { 634 /** P CMoutput stream. */635 R3PTRTYPE(PPDMAUDIOGSTSTRMOUT) pStrmOut;636 /** Mixer handle for line output stream. */637 R3PTRTYPE(PAUDMIXSTREAM) phStrmOut;671 /** Pointer to guest output stream. */ 672 R3PTRTYPE(PPDMAUDIOGSTSTRMOUT) pGstStrm; 673 /** Associated mixer handle. */ 674 R3PTRTYPE(PAUDMIXSTREAM) pMixStrm; 638 675 } HDAOUTPUTSTREAM, *PHDAOUTPUTSTREAM; 639 676 … … 666 703 /** Stream for line input. */ 667 704 HDAINPUTSTREAM LineIn; 705 #ifdef VBOX_WITH_HDA_MIC_IN 668 706 /** Stream for mic input. */ 669 707 HDAINPUTSTREAM MicIn; 670 /** Stream for output. */ 671 HDAOUTPUTSTREAM Out; 708 #endif 709 /** Stream for front output. */ 710 HDAOUTPUTSTREAM Front; 711 #ifdef VBOX_WITH_HDA_51_SURROUND 712 /** Stream for center/LFE output. */ 713 HDAOUTPUTSTREAM CenterLFE; 714 /** Stream for rear output. */ 715 HDAOUTPUTSTREAM Rear; 716 #endif 672 717 } HDADRIVER; 673 718 … … 691 736 RTGCPHYS MMIOBaseAddr; 692 737 /** The HDA's register set. */ 693 uint32_t au32Regs[HDA_NREGS]; 694 /** Stream state for line-in. */ 695 HDASTREAM StrmStLineIn; 696 /** Stream state for microphone-in. */ 697 HDASTREAM StrmStMicIn; 698 /** Stream state for output. */ 699 HDASTREAM StrmStOut; 738 uint32_t au32Regs[HDA_NUM_REGS]; 739 /** Internal stream states. */ 740 HDASTREAM aStreams[HDA_MAX_STREAMS]; 741 /** Mapping table between stream tags and stream states. */ 742 HDATAG aTags[HDA_MAX_TAGS]; 700 743 /** CORB buffer base address. */ 701 744 uint64_t u64CORBBase; … … 719 762 /** Size in bytes of RIRB buffer. */ 720 763 uint32_t cbRirbBuf; 721 /** Indicates if HDA is in reset. */764 /** Indicates if HDA controller is in reset mode. */ 722 765 bool fInReset; 723 766 /** Flag whether the R0 part is enabled. */ … … 748 791 R3PTRTYPE(PAUDIOMIXER) pMixer; 749 792 /** Audio sink for PCM output. */ 750 R3PTRTYPE(PAUDMIXSINK) pSinkOutput; 793 R3PTRTYPE(PAUDMIXSINK) pSinkFront; 794 #ifdef VBOX_WITH_HDA_51_SURROUND 795 R3PTRTYPE(PAUDMIXSINK) pSinkCenterLFE; 796 R3PTRTYPE(PAUDMIXSINK) pSinkRear; 797 #endif 751 798 /** Audio mixer sink for line input. */ 752 799 R3PTRTYPE(PAUDMIXSINK) pSinkLineIn; 800 #ifdef VBOX_WITH_HDA_MIC_IN 753 801 /** Audio mixer sink for microphone input. */ 754 802 R3PTRTYPE(PAUDMIXSINK) pSinkMicIn; 803 #endif 755 804 uint64_t u64BaseTS; 756 805 /** Response Interrupt Count (RINTCNT). */ … … 758 807 /** Padding for alignment. */ 759 808 uint8_t au8Padding2[7]; 809 #ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT 810 /** Circular buffer for interleaving streams support. 811 * This is needed for extracting multiple channels out of a single HDA stream. */ 812 R3PTRTYPE(PRTCIRCBUF) pCircBuf; 813 #endif 760 814 } HDASTATE; 761 815 /** Pointer to the ICH Intel HD Audio Controller state. */ … … 785 839 * Global register set read/write functions. 786 840 */ 787 static int hdaRegWriteGCTL(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);841 static int hdaRegWriteGCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 788 842 static int hdaRegReadINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 789 843 static int hdaRegReadLPIB(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 790 844 static int hdaRegReadWALCLK(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 791 static int hdaRegWriteINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 792 static int hdaRegWriteCORBWP(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 845 static int hdaRegReadSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 846 static int hdaRegWriteSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 847 static int hdaRegWriteINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 848 static int hdaRegWriteCORBWP(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 793 849 static int hdaRegWriteCORBRP(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 794 850 static int hdaRegWriteCORBCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 795 851 static int hdaRegWriteCORBSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 796 static int hdaRegWriteRIRBWP(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);852 static int hdaRegWriteRIRBWP(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 797 853 static int hdaRegWriteRIRBSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 798 static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 854 static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 855 static int hdaRegReadOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 856 static int hdaRegWriteOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 857 static int hdaRegReadOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 858 static int hdaRegWriteOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 799 859 static int hdaRegWriteIRS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 800 860 static int hdaRegReadIRS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); … … 804 864 * {IOB}SDn read/write functions. 805 865 */ 806 static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 807 static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 808 static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 809 static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 810 static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 811 static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 812 static int hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 813 static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 814 static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 815 inline bool hdaRegWriteSDIsAllowed(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 866 static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 867 static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 868 static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 869 static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 870 static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 871 static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 872 static int hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 873 static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 874 static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 875 DECLINLINE(int) hdaRegWriteSDLock(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t iReg, uint32_t u32Value); 876 DECLINLINE(void) hdaRegWriteSDUnlock(PHDASTREAM pStrmSt); 816 877 817 878 /* … … 819 880 */ 820 881 static int hdaRegReadU32(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 821 static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);882 static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 822 883 static int hdaRegReadU24(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 823 static int hdaRegWriteU24(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);884 static int hdaRegWriteU24(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 824 885 static int hdaRegReadU16(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 825 static int hdaRegWriteU16(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);886 static int hdaRegWriteU16(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 826 887 static int hdaRegReadU8(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 827 static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);888 static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 828 889 829 890 #ifdef IN_RING3 … … 832 893 static int hdaStreamStop(PHDASTREAM pStrmSt); 833 894 static int hdaStreamWaitForStateChange(PHDASTREAM pStrmSt, RTMSINTERVAL msTimeout); 834 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t cbToProcess, uint32_t *pcbProcessed);895 static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbToProcess, uint32_t *pcbProcessed); 835 896 #endif 836 897 … … 911 972 /** Descripton. */ 912 973 const char *desc; 913 } g_aHdaRegMap[HDA_N REGS] =974 } g_aHdaRegMap[HDA_NUM_REGS] = 914 975 915 976 { … … 919 980 { 0x00002, 0x00001, 0x000000FF, 0x00000000, hdaRegReadU8 , hdaRegWriteUnimpl , HDA_REG_IDX(VMIN) }, /* Minor Version */ 920 981 { 0x00003, 0x00001, 0x000000FF, 0x00000000, hdaRegReadU8 , hdaRegWriteUnimpl , HDA_REG_IDX(VMAJ) }, /* Major Version */ 921 { 0x00004, 0x00002, 0x0000FFFF, 0x00000000, hdaRegRead U16 , hdaRegWriteUnimpl, HDA_REG_IDX(OUTPAY) }, /* Output Payload Capabilities */982 { 0x00004, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadOUTPAY , hdaRegWriteOUTPAY , HDA_REG_IDX(OUTPAY) }, /* Output Payload Capabilities */ 922 983 { 0x00006, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadU16 , hdaRegWriteUnimpl , HDA_REG_IDX(INPAY) }, /* Input Payload Capabilities */ 923 984 { 0x00008, 0x00004, 0x00000103, 0x00000103, hdaRegReadU32 , hdaRegWriteGCTL , HDA_REG_IDX(GCTL) }, /* Global Control */ … … 925 986 { 0x0000e, 0x00002, 0x00000007, 0x00000007, hdaRegReadU8 , hdaRegWriteSTATESTS , HDA_REG_IDX(STATESTS) }, /* State Change Status */ 926 987 { 0x00010, 0x00002, 0xFFFFFFFF, 0x00000000, hdaRegReadUnimpl , hdaRegWriteUnimpl , HDA_REG_IDX(GSTS) }, /* Global Status */ 927 { 0x00018, 0x00002, 0x0000FFFF, 0x00000000, hdaRegRead U16 , hdaRegWriteUnimpl, HDA_REG_IDX(OUTSTRMPAY) }, /* Output Stream Payload Capability */988 { 0x00018, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadOUTSTRMPAY , hdaRegWriteOUTSTRMPAY , HDA_REG_IDX(OUTSTRMPAY) }, /* Output Stream Payload Capability */ 928 989 { 0x0001A, 0x00002, 0x0000FFFF, 0x00000000, hdaRegReadU16 , hdaRegWriteUnimpl , HDA_REG_IDX(INSTRMPAY) }, /* Input Stream Payload Capability */ 929 990 { 0x00020, 0x00004, 0xC00000FF, 0xC00000FF, hdaRegReadU32 , hdaRegWriteU32 , HDA_REG_IDX(INTCTL) }, /* Interrupt Control */ 930 991 { 0x00024, 0x00004, 0xC00000FF, 0x00000000, hdaRegReadINTSTS , hdaRegWriteUnimpl , HDA_REG_IDX(INTSTS) }, /* Interrupt Status */ 931 992 { 0x00030, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadWALCLK , hdaRegWriteUnimpl , HDA_REG_IDX_LOCAL(WALCLK) }, /* Wall Clock Counter */ 932 { 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegRead U32 , hdaRegWriteU32, HDA_REG_IDX(SSYNC) }, /* Stream Synchronization */993 { 0x00034, 0x00004, 0x000000FF, 0x000000FF, hdaRegReadSSYNC , hdaRegWriteSSYNC , HDA_REG_IDX(SSYNC) }, /* Stream Synchronization */ 933 994 { 0x00040, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteBase , HDA_REG_IDX(CORBLBASE) }, /* CORB Lower Base Address */ 934 995 { 0x00044, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteBase , HDA_REG_IDX(CORBUBASE) }, /* CORB Upper Base Address */ … … 1033 1094 1034 1095 LogFlowFunc(("[SD%RU8]: LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", 1035 pStrmSt->u8S trm, u32LPIB, pThis->fDMAPosition));1096 pStrmSt->u8SD, u32LPIB, pThis->fDMAPosition)); 1036 1097 1037 1098 /* Update LPIB in any case. */ 1038 HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm) = u32LPIB;1099 HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD) = u32LPIB; 1039 1100 1040 1101 /* Do we need to tell the current DMA position? */ … … 1042 1103 { 1043 1104 int rc2 = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 1044 (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8S trm* 2 * sizeof(uint32_t)),1105 (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8SD * 2 * sizeof(uint32_t)), 1045 1106 (void *)&u32LPIB, sizeof(uint32_t)); 1046 1107 AssertRC(rc2); 1047 #ifdef DEBUG1048 hdaBDLEDumpAll(pThis, pStrmSt->u64BDLBase, pStrmSt->State.uCurBDLE);1049 #endif1050 1108 } 1051 1109 } … … 1141 1199 1142 1200 #ifdef DEBUG 1143 LogFlowFunc(("[SD%RU8]: uOldBDLE=%RU16, uCurBDLE=%RU16, LVI=%RU32, %R[bdle]\n",1144 pStrmSt->u8S trm, uOldBDLE, pStrmSt->State.uCurBDLE, pStrmSt->u16LVI, &pStrmSt->State.BDLE));1201 LogFlowFunc(("[SD%RU8]: uOldBDLE=%RU16, uCurBDLE=%RU16, LVI=%RU32, rc=%Rrc, %R[bdle]\n", 1202 pStrmSt->u8SD, uOldBDLE, pStrmSt->State.uCurBDLE, pStrmSt->u16LVI, rc, &pStrmSt->State.BDLE)); 1145 1203 #endif 1146 1204 return rc; 1147 1205 } 1148 #endif 1149 1150 DECLINLINE(PHDASTREAM) hdaStreamFromID(PHDASTATE pThis, uint8_t uStreamID) 1151 { 1152 PHDASTREAM pStrmSt; 1153 1154 switch (uStreamID) 1155 { 1156 case 0: /** @todo Use dynamic indices, based on stream assignment. */ 1157 { 1158 pStrmSt = &pThis->StrmStLineIn; 1159 break; 1160 } 1161 # ifdef VBOX_WITH_HDA_MIC_IN 1162 case 2: /** @todo Use dynamic indices, based on stream assignment. */ 1163 { 1164 pStrmSt = &pThis->StrmStMicIn; 1165 break; 1166 } 1167 # endif 1168 case 4: /** @todo Use dynamic indices, based on stream assignment. */ 1169 { 1170 pStrmSt = &pThis->StrmStOut; 1171 break; 1172 } 1173 1174 default: 1175 { 1176 pStrmSt = NULL; 1177 LogFunc(("Warning: Stream with ID=%RU8 not handled\n", uStreamID)); 1178 break; 1179 } 1180 } 1181 1182 return pStrmSt; 1206 #endif /* IN_RING3 */ 1207 1208 DECLINLINE(PHDASTREAM) hdaStreamFromSD(PHDASTATE pThis, uint8_t uSD) 1209 { 1210 AssertPtrReturn(pThis, NULL); 1211 AssertReturn(uSD <= HDA_MAX_STREAMS, NULL); 1212 return &pThis->aStreams[uSD]; 1183 1213 } 1184 1214 … … 1197 1227 1198 1228 #ifdef VBOX_HDA_WITH_FIFO 1199 return hdaSDFIFOWToBytes(HDA_STREAM_REG(pThis, FIFOW, pStrmSt->u8S trm));1229 return hdaSDFIFOWToBytes(HDA_STREAM_REG(pThis, FIFOW, pStrmSt->u8SD)); 1200 1230 #else 1201 1231 return 0; … … 1210 1240 1211 1241 bool fIrq = false; 1242 1243 /** @todo Optimize IRQ handling. */ 1212 1244 1213 1245 if (/* Controller Interrupt Enable (CIE). */ … … 1218 1250 fIrq = true; 1219 1251 1220 /** @todo Don't hardcode stream numbers here. */1221 1252 if ( IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 0) 1222 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 4)) 1223 { 1224 #ifdef IN_RING3 1225 LogFunc(("BCIS\n")); 1226 #endif 1253 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 1) 1254 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 2) 1255 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 3) 1256 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 4) 1257 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 5) 1258 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 6) 1259 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 7)) 1260 { 1227 1261 fIrq = true; 1228 1262 } … … 1230 1264 if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE)) 1231 1265 { 1232 Log Func(("%s\n", fIrq ? "Asserted" : "Deasserted"));1266 Log3Func(("%s\n", fIrq ? "Asserted" : "Deasserted")); 1233 1267 PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , fIrq); 1234 1268 } … … 1472 1506 } 1473 1507 1474 static int hdaStreamCreate(PHDASTREAM pStrmSt )1508 static int hdaStreamCreate(PHDASTREAM pStrmSt, uint8_t uSD) 1475 1509 { 1476 1510 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 1511 AssertReturn(uSD <= HDA_MAX_STREAMS, VERR_INVALID_PARAMETER); 1477 1512 1478 1513 int rc = RTSemEventCreate(&pStrmSt->State.hStateChangedEvent); 1479 AssertRC(rc); 1480 1481 pStrmSt->u8Strm = UINT8_MAX; 1482 1483 pStrmSt->State.fActive = false; 1484 pStrmSt->State.fInReset = false; 1485 pStrmSt->State.fDoStop = false; 1486 1487 LogFlowFuncLeaveRC(rc); 1514 if (RT_SUCCESS(rc)) 1515 rc = RTSemMutexCreate(&pStrmSt->State.hMtx); 1516 1517 if (RT_SUCCESS(rc)) 1518 { 1519 pStrmSt->u8SD = uSD; 1520 pStrmSt->pSink = NULL; 1521 1522 pStrmSt->State.fActive = false; 1523 pStrmSt->State.fInReset = false; 1524 pStrmSt->State.fDoStop = false; 1525 } 1526 1527 LogFlowFunc(("uSD=%RU8\n", uSD)); 1488 1528 return rc; 1489 1529 } … … 1493 1533 AssertPtrReturnVoid(pStrmSt); 1494 1534 1495 LogFlowFunc(("[SD%RU8]: Destroy\n", pStrmSt->u8S trm));1535 LogFlowFunc(("[SD%RU8]: Destroy\n", pStrmSt->u8SD)); 1496 1536 1497 1537 int rc2 = hdaStreamStop(pStrmSt); 1498 1538 AssertRC(rc2); 1499 1539 1540 if (pStrmSt->State.hMtx != NIL_RTSEMMUTEX) 1541 { 1542 rc2 = RTSemMutexDestroy(pStrmSt->State.hMtx); 1543 AssertRC(rc2); 1544 pStrmSt->State.hMtx = NIL_RTSEMMUTEX; 1545 } 1546 1500 1547 if (pStrmSt->State.hStateChangedEvent != NIL_RTSEMEVENT) 1501 1548 { 1502 1549 rc2 = RTSemEventDestroy(pStrmSt->State.hStateChangedEvent); 1503 1550 AssertRC(rc2); 1551 pStrmSt->State.hStateChangedEvent = NIL_RTSEMEVENT; 1504 1552 } 1505 1553 … … 1507 1555 } 1508 1556 1509 static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8S trm)1557 static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8SD) 1510 1558 { 1511 1559 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1512 1560 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 1513 1561 1514 pStrmSt->u8S trm = u8Strm;1515 pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8S trm),1516 HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8S trm));1517 pStrmSt->u16LVI = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8S trm);1518 pStrmSt->u32CBL = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8S trm);1519 pStrmSt->u16FIFOS = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, pStrmSt->u8S trm));1562 pStrmSt->u8SD = u8SD; 1563 pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8SD), 1564 HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8SD)); 1565 pStrmSt->u16LVI = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8SD); 1566 pStrmSt->u32CBL = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8SD); 1567 pStrmSt->u16FIFOS = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, pStrmSt->u8SD)); 1520 1568 1521 1569 RT_ZERO(pStrmSt->State.BDLE); … … 1523 1571 1524 1572 LogFlowFunc(("[SD%RU8]: DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n", 1525 pStrmSt->u8S trm, pStrmSt->u64BDLBase, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS));1573 pStrmSt->u8SD, pStrmSt->u64BDLBase, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS)); 1526 1574 1527 1575 #ifdef DEBUG 1528 uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),1529 HDA_STREAM_REG(pThis, BDPU, u8Strm));1530 uint16_t u16LVI = HDA_STREAM_REG(pThis, LVI, u8Strm);1531 uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, u8Strm);1576 uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8SD), 1577 HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8SD)); 1578 uint16_t u16LVI = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8SD); 1579 uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8SD); 1532 1580 1533 1581 LogFlowFunc(("\t-> DMA @ 0x%x, LVI=%RU16, CBL=%RU32\n", u64BaseDMA, u16LVI, u32CBL)); … … 1543 1591 AssertPtrReturnVoid(pThis); 1544 1592 AssertPtrReturnVoid(pStrmSt); 1545 AssertReturnVoid(u8Strm <= 7); /** @todo Use a define for MAX_STREAMS! */1593 AssertReturnVoid(u8Strm <= HDA_MAX_STREAMS); 1546 1594 1547 1595 #ifdef VBOX_STRICT 1548 1596 AssertReleaseMsg(!RT_BOOL(HDA_STREAM_REG(pThis, CTL, u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)), 1549 (" Cannot reset stream %RU8while in running state\n", u8Strm));1597 ("[SD%RU8] Cannot reset stream while in running state\n", u8Strm)); 1550 1598 #endif 1551 1599 … … 1559 1607 * First, reset the internal stream state. 1560 1608 */ 1561 RT_BZERO(pStrmSt, sizeof(HDASTREAM)); 1609 RT_ZERO(pStrmSt->State.BDLE); 1610 pStrmSt->State.uCurBDLE = 0; 1562 1611 1563 1612 /* … … 1575 1624 HDA_STREAM_REG(pThis, CBL, u8Strm) = 0; 1576 1625 HDA_STREAM_REG(pThis, LVI, u8Strm) = 0; 1577 HDA_STREAM_REG(pThis, FMT, u8Strm) = 0; 1626 HDA_STREAM_REG(pThis, FMT, u8Strm) = HDA_SDFMT_MAKE(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ, 1627 HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT, 1628 HDA_SDFMT_CHAN_STEREO); 1578 1629 HDA_STREAM_REG(pThis, BDPU, u8Strm) = 0; 1579 1630 HDA_STREAM_REG(pThis, BDPL, u8Strm) = 0; 1580 1631 1581 1632 /* 1582 * Third, set the internal state accordingto the just set registers.1633 * Third, match the internal state to the just set registers. 1583 1634 */ 1584 pStrmSt->u8Strm = u8Strm; 1585 pStrmSt->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, u8Strm); 1586 1587 1588 /* Report that we're done resetting this stream. */ 1589 HDA_STREAM_REG(pThis, CTL, u8Strm) = 0; 1635 pStrmSt->u8SD = u8Strm; 1636 pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm), 1637 HDA_STREAM_REG(pThis, BDPU, u8Strm)); 1638 pStrmSt->u32CBL = HDA_STREAM_REG(pThis, CBL, u8Strm); 1639 pStrmSt->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, u8Strm); 1640 pStrmSt->u16FMT = HDA_STREAM_REG(pThis, FMT, u8Strm); 1641 pStrmSt->u16LVI = HDA_STREAM_REG(pThis, LVI, u8Strm); 1590 1642 1591 1643 LogFunc(("[SD%RU8]: Reset\n", u8Strm)); 1592 1644 1593 /* Exit reset mode. */1645 /* Exit reset state. */ 1594 1646 ASMAtomicXchgBool(&pStrmSt->State.fInReset, false); 1595 1647 } … … 1644 1696 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 1645 1697 1646 LogFlowFunc(("[SD%RU8]: msTimeout=%RU32\n", pStrmSt->u8S trm, msTimeout));1698 LogFlowFunc(("[SD%RU8]: msTimeout=%RU32\n", pStrmSt->u8SD, msTimeout)); 1647 1699 return RTSemEventWait(pStrmSt->State.hStateChangedEvent, msTimeout); 1648 1700 } … … 1728 1780 if (pThis->fInReset) 1729 1781 { 1730 LogFunc((" Leavingreset\n"));1782 LogFunc(("Guest leaving HDA reset\n")); 1731 1783 pThis->fInReset = false; 1732 1784 } … … 1736 1788 #ifdef IN_RING3 1737 1789 /* Enter reset state. */ 1738 if ( HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) 1739 || HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA)) 1740 { 1741 LogFunc(("Entering reset with DMA(RIRB:%s, CORB:%s)\n", 1742 HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off", 1743 HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off")); 1744 } 1745 1746 /* Clear the CRST bit to indicate that we're in reset mode. */ 1790 LogFunc(("Guest entering HDA reset with DMA(RIRB:%s, CORB:%s)\n", 1791 HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off", 1792 HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off")); 1793 1794 /* Clear the CRST bit to indicate that we're in reset state. */ 1747 1795 HDA_REG(pThis, GCTL) &= ~HDA_REG_FIELD_FLAG_MASK(GCTL, RST); 1748 1796 pThis->fInReset = true; 1749 1797 1750 /* As the CRST bit now is set, we now can proceed resetting stuff. */1751 1798 hdaReset(pThis->CTX_SUFF(pDevIns)); 1752 1799 #else … … 1754 1801 #endif 1755 1802 } 1803 1756 1804 if (u32Value & HDA_REG_FIELD_FLAG_MASK(GCTL, FSH)) 1757 1805 { … … 1771 1819 pThis->au32Regs[iRegMem] &= ~(v & nv); /* write of 1 clears corresponding bit */ 1772 1820 return VINF_SUCCESS; 1821 } 1822 1823 static int hdaRegReadOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 1824 { 1825 uint16_t u16OUTSTRMPAY = HDA_REG(pThis, OUTPAY); 1826 LogFlowFunc(("%RU16\n", u16OUTSTRMPAY)); 1827 1828 if (pu32Value) 1829 *pu32Value = u16OUTSTRMPAY; 1830 return VINF_SUCCESS; 1831 } 1832 1833 static int hdaRegWriteOUTPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1834 { 1835 LogFlowFunc(("%RU16\n", (uint16_t)u32Value)); 1836 return hdaRegWriteU16(pThis, iReg, u32Value); 1837 } 1838 1839 static int hdaRegReadOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 1840 { 1841 uint16_t u16OUTSTRMPAY = HDA_REG(pThis, OUTSTRMPAY); 1842 LogFlowFunc(("%RU16\n", u16OUTSTRMPAY)); 1843 1844 if (pu32Value) 1845 *pu32Value = u16OUTSTRMPAY; 1846 return VINF_SUCCESS; 1847 } 1848 1849 static int hdaRegWriteOUTSTRMPAY(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1850 { 1851 LogFlowFunc(("%RU16\n", (uint16_t)u32Value)); 1852 return hdaRegWriteU16(pThis, iReg, u32Value); 1773 1853 } 1774 1854 … … 1784 1864 } 1785 1865 1786 #define HDA_IS_STREAM_EVENT(pThis, num) \ 1787 ( (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE)) \ 1788 || (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE)) \ 1789 || (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) 1790 1791 #define HDA_MARK_STREAM(pThis, num, v) \ 1792 do { (v) |= HDA_IS_STREAM_EVENT((pThis), num) ? RT_BIT((num)) : 0; } while(0) 1793 1794 HDA_MARK_STREAM(pThis, 0, v); 1795 HDA_MARK_STREAM(pThis, 1, v); 1796 HDA_MARK_STREAM(pThis, 2, v); 1797 HDA_MARK_STREAM(pThis, 3, v); 1798 HDA_MARK_STREAM(pThis, 4, v); 1799 HDA_MARK_STREAM(pThis, 5, v); 1800 HDA_MARK_STREAM(pThis, 6, v); 1801 HDA_MARK_STREAM(pThis, 7, v); 1802 1803 #undef HDA_IS_STREAM_EVENT 1804 #undef HDA_MARK_STREAM 1866 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 1867 { 1868 const uint32_t u32STS = HDA_STREAM_REG(pThis, STS, i); 1869 bool fReport = (u32STS & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE)) 1870 || (u32STS & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE)) 1871 || (u32STS & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS)); 1872 v |= fReport ? RT_BIT(i) : 0; 1873 } 1805 1874 1806 1875 v |= v ? RT_BIT(31) : 0; 1807 1876 1808 *pu32Value = v; 1877 if (pu32Value) 1878 *pu32Value = v; 1879 1809 1880 return VINF_SUCCESS; 1810 1881 } … … 1829 1900 LogFlowFunc(("%RU32\n", *pu32Value)); 1830 1901 return VINF_SUCCESS; 1902 } 1903 1904 static int hdaRegReadSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 1905 { 1906 /* HDA spec (1a): 3.3.16 WALCLK counter ticks with 24Mhz bitclock rate. */ 1907 *pu32Value = HDA_REG(pThis, SSYNC); 1908 LogFlowFunc(("%RU32\n", *pu32Value)); 1909 return VINF_SUCCESS; 1910 } 1911 1912 static int hdaRegWriteSSYNC(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1913 { 1914 LogFlowFunc(("%RU32\n", u32Value)); 1915 return hdaRegWriteU32(pThis, iReg, u32Value); 1831 1916 } 1832 1917 … … 1880 1965 rc = hdaCORBCmdProcess(pThis); 1881 1966 return rc; 1882 #else 1967 #else /* !IN_RING3 */ 1883 1968 return VINF_IOM_R3_MMIO_WRITE; 1884 #endif 1969 #endif /* IN_RING3 */ 1885 1970 } 1886 1971 1887 1972 static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1888 1973 { 1889 int rc = hdaRegWriteU32(pThis, iReg, u32Value); 1890 if (RT_SUCCESS(rc)) 1891 { 1892 uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, CBL, iReg); 1893 1894 PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm); 1895 if (pStrmSt) 1896 { 1897 pStrmSt->u32CBL = u32Value; 1898 1899 /* Reset BDLE state. */ 1900 RT_ZERO(pStrmSt->State.BDLE); 1901 pStrmSt->State.uCurBDLE = 0; 1902 } 1903 1904 LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", u8Strm, u32Value)); 1905 } 1906 else 1907 AssertRCReturn(rc, VINF_SUCCESS); 1908 1909 return rc; 1974 #ifdef IN_RING3 1975 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 1976 return VINF_SUCCESS; 1977 1978 PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, CBL, iReg)); 1979 if (!pStrmSt) 1980 { 1981 LogFunc(("[SD%RU8]: Warning: Changing SDCBL on non-attached stream (0x%x)\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value)); 1982 return hdaRegWriteU32(pThis, iReg, u32Value); 1983 } 1984 1985 int rc2 = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value); 1986 AssertRC(rc2); 1987 1988 pStrmSt->u32CBL = u32Value; 1989 1990 /* Reset BDLE state. */ 1991 RT_ZERO(pStrmSt->State.BDLE); 1992 pStrmSt->State.uCurBDLE = 0; 1993 1994 rc2 = hdaRegWriteU32(pThis, iReg, u32Value); 1995 AssertRC(rc2); 1996 1997 LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", pStrmSt->u8SD, u32Value)); 1998 hdaRegWriteSDUnlock(pStrmSt); 1999 2000 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 2001 #else /* !IN_RING3 */ 2002 return VINF_IOM_R3_MMIO_WRITE; 2003 #endif /* IN_RING3 */ 1910 2004 } 1911 2005 … … 1917 2011 bool fInReset = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1918 2012 1919 uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg); 1920 1921 PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm); 1922 if (!pStrmSt) 1923 { 1924 LogFunc(("Warning: Changing SDCTL on non-attached stream with ID=%RU8 (iReg=0x%x)\n", u8Strm, iReg)); 1925 return hdaRegWriteU24(pThis, iReg, u32Value); /* Write 3 bytes. */ 1926 } 2013 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2014 return VINF_SUCCESS; 2015 2016 /* Get the stream descriptor. */ 2017 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg); 2018 2019 /* 2020 * Extract the stream tag the guest wants to use for this specific 2021 * stream descriptor (SDn). This only can happen if the stream is in a non-running 2022 * state, so we're doing the lookup and assignment here. 2023 * 2024 * So depending on the guest OS, SD3 can use stream tag 4, for example. 2025 */ 2026 uint8_t uTag = (u32Value >> HDA_SDCTL_NUM_SHIFT) & HDA_SDCTL_NUM_MASK; 2027 2028 /* Tag 0 is reserved for software / invalid, just skip. */ 2029 if ( !uTag 2030 || (uTag > HDA_MAX_TAGS)) 2031 { 2032 LogFunc(("[SD%RU8]: Warning: Invalid stream tag %RU8 specified!\n", uSD, uTag)); 2033 return hdaRegWriteU24(pThis, iReg, u32Value); 2034 } 2035 2036 #ifdef IN_RING3 2037 PHDATAG pTag = &pThis->aTags[uTag]; 2038 AssertPtr(pTag); 2039 2040 if (pTag->uTag) 2041 LogFunc(("[SD%RU8]: Warning: Tag %RU8 already assigned to %RU8 (pStrm=%p)\n", uSD, uTag, pTag->uTag, pTag->pStrm)); 2042 2043 /* Assign new values. */ 2044 pTag->uTag = uTag; 2045 pTag->pStrm = hdaStreamFromSD(pThis, uSD); 2046 2047 LogFunc(("[SD%RU8]: Using stream tag=%RU8\n", uSD, uTag)); 2048 2049 PHDASTREAM pStrmSt = pTag->pStrm; 2050 AssertPtr(pStrmSt); 2051 2052 /* Note: Do not use hdaRegWriteSDLock() here, as SDnCTL might change the RUN bit. */ 2053 int rc2 = RTSemMutexRequest(pStrmSt->State.hMtx, RT_INDEFINITE_WAIT); 2054 AssertRC(rc2); 2055 #endif /* IN_RING3 */ 1927 2056 1928 2057 LogFunc(("[SD%RU8]: fRun=%RTbool, fInRun=%RTbool, fReset=%RTbool, fInReset=%RTbool, %R[sdctl]\n", 1929 u 8Strm, fRun, fInRun, fReset, fInReset, u32Value));2058 uSD, fRun, fInRun, fReset, fInReset, u32Value)); 1930 2059 1931 2060 if (fInReset) 1932 2061 { 1933 /* Guest is resetting HDA's stream, we're expecting guest will mark stream as exit. */1934 2062 Assert(!fReset); 1935 LogFunc(("Guest initiated exit of stream reset\n")); 2063 Assert(!fInRun && !fRun); 2064 2065 /* Report that we're done resetting this stream by clearing SRST. */ 2066 HDA_STREAM_REG(pThis, CTL, uSD) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST); 2067 2068 LogFunc(("[SD%RU8]: Guest initiated exit of stream reset\n", uSD)); 1936 2069 } 1937 2070 else if (fReset) … … 1941 2074 Assert(!fInRun && !fRun); 1942 2075 1943 LogFunc(("Guest initiated enter to stream reset\n")); 1944 hdaStreamReset(pThis, pStrmSt, u8Strm); 1945 #else 1946 return VINF_IOM_R3_MMIO_WRITE; 2076 LogFunc(("[SD%RU8]: Guest initiated enter to stream reset\n", pStrmSt->u8SD)); 2077 hdaStreamReset(pThis, pStrmSt, pStrmSt->u8SD); 1947 2078 #endif 1948 2079 } … … 1956 2087 { 1957 2088 Assert(!fReset && !fInReset); 1958 LogFunc(("[SD%RU8]: fRun=%RTbool\n", u8Strm, fRun)); 1959 2089 LogFunc(("[SD%RU8]: fRun=%RTbool\n", pStrmSt->u8SD, fRun)); 2090 2091 Assert(pStrmSt->u8SD < HDA_MAX_STREAMS); 2092 2093 /* 2094 * The register layout specifies that input streams (SDI) come first, 2095 * followed by the output streams (SDO). So every stream ID below HDA_MAX_SDI 2096 * is an input stream, whereas everything >= HDA_MAX_SDI is an output stream. 2097 */ 1960 2098 PHDADRIVER pDrv; 1961 switch (u8Strm)2099 if (pStrmSt->u8SD < HDA_MAX_SDI) 1962 2100 { 1963 case 0: /** @todo Use a variable here. Later. */ 2101 # ifdef VBOX_WITH_HDA_MIC_IN 2102 # error "Implement mic-in support!" 2103 # else 2104 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2105 pDrv->pConnector->pfnEnableIn(pDrv->pConnector, 2106 pDrv->LineIn.pGstStrm, fRun); 2107 # endif 2108 } 2109 else 2110 { 2111 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 1964 2112 { 1965 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 1966 pDrv->pConnector->pfnEnableIn(pDrv->pConnector, 1967 pDrv->LineIn.pStrmIn, fRun); 1968 break; 2113 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Front.pGstStrm, fRun); 2114 # ifdef VBOX_WITH_HDA_51_SURROUND 2115 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->CenterLFE.pGstStrm, fRun); 2116 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Rear.pGstStrm, fRun); 2117 # endif 1969 2118 } 1970 # ifdef VBOX_WITH_HDA_MIC_IN1971 case 2: /** @todo Use a variable here. Later. */1972 {1973 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)1974 pDrv->pConnector->pfnEnableIn(pDrv->pConnector,1975 pDrv->MicIn.pStrmIn, fRun);1976 break;1977 }1978 # endif1979 case 4: /** @todo Use a variable here. Later. */1980 {1981 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)1982 pDrv->pConnector->pfnEnableOut(pDrv->pConnector,1983 pDrv->Out.pStrmOut, fRun);1984 break;1985 }1986 default:1987 AssertMsgFailed(("Changing RUN bit on non-attached stream, register %RU32\n", iReg));1988 break;1989 2119 } 1990 2120 } 1991 2121 1992 2122 if (!fInRun && !fRun) 1993 hdaStreamInit(pThis, pStrmSt, u8Strm); 1994 1995 #else /* !IN_RING3 */ 1996 return VINF_IOM_R3_MMIO_WRITE; 2123 hdaStreamInit(pThis, pStrmSt, pStrmSt->u8SD); 1997 2124 #endif /* IN_RING3 */ 1998 2125 } 1999 2126 2000 return hdaRegWriteU24(pThis, iReg, u32Value); 2127 #ifdef IN_RING3 2128 rc2 = hdaRegWriteU24(pThis, iReg, u32Value); 2129 AssertRC(rc2); 2130 2131 hdaRegWriteSDUnlock(pStrmSt); 2132 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 2133 #else 2134 return VINF_IOM_R3_MMIO_WRITE; 2135 #endif 2001 2136 } 2002 2137 2003 2138 static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2004 2139 { 2005 uint32_t v = HDA_REG_IND(pThis, iReg); 2006 v &= ~(u32Value & v); 2140 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2141 return VINF_SUCCESS; 2142 2143 uint32_t v = HDA_REG_IND(pThis, iReg); 2144 v &= ~(u32Value & v); 2007 2145 HDA_REG_IND(pThis, iReg) = v; 2146 2008 2147 hdaProcessInterrupt(pThis); 2009 2148 return VINF_SUCCESS; … … 2012 2151 static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2013 2152 { 2014 if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value)) 2153 #ifdef IN_RING3 2154 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2015 2155 return VINF_SUCCESS; 2016 2156 2017 int rc = hdaRegWriteU16(pThis, iReg, u32Value); 2018 if (RT_SUCCESS(rc)) 2019 { 2020 uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, LVI, iReg); 2021 2022 PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm); 2023 if (pStrmSt) 2024 { 2025 pStrmSt->u16LVI = u32Value; 2026 2027 /* Reset BDLE state. */ 2028 RT_ZERO(pStrmSt->State.BDLE); 2029 pStrmSt->State.uCurBDLE = 0; 2030 } 2031 2032 LogFlowFunc(("[SD%RU8]: CBL=%RU32\n", u8Strm, u32Value)); 2033 } 2034 else 2035 AssertRCReturn(rc, VINF_SUCCESS); 2036 2037 return rc; 2157 PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, LVI, iReg)); 2158 if (!pStrmSt) 2159 { 2160 LogFunc(("[SD%RU8]: Warning: Changing SDLVI on non-attached stream (0x%x)\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value)); 2161 return hdaRegWriteU16(pThis, iReg, u32Value); 2162 } 2163 2164 int rc2 = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value); 2165 AssertRC(rc2); 2166 2167 /** @todo Validate LVI. */ 2168 pStrmSt->u16LVI = u32Value; 2169 2170 /* Reset BDLE state. */ 2171 RT_ZERO(pStrmSt->State.BDLE); 2172 pStrmSt->State.uCurBDLE = 0; 2173 2174 rc2 = hdaRegWriteU16(pThis, iReg, u32Value); 2175 AssertRC(rc2); 2176 2177 LogFlowFunc(("[SD%RU8]: LVI=%RU32\n", pStrmSt->u8SD, u32Value)); 2178 hdaRegWriteSDUnlock(pStrmSt); 2179 2180 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 2181 #else /* !IN_RING3 */ 2182 return VINF_IOM_R3_MMIO_WRITE; 2183 #endif /* IN_RING3 */ 2038 2184 } 2039 2185 2040 2186 static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2041 2187 { 2188 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2189 return VINF_SUCCESS; 2190 2042 2191 switch (u32Value) 2043 2192 { … … 2059 2208 static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2060 2209 { 2210 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2211 return VINF_SUCCESS; 2212 2061 2213 /** @todo Only allow updating FIFOS if RUN bit is 0? */ 2062 2214 uint32_t u32FIFOS = 0; 2063 2215 2064 switch (iReg)2065 {2066 /* SDInFIFOS is RO, n=0-3. */2067 case HDA_ REG_SD0FIFOS:2068 case HDA_ REG_SD1FIFOS:2069 case HDA_ REG_SD2FIFOS:2070 case HDA_ REG_SD3FIFOS:2071 {2072 LogFunc(("Guest tries to change R/O value of FIFO size of input stream, ignoring\n"));2216 /** @todo Check if this is a SDI and deny writes to this. */ 2217 switch(u32Value) 2218 { 2219 case HDA_SDONFIFO_16B: 2220 case HDA_SDONFIFO_32B: 2221 case HDA_SDONFIFO_64B: 2222 case HDA_SDONFIFO_128B: 2223 case HDA_SDONFIFO_192B: 2224 u32FIFOS = u32Value; 2073 2225 break; 2074 } 2075 case HDA_REG_SD4FIFOS: 2076 case HDA_REG_SD5FIFOS: 2077 case HDA_REG_SD6FIFOS: 2078 case HDA_REG_SD7FIFOS: 2079 { 2080 switch(u32Value) 2081 { 2082 case HDA_SDONFIFO_16B: 2083 case HDA_SDONFIFO_32B: 2084 case HDA_SDONFIFO_64B: 2085 case HDA_SDONFIFO_128B: 2086 case HDA_SDONFIFO_192B: 2087 u32FIFOS = u32Value; 2088 break; 2089 2090 case HDA_SDONFIFO_256B: /** @todo r=andy Investigate this. */ 2091 LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n")); 2092 /* Fall through is intentional. */ 2093 default: 2094 u32FIFOS = HDA_SDONFIFO_192B; 2095 break; 2096 } 2097 2226 2227 case HDA_SDONFIFO_256B: /** @todo r=andy Investigate this. */ 2228 LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n")); 2229 /* Fall through is intentional. */ 2230 default: 2231 u32FIFOS = HDA_SDONFIFO_192B; 2098 2232 break; 2099 }2100 default:2101 {2102 AssertMsgFailed(("Something weird happened with register lookup routine\n"));2103 break;2104 }2105 2233 } 2106 2234 2107 2235 if (u32FIFOS) 2108 2236 { 2109 LogFunc(("[SD%RU8]: Updating FIFOS to %RU32 bytes\n", 0, hdaSDFIFOSToBytes(u32FIFOS))); 2237 LogFunc(("[SD%RU8]: Updating FIFOS to %RU32 bytes\n", 2238 HDA_SD_NUM_FROM_REG(pThis, FIFOS, iReg), hdaSDFIFOSToBytes(u32FIFOS))); 2110 2239 /** @todo Update internal stream state with new FIFOS. */ 2111 2240 … … 2158 2287 } 2159 2288 2160 PDMAUDIOFMT enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */ 2289 PDMAUDIOFMT enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */ 2290 uint8_t cSampleBits = 16; 2161 2291 switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)) 2162 2292 { 2163 2293 case 0: 2164 LogFunc(("Requested 8-bit\n"));2165 enmFmt = AUD_FMT_S8;2294 enmFmt = AUD_FMT_S8; 2295 cSampleBits = 8; 2166 2296 break; 2167 2297 case 1: 2168 LogFunc(("Requested 16-bit\n")); 2169 enmFmt = AUD_FMT_S16; 2298 enmFmt = AUD_FMT_S16; 2170 2299 break; 2171 2300 case 2: 2172 LogFunc(("Requested 20-bit\n"));2301 cSampleBits = 20; 2173 2302 break; 2174 2303 case 3: 2175 LogFunc(("Requested 24-bit\n"));2304 cSampleBits = 24; 2176 2305 break; 2177 2306 case 4: 2178 LogFunc(("Requested 32-bit\n"));2179 enmFmt = AUD_FMT_S32;2307 enmFmt = AUD_FMT_S32; 2308 cSampleBits = 32; 2180 2309 break; 2181 2310 default: 2182 AssertMsgFailed(("Unsupported bits shift%x\n",2311 AssertMsgFailed(("Unsupported bits per sample %x\n", 2183 2312 EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))); 2184 2313 rc = VERR_NOT_SUPPORTED; … … 2195 2324 2196 2325 # undef EXTRACT_VALUE 2197 2198 LogFlowFuncLeaveRC(rc);2199 2326 return rc; 2200 2327 } … … 2204 2331 { 2205 2332 #ifdef IN_RING3 2206 # ifdef VBOX_WITH_HDA_CODEC_EMU2207 /* No reason to re-open stream with same settings. */2208 if (u32Value == HDA_REG_IND(pThis, iReg))2209 return VINF_SUCCESS;2210 2211 2333 PDMAUDIOSTREAMCFG strmCfg; 2212 2334 int rc = hdaSDFMTToStrmCfg(u32Value, &strmCfg); … … 2214 2336 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 2215 2337 2216 uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, FMT, iReg); 2217 2218 PHDADRIVER pDrv; 2219 switch (iReg) 2220 { 2221 case HDA_REG_SD0FMT: 2222 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2223 rc = hdaCodecOpenStream(pThis->pCodec, PI_INDEX, &strmCfg); 2224 break; 2225 # ifdef VBOX_WITH_HDA_MIC_IN 2226 case HDA_REG_SD2FMT: 2227 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2228 rc = hdaCodecOpenStream(pThis->pCodec, MC_INDEX, &strmCfg); 2229 break; 2230 # endif 2231 case HDA_REG_SD4FMT: 2232 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2233 rc = hdaCodecOpenStream(pThis->pCodec, PO_INDEX, &strmCfg); 2234 break; 2235 default: 2236 LogFunc(("Warning: Changing SDFMT on non-attached stream with ID=%RU8 (iReg=0x%x)\n", u8Strm, iReg)); 2237 break; 2238 } 2239 2240 /** @todo r=andy rc gets lost; needs fixing. */ 2241 return hdaRegWriteU16(pThis, iReg, u32Value); 2242 # else /* !VBOX_WITH_HDA_CODEC_EMU */ 2243 return hdaRegWriteU16(pThis, iReg, u32Value); 2244 # endif 2338 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2339 return VINF_SUCCESS; 2340 2341 PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, HDA_SD_NUM_FROM_REG(pThis, FMT, iReg)); 2342 if (!pStrmSt) 2343 { 2344 LogFunc(("[SD%RU8]: Warning: Changing SDFMT on non-attached stream (0x%x)\n", 2345 HDA_SD_NUM_FROM_REG(pThis, FMT, iReg), u32Value)); 2346 return hdaRegWriteU16(pThis, iReg, u32Value); 2347 } 2348 2349 rc = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value); 2350 AssertRC(rc); 2351 2352 LogFlowFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, enmFmt=%RU32\n", 2353 pStrmSt->u8SD, strmCfg.uHz, strmCfg.cChannels, strmCfg.enmFormat)); 2354 2355 PDMAUDIOMIXERCTL enmMixerCtl; 2356 #ifdef VBOX_WITH_HDA_51_SURROUND 2357 # error "Implement me!" 2358 #endif 2359 2360 enmMixerCtl = PDMAUDIOMIXERCTL_FRONT; 2361 strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 2362 2363 if (RT_SUCCESS(rc)) 2364 { 2365 PHDADRIVER pDrv; 2366 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2367 { 2368 int rc2 = hdaCodecRemoveStream(pThis->pCodec, enmMixerCtl); 2369 if (RT_SUCCESS(rc2)) 2370 rc2 = hdaCodecAddStream(pThis->pCodec, enmMixerCtl, &strmCfg); 2371 2372 if ( RT_FAILURE(rc2) 2373 && (pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY)) /* We only care about primary drivers here, the rest may fail. */ 2374 { 2375 if (RT_SUCCESS(rc)) 2376 rc = rc2; 2377 /* Keep going. */ 2378 } 2379 } 2380 2381 /* If (re-)opening the stream by the codec above failed, don't write the new 2382 * format to the register so that the guest is aware it didn't work. */ 2383 if (RT_SUCCESS(rc)) 2384 { 2385 rc = hdaRegWriteU16(pThis, iReg, u32Value); 2386 AssertRC(rc); 2387 } 2388 else 2389 LogFunc(("[SD%RU8]: (Re-)Opening stream failed with rc=%Rrc\n", pStrmSt->u8SD, rc)); 2390 2391 hdaRegWriteSDUnlock(pStrmSt); 2392 } 2393 2394 return VINF_SUCCESS; /* Never return failure. */ 2245 2395 #else /* !IN_RING3 */ 2246 2396 return VINF_IOM_R3_MMIO_WRITE; … … 2251 2401 DECLINLINE(int) hdaRegWriteSDBDPX(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value, uint8_t u8Strm) 2252 2402 { 2253 if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value)) 2403 #ifdef IN_RING3 2404 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2254 2405 return VINF_SUCCESS; 2255 2406 2256 int rc = hdaRegWriteU32(pThis, iReg, u32Value); 2257 if (RT_SUCCESS(rc)) 2258 { 2259 PHDASTREAM pStrmSt = hdaStreamFromID(pThis, u8Strm); 2260 if (pStrmSt) 2261 { 2262 pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm), 2263 HDA_STREAM_REG(pThis, BDPU, u8Strm)); 2264 /* Reset BDLE state. */ 2265 RT_ZERO(pStrmSt->State.BDLE); 2266 pStrmSt->State.uCurBDLE = 0; 2267 } 2268 } 2269 else 2270 AssertRCReturn(rc, VINF_SUCCESS); 2271 2272 return rc; 2407 PHDASTREAM pStrmSt = hdaStreamFromSD(pThis, u8Strm); 2408 if (!pStrmSt) 2409 { 2410 LogFunc(("[SD%RU8]: Warning: Changing SDBPL/SDBPU on non-attached stream (0x%x)\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value)); 2411 return hdaRegWriteU32(pThis, iReg, u32Value); 2412 } 2413 2414 int rc2 = hdaRegWriteSDLock(pThis, pStrmSt, iReg, u32Value); 2415 AssertRC(rc2); 2416 2417 rc2 = hdaRegWriteU32(pThis, iReg, u32Value); 2418 AssertRC(rc2); 2419 2420 /* Update BDL base. */ 2421 pStrmSt->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm), 2422 HDA_STREAM_REG(pThis, BDPU, u8Strm)); 2423 /* Reset BDLE state. */ 2424 RT_ZERO(pStrmSt->State.BDLE); 2425 pStrmSt->State.uCurBDLE = 0; 2426 2427 LogFlowFunc(("[SD%RU8]: BDLBase=0x%x\n", pStrmSt->u8SD, pStrmSt->u64BDLBase)); 2428 hdaRegWriteSDUnlock(pStrmSt); 2429 2430 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ 2431 #else /* !IN_RING3 */ 2432 return VINF_IOM_R3_MMIO_WRITE; 2433 #endif /* IN_RING3 */ 2273 2434 } 2274 2435 … … 2283 2444 } 2284 2445 2446 #ifdef IN_RING3 2285 2447 /** 2286 * Checks whether a write to a specific SDnXXX register is allowed or not.2448 * XXX 2287 2449 * 2288 2450 * @return bool Returns @true if write is allowed, @false if not. … … 2291 2453 * @param u32Value Value to write. 2292 2454 */ 2293 inline bool hdaRegWriteSDIsAllowed(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2294 { 2455 DECLINLINE(int) hdaRegWriteSDLock(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t iReg, uint32_t u32Value) 2456 { 2457 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2458 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 2459 2460 #ifdef VBOX_STRICT 2295 2461 /* Check if the SD's RUN bit is set. */ 2296 bool fIsRunning = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 2462 uint32_t u32SDCTL = HDA_STREAM_REG(pThis, CTL, pStrmSt->u8SD); 2463 bool fIsRunning = RT_BOOL(u32SDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 2297 2464 if (fIsRunning) 2298 2465 { 2299 #ifdef VBOX_STRICT 2300 AssertMsgFailed(("[SD%RU8]: Cannot write to register 0x%x (0x%x) when RUN bit is set\n", 2301 HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), iReg, u32Value)); 2302 #endif 2303 return false; 2304 } 2305 2306 return true; 2307 } 2466 LogFlowFunc(("[SD%RU8]: Warning: Cannot write to register 0x%x (0x%x) when RUN bit is set (%R[sdctl])\n", 2467 pStrmSt->u8SD, iReg, u32Value, u32SDCTL)); 2468 return VERR_ACCESS_DENIED; 2469 } 2470 #endif 2471 2472 return RTSemMutexRequest(pStrmSt->State.hMtx, RT_INDEFINITE_WAIT); 2473 } 2474 2475 DECLINLINE(void) hdaRegWriteSDUnlock(PHDASTREAM pStrmSt) 2476 { 2477 AssertPtrReturnVoid(pStrmSt); 2478 2479 int rc2 = RTSemMutexRelease(pStrmSt->State.hMtx); 2480 AssertRC(rc2); 2481 } 2482 #endif /* IN_RING3 */ 2308 2483 2309 2484 static int hdaRegReadIRS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 2310 2485 { 2311 int rc = VINF_SUCCESS;2312 2486 /* regarding 3.4.3 we should mark IRS as busy in case CORB is active */ 2313 2487 if ( HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP) 2314 2488 || HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA)) 2489 { 2315 2490 HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, ICB); /* busy */ 2316 2317 rc = hdaRegReadU32(pThis, iReg, pu32Value); 2318 return rc;2491 } 2492 2493 return hdaRegReadU32(pThis, iReg, pu32Value); 2319 2494 } 2320 2495 … … 2364 2539 return rc; 2365 2540 } 2541 2366 2542 /* 2367 2543 * Once the guest read the response, it should clean the IRV bit of the IRS register. … … 2376 2552 { 2377 2553 if (u32Value & HDA_REG_FIELD_FLAG_MASK(RIRBWP, RST)) 2378 {2379 2554 HDA_REG(pThis, RIRBWP) = 0; 2380 } 2381 /* The remaining bits are O, see 6.2.22 */2555 2556 /* The remaining bits are O, see 6.2.22. */ 2382 2557 return VINF_SUCCESS; 2383 2558 } … … 2532 2707 PHDABDLE pBDLE = &pStrmSt->State.BDLE; 2533 2708 2534 uint32_t cbFree = pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm);2709 uint32_t cbFree = pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD); 2535 2710 if (cbFree) 2536 2711 { … … 2557 2732 } 2558 2733 2559 LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, cbFree=%RU32, %R[bdle]\n", pStrmSt->u8S trm,2560 pStrmSt->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm), cbFree, pBDLE));2734 LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, cbFree=%RU32, %R[bdle]\n", pStrmSt->u8SD, 2735 pStrmSt->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD), cbFree, pBDLE)); 2561 2736 return cbFree; 2562 2737 } … … 2602 2777 2603 2778 PHDABDLE pBDLE = &pStrmSt->State.BDLE; 2604 uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm);2779 uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD); 2605 2780 2606 2781 /* Did we reach the CBL (Cyclic Buffer List) limit? */ … … 2616 2791 2617 2792 LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32, fCBLLimitReached=%RTbool, fNeedsNextBDLE=%RTbool, %R[bdle]\n", 2618 pStrmSt->u8S trm, u32LPIB, pStrmSt->u32CBL, fCBLLimitReached, fNeedsNextBDLE, pBDLE));2793 pStrmSt->u8SD, u32LPIB, pStrmSt->u32CBL, fCBLLimitReached, fNeedsNextBDLE, pBDLE)); 2619 2794 2620 2795 if (fCBLLimitReached) … … 2633 2808 AssertPtrReturnVoid(pStrmSt); 2634 2809 2635 LogFlowFunc(("[SD%RU8]: cbInc=%RU32\n", pStrmSt->u8S trm, cbInc));2810 LogFlowFunc(("[SD%RU8]: cbInc=%RU32\n", pStrmSt->u8SD, cbInc)); 2636 2811 2637 2812 Assert(cbInc <= pStrmSt->u16FIFOS); … … 2646 2821 if (pBDLE->State.cbBelowFIFOW == 0) /* Did we hit (or exceed) the watermark? */ 2647 2822 { 2648 const uint32_t u32LPIB = RT_MIN(HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm) + cbInc,2823 const uint32_t u32LPIB = RT_MIN(HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD) + cbInc, 2649 2824 pStrmSt->u32CBL); 2650 2825 2651 2826 LogFlowFunc(("[SD%RU8]: LPIB: %RU32 -> %RU32, CBL=%RU32\n", 2652 pStrmSt->u8S trm,2653 HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm), HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) + cbInc,2827 pStrmSt->u8SD, 2828 HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD), HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD) + cbInc, 2654 2829 pStrmSt->u32CBL)); 2655 2830 … … 2666 2841 2667 2842 PHDABDLE pBDLE = &pStrmSt->State.BDLE; 2668 const uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8S trm);2843 const uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8SD); 2669 2844 2670 2845 if ( pBDLE->State.u32BufOff >= pBDLE->u32BufSize … … 2690 2865 * but in general sound quality gets worse. 2691 2866 */ 2692 HDA_STREAM_REG(pThis, STS, pStrmSt->u8S trm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);2867 HDA_STREAM_REG(pThis, STS, pStrmSt->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 2693 2868 2694 2869 /* … … 2696 2871 * we need to generate an interrupt. 2697 2872 */ 2698 if (HDA_STREAM_REG(pThis, CTL, pStrmSt->u8S trm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))2873 if (HDA_STREAM_REG(pThis, CTL, pStrmSt->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)) 2699 2874 hdaProcessInterrupt(pThis); 2700 2875 } … … 2704 2879 2705 2880 LogFlowFunc(("[SD%RU8]: u32LPIB=%RU32, CBL=%RU32, %R[bdle] => %s\n", 2706 pStrmSt->u8S trm, u32LPIB, pStrmSt->u32CBL, pBDLE, fIsComplete ? "COMPLETE" : "INCOMPLETE"));2881 pStrmSt->u8SD, u32LPIB, pStrmSt->u32CBL, pBDLE, fIsComplete ? "COMPLETE" : "INCOMPLETE")); 2707 2882 2708 2883 return fIsComplete; … … 2714 2889 * but "reports bytes" when all conditions are met (FIFOW). 2715 2890 */ 2716 static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStrmSt, PAUDMIXSINK pSink,uint32_t cbMax, uint32_t *pcbRead)2891 static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbMax, uint32_t *pcbRead) 2717 2892 { 2718 2893 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2719 2894 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 2720 AssertPtrReturn(pSink, VERR_INVALID_POINTER);2721 2895 /* pcbRead is optional. */ 2722 2896 … … 2736 2910 else 2737 2911 { 2738 rc = AudioMixerProcessSinkIn(pS ink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbBuf, &cbRead);2912 rc = AudioMixerProcessSinkIn(pStrmSt->pSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbBuf, &cbRead); 2739 2913 if (RT_SUCCESS(rc)) 2740 2914 { … … 2814 2988 AssertRC(rc); 2815 2989 2990 #if 0 2991 RTFILE fh; 2992 RTFileOpen(&fh, "c:\\temp\\hdaWriteAudio.pcm", 2993 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 2994 RTFileWrite(fh, pBDLE->State.au8FIFO + pBDLE->State.cbBelowFIFOW, cbData, NULL); 2995 RTFileClose(fh); 2996 #endif 2997 2816 2998 #ifdef VBOX_WITH_STATISTICS 2817 2999 STAM_COUNTER_ADD(&pThis->StatBytesRead, cbData); … … 2829 3011 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2830 3012 { 2831 if (pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv-> Out.pStrmOut))3013 if (pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Front.pGstStrm)) 2832 3014 { 3015 #ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT 3016 /** @todo Needs more hacking first. */ 3017 # if 0 3018 static int16_t restBuf = 0; 3019 static size_t cbRestOff = 0; 3020 3021 uint8_t temp[HDA_SDONFIFO_256B + 1]; 3022 3023 uint8_t *pu8Src = &pBDLE->State.au8FIFO[0]; 3024 uint8_t *pu8Dst = &temp[0]; 3025 3026 size_t cbSample = sizeof(int16_t) * 2; 3027 3028 size_t cbProc = 0; 3029 size_t cbToSkip = 5 * cbSample; 3030 size_t cbSkipSize = cbToSkip; 3031 size_t cbDstSize = 0; 3032 3033 while (cbProc < cbToWrite) 3034 { 3035 memcpy(pu8Dst, pu8Src, cbSample); 3036 3037 cbSkipSize = RT_MIN(cbToSkip, cbToWrite - cbProc); 3038 3039 pu8Src += 10; 3040 cbProc += cbSkipSize; 3041 3042 pu8Dst += 4; 3043 cbDstSize += cbSample; 3044 } 3045 3046 /* Sanity. */ 3047 AssertMsg(((cbDstSize * 8 /* Bit */) % 16) == 0, ("ASDF\n")); 3048 3049 LogFlowFunc(("cbRest=%zu, cbToWrite=%zu, cbProc=%zu, cbDstSize=%zu\n", 3050 0, cbToWrite, cbProc, cbDstSize)); 3051 2833 3052 rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Out.pStrmOut, 3053 temp, cbDstSize, &cbWrittenToStream); 3054 # if 1 3055 RTFILE fh; 3056 RTFileOpen(&fh, "/tmp/hdaWriteAudio.pcm", 3057 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 3058 RTFileWrite(fh, temp, cbDstSize, NULL); 3059 RTFileClose(fh); 3060 # endif 3061 3062 # else 3063 int16_t *pvStart; 3064 size_t cbAcqWrite; 3065 RTCircBufAcquireWriteBlock(pThis->pCircBuf, cbToWrite, (void **)&pvStart, &cbAcqWrite); 3066 3067 uint8_t cChannels = 1; 3068 size_t cbSample = sizeof(int16_t); 3069 3070 int16_t *pi16Src = (int16_t *)&pBDLE->State.au8FIFO[0]; 3071 int16_t *pi16Dst = pvStart; 3072 3073 size_t cbProcSrc = 0; 3074 size_t cbProcDst = 0; 3075 3076 while (cbProcSrc < cbAcqWrite) 3077 { 3078 memcpy(pi16Dst, pi16Src, cbSample); 3079 3080 pi16Src += 6 * cChannels; 3081 pi16Dst += cChannels; 3082 3083 cbProcSrc += RT_MIN(cbAcqWrite - cbProcSrc, 6 * cbSample); 3084 cbProcDst += cbSample; 3085 3086 Assert(cbProcSrc <= cbAcqWrite); 3087 size_t cbLeft = cbAcqWrite - cbProcSrc; 3088 LogFlowFunc(("cbProcSrc=%zu, cbProcDst=%zu, cbLeft=%zu\n", cbProcSrc, cbProcDst, cbLeft)); 3089 if ( cbLeft 3090 && cbLeft < cChannels) 3091 { 3092 LogFlowFunc(("%zu bytes left ...\n", cbAcqWrite - cbProcSrc)); 3093 break; 3094 } 3095 } 3096 3097 RTCircBufReleaseWriteBlock(pThis->pCircBuf, cbProcDst); 3098 3099 LogFlowFunc(("cbAcqWrite=%zu, cbToWrite=%zu, cbProcSrc=%zu, cbProcDst=%zu\n", 3100 cbAcqWrite, cbToWrite, cbProcSrc, cbProcDst)); 3101 3102 size_t cbAcqRead = 0; 3103 RTCircBufAcquireReadBlock(pThis->pCircBuf, _4K, (void **)&pvStart, &cbAcqRead); 3104 # if 1 3105 RTFILE fh; 3106 RTFileOpen(&fh, "/tmp/hdaWriteAudio.pcm", 3107 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 3108 RTFileWrite(fh, pvStart, cbAcqRead, NULL); 3109 RTFileClose(fh); 3110 # endif 3111 rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Front.pGstStrm, 3112 pvStart, cbAcqRead, &cbWrittenToStream); 3113 3114 /** @todo Add support for writing to center/LFE + rear. */ 3115 3116 RTCircBufReleaseReadBlock(pThis->pCircBuf, cbAcqRead); 3117 # endif 3118 3119 #else /* !VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT */ 3120 rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Front.pGstStrm, 2834 3121 pBDLE->State.au8FIFO, cbToWrite, &cbWrittenToStream); 3122 #endif /* VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT */ 2835 3123 if (RT_SUCCESS(rc2)) 2836 3124 { … … 2891 3179 } 2892 3180 2893 2894 static DECLCALLBACK(void) hdaCloseIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource) 2895 { 2896 NOREF(pThis); 2897 NOREF(enmRecSource); 2898 LogFlowFuncEnter(); 2899 } 2900 2901 static DECLCALLBACK(void) hdaCloseOut(PHDASTATE pThis) 2902 { 2903 NOREF(pThis); 2904 LogFlowFuncEnter(); 2905 } 2906 2907 static DECLCALLBACK(int) hdaOpenIn(PHDASTATE pThis, 2908 const char *pszName, PDMAUDIORECSOURCE enmRecSource, 2909 PPDMAUDIOSTREAMCFG pCfg) 3181 /** 3182 * Retrieves a corresponding sink for a given mixer control. 3183 * Returns NULL if no sink is found. 3184 * 3185 * @return PAUDMIXSINK 3186 * @param pThis HDA state. 3187 * @param enmMixerCtl Mixer control to get the corresponding sink for. 3188 */ 3189 static PAUDMIXSINK hdaMixerControlToSink(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl) 2910 3190 { 2911 3191 PAUDMIXSINK pSink; 2912 3192 2913 switch (enmRecSource) 2914 { 2915 # ifdef VBOX_WITH_HDA_MIC_IN 2916 case PDMAUDIORECSOURCE_MIC: 3193 switch (enmMixerCtl) 3194 { 3195 case PDMAUDIOMIXERCTL_VOLUME: 3196 /* Fall through is intentional. */ 3197 case PDMAUDIOMIXERCTL_FRONT: 3198 pSink = pThis->pSinkFront; 3199 break; 3200 #ifdef VBOX_WITH_HDA_51_SURROUND 3201 case PDMAUDIOMIXERCTL_CENTER_LFE: 3202 pSink = pThis->pSinkCenterLFE; 3203 break; 3204 case PDMAUDIOMIXERCTL_REAR: 3205 pSink = pThis->pSinkRear; 3206 break; 3207 #endif 3208 case PDMAUDIOMIXERCTL_LINE_IN: 3209 pSink = pThis->pSinkLineIn; 3210 break; 3211 #ifdef VBOX_WITH_HDA_MIC_IN 3212 case PDMAUDIOMIXERCTL_MIC_IN: 2917 3213 pSink = pThis->pSinkMicIn; 2918 3214 break; 2919 # endif 2920 case PDMAUDIORECSOURCE_LINE_IN: 2921 pSink = pThis->pSinkLineIn; 3215 #endif 3216 default: 3217 pSink = NULL; 3218 AssertMsgFailed(("Unhandled mixer control\n")); 2922 3219 break; 2923 default: 2924 AssertMsgFailed(("Audio source %ld not supported\n", enmRecSource)); 2925 return VERR_NOT_SUPPORTED; 2926 } 3220 } 3221 3222 return pSink; 3223 } 3224 3225 static DECLCALLBACK(int) hdaMixerAddStreamIn(PHDASTATE pThis, PAUDMIXSINK pSink, PPDMAUDIOSTREAMCFG pCfg) 3226 { 3227 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3228 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 3229 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 3230 3231 AssertReturn(pCfg->enmDir == PDMAUDIODIR_IN, VERR_INVALID_PARAMETER); 3232 3233 LogFunc(("Sink=%s, Source=%ld\n", pSink->pszName, pCfg->DestSource.Source)); 2927 3234 2928 3235 int rc = VINF_SUCCESS; 2929 char *pszDesc;2930 3236 2931 3237 PHDADRIVER pDrv; 2932 3238 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2933 3239 { 2934 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s", pDrv->uLUN, pszName) <= 0) 3240 char *pszDesc; 3241 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s", pDrv->uLUN, pCfg->pszName) <= 0) 2935 3242 { 2936 3243 rc = VERR_NO_MEMORY; … … 2938 3245 } 2939 3246 2940 rc = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, enmRecSource, pCfg, &pDrv->LineIn.pStrmIn);2941 LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));2942 if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */3247 int rc2 = VINF_SUCCESS; 3248 PHDAINPUTSTREAM pStream; 3249 switch (pCfg->DestSource.Source) 2943 3250 { 2944 AudioMixerRemoveStream(pSink, pDrv->LineIn.phStrmIn); 2945 rc = AudioMixerAddStreamIn(pSink, 2946 pDrv->pConnector, pDrv->LineIn.pStrmIn, 2947 0 /* uFlags */, &pDrv->LineIn.phStrmIn); 3251 case PDMAUDIORECSOURCE_LINE: 3252 pStream = &pDrv->LineIn; 3253 break; 3254 #ifdef VBOX_WITH_HDA_MIC_IN 3255 case PDMAUDIORECSOURCE_MIC: 3256 pStream = &pDrv->MicIn; 3257 break; 3258 #endif 3259 default: 3260 rc2 = VERR_NOT_SUPPORTED; 3261 break; 2948 3262 } 3263 3264 if (RT_SUCCESS(rc2)) 3265 { 3266 PPDMAUDIOGSTSTRMIN pGstStrm; 3267 PAUDMIXSTREAM pMixStrm; 3268 3269 rc2 = pDrv->pConnector->pfnCreateIn(pDrv->pConnector, pszDesc, pCfg, &pGstStrm); 3270 LogFlowFunc(("LUN#%RU8: Created input \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc)); 3271 if (RT_SUCCESS(rc2)) 3272 rc2 = AudioMixerAddStreamIn(pSink, pDrv->pConnector, pGstStrm, 0 /* uFlags */, &pMixStrm); 3273 3274 if (RT_SUCCESS(rc2)) 3275 { 3276 pStream->pGstStrm = pGstStrm; 3277 pStream->pMixStrm = pMixStrm; 3278 } 3279 } 3280 3281 if (RT_SUCCESS(rc)) 3282 rc = rc2; 2949 3283 2950 3284 RTStrFree(pszDesc); … … 2955 3289 } 2956 3290 2957 static DECLCALLBACK(int) hdaOpenOut(PHDASTATE pThis, 2958 const char *pszName, PPDMAUDIOSTREAMCFG pCfg) 2959 { 3291 static DECLCALLBACK(int) hdaMixerAddStreamOut(PHDASTATE pThis, PAUDMIXSINK pSink, PPDMAUDIOSTREAMCFG pCfg) 3292 { 3293 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3294 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 3295 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 3296 3297 AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER); 3298 3299 LogFunc(("Sink=%s, Dest=%ld\n", pSink->pszName, pCfg->DestSource.Dest)); 3300 2960 3301 int rc = VINF_SUCCESS; 2961 char *pszDesc;2962 3302 2963 3303 PHDADRIVER pDrv; 2964 3304 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 2965 3305 { 3306 char *pszDesc; 2966 3307 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s (%RU32Hz, %RU8 %s)", 2967 pDrv->uLUN, p szName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel") <= 0)3308 pDrv->uLUN, pCfg->pszName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel") <= 0) 2968 3309 { 2969 3310 rc = VERR_NO_MEMORY; … … 2971 3312 } 2972 3313 2973 rc = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pDrv->Out.pStrmOut);2974 LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc));2975 if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */3314 int rc2 = VINF_SUCCESS; 3315 PHDAOUTPUTSTREAM pStream; 3316 switch (pCfg->DestSource.Dest) 2976 3317 { 2977 AudioMixerRemoveStream(pThis->pSinkOutput, pDrv->Out.phStrmOut); 2978 rc = AudioMixerAddStreamOut(pThis->pSinkOutput, 2979 pDrv->pConnector, pDrv->Out.pStrmOut, 2980 0 /* uFlags */, &pDrv->Out.phStrmOut); 3318 case PDMAUDIOPLAYBACKDEST_FRONT: 3319 pStream = &pDrv->Front; 3320 break; 3321 #ifdef VBOX_WITH_HDA_51_SURROUND 3322 case PDMAUDIOPLAYBACKDEST_CENTER_LFE: 3323 pStream = &pDrv->CenterLFE; 3324 break; 3325 case PDMAUDIOPLAYBACKDEST_REAR: 3326 pStream = &pDrv->Rear; 3327 break; 3328 #endif 3329 default: 3330 rc2 = VERR_NOT_SUPPORTED; 3331 break; 2981 3332 } 3333 3334 if (RT_SUCCESS(rc2)) 3335 { 3336 PPDMAUDIOGSTSTRMOUT pGstStrm; 3337 PAUDMIXSTREAM pMixStrm; 3338 3339 rc2 = pDrv->pConnector->pfnCreateOut(pDrv->pConnector, pszDesc, pCfg, &pGstStrm); 3340 LogFlowFunc(("LUN#%RU8: Created output \"%s\", with rc=%Rrc\n", pDrv->uLUN, pszDesc, rc2)); 3341 if (RT_SUCCESS(rc2)) 3342 rc2 = AudioMixerAddStreamOut(pSink, pDrv->pConnector, pGstStrm, 0 /* uFlags */, &pMixStrm); 3343 3344 if (RT_SUCCESS(rc2)) 3345 { 3346 pStream->pGstStrm = pGstStrm; 3347 pStream->pMixStrm = pMixStrm; 3348 } 3349 } 3350 3351 if (RT_SUCCESS(rc)) 3352 rc = rc2; 2982 3353 2983 3354 RTStrFree(pszDesc); … … 2988 3359 } 2989 3360 2990 static DECLCALLBACK(int) hdaSetVolume(PHDASTATE pThis, ENMSOUNDSOURCE enmSource, 2991 bool fMute, uint8_t uVolLeft, uint8_t uVolRight) 2992 { 2993 int rc = VINF_SUCCESS; 2994 PDMAUDIOVOLUME vol = { fMute, uVolLeft, uVolRight }; 2995 PAUDMIXSINK pSink; 2996 2997 /* Convert the audio source to corresponding sink. */ 2998 switch (enmSource) 2999 { 3000 case PO_INDEX: 3001 pSink = pThis->pSinkOutput; 3002 break; 3003 case PI_INDEX: 3004 pSink = pThis->pSinkLineIn; 3005 break; 3006 case MC_INDEX: 3007 pSink = pThis->pSinkMicIn; 3008 break; 3009 default: 3010 AssertFailedReturn(VERR_INVALID_PARAMETER); 3011 break; 3012 } 3013 3014 /* Set the volume. Codec already converted it to the correct range. */ 3015 AudioMixerSetSinkVolume(pSink, &vol); 3361 /** 3362 * Adds a new audio stream to a specific mixer control. 3363 * Depending on the mixer control the stream then gets assigned to one of the internal 3364 * mixer sinks, which in turn then handle the mixing of all connected streams to that sink. 3365 * 3366 * @return IPRT status code. 3367 * @param pThis HDA state. 3368 * @param enmMixerCtl Mixer control to assign new stream to. 3369 * @param pCfg Stream configuration for the new stream. 3370 */ 3371 static DECLCALLBACK(int) hdaMixerAddStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg) 3372 { 3373 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3374 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 3375 3376 int rc; 3377 3378 PAUDMIXSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl); 3379 if (pSink) 3380 { 3381 if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 3382 { 3383 rc = hdaMixerAddStreamIn(pThis, pSink, pCfg); 3384 } 3385 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT) 3386 { 3387 rc = hdaMixerAddStreamOut(pThis, pSink, pCfg); 3388 } 3389 else 3390 { 3391 rc = VERR_INVALID_PARAMETER; 3392 AssertFailed(); 3393 } 3394 } 3395 else 3396 rc = VERR_NOT_FOUND; 3397 3398 LogFlowFuncLeaveRC(rc); 3399 return rc; 3400 } 3401 3402 /** 3403 * Removes a specified mixer control from the HDA's mixer. 3404 * 3405 * @return IPRT status code. 3406 * @param pThis HDA state. 3407 * @param enmMixerCtl Mixer control to remove. 3408 */ 3409 static DECLCALLBACK(int) hdaMixerRemoveStream(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl) 3410 { 3411 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3412 3413 int rc; 3414 3415 PAUDMIXSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl); 3416 if (pSink) 3417 { 3418 if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 3419 { 3420 /** @todo Remove streams. */ 3421 } 3422 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT) 3423 { 3424 /** @todo Remove streams. */ 3425 } 3426 else 3427 { 3428 rc = VERR_INVALID_PARAMETER; 3429 AssertFailed(); 3430 } 3431 } 3432 else 3433 rc = VERR_NOT_FOUND; 3434 3435 LogFlowFuncLeaveRC(rc); 3436 return rc; 3437 } 3438 3439 /** 3440 * Sets the volume of a specified mixer control. 3441 * 3442 * @return IPRT status code. 3443 * @param pThis HDA State. 3444 * @param enmMixerCtl Mixer control to set volume for. 3445 * @param pVol Pointer to volume data to set. 3446 */ 3447 static DECLCALLBACK(int) hdaMixerSetVolume(PHDASTATE pThis, 3448 PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol) 3449 { 3450 int rc; 3451 3452 PAUDMIXSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl); 3453 if (pSink) 3454 { 3455 /* Set the volume. 3456 * We assume that the codec already converted it to the correct range. */ 3457 rc = AudioMixerSetSinkVolume(pSink, pVol); 3458 } 3459 else 3460 rc = VERR_NOT_FOUND; 3016 3461 3017 3462 LogFlowFuncLeaveRC(rc); … … 3032 3477 uint32_t cbOutMin = UINT32_MAX; 3033 3478 3479 int rc; 3034 3480 PHDADRIVER pDrv; 3035 3481 … … 3044 3490 */ 3045 3491 AssertPtr(pThis->pCodec); 3046 PDMPCMPROPS codecStrmProps; 3047 3048 int rc = DrvAudioStreamCfgToProps(&pThis->pCodec->strmCfg, &codecStrmProps); 3049 AssertRC(rc); 3050 3051 uint32_t cCodecSamplesMin = (int)((2 * cTicksElapsed * pThis->pCodec->strmCfg.uHz + cTicksPerSec) / cTicksPerSec / 2); 3052 uint32_t cbCodecSamplesMin = cCodecSamplesMin << codecStrmProps.cShift; 3492 3493 /* Since the codec always runs at a fixed delivery rate (48 kHz), calculate the sample processing rate based 3494 * on the clock ticks elapsed (the clock itself runs at 24 Mhz). 3495 * A stream itself can have a higher or lower delivery rate, which in turn then results in more or less 3496 * stream samples per frame. */ 3497 uint32_t cCodecSamplesMin = (int)((2 * cTicksElapsed * 48000 /* Hz */ + cTicksPerSec) / cTicksPerSec / 2); 3498 /* We always use 32-bit as containers to make sure all data is being pumped if we need to. */ 3499 uint32_t cbCodecSamplesMin = cCodecSamplesMin << 1; 3053 3500 3054 3501 /* … … 3073 3520 * This is not the optimal solution, but as we have to deal with this on a timer-based approach 3074 3521 * (until we have the audio callbacks) we need to have device' DMA engines running. */ 3075 if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv-> Out.pStrmOut))3522 if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Front.pGstStrm)) 3076 3523 { 3077 3524 /* Use the codec's (fixed) sampling rate. */ … … 3080 3527 } 3081 3528 3082 const bool fIsActiveOut = pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv-> Out.pStrmOut);3529 const bool fIsActiveOut = pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Front.pGstStrm); 3083 3530 if ( RT_FAILURE(rc) 3084 3531 || !fIsActiveOut) 3085 3532 { 3086 uint32_t cSamplesMin = (int)((2 * cTicksElapsed * pDrv-> Out.pStrmOut->Props.uHz + cTicksPerSec) / cTicksPerSec / 2);3087 uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv-> Out.pStrmOut->MixBuf, cSamplesMin);3533 uint32_t cSamplesMin = (int)((2 * cTicksElapsed * pDrv->Front.pGstStrm->Props.uHz + cTicksPerSec) / cTicksPerSec / 2); 3534 uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv->Front.pGstStrm->MixBuf, cSamplesMin); 3088 3535 3089 3536 #ifdef DEBUG_TIMER … … 3104 3551 cbOutMin = 0; 3105 3552 3553 /** @todo Determine the streams to be handled. */ 3554 PHDASTREAM pStrmStIn = &pThis->aStreams[0]; 3555 PHDASTREAM pStrmStOut = &pThis->aStreams[4]; 3556 3106 3557 /* Do the actual device transfers. */ 3107 hdaTransfer(pThis, PO_INDEX, cbOutMin /* cbToProcess */, NULL /* pcbProcessed */);3108 hdaTransfer(pThis, PI_INDEX,cbInMax /* cbToProcess */, NULL /* pcbProcessed */);3558 hdaTransfer(pThis, pStrmStOut, cbOutMin /* cbToProcess */, NULL /* pcbProcessed */); 3559 hdaTransfer(pThis, pStrmStIn, cbInMax /* cbToProcess */, NULL /* pcbProcessed */); 3109 3560 3110 3561 /* Kick the timer again. */ … … 3166 3617 #endif /* VBOX_WITH_AUDIO_CALLBACKS */ 3167 3618 3168 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t cbToProcess, uint32_t *pcbProcessed) 3169 { 3170 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3619 static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbToProcess, uint32_t *pcbProcessed) 3620 { 3621 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3622 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 3171 3623 /* pcbProcessed is optional. */ 3172 3624 … … 3180 3632 } 3181 3633 3182 PHDASTREAM pStrmSt;3183 switch (enmSrc)3184 {3185 case PI_INDEX:3186 {3187 pStrmSt = &pThis->StrmStLineIn;3188 break;3189 }3190 3191 #ifdef VBOX_WITH_HDA_MIC_IN3192 case MC_INDEX:3193 {3194 pStrmSt = &pThis->StrmStMicIn;3195 break;3196 }3197 #endif3198 case PO_INDEX:3199 {3200 pStrmSt = &pThis->StrmStOut;3201 break;3202 }3203 3204 default:3205 {3206 AssertMsgFailed(("Unknown source index %ld\n", enmSrc));3207 return VERR_NOT_SUPPORTED;3208 }3209 }3210 3211 int rc = VINF_SUCCESS;3212 3634 bool fProceed = true; 3635 int rc = RTSemMutexRequest(pStrmSt->State.hMtx, RT_INDEFINITE_WAIT); 3636 if (RT_FAILURE(rc)) 3637 return rc; 3213 3638 3214 3639 /* Stop request received? */ 3215 if ( ASMAtomicReadBool(&pStrmSt->State.fDoStop))3640 if (pStrmSt->State.fDoStop) 3216 3641 { 3217 3642 pStrmSt->State.fActive = false; … … 3223 3648 } 3224 3649 /* Is the stream not in a running state currently? */ 3225 else if (!(HDA_STREAM_REG(pThis, CTL, pStrmSt->u8S trm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)))3650 else if (!(HDA_STREAM_REG(pThis, CTL, pStrmSt->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))) 3226 3651 fProceed = false; 3227 3652 /* Nothing to process? */ … … 3231 3656 if (!fProceed) 3232 3657 { 3658 rc = RTSemMutexRelease(pStrmSt->State.hMtx); 3659 AssertRC(rc); 3660 3233 3661 if (pcbProcessed) 3234 3662 *pcbProcessed = 0; … … 3236 3664 } 3237 3665 3238 LogFlowFunc(("enmSrc=%RU32, cbToProcess=%RU32\n", enmSrc, cbToProcess));3239 3240 3666 /* Sanity checks. */ 3241 Assert(pStrmSt->u8S trm <= 7); /** @todo Use a define for MAX_STREAMS! */3667 Assert(pStrmSt->u8SD <= HDA_MAX_STREAMS); 3242 3668 Assert(pStrmSt->u64BDLBase); 3243 3669 Assert(pStrmSt->u32CBL); 3244 3670 3245 3671 /* State sanity checks. */ 3246 Assert( ASMAtomicReadBool(&pStrmSt->State.fInReset)== false);3672 Assert(pStrmSt->State.fInReset == false); 3247 3673 3248 3674 uint32_t cbProcessedTotal = 0; … … 3253 3679 /* Do we need to fetch the next Buffer Descriptor Entry (BDLE)? */ 3254 3680 if (hdaStreamNeedsNextBDLE(pThis, pStrmSt)) 3255 hdaStreamGetNextBDLE(pThis, pStrmSt);3256 3257 /* Set the FIFORDY bit on the stream while doing the transfer. */3258 HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);3259 3260 uint32_t cbProcessed;3261 switch (enmSrc)3262 3681 { 3263 case PI_INDEX: 3264 rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkLineIn, cbToProcess, &cbProcessed); 3265 break; 3266 case PO_INDEX: 3267 rc = hdaWriteAudio(pThis, pStrmSt, cbToProcess, &cbProcessed); 3268 break; 3269 #ifdef VBOX_WITH_HDA_MIC_IN 3270 case MC_INDEX: 3271 rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkMicIn, cbToProcess, &cbProcessed); 3272 break; 3273 #endif 3274 default: 3275 AssertMsgFailed(("Unsupported source index %ld\n", enmSrc)); 3276 rc = VERR_NOT_SUPPORTED; 3682 rc = hdaStreamGetNextBDLE(pThis, pStrmSt); 3683 if (RT_FAILURE(rc)) 3277 3684 break; 3278 3685 } 3279 3686 3687 /* Set the FIFORDY bit on the stream while doing the transfer. */ 3688 HDA_STREAM_REG(pThis, STS, pStrmSt->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 3689 3690 /* 3691 * The register layout specifies that input streams (SDI) come first, 3692 * followed by the output streams (SDO). So every stream ID below HDA_MAX_SDI 3693 * is an input stream, whereas everything >= HDA_MAX_SDI is an output stream. 3694 */ 3695 uint32_t cbProcessed; 3696 if (pStrmSt->u8SD < HDA_MAX_SDI) 3697 rc = hdaReadAudio (pThis, pStrmSt, cbToProcess, &cbProcessed); 3698 else 3699 rc = hdaWriteAudio(pThis, pStrmSt, cbToProcess, &cbProcessed); 3700 3280 3701 /* Remove the FIFORDY bit again. */ 3281 HDA_STREAM_REG(pThis, STS, pStrmSt->u8S trm) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);3702 HDA_STREAM_REG(pThis, STS, pStrmSt->u8SD) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 3282 3703 3283 3704 if (RT_FAILURE(rc)) … … 3307 3728 *pcbProcessed = cbProcessedTotal; 3308 3729 } 3309 3310 LogFlowFuncLeaveRC(rc); 3730 else 3731 LogFlowFunc(("Failed with %Rrc\n", rc)); 3732 3733 int rc2 = RTSemMutexRelease(pStrmSt->State.hMtx); 3734 if (RT_SUCCESS(rc)) 3735 rc = rc2; 3736 3311 3737 return rc; 3312 3738 } … … 3337 3763 #endif 3338 3764 3339 Log Func(("offReg=%#x cb=%#x\n", offReg, cb));3765 Log3Func(("offReg=%#x cb=%#x\n", offReg, cb)); 3340 3766 Assert(cb == 4); Assert((offReg & 3) == 0); 3341 3767 3342 3768 if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL) 3343 LogFunc((" \tAccess to registers except GCTL is blocked while reset\n"));3769 LogFunc(("Access to registers except GCTL is blocked while reset\n")); 3344 3770 3345 3771 if (idxRegDsc == -1) 3346 LogRel(("HDA: Invalid read access @0x%x (bytes=% d)\n", offReg, cb));3772 LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", offReg, cb)); 3347 3773 3348 3774 if (idxRegDsc != -1) … … 3355 3781 */ 3356 3782 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, (uint32_t *)pv); 3357 Log Func(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));3783 Log3Func(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc)); 3358 3784 } 3359 3785 else … … 3371 3797 3372 3798 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Tmp); 3373 Log Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));3799 Log3Func(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc)); 3374 3800 if (rc != VINF_SUCCESS) 3375 3801 break; … … 3390 3816 { 3391 3817 rc = VINF_IOM_MMIO_UNUSED_FF; 3392 Log Func(("\tHole at %x is accessed for read\n", offReg));3818 Log3Func(("\tHole at %x is accessed for read\n", offReg)); 3393 3819 } 3394 3820 … … 3398 3824 #ifdef LOG_ENABLED 3399 3825 if (cbLog == 4) 3400 Log Func(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));3826 Log3Func(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc)); 3401 3827 else if (cbLog == 2) 3402 Log Func(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));3828 Log3Func(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc)); 3403 3829 else if (cbLog == 1) 3404 Log Func(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));3830 Log3Func(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc)); 3405 3831 #endif 3406 3832 return rc; … … 3421 3847 #endif 3422 3848 int rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32Value); 3423 Log Func(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,3424 g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog));3849 Log3Func(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev, 3850 g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog)); 3425 3851 return rc; 3426 3852 } … … 3464 3890 uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX; 3465 3891 if (idxRegDsc == -1) 3466 Log Func(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));3892 Log3Func(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb)); 3467 3893 else if (cb == 4) 3468 Log Func(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));3894 Log3Func(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3469 3895 else if (cb == 2) 3470 Log Func(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));3896 Log3Func(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3471 3897 else if (cb == 1) 3472 Log Func(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));3898 Log3Func(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3473 3899 3474 3900 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb) 3475 Log Func(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb));3901 Log3Func(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb)); 3476 3902 #endif 3477 3903 … … 3482 3908 { 3483 3909 rc = hdaWriteReg(pThis, idxRegDsc, u64Value, ""); 3484 #ifdef LOG_ENABLED 3485 LogFunc(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX)); 3486 #endif 3910 Log3Func(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX)); 3487 3911 } 3488 3912 /* … … 3504 3928 u64Value <<= cbBefore * 8; 3505 3929 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore]; 3506 Log Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n",3507 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value));3930 Log3Func(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n", 3931 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value)); 3508 3932 } 3509 3933 … … 3520 3944 { 3521 3945 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbReg] & ~g_afMasks[cb]; 3522 Log Func(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n",3523 g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value));3946 Log3Func(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n", 3947 g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value)); 3524 3948 } 3525 3949 uint32_t u32LogOldVal = pThis->au32Regs[idxRegMem]; 3526 3950 rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "*"); 3527 Log Func(("\t%#x -> %#x\n", u32LogOldVal, pThis->au32Regs[idxRegMem]));3951 Log3Func(("\t%#x -> %#x\n", u32LogOldVal, pThis->au32Regs[idxRegMem])); 3528 3952 } 3529 3953 else … … 3615 4039 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3616 4040 3617 LogFlowFunc(("[SD%RU8]\n", pStrm->u8S trm));4041 LogFlowFunc(("[SD%RU8]\n", pStrm->u8SD)); 3618 4042 3619 4043 /* Save stream ID. */ 3620 int rc = SSMR3PutU8(pSSM, pStrm->u8S trm);4044 int rc = SSMR3PutU8(pSSM, pStrm->u8SD); 3621 4045 AssertRCReturn(rc, rc); 3622 Assert(pStrm->u8S trm <= 7); /** @todo Use a define. */4046 Assert(pStrm->u8SD <= HDA_MAX_STREAMS); 3623 4047 3624 4048 rc = SSMR3PutStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /*fFlags*/, g_aSSMStreamStateFields6, NULL); … … 3626 4050 3627 4051 #ifdef DEBUG /* Sanity checks. */ 3628 uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrm->u8S trm),3629 HDA_STREAM_REG(pThis, BDPU, pStrm->u8S trm));3630 uint16_t u16LVI = HDA_STREAM_REG(pThis, LVI, pStrm->u8S trm);3631 uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, pStrm->u8S trm);4052 uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrm->u8SD), 4053 HDA_STREAM_REG(pThis, BDPU, pStrm->u8SD)); 4054 uint16_t u16LVI = HDA_STREAM_REG(pThis, LVI, pStrm->u8SD); 4055 uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, pStrm->u8SD); 3632 4056 3633 4057 hdaBDLEDumpAll(pThis, u64BaseDMA, u16LVI + 1); … … 3680 4104 3681 4105 /* Save MMIO registers. */ 3682 AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= HDA_NREGS_SAVED);3683 4106 SSMR3PutU32(pSSM, RT_ELEMENTS(pThis->au32Regs)); 3684 4107 SSMR3PutMem(pSSM, pThis->au32Regs, sizeof(pThis->au32Regs)); 3685 4108 3686 4109 /* Save number of streams. */ 3687 #ifdef VBOX_WITH_HDA_MIC_IN 3688 SSMR3PutU32(pSSM, 3); 3689 #else 3690 SSMR3PutU32(pSSM, 2); 3691 #endif 4110 SSMR3PutU32(pSSM, HDA_MAX_STREAMS); 3692 4111 3693 4112 /* Save stream states. */ 3694 int rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStOut); 3695 AssertRCReturn(rc, rc); 3696 #ifdef VBOX_WITH_HDA_MIC_IN 3697 rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStMicIn); 3698 AssertRCReturn(rc, rc); 3699 #endif 3700 rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStLineIn); 3701 AssertRCReturn(rc, rc); 4113 int rc; 4114 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 4115 { 4116 rc = hdaSaveStream(pDevIns, pSSM, &pThis->aStreams[i]); 4117 AssertRCReturn(rc, rc); 4118 } 3702 4119 3703 4120 return rc; … … 3750 4167 case HDA_SSM_VERSION_3: 3751 4168 cRegs = 112; 3752 AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= HDA_NREGS_SAVED);4169 AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= 112); 3753 4170 break; 3754 4171 … … 3824 4241 3825 4242 /* Output */ 3826 rc = hdaStreamInit(pThis, &pThis->StrmStOut, 4 /* Stream number, hardcoded */); 4243 PHDASTREAM pStream = &pThis->aStreams[4]; 4244 rc = hdaStreamInit(pThis, pStream, 4 /* Stream descriptor, hardcoded */); 3827 4245 if (RT_FAILURE(rc)) 3828 4246 break; 3829 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, p This->StrmStOut.State.BDLE);3830 p This->StrmStOut.State.uCurBDLE = pThis->StrmStOut.State.BDLE.State.u32BDLIndex;4247 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pStream->State.BDLE); 4248 pStream->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex; 3831 4249 3832 4250 /* Microphone-In */ 3833 rc = hdaStreamInit(pThis, &pThis->StrmStMicIn, 2 /* Stream number, hardcoded */); 4251 pStream = &pThis->aStreams[2]; 4252 rc = hdaStreamInit(pThis, pStream, 2 /* Stream descriptor, hardcoded */); 3834 4253 if (RT_FAILURE(rc)) 3835 4254 break; 3836 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, p This->StrmStMicIn.State.BDLE);3837 p This->StrmStMicIn.State.uCurBDLE = pThis->StrmStMicIn.State.BDLE.State.u32BDLIndex;4255 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pStream->State.BDLE); 4256 pStream->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex; 3838 4257 3839 4258 /* Line-In */ 3840 rc = hdaStreamInit(pThis, &pThis->StrmStLineIn, 0 /* Stream number, hardcoded */); 4259 pStream = &pThis->aStreams[0]; 4260 rc = hdaStreamInit(pThis, pStream, 0 /* Stream descriptor, hardcoded */); 3841 4261 if (RT_FAILURE(rc)) 3842 4262 break; 3843 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, p This->StrmStLineIn.State.BDLE);3844 p This->StrmStLineIn.State.uCurBDLE = pThis->StrmStLineIn.State.BDLE.State.u32BDLIndex;4263 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pStream->State.BDLE); 4264 pStream->State.uCurBDLE = pStream->State.BDLE.State.u32BDLIndex; 3845 4265 break; 3846 4266 } … … 3860 4280 for (uint32_t i = 0; i < cStreams; i++) 3861 4281 { 3862 uint8_t uS treamID;3863 rc = SSMR3GetU8(pSSM, &uS treamID);4282 uint8_t uSD; 4283 rc = SSMR3GetU8(pSSM, &uSD); 3864 4284 if (RT_FAILURE(rc)) 3865 4285 break; 3866 4286 3867 PHDASTREAM pStrm = hdaStreamFrom ID(pThis, uStreamID);4287 PHDASTREAM pStrm = hdaStreamFromSD(pThis, uSD); 3868 4288 HDASTREAM StreamDummy; 3869 4289 3870 4290 if (!pStrm) 3871 4291 { 4292 RT_ZERO(StreamDummy); 3872 4293 pStrm = &StreamDummy; 3873 LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uS treamID));4294 LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uSD)); 3874 4295 break; 3875 4296 } 3876 4297 3877 RT_BZERO(pStrm, sizeof(HDASTREAM)); 3878 3879 rc = hdaStreamInit(pThis, pStrm, uStreamID); 4298 rc = hdaStreamInit(pThis, pStrm, uSD); 3880 4299 if (RT_FAILURE(rc)) 3881 4300 { 3882 LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uS treamID, rc));4301 LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uSD, rc)); 3883 4302 break; 3884 4303 } … … 3972 4391 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 3973 4392 { 3974 rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, fEnableIn); 4393 PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector; 4394 rc = pCon->pfnEnableIn(pCon, pDrv->LineIn.pGstStrm, fEnableIn); 3975 4395 if (RT_FAILURE(rc)) 3976 4396 break; 3977 4397 #ifdef VBOX_WITH_HDA_MIC_IN 3978 rc = p Drv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, fEnableMicIn);4398 rc = pCon->pfnEnableIn(pCon, pDrv->MicIn.pGstStrm, fEnableMicIn); 3979 4399 if (RT_FAILURE(rc)) 3980 4400 break; 3981 4401 #endif 3982 rc = pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, fEnableOut); 4402 rc = pCon->pfnEnableOut(pCon, pDrv->Front.pGstStrm, fEnableOut); 4403 if (RT_FAILURE(rc)) 4404 break; 4405 #ifdef VBOX_WITH_HDA_51_SURROUND 4406 rc = pCon->pfnEnableOut(pCon, pDrv->CenterLFE.pGstStrm, fEnableOut); 4407 if (RT_FAILURE(rc)) 4408 break; 4409 rc = pCon->pfnEnableOut(pCon, pDrv->Rear.pGstStrm, fEnableOut); 4410 if (RT_FAILURE(rc)) 4411 break; 4412 #endif 3983 4413 if (RT_FAILURE(rc)) 3984 4414 break; … … 4083 4513 } 4084 4514 4085 static int hda LookUpRegisterByName(PHDASTATE pThis, const char *pszArgs)4515 static int hdaDbgLookupRegByName(PHDASTATE pThis, const char *pszArgs) 4086 4516 { 4087 4517 int iReg = 0; 4088 for (; iReg < HDA_N REGS; ++iReg)4518 for (; iReg < HDA_NUM_REGS; ++iReg) 4089 4519 if (!RTStrICmp(g_aHdaRegMap[iReg].abbrev, pszArgs)) 4090 4520 return iReg; … … 4097 4527 Assert( pThis 4098 4528 && iHdaIndex >= 0 4099 && iHdaIndex < HDA_N REGS);4529 && iHdaIndex < HDA_NUM_REGS); 4100 4530 pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]); 4101 4531 } … … 4104 4534 * @callback_method_impl{FNDBGFHANDLERDEV} 4105 4535 */ 4106 static DECLCALLBACK(void) hda Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)4536 static DECLCALLBACK(void) hdaDbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4107 4537 { 4108 4538 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 4109 int iHdaRegisterIndex = hda LookUpRegisterByName(pThis, pszArgs);4539 int iHdaRegisterIndex = hdaDbgLookupRegByName(pThis, pszArgs); 4110 4540 if (iHdaRegisterIndex != -1) 4111 4541 hdaDbgPrintRegister(pThis, pHlp, iHdaRegisterIndex); 4112 4542 else 4113 for(iHdaRegisterIndex = 0; (unsigned int)iHdaRegisterIndex < HDA_NREGS; ++iHdaRegisterIndex) 4543 { 4544 for(iHdaRegisterIndex = 0; (unsigned int)iHdaRegisterIndex < HDA_NUM_REGS; ++iHdaRegisterIndex) 4114 4545 hdaDbgPrintRegister(pThis, pHlp, iHdaRegisterIndex); 4115 } 4116 4117 static void hdaDbgPrintStream(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iHdaStrmIndex) 4546 } 4547 } 4548 4549 static void hdaDbgPrintStream(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iIdx) 4118 4550 { 4119 4551 Assert( pThis 4120 && iHdaStrmIndex >= 0 4121 && iHdaStrmIndex < 7); 4122 pHlp->pfnPrintf(pHlp, "Dump of %d HDA Stream:\n", iHdaStrmIndex); 4123 pHlp->pfnPrintf(pHlp, "SD%dCTL: %R[sdctl]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, CTL, iHdaStrmIndex)); 4124 pHlp->pfnPrintf(pHlp, "SD%dCTS: %R[sdsts]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, STS, iHdaStrmIndex)); 4125 pHlp->pfnPrintf(pHlp, "SD%dFIFOS: %R[sdfifos]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, FIFOS, iHdaStrmIndex)); 4126 pHlp->pfnPrintf(pHlp, "SD%dFIFOW: %R[sdfifow]\n", iHdaStrmIndex, HDA_STREAM_REG(pThis, FIFOW, iHdaStrmIndex)); 4127 } 4128 4129 static int hdaLookUpStreamIndex(PHDASTATE pThis, const char *pszArgs) 4130 { 4131 /* todo: add args parsing */ 4552 && iIdx >= 0 4553 && iIdx < HDA_MAX_STREAMS); 4554 4555 const PHDASTREAM pStrm = &pThis->aStreams[iIdx]; 4556 4557 pHlp->pfnPrintf(pHlp, "Stream #%d:\n", iIdx); 4558 pHlp->pfnPrintf(pHlp, "\tSD%dCTL : %R[sdctl]\n", iIdx, HDA_STREAM_REG(pThis, CTL, iIdx)); 4559 pHlp->pfnPrintf(pHlp, "\tSD%dCTS : %R[sdsts]\n", iIdx, HDA_STREAM_REG(pThis, STS, iIdx)); 4560 pHlp->pfnPrintf(pHlp, "\tSD%dFIFOS: %R[sdfifos]\n", iIdx, HDA_STREAM_REG(pThis, FIFOS, iIdx)); 4561 pHlp->pfnPrintf(pHlp, "\tSD%dFIFOW: %R[sdfifow]\n", iIdx, HDA_STREAM_REG(pThis, FIFOW, iIdx)); 4562 pHlp->pfnPrintf(pHlp, "\tBDLE : %R[bdle]\n", &pStrm->State.BDLE); 4563 } 4564 4565 static void hdaDbgPrintBDLE(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iIdx) 4566 { 4567 Assert( pThis 4568 && iIdx >= 0 4569 && iIdx < HDA_MAX_STREAMS); 4570 4571 const PHDASTREAM pStrm = &pThis->aStreams[iIdx]; 4572 const PHDABDLE pBDLE = &pStrm->State.BDLE; 4573 4574 pHlp->pfnPrintf(pHlp, "Stream #%d BDLE:\n", iIdx); 4575 pHlp->pfnPrintf(pHlp, "\t%R[bdle]\n", pBDLE); 4576 4577 uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, iIdx), 4578 HDA_STREAM_REG(pThis, BDPU, iIdx)); 4579 uint16_t u16LVI = HDA_STREAM_REG(pThis, LVI, iIdx); 4580 uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, iIdx); 4581 4582 if (!u64BaseDMA) 4583 return; 4584 4585 uint32_t cbBDLE = 0; 4586 for (uint16_t i = 0; i < u16LVI + 1; i++) 4587 { 4588 uint8_t bdle[16]; /** @todo Use a define. */ 4589 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + i * 16, bdle, 16); /** @todo Use a define. */ 4590 4591 uint64_t addr = *(uint64_t *)bdle; 4592 uint32_t len = *(uint32_t *)&bdle[8]; 4593 uint32_t ioc = *(uint32_t *)&bdle[12]; 4594 4595 pHlp->pfnPrintf(pHlp, "\t#%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n", 4596 i, addr, len, RT_BOOL(ioc & 0x1)); 4597 4598 cbBDLE += len; 4599 } 4600 4601 pHlp->pfnPrintf(pHlp, "Total: %RU32 bytes\n", cbBDLE); 4602 4603 pHlp->pfnPrintf(pHlp, "DMA counters (base @ 0x%llx):\n", pThis->u64DPBase); 4604 if (!pThis->u64DPBase) /* No DMA base given? Bail out. */ 4605 { 4606 pHlp->pfnPrintf(pHlp, "No counters found\n"); 4607 return; 4608 } 4609 4610 for (int i = 0; i < u16LVI + 1; i++) 4611 { 4612 uint32_t uDMACnt; 4613 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)), 4614 &uDMACnt, sizeof(uDMACnt)); 4615 4616 pHlp->pfnPrintf(pHlp, "\t#%03d DMA @ 0x%x\n", i , uDMACnt); 4617 } 4618 } 4619 4620 static int hdaDbgLookupStrmIdx(PHDASTATE pThis, const char *pszArgs) 4621 { 4622 /** @todo Add args parsing. */ 4132 4623 return -1; 4133 4624 } … … 4136 4627 * @callback_method_impl{FNDBGFHANDLERDEV} 4137 4628 */ 4138 static DECLCALLBACK(void) hda InfoStream(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)4629 static DECLCALLBACK(void) hdaDbgInfoStream(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4139 4630 { 4140 4631 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 4141 int iHdaStrmIndex = hda LookUpStreamIndex(pThis, pszArgs);4632 int iHdaStrmIndex = hdaDbgLookupStrmIdx(pThis, pszArgs); 4142 4633 if (iHdaStrmIndex != -1) 4143 4634 hdaDbgPrintStream(pThis, pHlp, iHdaStrmIndex); 4144 4635 else 4145 for(iHdaStrmIndex = 0; iHdaStrmIndex < 7; ++iHdaStrmIndex)4636 for(iHdaStrmIndex = 0; iHdaStrmIndex < HDA_MAX_STREAMS; ++iHdaStrmIndex) 4146 4637 hdaDbgPrintStream(pThis, pHlp, iHdaStrmIndex); 4147 4638 } … … 4150 4641 * @callback_method_impl{FNDBGFHANDLERDEV} 4151 4642 */ 4152 static DECLCALLBACK(void) hdaInfoCodecNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4643 static DECLCALLBACK(void) hdaDbgInfoBDLE(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4644 { 4645 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 4646 int iHdaStrmIndex = hdaDbgLookupStrmIdx(pThis, pszArgs); 4647 if (iHdaStrmIndex != -1) 4648 hdaDbgPrintBDLE(pThis, pHlp, iHdaStrmIndex); 4649 else 4650 for(iHdaStrmIndex = 0; iHdaStrmIndex < HDA_MAX_STREAMS; ++iHdaStrmIndex) 4651 hdaDbgPrintBDLE(pThis, pHlp, iHdaStrmIndex); 4652 } 4653 4654 /** 4655 * @callback_method_impl{FNDBGFHANDLERDEV} 4656 */ 4657 static DECLCALLBACK(void) hdaDbgInfoCodecNodes(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4153 4658 { 4154 4659 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); … … 4163 4668 * @callback_method_impl{FNDBGFHANDLERDEV} 4164 4669 */ 4165 static DECLCALLBACK(void) hda InfoCodecSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)4670 static DECLCALLBACK(void) hdaDbgInfoCodecSelector(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4166 4671 { 4167 4672 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); … … 4176 4681 * @callback_method_impl{FNDBGFHANDLERDEV} 4177 4682 */ 4178 static DECLCALLBACK(void) hda InfoMixer(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)4683 static DECLCALLBACK(void) hdaDbgInfoMixer(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 4179 4684 { 4180 4685 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); … … 4217 4722 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 4218 4723 4219 HDA_REG(pThis, GCAP) = HDA_MAKE_GCAP(4,4,0,0,1); /* see 6.2.1 */ 4220 HDA_REG(pThis, VMIN) = 0x00; /* see 6.2.2 */ 4221 HDA_REG(pThis, VMAJ) = 0x01; /* see 6.2.3 */ 4222 HDA_REG(pThis, OUTPAY) = 0x003C; /* see 6.2.4 */ 4223 HDA_REG(pThis, INPAY) = 0x001D; /* see 6.2.5 */ 4224 HDA_REG(pThis, CORBSIZE) = 0x42; /* see 6.2.1 */ 4225 HDA_REG(pThis, RIRBSIZE) = 0x42; /* see 6.2.1 */ 4226 HDA_REG(pThis, CORBRP) = 0x0; 4227 HDA_REG(pThis, RIRBWP) = 0x0; 4228 4229 LogFunc(("Resetting ...\n")); 4724 LogFlowFuncEnter(); 4230 4725 4231 4726 # ifndef VBOX_WITH_AUDIO_CALLBACKS … … 4241 4736 # endif 4242 4737 4738 /* See 6.2.1. */ 4739 HDA_REG(pThis, GCAP) = HDA_MAKE_GCAP(HDA_MAX_SDO /* Ouput streams */, 4740 HDA_MAX_SDI /* Input streams */, 4741 0 /* Bidirectional output streams */, 4742 0 /* Serial data out signals */, 4743 1 /* 64-bit */); 4744 HDA_REG(pThis, VMIN) = 0x00; /* see 6.2.2 */ 4745 HDA_REG(pThis, VMAJ) = 0x01; /* see 6.2.3 */ 4746 /* Announce the full 60 words output payload. */ 4747 HDA_REG(pThis, OUTPAY) = 0x003C; /* see 6.2.4 */ 4748 /* Announce the full 29 words input payload. */ 4749 HDA_REG(pThis, INPAY) = 0x001D; /* see 6.2.5 */ 4750 HDA_REG(pThis, CORBSIZE) = 0x42; /* see 6.2.1 */ 4751 HDA_REG(pThis, RIRBSIZE) = 0x42; /* see 6.2.1 */ 4752 HDA_REG(pThis, CORBRP) = 0x0; 4753 HDA_REG(pThis, RIRBWP) = 0x0; 4754 4243 4755 /* 4244 4756 * Stop any audio currently playing and/or recording. … … 4247 4759 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 4248 4760 { 4249 pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.p StrmIn,false /* Disable */);4761 pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pGstStrm, false /* Disable */); 4250 4762 # ifdef VBOX_WITH_HDA_MIC_IN 4251 /* Ignore rc. */ 4252 pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, false /* Disable */); 4763 pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pGstStrm, false /* Disable */); 4253 4764 # endif 4254 /* Ditto. */ 4255 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, false /* Disable */); 4256 /* Ditto. */ 4765 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Front.pGstStrm, false /* Disable */); 4766 # ifdef VBOX_WITH_HDA_51_SURROUND 4767 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->CenterLFE.pGstStrm, false /* Disable */); 4768 pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Rear.pGstStrm, false /* Disable */); 4769 # endif 4257 4770 } 4258 4771 … … 4272 4785 pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns); 4273 4786 4274 for (uint8_t u8Strm = 0; u8Strm < 8; u8Strm++) /** @todo Use a define here. */ 4275 { 4276 PHDASTREAM pStrmSt = NULL; 4277 if (u8Strm == 0) /** @todo Implement dynamic stream IDs. */ 4278 pStrmSt = &pThis->StrmStLineIn; 4279 # ifdef VBOX_WITH_HDA_MIC_IN 4280 else if (u8Strm == 2) /** @todo Implement dynamic stream IDs. */ 4281 pStrmSt = &pThis->StrmStMicIn; 4282 # endif 4283 else if (u8Strm == 4) /** @todo Implement dynamic stream IDs. */ 4284 pStrmSt = &pThis->StrmStOut; 4285 4286 if (pStrmSt) 4287 { 4288 /* Remove the RUN bit from SDnCTL in case the stream was in a running state before. */ 4289 HDA_STREAM_REG(pThis, CTL, u8Strm) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN); 4290 4291 hdaStreamReset(pThis, pStrmSt, u8Strm); 4292 } 4293 } 4787 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 4788 { 4789 /* Remove the RUN bit from SDnCTL in case the stream was in a running state before. */ 4790 HDA_STREAM_REG(pThis, CTL, i) &= ~HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN); 4791 hdaStreamReset(pThis, &pThis->aStreams[i], i); 4792 } 4793 4794 /* Clear stream tags <-> objects mapping table. */ 4795 RT_ZERO(pThis->aTags); 4294 4796 4295 4797 /* Emulation of codec "wake up" (HDA spec 5.5.1 and 6.5). */ … … 4308 4810 # endif 4309 4811 4812 LogFlowFuncLeave(); 4310 4813 LogRel(("HDA: Reset\n")); 4311 4814 } … … 4348 4851 pThis->pu64RirbBuf = NULL; 4349 4852 4350 hdaStreamDestroy(&pThis->StrmStLineIn); 4351 hdaStreamDestroy(&pThis->StrmStMicIn); 4352 hdaStreamDestroy(&pThis->StrmStOut); 4853 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 4854 hdaStreamDestroy(&pThis->aStreams[i]); 4353 4855 4354 4856 return VINF_SUCCESS; … … 4664 5166 4665 5167 RTListInit(&pThis->lstDrv); 5168 #ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT 5169 rc = RTCircBufCreate(&pThis->pCircBuf, _4K); 5170 if (RT_FAILURE(rc)) 5171 return rc; 5172 #endif 4666 5173 4667 5174 uint8_t uLUN; … … 4704 5211 AssertRC(rc); 4705 5212 4706 /* Add all required audio sinks. */ 5213 /* 5214 * Add mixer output sinks. 5215 */ 5216 #ifdef VBOX_WITH_HDA_51_SURROUND 5217 rc = AudioMixerAddSink(pThis->pMixer, "[Playback] Front", 5218 AUDMIXSINKDIR_OUTPUT, &pThis->pSinkFront); 5219 AssertRC(rc); 5220 rc = AudioMixerAddSink(pThis->pMixer, "[Playback] Center / Subwoofer", 5221 AUDMIXSINKDIR_OUTPUT, &pThis->pSinkCenterLFE); 5222 AssertRC(rc); 5223 rc = AudioMixerAddSink(pThis->pMixer, "[Playback] Rear", 5224 AUDMIXSINKDIR_OUTPUT, &pThis->pSinkRear); 5225 AssertRC(rc); 5226 #else 4707 5227 rc = AudioMixerAddSink(pThis->pMixer, "[Playback] PCM Output", 4708 AUDMIXSINKDIR_OUTPUT, &pThis->pSink Output);5228 AUDMIXSINKDIR_OUTPUT, &pThis->pSinkFront); 4709 5229 AssertRC(rc); 4710 5230 #endif 5231 /* 5232 * Add mixer input sinks. 5233 */ 4711 5234 rc = AudioMixerAddSink(pThis->pMixer, "[Recording] Line In", 4712 5235 AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn); 4713 5236 AssertRC(rc); 4714 5237 #ifdef VBOX_WITH_HDA_MIC_IN 4715 5238 rc = AudioMixerAddSink(pThis->pMixer, "[Recording] Microphone In", 4716 5239 AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn); 4717 5240 AssertRC(rc); 4718 5241 #endif 4719 5242 /* There is no master volume control. Set the master to max. */ 4720 5243 PDMAUDIOVOLUME vol = { false, 255, 255 }; … … 4732 5255 4733 5256 /* Audio driver callbacks for multiplexing. */ 4734 pThis->pCodec->pfnCloseIn = hdaCloseIn; 4735 pThis->pCodec->pfnCloseOut = hdaCloseOut; 4736 pThis->pCodec->pfnOpenIn = hdaOpenIn; 4737 pThis->pCodec->pfnOpenOut = hdaOpenOut; 4738 pThis->pCodec->pfnReset = hdaCodecReset; 4739 pThis->pCodec->pfnSetVolume = hdaSetVolume; 5257 pThis->pCodec->pfnMixerAddStream = hdaMixerAddStream; 5258 pThis->pCodec->pfnMixerRemoveStream = hdaMixerRemoveStream; 5259 pThis->pCodec->pfnMixerSetVolume = hdaMixerSetVolume; 5260 pThis->pCodec->pfnReset = hdaCodecReset; 4740 5261 4741 5262 pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */ … … 4756 5277 if (RT_SUCCESS(rc)) 4757 5278 { 4758 rc = hdaStreamCreate(&pThis->StrmStLineIn); 4759 AssertRC(rc); 4760 #ifdef VBOX_WITH_HDA_MIC_IN 4761 rc = hdaStreamCreate(&pThis->StrmStMicIn); 4762 AssertRC(rc); 4763 #endif 4764 rc = hdaStreamCreate(&pThis->StrmStOut); 4765 AssertRC(rc); 4766 5279 /* 5280 * Create all hardware streams. 5281 */ 5282 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 5283 { 5284 rc = hdaStreamCreate(&pThis->aStreams[i], i /* uSD */); 5285 AssertRC(rc); 5286 } 5287 5288 /* 5289 * As we don't have any dynamic stream <-> mixer sink mapping (yet), 5290 * hard-wire the associations here. 5291 */ 5292 #ifdef VBOX_WITH_HDA_51_SURROUND 5293 # error "Implement me!" /** @todo */ 5294 #else 5295 /* Same goes for the input sink. */ 5296 for (uint8_t i = 0; i < HDA_MAX_SDI; i++) 5297 pThis->aStreams[i].pSink = pThis->pSinkLineIn; 5298 # ifdef VBOX_WITH_HDA_MIC_IN 5299 # error "Implement me!" /** @todo */ 5300 # endif 5301 /* Assign all output streams to the one-and-only output sink. */ 5302 for (uint8_t i = HDA_MAX_SDI; i < HDA_MAX_SDO; i++) 5303 pThis->aStreams[i].pSink = pThis->pSinkFront; 5304 #endif /* VBOX_WITH_HDA_51_SURROUND */ 5305 5306 /* 5307 * Initialize the driver chain. 5308 */ 4767 5309 PHDADRIVER pDrv; 4768 5310 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) … … 4778 5320 AssertPtr(pCon); 4779 5321 4780 bool fValidLineIn = pCon->pfnIsValidIn(pCon, pDrv->LineIn.pStrmIn);5322 bool fValidLineIn = pCon->pfnIsValidIn(pCon, pDrv->LineIn.pGstStrm); 4781 5323 #ifdef VBOX_WITH_HDA_MIC_IN 4782 bool fValidMicIn = pCon->pfnIsValidIn (pCon, pDrv->MicIn.p StrmIn);4783 #endif 4784 bool fValidOut = pCon->pfnIsValidOut(pCon, pDrv-> Out.pStrmOut);5324 bool fValidMicIn = pCon->pfnIsValidIn (pCon, pDrv->MicIn.pGstStrm); 5325 #endif 5326 bool fValidOut = pCon->pfnIsValidOut(pCon, pDrv->Front.pGstStrm); 4785 5327 4786 5328 if ( !fValidLineIn … … 4885 5427 * Debug and string formatter types. 4886 5428 */ 4887 PDMDevHlpDBGFInfoRegister(pDevIns, "hda", "HDA info. (hda [register case-insensitive])", hdaInfo); 4888 PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm", "HDA stream info. (hdastrm [stream number])", hdaInfoStream); 4889 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes", "HDA codec nodes.", hdaInfoCodecNodes); 4890 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].", hdaInfoCodecSelector); 4891 PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer", "HDA mixer state.", hdaInfoMixer); 5429 PDMDevHlpDBGFInfoRegister(pDevIns, "hda", "HDA info. (hda [register case-insensitive])", hdaDbgInfo); 5430 PDMDevHlpDBGFInfoRegister(pDevIns, "hdabdle", "HDA stream BDLE info. (hdabdle [stream number])", hdaDbgInfoBDLE); 5431 PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm", "HDA stream info. (hdastrm [stream number])", hdaDbgInfoStream); 5432 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes", "HDA codec nodes.", hdaDbgInfoCodecNodes); 5433 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].", hdaDbgInfoCodecSelector); 5434 PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer", "HDA mixer state.", hdaDbgInfoMixer); 4892 5435 4893 5436 rc = RTStrFormatTypeRegister("bdle", hdaDbgFmtBDLE, NULL); -
trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
r59541 r60353 36 36 #include "VBoxDD.h" 37 37 #include "DevIchHdaCodec.h" 38 #include "DevIchHdaCommon.h" 39 #include "AudioMixer.h" 38 40 39 41 … … 103 105 #define CODEC_F00_00_VENDORID(f00_00) (((f00_00) >> 16) & 0xFFFF) 104 106 #define CODEC_F00_00_DEVICEID(f00_00) ((f00_00) & 0xFFFF) 105 /* RevisionID (7.3.4.2)*/ 106 #define CODEC_MAKE_F00_02(MajRev, MinRev, RevisionID, SteppingID) (((MajRev) << 20)|((MinRev) << 16)|((RevisionID) << 8)|(SteppingID)) 107 /* Subordinate node count (7.3.4.3)*/ 107 108 /** RevisionID (7.3.4.2). */ 109 #define CODEC_MAKE_F00_02(majRev, minRev, venFix, venProg, stepFix, stepProg) \ 110 ( (((majRev) & 0xF) << 20) \ 111 | (((minRev) & 0xF) << 16) \ 112 | (((venFix) & 0xF) << 12) \ 113 | (((venProg) & 0xF) << 8) \ 114 | (((stepFix) & 0xF) << 4) \ 115 | ((stepProg) & 0xF)) 116 117 /** Subordinate node count (7.3.4.3). */ 108 118 #define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF)) 109 119 #define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04) (((f00_04) >> 16) & 0xFF) … … 120 130 #define CODEC_F00_05_IS_UNSOL(f00_05) RT_BOOL((f00_05) & RT_BIT(8)) 121 131 #define CODEC_F00_05_GROUP(f00_05) ((f00_05) & 0xff) 122 /* Audio Function Group capabilities (7.3.4.5)*/132 /* Audio Function Group capabilities (7.3.4.5). */ 123 133 #define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF)) 124 134 #define CODEC_F00_08_BEEP_GEN(f00_08) ((f00_08) & RT_BIT(16) 125 135 126 /* Widget Capabilities (7.3.4.6) */ 127 #define CODEC_MAKE_F00_09(type, delay, chanel_count) \ 128 ( (((type) & 0xF) << 20) \ 129 | (((delay) & 0xF) << 16) \ 130 | (((chanel_count) & 0xF) << 13)) 136 /* Converter Stream, Channel (7.3.3.11). */ 137 #define CODEC_F00_06_GET_STREAM_ID(cmd) (((cmd) >> 4) & 0x0F) 138 #define CODEC_F00_06_GET_CHANNEL_ID(cmd) (((cmd) & 0x0F)) 139 140 /* Widget Capabilities (7.3.4.6). */ 141 #define CODEC_MAKE_F00_09(type, delay, chan_ext) \ 142 ( (((type) & 0xF) << 20) \ 143 | (((delay) & 0xF) << 16) \ 144 | (((chan_ext) & 0xF) << 13)) 131 145 /* note: types 0x8-0xe are reserved */ 132 146 #define CODEC_F00_09_TYPE_AUDIO_OUTPUT (0x0) … … 152 166 #define CODEC_F00_09_CAP_OUT_AMP_PRESENT RT_BIT(2) 153 167 #define CODEC_F00_09_CAP_IN_AMP_PRESENT RT_BIT(1) 154 #define CODEC_F00_09_CAP_ LSBRT_BIT(0)168 #define CODEC_F00_09_CAP_STEREO RT_BIT(0) 155 169 156 170 #define CODEC_F00_09_TYPE(f00_09) (((f00_09) >> 20) & 0xF) … … 208 222 #define CODEC_F00_0C_CAP_INPUT RT_BIT(5) 209 223 #define CODEC_F00_0C_CAP_OUTPUT RT_BIT(4) 210 #define CODEC_F00_0C_CAP_H PRT_BIT(3)224 #define CODEC_F00_0C_CAP_HEADPHONE_AMP RT_BIT(3) 211 225 #define CODEC_F00_0C_CAP_PRESENSE_DETECT RT_BIT(2) 212 226 #define CODEC_F00_0C_CAP_TRIGGER_REQUIRED RT_BIT(1) … … 225 239 #define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c) ((f00_0c) & RT_BIT(0)) 226 240 227 /* Input Amplifier capabilities (7.3.4.10) */241 /* Input Amplifier capabilities (7.3.4.10). */ 228 242 #define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \ 229 ( (((mute_cap) & 0x1) << 31)\243 ( (((mute_cap) & 0x1) << 31) \ 230 244 | (((step_size) & 0xFF) << 16) \ 231 245 | (((num_steps) & 0xFF) << 8) \ 232 | ((offset)& 0xFF))246 | ((offset) & 0xFF)) 233 247 234 248 #define CODEC_F00_0D_CAP_MUTE RT_BIT(7) … … 239 253 #define CODEC_F00_0D_OFFSET(f00_0d) ( (f00_0d) & 0x7F) 240 254 255 /** Indicates that the amplifier can be muted. */ 256 #define CODEC_AMP_CAP_MUTE 0x1 257 /** The amplifier's maximum number of steps. We want 258 * a ~90dB dynamic range, so 64 steps with 1.25dB each 259 * should do the trick. 260 * 261 * As we want to map our range to [0..128] values we can avoid 262 * multiplication and simply doing a shift later. 263 * 264 * Produces -96dB to +0dB. 265 * "0" indicates a step of 0.25dB, "127" indicates a step of 32dB. 266 */ 267 #define CODEC_AMP_NUM_STEPS 0x7F 268 /** The initial gain offset (and when doing a node reset). */ 269 #define CODEC_AMP_OFF_INITIAL 0x40 270 /** The amplifier's gain step size. */ 271 #define CODEC_AMP_STEP_SIZE 0x2 272 241 273 /* Output Amplifier capabilities (7.3.4.10) */ 242 274 #define CODEC_MAKE_F00_12 CODEC_MAKE_F00_0D … … 247 279 #define CODEC_F00_12_OFFSET(f00_12) CODEC_F00_0D_OFFSET(f00_12) 248 280 249 /* Connection list lenght (7.3.4.11) */281 /* Connection list lenght (7.3.4.11). */ 250 282 #define CODEC_MAKE_F00_0E(long_form, length) \ 251 283 ( (((long_form) & 0x1) << 7) \ … … 272 304 #define CODEC_F00_10_BENING(f00_10) ((f00_10) & 0x1) 273 305 274 /* CP/IO Count (7.3.4.14)*/306 /* GPIO count (7.3.4.14). */ 275 307 #define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \ 276 308 ( (((wake) & 0x1) << 31) \ … … 280 312 | ((numgpio) & 0xFF)) 281 313 282 /* Processing States (7.3.3.4) */314 /* Processing States (7.3.3.4). */ 283 315 #define CODEC_F03_OFF (0) 284 316 #define CODEC_F03_ON RT_BIT(0) 285 317 #define CODEC_F03_BENING RT_BIT(1) 286 /* Power States (7.3.3.10) */287 #define CODEC_MAKE_F05(reset, stopok, error, act, set) 288 ( (((reset) & 0x1) << 10)\289 | (((stopok) & 0x1) << 9)\290 | (((error) & 0x1) << 8)\291 | (((act) & 0x7) << 4)\292 | ((set) & 0x7))318 /* Power States (7.3.3.10). */ 319 #define CODEC_MAKE_F05(reset, stopok, error, act, set) \ 320 ( (((reset) & 0x1) << 10) \ 321 | (((stopok) & 0x1) << 9) \ 322 | (((error) & 0x1) << 8) \ 323 | (((act) & 0xF) << 4) \ 324 | ((set) & 0xF)) 293 325 #define CODEC_F05_D3COLD (4) 294 326 #define CODEC_F05_D3 (3) … … 300 332 #define CODEC_F05_IS_STOPOK(value) (((value) & RT_BIT(9)) != 0) 301 333 #define CODEC_F05_IS_ERROR(value) (((value) & RT_BIT(8)) != 0) 302 #define CODEC_F05_ACT(value) (((value) & 0x 7) >> 4)303 #define CODEC_F05_SET(value) (((value) & 0x 7))334 #define CODEC_F05_ACT(value) (((value) & 0xF0) >> 4) 335 #define CODEC_F05_SET(value) (((value) & 0xF)) 304 336 305 337 #define CODEC_F05_GE(p0, p1) ((p0) <= (p1)) 306 338 #define CODEC_F05_LE(p0, p1) ((p0) >= (p1)) 307 339 308 /* Pin Widged Control (7.3.3.13) */ 340 /* Converter Stream, Channel (7.3.3.11). */ 341 #define CODEC_MAKE_F06(stream, channel) \ 342 ( (((stream) & 0xF) << 4) \ 343 | ((channel) & 0xF)) 344 #define CODEC_F06_STREAM(value) ((value) & 0xF0) 345 #define CODEC_F06_CHANNEL(value) ((value) & 0xF) 346 347 /* Pin Widged Control (7.3.3.13). */ 309 348 #define CODEC_F07_VREF_HIZ (0) 310 349 #define CODEC_F07_VREF_50 (0x1) … … 316 355 #define CODEC_F07_OUT_H_ENABLE RT_BIT(7) 317 356 318 /* Unsolicited enabled (7.3.3.14) */ 357 /* Volume Knob Control (7.3.3.29). */ 358 #define CODEC_F0F_IS_DIRECT RT_BIT(7) 359 #define CODEC_F0F_VOLUME (0x7F) 360 361 /* Unsolicited enabled (7.3.3.14). */ 319 362 #define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F)) 320 363 321 /* Converter formats (7.3.3.8) and (3.7.1) */ 322 #define CODEC_MAKE_A(fNonPCM, f44_1BaseRate, mult, div, bits, chan) \ 323 ( (((fNonPCM) & 0x1) << 15) \ 324 | (((f44_1BaseRate) & 0x1) << 14) \ 325 | (((mult) & 0x7) << 11) \ 326 | (((div) & 0x7) << 8) \ 327 | (((bits) & 0x7) << 4) \ 328 | ((chan) & 0xF)) 329 330 #define CODEC_A_TYPE RT_BIT(15) 331 #define CODEC_A_TYPE_PCM (0) 332 #define CODEC_A_TYPE_NON_PCM (1) 333 334 #define CODEC_A_BASE RT_BIT(14) 335 #define CODEC_A_BASE_48KHZ (0) 336 #define CODEC_A_BASE_44KHZ (1) 337 338 #define CODEC_A_MULT_1X (0) 339 #define CODEC_A_MULT_2X (1) 340 #define CODEC_A_MULT_3X (2) 341 #define CODEC_A_MULT_4X (3) 342 343 #define CODEC_A_DIV_1X (0) 344 #define CODEC_A_DIV_2X (1) 345 #define CODEC_A_DIV_3X (2) 346 #define CODEC_A_DIV_4X (3) 347 #define CODEC_A_DIV_5X (4) 348 #define CODEC_A_DIV_6X (5) 349 #define CODEC_A_DIV_7X (6) 350 #define CODEC_A_DIV_8X (7) 351 352 #define CODEC_A_8_BIT (0) 353 #define CODEC_A_16_BIT (1) 354 #define CODEC_A_20_BIT (2) 355 #define CODEC_A_24_BIT (3) 356 #define CODEC_A_32_BIT (4) 357 358 #define CODEC_A_CHAN_MONO (0) 359 #define CODEC_A_CHAN_STEREO (1) 360 361 /* Pin Sense (7.3.3.15) */ 364 /* Converter formats (7.3.3.8) and (3.7.1). */ 365 /* This is the same format as SDnFMT. */ 366 #define CODEC_MAKE_A HDA_SDFMT_MAKE 367 368 #define CODEC_A_TYPE HDA_SDFMT_TYPE 369 #define CODEC_A_TYPE_PCM HDA_SDFMT_TYPE_PCM 370 #define CODEC_A_TYPE_NON_PCM HDA_SDFMT_TYPE_NON_PCM 371 372 #define CODEC_A_BASE HDA_SDFMT_BASE 373 #define CODEC_A_BASE_48KHZ HDA_SDFMT_BASE_48KHZ 374 #define CODEC_A_BASE_44KHZ HDA_SDFMT_BASE_44KHZ 375 376 /* Pin Sense (7.3.3.15). */ 362 377 #define CODEC_MAKE_F09_ANALOG(fPresent, impedance) \ 363 378 ( (((fPresent) & 0x1) << 31) \ … … 477 492 #define CODEC_F1C_MISC_MASK (0xF) 478 493 #define CODEC_F1C_MISC_SHIFT (8) 479 #define CODEC_F1C_MISC_JACK_DETECT (0) 480 #define CODEC_F1C_MISC_RESERVED_0 (1) 481 #define CODEC_F1C_MISC_RESERVED_1 (2) 482 #define CODEC_F1C_MISC_RESERVED_2 (3) 494 #define CODEC_F1C_MISC_NONE 0 495 #define CODEC_F1C_MISC_JACK_NO_PRESENCE_DETECT RT_BIT(0) 496 #define CODEC_F1C_MISC_RESERVED_0 RT_BIT(1) 497 #define CODEC_F1C_MISC_RESERVED_1 RT_BIT(2) 498 #define CODEC_F1C_MISC_RESERVED_2 RT_BIT(3) 483 499 484 500 /* Configuration default: Association */ … … 486 502 #define CODEC_F1C_ASSOCIATION_SHIFT (4) 487 503 488 /* Reserved; don't use. */504 /** Reserved; don't use. */ 489 505 #define CODEC_F1C_ASSOCIATION_INVALID 0x0 490 506 #define CODEC_F1C_ASSOCIATION_GROUP_0 0x1 … … 498 514 #define CODEC_F1C_ASSOCIATION_GROUP_15 0xF 499 515 500 /* Configuration default: Association Sequence */516 /* Configuration default: Association Sequence. */ 501 517 #define CODEC_F1C_SEQ_MASK (0xF) 502 518 #define CODEC_F1C_SEQ_SHIFT (0) 503 519 504 /* Implementation identification (7.3.3.30) */520 /* Implementation identification (7.3.3.30). */ 505 521 #define CODEC_MAKE_F20(bmid, bsku, aid) \ 506 522 ( (((bmid) & 0xFFFF) << 16) \ … … 509 525 ) 510 526 511 /* macro definition helping in filling the configuration registers. */527 /* Macro definition helping in filling the configuration registers. */ 512 528 #define CODEC_MAKE_F1C(port_connectivity, location, device, connection_type, color, misc, association, sequence) \ 513 ( (( port_connectivity) << CODEC_F1C_PORT_SHIFT)\514 | (( location) << CODEC_F1C_LOCATION_SHIFT)\515 | (( device) << CODEC_F1C_DEVICE_SHIFT)\516 | (( connection_type) << CODEC_F1C_CONNECTION_TYPE_SHIFT) \517 | (( color) << CODEC_F1C_COLOR_SHIFT)\518 | (( misc) << CODEC_F1C_MISC_SHIFT)\519 | (( association) << CODEC_F1C_ASSOCIATION_SHIFT)\520 | (( sequence)))529 ( (((port_connectivity) & 0xF) << CODEC_F1C_PORT_SHIFT) \ 530 | (((location) & 0xF) << CODEC_F1C_LOCATION_SHIFT) \ 531 | (((device) & 0xF) << CODEC_F1C_DEVICE_SHIFT) \ 532 | (((connection_type) & 0xF) << CODEC_F1C_CONNECTION_TYPE_SHIFT) \ 533 | (((color) & 0xF) << CODEC_F1C_COLOR_SHIFT) \ 534 | (((misc) & 0xF) << CODEC_F1C_MISC_SHIFT) \ 535 | (((association) & 0xF) << CODEC_F1C_ASSOCIATION_SHIFT) \ 536 | (((sequence) & 0xF))) 521 537 522 538 … … 585 601 { 586 602 CODECCOMMONNODE node; 603 uint32_t u32F01_param; 587 604 uint32_t u32F03_param; 588 605 uint32_t u32F05_param; … … 591 608 592 609 uint32_t u32A_param; 593 uint32_t u32F01_param;594 610 AMPLIFIER B_params; 595 611 } ADCNODE, *PADCNODE; … … 627 643 uint32_t u32F05_param; 628 644 uint32_t u32F08_param; 645 uint32_t u32F17_param; 629 646 uint32_t u32F20_param; 630 uint32_t u32F17_param;631 647 } AFGCODECNODE, *PAFGCODECNODE; 632 648 AssertNodeSize(AFGCODECNODE, 4); … … 635 651 { 636 652 CODECCOMMONNODE node; 653 uint32_t u32F01_param; 637 654 uint32_t u32F07_param; 638 655 uint32_t u32F08_param; 639 656 uint32_t u32F09_param; 640 uint32_t u32F01_param;641 657 uint32_t u32F1c_param; 642 658 AMPLIFIER B_params; … … 648 664 CODECCOMMONNODE node; 649 665 uint32_t u32F01_param; 666 uint32_t u32F05_param; 667 uint32_t u32F07_param; 650 668 uint32_t u32F08_param; 651 uint32_t u32F07_param;652 669 uint32_t u32F09_param; 653 670 uint32_t u32F1c_param; 654 671 } DIGOUTNODE, *PDIGOUTNODE; 655 AssertNodeSize(DIGOUTNODE, 5);672 AssertNodeSize(DIGOUTNODE, 6); 656 673 657 674 typedef struct DIGINNODE … … 723 740 uint32_t u32F07_param; 724 741 uint32_t u32F1c_param; 742 743 uint32_t u32A_param; 725 744 } RESNODE, *PRESNODE; 726 AssertNodeSize(RESNODE, 4);745 AssertNodeSize(RESNODE, 5); 727 746 728 747 /** … … 773 792 #define STAC9220_NID_SPDIF_OUT 0x8 /* Out */ 774 793 #define STAC9220_NID_SPDIF_IN 0x9 /* In */ 794 /** Also known as PIN_A. */ 775 795 #define STAC9220_NID_PIN_HEADPHONE0 0xA /* In, Out */ 776 796 #define STAC9220_NID_PIN_B 0xB /* In, Out */ 777 797 #define STAC9220_NID_PIN_C 0xC /* In, Out */ 798 /** Also known as PIN D. */ 778 799 #define STAC9220_NID_PIN_HEADPHONE1 0xD /* In, Out */ 779 800 #define STAC9220_NID_PIN_E 0xE /* In */ 780 801 #define STAC9220_NID_PIN_F 0xF /* In, Out */ 802 /** Also known as DIGOUT0. */ 781 803 #define STAC9220_NID_PIN_SPDIF_OUT 0x10 /* Out */ 804 /** Also known as DIGIN. */ 782 805 #define STAC9220_NID_PIN_SPDIF_IN 0x11 /* In */ 783 806 #define STAC9220_NID_ADC0_MUX 0x12 /* In */ … … 788 811 #define STAC9220_NID_AMP_ADC0 0x17 /* In */ 789 812 #define STAC9220_NID_AMP_ADC1 0x18 /* In */ 790 /* STAC9221. */813 /* Only for STAC9221. */ 791 814 #define STAC9221_NID_ADAT_OUT 0x19 /* Out */ 792 815 #define STAC9221_NID_I2S_OUT 0x1A /* Out */ 793 816 #define STAC9221_NID_PIN_I2S_OUT 0x1B /* Out */ 794 817 795 #if 1 796 /* STAC9220 - Referenced thru STAC9220WIDGET in the constructor below. */ 797 static uint8_t const g_abStac9220Ports[] = { 0x0A, 0xB, 0xC, 0xD, 0xE, 0xF, 0}; 798 static uint8_t const g_abStac9220Dacs[] = { 0x02, 0x3, 0x4, 0x5, 0}; 799 static uint8_t const g_abStac9220Adcs[] = { 0x06, 0x7, 0}; 800 static uint8_t const g_abStac9220SpdifOuts[] = { 0x08, 0 }; 801 static uint8_t const g_abStac9220SpdifIns[] = { 0x09, 0 }; 802 static uint8_t const g_abStac9220DigOutPins[] = { 0x10, 0 }; 803 static uint8_t const g_abStac9220DigInPins[] = { 0x11, 0 }; 804 static uint8_t const g_abStac9220AdcVols[] = { 0x17, 0x18, 0}; 805 static uint8_t const g_abStac9220AdcMuxs[] = { 0x12, 0x13, 0}; 806 static uint8_t const g_abStac9220Pcbeeps[] = { 0x14, 0 }; 807 static uint8_t const g_abStac9220Cds[] = { 0x15, 0 }; 808 static uint8_t const g_abStac9220VolKnobs[] = { 0x16, 0 }; 809 static uint8_t const g_abStac9220Reserveds[] = { 0x09, 0x19, 0x1a, 0x1b, 0 }; 810 #else /** @todo Enable this after 5.0 -- needs more testing first. */ 811 static uint8_t const g_abStac9220Ports[] = { STAC9220_NID_PIN_HEADPHONE0, STAC9220_NID_PIN_B, STAC9220_NID_PIN_C, STAC9220_NID_PIN_HEADPHONE1, STAC9220_NID_PIN_E, STAC9220_NID_PIN_F, 0}; 812 static uint8_t const g_abStac9220Dacs[] = { STAC9220_NID_DAC0, STAC9220_NID_DAC1, STAC9220_NID_DAC2, STAC9220_NID_DAC3, 0}; 813 static uint8_t const g_abStac9220Adcs[] = { STAC9220_NID_ADC0, STAC9220_NID_ADC1, 0}; 818 /** Number of total nodes emulated. */ 819 #define STAC9221_NUM_NODES 0x1C 820 821 /* STAC9220 - Referenced through STAC9220WIDGET in the constructor below. */ 822 static uint8_t const g_abStac9220Ports[] = { STAC9220_NID_PIN_HEADPHONE0, STAC9220_NID_PIN_B, STAC9220_NID_PIN_C, STAC9220_NID_PIN_HEADPHONE1, STAC9220_NID_PIN_E, STAC9220_NID_PIN_F, 0 }; 823 static uint8_t const g_abStac9220Dacs[] = { STAC9220_NID_DAC0, STAC9220_NID_DAC1, STAC9220_NID_DAC2, STAC9220_NID_DAC3, 0 }; 824 static uint8_t const g_abStac9220Adcs[] = { STAC9220_NID_ADC0, STAC9220_NID_ADC1, 0 }; 814 825 static uint8_t const g_abStac9220SpdifOuts[] = { STAC9220_NID_SPDIF_OUT, 0 }; 815 826 static uint8_t const g_abStac9220SpdifIns[] = { STAC9220_NID_SPDIF_IN, 0 }; 816 827 static uint8_t const g_abStac9220DigOutPins[] = { STAC9220_NID_PIN_SPDIF_OUT, 0 }; 817 828 static uint8_t const g_abStac9220DigInPins[] = { STAC9220_NID_PIN_SPDIF_IN, 0 }; 818 static uint8_t const g_abStac9220AdcVols[] = { STAC9220_NID_AMP_ADC0, STAC9220_NID_AMP_ADC1, 0 };819 static uint8_t const g_abStac9220AdcMuxs[] = { STAC9220_NID_ADC0_MUX, STAC9220_NID_ADC1_MUX, 0 };829 static uint8_t const g_abStac9220AdcVols[] = { STAC9220_NID_AMP_ADC0, STAC9220_NID_AMP_ADC1, 0 }; 830 static uint8_t const g_abStac9220AdcMuxs[] = { STAC9220_NID_ADC0_MUX, STAC9220_NID_ADC1_MUX, 0 }; 820 831 static uint8_t const g_abStac9220Pcbeeps[] = { STAC9220_NID_PCBEEP, 0 }; 821 832 static uint8_t const g_abStac9220Cds[] = { STAC9220_NID_PIN_CD, 0 }; … … 824 835 /** @todo Is STAC9220_NID_SPDIF_IN really correct for reserved nodes? */ 825 836 static uint8_t const g_abStac9220Reserveds[] = { STAC9220_NID_SPDIF_IN, STAC9221_NID_ADAT_OUT, STAC9221_NID_I2S_OUT, STAC9221_NID_PIN_I2S_OUT, 0 }; 826 #endif827 837 828 838 /** SSM description of a CODECNODE. */ … … 854 864 static DECLCALLBACK(void) stac9220DbgNodes(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs) 855 865 { 856 for (int i = 1; i < 12; i++)866 for (int i = 1; i < pThis->cTotalNodes; i++) 857 867 { 858 868 PCODECNODE pNode = &pThis->paNodes[i]; … … 867 877 868 878 869 static DECLCALLBACK(int) stac9220ResetNode(PHDACODEC pThis, uint8_t nodenum, PCODECNODE pNode) 870 { 871 pNode->node.id = nodenum; 872 pNode->node.au32F00_param[0xF] = 0; /* Power statest Supported: are the same as AFG reports */ 873 switch (nodenum) 874 { 875 /* Root Node*/ 876 case 0: 877 pNode->node.au32F00_param[0x02] = CODEC_MAKE_F00_02(0x1, 0x0, 0x34, 0x1); /* rev id */ 879 static DECLCALLBACK(int) stac9220ResetNode(PHDACODEC pThis, uint8_t uNID, PCODECNODE pNode) 880 { 881 LogFlowFunc(("NID=0x%x (%RU8)\n", uNID, uNID)); 882 883 if ( !pThis->fInReset 884 && ( uNID != STAC9220_NID_ROOT 885 && uNID != STAC9220_NID_AFG) 886 ) 887 { 888 RT_ZERO(pNode->node); 889 } 890 891 /* Set common parameters across all nodes. */ 892 pNode->node.id = uNID; 893 894 switch (uNID) 895 { 896 /* Root node. */ 897 case STAC9220_NID_ROOT: 898 { 899 /* Set the revision ID. */ 900 pNode->root.node.au32F00_param[0x02] = CODEC_MAKE_F00_02(0x1, 0x0, 0x3, 0x4, 0x0, 0x1); 878 901 break; 879 case 1: 880 pNode->node.au32F00_param[0x08] = CODEC_MAKE_F00_08(1, 0xd, 0xd); 881 pNode->node.au32F00_param[0x0C] = CODEC_MAKE_F00_0C(0x17) 882 | CODEC_F00_0C_CAP_BALANCED_IO 883 | CODEC_F00_0C_CAP_INPUT 884 | CODEC_F00_0C_CAP_PRESENSE_DETECT 885 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 886 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//(17 << 8)|RT_BIT(6)|RT_BIT(5)|RT_BIT(2)|RT_BIT(1)|RT_BIT(0); 887 pNode->node.au32F00_param[0x0B] = CODEC_F00_0B_PCM; 888 pNode->node.au32F00_param[0x0D] = CODEC_MAKE_F00_0D(1, 0x5, 0xE, 0);//RT_BIT(31)|(0x5 << 16)|(0xE)<<8; 889 pNode->node.au32F00_param[0x12] = RT_BIT(31)|(0x2 << 16)|(0x7f << 8)|0x7f; 890 pNode->node.au32F00_param[0x11] = CODEC_MAKE_F00_11(1, 1, 0, 0, 4);//0xc0000004; 891 pNode->node.au32F00_param[0x0F] = CODEC_F00_0F_D3|CODEC_F00_0F_D2|CODEC_F00_0F_D1|CODEC_F00_0F_D0; 892 pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2);//0x2 << 4| 0x2; /* PS-Act: D3, PS->Set D3 */ 902 } 903 904 /* 905 * AFG (Audio Function Group). 906 */ 907 case STAC9220_NID_AFG: 908 { 909 pNode->afg.node.au32F00_param[0x08] = CODEC_MAKE_F00_08(1, 0xd, 0xd); 910 /* We set the AFG's PCM capabitilies fixed to 44.1kHz, 16-bit signed. */ 911 pNode->afg.node.au32F00_param[0x0A] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT; 912 pNode->afg.node.au32F00_param[0x0B] = CODEC_F00_0B_PCM; 913 pNode->afg.node.au32F00_param[0x0C] = CODEC_MAKE_F00_0C(0x17) 914 | CODEC_F00_0C_CAP_BALANCED_IO 915 | CODEC_F00_0C_CAP_INPUT 916 | CODEC_F00_0C_CAP_OUTPUT 917 | CODEC_F00_0C_CAP_PRESENSE_DETECT 918 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 919 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE; 920 921 /* Default input amplifier capabilities. */ 922 pNode->node.au32F00_param[0x0D] = CODEC_MAKE_F00_0D(CODEC_AMP_CAP_MUTE, 923 0 /* Step size */, 924 CODEC_AMP_NUM_STEPS, 925 0 /* Initial offset */); 926 /* Default output amplifier capabilities. */ 927 pNode->node.au32F00_param[0x12] = CODEC_MAKE_F00_12(CODEC_AMP_CAP_MUTE, 928 CODEC_AMP_STEP_SIZE, 929 CODEC_AMP_NUM_STEPS, 930 CODEC_AMP_OFF_INITIAL); 931 932 pNode->afg.node.au32F00_param[0x11] = CODEC_MAKE_F00_11(1, 1, 0, 0, 4); 933 pNode->afg.node.au32F00_param[0x0F] = CODEC_F00_0F_D3 934 | CODEC_F00_0F_D2 935 | CODEC_F00_0F_D1 936 | CODEC_F00_0F_D0; 937 938 pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2); /* PS-Act: D2, PS->Set D2. */ 893 939 pNode->afg.u32F08_param = 0; 894 940 pNode->afg.u32F17_param = 0; 895 941 break; 896 case 2: 897 case 3: 898 case 4: 899 case 5: 900 memset(pNode->dac.B_params, 0, AMPLIFIER_SIZE); 901 pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 4)|0x1; /* 44100Hz/16bit/2ch */ 902 903 AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) = 0x7F | RT_BIT(7); 942 } 943 944 /* 945 * DACs. 946 */ 947 case STAC9220_NID_DAC0: /* DAC0: Headphones 0 + 1 */ 948 case STAC9220_NID_DAC1: /* DAC1: PIN C */ 949 case STAC9220_NID_DAC2: /* DAC2: PIN B */ 950 case STAC9220_NID_DAC3: /* DAC3: PIN F */ 951 { 952 pNode->dac.u32A_param = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ, 953 HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT, 954 HDA_SDFMT_CHAN_STEREO); 955 956 /* 7.3.4.6: Audio widget capabilities. */ 957 pNode->dac.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 13, 0) 958 | CODEC_F00_09_CAP_L_R_SWAP 959 | CODEC_F00_09_CAP_POWER_CTRL 960 | CODEC_F00_09_CAP_OUT_AMP_PRESENT 961 | CODEC_F00_09_CAP_STEREO; 962 963 /* Connection list; must be 0 if the only connection for the widget is 964 * to the High Definition Audio Link. */ 965 pNode->dac.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 0 /* Entries */); 966 967 pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3); 968 969 RT_ZERO(pNode->dac.B_params); 970 AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) = 0x7F | RT_BIT(7); 904 971 AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) = 0x7F | RT_BIT(7); 905 906 pNode->dac.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0xD, 0)907 | CODEC_F00_09_CAP_L_R_SWAP908 | CODEC_F00_09_CAP_POWER_CTRL909 | CODEC_F00_09_CAP_OUT_AMP_PRESENT910 | CODEC_F00_09_CAP_LSB;//(0xD << 16) | RT_BIT(11) | RT_BIT(10) | RT_BIT(2) | RT_BIT(0);911 pNode->dac.u32F0c_param = 0;912 pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3 */913 972 break; 914 case 6: 915 pNode->node.au32F02_param[0] = 0x17; 973 } 974 975 /* 976 * ADCs. 977 */ 978 case STAC9220_NID_ADC0: /* Analog input. */ 979 { 980 pNode->node.au32F02_param[0] = STAC9220_NID_AMP_ADC0; 916 981 goto adc_init; 917 case 7: 918 pNode->node.au32F02_param[0] = 0x18; 982 } 983 984 case STAC9220_NID_ADC1: /* Analog input (CD). */ 985 { 986 pNode->node.au32F02_param[0] = STAC9220_NID_AMP_ADC1; 987 988 /* Fall through is intentional. */ 919 989 adc_init: 920 pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 3)|0x1; /* 44100Hz/16bit/2ch */ 921 pNode->adc.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//RT_BIT(0); 990 991 pNode->adc.u32A_param = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ, 992 HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT, 993 HDA_SDFMT_CHAN_STEREO); 994 922 995 pNode->adc.u32F03_param = RT_BIT(0); 923 pNode->adc.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 Set: D3 */ 924 pNode->adc.u32F06_param = 0; 925 pNode->adc.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0xD, 0) 926 | CODEC_F00_09_CAP_POWER_CTRL 927 | CODEC_F00_09_CAP_CONNECTION_LIST 928 | CODEC_F00_09_CAP_PROC_WIDGET 929 | CODEC_F00_09_CAP_LSB;//RT_BIT(20)| (0xd << 16) | RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0); 996 pNode->adc.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3); /* PS-Act: D3 Set: D3 */ 997 998 pNode->adc.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 13, 0) 999 | CODEC_F00_09_CAP_POWER_CTRL 1000 | CODEC_F00_09_CAP_CONNECTION_LIST 1001 | CODEC_F00_09_CAP_PROC_WIDGET 1002 | CODEC_F00_09_CAP_STEREO; 1003 /* Connection list entries. */ 1004 pNode->adc.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */); 930 1005 break; 931 case 8: 932 pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1; 933 pNode->spdifout.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x4, 0) 934 | CODEC_F00_09_CAP_DIGITAL 935 | CODEC_F00_09_CAP_FMT_OVERRIDE 936 | CODEC_F00_09_CAP_LSB;//(4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1; 937 pNode->node.au32F00_param[0xa] = pThis->paNodes[1].node.au32F00_param[0xA]; 938 pNode->spdifout.node.au32F00_param[0xB] = CODEC_F00_0B_PCM; 1006 } 1007 1008 /* 1009 * SP/DIF In/Out. 1010 */ 1011 case STAC9220_NID_SPDIF_OUT: 1012 { 1013 pNode->spdifout.u32A_param = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ, 1014 HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT, 1015 HDA_SDFMT_CHAN_STEREO); 939 1016 pNode->spdifout.u32F06_param = 0; 940 1017 pNode->spdifout.u32F0d_param = 0; 1018 1019 pNode->spdifout.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 4, 0) 1020 | CODEC_F00_09_CAP_DIGITAL 1021 | CODEC_F00_09_CAP_FMT_OVERRIDE 1022 | CODEC_F00_09_CAP_STEREO; 1023 1024 /* Use a fixed format from AFG. */ 1025 pNode->spdifout.node.au32F00_param[0xA] = pThis->paNodes[STAC9220_NID_AFG].node.au32F00_param[0xA]; 1026 pNode->spdifout.node.au32F00_param[0xB] = CODEC_F00_0B_PCM; 941 1027 break; 942 case 9: 943 pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(0x1<<4) | 0x1; 944 pNode->spdifin.node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 0x4, 0) 945 | CODEC_F00_09_CAP_DIGITAL 946 | CODEC_F00_09_CAP_CONNECTION_LIST 947 | CODEC_F00_09_CAP_FMT_OVERRIDE 948 | CODEC_F00_09_CAP_LSB;//(0x1 << 20)|(4 << 16) | RT_BIT(9)| RT_BIT(8)|RT_BIT(4)|0x1; 949 pNode->node.au32F00_param[0xA] = pThis->paNodes[1].node.au32F00_param[0xA]; 950 pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//RT_BIT(0); 951 pNode->node.au32F02_param[0] = 0x11; 1028 } 1029 1030 case STAC9220_NID_SPDIF_IN: 1031 { 1032 pNode->spdifin.u32A_param = CODEC_MAKE_A(HDA_SDFMT_TYPE_PCM, HDA_SDFMT_BASE_44KHZ, 1033 HDA_SDFMT_MULT_1X, HDA_SDFMT_DIV_1X, HDA_SDFMT_16_BIT, 1034 HDA_SDFMT_CHAN_STEREO); 1035 1036 pNode->spdifin.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_INPUT, 4, 0) 1037 | CODEC_F00_09_CAP_DIGITAL 1038 | CODEC_F00_09_CAP_CONNECTION_LIST 1039 | CODEC_F00_09_CAP_FMT_OVERRIDE 1040 | CODEC_F00_09_CAP_STEREO; 1041 1042 /* Use a fixed format from AFG. */ 1043 pNode->spdifin.node.au32F00_param[0xA] = pThis->paNodes[STAC9220_NID_AFG].node.au32F00_param[0xA]; 952 1044 pNode->spdifin.node.au32F00_param[0xB] = CODEC_F00_0B_PCM; 953 pNode->spdifin.u32F06_param = 0; 954 pNode->spdifin.u32F0d_param = 0; 1045 1046 /* Connection list entries. */ 1047 pNode->spdifin.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */); 1048 pNode->spdifin.node.au32F02_param[0] = 0x11; 955 1049 break; 956 case 0xA: 957 pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 958 | CODEC_F00_0C_CAP_INPUT 959 | CODEC_F00_0C_CAP_OUTPUT 960 | CODEC_F00_0C_CAP_HP 961 | CODEC_F00_0C_CAP_PRESENSE_DETECT 962 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 963 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x173f; 964 pNode->node.au32F02_param[0] = 0x2; 965 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE 966 | CODEC_F07_OUT_ENABLE; 967 pNode->port.u32F08_param = 0; 1050 } 1051 1052 /* 1053 * PINs / Ports. 1054 */ 1055 case STAC9220_NID_PIN_HEADPHONE0: /* Port A: Headphone in/out (front). */ 1056 { 1057 pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 1058 | CODEC_F00_0C_CAP_INPUT 1059 | CODEC_F00_0C_CAP_OUTPUT 1060 | CODEC_F00_0C_CAP_HEADPHONE_AMP 1061 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1062 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED; 1063 1064 /* Connection list entry 0: Goes to DAC0. */ 1065 pNode->port.node.au32F02_param[0] = STAC9220_NID_DAC0; 1066 968 1067 if (!pThis->fInReset) 969 1068 pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, … … 972 1071 CODEC_F1C_CONNECTION_TYPE_1_8INCHES, 973 1072 CODEC_F1C_COLOR_GREEN, 974 CODEC_F1C_MISC_JACK_DETECT, 975 0x2, 0);//RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02); 976 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff; 1073 CODEC_F1C_MISC_NONE, 1074 CODEC_F1C_ASSOCIATION_GROUP_0, 0xF /* Seq */); 977 1075 goto port_init; 978 case 0xB: 979 pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 980 | CODEC_F00_0C_CAP_INPUT 981 | CODEC_F00_0C_CAP_OUTPUT 982 | CODEC_F00_0C_CAP_PRESENSE_DETECT 983 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 984 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737; 985 pNode->node.au32F02_param[0] = 0x4; 986 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE; 1076 } 1077 1078 case STAC9220_NID_PIN_B: /* Port B: Rear CLFE (Center / Subwoofer). */ 1079 { 1080 pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 1081 | CODEC_F00_0C_CAP_INPUT 1082 | CODEC_F00_0C_CAP_OUTPUT 1083 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1084 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED; 1085 1086 /* Connection list entry 0: Goes to DAC2. */ 1087 pNode->port.node.au32F02_param[0] = STAC9220_NID_DAC2; 1088 987 1089 if (!pThis->fInReset) 988 1090 pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, 989 CODEC_F1C_LOCATION_ INTERNAL|CODEC_F1C_LOCATION_REAR,1091 CODEC_F1C_LOCATION_REAR, 990 1092 CODEC_F1C_DEVICE_SPEAKER, 991 1093 CODEC_F1C_CONNECTION_TYPE_1_8INCHES, 992 1094 CODEC_F1C_COLOR_BLACK, 993 CODEC_F1C_MISC_JACK_DETECT, 994 0x1, 0x1);//RT_MAKE_U32_FROM_U8(0x11, 0x60, 0x11, 0x01); 995 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff; 1095 CODEC_F1C_MISC_NONE, 1096 CODEC_F1C_ASSOCIATION_GROUP_1, 0xE /* Seq */); 996 1097 goto port_init; 997 case 0xC: 998 pNode->node.au32F02_param[0] = 0x3; 999 pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 1000 | CODEC_F00_0C_CAP_INPUT 1001 | CODEC_F00_0C_CAP_OUTPUT 1002 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1003 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 1004 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737; 1005 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE; 1098 } 1099 1100 case STAC9220_NID_PIN_C: /* Rear Speaker. */ 1101 { 1102 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA); 1103 1104 pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 1105 | CODEC_F00_0C_CAP_INPUT 1106 | CODEC_F00_0C_CAP_OUTPUT 1107 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1108 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED; 1109 1110 /* Connection list entry 0: Goes to DAC1. */ 1111 pNode->port.node.au32F02_param[0x0] = STAC9220_NID_DAC1; 1112 1006 1113 if (!pThis->fInReset) 1007 1114 pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, … … 1010 1117 CODEC_F1C_CONNECTION_TYPE_1_8INCHES, 1011 1118 CODEC_F1C_COLOR_GREEN, 1012 0x0, 0x1, 0x0);//RT_MAKE_U32_FROM_U8(0x10, 0x40, 0x11, 0x01);1013 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff;1119 CODEC_F1C_MISC_NONE, 1120 CODEC_F1C_ASSOCIATION_GROUP_0, 0x0 /* Seq */); 1014 1121 goto port_init; 1015 case 0xD: 1016 pNode->node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 1017 | CODEC_F00_0C_CAP_INPUT 1018 | CODEC_F00_0C_CAP_OUTPUT 1019 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1020 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 1021 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737; 1022 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE; 1023 pNode->node.au32F02_param[0] = 0x2; 1122 } 1123 1124 case STAC9220_NID_PIN_HEADPHONE1: /* Also known as PIN_D. */ 1125 { 1126 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA); 1127 1128 pNode->port.node.au32F00_param[0xC] = CODEC_MAKE_F00_0C(0x17) 1129 | CODEC_F00_0C_CAP_INPUT 1130 | CODEC_F00_0C_CAP_OUTPUT 1131 | CODEC_F00_0C_CAP_HEADPHONE_AMP 1132 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1133 | CODEC_F00_0C_CAP_TRIGGER_REQUIRED; 1134 1135 /* Connection list entry 0: Goes to DAC1. */ 1136 pNode->port.node.au32F02_param[0x0] = STAC9220_NID_DAC0; 1137 1024 1138 if (!pThis->fInReset) 1025 1139 pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, … … 1028 1142 CODEC_F1C_CONNECTION_TYPE_1_8INCHES, 1029 1143 CODEC_F1C_COLOR_PINK, 1030 0x0, 0x5, 0x0);//RT_MAKE_U32_FROM_U8(0x50, 0x90, 0xA1, 0x02); /* Microphone */ 1031 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(1, CODEC_F09_ANALOG_NA);//RT_BIT(31)|0x7fffffff; 1144 CODEC_F1C_MISC_NONE, 1145 CODEC_F1C_ASSOCIATION_GROUP_15, 0xD /* Seq */); 1146 /* Fall through is intentional. */ 1032 1147 port_init: 1148 1149 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE 1150 | CODEC_F07_OUT_ENABLE; 1033 1151 pNode->port.u32F08_param = 0; 1034 pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0) 1035 | CODEC_F00_09_CAP_CONNECTION_LIST 1036 | CODEC_F00_09_CAP_UNSOL 1037 | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(0); 1038 pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1; 1152 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(true /* fPresent */, CODEC_F09_ANALOG_NA); 1153 1154 pNode->port.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1155 | CODEC_F00_09_CAP_CONNECTION_LIST 1156 | CODEC_F00_09_CAP_UNSOL 1157 | CODEC_F00_09_CAP_STEREO; 1158 /* Connection list entries. */ 1159 pNode->port.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */); 1039 1160 break; 1040 case 0xE: 1041 pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0) 1042 | CODEC_F00_09_CAP_UNSOL 1043 | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(7)|RT_BIT(0); 1161 } 1162 1163 case STAC9220_NID_PIN_E: 1164 { 1165 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE; 1044 1166 pNode->port.u32F08_param = 0; 1045 pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT 1046 | CODEC_F00_0C_CAP_OUTPUT 1047 | CODEC_F00_0C_CAP_PRESENSE_DETECT;//0x34; 1048 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE; 1049 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff; 1167 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(true /* fPresent */, CODEC_F09_ANALOG_NA); 1168 1169 pNode->port.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1170 | CODEC_F00_09_CAP_UNSOL 1171 | CODEC_F00_09_CAP_STEREO; 1172 pNode->port.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT 1173 | CODEC_F00_0C_CAP_PRESENSE_DETECT; 1174 1050 1175 if (!pThis->fInReset) 1051 1176 pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, 1052 1177 CODEC_F1C_LOCATION_REAR, 1053 CODEC_F1C_DEVICE_LINE_ OUT,1178 CODEC_F1C_DEVICE_LINE_IN, 1054 1179 CODEC_F1C_CONNECTION_TYPE_1_8INCHES, 1055 1180 CODEC_F1C_COLOR_BLUE, 1056 0x0, 0x4, 0x0);//0x01013040; /* Line Out */ 1181 CODEC_F1C_MISC_NONE, 1182 CODEC_F1C_ASSOCIATION_GROUP_15, 0xE /* Seq */); 1057 1183 break; 1058 case 0xF: 1059 pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0) 1060 | CODEC_F00_09_CAP_CONNECTION_LIST 1061 | CODEC_F00_09_CAP_UNSOL 1062 | CODEC_F00_09_CAP_OUT_AMP_PRESENT 1063 | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(2)|RT_BIT(0); 1064 pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT 1065 | CODEC_F00_0C_CAP_OUTPUT 1066 | CODEC_F00_0C_CAP_PRESENSE_DETECT 1067 /* | CODEC_F00_0C_CAP_TRIGGER_REQUIRED 1068 | CODEC_F00_0C_CAP_IMPENDANCE_SENSE */;//0x37; 1069 pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 1);//0x1; 1184 } 1185 1186 case STAC9220_NID_PIN_F: 1187 { 1188 pNode->port.u32F07_param = CODEC_F07_IN_ENABLE | CODEC_F07_OUT_ENABLE; 1070 1189 pNode->port.u32F08_param = 0; 1071 pNode->port.u32F07_param = CODEC_F07_OUT_ENABLE 1072 | CODEC_F07_IN_ENABLE; 1190 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(true /* fPresent */, CODEC_F09_ANALOG_NA); 1191 1192 pNode->port.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1193 | CODEC_F00_09_CAP_CONNECTION_LIST 1194 | CODEC_F00_09_CAP_UNSOL 1195 | CODEC_F00_09_CAP_OUT_AMP_PRESENT 1196 | CODEC_F00_09_CAP_STEREO; 1197 pNode->port.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT 1198 | CODEC_F00_0C_CAP_OUTPUT; 1199 1200 /* Connection list entry 0: Goes to DAC3. */ 1201 pNode->port.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */); 1202 pNode->port.node.au32F02_param[0x0] = STAC9220_NID_DAC3; 1203 1073 1204 if (!pThis->fInReset) 1074 1205 pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, … … 1077 1208 CODEC_F1C_CONNECTION_TYPE_1_8INCHES, 1078 1209 CODEC_F1C_COLOR_ORANGE, 1079 0x0, 0x1, 0x2);//RT_MAKE_U32_FROM_U8(0x12, 0x60, 0x11, 0x01); 1080 pNode->node.au32F02_param[0] = 0x5; 1081 pNode->port.u32F09_param = CODEC_MAKE_F09_ANALOG(0, CODEC_F09_ANALOG_NA);//0x7fffffff; 1210 CODEC_F1C_MISC_NONE, 1211 CODEC_F1C_ASSOCIATION_GROUP_1, 0x0 /* Seq */); 1082 1212 break; 1083 case 0x10: 1084 pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0x0, 0x0) 1085 | CODEC_F00_09_CAP_DIGITAL 1086 | CODEC_F00_09_CAP_CONNECTION_LIST 1087 | CODEC_F00_09_CAP_LSB;//(4<<20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0); 1088 pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;//RT_BIT(4); 1089 pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 0x3); 1090 pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x08, 0x17, 0x19, 0); 1213 } 1214 1215 case STAC9220_NID_PIN_SPDIF_OUT: /* Rear SPDIF Out. */ 1216 { 1217 pNode->digout.u32F07_param = CODEC_F07_OUT_ENABLE; 1218 pNode->digout.u32F09_param = 0; 1219 1220 pNode->digout.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1221 | CODEC_F00_09_CAP_DIGITAL 1222 | CODEC_F00_09_CAP_CONNECTION_LIST 1223 | CODEC_F00_09_CAP_STEREO; 1224 pNode->digout.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT 1225 | CODEC_F00_0C_CAP_PRESENSE_DETECT; 1226 1227 /* Connection list entries. */ 1228 pNode->digout.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 3 /* Entries */); 1229 pNode->digout.node.au32F02_param[0x0] = RT_MAKE_U32_FROM_U8(STAC9220_NID_SPDIF_OUT, 1230 STAC9220_NID_AMP_ADC0, STAC9221_NID_ADAT_OUT, 0); 1091 1231 if (!pThis->fInReset) 1092 1232 pNode->digout.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, … … 1095 1235 CODEC_F1C_CONNECTION_TYPE_DIN, 1096 1236 CODEC_F1C_COLOR_BLACK, 1097 0x0, 0x3, 0x0);//RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01); 1237 CODEC_F1C_MISC_NONE, 1238 CODEC_F1C_ASSOCIATION_GROUP_2, 0x0 /* Seq */); 1098 1239 break; 1099 case 0x11: 1100 pNode->node.au32F00_param[9] = (4 << 20) | (3 << 16) | RT_BIT(10) | RT_BIT(9) | RT_BIT(7) | RT_BIT(0); 1101 pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_EAPD 1102 | CODEC_F00_0C_CAP_INPUT 1103 | CODEC_F00_0C_CAP_PRESENSE_DETECT;//RT_BIT(16)| RT_BIT(5)|RT_BIT(2); 1104 pNode->digin.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 -> D3 */ 1105 pNode->digin.u32F07_param = 0; 1240 } 1241 1242 case STAC9220_NID_PIN_SPDIF_IN: 1243 { 1244 pNode->digin.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3); /* PS-Act: D3 -> D3 */ 1245 pNode->digin.u32F07_param = CODEC_F07_IN_ENABLE; 1106 1246 pNode->digin.u32F08_param = 0; 1107 1247 pNode->digin.u32F09_param = CODEC_MAKE_F09_DIGITAL(0, 0); 1108 1248 pNode->digin.u32F0c_param = 0; 1249 1250 pNode->digin.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 3, 0) 1251 | CODEC_F00_09_CAP_POWER_CTRL 1252 | CODEC_F00_09_CAP_DIGITAL 1253 | CODEC_F00_09_CAP_UNSOL 1254 | CODEC_F00_09_CAP_STEREO; 1255 1256 pNode->digin.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_EAPD 1257 | CODEC_F00_0C_CAP_INPUT 1258 | CODEC_F00_0C_CAP_PRESENSE_DETECT; 1109 1259 if (!pThis->fInReset) 1110 1260 pNode->digin.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX, … … 1113 1263 CODEC_F1C_CONNECTION_TYPE_OTHER_DIGITAL, 1114 1264 CODEC_F1C_COLOR_BLACK, 1115 0x0, 0x6, 0x0);//(0x1 << 24) | (0xc5 << 16) | (0x10 << 8) | 0x60; 1265 CODEC_F1C_MISC_NONE, 1266 CODEC_F1C_ASSOCIATION_GROUP_3, 0x0 /* Seq */); 1116 1267 break; 1117 case 0x12: 1118 pNode->adcmux.u32F01_param = 0; 1268 } 1269 1270 case STAC9220_NID_ADC0_MUX: 1271 { 1272 pNode->adcmux.u32F01_param = 0; /* Connection select control index (STAC9220_NID_PIN_E). */ 1119 1273 goto adcmux_init; 1120 case 0x13: 1121 pNode->adcmux.u32F01_param = 1; 1122 adcmux_init: 1123 pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0x0, 0) 1124 | CODEC_F00_09_CAP_CONNECTION_LIST 1125 | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE 1126 | CODEC_F00_09_CAP_OUT_AMP_PRESENT 1127 | CODEC_F00_09_CAP_LSB;//(3<<20)|RT_BIT(8)|RT_BIT(3)|RT_BIT(2)|RT_BIT(0); 1128 pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x7); 1129 pNode->node.au32F00_param[0x12] = (0x27 << 16)|(0x4 << 8); 1130 /* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplefiers inited with 0*/ 1131 memset(pNode->adcmux.B_params, 0, AMPLIFIER_SIZE); 1132 pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xe, 0x15, 0xf, 0xb); 1133 pNode->node.au32F02_param[4] = RT_MAKE_U32_FROM_U8(0xc, 0xd, 0xa, 0x0); 1274 } 1275 1276 case STAC9220_NID_ADC1_MUX: 1277 { 1278 pNode->adcmux.u32F01_param = 1; /* Connection select control index (STAC9220_NID_PIN_CD). */ 1279 1280 /* Fall through is intentional. */ 1281 adcmux_init: 1282 1283 pNode->adcmux.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0) 1284 | CODEC_F00_09_CAP_CONNECTION_LIST 1285 | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE 1286 | CODEC_F00_09_CAP_OUT_AMP_PRESENT 1287 | CODEC_F00_09_CAP_STEREO; 1288 1289 pNode->adcmux.node.au32F00_param[0xD] = CODEC_MAKE_F00_0D(0, 27, 4, 0); 1290 1291 /* Connection list entries. */ 1292 pNode->adcmux.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 7 /* Entries */); 1293 pNode->adcmux.node.au32F02_param[0x0] = RT_MAKE_U32_FROM_U8(STAC9220_NID_PIN_E, 1294 STAC9220_NID_PIN_CD, 1295 STAC9220_NID_PIN_F, 1296 STAC9220_NID_PIN_B); 1297 pNode->adcmux.node.au32F02_param[0x4] = RT_MAKE_U32_FROM_U8(STAC9220_NID_PIN_C, 1298 STAC9220_NID_PIN_HEADPHONE1, 1299 STAC9220_NID_PIN_HEADPHONE0, 1300 0x0 /* Unused */); 1301 1302 /* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplifiers initialized with 0. */ 1303 RT_BZERO(pNode->adcmux.B_params, AMPLIFIER_SIZE); 1134 1304 break; 1135 case 0x14: 1136 pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0) 1137 | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE 1138 | CODEC_F00_09_CAP_OUT_AMP_PRESENT;//(7 << 20) | RT_BIT(3) | RT_BIT(2); 1139 pNode->node.au32F00_param[0x12] = (0x17 << 16)|(0x3 << 8)| 0x3; 1305 } 1306 1307 case STAC9220_NID_PCBEEP: 1308 { 1140 1309 pNode->pcbeep.u32F0a_param = 0; 1141 memset(pNode->pcbeep.B_params, 0, AMPLIFIER_SIZE); 1310 1311 pNode->pcbeep.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0) 1312 | CODEC_F00_09_CAP_AMP_FMT_OVERRIDE 1313 | CODEC_F00_09_CAP_OUT_AMP_PRESENT; 1314 pNode->pcbeep.node.au32F00_param[0xD] = CODEC_MAKE_F00_0D(0, 17, 3, 3); 1315 1316 RT_BZERO(pNode->pcbeep.B_params, AMPLIFIER_SIZE); 1142 1317 break; 1143 case 0x15: 1144 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1145 | CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(0); 1146 pNode->node.au32F00_param[0xc] = CODEC_F00_0C_CAP_INPUT;//RT_BIT(5); 1318 } 1319 1320 case STAC9220_NID_PIN_CD: 1321 { 1322 pNode->cdnode.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1323 | CODEC_F00_09_CAP_STEREO; 1324 pNode->cdnode.node.au32F00_param[0xC] = CODEC_F00_0C_CAP_INPUT; 1325 1147 1326 if (!pThis->fInReset) 1148 1327 pNode->cdnode.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_FIXED, … … 1151 1330 CODEC_F1C_CONNECTION_TYPE_ATAPI, 1152 1331 CODEC_F1C_COLOR_UNKNOWN, 1153 0x0, 0x7, 0x0);//RT_MAKE_U32_FROM_U8(0x70, 0x0, 0x33, 0x90); 1332 CODEC_F1C_MISC_NONE, 1333 CODEC_F1C_ASSOCIATION_GROUP_15, 0xF /* Seq */); 1154 1334 break; 1155 case 0x16: 1156 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0x0, 0x0);//(0x6 << 20); 1157 pNode->node.au32F00_param[0x13] = RT_BIT(7)| 0x7F; 1158 pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x4); 1159 pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0x2, 0x3, 0x4, 0x5); 1335 } 1336 1337 case STAC9220_NID_VOL_KNOB: 1338 { 1160 1339 pNode->volumeKnob.u32F08_param = 0; 1161 1340 pNode->volumeKnob.u32F0f_param = 0x7f; 1341 1342 pNode->volumeKnob.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0, 0); 1343 pNode->volumeKnob.node.au32F00_param[0xD] = RT_BIT(7) | 0x7F; 1344 1345 /* Connection list entries. */ 1346 pNode->volumeKnob.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 4 /* Entries */); 1347 pNode->volumeKnob.node.au32F02_param[0x0] = RT_MAKE_U32_FROM_U8(STAC9220_NID_DAC0, 1348 STAC9220_NID_DAC1, 1349 STAC9220_NID_DAC2, 1350 STAC9220_NID_DAC3); 1162 1351 break; 1163 case 0x17: 1164 pNode->node.au32F02_param[0] = 0x12; 1352 } 1353 1354 case STAC9220_NID_AMP_ADC0: 1355 { 1356 pNode->adcvol.node.au32F02_param[0] = STAC9220_NID_ADC0_MUX; 1165 1357 goto adcvol_init; 1166 case 0x18: 1167 pNode->node.au32F02_param[0] = 0x13; 1358 } 1359 1360 case STAC9220_NID_AMP_ADC1: 1361 { 1362 pNode->adcvol.node.au32F02_param[0] = STAC9220_NID_ADC1_MUX; 1363 1364 /* Fall through is intentional. */ 1168 1365 adcvol_init: 1169 memset(pNode->adcvol.B_params, 0, AMPLIFIER_SIZE); 1170 1171 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0) 1172 | CODEC_F00_09_CAP_L_R_SWAP 1173 | CODEC_F00_09_CAP_CONNECTION_LIST 1174 | CODEC_F00_09_CAP_IN_AMP_PRESENT 1175 | CODEC_F00_09_CAP_LSB;//(0x3 << 20)|RT_BIT(11)|RT_BIT(8)|RT_BIT(1)|RT_BIT(0); 1176 pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x1); 1177 AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(7); 1366 1367 pNode->adcvol.u32F0c_param = 0; 1368 1369 pNode->adcvol.node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_SELECTOR, 0, 0) 1370 | CODEC_F00_09_CAP_L_R_SWAP 1371 | CODEC_F00_09_CAP_CONNECTION_LIST 1372 | CODEC_F00_09_CAP_IN_AMP_PRESENT 1373 | CODEC_F00_09_CAP_STEREO; 1374 1375 1376 pNode->adcvol.node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */); 1377 1378 RT_BZERO(pNode->adcvol.B_params, AMPLIFIER_SIZE); 1379 AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_LEFT, 0) = RT_BIT(7); 1178 1380 AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(7); 1179 pNode->adcvol.u32F0c_param = 0;1180 1381 break; 1181 case 0x19: 1182 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VENDOR_DEFINED, 0x3, 0) 1382 } 1383 1384 /* 1385 * STAC9221 nodes. 1386 */ 1387 1388 case STAC9221_NID_ADAT_OUT: 1389 { 1390 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VENDOR_DEFINED, 3, 0) 1183 1391 | CODEC_F00_09_CAP_DIGITAL 1184 | CODEC_F00_09_CAP_ LSB;//(0xF << 20)|(0x3 << 16)|RT_BIT(9)|RT_BIT(0);1392 | CODEC_F00_09_CAP_STEREO; 1185 1393 break; 1186 case 0x1A: 1187 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 0x3, 0) 1394 } 1395 1396 case STAC9221_NID_I2S_OUT: 1397 { 1398 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_AUDIO_OUTPUT, 3, 0) 1188 1399 | CODEC_F00_09_CAP_DIGITAL 1189 | CODEC_F00_09_CAP_ LSB;//(0x3 << 16)|RT_BIT(9)|RT_BIT(0);1400 | CODEC_F00_09_CAP_STEREO; 1190 1401 break; 1191 case 0x1B: 1402 } 1403 1404 case STAC9221_NID_PIN_I2S_OUT: 1405 { 1192 1406 pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0) 1193 1407 | CODEC_F00_09_CAP_DIGITAL 1194 1408 | CODEC_F00_09_CAP_CONNECTION_LIST 1195 | CODEC_F00_09_CAP_LSB;//(0x4 << 20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0); 1196 pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(0, 0x1); 1197 pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT;//0x10; 1198 pNode->node.au32F02_param[0] = 0x1a; 1199 pNode->reserved.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_NO_PHYS, 1200 CODEC_F1C_LOCATION_NA, 1201 CODEC_F1C_DEVICE_LINE_OUT, 1202 CODEC_F1C_CONNECTION_TYPE_UNKNOWN, 1203 CODEC_F1C_COLOR_UNKNOWN, 1204 0x0, 0x0, 0xf);//0x4000000f; 1409 | CODEC_F00_09_CAP_STEREO; 1410 pNode->node.au32F00_param[0xC] = CODEC_F00_0C_CAP_OUTPUT; 1411 1412 /* Connection list entries. */ 1413 pNode->node.au32F00_param[0xE] = CODEC_MAKE_F00_0E(CODEC_F00_0E_LIST_NID_SHORT, 1 /* Entries */); 1414 pNode->node.au32F02_param[0] = STAC9221_NID_I2S_OUT; 1415 1416 if (!pThis->fInReset) 1417 pNode->reserved.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_NO_PHYS, 1418 CODEC_F1C_LOCATION_NA, 1419 CODEC_F1C_DEVICE_LINE_OUT, 1420 CODEC_F1C_CONNECTION_TYPE_UNKNOWN, 1421 CODEC_F1C_COLOR_UNKNOWN, 1422 CODEC_F1C_MISC_NONE, 1423 CODEC_F1C_ASSOCIATION_GROUP_15, 0xB /* Seq */); 1205 1424 break; 1425 } 1426 1206 1427 default: 1207 break; 1208 } 1428 AssertMsgFailed(("Node %RU8 not implemented\n", uNID)); 1429 break; 1430 } 1431 1209 1432 return VINF_SUCCESS; 1210 1433 } … … 1213 1436 static int stac9220Construct(PHDACODEC pThis) 1214 1437 { 1215 unconst(pThis->cTotalNodes) = 0x1C; 1438 unconst(pThis->cTotalNodes) = STAC9221_NUM_NODES; 1439 1216 1440 pThis->pfnCodecNodeReset = stac9220ResetNode; 1217 pThis->pfnDbgListNodes = stac9220DbgNodes; 1218 pThis->u16VendorId = 0x8384; 1219 pThis->u16DeviceId = 0x7680; 1220 pThis->u8BSKU = 0x76; 1441 1442 pThis->u16VendorId = 0x8384; /* SigmaTel */ 1443 /* 1444 * Note: The Linux kernel uses "patch_stac922x" for the fixups, 1445 * which in turn uses "ref922x_pin_configs" for the configuration 1446 * defaults tweaking in sound/pci/hda/patch_sigmatel.c. 1447 */ 1448 pThis->u16DeviceId = 0x7680; /* STAC9221 A1 */ 1449 pThis->u8BSKU = 0x76; 1221 1450 pThis->u8AssemblyId = 0x80; 1451 1222 1452 pThis->paNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pThis->cTotalNodes); 1223 1453 if (!pThis->paNodes) 1224 1454 return VERR_NO_MEMORY; 1455 1225 1456 pThis->fInReset = false; 1457 1226 1458 #define STAC9220WIDGET(type) pThis->au8##type##s = g_abStac9220##type##s 1227 1459 STAC9220WIDGET(Port); … … 1239 1471 STAC9220WIDGET(Reserved); 1240 1472 #undef STAC9220WIDGET 1241 unconst(pThis->u8AdcVolsLineIn) = 0x17; 1242 unconst(pThis->u8DacLineOut) = 0x3; 1473 1474 unconst(pThis->u8AdcVolsLineIn) = STAC9220_NID_AMP_ADC0; 1475 unconst(pThis->u8DacLineOut) = STAC9220_NID_DAC1; 1243 1476 1244 1477 return VINF_SUCCESS; … … 1290 1523 * Misc helpers. 1291 1524 */ 1292 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL mt) 1293 { 1294 uint32_t dir = AMPLIFIER_OUT; 1295 ENMSOUNDSOURCE enmSrc; 1296 switch (mt) 1297 { 1298 case PDMAUDIOMIXERCTL_PCM: 1299 enmSrc = PO_INDEX; 1300 dir = AMPLIFIER_OUT; 1525 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl) 1526 { 1527 uint8_t iDir; 1528 switch (enmMixerCtl) 1529 { 1530 case PDMAUDIOMIXERCTL_VOLUME: 1531 case PDMAUDIOMIXERCTL_FRONT: 1532 iDir = AMPLIFIER_OUT; 1301 1533 break; 1302 1534 case PDMAUDIOMIXERCTL_LINE_IN: 1303 enmSrc = PI_INDEX;1304 dir = AMPLIFIER_IN;1535 case PDMAUDIOMIXERCTL_MIC_IN: 1536 iDir = AMPLIFIER_IN; 1305 1537 break; 1306 1538 default: 1307 AssertMsgFailedReturn(("Invalid mixer control %ld\n", mt), VERR_INVALID_PARAMETER);1539 AssertMsgFailedReturn(("Invalid mixer control %ld\n", enmMixerCtl), VERR_INVALID_PARAMETER); 1308 1540 break; 1309 1541 } 1310 1542 1311 int mute = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & RT_BIT(7); 1312 mute |= AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & RT_BIT(7); 1313 mute >>=7; 1314 mute &= 0x1; 1315 uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f; 1316 uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f; 1317 1318 /* The STAC9220 volume controls have 0 to -96dB attenuation range in 128 steps. 1543 int iMute; 1544 iMute = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_LEFT, 0) & RT_BIT(7); 1545 iMute |= AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_RIGHT, 0) & RT_BIT(7); 1546 iMute >>=7; 1547 iMute &= 0x1; 1548 1549 uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_LEFT, 0) & 0x7f; 1550 uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_RIGHT, 0) & 0x7f; 1551 1552 /* 1553 * The STAC9220 volume controls have 0 to -96dB attenuation range in 128 steps. 1319 1554 * We have 0 to -96dB range in 256 steps. HDA volume setting of 127 must map 1320 1555 * to 255 internally (0dB), while HDA volume setting of 0 (-96dB) should map … … 1324 1559 rVol = (rVol + 1) * (2 * 255) / 256; 1325 1560 1326 return pThis->pfnSetVolume(pThis->pHDAState, enmSrc, RT_BOOL(mute), lVol, rVol); 1561 PDMAUDIOVOLUME Vol = { RT_BOOL(iMute), lVol, rVol }; 1562 return pThis->pfnMixerSetVolume(pThis->pHDAState, enmMixerCtl, &Vol); 1327 1563 } 1328 1564 … … 1426 1662 u8Index); 1427 1663 else 1428 LogRel2(("HDA: Unhandled get amplifier command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));1664 LogRel2(("HDA: Warning: Unhandled get amplifier command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd))); 1429 1665 1430 1666 return VINF_SUCCESS; … … 1454 1690 pAmplifier = &pNode->adc.B_params; 1455 1691 else 1456 LogRel2(("HDA: Unhandled set amplifier command: 0x%x (Payload=%RU16, NID=0x%x [%RU8])\n",1692 LogRel2(("HDA: Warning: Unhandled set amplifier command: 0x%x (Payload=%RU16, NID=0x%x [%RU8])\n", 1457 1693 cmd, CODEC_VERB_PAYLOAD16(cmd), CODEC_NID(cmd))); 1458 1694 … … 1488 1724 1489 1725 if (CODEC_NID(cmd) == pThis->u8DacLineOut) 1490 hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_ PCM);1726 hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_FRONT); 1491 1727 } 1492 1728 … … 1531 1767 *pResp = pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param; 1532 1768 else 1533 LogRel2(("HDA: Unhandled get pin control command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));1769 LogRel2(("HDA: Warning: Unhandled get connection select control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1534 1770 1535 1771 return VINF_SUCCESS; … … 1556 1792 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param; 1557 1793 else 1558 LogRel2(("HDA: Unhandled set connection select control command: 0x%x (Payload=0x%x, NID=0x%x [%RU8])\n", 1559 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 1794 LogRel2(("HDA: Warning: Unhandled set connection select control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1560 1795 1561 1796 if (pu32Reg) … … 1586 1821 *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param; 1587 1822 else 1588 LogRel2(("HDA: Unhandled get pin control command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));1823 LogRel2(("HDA: Warning: Unhandled get pin control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1589 1824 1590 1825 return VINF_SUCCESS; … … 1614 1849 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param; 1615 1850 else 1616 LogRel2(("HDA: Unhandled set pin control command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 1617 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 1851 LogRel2(("HDA: Warning: Unhandled set pin control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1618 1852 1619 1853 if (pu32Reg) … … 1635 1869 else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd))) 1636 1870 *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param; 1637 else if ((cmd) == 1 /* AFG */)1871 else if ((cmd) == STAC9220_NID_AFG) 1638 1872 *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param; 1639 1873 else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd))) … … 1644 1878 *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param; 1645 1879 else 1646 LogRel2(("HDA: Unhandled get unsolicited enabled command: 0x%x (NID=0x%x [%RU8])\n", 1647 cmd, CODEC_NID(cmd))); 1880 LogRel2(("HDA: Warning: Unhandled get unsolicited enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1648 1881 1649 1882 return VINF_SUCCESS; … … 1663 1896 else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd))) 1664 1897 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param; 1665 else if (CODEC_NID(cmd) == 1 /* AFG */)1898 else if (CODEC_NID(cmd) == STAC9220_NID_AFG) 1666 1899 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param; 1667 1900 else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd))) … … 1672 1905 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F08_param; 1673 1906 else 1674 LogRel2(("HDA: Unhandled set unsolicited enabled command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 1675 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 1907 LogRel2(("HDA: Warning: Unhandled set unsolicited enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1676 1908 1677 1909 if (pu32Reg) … … 1694 1926 *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param; 1695 1927 else 1696 LogRel2(("HDA: Unhandled get pin sense command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));1928 LogRel2(("HDA: Warning: Unhandled get pin sense command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1697 1929 1698 1930 return VINF_SUCCESS; … … 1713 1945 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param; 1714 1946 else 1715 LogRel2(("HDA: Unhandled set pin sense command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 1716 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 1947 LogRel2(("HDA: Warning: Unhandled set pin sense command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1717 1948 1718 1949 if (pu32Reg) … … 1818 2049 return VINF_SUCCESS; 1819 2050 } 1820 if (CODEC_NID(cmd) == 1 /* AFG */)2051 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 1821 2052 *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param; 1822 2053 else … … 1835 2066 } 1836 2067 uint32_t *pu32Reg; 1837 if (CODEC_NID(cmd) == 0x1 /* AFG */)2068 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 1838 2069 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param; 1839 2070 else … … 1874 2105 { 1875 2106 Assert(CODEC_CAD(cmd) == pThis->id); 1876 Assert(CODEC_NID(cmd) == 1 /* AFG */);1877 if ( CODEC_NID(cmd) == 1 /* AFG */2107 Assert(CODEC_NID(cmd) == STAC9220_NID_AFG); 2108 if ( CODEC_NID(cmd) == STAC9220_NID_AFG 1878 2109 && pThis->pfnCodecNodeReset) 1879 2110 { … … 1900 2131 *pResp = 0; 1901 2132 1902 if (CODEC_NID(cmd) == 1 /* AFG */)2133 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 1903 2134 *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param; 1904 2135 else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd))) … … 1906 2137 else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd))) 1907 2138 *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param; 2139 else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd))) 2140 *pResp = pThis->paNodes[CODEC_NID(cmd)].digout.u32F05_param; 1908 2141 else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd))) 1909 2142 *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param; … … 1915 2148 *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param; 1916 2149 else 1917 LogRel2(("HDA: Unhandled get power state command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd))); 1918 1919 return VINF_SUCCESS; 1920 } 1921 1922 DECLINLINE(void) codecPropogatePowerState(uint32_t *pu32F05_param) 1923 { 1924 AssertPtr(pu32F05_param); 1925 if (!pu32F05_param) 1926 return; 1927 1928 bool fReset = CODEC_F05_IS_RESET(*pu32F05_param); 1929 bool fStopOk = CODEC_F05_IS_STOPOK(*pu32F05_param); 1930 uint8_t u8SetPowerState = CODEC_F05_SET(*pu32F05_param); 1931 1932 *pu32F05_param = CODEC_MAKE_F05(fReset, fStopOk, 0, u8SetPowerState, u8SetPowerState); 2150 LogRel2(("HDA: Warning: Unhandled get power state command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2151 2152 LogFunc(("NID=0x%x, fReset=%RTbool, fStopOk=%RTbool, Set=%RU8, Act=%RU8\n", 2153 CODEC_NID(cmd), CODEC_F05_IS_RESET(*pResp), CODEC_F05_IS_STOPOK(*pResp), CODEC_F05_SET(*pResp), CODEC_F05_ACT(*pResp))); 2154 return VINF_SUCCESS; 1933 2155 } 1934 2156 … … 1942 2164 1943 2165 uint32_t *pu32Reg = NULL; 1944 if (CODEC_NID(cmd) == 1 /* AFG */)2166 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 1945 2167 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param; 1946 2168 else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd))) … … 1948 2170 else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd))) 1949 2171 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F05_param; 2172 else if (hdaCodecIsDigOutPinNode(pThis, CODEC_NID(cmd))) 2173 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F05_param; 1950 2174 else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd))) 1951 2175 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param; … … 1957 2181 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param; 1958 2182 else 1959 LogRel2(("HDA: Unhandled set power state command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 1960 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2183 LogRel2(("HDA: Warning: Unhandled set power state command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 1961 2184 1962 2185 if (!pu32Reg) 1963 2186 return VINF_SUCCESS; 1964 2187 1965 bool fReset = CODEC_F05_IS_RESET(*pu32Reg); 1966 bool fStopOk = CODEC_F05_IS_STOPOK(*pu32Reg); 1967 1968 if (CODEC_NID(cmd) != 1 /* AFG */) 1969 { 1970 /* 1971 * We shouldn't propogate actual power state, which actual for AFG 1972 */ 2188 bool fReset = CODEC_F05_IS_RESET (*pu32Reg); 2189 bool fStopOk = CODEC_F05_IS_STOPOK(*pu32Reg); 2190 uint8_t uPwrAct = CODEC_F05_ACT (*pu32Reg); 2191 uint8_t uPwrSet = CODEC_F05_SET (*pu32Reg); 2192 uint8_t uPwrCmd = CODEC_F05_SET (cmd); 2193 2194 LogFunc(("[NID=0x%x] Cmd=D%RU8, Act=D%RU8, Set=D%RU8 (AFG Act=D%RU8, Set=D%RU8)\n", 2195 CODEC_NID(cmd), uPwrCmd, uPwrAct, uPwrSet, 2196 CODEC_F05_ACT(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param), 2197 CODEC_F05_SET(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param))); 2198 2199 const uint8_t uAFGPwrSet = CODEC_F05_SET(pThis->paNodes[STAC9220_NID_AFG].afg.u32F05_param); 2200 2201 /* If this is the AFG node, PS-Act always matches the PS-Set power state.*/ 2202 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 2203 { 2204 *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, uPwrCmd /* PS-Act */, uPwrCmd /* PS-Set */); 2205 2206 /* Propagate to all other nodes under this AFG. */ 2207 LogFunc(("Propagating Set=D%RU8 to all nodes ...\n", uPwrCmd)); 2208 2209 #define PROPAGATE_PWR_STATE(_aList, _aMember) \ 2210 { \ 2211 const uint8_t *pu8NodeIndex = &_aList[0]; \ 2212 while (*(pu8NodeIndex++)) \ 2213 { \ 2214 pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param = \ 2215 CODEC_MAKE_F05(fReset, fStopOk, 0, RT_MIN((uAFGPwrSet + 1), CODEC_F05_D3), \ 2216 uPwrCmd /* Always update PS-Set with command power state just received. */); \ 2217 LogFunc(("\t[NID=0x%x]: Act=D%RU8, Set=D%RU8\n", *pu8NodeIndex, \ 2218 CODEC_F05_ACT(pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param), \ 2219 CODEC_F05_SET(pThis->paNodes[*pu8NodeIndex]._aMember.u32F05_param))); \ 2220 } \ 2221 } 2222 2223 PROPAGATE_PWR_STATE(pThis->au8Dacs, dac); 2224 PROPAGATE_PWR_STATE(pThis->au8Adcs, adc); 2225 PROPAGATE_PWR_STATE(pThis->au8DigInPins, digin); 2226 PROPAGATE_PWR_STATE(pThis->au8DigOutPins, digout); 2227 PROPAGATE_PWR_STATE(pThis->au8SpdifIns, spdifin); 2228 PROPAGATE_PWR_STATE(pThis->au8SpdifOuts, spdifout); 2229 PROPAGATE_PWR_STATE(pThis->au8Reserveds, reserved); 2230 2231 #undef PROPAGATE_PWR_STATE 2232 } 2233 /* 2234 * If this node is a reqular node (not the AFG one), adpopt PS-Set of the AFG node 2235 * as PS-Set of this node. PS-Act always is one level under PS-Set here. 2236 */ 2237 else 2238 { 1973 2239 *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, 1974 CODEC_F05_ACT(pThis->paNodes[1].afg.u32F05_param), 1975 CODEC_F05_SET(cmd)); 1976 } 1977 1978 /* Propagate next power state only if AFG is on or verb modifies AFG power state */ 1979 if ( CODEC_NID(cmd) == 1 /* AFG */ 1980 || !CODEC_F05_ACT(pThis->paNodes[1].afg.u32F05_param)) 1981 { 1982 *pu32Reg = CODEC_MAKE_F05(fReset, fStopOk, 0, CODEC_F05_SET(cmd), CODEC_F05_SET(cmd)); 1983 if ( CODEC_NID(cmd) == 1 /* AFG */ 1984 && (CODEC_F05_SET(cmd)) == CODEC_F05_D0) 1985 { 1986 /* now we're powered on AFG and may propogate power states on nodes */ 1987 const uint8_t *pu8NodeIndex = &pThis->au8Dacs[0]; 1988 while (*(++pu8NodeIndex)) 1989 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].dac.u32F05_param); 1990 1991 pu8NodeIndex = &pThis->au8Adcs[0]; 1992 while (*(++pu8NodeIndex)) 1993 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].adc.u32F05_param); 1994 1995 pu8NodeIndex = &pThis->au8DigInPins[0]; 1996 while (*(++pu8NodeIndex)) 1997 codecPropogatePowerState(&pThis->paNodes[*pu8NodeIndex].digin.u32F05_param); 1998 } 1999 } 2240 RT_MIN((uAFGPwrSet + 1), CODEC_F05_D3), 2241 uPwrCmd /* Always update PS-Set with command power state just received. */); 2242 } 2243 2244 if (pu32Reg) 2245 hdaCodecSetRegisterU8(pu32Reg, cmd, 0); 2246 2247 LogFunc(("[NID=0x%x] fReset=%RTbool, fStopOk=%RTbool, Act=D%RU8, Set=D%RU8\n", 2248 CODEC_NID(cmd), fReset, fStopOk, CODEC_F05_ACT(*pu32Reg), CODEC_F05_SET(*pu32Reg))); 2249 2000 2250 return VINF_SUCCESS; 2001 2251 } … … 2016 2266 else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd))) 2017 2267 *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifout.u32F06_param; 2018 else if (CODEC_NID(cmd) == 0x1A)2268 else if (CODEC_NID(cmd) == STAC9221_NID_I2S_OUT) 2019 2269 *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param; 2020 2270 else 2021 LogRel2(("HDA: Unhandled get stream ID command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd))); 2271 LogRel2(("HDA: Warning: Unhandled get stream ID command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2272 2273 LogFlowFunc(("[NID0x%x] Stream ID is 0x%x\n", 2274 CODEC_NID(cmd), CODEC_F00_06_GET_STREAM_ID(*pResp))); 2022 2275 2023 2276 return VINF_SUCCESS; … … 2044 2297 pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param; 2045 2298 else 2046 LogRel2(("HDA: Unhandled set stream ID command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 2047 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2299 LogRel2(("HDA: Warning: Unhandled set stream ID command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2300 2301 LogFlowFunc(("[NID0x%x] Setting new stream ID to 0x%x\n", 2302 CODEC_NID(cmd), CODEC_F00_06_GET_STREAM_ID(cmd))); 2048 2303 2049 2304 if (pu32Addr) … … 2053 2308 } 2054 2309 2055 /* F06*/2310 /* A0 */ 2056 2311 static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2057 2312 { … … 2069 2324 else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd))) 2070 2325 *pResp = pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param; 2326 else if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd))) 2327 *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32A_param; 2071 2328 else 2072 LogRel2(("HDA: Unhandled get power state command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd))); 2073 2074 return VINF_SUCCESS; 2075 } 2076 2329 LogRel2(("HDA: Warning: Unhandled get converter format command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2330 2331 return VINF_SUCCESS; 2332 } 2333 2334 /* Also see section 3.7.1. */ 2077 2335 static DECLCALLBACK(int) vrbProcSetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2078 2336 { … … 2091 2349 hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0); 2092 2350 else 2093 LogRel2(("HDA: Unhandled set converter format command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 2094 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2351 LogRel2(("HDA: Warning: Unhandled set converter format command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2095 2352 2096 2353 return VINF_SUCCESS; … … 2112 2369 *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param; 2113 2370 else 2114 LogRel2(("HDA: Unhandled get EAPD/BTL enable command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));2371 LogRel2(("HDA: Warning: Unhandled get EAPD/BTL enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2115 2372 2116 2373 return VINF_SUCCESS; … … 2133 2390 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param; 2134 2391 else 2135 LogRel2(("HDA: Unhandled set EAPD/BTL enable command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 2136 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2392 LogRel2(("HDA: Warning: Unhandled set EAPD/BTL enabled command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2137 2393 2138 2394 if (pu32Reg) … … 2153 2409 *pResp = pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param; 2154 2410 else 2155 LogRel2(("HDA: Unhandled get volume knob control command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));2411 LogRel2(("HDA: Warning: Unhandled get volume knob control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2156 2412 2157 2413 return VINF_SUCCESS; … … 2170 2426 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param; 2171 2427 else 2172 LogRel2(("HDA: Unhandled set volume control command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 2173 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2428 LogRel2(("HDA: Warning: Unhandled set volume knob control command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2174 2429 2175 2430 if (pu32Reg) … … 2179 2434 } 2180 2435 2436 /* F15 */ 2437 static DECLCALLBACK(int) vrbProcGetGPIOData(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2438 { 2439 if (!vrbIsValidNode(pThis, cmd, pResp)) 2440 return VINF_SUCCESS; 2441 2442 *pResp = 0; 2443 2444 return VINF_SUCCESS; 2445 } 2446 2447 /* 715 */ 2448 static DECLCALLBACK(int) vrbProcSetGPIOData(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2449 { 2450 if (!vrbIsValidNode(pThis, cmd, pResp)) 2451 return VINF_SUCCESS; 2452 2453 *pResp = 0; 2454 2455 return VINF_SUCCESS; 2456 } 2457 2458 /* F16 */ 2459 static DECLCALLBACK(int) vrbProcGetGPIOEnableMask(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2460 { 2461 if (!vrbIsValidNode(pThis, cmd, pResp)) 2462 return VINF_SUCCESS; 2463 2464 *pResp = 0; 2465 2466 return VINF_SUCCESS; 2467 } 2468 2469 /* 716 */ 2470 static DECLCALLBACK(int) vrbProcSetGPIOEnableMask(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2471 { 2472 if (!vrbIsValidNode(pThis, cmd, pResp)) 2473 return VINF_SUCCESS; 2474 2475 *pResp = 0; 2476 2477 return VINF_SUCCESS; 2478 } 2479 2181 2480 /* F17 */ 2182 2481 static DECLCALLBACK(int) vrbProcGetGPIOUnsolisted(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) … … 2188 2487 2189 2488 /* Note: this is true for ALC885. */ 2190 if (CODEC_NID(cmd) == 0x1 /* AFG */)2489 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 2191 2490 *pResp = pThis->paNodes[1].afg.u32F17_param; 2192 2491 else 2193 LogRel2(("HDA: Unhandled get GPIO unsolisted command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));2492 LogRel2(("HDA: Warning: Unhandled get GPIO unsolisted command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2194 2493 2195 2494 return VINF_SUCCESS; … … 2205 2504 2206 2505 uint32_t *pu32Reg = NULL; 2207 if (CODEC_NID(cmd) == 1 /* AFG */)2506 if (CODEC_NID(cmd) == STAC9220_NID_AFG) 2208 2507 pu32Reg = &pThis->paNodes[1].afg.u32F17_param; 2209 2508 else 2210 LogRel2(("HDA: Unhandled set GPIO unsolisted command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 2211 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2509 LogRel2(("HDA: Warning: Unhandled set GPIO unsolisted command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2212 2510 2213 2511 if (pu32Reg) … … 2238 2536 *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param; 2239 2537 else 2240 LogRel2(("HDA: Unhandled get config command: 0x%x (NID=0x%x [%RU8])\n", cmd, CODEC_NID(cmd)));2538 LogRel2(("HDA: Warning: Unhandled get config command for NID0x%x: 0x%x\n", CODEC_NID(cmd), cmd)); 2241 2539 2242 2540 return VINF_SUCCESS; … … 2259 2557 pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param; 2260 2558 else 2261 LogRel2(("HDA: Unhandled set config command: 0x%x (Payload=%RU8, NID=0x%x [%RU8])\n", 2262 cmd, CODEC_VERB_PAYLOAD8(cmd), CODEC_NID(cmd))); 2559 LogRel2(("HDA: Warning: Unhandled set config command (%RU8) for NID0x%x: 0x%x\n", u8Offset, CODEC_NID(cmd), cmd)); 2263 2560 2264 2561 if (pu32Reg) … … 2346 2643 { 0x000F0F00, CODEC_VERB_8BIT_CMD , vrbProcGetVolumeKnobCtrl }, 2347 2644 { 0x00070F00, CODEC_VERB_8BIT_CMD , vrbProcSetVolumeKnobCtrl }, 2645 { 0x000F1500, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOData }, 2646 { 0x00071500, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOData }, 2647 { 0x000F1600, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOEnableMask }, 2648 { 0x00071600, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOEnableMask }, 2348 2649 { 0x000F1700, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOUnsolisted }, 2349 2650 { 0x00071700, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOUnsolisted }, … … 2357 2658 { 0x000B0000, CODEC_VERB_16BIT_CMD, vrbProcGetAmplifier }, 2358 2659 { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcSetAmplifier }, 2660 /** @todo Implement 0x7e7: IDT Set GPIO (STAC922x only). */ 2359 2661 }; 2360 2662 … … 2581 2883 { 2582 2884 Assert(CODEC_CAD(cmd) == pThis->id); 2583 if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))2584 LogFlowFunc(("cmd %x was addressed to reserved node\n", cmd));2585 2885 2586 2886 if ( CODEC_VERBDATA(cmd) == 0 … … 2588 2888 { 2589 2889 *pfn = vrbProcUnimplemented; 2590 /// @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp) 2591 LogFlowFunc(("cmd %x was ignored\n", cmd)); 2592 return VINF_SUCCESS; 2593 } 2594 2595 for (int i = 0; i < pThis->cVerbs; ++i) 2890 AssertMsgFailed(("Unknown / invalid node 0x%x\n", CODEC_NID(cmd))); 2891 return VINF_SUCCESS; 2892 } 2893 2894 for (int i = 0; i < pThis->cVerbs; i++) 2596 2895 { 2597 2896 if ((CODEC_VERBDATA(cmd) & pThis->paVerbs[i].mask) == pThis->paVerbs[i].verb) … … 2603 2902 2604 2903 *pfn = vrbProcUnimplemented; 2605 LogFlowFunc(("callback for %x wasn't found\n", CODEC_VERBDATA(cmd))); 2904 2905 LogFlowFunc(("[NID0x%x] Callback for %x not found\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd))); 2606 2906 return VINF_SUCCESS; 2607 2907 } … … 2611 2911 */ 2612 2912 2613 /** 2614 * 2615 * routines open one of the voices (IN, OUT) with corresponding parameters. 2616 * this routine could be called from HDA on setting/resseting sound format. 2617 * 2618 * @todo Probably passed settings should be verified (if AFG's declared proposed 2619 * format) before enabling. 2620 */ 2621 int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg) 2913 int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg) 2622 2914 { 2623 2915 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2624 2625 int rc; 2626 switch (enmSoundSource) 2627 { 2628 case PI_INDEX: 2629 rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.in", PDMAUDIORECSOURCE_LINE_IN, pCfg); 2916 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 2917 2918 int rc = VINF_SUCCESS; 2919 2920 switch (enmMixerCtl) 2921 { 2922 case PDMAUDIOMIXERCTL_LINE_IN: 2923 #ifdef VBOX_WITH_HDA_MIC_IN 2924 case PDMAUDIOMIXERCTL_MIC_IN: 2925 #endif 2926 { 2927 pCfg->enmDir = PDMAUDIODIR_IN; 2630 2928 break; 2631 #ifdef VBOX_WITH_HDA_MIC_IN 2632 case MC_INDEX: 2633 rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.mc", PDMAUDIORECSOURCE_MIC, pCfg); 2929 } 2930 2931 case PDMAUDIOMIXERCTL_VOLUME: 2932 case PDMAUDIOMIXERCTL_FRONT: 2933 { 2934 pCfg->enmDir = PDMAUDIODIR_OUT; 2634 2935 break; 2635 #endif 2636 case PO_INDEX: 2637 rc = pThis->pfnOpenOut(pThis->pHDAState, "hda.out", pCfg); 2936 } 2937 2938 default: 2939 AssertMsgFailed(("Mixer control %ld not implemented\n", enmMixerCtl)); 2940 rc = VERR_NOT_IMPLEMENTED; 2638 2941 break; 2639 2640 default: 2641 AssertMsgFailed(("Index %ld not implemented\n", enmSoundSource)); 2642 rc = VERR_NOT_IMPLEMENTED; 2643 } 2942 } 2943 2944 if (RT_SUCCESS(rc)) 2945 rc = pThis->pfnMixerAddStream(pThis->pHDAState, enmMixerCtl, pCfg); 2644 2946 2645 2947 LogFlowFuncLeaveRC(rc); … … 2647 2949 } 2648 2950 2951 int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl) 2952 { 2953 return VINF_SUCCESS; 2954 } 2955 2649 2956 int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM) 2650 2957 { 2651 AssertLogRelMsgReturn(pThis->cTotalNodes == 0x1c, ("cTotalNodes=%#x, should be 0x1c", pThis->cTotalNodes),2958 AssertLogRelMsgReturn(pThis->cTotalNodes == STAC9221_NUM_NODES, ("cTotalNodes=%#x, should be 0x1c", pThis->cTotalNodes), 2652 2959 VERR_INTERNAL_ERROR); 2653 2960 SSMR3PutU32(pSSM, pThis->cTotalNodes); … … 2715 3022 */ 2716 3023 if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut)) 2717 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_ PCM);3024 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_FRONT); 2718 3025 else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut)) 2719 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_ PCM);3026 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_FRONT); 2720 3027 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 2721 3028 … … 2740 3047 { 2741 3048 AssertPtrReturn(pDevIns, VERR_INVALID_POINTER); 2742 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2743 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 2744 2745 pThis->id = uLUN; 2746 pThis->paVerbs = &g_aCodecVerbs[0]; 2747 pThis->cVerbs = RT_ELEMENTS(g_aCodecVerbs); 2748 2749 pThis->pfnLookup = codecLookup; 3049 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3050 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 3051 3052 pThis->id = uLUN; 3053 pThis->paVerbs = &g_aCodecVerbs[0]; 3054 pThis->cVerbs = RT_ELEMENTS(g_aCodecVerbs); 3055 2750 3056 #ifdef DEBUG 2751 3057 pThis->pfnDbgSelector = codecDbgSelector; 2752 3058 pThis->pfnDbgListNodes = codecDbgListNodes; 2753 3059 #endif 3060 pThis->pfnLookup = codecLookup; 3061 2754 3062 int rc = stac9220Construct(pThis); 2755 3063 AssertRC(rc); 2756 3064 2757 /* common root node initializers */ 2758 pThis->paNodes[0].node.au32F00_param[0] = CODEC_MAKE_F00_00(pThis->u16VendorId, pThis->u16DeviceId); 2759 pThis->paNodes[0].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1); 2760 /* common AFG node initializers */ 2761 pThis->paNodes[1].node.au32F00_param[4] = CODEC_MAKE_F00_04(0x2, pThis->cTotalNodes - 2); 2762 pThis->paNodes[1].node.au32F00_param[5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG); 2763 pThis->paNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId); 2764 2765 /* This codec uses a fixed setting (44.1 kHz, 16-bit signed, 2 channels). */ 2766 pThis->strmCfg.uHz = 44100; 2767 pThis->strmCfg.cChannels = 2; 2768 pThis->strmCfg.enmFormat = AUD_FMT_S16; 2769 pThis->strmCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 2770 2771 hdaCodecOpenStream(pThis, PI_INDEX, &pThis->strmCfg); 3065 /* Common root node initializers. */ 3066 pThis->paNodes[STAC9220_NID_ROOT].root.node.au32F00_param[0] = CODEC_MAKE_F00_00(pThis->u16VendorId, pThis->u16DeviceId); 3067 pThis->paNodes[STAC9220_NID_ROOT].root.node.au32F00_param[4] = CODEC_MAKE_F00_04(0x1, 0x1); 3068 3069 /* Common AFG node initializers. */ 3070 pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x4] = CODEC_MAKE_F00_04(0x2, pThis->cTotalNodes - 2); 3071 pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0x5] = CODEC_MAKE_F00_05(1, CODEC_F00_05_AFG); 3072 pThis->paNodes[STAC9220_NID_AFG].afg.node.au32F00_param[0xA] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT; 3073 pThis->paNodes[STAC9220_NID_AFG].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId); 3074 3075 /* Initialize the streams to some default values (44.1 kHz, 16-bit signed, 2 channels). 3076 * The codec's (fixed) delivery rate is 48kHz, so a frame will be delivered every 20.83us. */ 3077 PDMAUDIOSTREAMCFG strmCfg; 3078 strmCfg.uHz = 44100; 3079 strmCfg.cChannels = 2; 3080 strmCfg.enmFormat = AUD_FMT_S16; 3081 strmCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 3082 3083 /* 3084 * Output streams. 3085 */ 3086 strmCfg.enmDir = PDMAUDIODIR_OUT; 3087 3088 /* Front. */ 3089 strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 3090 rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_FRONT, &strmCfg); 3091 AssertRC(rc); 3092 3093 #ifdef VBOX_WITH_HDA_51_SURROUND 3094 /* Center / LFE. */ 3095 strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_CENTER_LFE; 3096 rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_CENTER_LFE, &strmCfg); 3097 AssertRC(rc); 3098 3099 /* Rear. */ 3100 strmCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_REAR; 3101 rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_REAR, &strmCfg); 3102 AssertRC(rc); 3103 #endif 3104 3105 /* 3106 * Input streams. 3107 */ 3108 strmCfg.enmDir = PDMAUDIODIR_IN; 3109 2772 3110 #ifdef VBOX_WITH_HDA_MIC_IN 2773 hdaCodecOpenStream(pThis, MC_INDEX, &pThis->strmCfg); 3111 strmCfg.DestSource.Source = PDMAUDIORECSOURCE_MIC; 3112 rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_MIC_IN, &strmCfg); 3113 AssertRC(rc); 2774 3114 #endif 2775 hdaCodecOpenStream(pThis, PO_INDEX, &pThis->strmCfg); 2776 2777 /* Initialize the AFG node with the fixed setting. */ 2778 pThis->paNodes[1].node.au32F00_param[0xA] = CODEC_F00_0A_44_1KHZ | CODEC_F00_0A_16_BIT; 2779 3115 strmCfg.DestSource.Source = PDMAUDIORECSOURCE_LINE; 3116 rc = hdaCodecAddStream(pThis, PDMAUDIOMIXERCTL_LINE_IN, &strmCfg); 3117 AssertRC(rc); 3118 3119 /* 3120 * Reset nodes. 3121 */ 2780 3122 AssertPtr(pThis->paNodes); 2781 3123 AssertPtr(pThis->pfnCodecNodeReset); … … 2784 3126 pThis->pfnCodecNodeReset(pThis, i, &pThis->paNodes[i]); 2785 3127 2786 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_PCM); 3128 /* 3129 * Set initial volume. 3130 */ 3131 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_FRONT); 2787 3132 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 2788 2789 return VINF_SUCCESS; 2790 } 2791 3133 #ifdef VBOX_WITH_HDA_MIC_IN 3134 #error "Implement mic-in support!" 3135 #endif 3136 3137 return VINF_SUCCESS; 3138 } 3139 -
trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h
r59439 r60353 16 16 */ 17 17 18 #ifndef DEV_ CODEC_H19 #define DEV_ CODEC_H18 #ifndef DEV_HDA_CODEC_H 19 #define DEV_HDA_CODEC_H 20 20 21 21 /** The ICH HDA (Intel) controller. */ … … 39 39 #define CODEC_RESPONSE_UNSOLICITED RT_BIT_64(34) 40 40 41 42 #ifndef VBOX_WITH_HDA_CODEC_EMU43 41 typedef struct CODECVERB 44 42 { … … 48 46 PFNHDACODECVERBPROCESSOR pfn; 49 47 } CODECVERB; 50 #endif51 48 52 #ifndef VBOX_WITH_HDA_CODEC_EMU 53 # define TYPE union 54 #else 55 # define TYPE struct 56 typedef struct CODECEMU CODECEMU; 57 typedef CODECEMU *PCODECEMU; 58 #endif 59 TYPE CODECNODE; 60 typedef TYPE CODECNODE CODECNODE; 61 typedef TYPE CODECNODE *PCODECNODE; 49 union CODECNODE; 50 typedef union CODECNODE CODECNODE, *PCODECNODE; 62 51 63 typedef enum 64 { 65 PI_INDEX = 0, /**< PCM in */ 66 PO_INDEX, /**< PCM out */ 67 MC_INDEX, /**< Mic in */ 68 LAST_INDEX 69 } ENMSOUNDSOURCE; 70 52 /** 53 * Structure for keeping a HDA codec state. 54 */ 71 55 typedef struct HDACODEC 72 56 { … … 79 63 * A driver only can be assigned to one codec at a time. */ 80 64 RTLISTANCHOR lstDrv; 81 /** The codec's current audio stream configuration. */82 PDMAUDIOSTREAMCFG strmCfg;83 65 84 #ifndef VBOX_WITH_HDA_CODEC_EMU85 66 CODECVERB const *paVerbs; 86 67 int cVerbs; 87 #else 88 PCODECEMU pCodecBackend; 89 #endif 68 90 69 PCODECNODE paNodes; 91 70 /** Pointer to HDA state (controller) this … … 93 72 PHDASTATE pHDAState; 94 73 bool fInReset; 95 #ifndef VBOX_WITH_HDA_CODEC_EMU 74 96 75 const uint8_t cTotalNodes; 97 76 const uint8_t *au8Ports; … … 110 89 const uint8_t u8AdcVolsLineIn; 111 90 const uint8_t u8DacLineOut; 112 #endif 91 113 92 /** Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */ 114 DECLR3CALLBACKMEMBER(void, pfnCloseIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource)); 115 DECLR3CALLBACKMEMBER(void, pfnCloseOut, (PHDASTATE pThis)); 116 DECLR3CALLBACKMEMBER(int, pfnOpenIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg)); 117 DECLR3CALLBACKMEMBER(int, pfnOpenOut, (PHDASTATE pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg)); 118 DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PHDASTATE pThis, ENMSOUNDSOURCE enmSource, bool fMute, uint8_t uVolLeft, uint8_t uVolRight)); 93 DECLR3CALLBACKMEMBER(int, pfnMixerAddStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)); 94 DECLR3CALLBACKMEMBER(int, pfnMixerRemoveStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl)); 95 DECLR3CALLBACKMEMBER(int, pfnMixerSetVolume, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol)); 119 96 /** Callbacks by codec implementation. */ 120 97 DECLR3CALLBACKMEMBER(int, pfnLookup, (PHDACODEC pThis, uint32_t verb, PPFNHDACODECVERBPROCESSOR)); … … 130 107 int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM); 131 108 int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion); 132 int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg); 109 int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg); 110 int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl); 133 111 134 112 #define HDA_SSM_VERSION 6 … … 143 121 #define HDA_SSM_VERSION_1 1 144 122 145 # ifdef VBOX_WITH_HDA_CODEC_EMU 146 /* */ 147 struct CODECEMU 148 { 149 DECLR3CALLBACKMEMBER(int, pfnCodecEmuConstruct,(PHDACODEC pThis)); 150 DECLR3CALLBACKMEMBER(int, pfnCodecEmuDestruct,(PHDACODEC pThis)); 151 DECLR3CALLBACKMEMBER(int, pfnCodecEmuReset,(PHDACODEC pThis, bool fInit)); 152 }; 153 # endif 154 #endif 123 #endif /* DEV_HDA_CODEC_H */ 155 124 -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r59994 r60353 72 72 int drvAudioAddHstOut(PDRVAUDIO pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOHSTSTRMOUT *ppHstStrmOut) 73 73 { 74 AssertPtrReturn(pThis, VERR_INVALID_POINTER);74 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 75 75 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 76 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 77 78 PPDMAUDIOHSTSTRMOUT pHstStrmOut; 76 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 79 77 80 78 int rc; 81 if ( conf.fixed_out.enabled /** @todo Get rid of these settings! */ 82 && conf.fixed_out.greedy) 79 80 PPDMAUDIOHSTSTRMOUT pHstStrmOut = drvAudioFindSpecificOut(pThis, NULL, pCfg); 81 if (!pHstStrmOut) 83 82 { 84 83 rc = drvAudioAllocHstOut(pThis, pszName, pCfg, &pHstStrmOut); 85 } 86 else 87 rc = VERR_NOT_FOUND; 88 89 if (RT_FAILURE(rc)) 90 { 91 pHstStrmOut = drvAudioFindSpecificOut(pThis, NULL, pCfg); 92 if (!pHstStrmOut) 93 { 94 rc = drvAudioAllocHstOut(pThis, pszName, pCfg, &pHstStrmOut); 95 if (RT_FAILURE(rc)) 96 pHstStrmOut = drvAudioFindAnyHstOut(pThis, NULL /* pHstStrmOut */); 97 } 98 99 rc = pHstStrmOut ? VINF_SUCCESS : rc; 100 } 84 if (RT_FAILURE(rc)) 85 pHstStrmOut = drvAudioFindAnyHstOut(pThis, NULL /* pHstStrmOut */); 86 } 87 88 rc = pHstStrmOut ? VINF_SUCCESS : rc; 101 89 102 90 if (RT_SUCCESS(rc)) … … 106 94 } 107 95 96 #ifndef VBOX_AUDIO_TESTCASE 108 97 static PDMAUDIOFMT drvAudioGetConfFormat(PCFGMNODE pCfgHandle, const char *pszKey, 109 98 PDMAUDIOFMT enmDefault, bool *pfDefault) … … 272 261 return VINF_SUCCESS; 273 262 } 263 #endif /* !VBOX_AUDIO_TESTCASE */ 274 264 275 265 static bool drvAudioStreamCfgIsValid(PPDMAUDIOSTREAMCFG pCfg) … … 301 291 fValid |= pCfg->uHz > 0; 302 292 303 #ifdef DEBUG304 drvAudioStreamCfgPrint(pCfg);305 #endif306 307 LogFlowFunc(("pCfg=%p, fValid=%RTbool\n", pCfg, fValid));308 293 return fValid; 309 294 } … … 828 813 PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMOUT *ppGstStrmOut) 829 814 { 830 AssertPtrReturn(pThis, VERR_INVALID_POINTER);815 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 831 816 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 832 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 833 834 /* 835 * Try figuring out which audio stream configuration this backend 836 * should use. If fixed output is enabled the backend will be tied 837 * to a fixed rate (in Hz, among other parameters), regardless of 838 * what the backend could do else. 839 */ 840 PPDMAUDIOSTREAMCFG pBackendCfg; 841 if (conf.fixed_out.enabled) 842 pBackendCfg = &conf.fixed_out.settings; 843 else 844 pBackendCfg = pCfg; 845 846 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 847 848 LogFlowFunc(("Using fixed audio output settings: %RTbool\n", 849 RT_BOOL(conf.fixed_out.enabled))); 817 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 850 818 851 819 PPDMAUDIOGSTSTRMOUT pGstStrmOut = … … 861 829 */ 862 830 PPDMAUDIOHSTSTRMOUT pHstStrmOut; 863 int rc = drvAudioAddHstOut(pThis, pszName, p BackendCfg, &pHstStrmOut);831 int rc = drvAudioAddHstOut(pThis, pszName, pCfg, &pHstStrmOut); 864 832 if (RT_FAILURE(rc)) 865 833 { … … 893 861 PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMIN *ppGstStrmIn) 894 862 { 895 AssertPtrReturn(pThis, VERR_INVALID_POINTER);863 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 896 864 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 897 898 /* 899 * Try figuring out which audio stream configuration this backend 900 * should use for the audio input data. If fixed input is enabled 901 * the backend will be tied to a fixed rate (in Hz, among other parameters), 902 * regardless of what the backend initially wanted to use. 903 */ 904 PPDMAUDIOSTREAMCFG pBackendCfg; 905 if (conf.fixed_in.enabled) 906 pBackendCfg = &conf.fixed_in.settings; 907 else 908 pBackendCfg = pCfg; 909 910 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 911 912 LogFlowFunc(("Using fixed audio input settings: %RTbool\n", 913 RT_BOOL(conf.fixed_in.enabled))); 865 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 914 866 915 867 PPDMAUDIOGSTSTRMIN pGstStrmIn = (PPDMAUDIOGSTSTRMIN)RTMemAllocZ(sizeof(PDMAUDIOGSTSTRMIN)); … … 921 873 */ 922 874 PPDMAUDIOHSTSTRMIN pHstStrmIn; 923 int rc = drvAudioHstInAdd(pThis, pszName, p BackendCfg, enmRecSource, &pHstStrmIn);875 int rc = drvAudioHstInAdd(pThis, pszName, pCfg, enmRecSource, &pHstStrmIn); 924 876 if (RT_FAILURE(rc)) 925 877 { … … 1716 1668 } 1717 1669 1718 static struct audio_option audio_options[] =1719 {1720 /* DAC */1721 {"DACFixedSettings", AUD_OPT_BOOL, &conf.fixed_out.enabled,1722 "Use fixed settings for host DAC", NULL, 0},1723 1724 {"DACFixedFreq", AUD_OPT_INT, &conf.fixed_out.settings.uHz,1725 "Frequency for fixed host DAC", NULL, 0},1726 1727 {"DACFixedFmt", AUD_OPT_FMT, &conf.fixed_out.settings.enmFormat,1728 "Format for fixed host DAC", NULL, 0},1729 1730 {"DACFixedChannels", AUD_OPT_INT, &conf.fixed_out.settings.cChannels,1731 "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},1732 1733 {"DACVoices", AUD_OPT_INT, &conf.fixed_out.cStreams, /** @todo Rename! */1734 "Number of streams for DAC", NULL, 0},1735 1736 /* ADC */1737 {"ADCFixedSettings", AUD_OPT_BOOL, &conf.fixed_in.enabled,1738 "Use fixed settings for host ADC", NULL, 0},1739 1740 {"ADCFixedFreq", AUD_OPT_INT, &conf.fixed_in.settings.uHz,1741 "Frequency for fixed host ADC", NULL, 0},1742 1743 {"ADCFixedFmt", AUD_OPT_FMT, &conf.fixed_in.settings.enmFormat,1744 "Format for fixed host ADC", NULL, 0},1745 1746 {"ADCFixedChannels", AUD_OPT_INT, &conf.fixed_in.settings.cChannels,1747 "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},1748 1749 {"ADCVoices", AUD_OPT_INT, &conf.fixed_in.cStreams, /** @todo Rename! */1750 "Number of streams for ADC", NULL, 0},1751 1752 /* Misc */1753 {"TimerFreq", AUD_OPT_INT, &conf.period.hz,1754 "Timer frequency in Hz (0 - use lowest possible)", NULL, 0},1755 1756 {"PLIVE", AUD_OPT_BOOL, &conf.plive,1757 "(undocumented)", NULL, 0} /** @todo What is this? */1758 };1759 1760 1670 static DECLCALLBACK(int) drvAudioInit(PCFGMNODE pCfgHandle, PPDMDRVINS pDrvIns) 1761 1671 { … … 1774 1684 1775 1685 int rc = RTCritSectInit(&pThis->CritSect); 1776 if (RT_SUCCESS(rc)) 1777 { 1778 rc = drvAudioProcessOptions(pCfgHandle, "AUDIO", audio_options, RT_ELEMENTS(audio_options)); 1779 /** @todo Check for invalid options? */ 1780 1781 pThis->cStreamsFreeOut = conf.fixed_out.cStreams; 1782 pThis->cStreamsFreeIn = conf.fixed_in.cStreams; 1783 1784 if (!pThis->cStreamsFreeOut) 1785 pThis->cStreamsFreeOut = 1; 1786 1787 if (!pThis->cStreamsFreeIn) 1788 pThis->cStreamsFreeIn = 1; 1789 } 1686 1687 /** @todo Add audio driver options. */ 1790 1688 1791 1689 /* … … 1964 1862 1965 1863 static DECLCALLBACK(int) drvAudioCreateIn(PPDMIAUDIOCONNECTOR pInterface, const char *pszName, 1966 PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg, 1967 PPDMAUDIOGSTSTRMIN *ppGstStrmIn) 1864 PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMIN *ppGstStrmIn) 1968 1865 { 1969 1866 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1973 1870 AssertPtrReturn(ppGstStrmIn, VERR_INVALID_POINTER); 1974 1871 1872 Assert(pCfg->enmDir == PDMAUDIODIR_IN); 1873 1975 1874 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1976 1875 … … 1987 1886 } 1988 1887 1989 PPDMAUDIOGSTSTRMIN pGstStrmIn = *ppGstStrmIn; 1990 if ( RT_SUCCESS(rc) 1991 && pGstStrmIn 1992 && drvAudioPCMPropsAreEqual(&pGstStrmIn->Props, pCfg)) 1993 { 1994 LogFunc(("[%s] Exists and matches required configuration, skipping creation\n", 1995 pGstStrmIn->MixBuf.pszName)); 1996 rc = VWRN_ALREADY_EXISTS; 1997 } 1998 1999 if (rc != VINF_SUCCESS) /* Note: Can be VWRN_ALREADY_EXISTS, so don't use VINF_SUCCESS here. */ 2000 { 2001 int rc2 = RTCritSectLeave(&pThis->CritSect); 2002 AssertRC(rc2); 2003 2004 return rc; 2005 } 2006 2007 if ( !conf.fixed_in.enabled 2008 && pGstStrmIn) 2009 { 2010 drvAudioDestroyGstIn(pThis, pGstStrmIn); 2011 pGstStrmIn = NULL; 2012 } 2013 2014 if (pGstStrmIn) 2015 { 2016 PPDMAUDIOHSTSTRMIN pHstStrmIn = pGstStrmIn->pHstStrmIn; 2017 AssertPtr(pHstStrmIn); 2018 2019 drvAudioGstInFreeRes(pGstStrmIn); 2020 2021 char *pszTemp; 2022 if (RTStrAPrintf(&pszTemp, "%s (Guest)", pszName) <= 0) 2023 { 2024 RTMemFree(pGstStrmIn); 2025 2026 int rc2 = RTCritSectLeave(&pThis->CritSect); 2027 AssertRC(rc2); 2028 2029 return VERR_NO_MEMORY; 2030 } 2031 2032 rc = drvAudioGstInInit(pGstStrmIn, pHstStrmIn, pszName, pCfg); 2033 2034 RTStrFree(pszTemp); 2035 } 2036 else 2037 rc = drvAudioCreateStreamPairIn(pThis, pszName, enmRecSource, pCfg, &pGstStrmIn); 2038 2039 if (RT_SUCCESS(rc)) 2040 { 2041 if (pGstStrmIn) 1888 if (RT_SUCCESS(rc)) 1889 { 1890 PPDMAUDIOGSTSTRMIN pGstStrmIn; 1891 rc = drvAudioCreateStreamPairIn(pThis, pszName, pCfg->DestSource.Source, pCfg, &pGstStrmIn); 1892 if (RT_SUCCESS(rc)) 2042 1893 *ppGstStrmIn = pGstStrmIn; 2043 1894 } … … 2059 1910 AssertPtrReturn(ppGstStrmOut, VERR_INVALID_POINTER); 2060 1911 1912 Assert(pCfg->enmDir == PDMAUDIODIR_OUT); 1913 2061 1914 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2062 1915 … … 2073 1926 } 2074 1927 2075 PPDMAUDIOGSTSTRMOUT pGstStrmOut = *ppGstStrmOut; 2076 if ( RT_SUCCESS(rc) 2077 && pGstStrmOut 2078 && drvAudioPCMPropsAreEqual(&pGstStrmOut->Props, pCfg)) 2079 { 2080 LogFunc(("[%s] Exists and matches required configuration, skipping creation\n", 2081 pGstStrmOut->MixBuf.pszName)); 2082 2083 rc = VWRN_ALREADY_EXISTS; 2084 } 2085 2086 if (rc != VINF_SUCCESS) /* Note: Can be VWRN_ALREADY_EXISTS, so don't use VINF_SUCCESS here. */ 2087 { 2088 int rc2 = RTCritSectLeave(&pThis->CritSect); 2089 AssertRC(rc2); 2090 2091 return rc; 2092 } 2093 2094 #if 0 2095 /* Any live samples that need to be updated after 2096 * we set the new parameters? */ 2097 PPDMAUDIOGSTSTRMOUT pOldGstStrmOut = NULL; 2098 uint32_t cLiveSamples = 0; 2099 2100 if ( conf.plive 2101 && pGstStrmOut 2102 && ( !pGstStrmOut->State.fActive 2103 && !pGstStrmOut->State.fEmpty)) 2104 { 2105 cLiveSamples = pGstStrmOut->cTotalSamplesWritten; 2106 if (cLiveSamples) 2107 { 2108 pOldGstStrmOut = pGstStrmOut; 2109 pGstStrmOut = NULL; 2110 } 2111 } 2112 #endif 2113 2114 if ( pGstStrmOut 2115 && !conf.fixed_out.enabled) 2116 { 2117 drvAudioDestroyGstOut(pThis, pGstStrmOut); 2118 pGstStrmOut = NULL; 2119 } 2120 2121 if (pGstStrmOut) 2122 { 2123 PPDMAUDIOHSTSTRMOUT pHstStrmOut = pGstStrmOut->pHstStrmOut; 2124 AssertPtr(pHstStrmOut); 2125 2126 drvAudioGstOutFreeRes(pGstStrmOut); 2127 2128 rc = drvAudioGstOutInit(pGstStrmOut, pHstStrmOut, pszName, pCfg); 2129 } 2130 else 2131 { 1928 if (RT_SUCCESS(rc)) 1929 { 1930 PPDMAUDIOGSTSTRMOUT pGstStrmOut; 2132 1931 rc = drvAudioCreateStreamPairOut(pThis, pszName, pCfg, &pGstStrmOut); 2133 if (RT_FAILURE(rc)) 2134 LogFunc(("Failed to create output stream \"%s\", rc=%Rrc\n", pszName, rc)); 2135 } 2136 2137 if (RT_SUCCESS(rc)) 2138 { 2139 if (pGstStrmOut) 1932 if (RT_SUCCESS(rc)) 2140 1933 *ppGstStrmOut = pGstStrmOut; 2141 #if 02142 /* Update remaining live samples with new rate. */2143 if (cLiveSamples)2144 {2145 AssertPtr(pOldGstStrmOut);2146 2147 uint32_t cSamplesMixed =2148 (cLiveSamples << pOldGstStrmOut->Props.cShift)2149 * pOldGstStrmOut->Props.cbPerSec2150 / (*ppGstStrmOut)->Props.cbPerSec;2151 2152 pGstStrmOut->cTotalSamplesWritten += cSamplesMixed;2153 }2154 #endif2155 1934 } 2156 1935 … … 2377 2156 } 2378 2157 2379 #if def DEBUG_andy2158 #ifndef VBOX_AUDIO_TESTCASE 2380 2159 CFGMR3Dump(pCfgHandle); 2381 2160 #endif -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r59987 r60353 154 154 int DrvAudioStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMPCMPROPS pProps); 155 155 156 typedef struct fixed_settings157 {158 int enabled;159 int cStreams;160 int greedy;161 PDMAUDIOSTREAMCFG settings;162 } fixed_settings;163 164 static struct {165 struct fixed_settings fixed_out;166 struct fixed_settings fixed_in;167 union {168 int hz;169 int64_t ticks;170 } period;171 int plive;172 } conf = {173 174 /* Fixed output settings. */175 { /* DAC fixed settings */176 1, /* enabled */177 1, /* cStreams */178 1, /* greedy */179 {180 44100, /* freq */181 2, /* nchannels */182 AUD_FMT_S16, /* fmt */183 PDMAUDIOHOSTENDIANNESS184 }185 },186 187 /* Fixed input settings. */188 { /* ADC fixed settings */189 1, /* enabled */190 2, /* cStreams */191 1, /* greedy */192 {193 44100, /* freq */194 2, /* nchannels */195 AUD_FMT_S16, /* fmt */196 PDMAUDIOHOSTENDIANNESS197 }198 },199 200 { 200 }, /* frequency (in Hz) */201 0, /* plive */ /** @todo Disable pending live? */202 };203 156 #endif /* DRV_AUDIO_H */ 204 157 -
trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
r59890 r60353 71 71 case PDMAUDIORECSOURCE_VIDEO: return "Video"; 72 72 case PDMAUDIORECSOURCE_AUX: return "AUX"; 73 case PDMAUDIORECSOURCE_LINE _IN: return "Line In";73 case PDMAUDIORECSOURCE_LINE: return "Line In"; 74 74 case PDMAUDIORECSOURCE_PHONE: return "Phone"; 75 75 default: -
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r59987 r60353 907 907 } 908 908 909 case PDMAUDIORECSOURCE_LINE _IN:909 case PDMAUDIORECSOURCE_LINE: 910 910 default: 911 911 /* Try opening the default device (NULL). */ -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r60307 r60353 1902 1902 1903 1903 GEN_CHECK_SIZE(HDAINPUTSTREAM); 1904 GEN_CHECK_OFF(HDAINPUTSTREAM, p StrmIn);1905 GEN_CHECK_OFF(HDAINPUTSTREAM, p hStrmIn);1904 GEN_CHECK_OFF(HDAINPUTSTREAM, pGstStrm); 1905 GEN_CHECK_OFF(HDAINPUTSTREAM, pMixStrm); 1906 1906 1907 1907 GEN_CHECK_SIZE(HDAOUTPUTSTREAM); 1908 GEN_CHECK_OFF(HDAOUTPUTSTREAM, p StrmOut);1909 GEN_CHECK_OFF(HDAOUTPUTSTREAM, p hStrmOut);1908 GEN_CHECK_OFF(HDAOUTPUTSTREAM, pGstStrm); 1909 GEN_CHECK_OFF(HDAOUTPUTSTREAM, pMixStrm); 1910 1910 1911 1911 GEN_CHECK_SIZE(HDADRIVER); … … 1917 1917 GEN_CHECK_OFF(HDADRIVER, pConnector); 1918 1918 GEN_CHECK_OFF(HDADRIVER, LineIn); 1919 #ifdef VBOX_WITH_HDA_MIC_IN 1919 1920 GEN_CHECK_OFF(HDADRIVER, MicIn); 1920 GEN_CHECK_OFF(HDADRIVER, Out); 1921 #endif 1922 GEN_CHECK_OFF(HDADRIVER, Front); 1921 1923 1922 1924 GEN_CHECK_SIZE(HDABDLESTATE); … … 1937 1939 1938 1940 GEN_CHECK_SIZE(HDASTREAM); 1939 GEN_CHECK_OFF(HDASTREAM, u8S trm);1941 GEN_CHECK_OFF(HDASTREAM, u8SD); 1940 1942 GEN_CHECK_OFF(HDASTREAM, u64BDLBase); 1941 1943 GEN_CHECK_OFF(HDASTREAM, u16FMT); … … 1952 1954 GEN_CHECK_OFF(HDASTATE, MMIOBaseAddr); 1953 1955 GEN_CHECK_OFF(HDASTATE, au32Regs[0]); 1954 GEN_CHECK_OFF(HDASTATE, au32Regs[HDA_NREGS]); 1955 GEN_CHECK_OFF(HDASTATE, StrmStLineIn); 1956 GEN_CHECK_OFF(HDASTATE, StrmStOut); 1957 GEN_CHECK_OFF(HDASTATE, StrmStMicIn); 1956 GEN_CHECK_OFF(HDASTATE, au32Regs[HDA_NUM_REGS]); 1957 GEN_CHECK_OFF(HDASTATE, aStreams); 1958 GEN_CHECK_OFF(HDASTATE, aTags); 1958 1959 GEN_CHECK_OFF(HDASTATE, u64CORBBase); 1959 1960 GEN_CHECK_OFF(HDASTATE, u64RIRBBase); … … 1977 1978 GEN_CHECK_OFF(HDASTATE, StatBytesRead); 1978 1979 GEN_CHECK_OFF(HDASTATE, StatBytesWritten); 1979 #endif 1980 #endif /* VBOX_WITH_STATISTICS */ 1980 1981 GEN_CHECK_OFF(HDASTATE, pCodec); 1981 1982 GEN_CHECK_OFF(HDASTATE, lstDrv); 1982 1983 GEN_CHECK_OFF(HDASTATE, pMixer); 1984 GEN_CHECK_OFF(HDASTATE, pSinkFront); 1985 #ifdef VBOX_WITH_HDA_51_SURROUND 1986 GEN_CHECK_OFF(HDASTATE, pSinkCenterLFE); 1987 GEN_CHECK_OFF(HDASTATE, pSinkRear); 1988 #endif 1983 1989 GEN_CHECK_OFF(HDASTATE, pSinkLineIn); 1990 #ifdef VBOX_WITH_HDA_MIC_IN 1984 1991 GEN_CHECK_OFF(HDASTATE, pSinkMicIn); 1992 #endif 1985 1993 GEN_CHECK_OFF(HDASTATE, u64BaseTS); 1986 1994 GEN_CHECK_OFF(HDASTATE, u8RespIntCnt); 1995 #ifdef VBOX_WITH_HDA_INTERLEAVING_STREAMS_SUPPORT 1996 GEN_CHECK_OFF(HDASTATE, pCircBuf); 1997 #endif 1987 1998 1988 1999 #ifdef VBOX_WITH_NVME_IMPL
Note:
See TracChangeset
for help on using the changeset viewer.