/** \brief This function creates a task and allocates all the necessary resources. Note that creating a task do not start it automatically, an explicit call to IWTaskStart must be made. \param pFunc Pointer to the function that will be executed in the task context. \param Priority Priority of the task. The minimum priority is 0, the maximum is 255. \param StackSize Size of the stack to allocate for this task. \param pHandle Pointer to the handle buffer. \return The call result: - TM_OK: the call was successful - TMDL_ERR_DLHDMICEC_NO_RESOURCES: the resource is not available - TMDL_ERR_DLHDMICEC_INCONSISTENT_PARAMS: an input parameter is inconsistent ******************************************************************************/ tmErrorCode_t tmdlHdmiTxIWTaskCreate ( tmdlHdmiTxIWFuncPtr_t pFunc, UInt8 priority, UInt16 stackSize, tmdlHdmiTxIWTaskHandle_t *pHandle ) { UInt32 i; /* check that input pointer is not NULL */ RETIF(pFunc == Null, TMDL_ERR_DLHDMICEC_INCONSISTENT_PARAMS) /* check that input pointer is not NULL */ RETIF(pHandle == Null, TMDL_ERR_DLHDMICEC_INCONSISTENT_PARAMS) /* search for available task slot */ for(i = 0; i < MAX_TASKS; i++) { if (taskTable[i].created == False) break; } RETIF(i >= MAX_TASKS, TMDL_ERR_DLHDMICEC_NO_RESOURCES) /* store task parameters into the dedicated structure */ taskTable[i].priority = priority; taskTable[i].stackSize = stackSize; taskTable[i].associatedTask = pFunc; taskTable[i].created = True; *pHandle = (tmdlHdmiTxIWTaskHandle_t)i; return(TM_OK); }
/*============================================================================*/ tmErrorCode_t checkUnitSetDis ( tmUnitSelect_t txUnit, tmHdmiTxobject_t **ppDis ) { /* Return error if unit numbr is out of range */ RETIF(txUnit < tmUnit0, TMBSL_ERR_HDMI_BAD_UNIT_NUMBER) // printk(KERN_INFO "[hycho00] -- 1\n"); RETIF(txUnit >= HDMITX_UNITS_MAX, TMBSL_ERR_HDMI_BAD_UNIT_NUMBER) // printk(KERN_INFO "[hycho00] -- 2\n"); /* Point to unit's Device Instance Structure */ *ppDis = &gHdmiTxInstance[txUnit]; /* Return if this device instance is not initialised */ if(!(*ppDis)->bInitialized) { printk(KERN_ERR "[HDMI] TMBSL_ERR_HDMI_NOT_INITIALIZED %s %d\n",__func__,__LINE__); return TMBSL_ERR_HDMI_NOT_INITIALIZED; } // printk(KERN_INFO "[hycho00] -- 3\n"); return TM_OK; }
tmErrorCode_t tmdlHdmiTxIWSemaphoreCreate(tmdlHdmiTxIWSemHandle_t *pHandle) { static int i = 0; struct semaphore * mutex[3]; // check that input pointer is not NULL RETIF(pHandle == Null, TMDL_ERR_DLHDMITX_INCONSISTENT_PARAMS) mutex[0] = &mutex0; mutex[1] = &mutex1; mutex[2] = &mutex2; if (i > 2 || i < 0) { printk("%s,create semphore error\n", __func__); return -1; } *pHandle = (tmdlHdmiTxIWSemHandle_t)mutex[i]; i++; RETIF(pHandle == NULL, TMDL_ERR_DLHDMITX_NO_RESOURCES) return(TM_OK); }
/*============================================================================*/ tmErrorCode_t setHwRegisters ( tmHdmiTxobject_t *pDis, UInt16 regShadPageAddr, UInt8 *pData, UInt16 lenData ) { tmErrorCode_t err; /* Error code */ UInt8 regShad; /* The index to the register's shadow copy */ UInt8 regPage; /* The index to the register's page */ UInt8 regAddr; /* The register's address on the page */ UInt8 newRegPage; /* The register's new page number */ tmbslHdmiTxSysArgs_t sysArgs; /* Arguments passed to system function */ /* Unpack 1st register's shadow index, page index and address */ regShad = SPA2SHAD(regShadPageAddr); regPage = SPA2PAGE(regShadPageAddr); regAddr = SPA2ADDR(regShadPageAddr); newRegPage = kPageIndexToPage[regPage]; /* Check length does not overflow page */ RETIF_BADPARAM((regAddr+lenData) > E_REG_CURPAGE_ADR_W) /* Check 1st reg does not have a shadow - whole range assumed likewise */ RETIF_BADPARAM(regShad != E_SNONE) /* Set page register if required - whole range is on same page */ if (pDis->curRegPage != newRegPage) { /* All non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = E_REG_CURPAGE_ADR_W; sysArgs.lenData = 1; sysArgs.pData = &newRegPage; err = pDis->sysFuncWrite(&sysArgs); RETIF(err != TM_OK, TMBSL_ERR_HDMI_I2C_WRITE) pDis->curRegPage = newRegPage; } /* Write to I2C register range - all non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = regAddr; sysArgs.lenData = (UInt8)lenData; sysArgs.pData = pData; err = pDis->sysFuncWrite(&sysArgs); if (err == TM_OK) { return TM_OK; } else { printk(KERN_ERR "[HDMI] TMBSL_ERR_HDMI_I2C_WRITE %s %d\n",__func__,__LINE__); return TMBSL_ERR_HDMI_I2C_WRITE; } }
/*============================================================================*/ tmErrorCode_t setHwRegister ( tmHdmiTxobject_t *pDis, UInt16 regShadPageAddr, UInt8 regValue ) { tmErrorCode_t err; /* Error code */ UInt8 regShad; /* The index to the register's shadow copy */ UInt8 regPage; /* The index to the register's page */ UInt8 regAddr; /* The register's address on the page */ UInt8 newRegPage; /* The register's new page number */ tmbslHdmiTxSysArgs_t sysArgs; /* Arguments passed to system function */ /* Unpack register shadow index, page index and address */ regShad = SPA2SHAD(regShadPageAddr); regPage = SPA2PAGE(regShadPageAddr); regAddr = SPA2ADDR(regShadPageAddr); newRegPage = kPageIndexToPage[regPage]; /* Set page register if required */ if (pDis->curRegPage != newRegPage) { /* All non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = E_REG_CURPAGE_ADR_W; sysArgs.lenData = 1; sysArgs.pData = &newRegPage; err = pDis->sysFuncWrite(&sysArgs); RETIF(err != TM_OK, TMBSL_ERR_HDMI_I2C_WRITE) pDis->curRegPage = newRegPage; } /* Set shadow copy */ if (regShad != E_SNONE) { pDis->shadowReg[regShad] = regValue; } /* Write to I2C - all non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = regAddr; sysArgs.lenData = 1; sysArgs.pData = ®Value; err = pDis->sysFuncWrite(&sysArgs); if (err == TM_OK) { return TM_OK; } else { printk(KERN_ERR "[HDMI] TMBSL_ERR_HDMI_I2C_WRITE %s %d\n",__func__,__LINE__); return TMBSL_ERR_HDMI_I2C_WRITE; } }
/*============================================================================*/ tmErrorCode_t setHwRegisterMsbLsb ( tmHdmiTxobject_t *pDis, UInt16 regShadPageAddr, UInt16 regWord ) { tmErrorCode_t err; /* Error code */ UInt8 regPage; /* The index to the register's page */ UInt8 regAddr; /* The register's address on the page */ UInt8 newRegPage; /* The register's new page number */ UInt8 msbLsb[2]; /* The bytes from regWord */ tmbslHdmiTxSysArgs_t sysArgs; /* Arguments passed to system function */ /* Unpack register shadow index, page index and address */ regPage = SPA2PAGE(regShadPageAddr); regAddr = SPA2ADDR(regShadPageAddr); newRegPage = kPageIndexToPage[regPage]; /* Unpack regWord bytes, MSB first */ msbLsb[0] = (UInt8)(regWord >> 8); msbLsb[1] = (UInt8)(regWord & 0xFF); /* Set page register if required */ if (pDis->curRegPage != newRegPage) { /* All non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = E_REG_CURPAGE_ADR_W; sysArgs.lenData = 1; sysArgs.pData = &newRegPage; err = pDis->sysFuncWrite(&sysArgs); RETIF(err != TM_OK, TMBSL_ERR_HDMI_I2C_WRITE) pDis->curRegPage = newRegPage; } /* No word registers are shadowed */ /* Write to I2C - all non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = regAddr; sysArgs.lenData = 2; sysArgs.pData = &msbLsb[0]; err = pDis->sysFuncWrite(&sysArgs); if (err == TM_OK) { return TM_OK; } else { printk(KERN_ERR "[HDMI] TMBSL_ERR_HDMI_I2C_WRITE %s %d\n",__func__,__LINE__); return TMBSL_ERR_HDMI_I2C_WRITE; } }
/*============================================================================*/ tmErrorCode_t getHwRegister ( tmHdmiTxobject_t *pDis, UInt16 regShadPageAddr, UInt8 *pRegValue ) { tmErrorCode_t err; /* Error code */ UInt8 regShad; /* The index to the register's shadow copy */ UInt8 regPage; /* The index to the register's page */ UInt8 regAddr; /* The register's address on the page */ UInt8 newRegPage; /* The register's new page number */ tmbslHdmiTxSysArgs_t sysArgs; /* Arguments passed to system function */ /* Unpack register shadow index, page index and address */ regShad = SPA2SHAD(regShadPageAddr); regPage = SPA2PAGE(regShadPageAddr); regAddr = SPA2ADDR(regShadPageAddr); newRegPage = kPageIndexToPage[regPage]; /* Set page register if required */ if (pDis->curRegPage != newRegPage) { /* All non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = E_REG_CURPAGE_ADR_W; sysArgs.lenData = 1; sysArgs.pData = &newRegPage; err = pDis->sysFuncWrite(&sysArgs); RETIF(err != TM_OK, TMBSL_ERR_HDMI_I2C_WRITE) pDis->curRegPage = newRegPage; } if ((regShad != E_SNONE) && (regShadPageAddr != E_REG_P00_INT_FLAGS_0_RW) && (regShadPageAddr != E_REG_P00_INT_FLAGS_1_RW) && (regShadPageAddr != E_REG_P00_INT_FLAGS_2_RW)) { /* Get shadow copy - shadowed registers can't be read */ /* Don't read shadow copy of interrupt status flags! */ *pRegValue = pDis->shadowReg[regShad]; return TM_OK; } else { /* Get I2C register - all non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = regAddr; sysArgs.lenData = 1; sysArgs.pData = pRegValue; err = pDis->sysFuncRead(&sysArgs); return (err == TM_OK) ? TM_OK : TMBSL_ERR_HDMI_I2C_READ; } }
/*============================================================================*/ tmErrorCode_t tmbslTDA9989EdidGetAudioCapabilities (tmUnitSelect_t txUnit, tmbslHdmiTxEdidSad_t *pEdidAFmts, UInt aFmtLength, UInt *pAFmtsAvail, UInt8 *pAudioFlags) { tmHdmiTxobject_t *pDis; /* Pointer to Device Instance Structure */ tmErrorCode_t err; /* Error code */ UInt i; /* Loop index */ /* Check unit parameter and point to TX unit object */ err = checkUnitSetDis(txUnit, &pDis); RETIF(err != TM_OK, err) /* Check remaining parameter(s) */ RETIF_BADPARAM(pEdidAFmts == Null) RETIF_BADPARAM(aFmtLength < 1) RETIF_BADPARAM(pAFmtsAvail == Null) RETIF_BADPARAM(pAudioFlags == Null) if ((pDis->EdidStatus == HDMITX_EDID_READ) || (pDis->EdidStatus == HDMITX_EDID_ERROR_CHK)) { /* allow if edid are read or if there are a chk error on an other block than block 0 */ /* Copy the Device Instance Structure EdidAFmts descriptors to * pEdidAFmts until we run out or no more space in structure. */ if (pDis->EdidSadCnt > 0) { for (i = 0; (i < (UInt) pDis->EdidSadCnt) && (i < aFmtLength); i++) { pEdidAFmts[i].ModeChans = pDis->EdidAFmts[i].ModeChans; pEdidAFmts[i].Freqs = pDis->EdidAFmts[i].Freqs; pEdidAFmts[i].Byte3 = pDis->EdidAFmts[i].Byte3; } } else { /* No pEdidAFmts to copy so set a zero format to be safe */ pEdidAFmts[0].ModeChans = 0; pEdidAFmts[0].Freqs = 0; pEdidAFmts[0].Byte3 = 0; } /* Fill Audio Flags parameter */ *pAudioFlags = ((pDis->EdidCeaFlags & 0x40) << 1); /* Basic audio */ if (pDis->EdidSinkAi == True) { *pAudioFlags += 0x40; /* Mask in AI support */ } /* Fill number of SADs available parameter */ *pAFmtsAvail = pDis->EdidSadCnt; } else { /* Not allowed if EdidStatus value is not valid */ err = TMBSL_ERR_HDMI_RESOURCE_NOT_AVAILABLE; } return err; }
/*============================================================================*/ tmErrorCode_t checkUnitSetDis ( tmUnitSelect_t txUnit, tmHdmiTxobject_t **ppDis ) { /* Return error if unit numbr is out of range */ RETIF(txUnit < tmUnit0, TMBSL_ERR_HDMI_BAD_UNIT_NUMBER) RETIF(txUnit >= HDMITX_UNITS_MAX, TMBSL_ERR_HDMI_BAD_UNIT_NUMBER) /* Point to unit's Device Instance Structure */ *ppDis = &gHdmiTxInstance[txUnit]; /* Return if this device instance is not initialised */ if(!(*ppDis)->bInitialized) { return TMBSL_ERR_HDMI_NOT_INITIALIZED; } return TM_OK; }
/****************************************************************************** \brief This function destroys an existing semaphore. \param Handle Handle of the semaphore to be destroyed. \return The call result: - TM_OK: the call was successful - TMDL_ERR_DLHDMITX_BAD_HANDLE: the handle number is wrong ******************************************************************************/ tmErrorCode_t tmdlHdmiTxIWSemaphoreDestroy ( tmdlHdmiTxIWSemHandle_t handle ) { RETIF(handle == False, TMDL_ERR_DLHDMITX_BAD_HANDLE); if (atomic_read((atomic_t*)&((struct semaphore *)handle)->count) < 1) { printk(KERN_ERR "release catched semaphore"); } kfree((void*)handle); return(TM_OK); }
/*============================================================================*/ tmErrorCode_t tmbslTDA9989EdidGetStatus(tmUnitSelect_t txUnit, UInt8 *puEdidStatus) { tmHdmiTxobject_t *pDis; /* Pointer to Device Instance Structure */ tmErrorCode_t err; /* Error code */ /* Check unit parameter and point to TX unit object */ err = checkUnitSetDis(txUnit, &pDis); RETIF(err != TM_OK, err) /* Check remaining parameter(s) */ RETIF_BADPARAM(puEdidStatus == Null) if (puEdidStatus) { *puEdidStatus = pDis->EdidStatus; } return err; }
/*============================================================================*/ tmErrorCode_t tmbslTDA9989EdidGetBlockCount(tmUnitSelect_t txUnit, UInt8 *puEdidBlockCount) { tmHdmiTxobject_t *pDis; /* Pointer to Device Instance Structure */ tmErrorCode_t err; /* Error code */ /* Check unit parameter and point to TX unit object */ err = checkUnitSetDis(txUnit, &pDis); RETIF(err != TM_OK, err) /* Check remaining parameter(s) */ RETIF_BADPARAM(puEdidBlockCount == Null) if ((pDis->EdidStatus == HDMITX_EDID_READ) || (pDis->EdidStatus == HDMITX_EDID_ERROR_CHK)) { /* allow if edid are read or if there are a chk error on an other block than block 0 */ *puEdidBlockCount = pDis->EdidBlockCnt; } else { /* Not allowed if EdidStatus value is not valid */ err = TMBSL_ERR_HDMI_RESOURCE_NOT_AVAILABLE; } return err; }
/****************************************************************************** \brief This function creates a semaphore. \param pHandle Pointer to the handle buffer. \return The call result: - TM_OK: the call was successful - TMDL_ERR_DLHDMITX_NO_RESOURCES: the resource is not available - TMDL_ERR_DLHDMITX_INCONSISTENT_PARAMS: an input parameter is inconsistent ******************************************************************************/ tmErrorCode_t tmdlHdmiTxIWSemaphoreCreate ( tmdlHdmiTxIWSemHandle_t *pHandle ) { struct semaphore * mutex; /* check that input pointer is not NULL */ RETIF(pHandle == Null, TMDL_ERR_DLHDMITX_INCONSISTENT_PARAMS) mutex = (struct semaphore *)kmalloc(sizeof(struct semaphore),GFP_KERNEL); if (!mutex) { printk(KERN_ERR "malloc failed in %s\n",__func__); return TMDL_ERR_DLHDMITX_NO_RESOURCES; } init_MUTEX(mutex); *pHandle = (tmdlHdmiTxIWSemHandle_t)mutex; RETIF(pHandle == NULL, TMDL_ERR_DLHDMITX_NO_RESOURCES) return(TM_OK); }
/*============================================================================*/ tmErrorCode_t setHwRegisterField ( tmHdmiTxobject_t *pDis, UInt16 regShadPageAddr, UInt8 fieldMask, UInt8 fieldValue ) { tmErrorCode_t err; /* Error code */ UInt8 regShad; /* The index to the register's shadow copy */ UInt8 regPage; /* The index to the register's page */ UInt8 regAddr; /* The register's address on the page */ UInt8 newRegPage; /* The register's new page number */ UInt8 regValue; /* The register's current value */ tmbslHdmiTxSysArgs_t sysArgs; /* Arguments passed to system function */ /* Unpack register shadow index, page index and address */ regShad = SPA2SHAD(regShadPageAddr); regPage = SPA2PAGE(regShadPageAddr); regAddr = SPA2ADDR(regShadPageAddr); newRegPage = kPageIndexToPage[regPage]; /* Set page register if required */ if (pDis->curRegPage != newRegPage) { /* All non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = E_REG_CURPAGE_ADR_W; sysArgs.lenData = 1; sysArgs.pData = &newRegPage; err = pDis->sysFuncWrite(&sysArgs); RETIF(err != TM_OK, TMBSL_ERR_HDMI_I2C_WRITE) pDis->curRegPage = newRegPage; } if (regShad != E_SNONE) { /* Get shadow copy */ regValue = pDis->shadowReg[regShad]; } else { /* Read I2C register value. * All bitfield registers are either shadowed or can be read. */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = regAddr; sysArgs.lenData = 1; sysArgs.pData = ®Value; err = pDis->sysFuncRead(&sysArgs); RETIF(err != TM_OK, TMBSL_ERR_HDMI_I2C_READ) } /* Reset register bits that are set in the mask */ regValue = regValue & (UInt8)(~fieldMask); /* Shift the field value left to align its bits with the mask */ fieldValue <<= kMaskToShift[fieldMask]; /* Reset shifted field bits that are not set in the mask */ fieldValue &= fieldMask; /* Set the shifted bitfield */ regValue |= fieldValue; /* Set shadow copy */ if (regShad != E_SNONE) { pDis->shadowReg[regShad] = regValue; } /* Write to I2C - all non-OK results are errors */ sysArgs.slaveAddr = pDis->uHwAddress; sysArgs.firstRegister = regAddr; sysArgs.lenData = 1; sysArgs.pData = ®Value; err = pDis->sysFuncWrite(&sysArgs); return (err == TM_OK) ? TM_OK : TMBSL_ERR_HDMI_I2C_WRITE; }
/* Will only be used in ioctl(MTK_HDMI_AUDIO_VIDEO_ENABLE) */ static HDMI_STATUS hdmi_drv_init(void) { int lcm_width, lcm_height; int tmpBufferSize; M4U_PORT_STRUCT portStruct; HDMI_FUNC(); RETIF(p->output_mode == HDMI_OUTPUT_MODE_DPI_BYPASS, 0); p->hdmi_width = 1280; p->hdmi_height = 720; lcm_width = DISP_GetScreenWidth(); lcm_height = DISP_GetScreenHeight(); //printk("[hdmi]%s, hdmi_width=%d, hdmi_height=%d\n", __func__, p->hdmi_width, p->hdmi_height); HDMI_LOG("lcm_width=%d, lcm_height=%d\n", lcm_width, lcm_height); tmpBufferSize = lcm_width * lcm_height *4 * 4; temp_va = (unsigned int) vmalloc(tmpBufferSize); if (((void*) temp_va) == NULL) { HDMI_LOG("vmalloc %dbytes fail\n", tmpBufferSize); return -1; } // WDMA1 if (m4u_alloc_mva(M4U_CLNTMOD_WDMA, temp_va, tmpBufferSize, 0, 0, &temp_mva_w)) { HDMI_LOG("m4u_alloc_mva for temp_mva_w fail\n"); return -1; } m4u_dma_cache_maint(M4U_CLNTMOD_WDMA, temp_va, tmpBufferSize, DMA_BIDIRECTIONAL); portStruct.ePortID = M4U_PORT_WDMA1; //hardware port ID, defined in M4U_PORT_ID_ENUM portStruct.Virtuality = 1; portStruct.Security = 0; portStruct.domain = 0; //domain : 0 1 2 3 portStruct.Distance = 1; portStruct.Direction = 0; m4u_config_port(&portStruct); HDMI_LOG("temp_va=0x%08x, temp_mva_w=0x%08x\n", temp_va, temp_mva_w); p->lcm_width = lcm_width; p->lcm_height = lcm_height; p->output_video_resolution = hdmi_params->init_config.vformat; p->output_audio_format = hdmi_params->init_config.aformat; //#ifdef NEW_HDMI_ARCH // hdmi_display_path_overlay_config(true); //#endif DISP_Config_Overlay_to_Memory(temp_mva_w, 1); //hdmi_dpi_config_clock(); // configure dpi clock //hdmi_dpi_power_switch(false); // but dpi power is still off //hdmi_drv->suspend(); #if 0 LCD_WaitForNotBusy(); LCD_SetOutputMode(3); // LCD write to memory and LCM #endif return HDMI_STATUS_OK; }
/*============================================================================*/ tmErrorCode_t tmbslTDA9989HwGetCapabilities (tmUnitSelect_t txUnit, tmbslHdmiTxHwFeature_t deviceCapability, Bool *pFeatureSupported) { tmHdmiTxobject_t *pDis; tmErrorCode_t err = TM_OK; /* Check unit parameter and point to its object */ err = checkUnitSetDis(txUnit, &pDis); RETIF(err != TM_OK, err) RETIF_BADPARAM(pFeatureSupported == Null) * pFeatureSupported = False; switch (deviceCapability) { case HDMITX_FEATURE_HW_HDCP: if ((pDis->uDeviceFeatures & E_MASKREG_P00_VERSION_not_h) == 0) { *pFeatureSupported = True; } break; case HDMITX_FEATURE_HW_SCALER: if ((pDis->uDeviceFeatures & E_MASKREG_P00_VERSION_not_s) == 0) { *pFeatureSupported = True; } break; case HDMITX_FEATURE_HW_AUDIO_OBA: *pFeatureSupported = True; break; case HDMITX_FEATURE_HW_AUDIO_DST: *pFeatureSupported = False; break; case HDMITX_FEATURE_HW_AUDIO_HBR: *pFeatureSupported = False; break; case HDMITX_FEATURE_HW_HDMI_1_1: *pFeatureSupported = True; break; case HDMITX_FEATURE_HW_HDMI_1_2A: *pFeatureSupported = True; break; case HDMITX_FEATURE_HW_HDMI_1_3A: *pFeatureSupported = False; break; case HDMITX_FEATURE_HW_DEEP_COLOR_30: *pFeatureSupported = False; break; case HDMITX_FEATURE_HW_DEEP_COLOR_36: *pFeatureSupported = False; break; case HDMITX_FEATURE_HW_DEEP_COLOR_48: *pFeatureSupported = False; break; case HDMITX_FEATURE_HW_UPSAMPLER: *pFeatureSupported = True; break; case HDMITX_FEATURE_HW_DOWNSAMPLER: *pFeatureSupported = True; break; case HDMITX_FEATURE_HW_COLOR_CONVERSION: *pFeatureSupported = True; break; default: *pFeatureSupported = False; break; } return err; }