Beispiel #1
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferWriteData -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// This function adds data to the current ping/pong buffer. If the buffer is full,
// an error is returned
//
DtStatus  DtaPPBufferWriteData(
    UInt8*  pSourceBuffer,
    PPBuffer*  pPPBuffer,
    UInt  DataSize)
{
    UInt8*  pDst = NULL;
    UInt  PPBufferIndex = pPPBuffer->m_CurRwBufferId;
    DT_ASSERT(pPPBuffer->m_pDmaChannel->m_DmaDirection == DT_DMA_DIRECTION_TO_DEVICE);
    DT_ASSERT(!DtaPPBufferIsFull(pPPBuffer, PPBufferIndex));
    
    // Check if we do not exceed the size of the available buffer space
    // If so, we have an overflow situation!
    if (pPPBuffer->m_BufTransferSize[PPBufferIndex]+DataSize >
                                                      pPPBuffer->m_BufSize[PPBufferIndex])
        return DT_STATUS_BUFFER_OVERFLOW;

    // Calculate current location of the destiny for ping or pong buffer
    pDst = pPPBuffer->m_pBufStart + pPPBuffer->m_BufOffset[PPBufferIndex] +
                                              pPPBuffer->m_BufTransferSize[PPBufferIndex];

    DtMemCopy(pDst, pSourceBuffer, DataSize);
    pPPBuffer->m_BufTransferSize[PPBufferIndex] += DataSize;

    return DT_STATUS_OK;
}
Beispiel #2
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtWorkItemCopy -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
static DtStatus  DtWorkItemStructCopy(
    DtWorkItemStruct*  pWorkItemStructDst, 
    DtWorkItemStruct*  pWorkItemStructSrc)
{
    DtMemCopy(pWorkItemStructDst, pWorkItemStructSrc, sizeof(DtWorkItemStruct));
    return DT_STATUS_OK;
}
Beispiel #3
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaHdmiControllerThread -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
void  DtaHdmiControllerThread(DtThread* pThread, void* pContext)
{
    DtStatus  Status = DT_STATUS_OK;
    DtaNonIpPort* pNonIpPort = (DtaNonIpPort*)pContext;
    DtaHdmi*  pHdmi = &pNonIpPort->m_HdmiRx;
    Bool  ConfigForHd = TRUE;

    DtDbgOut(MAX, HDMI, "Thread begin");
    
    DtaFwbRegWrite(pNonIpPort->m_pFwbRegs, &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 1);
    DtSleep(5);
    DtaFwbRegWrite(pNonIpPort->m_pFwbRegs, &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 0);
    DtSleep(10);
    
    // Disable VGA framing
    DtaFwbRegWrite(pNonIpPort->m_pFwbRegs,
                &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_VgaFraming, DTFWB_HDMI_NO_FRAMING);

    //  Disable powerdown bit
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_0C, 0x42);
    
    DtSleep(10);

    if (Status != DT_STATUS_OK)
    {
        DtDbgOut(ERR, HDMI, "Failed to disable powerdown bit: 0x%X", Status);
        DtaFwbRegWrite(pNonIpPort->m_pFwbRegs,
                                         &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 1);
        DtThreadWaitForStop(pThread);
        return;
    }

    // Initialize I2C addresses of other register pages
    
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, CEC_SLAVE_ADDRESS, ADV7610_I2CADDR_CEC);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, INFOFRAME_SLAVE_ADDRESS, ADV7610_I2CADDR_INFOFRAME);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, KSV_SLAVE_ADDRESS, ADV7610_I2CADDR_KSV);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, EDID_SLAVE_ADDRESS, ADV7610_I2CADDR_EDID);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_SLAVE_ADDRESS, ADV7610_I2CADDR_HDMI);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, CP_SLAVE_ADDRESS, ADV7610_I2CADDR_CP);

    if (Status != DT_STATUS_OK)
        DtDbgOut(ERR, HDMI, "Failed to set slave I2C addresses: 0x%X", Status);

    // Setting clock frequency to 27Mhz and pixel bus to mode 2
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_04, 0x60);
    // color space settings
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_02, 0xF4);
    // set IO_REG_05
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_05, 0x2C);
    // enabling output
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_15, 0xA8);
    // disable free run mode
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(CP, HDMI_CP_CNTRL_1, 0x00);
    // disable cable detect reset
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, REGISTER_48, 0x40);
    // enable termination automatic control
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, REGISTER_01, 0x01);
    // enable clock termination on port a
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, REGISTER_02, 0xFE);
    // enable dynamic eq control
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, EQ_DYNAMIC_ENABLE, 0x01);
    // Set bit width for right justified mode on I2S interface
    //if (Status == DT_STATUS_OK)
    //    Status = ADV7610_WRITE_REG(HDMI, REGISTER_03, 0x10);
    // Disable "mute if compressed audio is detected" bit
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, MUTE_MASK21_16, 0x1F);
    
    if (Status != DT_STATUS_OK)
        DtDbgOut(ERR, HDMI, "Failed to initialize general registers");

    // Write EDID data
    if (Status == DT_STATUS_OK)
    {
        Int  i;
        UInt8  Sum = 0;
        UInt8  Edid[257];
        UInt32  Serial;
        Edid[0] = 0; // Address byte
        DtMemCopy(Edid+1, EDID_Block, sizeof(EDID_Block));
        Serial = (UInt32)pNonIpPort->m_pDvcData->m_DevInfo.m_Serial;
        DtMemCopy(Edid+1+0x0C, &Serial, sizeof(Serial));
        for (i=0; i<127; i++)
            Sum += Edid[i+1];
        Edid[0x80] = (255 - Sum + 1);
        Status = DtaI2cmWrite(&pHdmi->m_I2c, ADV7610_I2CADDR_EDID, sizeof(Edid), Edid);
    }

    if (Status != DT_STATUS_OK)
        DtDbgOut(ERR, HDMI, "Write EDID failure");

    // enable EDID for port a
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(KSV, HDCP_EDID_CONTROLS, 0x01);

    if (Status == DT_STATUS_OK)
        Status = DtaHdmiConfigForHd(pHdmi);
    ConfigForHd = TRUE;
    
    // Set interrupt signal duration to '11': Active until cleared
    // Set signal configuration '10': drives high when active
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, INT1_CONFIGURATION, 0xE2);
    
    // Enable cable detect / encrypted signal interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_MASKB4, 0x05);
    // Enable Video clock changed, Audio mode changed, new sample rate,
    // TMDS freq changed interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_EDG_INT_MASKB3, 0x6A);
    // Enable TMDS-PLL locked, TMDS clock detect, Vertical sync lock, DE regeneration
    // lock interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_MASKB3, 0x53);
    // Enable NEW_AVI_INFO and NEW_AUDIO_INFO interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_MASKB1, 0x03);

    if (Status != DT_STATUS_OK)
    {
        DtDbgOut(ERR, HDMI, "HDMI initialization failed.");
        DtaFwbRegWrite(pNonIpPort->m_pFwbRegs,
                                         &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 1);
        DtThreadWaitForStop(pThread);
        return;
    }

    DtDbgOut(AVG, HDMI, "HDMI initialization complete");

    while (!pThread->m_StopThread)
    {
        UInt8  Value;
        DtaHdmiStatus  NewStatus;
        Int  NewVidStd = DT_VIDSTD_UNKNOWN;

        DtaHdmiClearStatus(&NewStatus);

        // Read/clear cable detect / encrypted signal interrupts
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_INT_STATUS4, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_CLR4, Value&0x05);
        
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_RAW_STATUS4, &Value);
        if (Status == DT_STATUS_OK)
        {
            NewStatus.m_CableDet = (Value&0x01)!=0;
            NewStatus.m_Encrypted = (Value&0x04)!=0;
        }
        
        // Read/clear TMDS-PLL locked, TMDS clock detect, Vertical sync lock, 
        // DE regeneration lock interrupts
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_INT_STATUS3, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_CLR3, Value);

        // Read/clear TMDS freq changed interrupt
        Status = ADV7610_READ_REG(GENERAL, HDMI_EDG_STATUS3, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_EDG_INT_CLR3, Value);
        if (NewStatus.m_CableDet)
        {
            Status = ADV7610_READ_REG(HDMI, REGISTER_04, &Value);
            NewStatus.m_TmdsPllLocked = (Value&0x02)!=0;
            NewStatus.m_AudioLocked = (Value&0x01)!=0;
        }

        // Read/clear new audio info interrupt
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_INT_STATUS1, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_CLR1, Value);

        if (NewStatus.m_TmdsPllLocked)
        {
            Status = ADV7610_READ_REG(HDMI, HDMI_COLORSPACE, &Value);
            NewStatus.m_InpColorspace = Value&0x0F;
            
            Status = ADV7610_READ_REG(HDMI, REGISTER_05, &Value);
            NewStatus.m_PixelRepetition = Value&0x0F;
            
            Status = ADV7610_READ_REG(HDMI, LINE_WIDTH1, &Value);
            NewStatus.m_VertFilterLocked = (Value&0x80)!=0;
            NewStatus.m_DeRegenFilterLocked = (Value&0x20)!=0;
            NewStatus.m_VidWidth = (Value&0x01F)<<8;
            Status = ADV7610_READ_REG(HDMI, LINE_WIDTH2, &Value);
            NewStatus.m_VidWidth |= Value;
            
            Status = ADV7610_READ_REG(HDMI, FIELD0_HEIGHT1, &Value);
            NewStatus.m_VidHeight1 = (Value&0x01F)<<8;
            Status = ADV7610_READ_REG(HDMI, FIELD0_HEIGHT2, &Value);
            NewStatus.m_VidHeight1 |= Value;
            
            Status = ADV7610_READ_REG(HDMI, REGISTER_51, &Value);
            NewStatus.m_TmdsFreq = Value<<8;
            Status = ADV7610_READ_REG(HDMI, REGISTER_52, &Value);
            NewStatus.m_TmdsFreq |= Value;
            
            Status = ADV7610_READ_REG(HDMI, FIELD1_HEIGHT1, &Value);
            switch (Value>>6)
            {
            case 0: NewStatus.m_BitsPerChannel = 8; break;
            case 1: NewStatus.m_BitsPerChannel = 10; break;
            case 2: NewStatus.m_BitsPerChannel = 12; break;
            case 3: NewStatus.m_BitsPerChannel = 16; break;
            }
            NewStatus.m_Interlaced = (Value&0x20)!=0;
            NewStatus.m_VidHeight2 = (Value&0x01F)<<8;
            Status = ADV7610_READ_REG(HDMI, FIELD1_HEIGHT2, &Value);
            NewStatus.m_VidHeight2 |= Value;
            
            Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_RAW_STATUS2, &Value);
            NewStatus.m_AudioChanStatusValid = (Value&0x80)!=0;
            if (NewStatus.m_AudioChanStatusValid)
            {
                UInt8  RegAddr = ADV7610_HDMI_CHANNEL_STATUS_DATA_1;
                DtaI2cmWriteRead(&pHdmi->m_I2c, ADV7610_I2CADDR_HDMI, 1, &RegAddr,
                                                   sizeof(NewStatus.m_AudioChannelStatus),
                                                   NewStatus.m_AudioChannelStatus);
            }
        }

        if (NewStatus.m_AudioLocked)
        {
            Status = ADV7610_READ_REG(HDMI, LINE_WIDTH1, &Value);
            NewStatus.m_AudioChannelMode = (Value>>6)&1;
            Status = ADV7610_READ_REG(HDMI, PACKETS_DETECTED_2, &Value);
            if ((Value&0x01) != 0)
                NewStatus.m_AudioType = 0;
            else if ((Value&0x02) != 0)
                NewStatus.m_AudioType = 1;
            else if ((Value&0x04) != 0)
                NewStatus.m_AudioType = 2;
            else if ((Value&0x08) != 0)
                NewStatus.m_AudioType = 3;
        }
Beispiel #4
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtTableGet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  DtTableGet(
    DtPropertyData*  pPropData,
    const char*  pTableName,
    Int  PortIndex,
    UInt  MaxNumEntries,
    UInt*  pNumEntries,
    DtTableEntry*  pTableEntry2,
    UInt OutBufSize)
{
    DtStatus  Status = DT_STATUS_OK;
    const DtTableStore*  pStore = (DtTableStore*)pPropData->m_pTableStore;
    Int  HwRevision = pPropData->m_HardwareRevision;
    Int  FwVariant = pPropData->m_FirmwareVariant;

    Bool  TableNameFound = FALSE;
    Int  FindCount = 0;
    UInt  Index;
    DtTableLink*  pTableLinkFound = NULL;

    // For devices with no 'EC' VPD resource and no registry key which forces the
    // hardware revision, treat the hardware revision as 0
    if (HwRevision < 0)
        HwRevision = 0;
    
    *pNumEntries = 0;
    if (pPropData->m_pTableStore == NULL)
    {
        DtDbgOut(ERR, TABLE, "There are no tables defined at all for DTX-%d", 
                                                                 pPropData->m_TypeNumber);
        return DT_STATUS_NOT_FOUND;
    }

    // If the property is not found for a specific fw-variant try a second time
    // without specifying a specific fw-variant
    for (FindCount=0; FindCount<2 && pTableLinkFound==NULL; FindCount++)
    {
        if (FindCount == 1)
            FwVariant = -1;

        TableNameFound = FALSE;

        // Search all tables
        for (Index=0; Index<pStore->m_TableLinkCount; Index++)
        {
            const DtTableLink*  pTableLink = &pStore->m_pTableLink[Index];

            // Check if the table name was already found. If so, we stop if
            // name <> NULL.
            if (TableNameFound)
            {
                // When the table name was found earlier, only accept entries without
                // a name. We just stop when (another) named entry is found.
                if (pTableLink->m_pName != NULL)
                    break;
            } else {
                // Compare name to check if we found the first occurrence
                if (DtAnsiCharArrayIsEqual(pTableName, pTableLink->m_pName))
                    TableNameFound = TRUE;
            }

            if (TableNameFound)
            {
                // Check port number and firmware variant
                if (PortIndex==pTableLink->m_PortIndex
                                                    && FwVariant==pTableLink->m_FwVariant)
                {
                    // Check minimal firmware version
                    if (pPropData->m_FirmwareVersion >= pTableLink->m_MinFw)
                    {
                        // Check minimal hardware version
                        if (HwRevision >= pTableLink->m_MinHw)
                        {
                            pTableLinkFound = (DtTableLink*)pTableLink;

                            // We can stop here since the parser has ordened each
                            // property by minimal firmware version/hardware version.
                            // This means the first hit is the best one
                            break;
                        }
                    }
                }
            }
        }
    }

    if (!TableNameFound)
    {   
        DtDbgOut(ERR, TABLE, "Table %s is not found at all for DTX-%d",
                                                        pTableName, pStore->m_TypeNumber);
        Status = DT_STATUS_NOT_FOUND;
    }
        
    // Check if the table was found
    if (pTableLinkFound == NULL)
    {
        Status = DT_STATUS_NOT_FOUND;
        DtDbgOut(ERR, TABLE, "Failed to get table %s for DTX-%d:%d, FW %d, HW %d port %i", 
                                                  pTableName,
                                                  pPropData->m_TypeNumber,
                                                  pPropData->m_SubDvc,
                                                  pPropData->m_FirmwareVersion,
                                                  pPropData->m_HardwareRevision,
                                                  PortIndex);
    }
    
    if (DT_SUCCESS(Status) && pTableLinkFound!=NULL)
    {
        DtDbgOut(MAX, TABLE, "Found table %s for DTX-%d:%d, FW %d, HW %d. #EL:%i #MAX:%i" ,
                                                  pTableName,
                                                  pPropData->m_TypeNumber,
                                                  pPropData->m_SubDvc,
                                                  pPropData->m_FirmwareVersion,
                                                  pPropData->m_HardwareRevision,
                                                  pTableLinkFound->m_TableEntryCount,
                                                  MaxNumEntries);
        *pNumEntries =  pTableLinkFound->m_TableEntryCount;
        
        // Check if enough space for the table
        if (MaxNumEntries < pTableLinkFound->m_TableEntryCount)
        {
            if (MaxNumEntries != 0)
                DtDbgOut(ERR, TABLE, "Max. number of entries to small. Needed:%i, "
                       "Space for:%i", pTableLinkFound->m_TableEntryCount, MaxNumEntries);
        }
        else if (OutBufSize < pTableLinkFound->m_TableEntryCount * sizeof(DtTableEntry)) {
            DtDbgOut(ERR, TABLE, "Buffer smaller than indicated by MaxNumEntries");
            Status = DT_STATUS_INVALID_PARAMETER;
        } else {
            // Copy table
            DtMemCopy(pTableEntry2, (void*)pTableLinkFound->m_pTableEntries, 
                             pTableLinkFound->m_TableEntryCount * sizeof(DtTableEntry));
        }
    } 
    return Status;
}