コード例 #1
0
NVENCSTATUS CNvHWEncoder::NvEncEncodeFrame(EncodeBuffer *pEncodeBuffer, NvEncPictureCommand *encPicCommand,
                                           uint32_t width, uint32_t height, NV_ENC_PIC_STRUCT ePicStruct,
                                           int8_t *qpDeltaMapArray, uint32_t qpDeltaMapArraySize)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_PIC_PARAMS encPicParams;

    memset(&encPicParams, 0, sizeof(encPicParams));
    SET_VER(encPicParams, NV_ENC_PIC_PARAMS);


    encPicParams.inputBuffer = pEncodeBuffer->stInputBfr.hInputSurface;
    encPicParams.bufferFmt = pEncodeBuffer->stInputBfr.bufferFmt;
    encPicParams.inputWidth = width;
    encPicParams.inputHeight = height;
    encPicParams.outputBitstream = pEncodeBuffer->stOutputBfr.hBitstreamBuffer;
    encPicParams.completionEvent = pEncodeBuffer->stOutputBfr.hOutputEvent;
    encPicParams.inputTimeStamp = m_EncodeIdx;
    encPicParams.pictureStruct = ePicStruct;
    encPicParams.qpDeltaMap = qpDeltaMapArray;
    encPicParams.qpDeltaMapSize = qpDeltaMapArraySize;


    if (encPicCommand)
    {
        if (encPicCommand->bForceIDR)
        {
            encPicParams.encodePicFlags |= NV_ENC_PIC_FLAG_FORCEIDR;
        }

        if (encPicCommand->bForceIntraRefresh)
        {
            if (codecGUID == NV_ENC_CODEC_HEVC_GUID)
            {
                encPicParams.codecPicParams.hevcPicParams.forceIntraRefreshWithFrameCnt = encPicCommand->intraRefreshDuration;
            }
            else
            {
                encPicParams.codecPicParams.h264PicParams.forceIntraRefreshWithFrameCnt = encPicCommand->intraRefreshDuration;

            }
        }
    }
#if 0	
//	иокг
	encPicParams.codecPicParams.h264PicParams.sliceMode = 3;
	encPicParams.codecPicParams.h264PicParams.sliceModeData= 5;
	encPicParams.codecPicParams.h264PicParams.sliceModeDataUpdate=1;
#endif
    nvStatus = m_pEncodeAPI->nvEncEncodePicture(m_hEncoder, &encPicParams);
    if (nvStatus != NV_ENC_SUCCESS && nvStatus != NV_ENC_ERR_NEED_MORE_INPUT)
    {
        assert(0);
        return nvStatus;
    }

    m_EncodeIdx++;

    return NV_ENC_SUCCESS;
}
コード例 #2
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
CNvHWEncoder::CNvHWEncoder()
{
    m_hEncoder = NULL;
    m_bEncoderInitialized = false;
    m_pEncodeAPI = NULL;
    m_hinstLib = NULL;
    m_fOutput = NULL;
    m_EncodeIdx = 0;
    m_uCurWidth = 0;
    m_uCurHeight = 0;
    m_uMaxWidth = 0;
    m_uMaxHeight = 0;

    memset(&m_stCreateEncodeParams, 0, sizeof(m_stCreateEncodeParams));
    SET_VER(m_stCreateEncodeParams, NV_ENC_INITIALIZE_PARAMS);

    memset(&m_stEncodeConfig, 0, sizeof(m_stEncodeConfig));
    SET_VER(m_stEncodeConfig, NV_ENC_CONFIG);
}
コード例 #3
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncFlushEncoderQueue(void *hEOSEvent)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_PIC_PARAMS encPicParams;
    memset(&encPicParams, 0, sizeof(encPicParams));
    SET_VER(encPicParams, NV_ENC_PIC_PARAMS);
    encPicParams.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
    encPicParams.completionEvent = hEOSEvent;
    nvStatus = m_pEncodeAPI->nvEncEncodePicture(m_hEncoder, &encPicParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }
    return nvStatus;
}
コード例 #4
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::ProcessOutput(const EncodeBuffer *pEncodeBuffer)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;

    if (pEncodeBuffer->stOutputBfr.hBitstreamBuffer == NULL && pEncodeBuffer->stOutputBfr.bEOSFlag == FALSE)
    {
        return NV_ENC_ERR_INVALID_PARAM;
    }

    if (pEncodeBuffer->stOutputBfr.bWaitOnEvent == TRUE)
    {
        if (!pEncodeBuffer->stOutputBfr.hOutputEvent)
        {
            return NV_ENC_ERR_INVALID_PARAM;
        }
#if defined(NV_WINDOWS)
        WaitForSingleObject(pEncodeBuffer->stOutputBfr.hOutputEvent, INFINITE);
#endif
    }

    if (pEncodeBuffer->stOutputBfr.bEOSFlag)
        return NV_ENC_SUCCESS;

    nvStatus = NV_ENC_SUCCESS;
    NV_ENC_LOCK_BITSTREAM lockBitstreamData;
    memset(&lockBitstreamData, 0, sizeof(lockBitstreamData));
    SET_VER(lockBitstreamData, NV_ENC_LOCK_BITSTREAM);
    lockBitstreamData.outputBitstream = pEncodeBuffer->stOutputBfr.hBitstreamBuffer;
    lockBitstreamData.doNotWait = false;

    nvStatus = m_pEncodeAPI->nvEncLockBitstream(m_hEncoder, &lockBitstreamData);
    if (nvStatus == NV_ENC_SUCCESS)
    {
        fwrite(lockBitstreamData.bitstreamBufferPtr, 1, lockBitstreamData.bitstreamSizeInBytes, m_fOutput);
        nvStatus = m_pEncodeAPI->nvEncUnlockBitstream(m_hEncoder, pEncodeBuffer->stOutputBfr.hBitstreamBuffer);
    }
    else
    {
        PRINTERR("lock bitstream function failed \n");
    }

    return nvStatus;
}
コード例 #5
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncMapInputResource(void* registeredResource, void** mappedResource)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_MAP_INPUT_RESOURCE mapInputResParams;

    memset(&mapInputResParams, 0, sizeof(mapInputResParams));
    SET_VER(mapInputResParams, NV_ENC_MAP_INPUT_RESOURCE);

    mapInputResParams.registeredResource = registeredResource;

    nvStatus = m_pEncodeAPI->nvEncMapInputResource(m_hEncoder, &mapInputResParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *mappedResource = mapInputResParams.mappedResource;

    return nvStatus;
}
コード例 #6
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncLockInputBuffer(void* inputBuffer, void** bufferDataPtr, uint32_t* pitch)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_LOCK_INPUT_BUFFER lockInputBufferParams;

    memset(&lockInputBufferParams, 0, sizeof(lockInputBufferParams));
    SET_VER(lockInputBufferParams, NV_ENC_LOCK_INPUT_BUFFER);

    lockInputBufferParams.inputBuffer = inputBuffer;
    nvStatus = m_pEncodeAPI->nvEncLockInputBuffer(m_hEncoder, &lockInputBufferParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *bufferDataPtr = lockInputBufferParams.bufferDataPtr;
    *pitch = lockInputBufferParams.pitch;

    return nvStatus;
}
コード例 #7
0
//NOT USED UNDER LINUX
NVENCSTATUS CNvHWEncoder::NvEncRegisterAsyncEvent(void** completionEvent)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_EVENT_PARAMS eventParams;

    memset(&eventParams, 0, sizeof(eventParams));
    SET_VER(eventParams, NV_ENC_EVENT_PARAMS);

    eventParams.completionEvent = NULL;

    nvStatus = m_pEncodeAPI->nvEncRegisterAsyncEvent(m_hEncoder, &eventParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *completionEvent = eventParams.completionEvent;

    return nvStatus;
}
コード例 #8
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncOpenEncodeSessionEx(void* device, NV_ENC_DEVICE_TYPE deviceType)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS openSessionExParams;

    memset(&openSessionExParams, 0, sizeof(openSessionExParams));
    SET_VER(openSessionExParams, NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS);

    openSessionExParams.device = device;
    openSessionExParams.deviceType = deviceType;
    openSessionExParams.reserved = NULL;
    openSessionExParams.apiVersion = NVENCAPI_VERSION;

    nvStatus = m_pEncodeAPI->nvEncOpenEncodeSessionEx(&openSessionExParams, &m_hEncoder);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    return nvStatus;
}
コード例 #9
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncCreateBitstreamBuffer(uint32_t size, void** bitstreamBuffer)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_CREATE_BITSTREAM_BUFFER createBitstreamBufferParams;

    memset(&createBitstreamBufferParams, 0, sizeof(createBitstreamBufferParams));
    SET_VER(createBitstreamBufferParams, NV_ENC_CREATE_BITSTREAM_BUFFER);

    createBitstreamBufferParams.size = size;
    createBitstreamBufferParams.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_CACHED;

    nvStatus = m_pEncodeAPI->nvEncCreateBitstreamBuffer(m_hEncoder, &createBitstreamBufferParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *bitstreamBuffer = createBitstreamBufferParams.bitstreamBuffer;

    return nvStatus;
}
コード例 #10
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncRegisterAsyncEvent(void** completionEvent)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_EVENT_PARAMS eventParams;

    memset(&eventParams, 0, sizeof(eventParams));
    SET_VER(eventParams, NV_ENC_EVENT_PARAMS);

#if defined (NV_WINDOWS)
    eventParams.completionEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#else
    eventParams.completionEvent = NULL;
#endif
    nvStatus = m_pEncodeAPI->nvEncRegisterAsyncEvent(m_hEncoder, &eventParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *completionEvent = eventParams.completionEvent;

    return nvStatus;
}
コード例 #11
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncCreateInputBuffer(uint32_t width, uint32_t height, void** inputBuffer, uint32_t isYuv444)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_CREATE_INPUT_BUFFER createInputBufferParams;

    memset(&createInputBufferParams, 0, sizeof(createInputBufferParams));
    SET_VER(createInputBufferParams, NV_ENC_CREATE_INPUT_BUFFER);

    createInputBufferParams.width = width;
    createInputBufferParams.height = height;
    createInputBufferParams.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_CACHED;
    createInputBufferParams.bufferFmt = isYuv444 ? NV_ENC_BUFFER_FORMAT_YUV444_PL : NV_ENC_BUFFER_FORMAT_NV12_PL;

    nvStatus = m_pEncodeAPI->nvEncCreateInputBuffer(m_hEncoder, &createInputBufferParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *inputBuffer = createInputBufferParams.inputBuffer;

    return nvStatus;
}
コード例 #12
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::NvEncRegisterResource(NV_ENC_INPUT_RESOURCE_TYPE resourceType, void* resourceToRegister, uint32_t width, uint32_t height, uint32_t pitch, void** registeredResource)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;
    NV_ENC_REGISTER_RESOURCE registerResParams;

    memset(&registerResParams, 0, sizeof(registerResParams));
    SET_VER(registerResParams, NV_ENC_REGISTER_RESOURCE);

    registerResParams.resourceType = resourceType;
    registerResParams.resourceToRegister = resourceToRegister;
    registerResParams.width = width;
    registerResParams.height = height;
    registerResParams.pitch = pitch;

    nvStatus = m_pEncodeAPI->nvEncRegisterResource(m_hEncoder, &registerResParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        assert(0);
    }

    *registeredResource = registerResParams.registeredResource;

    return nvStatus;
}
コード例 #13
0
ファイル: NvHWEncoder.cpp プロジェクト: hmoenck/ImageCompress
NVENCSTATUS CNvHWEncoder::CreateEncoder(const EncodeConfig *pEncCfg)
{
    NVENCSTATUS nvStatus = NV_ENC_SUCCESS;

    if (pEncCfg == NULL)
    {
        return NV_ENC_ERR_INVALID_PARAM;
    }

    m_uCurWidth = pEncCfg->width;
    m_uCurHeight = pEncCfg->height;

    m_uMaxWidth = (pEncCfg->maxWidth > 0 ? pEncCfg->maxWidth : pEncCfg->width);
    m_uMaxHeight = (pEncCfg->maxHeight > 0 ? pEncCfg->maxHeight : pEncCfg->height);

    if ((m_uCurWidth > m_uMaxWidth) || (m_uCurHeight > m_uMaxHeight)) {
        return NV_ENC_ERR_INVALID_PARAM;
    }

    m_fOutput = pEncCfg->fOutput;

    if (!pEncCfg->width || !pEncCfg->height || !m_fOutput)
    {
        return NV_ENC_ERR_INVALID_PARAM;
    }

    GUID inputCodecGUID = pEncCfg->codec == NV_ENC_H264 ? NV_ENC_CODEC_H264_GUID : NV_ENC_CODEC_HEVC_GUID;
    nvStatus = ValidateEncodeGUID(inputCodecGUID);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        PRINTERR("codec not supported \n");
        return nvStatus;
    }

    codecGUID = inputCodecGUID;

    m_stCreateEncodeParams.encodeGUID = inputCodecGUID;
    m_stCreateEncodeParams.presetGUID = pEncCfg->presetGUID;
    m_stCreateEncodeParams.encodeWidth = pEncCfg->width;
    m_stCreateEncodeParams.encodeHeight = pEncCfg->height;

    m_stCreateEncodeParams.darWidth = pEncCfg->width;
    m_stCreateEncodeParams.darHeight = pEncCfg->height;
    m_stCreateEncodeParams.frameRateNum = pEncCfg->fps;
    m_stCreateEncodeParams.frameRateDen = 1;
#if defined(NV_WINDOWS)
    m_stCreateEncodeParams.enableEncodeAsync = 1;
#else
    m_stCreateEncodeParams.enableEncodeAsync = 0;
#endif
    m_stCreateEncodeParams.enablePTD = 1;
    m_stCreateEncodeParams.reportSliceOffsets = 0;
    m_stCreateEncodeParams.enableSubFrameWrite = 0;
    m_stCreateEncodeParams.encodeConfig = &m_stEncodeConfig;
    m_stCreateEncodeParams.maxEncodeWidth = m_uMaxWidth;
    m_stCreateEncodeParams.maxEncodeHeight = m_uMaxHeight;

    // apply preset
    NV_ENC_PRESET_CONFIG stPresetCfg;
    memset(&stPresetCfg, 0, sizeof(NV_ENC_PRESET_CONFIG));
    SET_VER(stPresetCfg, NV_ENC_PRESET_CONFIG);
    SET_VER(stPresetCfg.presetCfg, NV_ENC_CONFIG);

    nvStatus = m_pEncodeAPI->nvEncGetEncodePresetConfig(m_hEncoder, m_stCreateEncodeParams.encodeGUID, m_stCreateEncodeParams.presetGUID, &stPresetCfg);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        PRINTERR("nvEncGetEncodePresetConfig returned failure");
        return nvStatus;
    }
    memcpy(&m_stEncodeConfig, &stPresetCfg.presetCfg, sizeof(NV_ENC_CONFIG));

    m_stEncodeConfig.gopLength = pEncCfg->gopLength;
    m_stEncodeConfig.frameIntervalP = pEncCfg->numB + 1;
    if (pEncCfg->pictureStruct == NV_ENC_PIC_STRUCT_FRAME)
    {
        m_stEncodeConfig.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME;
    }
    else
    {
        m_stEncodeConfig.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
    }

    m_stEncodeConfig.mvPrecision = NV_ENC_MV_PRECISION_QUARTER_PEL;

    if (pEncCfg->bitrate || pEncCfg->vbvMaxBitrate)
    {
        m_stEncodeConfig.rcParams.rateControlMode = (NV_ENC_PARAMS_RC_MODE)pEncCfg->rcMode;
        m_stEncodeConfig.rcParams.averageBitRate = pEncCfg->bitrate;
        m_stEncodeConfig.rcParams.maxBitRate = pEncCfg->vbvMaxBitrate;
        m_stEncodeConfig.rcParams.vbvBufferSize = pEncCfg->vbvSize;
        m_stEncodeConfig.rcParams.vbvInitialDelay = pEncCfg->vbvSize * 9 / 10;
    }
    else
    {
        m_stEncodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
    }

    if (pEncCfg->rcMode == 0)
    {
        m_stEncodeConfig.rcParams.constQP.qpInterP = pEncCfg->presetGUID == NV_ENC_PRESET_LOSSLESS_HP_GUID? 0 : pEncCfg->qp;
        m_stEncodeConfig.rcParams.constQP.qpInterB = pEncCfg->presetGUID == NV_ENC_PRESET_LOSSLESS_HP_GUID? 0 : pEncCfg->qp;
        m_stEncodeConfig.rcParams.constQP.qpIntra = pEncCfg->presetGUID == NV_ENC_PRESET_LOSSLESS_HP_GUID? 0 : pEncCfg->qp;
    }

    if (pEncCfg->isYuv444)
    {
        m_stEncodeConfig.encodeCodecConfig.h264Config.chromaFormatIDC = 3;
    }
    else
    {
        m_stEncodeConfig.encodeCodecConfig.h264Config.chromaFormatIDC = 1;
    }

    if (pEncCfg->intraRefreshEnableFlag)
    {
        if (pEncCfg->codec == NV_ENC_HEVC)
        {
            m_stEncodeConfig.encodeCodecConfig.hevcConfig.enableIntraRefresh = 1;
            m_stEncodeConfig.encodeCodecConfig.hevcConfig.intraRefreshPeriod = pEncCfg->intraRefreshPeriod;
            m_stEncodeConfig.encodeCodecConfig.hevcConfig.intraRefreshCnt = pEncCfg->intraRefreshDuration;
        }
        else
        {
            m_stEncodeConfig.encodeCodecConfig.h264Config.enableIntraRefresh = 1;
            m_stEncodeConfig.encodeCodecConfig.h264Config.intraRefreshPeriod = pEncCfg->intraRefreshPeriod;
            m_stEncodeConfig.encodeCodecConfig.h264Config.intraRefreshCnt = pEncCfg->intraRefreshDuration;
        }
    }

    if (pEncCfg->invalidateRefFramesEnableFlag)
    {
        if (pEncCfg->codec == NV_ENC_HEVC)
        {
            m_stEncodeConfig.encodeCodecConfig.hevcConfig.maxNumRefFramesInDPB = 16;
        }
        else
        {
            m_stEncodeConfig.encodeCodecConfig.h264Config.maxNumRefFrames = 16;
        }
    }

    if (pEncCfg->qpDeltaMapFile)
    {
        m_stEncodeConfig.rcParams.enableExtQPDeltaMap = 1;
    }
    if (pEncCfg->codec == NV_ENC_H264)
    {
        m_stEncodeConfig.encodeCodecConfig.h264Config.idrPeriod = pEncCfg->gopLength;
    }
    else if (pEncCfg->codec == NV_ENC_HEVC)
    {
        m_stEncodeConfig.encodeCodecConfig.hevcConfig.idrPeriod = pEncCfg->gopLength;
    }

    nvStatus = m_pEncodeAPI->nvEncInitializeEncoder(m_hEncoder, &m_stCreateEncodeParams);
    if (nvStatus != NV_ENC_SUCCESS)
    {
        PRINTERR("Encode Session Initialization failed");
        return nvStatus;
    }
    m_bEncoderInitialized = true;

    return nvStatus;
}
コード例 #14
0
ファイル: stx7200_audio.c プロジェクト: highzeth/satip-axe
static int __init stx7200_audio_devices_setup(void)
{
    int result;
    int ver;

    if (cpu_data->type != CPU_STX7200) {
        BUG();
        return -ENODEV;
    }

    /* We assume farther that MEM resource is first, let's check it... */
    BUG_ON(stx7200_spdif_player.resource[0].flags != IORESOURCE_MEM);
    BUG_ON(stx7200_hdmi_pcm_player.resource[0].flags != IORESOURCE_MEM);
    BUG_ON(stx7200_hdmi_spdif_player.resource[0].flags != IORESOURCE_MEM);

    switch (cpu_data->cut_major) {
    case 1:
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_0, 5);
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_1, 5);
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_2, 5);
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_3, 5);

        SET_VER(snd_stm_spdif_player_info, stx7200_spdif_player, 3);
        stx7200_spdif_player.resource[0].end += 0x40;

        SET_VER(snd_stm_pcm_player_info, stx7200_hdmi_pcm_player, 5);
        stx7200_hdmi_pcm_player.resource[0].start = 0xfd106d00;
        stx7200_hdmi_pcm_player.resource[0].end = 0xfd106d27;

        SET_VER(snd_stm_spdif_player_info,
                stx7200_hdmi_spdif_player, 3);
        stx7200_hdmi_spdif_player.resource[0].start = 0xfd106c00;
        stx7200_hdmi_spdif_player.resource[0].end = 0xfd106c3f;

        SET_VER(snd_stm_pcm_reader_info, stx7200_pcm_reader_0, 3);

        break;

    case 2 ... 3:
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_0, 6);
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_1, 6);
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_2, 6);
        SET_VER(snd_stm_pcm_player_info, stx7200_pcm_player_3, 6);

        SET_VER(snd_stm_spdif_player_info, stx7200_spdif_player, 4);
        stx7200_spdif_player.resource[0].end += 0x44;

        SET_VER(snd_stm_pcm_player_info, stx7200_hdmi_pcm_player, 6);
        stx7200_hdmi_pcm_player.resource[0].start = 0xfd112d00;
        stx7200_hdmi_pcm_player.resource[0].end = 0xfd112d27;

        SET_VER(snd_stm_spdif_player_info,
                stx7200_hdmi_spdif_player, 4);
        stx7200_hdmi_spdif_player.resource[0].start = 0xfd112c00;
        stx7200_hdmi_spdif_player.resource[0].end = 0xfd112c43;

        ver = (cpu_data->cut_major == 2 ? 5 : 6);
        SET_VER(snd_stm_pcm_reader_info, stx7200_pcm_reader_0, ver);
        SET_VER(snd_stm_pcm_reader_info, stx7200_pcm_reader_1, ver);

        break;

    default:
        printk(KERN_ERR "%s(): Not supported STx7200 cut %d detected!"
               "\n", __func__, cpu_data->cut_major);
        return -ENODEV;
    }

    /* Ugly but quick hack to have HDMI SPDIF player & I2S to SPDIF
     * converters enabled without loading STMFB...
     * TODO: do this in some sane way! */
    {
        void *hdmi_gpout;

        if (cpu_data->cut_major == 1)
            hdmi_gpout = ioremap(0xfd106020, 4);
        else
            hdmi_gpout = ioremap(0xfd112020, 4);

        writel(readl(hdmi_gpout) | 0x3, hdmi_gpout);
        iounmap(hdmi_gpout);
    }

    result = platform_add_devices(stx7200_audio_devices,
                                  ARRAY_SIZE(stx7200_audio_devices));

    if (result == 0 && cpu_data->cut_major > 1)
        result = platform_add_devices(stx7200_cut2_audio_devices,
                                      ARRAY_SIZE(stx7200_cut2_audio_devices));

    return result;
}