u8 fgCompareRi(void) { u8 bTemp; u8 bHDCPBuf[4]; MT8193_HDCP_FUNC(); /* Read R0/ Ri from Transmitter */ /* fgI2CDataRead(HDMI_DEV_GRL, GRL_RI_0, HDCP_RI_COUNT, bHDCPBuf+HDCP_RI_COUNT); */ bReadDataHdmiGRL(GRL_RI_0, HDCP_RI_COUNT, &bHDCPBuf[HDCP_RI_COUNT]); /* Read R0'/ Ri' from Receiver */ fgDDCDataRead(RX_ID, RX_REG_RI, HDCP_RI_COUNT, bHDCPBuf); MT8193_HDCP_LOG("bHDCPBuf[0]=0x%x,bHDCPBuf[1]=0x%x,bHDCPBuf[2]=0x%x,bHDCPBuf[3]=0x%x\n", bHDCPBuf[0], bHDCPBuf[1], bHDCPBuf[2], bHDCPBuf[3]); /* compare R0 and R0' */ for (bTemp = 0; bTemp < HDCP_RI_COUNT; bTemp++) { if (bHDCPBuf[bTemp] == bHDCPBuf[bTemp + HDCP_RI_COUNT]) { continue; } else { break; } } if (bTemp == HDCP_RI_COUNT) { return TRUE; } else { return FALSE; } }
void vReadKSVFIFO(void) { u8 bTemp, bIndex, bDevice_Count; /* , bBlock; */ u8 bStatus[2], bBstatus1; MT8193_HDCP_FUNC(); fgDDCDataRead(RX_ID, RX_REG_BSTATUS1 + 1, 1, &bBstatus1); fgDDCDataRead(RX_ID, RX_REG_BSTATUS1, 1, &bDevice_Count); bDevice_Count &= DEVICE_COUNT_MASK; if ((bDevice_Count & MAX_DEVS_EXCEEDED) || (bBstatus1 & MAX_CASCADE_EXCEEDED)) { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); return; } if (bDevice_Count > 32) { for (bTemp = 0; bTemp < 2; bTemp++) /* retry 1 times */ { fgDDCDataRead(RX_ID, RX_REG_BSTATUS1, 1, &bDevice_Count); bDevice_Count &= DEVICE_COUNT_MASK; if (bDevice_Count <= 32) break; } if (bTemp == 2) { bDevice_Count = 32; } } vSetSharedInfo(SI_REPEATER_DEVICE_COUNT, bDevice_Count); if (bDevice_Count == 0) { for (bIndex = 0; bIndex < 5; bIndex++) bKsv_buff[bIndex] = 0; for (bIndex = 0; bIndex < 2; bIndex++) bStatus[bIndex] = 0; for (bIndex = 0; bIndex < 20; bIndex++) bSHABuff[bIndex] = 0; } else { fgDDCDataRead(RX_ID, RX_REG_KSV_FIFO, bDevice_Count * 5, bKsv_buff); } fgDDCDataRead(RX_ID, RX_REG_BSTATUS1, 2, bStatus); fgDDCDataRead(RX_ID, RX_REG_REPEATER_V, 20, bSHABuff); if ((bDevice_Count * 5) < KSV_BUFF_SIZE) vHalWriteKsvListPort(bKsv_buff, bDevice_Count, bStatus); vHalWriteHashPort(bSHABuff); vEnableHashHardwrae(); vSetHDCPState(HDCP_COMPARE_V); /* set time-out value as 0.5 sec */ vSetHDCPTimeOut(HDCP_WAIT_V_RDY_TIMEOUE); }
void vExchangeKSVs(void) { u8 bHDCPBuf[HDCP_AKSV_COUNT]; MT8193_HDCP_FUNC(); /* Step 1: read Aksv from transmitter, and send to receiver */ if (fgHostKey()) { fgDDCDataWrite(RX_ID, RX_REG_HDCP_AKSV, HDCP_AKSV_COUNT, HDMI_AKSV); } else { /* fgI2CDataRead(HDMI_DEV_GRL, GRL_RD_AKSV0, HDCP_AKSV_COUNT, bHDCPBuf); */ bReadDataHdmiGRL(GRL_RD_AKSV0, HDCP_AKSV_COUNT, bHDCPBuf); fgDDCDataWrite(RX_ID, RX_REG_HDCP_AKSV, HDCP_AKSV_COUNT, bHDCPBuf); } /* Step 4: read Bksv from receiver, and send to transmitter */ fgDDCDataRead(RX_ID, RX_REG_HDCP_BKSV, HDCP_BKSV_COUNT, bHDCPBuf); /* fgI2CDataWrite(HDMI_DEV_GRL, GRL_WR_BKSV0, HDCP_BKSV_COUNT, bHDCPBuf); */ vWriteDataHdmiGRL(GRL_WR_BKSV0, HDCP_BKSV_COUNT, bHDCPBuf); }
u8 fgCompareRi(void) { u8 bTemp; u8 bHDCPBuf[4]; MT8193_HDCP_FUNC(); // Read R0/ Ri from Transmitter //fgI2CDataRead(HDMI_DEV_GRL, GRL_RI_0, HDCP_RI_COUNT, bHDCPBuf+HDCP_RI_COUNT); bReadDataHdmiGRL(GRL_RI_0, HDCP_RI_COUNT, &bHDCPBuf[HDCP_RI_COUNT]); // Read R0'/ Ri' from Receiver fgDDCDataRead(RX_ID, RX_REG_RI, HDCP_RI_COUNT, bHDCPBuf); // compare R0 and R0' for(bTemp=0; bTemp<HDCP_RI_COUNT; bTemp++) { if(bHDCPBuf[bTemp] == bHDCPBuf[bTemp+HDCP_RI_COUNT]) { continue; } else { break; } } if(bTemp==HDCP_RI_COUNT) { return TRUE; } else { return FALSE; } }
void HdcpService(HDCP_CTRL_STATE_T e_hdcp_state) { u8 bIndx, bTemp; u8 bMask; MT8193_HDCP_FUNC(); if (_bHdcpOff == 1) { vSetHDCPState(HDCP_RECEIVER_NOT_READY); vHDMIAVUnMute(); vWriteHdmiIntMask(0xff); } switch (e_hdcp_state) { case HDCP_RECEIVER_NOT_READY: MT8193_HDCP_LOG("HDCP_RECEIVER_NOT_READY\n"); break; case HDCP_READ_EDID: break; case HDCP_WAIT_RES_CHG_OK: MT8193_HDCP_LOG("HDCP_WAIT_RES_CHG_OK\n"); _bReAUTHCount = 0; if (fgIsHDCPCtrlTimeOut()) { if (_bHdcpOff == 1) /* disable HDCP */ { vSetHDCPState(HDCP_RECEIVER_NOT_READY); vHDMIAVUnMute(); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } else { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } } break; case HDCP_INIT_AUTHENTICATION: MT8193_HDCP_LOG("HDCP_INIT_AUTHENTICATION\n"); _bReAUTHCount++; vHDMIAVMute(); vSetSharedInfo(SI_HDMI_HDCP_RESULT, 0); if (!fgDDCDataRead(RX_ID, RX_REG_BCAPS, 1, &bTemp)) { vSetHDCPTimeOut(HDCP_WAIT_300MS_TIMEOUT); break; } vMiAnUpdateOrFix(TRUE); if (fgHostKey()) { for (bIndx = 0; bIndx < HDCP_AKSV_COUNT; bIndx++) { HDMI_AKSV[bIndx] = bHdcpKeyBuff[1 + bIndx]; } if ((_bReAUTHCount > 2) || ((HDMI_AKSV[0] == 0) && (HDMI_AKSV[1] == 0) && (HDMI_AKSV[2] == 0) && (HDMI_AKSV[3] == 0))) { vSetHDCPState(HDCP_RECEIVER_NOT_READY); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); _bReAUTHCount = 0; return; } } else { vReadAksvFromReg(&HDMI_AKSV[0]); } if ((bhdcpkey == INTERNAL_ENCRYPT_KEY) || (bhdcpkey == EXTERNAL_KEY)) vWriteAksvKeyMask(&HDMI_AKSV[0]); vEnableAuthHardware(); fgDDCDataRead(RX_ID, RX_REG_BCAPS, 1, &bTemp); vSetSharedInfo(SI_REPEATER_DEVICE_COUNT, 0); if (bTemp & RX_BIT_ADDR_RPTR) { _fgRepeater = TRUE; } else { _fgRepeater = FALSE; } if (fgIsRepeater()) { vRepeaterOnOff(TRUE); } else { vRepeaterOnOff(FALSE); } vSendAn(); vExchangeKSVs(); if (fgHostKey()) { vSendAKey(&bHdcpKeyBuff[6]); /* around 190msec */ vSetHDCPTimeOut(HDCP_WAIT_R0_TIMEOUT); } else { vSetHDCPTimeOut(HDCP_WAIT_R0_TIMEOUT); /* 100 ms */ } /* change state as waiting R0 */ vSetHDCPState(HDCP_WAIT_R0); break; case HDCP_WAIT_R0: MT8193_HDCP_LOG("HDCP_WAIT_R0\n"); bTemp = bCheckHDCPStatus(HDCP_STA_RI_RDY); if (bTemp == TRUE) { vSetHDCPState(HDCP_COMPARE_R0); } else { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); break; } case HDCP_COMPARE_R0: MT8193_HDCP_LOG("HDCP_COMPARE_R0\n"); if (fgCompareRi() == TRUE) { vMiAnUpdateOrFix(FALSE); vEnableEncrpt(); /* Enabe encrption */ vSetCTL0BeZero(TRUE); /* change state as check repeater */ vSetHDCPState(HDCP_CHECK_REPEATER); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); vSetSharedInfo(SI_HDMI_HDCP_RESULT, 0x01); /* step 1 OK. */ } else { vSetHDCPState(HDCP_RE_COMPARE_R0); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); _bReCompRiCount = 0; } break; case HDCP_RE_COMPARE_R0: MT8193_HDCP_LOG("HDCP_RE_COMPARE_R0\n"); _bReCompRiCount++; if (fgIsHDCPCtrlTimeOut() && _bReCompRiCount > 3) { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); _bReCompRiCount = 0; } else { if (fgCompareRi() == TRUE) { vMiAnUpdateOrFix(FALSE); vEnableEncrpt(); /* Enabe encrption */ vSetCTL0BeZero(TRUE); /* change state as check repeater */ vSetHDCPState(HDCP_CHECK_REPEATER); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); vSetSharedInfo(SI_HDMI_HDCP_RESULT, 0x01); /* step 1 OK. */ } else { vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } } break; case HDCP_CHECK_REPEATER: MT8193_HDCP_LOG("HDCP_CHECK_REPEATER\n"); /* if the device is a Repeater, */ if (fgIsRepeater()) { _bReCheckReadyBit = 0; vSetHDCPState(HDCP_WAIT_KSV_LIST); vSetHDCPTimeOut(HDCP_WAIT_KSV_LIST_TIMEOUT); } else { vSetHDCPState(HDCP_WAIT_RI); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } break; case HDCP_WAIT_KSV_LIST: MT8193_HDCP_LOG("HDCP_WAIT_KSV_LIST\n"); fgDDCDataRead(RX_ID, RX_REG_BCAPS, 1, &bTemp); if ((bTemp & RX_BIT_ADDR_READY)) { _bReCheckReadyBit = 0; vSetHDCPState(HDCP_READ_KSV_LIST); } else if (_bReCheckReadyBit > HDCP_CHECK_KSV_LIST_RDY_RETRY_COUNT) { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); _bReCheckReadyBit = 0; break; } else { _bReCheckReadyBit++; vSetHDCPState(HDCP_WAIT_KSV_LIST); vSetHDCPTimeOut(HDCP_WAIT_KSV_LIST_RETRY_TIMEOUT); break; } case HDCP_READ_KSV_LIST: MT8193_HDCP_LOG("HDCP_READ_KSV_LIST\n"); vReadKSVFIFO(); break; case HDCP_COMPARE_V: MT8193_HDCP_LOG("HDCP_COMPARE_V\n"); bTemp = bReadHDCPStatus(); if ((bTemp & HDCP_STA_V_MATCH) || (bTemp & HDCP_STA_V_RDY)) { if ((bTemp & HDCP_STA_V_MATCH)) /* for Simplay #7-20-5 */ { vSetHDCPState(HDCP_WAIT_RI); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x02)); /* step 2 OK. */ } else { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } } break; case HDCP_WAIT_RI: MT8193_HDCP_LOG("HDCP_WAIT_RI\n"); vHDMIAVUnMute(); bMask = bReadHdmiIntMask(); vWriteHdmiIntMask(0xfd); break; case HDCP_CHECK_LINK_INTEGRITY: MT8193_HDCP_LOG("HDCP_CHECK_LINK_INTEGRITY\n"); if (fgCompareRi() == TRUE) { vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x04)); /* step 3 OK. */ if (fgIsRepeater()) { if (i4SharedInfo(SI_HDMI_HDCP_RESULT) == 0x07) /* step 1, 2, 3. */ { vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x08)); /* all ok. */ } } else /* not repeater, don't need step 2. */ { if (i4SharedInfo(SI_HDMI_HDCP_RESULT) == 0x05) /* step 1, 3. */ { vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x08)); /* all ok. */ } } } else { bMask = bReadHdmiIntMask(); vWriteHdmiIntMask(0xff); /* disable INT HDCP */ _bReCompRiCount = 0; vSetHDCPState(HDCP_RE_COMPARE_RI); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } break; case HDCP_RE_COMPARE_RI: MT8193_HDCP_LOG("HDCP_RE_COMPARE_RI\n"); _bReCompRiCount++; if (_bReCompRiCount > 5) { vSetHDCPState(HDCP_RE_DO_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); _bReCompRiCount = 0; } else { if (fgCompareRi() == TRUE) { _bReCompRiCount = 0; vSetHDCPState(HDCP_CHECK_LINK_INTEGRITY); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x04)); /* step 3 OK. */ if (fgIsRepeater()) { if (i4SharedInfo(SI_HDMI_HDCP_RESULT) == 0x07) /* step 1, 2, 3. */ { vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x08)); /* all ok. */ } } else { if (i4SharedInfo(SI_HDMI_HDCP_RESULT) == 0x05) /* step 1, 3. */ { vSetSharedInfo(SI_HDMI_HDCP_RESULT, (i4SharedInfo(SI_HDMI_HDCP_RESULT) | 0x08)); /* all ok. */ } } bMask = bReadHdmiIntMask(); vWriteHdmiIntMask(0xfd); } else { vSetHDCPState(HDCP_RE_COMPARE_RI); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } } break; case HDCP_RE_DO_AUTHENTICATION: MT8193_HDCP_LOG("HDCP_RE_DO_AUTHENTICATION\n"); vHDMIAVMute(); vHDCPReset(); if (i4SharedInfo(SI_HDMI_RECEIVER_STATUS) != HDMI_PLUG_IN_AND_SINK_POWER_ON) { vSetHDCPState(HDCP_RECEIVER_NOT_READY); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } else { vSetHDCPState(HDCP_WAIT_RESET_OK); vSetHDCPTimeOut(HDCP_WAIT_RE_DO_AUTHENTICATION); } break; case HDCP_WAIT_RESET_OK: MT8193_HDCP_LOG("HDCP_WAIT_RESET_OK\n"); if (fgIsHDCPCtrlTimeOut()) { vSetHDCPState(HDCP_INIT_AUTHENTICATION); vSendHdmiCmd(HDMI_HDCP_PROTOCAL_CMD); } break; default: break; } }