Exemplo n.º 1
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	Poll the status registers to keep the register cache somewhat coherent
//	for the user client to access status data properly.  Polling avoids
//  accessing any interrupt register that is processed in the 'notifyHardwareEvent'
//  method to avoid potential corruption of the interrupt status.
void AppleTopazPluginCS8420::poll ( void ) {
    for ( UInt32 registerAddress = map_CS8420_MISC_CNTRL_1; registerAddress <= map_CS8420_BUFFER_23; registerAddress++ ) {
        if ( ( 0x31 != registerAddress ) && ( map_CS8420_RX_ERROR != registerAddress ) ) {
            CODEC_ReadRegister ( registerAddress, &mShadowRegs[registerAddress], 1 );
            if ( map_CS8420_SERIAL_OUTPUT_FMT >= registerAddress ) {	//  [3686032]   initialize so log will show register dump a while longer
                debugIOLog ( 5, "  AppleTopazPluginCS8420::poll register 0x%2.2X : 0x%2.2X", registerAddress, mShadowRegs[registerAddress] );
            }
        }
    }
    CODEC_ReadRegister ( map_ID_VERSION, &mShadowRegs[map_ID_VERSION], 1 );
}
Exemplo n.º 2
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IOReturn	AppleTopazPluginCS8420::makeClockSelectPreLock ( UInt32 clockSource ) {
    IOReturn			result;
    UInt8				data;

    debugIOLog (5,  "+ AppleTopazPluginCS8420::makeClockSelect ( %d )", (unsigned int)clockSource );

    //	Clear any pending error interrupt status and re-enable error interrupts after completing clock source selection
    result = CODEC_ReadRegister ( map_CS8420_RX_ERROR, &data, 1 );
    FailIf ( kIOReturnSuccess != result, Exit );

    //	Enable error (i.e. RERR) interrupts ONLY IF C28420 IS CLOCK MASTER
    if ( kTRANSPORT_SLAVE_CLOCK == clockSource ) {
        result = CODEC_WriteRegister ( map_CS8420_RX_ERROR_MASK, kCS8420_RX_ERROR_MASK_ENABLE_RERR );
        FailIf ( kIOReturnSuccess != result, Exit );
    }

    switch ( clockSource ) {
    case kTRANSPORT_MASTER_CLOCK:
        data = mShadowRegs[map_CS8420_DATA_FLOW_CTRL];
        data &= ~( bvCS8420_spdMASK << baCS8420_SPD );
        data |= ( bvCS8420_spdSrcOut << baCS8420_SPD );
        result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, data );

        data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL];
        data &= ~( 1 << baCS8420_OUTC );
        data |= ( bvCS8420_outcOmckXbaCLK << baCS8420_OUTC );
        result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data );
        break;
    case kTRANSPORT_SLAVE_CLOCK:
        data = mShadowRegs[map_CS8420_DATA_FLOW_CTRL];
        data &= ~( bvCS8420_spdMASK << baCS8420_SPD );
        data |= ( bvCS8420_spdAES3 << baCS8420_SPD );
        result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, data );

        data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL];
        data &= ~( 1 << baCS8420_OUTC );
        data |= ( bvCS8420_outcRecIC << baCS8420_OUTC );
        result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data );
        break;
    }

    //	restart the codec after switching clocks
    data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL];
    data &= ~( 1 << baCS8420_RUN );
    data |= ( bvCS8420_runNORMAL << baCS8420_RUN );
    result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data );

    setChannelStatus ( &mChanStatusStruct );		//  [3669626]   Flush channel status buffer

Exit:
    debugIOLog (5,  "- AppleTopazPluginCS8420::makeClockSelect ( %d ) returns %d", (unsigned int)clockSource, (unsigned int)result );

    return result;
}
Exemplo n.º 3
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  This method is invoked from the 'codecErrorInterruptHandler' residing in the
//  platform interface object.  The 'codecErrorInterruptHandler' may be invoked
//  through GPIO hardware interrupt dispatch services or throught timer polled
//  services.
void AppleTopazPluginCS8420::notifyHardwareEvent ( UInt32 statusSelector, UInt32 newValue ) {
    IOReturn    error;
    UInt8       ratio;

    if ( kCodecErrorInterruptStatus == statusSelector ) {
        error = CODEC_ReadRegister ( map_CS8420_RX_ERROR, &mShadowRegs[map_CS8420_RX_ERROR], 1 );
        FailIf ( kIOReturnSuccess != error, Exit );

        // [4073140] - validate OMCK/RMCK ratio register
        error = CODEC_ReadRegister ( map_CS8420_SAMPLE_RATE_RATIO, &mShadowRegs[map_CS8420_SAMPLE_RATE_RATIO], 1 );
        FailIf ( kIOReturnSuccess != error, Exit );

        ratio = mShadowRegs[map_CS8420_SAMPLE_RATE_RATIO];

        if ( ( ( bvCS8420_pllLocked << baCS8420_UNLOCK ) == ( ( bvCS8420_pllUnlocked << baCS8420_UNLOCK ) & mShadowRegs[map_CS8420_RX_ERROR] ) ) &&
                ( ( kCS84XX_OMCK_RMCK_RATIO_LOCKED_MIN <= ratio ) && ( kCS84XX_OMCK_RMCK_RATIO_LOCKED_MAX >= ratio ) ) ) {
            mUnlockErrorCount = 0;
            mLockStatus = TRUE;
        } else {
            mUnlockErrorCount++;
            if ( kCLOCK_UNLOCK_ERROR_TERMINAL_COUNT < mUnlockErrorCount ) {
                mUnlockErrorCount = 0;
                mLockStatus = FALSE;
            }
        }

        if ( mLockStatus ) {
            debugIOLog ( 4, "  AppleTopazPluginCS8420::notifyHardwareEvent posts kClockLockStatus, mShadowRegs[map_CS8420_RX_ERROR] = 0x%0.2X, OMCK/RMCK ratio = 0x%0.2X", mShadowRegs[map_CS8420_RX_ERROR], ratio );
            mAudioDeviceProvider->interruptEventHandler ( kClockLockStatus, (UInt32)0 );
        } else {
            debugIOLog ( 4, "  AppleTopazPluginCS8420::notifyHardwareEvent posts kClockUnLockStatus, mShadowRegs[map_CS8420_RX_ERROR] = 0x%0.2X, OMCK/RMCK ratio = 0x%0.2X", mShadowRegs[map_CS8420_RX_ERROR], ratio );
            mAudioDeviceProvider->interruptEventHandler ( kClockUnLockStatus, (UInt32)0 );
        }
    } else if ( kCodecInterruptStatus == statusSelector ) {
    }

Exit:

    return;
}
Exemplo n.º 4
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IOReturn	AppleTopazPluginCS8420::initCodecRegisterCache ( void ) {
    IOReturn		result = kIOReturnSuccess;
    IOReturn		err;

    for ( UInt32 loopCnt = map_CS8420_MISC_CNTRL_1; loopCnt <= map_CS8420_BUFFER_23; loopCnt++ ) {
        if ( map_CS8420_RX_ERROR != loopCnt && map_CS8420_RESERVED_1F != loopCnt ) {					//	avoid hole in register address space
            err = CODEC_ReadRegister ( loopCnt, NULL, 1 );												//	read I2C register into cache only
            if ( kIOReturnSuccess != err && kIOReturnSuccess == result ) {
                result = err;
            }
        }
    }
    return result;
}
Exemplo n.º 5
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool	AppleTopazPluginCS8420::preDMAEngineInit ( void ) {
    bool			result = false;
    IOReturn		err;

    //	Place device into power down state prior to initialization
    err = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, kCS8420_CLOCK_SOURCE_CTRL_INIT_STOP );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_1, kCS8420_MISC_CNTRL_1_INIT );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_2, kCS8420_MISC_CNTRL_2_INIT );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, kCS8420_DATA_FLOW_CTRL_INIT );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_SERIAL_INPUT_FMT, kCS8420_SERIAL_AUDIO_INPUT_FORMAT_INIT );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_SERIAL_OUTPUT_FMT, kCS8420_SERIAL_AUDIO_OUTPUT_FORMAT_INIT );
    FailIf ( kIOReturnSuccess != err, Exit );

    //	Enable receiver error (i.e. RERR) interrupts
    err = CODEC_WriteRegister ( map_CS8420_RX_ERROR_MASK, kCS8420_RX_ERROR_MASK_ENABLE_RERR );
    FailIf ( kIOReturnSuccess != err, Exit );

    //	Clear any pending error interrupt
    err = CODEC_ReadRegister ( map_CS8420_RX_ERROR, NULL, 1 );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, kCS8420_CLOCK_SOURCE_CTRL_INIT );
    FailIf ( kIOReturnSuccess != err, Exit );

    err = CODEC_WriteRegister ( map_CS8420_USER_DATA_BUF_CTRL, bvCS8420_ubmBlock << baCS8420_UBM );
    FailIf ( kIOReturnSuccess != err, Exit );

    result = true;
Exit:
    return result;
}
/*******************************************************************************
* Function Name  : CODEC_WriteRegister
* Description    : Writes a value in a register of the audio Codec through I2C.
* Input          :  - RegisterAddr: The target register address (between 00x and 0x24)
*                :  - RegisterValue: The target register value to be written
*                :  - Verify: 0-> Don't verify the written data, 1-> Verify the written data
* Output         : None
* Return         : - 0  -> Correct write operation
*                : - !0 -> Incorrect write operation
*******************************************************************************/
uint32_t CODEC_WriteRegister(uint32_t RegisterAddr, uint32_t RegisterValue)
{
  uint32_t read_verif = 0;

  /* Reset all I2C2 registers */
  I2C_SoftwareResetCmd(I2C1, ENABLE);
  I2C_SoftwareResetCmd(I2C1, DISABLE);

  /* Enable the I2C1 peripheral  */
  I2C_Cmd(I2C1, ENABLE);

  /* Configure the I2C peripheral */
  I2C_Config();

  /* Begin the config sequence */
  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on EV5 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
  {}
  /* Transmit the slave address and enable writing operation */
  I2C_Send7bitAddress(I2C1, CODEC_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {}
  /* Transmit the first address for r/w operations */
  I2C_SendData(I2C1, RegisterAddr);

  /* Test on EV8 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {}
  /* Prepare the register value to be sent */
  I2C_SendData(I2C1, RegisterValue);

  /* Test on EV8 and clear it */
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  {}
  /* End the configuration sequence */
  I2C_GenerateSTOP(I2C1, ENABLE);

  /* Verify (if needed) that the loaded data is correct  */
#ifdef VERIFY_WRITTENDATA
  /* Read the just written register*/
  read_verif = CODEC_ReadRegister(RegisterAddr);

  /* Load the register and verify its value  */
  if (read_verif != RegisterValue)
  {
    /* Control data wrongly transferred */
    read_verif = 1;
  }
  else
  {
    /* Control data correctly transferred */
    read_verif = 0;
  }
#endif

  /* Return the verifying value: 0 (Passed) or 1 (Failed) */
  return read_verif;
}