VirtualBox

Ignore:
Timestamp:
Apr 6, 2016 11:54:39 AM (9 years ago)
Author:
vboxsync
Message:

Audio: Added HDA support for newer Linux guests; more work on surround support (disabled by default).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp

    r59541 r60353  
    3636#include "VBoxDD.h"
    3737#include "DevIchHdaCodec.h"
     38#include "DevIchHdaCommon.h"
     39#include "AudioMixer.h"
    3840
    3941
     
    103105#define CODEC_F00_00_VENDORID(f00_00)                      (((f00_00) >> 16) & 0xFFFF)
    104106#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). */
    108118#define CODEC_MAKE_F00_04(startNodeNumber, totalNodeNumber) ((((startNodeNumber) & 0xFF) << 16)|((totalNodeNumber) & 0xFF))
    109119#define CODEC_F00_04_TO_START_NODE_NUMBER(f00_04)          (((f00_04) >> 16) & 0xFF)
     
    120130#define CODEC_F00_05_IS_UNSOL(f00_05)                      RT_BOOL((f00_05) & RT_BIT(8))
    121131#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). */
    123133#define CODEC_MAKE_F00_08(BeepGen, InputDelay, OutputDelay) ((((BeepGen) & 0x1) << 16)| (((InputDelay) & 0xF) << 8) | ((OutputDelay) & 0xF))
    124134#define CODEC_F00_08_BEEP_GEN(f00_08)                      ((f00_08) & RT_BIT(16)
    125135
    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))
    131145/* note: types 0x8-0xe are reserved */
    132146#define CODEC_F00_09_TYPE_AUDIO_OUTPUT                     (0x0)
     
    152166#define CODEC_F00_09_CAP_OUT_AMP_PRESENT                   RT_BIT(2)
    153167#define CODEC_F00_09_CAP_IN_AMP_PRESENT                    RT_BIT(1)
    154 #define CODEC_F00_09_CAP_LSB                               RT_BIT(0)
     168#define CODEC_F00_09_CAP_STEREO                            RT_BIT(0)
    155169
    156170#define CODEC_F00_09_TYPE(f00_09)                          (((f00_09) >> 20) & 0xF)
     
    208222#define CODEC_F00_0C_CAP_INPUT                             RT_BIT(5)
    209223#define CODEC_F00_0C_CAP_OUTPUT                            RT_BIT(4)
    210 #define CODEC_F00_0C_CAP_HP                                RT_BIT(3)
     224#define CODEC_F00_0C_CAP_HEADPHONE_AMP                     RT_BIT(3)
    211225#define CODEC_F00_0C_CAP_PRESENSE_DETECT                   RT_BIT(2)
    212226#define CODEC_F00_0C_CAP_TRIGGER_REQUIRED                  RT_BIT(1)
     
    225239#define CODEC_F00_0C_IS_CAP_IMPENDANCE_SENSE(f00_0c)       ((f00_0c) & RT_BIT(0))
    226240
    227 /* Input Amplifier capabilities (7.3.4.10) */
     241/* Input Amplifier capabilities (7.3.4.10). */
    228242#define CODEC_MAKE_F00_0D(mute_cap, step_size, num_steps, offset) \
    229         (  (((mute_cap) & 0x1) << 31)                             \
     243        (  (((mute_cap)  & 0x1)  << 31)                           \
    230244         | (((step_size) & 0xFF) << 16)                           \
    231245         | (((num_steps) & 0xFF) << 8)                            \
    232          | ((offset) & 0xFF))
     246         |  ((offset)    & 0xFF))
    233247
    234248#define CODEC_F00_0D_CAP_MUTE                              RT_BIT(7)
     
    239253#define CODEC_F00_0D_OFFSET(f00_0d)                        (  (f00_0d) & 0x7F)
    240254
     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
    241273/* Output Amplifier capabilities (7.3.4.10) */
    242274#define CODEC_MAKE_F00_12                                  CODEC_MAKE_F00_0D
     
    247279#define CODEC_F00_12_OFFSET(f00_12)                        CODEC_F00_0D_OFFSET(f00_12)
    248280
    249 /* Connection list lenght (7.3.4.11) */
     281/* Connection list lenght (7.3.4.11). */
    250282#define CODEC_MAKE_F00_0E(long_form, length)    \
    251283    (  (((long_form) & 0x1) << 7)               \
     
    272304#define CODEC_F00_10_BENING(f00_10)                        ((f00_10) & 0x1)
    273305
    274 /* CP/IO Count (7.3.4.14) */
     306/* GPIO count (7.3.4.14). */
    275307#define CODEC_MAKE_F00_11(wake, unsol, numgpi, numgpo, numgpio) \
    276308    (  (((wake) & 0x1) << 31)                                   \
     
    280312     | ((numgpio) & 0xFF))
    281313
    282 /* Processing States (7.3.3.4) */
     314/* Processing States (7.3.3.4). */
    283315#define CODEC_F03_OFF                                      (0)
    284316#define CODEC_F03_ON                                       RT_BIT(0)
    285317#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))
    293325#define CODEC_F05_D3COLD                                   (4)
    294326#define CODEC_F05_D3                                       (3)
     
    300332#define CODEC_F05_IS_STOPOK(value)                         (((value) & RT_BIT(9)) != 0)
    301333#define CODEC_F05_IS_ERROR(value)                          (((value) & RT_BIT(8)) != 0)
    302 #define CODEC_F05_ACT(value)                               (((value) & 0x7) >> 4)
    303 #define CODEC_F05_SET(value)                               (((value) & 0x7))
     334#define CODEC_F05_ACT(value)                               (((value) & 0xF0) >> 4)
     335#define CODEC_F05_SET(value)                               (((value) & 0xF))
    304336
    305337#define CODEC_F05_GE(p0, p1)                               ((p0) <= (p1))
    306338#define CODEC_F05_LE(p0, p1)                               ((p0) >= (p1))
    307339
    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). */
    309348#define CODEC_F07_VREF_HIZ                                 (0)
    310349#define CODEC_F07_VREF_50                                  (0x1)
     
    316355#define CODEC_F07_OUT_H_ENABLE                             RT_BIT(7)
    317356
    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). */
    319362#define CODEC_MAKE_F08(enable, tag) ((((enable) & 1) << 7) | ((tag) & 0x3F))
    320363
    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). */
    362377#define CODEC_MAKE_F09_ANALOG(fPresent, impedance)  \
    363378(  (((fPresent) & 0x1) << 31)                       \
     
    477492#define CODEC_F1C_MISC_MASK                                (0xF)
    478493#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)
    483499
    484500/* Configuration default: Association */
     
    486502#define CODEC_F1C_ASSOCIATION_SHIFT                        (4)
    487503
    488 /* Reserved; don't use. */
     504/** Reserved; don't use. */
    489505#define CODEC_F1C_ASSOCIATION_INVALID                      0x0
    490506#define CODEC_F1C_ASSOCIATION_GROUP_0                      0x1
     
    498514#define CODEC_F1C_ASSOCIATION_GROUP_15                     0xF
    499515
    500 /* Configuration default: Association Sequence */
     516/* Configuration default: Association Sequence. */
    501517#define CODEC_F1C_SEQ_MASK                                 (0xF)
    502518#define CODEC_F1C_SEQ_SHIFT                                (0)
    503519
    504 /* Implementation identification (7.3.3.30) */
     520/* Implementation identification (7.3.3.30). */
    505521#define CODEC_MAKE_F20(bmid, bsku, aid)     \
    506522    (  (((bmid) & 0xFFFF) << 16)            \
     
    509525    )
    510526
    511 /* macro definition helping in filling the configuration registers. */
     527/* Macro definition helping in filling the configuration registers. */
    512528#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)))
    521537
    522538
     
    585601{
    586602    CODECCOMMONNODE node;
     603    uint32_t    u32F01_param;
    587604    uint32_t    u32F03_param;
    588605    uint32_t    u32F05_param;
     
    591608
    592609    uint32_t    u32A_param;
    593     uint32_t    u32F01_param;
    594610    AMPLIFIER   B_params;
    595611} ADCNODE, *PADCNODE;
     
    627643    uint32_t  u32F05_param;
    628644    uint32_t  u32F08_param;
     645    uint32_t  u32F17_param;
    629646    uint32_t  u32F20_param;
    630     uint32_t  u32F17_param;
    631647} AFGCODECNODE, *PAFGCODECNODE;
    632648AssertNodeSize(AFGCODECNODE, 4);
     
    635651{
    636652    CODECCOMMONNODE node;
     653    uint32_t u32F01_param;
    637654    uint32_t u32F07_param;
    638655    uint32_t u32F08_param;
    639656    uint32_t u32F09_param;
    640     uint32_t u32F01_param;
    641657    uint32_t u32F1c_param;
    642658    AMPLIFIER   B_params;
     
    648664    CODECCOMMONNODE node;
    649665    uint32_t u32F01_param;
     666    uint32_t u32F05_param;
     667    uint32_t u32F07_param;
    650668    uint32_t u32F08_param;
    651     uint32_t u32F07_param;
    652669    uint32_t u32F09_param;
    653670    uint32_t u32F1c_param;
    654671} DIGOUTNODE, *PDIGOUTNODE;
    655 AssertNodeSize(DIGOUTNODE, 5);
     672AssertNodeSize(DIGOUTNODE, 6);
    656673
    657674typedef struct DIGINNODE
     
    723740    uint32_t    u32F07_param;
    724741    uint32_t    u32F1c_param;
     742
     743    uint32_t    u32A_param;
    725744} RESNODE, *PRESNODE;
    726 AssertNodeSize(RESNODE, 4);
     745AssertNodeSize(RESNODE, 5);
    727746
    728747/**
     
    773792#define STAC9220_NID_SPDIF_OUT                             0x8  /* Out */
    774793#define STAC9220_NID_SPDIF_IN                              0x9  /* In */
     794/** Also known as PIN_A. */
    775795#define STAC9220_NID_PIN_HEADPHONE0                        0xA  /* In, Out */
    776796#define STAC9220_NID_PIN_B                                 0xB  /* In, Out */
    777797#define STAC9220_NID_PIN_C                                 0xC  /* In, Out */
     798/** Also known as PIN D. */
    778799#define STAC9220_NID_PIN_HEADPHONE1                        0xD  /* In, Out */
    779800#define STAC9220_NID_PIN_E                                 0xE  /* In */
    780801#define STAC9220_NID_PIN_F                                 0xF  /* In, Out */
     802/** Also known as DIGOUT0. */
    781803#define STAC9220_NID_PIN_SPDIF_OUT                         0x10 /* Out */
     804/** Also known as DIGIN. */
    782805#define STAC9220_NID_PIN_SPDIF_IN                          0x11 /* In */
    783806#define STAC9220_NID_ADC0_MUX                              0x12 /* In */
     
    788811#define STAC9220_NID_AMP_ADC0                              0x17 /* In */
    789812#define STAC9220_NID_AMP_ADC1                              0x18 /* In */
    790 /* STAC9221. */
     813/* Only for STAC9221. */
    791814#define STAC9221_NID_ADAT_OUT                              0x19 /* Out */
    792815#define STAC9221_NID_I2S_OUT                               0x1A /* Out */
    793816#define STAC9221_NID_PIN_I2S_OUT                           0x1B /* Out */
    794817
    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. */
     822static 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 };
     823static uint8_t const g_abStac9220Dacs[]       = { STAC9220_NID_DAC0, STAC9220_NID_DAC1, STAC9220_NID_DAC2, STAC9220_NID_DAC3, 0 };
     824static uint8_t const g_abStac9220Adcs[]       = { STAC9220_NID_ADC0, STAC9220_NID_ADC1, 0 };
    814825static uint8_t const g_abStac9220SpdifOuts[]  = { STAC9220_NID_SPDIF_OUT, 0 };
    815826static uint8_t const g_abStac9220SpdifIns[]   = { STAC9220_NID_SPDIF_IN, 0 };
    816827static uint8_t const g_abStac9220DigOutPins[] = { STAC9220_NID_PIN_SPDIF_OUT, 0 };
    817828static 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};
     829static uint8_t const g_abStac9220AdcVols[]    = { STAC9220_NID_AMP_ADC0, STAC9220_NID_AMP_ADC1, 0 };
     830static uint8_t const g_abStac9220AdcMuxs[]    = { STAC9220_NID_ADC0_MUX, STAC9220_NID_ADC1_MUX, 0 };
    820831static uint8_t const g_abStac9220Pcbeeps[]    = { STAC9220_NID_PCBEEP, 0 };
    821832static uint8_t const g_abStac9220Cds[]        = { STAC9220_NID_PIN_CD, 0 };
     
    824835/** @todo Is STAC9220_NID_SPDIF_IN really correct for reserved nodes? */
    825836static uint8_t const g_abStac9220Reserveds[]  = { STAC9220_NID_SPDIF_IN, STAC9221_NID_ADAT_OUT, STAC9221_NID_I2S_OUT, STAC9221_NID_PIN_I2S_OUT, 0 };
    826 #endif
    827837
    828838/** SSM description of a CODECNODE. */
     
    854864static DECLCALLBACK(void) stac9220DbgNodes(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)
    855865{
    856     for (int i = 1; i < 12; i++)
     866    for (int i = 1; i < pThis->cTotalNodes; i++)
    857867    {
    858868        PCODECNODE pNode = &pThis->paNodes[i];
     
    867877
    868878
    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 */
     879static 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);
    878901            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. */
    893939            pNode->afg.u32F08_param = 0;
    894940            pNode->afg.u32F17_param = 0;
    895941            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);
    904971            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_SWAP
    908                                              | CODEC_F00_09_CAP_POWER_CTRL
    909                                              | CODEC_F00_09_CAP_OUT_AMP_PRESENT
    910                                              | 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  */
    913972            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;
    916981            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. */
    919989        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
    922995            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 */);
    9301005            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);
    9391016            pNode->spdifout.u32F06_param = 0;
    9401017            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;
    9411027            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];
    9521044            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;
    9551049            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
    9681067            if (!pThis->fInReset)
    9691068                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    9721071                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    9731072                                                          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 */);
    9771075            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
    9871089            if (!pThis->fInReset)
    9881090                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,
    9901092                                                          CODEC_F1C_DEVICE_SPEAKER,
    9911093                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    9921094                                                          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 */);
    9961097            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
    10061113            if (!pThis->fInReset)
    10071114                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10101117                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10111118                                                          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 */);
    10141121            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
    10241138            if (!pThis->fInReset)
    10251139                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10281142                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10291143                                                          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. */
    10321147        port_init:
     1148
     1149            pNode->port.u32F07_param = CODEC_F07_IN_ENABLE
     1150                                     | CODEC_F07_OUT_ENABLE;
    10331151            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 */);
    10391160            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;
    10441166            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
    10501175            if (!pThis->fInReset)
    10511176                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
    10521177                                                          CODEC_F1C_LOCATION_REAR,
    1053                                                           CODEC_F1C_DEVICE_LINE_OUT,
     1178                                                          CODEC_F1C_DEVICE_LINE_IN,
    10541179                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10551180                                                          CODEC_F1C_COLOR_BLUE,
    1056                                                           0x0, 0x4, 0x0);//0x01013040;  /* Line Out */
     1181                                                          CODEC_F1C_MISC_NONE,
     1182                                                          CODEC_F1C_ASSOCIATION_GROUP_15, 0xE /* Seq */);
    10571183            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;
    10701189            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
    10731204            if (!pThis->fInReset)
    10741205                pNode->port.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10771208                                                          CODEC_F1C_CONNECTION_TYPE_1_8INCHES,
    10781209                                                          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 */);
    10821212            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);
    10911231            if (!pThis->fInReset)
    10921232                pNode->digout.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    10951235                                                            CODEC_F1C_CONNECTION_TYPE_DIN,
    10961236                                                            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 */);
    10981239            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;
    11061246            pNode->digin.u32F08_param = 0;
    11071247            pNode->digin.u32F09_param = CODEC_MAKE_F09_DIGITAL(0, 0);
    11081248            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;
    11091259            if (!pThis->fInReset)
    11101260                pNode->digin.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_COMPLEX,
     
    11131263                                                           CODEC_F1C_CONNECTION_TYPE_OTHER_DIGITAL,
    11141264                                                           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 */);
    11161267            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). */
    11191273            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);
    11341304            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        {
    11401309            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);
    11421317            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
    11471326            if (!pThis->fInReset)
    11481327                pNode->cdnode.u32F1c_param = CODEC_MAKE_F1C(CODEC_F1C_PORT_FIXED,
     
    11511330                                                            CODEC_F1C_CONNECTION_TYPE_ATAPI,
    11521331                                                            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 */);
    11541334            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        {
    11601339            pNode->volumeKnob.u32F08_param = 0;
    11611340            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);
    11621351            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;
    11651357            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. */
    11681365        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);
    11781380            AMPLIFIER_REGISTER(pNode->adcvol.B_params, AMPLIFIER_IN, AMPLIFIER_RIGHT, 0) = RT_BIT(7);
    1179             pNode->adcvol.u32F0c_param = 0;
    11801381            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)
    11831391                                           | 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;
    11851393            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)
    11881399                                           | 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;
    11901401            break;
    1191         case 0x1B:
     1402        }
     1403
     1404        case STAC9221_NID_PIN_I2S_OUT:
     1405        {
    11921406            pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_PIN_COMPLEX, 0, 0)
    11931407                                           | CODEC_F00_09_CAP_DIGITAL
    11941408                                           | 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 */);
    12051424            break;
     1425        }
     1426
    12061427        default:
    1207         break;
    1208     }
     1428            AssertMsgFailed(("Node %RU8 not implemented\n", uNID));
     1429            break;
     1430    }
     1431
    12091432    return VINF_SUCCESS;
    12101433}
     
    12131436static int stac9220Construct(PHDACODEC pThis)
    12141437{
    1215     unconst(pThis->cTotalNodes) = 0x1C;
     1438    unconst(pThis->cTotalNodes) = STAC9221_NUM_NODES;
     1439
    12161440    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;
    12211450    pThis->u8AssemblyId = 0x80;
     1451
    12221452    pThis->paNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pThis->cTotalNodes);
    12231453    if (!pThis->paNodes)
    12241454        return VERR_NO_MEMORY;
     1455
    12251456    pThis->fInReset = false;
     1457
    12261458#define STAC9220WIDGET(type) pThis->au8##type##s = g_abStac9220##type##s
    12271459    STAC9220WIDGET(Port);
     
    12391471    STAC9220WIDGET(Reserved);
    12401472#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;
    12431476
    12441477    return VINF_SUCCESS;
     
    12901523 * Misc helpers.
    12911524 */
    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;
     1525static 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;
    13011533            break;
    13021534        case PDMAUDIOMIXERCTL_LINE_IN:
    1303             enmSrc = PI_INDEX;
    1304             dir = AMPLIFIER_IN;
     1535        case PDMAUDIOMIXERCTL_MIC_IN:
     1536            iDir = AMPLIFIER_IN;
    13051537            break;
    13061538        default:
    1307             AssertMsgFailedReturn(("Invalid mixer control %ld\n", mt), VERR_INVALID_PARAMETER);
     1539            AssertMsgFailedReturn(("Invalid mixer control %ld\n", enmMixerCtl), VERR_INVALID_PARAMETER);
    13081540            break;
    13091541    }
    13101542
    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.
    13191554     * We have 0 to -96dB range in 256 steps. HDA volume setting of 127 must map
    13201555     * to 255 internally (0dB), while HDA volume setting of 0 (-96dB) should map
     
    13241559    rVol = (rVol + 1) * (2 * 255) / 256;
    13251560
    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);
    13271563}
    13281564
     
    14261662                            u8Index);
    14271663    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)));
    14291665
    14301666    return VINF_SUCCESS;
     
    14541690        pAmplifier = &pNode->adc.B_params;
    14551691    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",
    14571693                 cmd, CODEC_VERB_PAYLOAD16(cmd), CODEC_NID(cmd)));
    14581694
     
    14881724
    14891725        if (CODEC_NID(cmd) == pThis->u8DacLineOut)
    1490             hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_PCM);
     1726            hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
    14911727    }
    14921728
     
    15311767        *pResp = pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
    15321768    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));
    15341770
    15351771    return VINF_SUCCESS;
     
    15561792        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adcvol.u32F01_param;
    15571793    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));
    15601795
    15611796    if (pu32Reg)
     
    15861821        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    15871822    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));
    15891824
    15901825    return VINF_SUCCESS;
     
    16141849        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F07_param;
    16151850    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));
    16181852
    16191853    if (pu32Reg)
     
    16351869    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    16361870        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
    1637     else if ((cmd) == 1 /* AFG */)
     1871    else if ((cmd) == STAC9220_NID_AFG)
    16381872        *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param;
    16391873    else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
     
    16441878        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F08_param;
    16451879    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));
    16481881
    16491882    return VINF_SUCCESS;
     
    16631896    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    16641897        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)
    16661899        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F08_param;
    16671900    else if (hdaCodecIsVolKnobNode(pThis, CODEC_NID(cmd)))
     
    16721905        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digout.u32F08_param;
    16731906    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));
    16761908
    16771909    if (pu32Reg)
     
    16941926        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param;
    16951927    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));
    16971929
    16981930    return VINF_SUCCESS;
     
    17131945        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F09_param;
    17141946    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));
    17171948
    17181949    if (pu32Reg)
     
    18182049        return VINF_SUCCESS;
    18192050    }
    1820     if (CODEC_NID(cmd) == 1 /* AFG */)
     2051    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    18212052        *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param;
    18222053    else
     
    18352066    }
    18362067    uint32_t *pu32Reg;
    1837     if (CODEC_NID(cmd) == 0x1 /* AFG */)
     2068    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    18382069        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F20_param;
    18392070    else
     
    18742105{
    18752106    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
    18782109        && pThis->pfnCodecNodeReset)
    18792110    {
     
    19002131    *pResp = 0;
    19012132
    1902     if (CODEC_NID(cmd) == 1 /* AFG */)
     2133    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    19032134        *pResp = pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
    19042135    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     
    19062137    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    19072138        *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;
    19082141    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    19092142        *pResp = pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     
    19152148        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    19162149    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;
    19332155}
    19342156
     
    19422164
    19432165    uint32_t *pu32Reg = NULL;
    1944     if (CODEC_NID(cmd) == 1 /* AFG */)
     2166    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    19452167        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].afg.u32F05_param;
    19462168    else if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     
    19482170    else if (hdaCodecIsDigInPinNode(pThis, CODEC_NID(cmd)))
    19492171        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;
    19502174    else if (hdaCodecIsAdcNode(pThis, CODEC_NID(cmd)))
    19512175        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].adc.u32F05_param;
     
    19572181        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F05_param;
    19582182    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));
    19612184
    19622185    if (!pu32Reg)
    19632186        return VINF_SUCCESS;
    19642187
    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    {
    19732239        *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
    20002250    return VINF_SUCCESS;
    20012251}
     
    20162266    else if (hdaCodecIsSpdifOutNode(pThis, CODEC_NID(cmd)))
    20172267        *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)
    20192269        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    20202270    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)));
    20222275
    20232276    return VINF_SUCCESS;
     
    20442297        pu32Addr = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F06_param;
    20452298    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)));
    20482303
    20492304    if (pu32Addr)
     
    20532308}
    20542309
    2055 /* F06 */
     2310/* A0 */
    20562311static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    20572312{
     
    20692324    else if (hdaCodecIsSpdifInNode(pThis, CODEC_NID(cmd)))
    20702325        *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;
    20712328    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. */
    20772335static DECLCALLBACK(int) vrbProcSetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    20782336{
     
    20912349        hdaCodecSetRegisterU16(&pThis->paNodes[CODEC_NID(cmd)].spdifin.u32A_param, cmd, 0);
    20922350    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));
    20952352
    20962353    return VINF_SUCCESS;
     
    21122369        *pResp = pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    21132370    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));
    21152372
    21162373    return VINF_SUCCESS;
     
    21332390        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].digin.u32F0c_param;
    21342391    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));
    21372393
    21382394    if (pu32Reg)
     
    21532409        *pResp = pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    21542410    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));
    21562412
    21572413    return VINF_SUCCESS;
     
    21702426        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].volumeKnob.u32F0f_param;
    21712427    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));
    21742429
    21752430    if (pu32Reg)
     
    21792434}
    21802435
     2436/* F15 */
     2437static 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 */
     2448static 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 */
     2459static 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 */
     2470static 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
    21812480/* F17 */
    21822481static DECLCALLBACK(int) vrbProcGetGPIOUnsolisted(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     
    21882487
    21892488    /* Note: this is true for ALC885. */
    2190     if (CODEC_NID(cmd) == 0x1 /* AFG */)
     2489    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    21912490        *pResp = pThis->paNodes[1].afg.u32F17_param;
    21922491    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));
    21942493
    21952494    return VINF_SUCCESS;
     
    22052504
    22062505    uint32_t *pu32Reg = NULL;
    2207     if (CODEC_NID(cmd) == 1 /* AFG */)
     2506    if (CODEC_NID(cmd) == STAC9220_NID_AFG)
    22082507        pu32Reg = &pThis->paNodes[1].afg.u32F17_param;
    22092508    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));
    22122510
    22132511    if (pu32Reg)
     
    22382536        *pResp = pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    22392537    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));
    22412539
    22422540    return VINF_SUCCESS;
     
    22592557        pu32Reg = &pThis->paNodes[CODEC_NID(cmd)].reserved.u32F1c_param;
    22602558    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));
    22632560
    22642561    if (pu32Reg)
     
    23462643    { 0x000F0F00, CODEC_VERB_8BIT_CMD , vrbProcGetVolumeKnobCtrl      },
    23472644    { 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      },
    23482649    { 0x000F1700, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOUnsolisted      },
    23492650    { 0x00071700, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOUnsolisted      },
     
    23572658    { 0x000B0000, CODEC_VERB_16BIT_CMD, vrbProcGetAmplifier           },
    23582659    { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcSetAmplifier           },
     2660    /** @todo Implement 0x7e7: IDT Set GPIO (STAC922x only). */
    23592661};
    23602662
     
    25812883{
    25822884    Assert(CODEC_CAD(cmd) == pThis->id);
    2583     if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2584         LogFlowFunc(("cmd %x was addressed to reserved node\n", cmd));
    25852885
    25862886    if (   CODEC_VERBDATA(cmd) == 0
     
    25882888    {
    25892889        *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++)
    25962895    {
    25972896        if ((CODEC_VERBDATA(cmd) & pThis->paVerbs[i].mask) == pThis->paVerbs[i].verb)
     
    26032902
    26042903    *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)));
    26062906    return VINF_SUCCESS;
    26072907}
     
    26112911 */
    26122912
    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)
     2913int hdaCodecAddStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg)
    26222914{
    26232915    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;
    26302928            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;
    26342935            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;
    26382941            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);
    26442946
    26452947    LogFlowFuncLeaveRC(rc);
     
    26472949}
    26482950
     2951int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl)
     2952{
     2953    return VINF_SUCCESS;
     2954}
     2955
    26492956int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM)
    26502957{
    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),
    26522959                          VERR_INTERNAL_ERROR);
    26532960    SSMR3PutU32(pSSM, pThis->cTotalNodes);
     
    27153022     */
    27163023    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);
    27183025    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);
    27203027    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    27213028
     
    27403047{
    27413048    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
    27503056#ifdef DEBUG
    27513057    pThis->pfnDbgSelector  = codecDbgSelector;
    27523058    pThis->pfnDbgListNodes = codecDbgListNodes;
    27533059#endif
     3060    pThis->pfnLookup       = codecLookup;
     3061
    27543062    int rc = stac9220Construct(pThis);
    27553063    AssertRC(rc);
    27563064
    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
    27723110#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);
    27743114#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     */
    27803122    AssertPtr(pThis->paNodes);
    27813123    AssertPtr(pThis->pfnCodecNodeReset);
     
    27843126        pThis->pfnCodecNodeReset(pThis, i, &pThis->paNodes[i]);
    27853127
    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);
    27873132    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
Note: See TracChangeset for help on using the changeset viewer.

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