]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blobdiff - pasdk/test_dsp/framework/audioStreamInpProcNewIO.c
PASDK-577:Clear already posted Input events on Input re-select
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamInpProcNewIO.c
index 9c37ea115fac5da5181d418690179cf682a6e423..84d525c83631c5869794344ccac9edb3121db9df 100644 (file)
@@ -38,13 +38,19 @@ All rights reserved.
  */
 #include <xdc/runtime/Log.h>
 #include <ti/sysbios/BIOS.h>
+#include <xdc/runtime/Error.h>
+#include <ti/sysbios/knl/Event.h>
 
+#include "procsdk_audio_typ.h"
 #include "audioStreamInpProc.h"
 #include "audioStreamProc_common.h"
+#include "aspMsg_common.h"
+#include "aspMsg_master.h"
 #include "asperr.h"
+#include "common.h"
 
-#include "audk2g.h"
-#include "audk2g_audio.h"
+#include "aud.h"
+#include "aud_audio.h"
 #include "mcasp_cfg.h"
 #include "ioConfig.h"    //TODO: remove this header
 #include "ioBuff.h"
@@ -52,6 +58,9 @@ All rights reserved.
 #include "ioData.h"
 
 
+#define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
+
+//#define DEBUG_SKIP_DECODING
 
 #define SYNC_PC_MASK         0x1F
 #define SYNC_SUBTYPE_MASK    0x700
@@ -62,6 +71,7 @@ All rights reserved.
 
 #define IEC_HEADER_LENGTH    4
 
+#define INPUT_SWITCH_HANGOVER 8
 
 //table needed until PAF_SOURCE is reordered to match IEC numbering
 const SmUns IECpafSource[23] =
@@ -99,46 +109,73 @@ extern Void taskAsipFxnInit(const PAF_ASIT_Params *pP,const PAF_ASIT_Patchs *pQ)
 
 // avoid including sap_d10.h, which would cause symbol redefinition
 // warning (MCASP_PFUNC_XXX)
-extern XDAS_Int32 D10_init();
+//extern XDAS_Int32 D10_init(void * pD10Params);
+extern XDAS_Int32 D10_initClkMux(void *pD10Params);
 extern XDAS_Int32 D10_RxControl(const void *pD10RxParams,
                                 XDAS_Int32 code, XDAS_Int32 arg);
 
 /*
  * Functions only used in this file
  */
-int asipPrepareProcessing();
-int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo);
-void asipProcInit(PAF_AST_IoInp  *pInp);
-void asipIoPhyPrime(PAF_AST_IoInp *pInpIo);
-void asipPhyTransferPend(void);
-void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo);
-void asipPhyTransferStart(PAF_AST_IoInp *pInpIo);
-Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp);
-Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
+int asitPrepareProcessing();
+int asitIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo);
+void asitProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec);
+void asitIoPhyPrime(PAF_AST_IoInp *pInpIo);
+void asitPhyTransferComplete(PAF_AST_IoInp * pInpIo);
+void asitPhyTransferStart(PAF_AST_IoInp *pInpIo);
+Int asitRecfgPhyXfer(PAF_AST_IoInp *pInp, size_t xferSize);
+
+// Select Input devices
+Int asitSelectDevices(
+    const PAF_ASIT_Patchs *pQ, 
+    PAF_AST_Config *pAstCfg, 
+    PAF_AST_IoInp *pInp
+);
+
+Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
                           PAF_InpBufConfig *pInpBuf);
 
-Int asipProcessing(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp);
-void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno);
+Int asitSourceDetection(const PAF_ASIT_Params *pP,
+                        const PAF_ASIT_Patchs *pQ,
+                        PAF_ASIT_Config       *pAsitCfg);
+
+Int asitDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp,
+                     ioDataAutoDetStat_t *autoDetStatus);
+Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg,
+                      PAF_AST_IoInp  *pInp, ioDataAutoDetStat_t *autoDetStatus);
+Int asitBypassIoData(PAF_AST_IoInp *pInp);
+Int asitPcmTransition(PAF_ASIT_Config *pAsitCfg);
+
+void asitUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp);
+Int asitInputDataProcess(PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *pAutoDetStats);
+
+UInt asitEventsToDecMsg(UInt asitEvents);
+void asitErrorHandling(PAF_ASIT_Config *pAsitCfg, Int asitErr);
+Int asitEvtErrCheck(UInt actualEvents, UInt expectedEvents);
+
+void asitPostInfoEvent();
+void asitPostDecEvent();
 
 /*
  * variables/structures to be put into proper global structures
  */
-extern Semaphore_Handle asipSemRx;
 extern PAF_ASIT_Config gPAF_ASIT_config;
+extern const MdUns iecFrameLength[23];
+extern Ptr hMcaspRxChan;
 
-enum
-{
-    ASIP_SOURCE_DETECTION,
-    ASIP_DECODE_BITSTREAM,
-    ASIP_SWITCH_TO_PCM,
-    ASIP_DECODE_PCM
-};
+// temp for simulation
+//#define ASIT_ALL_EVENTS (  ASIT_EVTMSK_INPDATA \
+//                         + ASIT_EVTMSK_INFOACK \
+//                         + ASIT_EVTMSK_DECACK )
+#define ASIT_ALL_EVENTS (  ASIT_EVTMSK_INPDATA \
+                         + ASIT_EVTMSK_RXACK )
 
-enum
-{
-    ASIP_INPUT_PREPARATION,
-    ASIP_INPUT_PROCESSING
-};
+// temp for simulation
+//#define ASIT_DEC_EVENTS (  ASIT_EVTMSK_INPDATA \
+//                         + ASIT_EVTMSK_INFOACK \
+//                         + ASIT_EVTMSK_DECACK )
+#define ASIT_DEC_EVENTS (  ASIT_EVTMSK_INPDATA \
+                         + ASIT_EVTMSK_RXACK )
 
 #define ASIP_DEBUG
 
@@ -147,8 +184,16 @@ enum
 int asipLoopCount1, asipLoopCount2;
 Int asipErrno;
 Int inputReadyForProcessing;
+
+// debug
+#include "evmc66x_gpio_dbg.h"
 #endif
 
+Event_Handle gAsitEvtHandle;            // ASIT event handle
+Int eventsOn;                           // flag indicating whether to process events
+
+SyncEvent_Handle gAsitSyncEvtHandle;    // ASIT Sync event handle
+
 /*
  *  ======== taskAsipFxn ========
  *  Audio Stream Input Processing task function
@@ -176,6 +221,10 @@ int asipLoopCount1, asipLoopCount2;
 Int asipErrno;
 Int inputReadyForProcessing;
 #endif
+    Int asitErr;
+    UInt events;
+//    Int eventsOn;
+//    Error_Block  eb;
 
     Log_info0("Enter taskAsipFxn()");
 
@@ -186,7 +235,6 @@ Int inputReadyForProcessing;
     //
     pAsitCfg = &gPAF_ASIT_config;       // initialize pointer to task configuration
     pAstCfg  = pAsitCfg->pAstCfg;       // pointer to AST common (shared) configuration
-    pInp     = pAsitCfg->pIoInp;        // pointer to input I/O components
 
     /* Set Audio Stream Number (1, 2, etc.) */
     as = pAstCfg->as;
@@ -194,151 +242,38 @@ Int inputReadyForProcessing;
     //
     // Determine decoder and stream indices associated with the master input
     //
-    zMI = pP->zone.master;
-
-    pInp[zMI].numPrimeXfers = NUM_PRIME_XFERS;
-    //asipInitDebug(&pInp[zMI]);
+    zMI  = pP->zone.master;
+    pInp = &pAsitCfg->pIoInp[zMI];        // pointer to input I/O components
 
     for (z=STREAM1; z < STREAMN; z++)
     {
         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
     }
 
-    TRACE_TERSE0("TaskAsip: Entering Main Loop.");
-
-#if 0
-    // Wait until input device is ready - change this to event based scheduling
-    asipErrno = 0;
-    while (!inputReadyForProcessing)
-    {
-        // Indicate decoder no decoding yet
-        pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
+    Log_info0("TaskAsip: Entering Main Loop.");
 
-        Task_sleep(5);  // 5 system tick, or 5 msec. Should remove this later when implementing event based scheduling.
-
-        inputReadyForProcessing = asipPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
-
-        if(asipErrno) {
-            asipErrorHandling(pAstCfg, asipErrno);
-        }
-    }
-
-    // .....................................................................
-    // At this point we have an enabled input and want to decode something.
-    // If no decoder selected then do nothing. Need to reset the sourceProgram, since
-    // when no decoder is selected there are no calls to IB
-    asipErrno = asipIoCompsInit(&pAstCfg->xInp[zMI], &pInp[zMI]);
-    if(asipErrno) {
-        printf("ASIP IO components init error!\n");
-        exit(0);
-    }
-
-    asipProcInit(&pInp[zMI]);
-
-    // start I/O physical layer by priming McASP LLD for input
-    asipIoPhyPrime(&pInp[zMI]);
-
-    //
-    // Main processing loop
-    //
-    asipErrno = 0;
-    for (;;)
-    {
-        // Pending on I/O PHY transfer
-        asipPhyTransferPend();
-
-        // Marks I/O PHY transfer and I/O BUFF write complete
-        asipPhyTransferComplete(&pInp[zMI]);
-
-        // Main function to process input data
-        asipErrno = asipProcessing(pAstCfg, &pInp[zMI]);
-
-        // Start next transfer
-        asipPhyTransferStart(&pInp[zMI]);
-
-        if(asipErrno) {
-            asipErrorHandling(pAstCfg, asipErrno);
-        }
-    }
-#endif
-
-#if 0
     //
     // Main processing loop
     //
     asipLoopCount1 = 0;
     asipLoopCount2 = 0;
-    asipErrno = 0;
-    inputReadyForProcessing = FALSE;
-    for (;;)
-    {
-        asipLoopCount1++;
-
-        if(asipErrno) {
-            asipErrorHandling(pAstCfg, asipErrno);
-
-            inputReadyForProcessing = FALSE;
-        }
-
-        // Wait until input device is ready - change this to event based scheduling
-        if(!inputReadyForProcessing) {
-            // Indicate decoder no decoding yet
-            pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
-
-            // 5 system tick, or 5 msec. Should remove this later when implementing
-            // event based scheduling.
-            Task_sleep(5);
-
-            inputReadyForProcessing = asipPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
-
-            if (inputReadyForProcessing) {
-                // Input is ready for processing, so we initialize the I/O components
-                asipIoCompsInit(&pAstCfg->xInp[zMI], &pInp[zMI]);
+    asitErr = ASIT_NO_ERR;
 
-                // Initialize ASIP processing
-                asipProcInit(&pInp[zMI]);
-
-                // Start I/O physical layer by priming McASP LLD for input
-                asipIoPhyPrime(&pInp[zMI]);
-            }
-            else {
-                // Input is not ready, so go back to the beginning of the loop
-                continue;
-            }
-        }  /* if(!inputReadyForProcessing) */
-
-        // Pending on I/O PHY transfer
-        asipPhyTransferPend();
-
-        // Marks I/O PHY transfer and I/O BUFF write complete
-        asipPhyTransferComplete(&pInp[zMI]);
-
-        // Main function to process input data
-        asipErrno = asipProcessing(pAstCfg, &pInp[zMI]);
-
-        // Start next transfer
-        asipPhyTransferStart(&pInp[zMI]);
-
-        asipLoopCount2++;
-    }  // for (;;)
-#endif
-
-    //
-    // Main processing loop
-    //
-    asipLoopCount1 = 0;
-    asipLoopCount2 = 0;
-    asipErrno = 0;
-    inputReadyForProcessing = FALSE;
-    pInp->asipState = ASIP_INPUT_PREPARATION;
+    // The events_on flag will be removed if the RESTART state is changed to
+    // event-based scheduling instead of polling
+    eventsOn = FALSE;
 
     for (;;)
     {
         asipLoopCount1++;
 
+        if(eventsOn) {
+            events = Event_pend(gAsitEvtHandle, ASIT_EVTMSK_NONE, ASIT_ALL_EVENTS,
+                                BIOS_WAIT_FOREVER);
+        }
         switch (pInp->asipState)
         {
-        case ASIP_INPUT_PREPARATION:
+        case ASIT_RESET:    // No events pending in this state
             // Indicate decoder no decoding yet
             pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_NONE);
 
@@ -346,62 +281,112 @@ Int inputReadyForProcessing;
             // event based scheduling.
             Task_sleep(5);
 
-            inputReadyForProcessing = asipPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
-
+            inputReadyForProcessing = asitPrepareProcessing(pP, pQ, pAsitCfg, &asipErrno);
             if (inputReadyForProcessing) {
-                // Input is ready for processing, so we initialize the I/O components
-                asipIoCompsInit(&pAstCfg->xInp[zMI], &pInp[zMI]);
-
-                // Initialize ASIP processing
-                asipProcInit(&pInp[zMI]);
-
-                // Start I/O physical layer by priming McASP LLD for input
-                asipIoPhyPrime(&pInp[zMI]);
-
-                pInp->asipState = ASIP_INPUT_PROCESSING;
+                TRACE_VERBOSE0("TaskAsip: Input is ready. Initialize I/O components.");
+                // Input is ready for processing, so we initialize the I/O components.
+                // Note that the I/O components init. and I/O PHY prime are performed only
+                // at the first time. This should be changed later - init. and prime
+                // should be done whenever input interface has changed.
+                asitErr = asitIoCompsInit(&pAstCfg->xInp[zMI], pInp);
+
+                // Initialize ASIT processing
+                asitProcInit(pInp, &pAsitCfg->inpDec);
+                pInp->asipState = ASIT_SOURCE_DETECTION;
+                eventsOn = TRUE;   // turn on events pending
+                TRACE_VERBOSE0("TaskAsip: turn on events and go to source detection.");
             }
             break;
 
-        case ASIP_INPUT_PROCESSING:
-            // Pending on I/O PHY transfer
-            asipPhyTransferPend();
-
-            // Marks I/O PHY transfer and I/O BUFF write complete
-            asipPhyTransferComplete(&pInp[zMI]);
-
-            // Main function to process input data
-            asipErrno = asipProcessing(pAstCfg, &pInp[zMI]);
-
-            // Start next transfer
-            asipPhyTransferStart(&pInp[zMI]);
+        case ASIT_SOURCE_DETECTION:
+            // Source unknown - to detect & identify source
+            if(events == ASIT_EVTMSK_INPDATA) {  
+                // Only this event is expected. If any other event, it's error.
+                // Input data is ready - perform source detection.
+                // New state will be decided inside the function
+                asitErr = asitSourceDetection(pP, pQ, pAsitCfg);
+
+                if(asitErr == ASIT_AUTODET_TIME_OUT) {
+                    // Should restart if new interface is selected.
+                    TRACE_VERBOSE0("TaskAsip: auto-detection time out.");
+                }
+            }
+            else {
+                //Error checking & debug
+                asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA);
+            }
 
-            if(asipErrno) {
-                asipErrorHandling(pAstCfg, asipErrno);
+            break;
 
-                pInp->asipState = ASIP_INPUT_PREPARATION;
+        case ASIT_PCM_TRANSITION:
+            // Source is PCM - transition to PCM decoding
+            if(events == ASIT_EVTMSK_INPDATA) {
+                // Only this event is expected. If any other event, it's error.
+                // Input data is ready - transition to PCM decoding
+                // New state will be decided inside the function
+                asitErr = asitPcmTransition(pAsitCfg);
+            }
+            else {
+                //Error checking & debug
+                asitErr = asitEvtErrCheck(events, ASIT_EVTMSK_INPDATA);
             }
+            break;
 
+        case ASIT_DECODE_PROCESSING:
+            if(events & ASIT_DEC_EVENTS) {
+                
+#if 1 // debug 
+                if (events & ASIT_EVTMSK_INPDATA)
+                {
+                    // shows timing of Input (Rx McASP EDMA)
+                    // ADC B5
+                    {
+                        static Uint8 toggleState = 0;
+                        if (toggleState == 0)
+                            GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
+                        else
+                            GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
+                        toggleState = ~(toggleState);
+                    }
+                }
+#endif           
+                
+                // Decode processing for either PCM or bitstream
+                // New state will be decided inside the function
+                asitErr = asitDecodeProcessing(pP, pQ, pAsitCfg, events);
+            }
+            else {
+                //Error checking & debug
+                asitErr = asitEvtErrCheck(events, ASIT_DEC_EVENTS);
+            }
             break;
 
         default:
             break;
         }
+
+        if(asitErr) {
+            asitErrorHandling(pAsitCfg, asitErr);
+
+            if(pInp->asipState == ASIT_RESET) {
+                eventsOn = FALSE;
+            }
+
+            asitErr = ASIT_NO_ERR;
+        }
+
     }  // for (;;)
 
 }  /* taskAsipFxn */
 
-extern const MdUns iecFrameLength[23];
-extern Ptr hMcaspRxChan;
-#define STRIDE_WORST_CASE 32  // 4-byte (32-bit) word, 2 slots, 4 serializers
-
 
 /*===========================================================================
- * ASIP processing preparation
+ * ASIT Processing Preparation
  * Output:
  *        - return        TRUE (input is ready) or FALSE (input is not ready)
- *        - *asipErrno        Error number
+ *        - *asipErrno    Error number
 ============================================================================*/
-Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
+Int asitPrepareProcessing(const PAF_ASIT_Params *pP,
                           const PAF_ASIT_Patchs *pQ,
                           PAF_ASIT_Config       *pC,
                           Int                   *asipErrno)
@@ -421,9 +406,10 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
     *asipErrno = 0;
 
     // Select source and initialize physical layer / HW interface
-    *asipErrno = asipSelectDevices(pQ, pInp);
+    *asipErrno = asitSelectDevices(pQ, pAstCfg, pInp);
     if (*asipErrno) {
-        TRACE_TERSE2("TaskAsip: selectDevices returned asipErrno = 0x%04x at line %d. AS%d", *asipErrno, as+zMS);
+        TRACE_TERSE2("asitSelectDevices returned asipErrno = 0x%04x at line %d. AS%d",
+                     *asipErrno, as+zMS);
         return FALSE;    // Input is not ready for processing due to error
     }
 
@@ -438,7 +424,7 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
     }
 
     // If here then we have a valid input so query its status
-    *asipErrno = asipUpdateInputStatus(pInp[zMI].pRxParams,
+    *asipErrno = asitUpdateInputStatus(pInp[zMI].pRxParams,
                                    &pAstCfg->xInp[zMI].inpBufStatus,
                                    &pAstCfg->xInp[zMI].inpBufConfig);
     if(*asipErrno) {
@@ -478,7 +464,8 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
             *asipErrno = pP->fxns->passProcessing(pP, pQ, pC, NULL);
         }
         else {
-            TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x", as+zMS, ASPERR_PASS);
+            TRACE_TERSE2("TaskAsip: AS%d: Pass Processing not supported, asipErrno 0x%x",
+                         as+zMS, ASPERR_PASS);
             *asipErrno = ASPERR_PASS;
         }
 
@@ -488,68 +475,530 @@ Int asipPrepareProcessing(const PAF_ASIT_Params *pP,
 
     // No error and input processing is ready
     return TRUE;
-} /* asipPrepareProcessing */
+} /* asitPrepareProcessing */
+
+
+/*===========================================================================
+ * ASIT Source Detection:
+ *     ASIT processing for input source identification:
+ *     - mark I/O PHY transfer completion
+ *     - run auto-detection via I/O DATA in asitInputDataProcess
+ *     - mark I/O DATA read completion
+ *     - check auto-detection status and take corresponding actions if either
+ *       PCM or bitstream is identified:
+ *       - decide input source
+ *       - update I/O components
+ *       - reconfigure McASP LLD if it is PCM
+ *     - start next I/O PHY transfer
+============================================================================*/
+Int asitSourceDetection(const PAF_ASIT_Params *pP,
+                        const PAF_ASIT_Patchs *pQ,
+                        PAF_ASIT_Config       *pAsitCfg)
+{
+    PAF_AST_Config  *pAstCfg;
+    PAF_AST_IoInp *pInp;                // I/O components for input
+    Int zMD, mcaspErr, asitErr;
+    ioDataAutoDetStat_t autoDetStatus;
+
+    pAstCfg  = pAsitCfg->pAstCfg;               // pointer to AST common (shared) configuration
+    zMD = pAstCfg->masterDec;
+    pInp = &pAsitCfg->pIoInp[zMD];              // pointer to input I/O components
+
+    // Marks I/O PHY transfer and I/O BUFF write complete
+    asitPhyTransferComplete(pInp);
+
+    // Process input data - either searching SYNC for PCM or checking SYNC for bitstream
+    asitErr = asitInputDataProcess(pInp, &autoDetStatus);
+    if(asitErr != ASIT_NO_ERR) {
+        // Even though there is error, still need to start next transfer to
+        // maintain McASP transfer.
+        asitPhyTransferStart(pInp);
+
+        return asitErr;
+    }
+
+    // Mark input data read complete
+    ioDataReadComplete(pInp->hIoData);
+
+    if(autoDetStatus.syncTimeOut) {
+        return ASIT_AUTODET_TIME_OUT;
+    }
+    // Check if bitstream or PCM is detected
+    else if(   autoDetStatus.syncState == IODATA_SYNC_BITSTREAM
+       || autoDetStatus.syncState == IODATA_SYNC_PCM) {
+        // Decide input source and inform decoder
+        asitErr = asitDecideSource(pAstCfg, pInp, &autoDetStatus);
+        if(asitErr != ASIT_NO_ERR) {
+            return asitErr;
+        }
+        else {
+            // Update I/O components and input buffer config
+            asitUpdateIoComps(pP, pAstCfg, pInp, &autoDetStatus);
+
+            // set to unknown so that we can ensure, for IOS purposes, that
+            // sourceDecode = NONE iff we are in this top level state machine
+            // and specifically not in decodeProcessing
+#ifndef DEBUG_SKIP_DECODING
+            pP->fxns->sourceDecode(pP, pQ, pAsitCfg, PAF_SOURCE_UNKNOWN);
+#endif
+
+            if(autoDetStatus.syncState == IODATA_SYNC_BITSTREAM) {
+                // Input is bit stream: go to decoding
+                pInp->asipState = ASIT_DECODE_PROCESSING;
+            }
+            else  {
+                // Input is PCM: stop swapping data
+                pInp->swapData = FALSE;
+
+                // Reconfigure McASP LLD to transfer 32-bit unpacked data
+                mcaspErr = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_32);
+                if(mcaspErr != Aud_EOK) {
+                    return ASIT_ERR_MCASP_CFG;
+                }
+
+                // Adjust I/O BUFF delay and read pointer - to make sure read pointers
+                // always point to PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
+                ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
+
+                // Go to transition state to switch to PCM
+                pInp->asipState = ASIT_PCM_TRANSITION;
+            }
+        }
+    }
+    else {
+        // SYNC search ongoing, no action is needed
+    }
+
+    // Start next transfer
+    asitPhyTransferStart(pInp);
+
+    return (ASIT_NO_ERR);
+}  /* asitSourceDetection */
+
+
+/*===========================================================================
+    //
+    // which will cause all 0's in one McASP LLD transfer. This will
+    // be detected as loss of SYNC by auto detection. To prevent that,
+    // skip I/O DATA process for hangover period so that this all 0's
+    // frame will not be seen by auto-detection. Also, playing out PCM
+    // needs to be skipped as well, to prevent from playing out garbage
+    // (16-bit packed data).
+ *
+ * ASIT Transition to PCM decoding.
+ *     When PCM is detected, McASP LLD will be reconfigured to transmit 32-bit
+ *     words, which will modify the RFMT register. This will cause all 0's in
+ *     one McASP LLD transfer, which would be detected as loss of SYNC by auto
+ *     detection (performed by I/O DATA). To prevent that, skip I/O DATA process
+ *     for hangover period so that this all-0's frame will not be seen by the
+ *     auto-detection.
+ *
+ *     In addition, playing out PCM should be skipped as well to prevent from
+ *     playing out the 16-bit packed data that's still in the input buffer.
+ *
+ *     This function does the following:
+ *     - mark I/O PHY transfer completion
+ *     - bypass I/O DATA
+ *     - start next I/O PHY transfer
+============================================================================*/
+Int asitPcmTransition(PAF_ASIT_Config *pAsitCfg)
+{
+    Int asitErr;
+    PAF_AST_IoInp *pInp;                  // I/O components for input
+    Int zMD;
+
+    zMD = pAsitCfg->pAstCfg->masterDec;   // pointer to AST common (shared) configuration
+    pInp = &pAsitCfg->pIoInp[zMD];        // pointer to input I/O components
+
+    // Marks I/O PHY transfer and I/O BUFF write complete
+    asitPhyTransferComplete(pInp);
+
+    // Bypass I/O data processing due to McASP LLD work around
+    // (refer to comments inside the function)
+    asitErr = asitBypassIoData(pInp);
+
+    pInp->pcmSwitchHangOver--;
+    if(pInp->pcmSwitchHangOver == 0) {
+        pInp->asipState = ASIT_DECODE_PROCESSING;
+    }
+    else {
+        ; // stay in this state
+    }
+
+    // Start next transfer
+    asitPhyTransferStart(pInp);
+
+    return asitErr;
+
+} /* asitPcmTransition */
+
+/*============================================================================
+ * ASIT Bypass I/O DATA Processing
+ *     This function bypasses the I/O DATA processing. It maintains the read
+ *     operation of I/O BUFF by directly calling I/O BUFF APIs. When I/O DATA
+ *     is not bypassed, I/O BUFF read operation is invoked by I/O DATA.
+ *
+============================================================================*/
+Int asitBypassIoData(PAF_AST_IoInp *pInp)
+{
+    void *buff1, *buff2;
+    size_t size1, size2;
+
+    // Get read pointers (or sub-buffers) of the input buffer
+    if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
+                          &buff1, &size1, &buff2, &size2)
+        == IOBUFF_ERR_UNDERFLOW) {
+        pInp->numUnderflow += 1;
+
+        // Return since there is no enough data to process
+        return ASIT_ERR_INPBUF_UNDERFLOW;
+    }
+
+    ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
+
+    if(buff2 != NULL) {
+        ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
+    }
+
+    return ASIT_NO_ERR;
+} /* asitBypassIoData */
+
+
+/*============================================================================
+ * ASIT Decode Processing
+ *     This function performs the decode processing and does the following based
+ *     on the ASIT events:
+ *     - initialize the decode processing if it is the first time
+ *     - if there is ASIT INPUT DATA event (ASIT_EVTMSK_INPDATA):
+ *        - mark I/O PHY transfer completion
+ *        - run auto-detection via I/O DATA in asitInputDataProcess
+ *        - check auto-detection status and take corresponding actions if SYNC
+ *          is lost.
+ *        - start next I/O PHY transfer
+ *     - map ASIT events to decoding messages
+ *     - invoke decDecodeFsm() and pass the mapped decoding messages
+ *     - if there is ASIT DECODE ACK event (ASIT_EVTMSK_DECACK)
+ *        - mark I/O DATA read completion
+ *     - error handling
+============================================================================*/
+Int asitDecodeProcessing(const PAF_ASIT_Params *pP,
+                         const PAF_ASIT_Patchs *pQ,
+                         PAF_ASIT_Config       *pAsitCfg,
+                         UInt asitEvents)
+{
+    Int asitErr, decErr;
+    PAF_AST_IoInp *pInp;                  // I/O components for input
+    AspMsgMaster_Handle hAspMsgMaster;    // ASIT message master handle
+    asipDecProc_t *pDec;
+    ioDataAutoDetStat_t autoDetStatus;
+    Int zMD;
+    UInt decMsg;
+    Int status;
+
+    zMD = pAsitCfg->pAstCfg->masterDec;         // pointer to AST common (shared) configuration
+    pInp = &pAsitCfg->pIoInp[zMD];              // pointer to input I/O components
+    hAspMsgMaster = pAsitCfg->hAspMsgMaster;    // get ASIT message master handle
+    pDec = &pAsitCfg->inpDec;
+
+    // Initialization for decode processing when this function is called the first time
+#ifndef DEBUG_SKIP_DECODING
+    if(!pDec->initDone) {
+        // Initialize decoder
+        decDecodeInit(pP, pAsitCfg, pInp->sourceSelect);
+
+        pDec->initDone = TRUE;
+    }
+#endif
+
+    // Process input data if this is a data ready message
+    if(asitEvents & ASIT_EVTMSK_INPDATA) {
+        TRACE_TERSE0("asitDecodeProcessing: process input data.");
+
+        // Marks I/O PHY transfer and I/O BUFF write complete
+        asitPhyTransferComplete(pInp);
+
+        // Process input data - either search SYNC for PCM or check SYNC for bitstream
+        asitErr = asitInputDataProcess(pInp, &autoDetStatus);
+
+        if(asitErr == ASIT_NO_ERR) {
+            ioDataReadComplete(pInp->hIoData);
+
+            // Check if SYNC is maintained or lost (stream stops or format changes)
+            if(autoDetStatus.syncState == IODATA_SYNC_NONE) {
+                // SYNC lost: change I/O PHY transfer size to default for auto-detection
+                //asitErr = asitRecfgPhyXfer(pInp, INPUT_FRAME_SIZE_DEF);
+                //if(asitErr != ASIT_NO_ERR) {
+                //    return asitErr;
+                //}
+
+                // Inform decoder to complete the decoding of previous frame - is this good?
+                pInp->sourceSelect = PAF_SOURCE_NONE;
+                pInp->numFrameReceived = 0;    // for debugging
+                TRACE_TERSE0("asitDecodeProcessing: SYNC lost.");
+
+#ifdef DEBUG_SKIP_DECODING
+                asitErr = ASIT_ERR_DECODE_QUIT;
+#endif
+            }
+            else {
+                pInp->numFrameReceived += 1;    // for debugging
+
+                // Communicate input stream information to decoder through input
+                // buffer configuration -- this was moved inside decDecodeFsm
+                //asitUpdateInpBufConfig(pAsitCfg->pAstCfg, pInp);
+
+                // Start next transfer
+                asitPhyTransferStart(pInp);
+            }
+
+            // Start next transfer
+            //asitPhyTransferStart(pInp);
+
+#ifdef DEBUG_SKIP_DECODING
+            return asitErr;
+#endif
+        }
+        else if(asitErr == ASIT_ERR_INPBUF_UNDERFLOW) {
+            TRACE_TERSE0("asitDecodeProcessing: Input buffer underflows.");
+
+            // When input buffer underflows, it is not an error but decoding needs
+            // to be skipped as there is not enough data in the buffer.
+            asitPhyTransferStart(pInp);
+
+            return asitErr;
+        }
+        else {
+            // Inform decoder to complete the decoding of previous frame - is this good?
+            pInp->sourceSelect = PAF_SOURCE_NONE;
+            pInp->numFrameReceived = 0;    // for debugging
+            TRACE_TERSE1("asitDecodeProcessing: asitInputDataProcess error: %d", asitErr);
+
+#ifdef DEBUG_SKIP_DECODING
+            return ASIT_ERR_DECODE_QUIT;
+#endif
+        }
+    } /* ASIT_EVTMSK_INPDATA */
+#ifdef DEBUG_SKIP_DECODING
+    else {
+        TRACE_TERSE0("asitDecodeProcessing: events error.");
+        return ASIT_ERR_EVENTS;
+    }
+#endif
+
+#ifndef DEBUG_SKIP_DECODING
+    // Map ASIT events to decode messages
+    decMsg = asitEventsToDecMsg(asitEvents);
+
+    // Pass messages (corresponding to events) to decode FSM
+    decErr = decDecodeFsm(pP, pQ, pAsitCfg, pInp->sourceSelect, decMsg);
+
+    // Mark I/O DATA read complete if decoder indicates decoding is done.
+    if((asitEvents & ASIT_EVTMSK_DECACK)) {  // DECACK -> decoding done
+        //ioDataReadComplete(pInp->hIoData);
+    }
+
+    if(decErr != DEC_NO_ERR) {
+        TRACE_VERBOSE0("TaskAsip: send DEC_EXIT message to slave decoder.");
+
+        // Send dec exit message to slave decoder
+        status = AspMsgSnd(hAspMsgMaster, ASP_SLAVE_DEC_EXIT, NULL);
+        if (status != ASP_MSG_NO_ERR)
+        {
+            TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
+            SW_BREAKPOINT;
+        }
+        status = AspMsgRcvAck(hAspMsgMaster, ASP_MASTER_DEC_EXIT_DONE, NULL, TRUE);
+        if (status != ASP_MSG_NO_ERR) 
+        {
+            TRACE_VERBOSE0("TaskAsip: error in sending DEC_EXIT message");
+            SW_BREAKPOINT;
+        }
+
+        return ASIT_ERR_DECODE_QUIT;  // This is not necessarily an error
+    }
+    else {
+        return ASIT_NO_ERR;
+    }
+#endif
+}  /* asitDecodeProcessing */
+
+
+/*============================================================================
+ * ASIT Input Data Processing:
+ *    - invoke ioDataProcess() to inspect input data for
+ *       - initial auto-detection,  or
+ *       - background scanning for PCM data, or
+ *       - SYNC check for bitstream
+ *    - return auto-detection status (SYNC detected, SYNC loss, etc)
+============================================================================*/
+Int asitInputDataProcess(PAF_AST_IoInp *pInp, ioDataAutoDetStat_t *pAutoDetStats)
+{
+    Int ioDataErr, retVal;
+    ioDataCtl_t ioDataCtl;
+
+    // Perform auto-detection inside I/O DATA component
+    ioDataErr = ioDataProcess(pInp->hIoData);
+
+    if(ioDataErr == IODATA_NO_ERR) {
+        // Normal operation - check auto-detection status
+        ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
+        ioDataControl(pInp->hIoData, &ioDataCtl);
+
+        *pAutoDetStats = ioDataCtl.param.autoDetStats;
+
+        retVal = ASIT_NO_ERR;
+    }
+    else if(ioDataErr == IODATA_ERR_IOBUF_UNDERFLOW) {
+        // Input buffer underflows - there is no enough data to process.
+        // This is not error and no action is needed.
+        pInp->numUnderflow += 1; // debug
+
+        retVal = ASIT_ERR_INPBUF_UNDERFLOW;
+    }
+    else {
+        // Something is wrong: print error log and return
+        //printf("IODATA processing error!\n");
+        retVal = ASIT_ERR_INPDATA_PROC;
+    }
+
+    return retVal;
+} /* asitInputDataProcess */
+
+/*============================================================================
+ * Mapping ASIT Events to Decoding Messages
+============================================================================*/
+UInt asitEventsToDecMsg(UInt asitEvents)
+{
+    UInt decMsg = 0;
+
+    if (asitEvents & ASIT_EVTMSK_INPDATA) {
+        // Input data event
+        decMsg |= DEC_MSGMSK_INPDATA;
+    }
+
+    // temp, simulation
+    //if(asitEvents & ASIT_EVTMSK_INFOACK) {
+    //    decMsg |= DEC_MSGMSK_INFOACK;
+    //}
+
+    // temp, simulation
+    //if(asitEvents & ASIT_EVTMSK_DECACK) {
+    //    decMsg |= DEC_MSGMSK_DECACK;
+    //}
+
+    if (asitEvents & ASIT_EVTMSK_RXACK)
+    {
+       // Receive acknowledge message event
+        decMsg |= DEC_MSGMSK_RXACK;
+    }
+    
+    return decMsg;
+} /* asitEventsToDecMsg */
 
 /*===========================================================================
  * Initialize I/O components for input processing
 ============================================================================*/
-int asipIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
+int asitIoCompsInit(PAF_AST_InpBuf * pInpBuf, PAF_AST_IoInp * pInpIo)
 {
-    // Initialize I/O BUFF and I/O PHY components for input task
     ioBuffParams_t ioBuffParams;
     ioPhyParams_t  ioPhyParams;
     ioDataParam_t  ioDataCfg;
+    ioPhyCtl_t     ioPhyCtl;
 
-    ioBuffParams.base         = pInpBuf->inpBufConfig.base.pVoid;
-    ioBuffParams.size         = pInpBuf->inpBufConfig.allocation/STRIDE_WORST_CASE*STRIDE_WORST_CASE;
-    ioBuffParams.sync         = IOBUFF_WRITE_SYNC;
-    ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
-    if(ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
-        return (-1);   // to remove magic number
-    }
+    if (pInpIo->hMcaspChan != NULL)
+    {
+        //pInpIo->phyXferSize = INPUT_FRAME_SIZE_DEF;
+        pInpIo->phyXferSize = pInpIo->stride * NUM_CYCLE_PER_FRAME_DEF * WORD_SIZE_BITSTREAM;
+
+        if (pInpIo->firstTimeInit) {
+            TRACE_VERBOSE0("Initialize I/O BUFF and I/O PHY.");
+            ioBuffParams.base         = pInpBuf->inpBufConfig.base.pVoid;
+            ioBuffParams.size         = pInpBuf->inpBufConfig.allocation / STRIDE_WORST_CASE
+                                                                         * STRIDE_WORST_CASE;
+            ioBuffParams.sync         = IOBUFF_WRITE_SYNC;
+            ioBuffParams.nominalDelay = INPUT_FRAME_SIZE_DEF;
+            if (ioBuffInit(pInpIo->hIoBuff, &ioBuffParams) != IOBUFF_NOERR) {
+                return (ASIT_ERR_IOBUFF_INIT);   // to remove magic number
+            }
 
-    ioPhyParams.ioBuffHandle    = pInpIo->hIoBuff;
-    ioPhyParams.xferFrameSize   = INPUT_FRAME_SIZE_DEF;
-    ioPhyParams.mcaspChanHandle = hMcaspRxChan;
-    ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_WRITE;
-    if(ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
-        return (-1);   // to remove magic number
-    }
+            ioPhyParams.ioBuffHandle    = pInpIo->hIoBuff;
+            ioPhyParams.xferFrameSize   = pInpIo->phyXferSize;
+            ioPhyParams.mcaspChanHandle = pInpIo->hMcaspChan;
+            ioPhyParams.ioBuffOp        = IOPHY_IOBUFFOP_WRITE;
+            if (ioPhyInit(pInpIo->hIoPhy, &ioPhyParams) != IOPHY_NOERR) {
+                return (ASIT_ERR_IOPHY_INIT);   // to remove magic number
+            }
 
-    ioDataCfg.ioBuffHandle         = pInpIo->hIoBuff;
-    ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
-    ioDataCfg.frameLengthsIEC      = (uint_least16_t *)&iecFrameLength[0];
-    ioDataCfg.frameLengthPCM       = INPUT_FRAME_SIZE_PCM / WORD_SIZE_PCM;
-    ioDataCfg.frameLengthDef       = INPUT_FRAME_SIZE_DEF / WORD_SIZE_BITSTREAM;
-    ioDataCfg.ibMode               = pInpBuf->inpBufConfig.pBufStatus->mode;
-    ioDataCfg.zeroRunRestart       = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
-    ioDataCfg.zeroRunTrigger       = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
+            pInpIo->numPrimeXfers = NUM_PRIME_XFERS;
+        }
 
-    if(ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
-        return (-1);   // to remove magic number
-    }
+        /* Reinitialize I/O DATA every time when ASIT restarts */
+        TRACE_VERBOSE0("Initialize I/O DATA.");
+        ioDataCfg.ioBuffHandle         = pInpIo->hIoBuff;
+        ioDataCfg.unknownSourceTimeOut = pInpBuf->inpBufConfig.pBufStatus->unknownTimeout;
+        ioDataCfg.frameLengthsIEC      = (uint_least16_t *)&iecFrameLength[0];
+        ioDataCfg.frameLengthPCM       = pInpIo->stride * NUM_CYCLE_PER_FRAME_DEF;
+        ioDataCfg.frameLengthDef       = pInpIo->stride * NUM_CYCLE_PER_FRAME_DEF;
+        ioDataCfg.ibMode               = pInpBuf->inpBufConfig.pBufStatus->mode;
+        ioDataCfg.zeroRunRestart       = pInpBuf->inpBufConfig.pBufStatus->zeroRunRestart;
+        ioDataCfg.zeroRunTrigger       = pInpBuf->inpBufConfig.pBufStatus->zeroRunTrigger;
+
+        if (ioDataInit(pInpIo->hIoData, &ioDataCfg) != IODATA_NO_ERR) {
+            return (ASIT_ERR_IODATA_INIT);   // to remove magic number
+        }
+
+        if (pInpIo->firstTimeInit) {
+            /* Initialize I/O BUFF and I/O PHY only when input interface changes. */
+            TRACE_VERBOSE0("Prime I/O PHY.");
 
-    pInpIo->phyXferSize    = ioPhyParams.xferFrameSize;
-    pInpIo->switchHangOver = 0;
-    pInpIo->syncState      = IODATA_SYNC_NONE;
+            // Start I/O physical layer by priming McASP LLD for input
+            asitIoPhyPrime(pInpIo);
+
+            pInpIo->firstTimeInit = FALSE;
+        }
+        else {
+            // Reconfigure I/O PHY transfer size
+            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+            ioPhyCtl.params.xferFrameSize = pInpIo->phyXferSize;
+            ioPhyControl(pInpIo->hIoPhy, &ioPhyCtl);
+    #if 0
+            // If previous stream before reset was PCM, reconfigure McASP LLD to receive 16-bit packed bits
+            if (!pInpIo->swapData) {
+                Int mcaspErr;
+                mcaspErr = mcaspRecfgWordWidth(pInpIo->hMcaspChan, Mcasp_WordLength_16);
+                if(mcaspErr != Aud_EOK) {
+                    return ASIT_ERR_MCASP_CFG;
+                }
+
+                // Start swapping data
+                pInpIo->swapData = TRUE;
+                TRACE_VERBOSE0("Reconfigure McASP word length and start swapping data.");
+            }
+    #endif
+            // Start PHY transfer
+            TRACE_VERBOSE0("Start I/O PHY transfer.");
+            asitPhyTransferStart(pInpIo);
+        }
+    }
 
     return 0;
-} /* asipIoCompsInit */
+} /* asitIoCompsInit */
 
 /*======================================================================================
- *  This function initializes ASIP processing
+ *  This function initializes ASIT processing
  *====================================================================================*/
-void asipProcInit(PAF_AST_IoInp  *pInp)
+void asitProcInit(PAF_AST_IoInp  *pInp, asipDecProc_t *pDec)
 {
-    pInp->swapData = SWAP_INPUT_DATA;
-    pInp->asipProcState = ASIP_SOURCE_DETECTION;
-    pInp->switchHangOver = 0;
+//    pInp->swapData = TRUE;
+    pInp->pcmSwitchHangOver = INPUT_SWITCH_HANGOVER;
+    pDec->initDone = FALSE;
+    pInp->numFrameReceived = 0;
 }
 
 /*======================================================================================
  *  I/O physical layer prime operation required by McASP LLD
  *====================================================================================*/
-void asipIoPhyPrime(PAF_AST_IoInp *pInp)
+void asitIoPhyPrime(PAF_AST_IoInp *pInp)
 {
     Int32        count;
 
@@ -560,26 +1009,45 @@ void asipIoPhyPrime(PAF_AST_IoInp *pInp)
         //pInp->numXferStart++;
 #endif
     }
-} /* asipIoPhyPrime */
+} /* asitIoPhyPrime */
 
-/*======================================================================================
- *  This function pends on I/O PHY transfer for the input task
- *====================================================================================*/
-void asipPhyTransferPend()
-{
-    // asipSemRx needs to be placed into some data structure
-    Semaphore_pend(asipSemRx, BIOS_WAIT_FOREVER);
-} /* asipPhyTransferPend */
 
 /*======================================================================================
  *  This function marks the I/O PHY transfer as complete
  *====================================================================================*/
-void asipPhyTransferComplete(PAF_AST_IoInp * pInpIo)
+void asitPhyTransferComplete(PAF_AST_IoInp * pInpIo)
 {
     // Mark underlining I/O BUFF write complete and swap data if needed
     ioPhyXferComplete(pInpIo->hIoPhy, pInpIo->swapData);
-} /* asipPhyTransferComplete */
+} /* asitPhyTransferComplete */
+
+#if 0
+Int asitRecfgPhyXfer(PAF_AST_IoInp *pInp, size_t xferSize)
+{
+    ioPhyCtl_t ioPhyCtl;
+    Int mcaspErr;
 
+    ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+    ioPhyCtl.params.xferFrameSize = xferSize;
+    ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
+
+    pInp->phyXferSize  = ioPhyCtl.params.xferFrameSize;
+
+    if(!pInp->swapData) {
+        // If it was PCM, reconfigure McASP LLD to receive 16-bit packed bits
+        mcaspErr = mcaspRecfgWordWidth(pInp->hMcaspChan, Mcasp_WordLength_16);
+        if(mcaspErr != Aud_EOK) {
+            return ASIT_ERR_MCASP_CFG;
+        }
+
+        // Start swapping data
+        pInp->swapData = TRUE;
+    }
+
+    return ASIT_NO_ERR;
+
+} /* asitRecfgPhyXfer */
+#endif
 
 /*======================================================================================
  *  McASP LLD call back function
@@ -588,7 +1056,8 @@ void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
 {
     /* post semaphore */
     if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
-        Semaphore_post(asipSemRx);
+        //Semaphore_post(asipSemRx);
+        Event_post(gAsitEvtHandle, ASIT_EVTMSK_INPDATA);
     } else {
         ;    // intermediate packet due to buffer wrapping around
     }
@@ -597,39 +1066,47 @@ void asipMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
 /*======================================================================================
  *  This function checks if McASP Rx for input overruns
  *====================================================================================*/
-int asipCheckMcaspRxOverrun(void)
+int asipCheckMcaspRxOverrun(Ptr mcaspChanHandle)
 {
     Mcasp_errCbStatus mcaspErrStat;
 
-    mcaspControlChan(hMcaspRxChan, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
+    mcaspControlChan(mcaspChanHandle, Mcasp_IOCTL_CHAN_QUERY_ERROR_STATS, &mcaspErrStat);
 
     return (mcaspErrStat.isRcvOvrRunOrTxUndRunErr);
 }
 
+#if 0
 /*======================================================================================
  *  This function restarts McASP LLD channel for input
  *====================================================================================*/
-void asipMcaspRxRestart(void)
+void asipMcaspRxRestart(PAF_AST_IoInp *pInpIo)
 {
     mcaspRxReset();
     mcaspRxCreate();
 }
+#endif
 
 /*======================================================================================
  *  This function starts an I/O PHY transfer
  *====================================================================================*/
-void asipPhyTransferStart(PAF_AST_IoInp *pInpIo)
+void asitPhyTransferStart(PAF_AST_IoInp *pInpIo)
 {
-    if(asipCheckMcaspRxOverrun()) {
+    Int ioPhyErr;
+
+    if(asipCheckMcaspRxOverrun(pInpIo->hMcaspChan)) {
 #ifdef ASIP_DEBUG
         pInpIo->numInputOverrun++;
 #endif
-        asipMcaspRxRestart();
+        //asipMcaspRxRestart(pInpIo);
+        System_abort("\nMcASP for input overruns! %d!\n");
     }
     else {
-        if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
+        ioPhyErr = ioPhyXferSubmit(pInpIo->hIoPhy);
+        //if(ioPhyXferSubmit(pInpIo->hIoPhy)==IOPHY_ERR_BUFF_OVERFLOW) {
+        if(ioPhyErr!=IOPHY_NOERR){
+            printf("\n I/O PHY ioPhyXferSubmit fails with error %d!\n", ioPhyErr);
             // Input buffer overflows!
-            printf("\nInput buffer overflows!\n");
+            //printf("\nInput buffer overflows!\n");
             exit(0);
         }
         else {
@@ -642,59 +1119,183 @@ void asipPhyTransferStart(PAF_AST_IoInp *pInpIo)
     }
 }
 
+// Indicates whether Input has been selected
 Int d10Initialized = 0;
-//extern Audk2g_STATUS mcaspAudioConfig(void);
-extern void McaspDevice_init(void);
+
+//extern Aud_STATUS mcaspAudioConfig(void);
+//extern void McaspDevice_init(void);
 
 /*======================================================================================
  *  This function initializes HW interface and selects the right device for input
  *====================================================================================*/
-Int asipSelectDevices(const PAF_ASIT_Patchs *pQ, PAF_AST_IoInp *pInp)
+Int asitSelectDevices(
+    const PAF_ASIT_Patchs *pQ, 
+    PAF_AST_Config *pAstCfg, 
+    PAF_AST_IoInp *pInp
+)
 {
-    Audk2g_STATUS status;
+    Aud_STATUS status;
+    const PAF_SIO_Params *pInPrms;
+    mcaspLLDconfig *pLldCfg;
+    mcaspLLDconfig *pReqLldCfg;
+    Ptr mcaspChanHandle;
+    Int zMD;
+    Int interface;
+    const PAF_SIO_Params *pD10Params;
+    UInt postedEvents;
 
-    //more configuration is needed to abstract out D10
-    if(!d10Initialized) {
-        /* Initialize McASP HW details */
-        McaspDevice_init();
-
-        D10_init();
-
-#ifdef INPUT_SPDIF
-        // Input is DIR
-        status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_DIR);
-#else
-        // Input is HDMI
-        status = audk2g_AudioSelectClkSrc(AUDK2G_AUDIO_CLK_SRC_I2S);
-#endif
-        if(status != Audk2g_EOK) {
-            Log_info0("audk2g_AudioSelectClkSrc Failed!\n");
+    zMD = pAstCfg->masterDec;
+    
+    interface = pAstCfg->xInp[zMD].inpBufStatus.sioSelect; // obtain SIO select for input
+    
+    if (interface >= 0)
+    {
+        // Positive value for interface: new Input SIO update request has been received via alpha command.
+        // Negative value for interface: no new Input SIO update request has been received,
+        //                               previous requests have been processed.
+        
+        // check for valid index into device array
+        if (interface >= pQ->devinp->n)    // DEVINP_N
+        {
+            interface = 0; // treat as device InNone
         }
-        audk2g_delay(50000); // Without delay between these 2 calls system aborts.
+        
+        //
+        // Deactivate currently active interface
+        //
+        if (pInp->hMcaspChan != NULL)   // non-NULL McASP LLD channel handle indicates there's an active interface
+        {
+            d10Initialized = 0; // indicate no Input selected
+            
+            // check McASP LLD control API
+            mcaspControlChan(pInp->hMcaspChan, MCASP_CHAN_RESET, NULL);   // Rx reset channel
+            //mcaspControlChan(pInp->hMcaspChan, MCASP_DEVICE_RESET, NULL); // Reset Tx/Rx channel
+            
+            // Delete McASP LLD channel
+            status = mcaspDeleteChan(pInp->hMcaspChan);
+            if (status != Aud_EOK)
+            {
+                Log_info0("asitSelectDevices(): McASP channel deletion failed!\n");
+                return ASIP_ERR_MCASP_CFG;
+            }
+            
+            // Clear (drop) already posted Input data events
+            postedEvents = Event_getPostedEvents(gAsitEvtHandle);
+            while ((postedEvents & ASIT_EVTMSK_INPDATA) != 0)
+            {
+                Event_pend(gAsitEvtHandle, ASIT_EVTMSK_NONE, ASIT_EVTMSK_INPDATA, 0);
+                postedEvents = Event_getPostedEvents(gAsitEvtHandle);
+            }
 
-        /* Initialize McASP module */
-        status = mcaspAudioConfig(); //defined in newio\fw\mcasp_cfg.c
-        if(status != Audk2g_EOK) {
-            TRACE_TERSE0("McASP Configuration Failed!\n");
+            pInp->hMcaspChan = NULL;        // reset active McASP LLD handle
+            if (pInp->pRxParams != NULL)    // sanity check, pInp->pRxParams should be non NULL if pInp->hMcaspChan is non NULL
+            {
+                pInPrms = (const PAF_SIO_Params *)pInp->pRxParams;
+                pLldCfg = (mcaspLLDconfig *)pInPrms->sio.pConfig; // get pointer to active McASP LLD configuration
+                pLldCfg->hMcaspChan = NULL; // reset McASP LLD handle for active McASP LLD configuration
+                pInp->pRxParams = NULL;     // reset pointer to active D10 parameters
+            }
+            else 
+            {
+                // This is a programming error
+                SW_BREAKPOINT;  // debug
+            }
         }
 
-        d10Initialized = 1;
+        //
+        // Activate requested interface
+        //
+        pD10Params = (const PAF_SIO_Params *)pQ->devinp->x[interface];  // get D10 parameters for selected interface
+        if (pD10Params != NULL)
+        {
+            //
+            // Requested device is other than InNone
+            //
+            
+            // Initialize Tx clock mux
+            D10_initClkMux((void *)pD10Params);
+                
+            pReqLldCfg = (mcaspLLDconfig *)pD10Params->sio.pConfig;
+            if (pReqLldCfg->hMcaspChan == NULL)
+            {
+                // Create McASP LLD channel
+                mcaspChanHandle = NULL;
+                status = mcasplldChanCreate(pReqLldCfg, &mcaspChanHandle);
+                if (status != Aud_EOK) 
+                {
+                    Log_info0("asitSelectDevices(): McASP channel creation failed!\n");
+                    return ASIP_ERR_MCASP_CFG;
+                }
+                
+                pReqLldCfg->hMcaspChan = mcaspChanHandle;   // set McASP LLD handle for requested McASP LLD configuration
+                pInp->pRxParams = (const void *)pD10Params; // set pointer to active D10 parameters
+                pInp->hMcaspChan = pReqLldCfg->hMcaspChan;  // set active McASP LLD handle
+                
+                // configure stride according to selected McASP LLD configuration
+                pInp->stride = pReqLldCfg->mcaspChanParams->noOfSerRequested * 
+                    pReqLldCfg->mcaspChanParams->noOfChannels;
+                
+                pInp->firstTimeInit = TRUE; // set flag for IO Phy & Buff initialization
+                
+                d10Initialized = 1; // indicate Input selected
+            }
+        }
+        else
+        {
+            //
+            // Requested device is InNone
+            //
+            pInp->hMcaspChan = NULL;    // reset active McASP LLD handle
+            pInp->pRxParams = NULL;     // reset pointer to active D10 parameters
+        }
+        
+        // indicate SIO update request processed
+        pAstCfg->xInp[zMD].inpBufStatus.sioSelect = interface | 0x80;
     }
 
-    /////////////// TODO: HW interface selection and initialization //////////////
-#ifdef IO_HW_INTERFACE
-    pInp->pRxParams = pQ->devinp->x[IO_HW_INTERFACE];
-#else
-    pInp->pRxParams = NULL;
-#endif
+    if (pInp->hMcaspChan != NULL)       // non NULL indicates there's an active interface
+    {
+        if (pInp->pRxParams != NULL)    // sanity check, this should be non NULL if pInp->hMcaspChan is non NULL
+        {
+            pInPrms = (const PAF_SIO_Params *)pInp->pRxParams;
+            pLldCfg = (mcaspLLDconfig *)pInPrms->sio.pConfig;   // get currently active McASP LLD configuration
+            if (pLldCfg != NULL)        // sanity check, this should be non NULL if pInp->hMcaspChan is non NULL
+            {
+                // Configure McASP to receive 16/32-bit data according to default configuration
+                mcaspRecfgWordWidth(pInp->hMcaspChan, pLldCfg->mcaspChanParams->wordWidth);
+                
+                // Set flag to swap HDMI data if it is 4xI2S and word length is 16
+                if ((pLldCfg->mcaspChanParams->wordWidth == Mcasp_WordLength_16) &&
+                    (pLldCfg->mcaspChanParams->noOfSerRequested == 4)) 
+                {
+                    pInp->swapData = TRUE;
+                }
+                else 
+                {
+                    pInp->swapData = FALSE;
+                }
+            }
+            else
+            {
+                // This is a programming error
+                SW_BREAKPOINT;  // debug
+            }
 
-    return 0;
-}  /* asipSelectDevices */
+        }
+        else
+        {
+            // This is a programming error
+            SW_BREAKPOINT;  // debug
+        }
+    }
+    
+    return ASIP_NO_ERR;
+}  /* asitSelectDevices */
 
 /*======================================================================================
  *  This function updates input status
  *====================================================================================*/
-Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
+Int asitUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
                           PAF_InpBufConfig *pInpBuf)
 {
     Int asipErrno;
@@ -715,8 +1316,9 @@ Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
     asipErrno = D10_RxControl(pRxParams,
                           (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS,
                           (Arg) &inputStatus);
-    if (asipErrno)
+    if (asipErrno) {
         return asipErrno;
+    }
     pStatus->sampleRateData = inputStatus.sampleRateData;
     pStatus->sampleRateMeasured = inputStatus.sampleRateMeasured;
     pStatus->nonaudio = inputStatus.nonaudio;
@@ -774,212 +1376,388 @@ Int asipUpdateInputStatus(const void *pRxParams, PAF_InpBufStatus *pStatus,
 }
 
 
-/*=============================================================================
- *  Main function of ASIP processing
- *============================================================================*/
-#define INPUT_SWITCH_HANGOVER 8
-
-Int asipProcessing(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
+/*==============================================================================
+ * This function updates input buffer config based on frame information provided
+ * by I/O DATA.
+ ==============================================================================*/
+void asitUpdateInpBufConfig(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp)
 {
-    int autoDetstatus, syncState;
-    Audk2g_STATUS mcaspStatus;
-
+    PAF_InpBufConfig *pBufConfig;
     ioDataCtl_t ioDataCtl;
-    ioPhyCtl_t  ioPhyCtl;
 
-    if(pInp->asipProcState == ASIP_SWITCH_TO_PCM) {
-        // When switching to PCM, McASP RFMT register will be modified,
-        // which will cause all 0's in one McASP LLD transfer. This will
-        // be detected as loss of SYNC by auto detection. To prevent that,
-        // skip I/O DATA process for hangover period so that this all 0's
-        // frame will not be seen by auto-detection. Also, playing out PCM
-        // needs to be skipped as well, to prevent from playing out garbage
-        // (16-bit packed data).
-        void *buff1, *buff2;
-        size_t size1, size2;
-
-        // Get read pointers (or sub-buffers) of the input buffer
-        if (ioBuffGetReadPtrs(pInp->hIoBuff, pInp->phyXferSize,
-                              &buff1, &size1, &buff2, &size2)
-            == IOBUFF_ERR_UNDERFLOW) {
-            //printf("Input buffer underflows during switch hangover!\n");
-            return ASIP_ERR_SWITCH_TO_PCM;
-        }
-
-        ioBuffReadComplete(pInp->hIoBuff, buff1, size1);
+    /* Get information for reading input data */
+    ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
+    ioDataControl(pInp->hIoData, &ioDataCtl);
 
-        if(buff2 != NULL) {
-            ioBuffReadComplete(pInp->hIoBuff, buff2, size2);
-        }
+    if(ioDataCtl.param.dataReadInfo.frameSize != pInp->phyXferSize) {
+        // Fatal error!
+        TRACE_VERBOSE0("TaskAsip: error in updating I/O");
+        SW_BREAKPOINT;
     }
-    else {
-        // Perform auto-detection when not switching
-        autoDetstatus = ioDataProcess(pInp->hIoData);
-        if(autoDetstatus == IODATA_ERR_IOBUF_UNDERFLOW) {
-            // Input buffer underflows - no action is needed
-            //printf("Input buffer underflows.\n");
-            pInp->numUnderflow += 1;
-
-            // Return since there is no enough data to process
-            return ASIP_NO_ERR;
-        }
-        else if(autoDetstatus != IODATA_NO_ERR) {
-            // Something run happens: print error log and return
-            //printf("IODATA processing error!\n");
-            return ASIP_ERR_AUTO_DETECION;
+
+    pBufConfig = &(pAstCfg->xInp[pAstCfg->masterDec].inpBufConfig);
+
+    //JXTODO: do we need to gate here?
+    //key = GateMP_enter(gateHandle);
+
+    pBufConfig->base.pVoid   = ioDataCtl.param.dataReadInfo.buffBase;
+    pBufConfig->sizeofBuffer = ioDataCtl.param.dataReadInfo.buffSize;
+    pBufConfig->pntr.pSmInt  = ioDataCtl.param.dataReadInfo.startAddress;
+
+    // Leave the gate
+    //GateMP_leave(gateHandle, key);
+
+    TRACE_TERSE2("Frame start address: 0x%x., preamble: 0x%x",
+                 (UInt)ioDataCtl.param.dataReadInfo.startAddress,
+                 *(UInt *)ioDataCtl.param.dataReadInfo.startAddress);
+}
+
+/*==============================================================================
+ * Decide source after SYNC is found, i.e. either bitstream preamble is detected
+ * or it times out to PCM.
+ ==============================================================================*/
+Int asitDecideSource(PAF_AST_Config *pAstCfg, PAF_AST_IoInp  *pInp, 
+                     ioDataAutoDetStat_t *autoDetStatus)
+{
+    Int sourceConfig, sourceSelect, sourceProgram;
+    Int zMD;
+    char asipMsgBuf[ASP_MSG_BUF_LEN];
+    Int status;
+
+    // Get the configured source
+    zMD = pAstCfg->masterDec;
+    sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+                                          GATEMP_INDEX_DEC);
+
+    if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
+        if (sourceConfig == PAF_SOURCE_DSD1 || sourceConfig == PAF_SOURCE_DSD2 ||
+            sourceConfig == PAF_SOURCE_DSD3) {
+            sourceProgram = sourceConfig;
         }
         else {
-            // Normal operation - check auto-detection status
-            ioDataCtl.code = IODATA_CTL_GET_AUTODET_STATUS;
-            ioDataControl(pInp->hIoData, &ioDataCtl);
-
-            syncState = ioDataCtl.param.autoDetStats.syncState;
+            sourceProgram = PAF_SOURCE_PCM;
         }
     }
 
-    switch(pInp->asipProcState)
+    if(autoDetStatus->syncState == IODATA_SYNC_BITSTREAM) {
+        uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
+        sourceProgram = IECpafSource[pc];
+    }
+
+    // write the decided source program to memory
+    sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), sourceProgram,
+                       GATEMP_INDEX_DEC);
+
+    // now that we have some input classification, and possibly an outstanding
+    // input frame, we determine whether or not to call decodeProcessing and with
+    // what decAlg.
+    sourceSelect = PAF_SOURCE_NONE;
+
+    switch (sourceConfig)
     {
-    case ASIP_SOURCE_DETECTION:
-        // zero out the output buffer
-        rxDecodePlayZero(pInp);
+        // If autodetecting, decoding everything, and input is something
+        // (i.e. bitstream or PCM) then decode.
+        case PAF_SOURCE_AUTO:
+            if (sourceProgram >= PAF_SOURCE_PCM)  {
+                sourceSelect = sourceProgram; // use whatever from autodet
+            }
+            break;
 
-        ioDataReadComplete(pInp->hIoData);
+        // If autodetecting, decoding only PCM, and input is PCM then decode.
+        case PAF_SOURCE_PCMAUTO:
+            if (sourceProgram == PAF_SOURCE_PCM) {
+                // only expect autodet to give PAF_SOURCE_PCM, otherwise set to NONE
+                sourceSelect = sourceProgram;
+            }
+            break;
 
-        if(syncState == IODATA_SYNC_BITSTREAM) {
-            // Change I/O PHY transfer size to be the same as the bitstream frame size
-            int frameSize;
-            uint_least16_t pc = ioDataCtl.param.autoDetStats.bitStreamInfo & SYNC_PC_MASK; //0x001F
-            frameSize = iecFrameLength[pc] * WORD_SIZE_BITSTREAM;
+        // If autodetecting, decoding only bitstreams, and input is a bitstream then decode.
+        case PAF_SOURCE_BITSTREAM:
+            if (sourceProgram >= PAF_SOURCE_AC3) {
+                sourceSelect = sourceProgram;
+            }
+            break;
 
-            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
-            ioPhyCtl.params.xferFrameSize = frameSize;
-            ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
-            pInp->phyXferSize = ioPhyCtl.params.xferFrameSize;
+        // If autodetecting, decoding only DTS, and input is DTS then decode.
+        case PAF_SOURCE_DTSALL:
+            switch (sourceProgram)
+            {
+                case PAF_SOURCE_DTS11:
+                case PAF_SOURCE_DTS12:
+                case PAF_SOURCE_DTS13:
+                case PAF_SOURCE_DTS14:
+                case PAF_SOURCE_DTS16:
+                case PAF_SOURCE_DTSHD:
+                    sourceSelect = sourceProgram;
+                    break;
+            }
+            break;
 
-            pInp->asipProcState = ASIP_DECODE_BITSTREAM;
-            pInp->numFrameReceived = 1;
-        }
-        else if(syncState == IODATA_SYNC_PCM) {
-            // reconfigure McASP LLD to transfer 32-bit unpacked data
-            mcaspStatus = mcaspRecfgWordWidth(hMcaspRxChan, Mcasp_WordLength_32);
-            if(mcaspStatus != Audk2g_EOK) {
-                return ASIP_ERR_MCASP_CFG;
+        // All others, e.g., force modes, fall through to here.
+        // If user made specific selection then program must match select.
+        // (NB: this compare relies on ordering of PAF_SOURCE)
+        default:
+            sourceSelect = sourceConfig;
+            if ((sourceSelect >= PAF_SOURCE_PCM) && (sourceSelect <= PAF_SOURCE_N)) {
+                if (sourceProgram != sourceSelect) {
+                    sourceSelect = PAF_SOURCE_NONE;
+                }
             }
+            break;
+    }
 
-            // Change I/O PHY transfer size to PCM frame size
-            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
-            ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_PCM;
-            ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
-            pInp->phyXferSize = ioPhyCtl.params.xferFrameSize;
+    // if we didn't find any matches then skip
+    if (sourceSelect == PAF_SOURCE_NONE) {
+        TRACE_VERBOSE0("TaskAsip: no matching source type, continue");
+        return ASIT_ERR_NO_MATCHING_SOURCE;
+    }
 
-            // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
-            // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
-            // Adjust delay and don't mark input buffer as read complete
-            ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
+#ifndef DEBUG_SKIP_DECODING
+    // send source select message to slave
+    *(Int32 *)&asipMsgBuf[0] = sourceSelect;
+    status = AspMsgSnd(gPAF_ASIT_config.hAspMsgMaster, ASP_SLAVE_DEC_SOURCE_SELECT, asipMsgBuf);
+    if (status != ASP_MSG_NO_ERR) 
+    {
+        TRACE_VERBOSE0("TaskAsip: error in sending SOURCE_SELECT message");
+        SW_BREAKPOINT;
+    }
+    status = AspMsgRcvAck(gPAF_ASIT_config.hAspMsgMaster, ASP_MASTER_DEC_SOURCE_SELECT_DONE, NULL, TRUE);
+    if (status != ASP_MSG_NO_ERR)
+    {
+        TRACE_VERBOSE0("TaskAsip: error in receiving SOURCE_SELECT ack message");
+        SW_BREAKPOINT;
+    }
+#endif
 
-            // Stop swapping data
-            pInp->swapData = FALSE;
+    pInp->sourceSelect  = sourceSelect;
+    pInp->sourceProgram = sourceProgram;
 
-            // Go to transition state to switch to PCM
-            pInp->asipProcState = ASIP_SWITCH_TO_PCM;
-            pInp->switchHangOver = INPUT_SWITCH_HANGOVER;
+    return ASIT_NO_ERR;
+} /* asitDecideSource */
 
-            pInp->numPcmFrameReceived = 0;
-        }
-        else {
-            // Source is still unknown - take no action
-            ;
-        }
-        break;
+/*==============================================================================
+ * After SYNC is found, i.e. either bitstream preamble is detected or it times
+ * out to PCM, update input buffer config and I/o components accordingly.
+ ==============================================================================*/
+Int asitUpdateIoComps(const PAF_ASIT_Params *pP, PAF_AST_Config *pAstCfg,
+                      PAF_AST_IoInp  *pInp, ioDataAutoDetStat_t *autoDetStatus)
+{
+    Int sourceConfig;
+    Int zMD, deliverZeros;
+    int ioFrameLength, decFrameLength;
+    PAF_InpBufConfig *pBufConfig;
+    ioPhyCtl_t  ioPhyCtl;
+    ioDataCtl_t ioDataCtl;
 
-    case ASIP_DECODE_BITSTREAM:
-        if (syncState == IODATA_SYNC_NONE) {
-            // Change I/O PHY transfer size to default
-            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
-            ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
-            ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
-            pInp->phyXferSize  = ioPhyCtl.params.xferFrameSize;
+    zMD = pAstCfg->masterDec;
+    pBufConfig = &pAstCfg->xInp[zMD].inpBufConfig;
 
-            pInp->numFrameReceived = 0;
-            pInp->asipProcState  = ASIP_SOURCE_DETECTION;
-        }
-        else {
-            pInp->numFrameReceived += 1;
+    // Compute decoder frame length based on source selection
+    decFrameLength = getFrameLengthSourceSel(pP, pInp->sourceSelect);
 
-            rxDecodeBitStream(pInp);
+    pAstCfg->xDec[zMD].decodeControl.frameLength  = decFrameLength;
+    pAstCfg->xDec[zMD].decodeInStruct.sampleCount = decFrameLength;
+    pAstCfg->xDec[zMD].decodeControl.sampleRate   = PAF_SAMPLERATE_UNKNOWN;
 
-            ioDataReadComplete(pInp->hIoData);
-        }
-        break;
+    // Decide frame length for I/O DATA and I/O PHY
+    if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
+        // For PCM, I/O frame length is decode frame length multiplied by stride
+        ioFrameLength = decFrameLength * pInp->stride;
 
-    case ASIP_SWITCH_TO_PCM:
-        // zero out the output buffer
-        rxDecodePlayZero(pInp);
+        pBufConfig->sizeofElement = WORD_SIZE_PCM;
+        pBufConfig->frameLength   = pBufConfig->lengthofData = ioFrameLength;
 
-        pInp->switchHangOver--;
-        if(pInp->switchHangOver == 0) {
-            pInp->asipProcState = ASIP_DECODE_PCM;
-            // send message to decoder
-        }
-        break;
+        // Configure I/O DATA PCM frame length
+        ioDataCtl.code = IODATA_CTL_SET_PCM_FRAME_LENGTH;
+        ioDataCtl.param.frameLengthPcm = ioFrameLength;
+        ioDataControl(pInp->hIoData, &ioDataCtl);
 
-    case ASIP_DECODE_PCM:
-        if (syncState == IODATA_SYNC_NONE) {
-            // reconfigure McASP LLD to receive 16-bit packed bits
-            mcaspStatus = mcaspRecfgWordWidth(hMcaspRxChan, Mcasp_WordLength_16);
-            if(mcaspStatus != Audk2g_EOK) {
-                return ASIP_ERR_MCASP_CFG;
-            }
+        // Change I/O PHY transfer size to PCM frame size
+        pInp->phyXferSize = ioFrameLength*(WORD_SIZE_PCM);
 
-            // Change I/O PHY transfer size to default
-            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
-            ioPhyCtl.params.xferFrameSize = INPUT_FRAME_SIZE_DEF;
-            ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
-            pInp->phyXferSize  = ioPhyCtl.params.xferFrameSize;
+        // Adjust I/O BUFF delay and read pointer - to make sure read pointers always point to
+        // PCM data from 1st I2S (out of 4 for HDMI 4xI2S)
+        // Adjust delay and don't mark input buffer as read complete
+        //ioBuffAdjustDelay(pInp->hIoBuff, pInp->phyXferSize);
 
-            // Start swapping data
-            pInp->swapData = TRUE;
-            pInp->numPcmFrameReceived = 0;
+        // Stop swapping data
+        //pInp->swapData = FALSE;
+    }
+    else {
+        // For bitstream, I/O frame length is the frame length of the bitstream
+        uint_least16_t pc = autoDetStatus->bitStreamInfo & SYNC_PC_MASK; //0x001F
+        ioFrameLength = iecFrameLength[pc];
 
-            pInp->asipProcState = ASIP_SOURCE_DETECTION;
+/*
+        if(   (pc == 0x11) && (DTSHDSubType == 3)
+           && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
+            pDevExt->sourceProgram = PAF_SOURCE_DXP;    // LBR is 23
+
+        if (pc == 1)
+            pDevExt->elementSize = 4288;
+        else if (pc == 0x11) {
+            pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
+            pDevExt->lengthofData = pDevExt->frameLength;
         }
-        else {
-            pInp->numPcmFrameReceived += 1;
+*/
 
-            rxDecodePcm(pInp);
+        pBufConfig->sizeofElement = WORD_SIZE_BITSTREAM;
+        pBufConfig->frameLength   = ioFrameLength;
+        pBufConfig->lengthofData  = ioFrameLength - IEC_HEADER_LENGTH;
 
-            ioDataReadComplete(pInp->hIoData);
-        }
+        // Change I/O PHY transfer size to bitstream frame size
+        pInp->phyXferSize = ioFrameLength*WORD_SIZE_BITSTREAM;
+    }
 
-        break;
+    pBufConfig->stride = pInp->stride;   // common for PCM and bitstream
 
-    default:
-        break;
+    // Configure I/O PHY transfer size
+    ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
+    ioPhyCtl.params.xferFrameSize = pInp->phyXferSize;
+    ioPhyControl(pInp->hIoPhy, &ioPhyCtl);
+
+    // Decide if zeros should be delivered based on the configured source
+    sourceConfig = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+                                          GATEMP_INDEX_DEC);
+
+    if(autoDetStatus->syncState == IODATA_SYNC_PCM) {
+        // Bitstream preamble is not found and it times out -> assume this is PCM
+        deliverZeros = autoDetStatus->deliverZeros;
+        if (sourceConfig == PAF_SOURCE_PCM || sourceConfig == PAF_SOURCE_DSD1 ||
+            sourceConfig == PAF_SOURCE_DSD2 || sourceConfig == PAF_SOURCE_DSD3) {
+            // set to one -- ensures that PCM decode calls made before data is
+            // available will result in zero output.
+            // (mostly needed for PA15 since, currently, all other frameworks
+            // require a frame of data before the first decode call.
+            deliverZeros = TRUE;  // override deliverZeros returned by ioDataControl
+        }
+
+        // update input buffer config structure
+        pBufConfig->deliverZeros  = deliverZeros;
     }
 
-    return 0;
-} /* asipProcessing */
+    //JXTODO: decide what to do with hRxSio
+    //temporary - does ARM use hRxSio or just check if it is not NULL?
+    pAstCfg->xInp[zMD].hRxSio = pInp->hIoData;
+    pAstCfg->xInp[zMD].pInpBuf = &(pAstCfg->xInp[zMD].inpBufConfig);
 
+    return ASIT_NO_ERR;
+} /* asitUpdateIoComps */
+
+#if 0
 #ifndef IO_LOOPBACK_TEST
+#if OUTPUT_FRAME_LENGTH == INPUT_FRAME_LENGTH
+U8 pcmbuf[OUTPUT_FRAME_SIZE];
+#else
+#error Input frame length is not equal to output frame length!
+#endif
+
 Int rxDecodePcm(PAF_AST_IoInp  *pInp)
 {
-    return ASIP_NO_ERR;
+    ioDataCtl_t ioDataCtl;
+    void *buffBase;
+    void *dataStartAddress;
+    size_t buffSize, frameSize, size1, size2;
+
+    /* Get information for reading input data */
+    ioDataCtl.code = IODATA_CTL_GET_INPBUFFINFO;
+    ioDataControl(pInp->hIoData, &ioDataCtl);
+
+    buffBase = ioDataCtl.param.dataReadInfo.buffBase;
+    buffSize = ioDataCtl.param.dataReadInfo.buffSize;
+    dataStartAddress = ioDataCtl.param.dataReadInfo.startAddress;
+    frameSize        = ioDataCtl.param.dataReadInfo.frameSize;
+
+    // Copy PCM data to output buffer
+    if(((size_t)dataStartAddress+frameSize) <= ((size_t)buffBase+buffSize)) {
+        // Input buffer doesn't wrap around
+        Cache_inv(dataStartAddress, frameSize, Cache_Type_ALL, TRUE);
+        memcpy((void *)&pcmbuf[0], dataStartAddress, frameSize);
+    }
+    else {
+        // Input buffer wraps around
+        size1 = (size_t)buffBase + buffSize - (size_t)dataStartAddress;
+        size2 = frameSize - size1;
+        Cache_inv(dataStartAddress, size1, Cache_Type_ALL, TRUE);
+        memcpy((void *)&pcmbuf[0], dataStartAddress, size1);
+
+        Cache_inv(buffBase, size2, Cache_Type_ALL, TRUE);
+        memcpy((void *)&pcmbuf[size1], buffBase, size2);
+    }
+
+
+    return ASIT_NO_ERR;
 }
 
-Int rxDecodeBitStream(PAF_AST_IoInp  *pInp)
+
+Int rxDecodePlayZero(PAF_AST_IoInp  *pInp)
 {
-    return ASIP_NO_ERR;
+    return ASIT_NO_ERR;
 }
+#endif
 
-Int rxDecodePlayZero(PAF_AST_IoInp  *pInp)
+#endif
+
+Int asitEvtErrCheck(UInt actualEvents, UInt expectedEvents)
 {
-    return ASIP_NO_ERR;
+    TRACE_VERBOSE2("ASIT events error: actual events are: %d, expected events are: %d.",
+                   actualEvents, expectedEvents);
+
+    return ASIT_ERR_EVENTS;
 }
+
+void asitErrorHandling(PAF_ASIT_Config *pAsitCfg, Int asitErr)
+{
+    //UInt events;
+
+    if(asitErr == ASIT_ERR_INPBUF_UNDERFLOW) {
+        TRACE_VERBOSE0("ASIT error handling: input buffer underflows. No actions needed.");
+    }
+
+    if(asitErr == ASIT_AUTODET_TIME_OUT) {
+        pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
+        pAsitCfg->pIoInp[0].numAsitRestart++;
+        TRACE_VERBOSE1("ASIT error %d handling finished. Go to state ASIT_RESET.", asitErr);
+    }
+    
+    if(asitErr == ASIT_ERR_DECODE_QUIT) {
+        TRACE_VERBOSE0("ASIT error handling: DECODE_QUIT - clear INPDATA event.");
+#if 0
+        // Pend on INPTDATA event that should have been posted before decoding quits.
+        events = Event_pend(asitEvent, ASIT_EVTMSK_NONE, ASIT_EVTMSK_INPDATA,
+                            BIOS_WAIT_FOREVER);
+
+        // Marks I/O PHY transfer and I/O BUFF write complete
+        asitPhyTransferComplete(&pAsitCfg->pIoInp[0]);
+
+        // Keep I/O BUFF read pointers going
+        asitBypassIoData(&pAsitCfg->pIoInp[0]);
 #endif
+        pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
+        pAsitCfg->pIoInp[0].numAsitRestart++;
+        TRACE_VERBOSE1("ASIT error %d handling finished. Go to state ASIT_RESET.", asitErr);
+    }
 
-void asipErrorHandling(PAF_AST_Config *pAstCfg, int asipErrno)
+    if(asitErr == ASIT_ERR_EVENTS) {
+        pAsitCfg->pIoInp[0].asipState = ASIT_RESET;
+        pAsitCfg->pIoInp[0].numAsitRestart++;
+        TRACE_VERBOSE1("ASIT error %d handling: events error. Go to state ASIT_RESET.", asitErr);
+    }
+
+    return;
+}  /* asitErrorHandling */
+
+
+//////////////////////////////////////////////////////////////////////////////
+void asitPostInfoEvent()
 {
+    Event_post(gAsitEvtHandle, ASIT_EVTMSK_INFOACK);
+}
 
+void asitPostDecEvent()
+{
+    Event_post(gAsitEvtHandle, ASIT_EVTMSK_DECACK);
 }
+//////////////////////////////////////////////////////////////////////////////
 
 /* Nothing past this line */