mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-07-22 12:15:55 -04:00
@@ -0,0 +1,745 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup HDMI
|
||||
* @{
|
||||
*
|
||||
* @brief Declares standard APIs of basic High-Definition Multimedia Interface (HDMI) capabilities.
|
||||
*
|
||||
* You can use this module to access the HDMI and enable the driver to operate an HDMI sink device.
|
||||
* These capabilities include start and stop tramnsfer on HDMI, setting some attributes,
|
||||
* and read sink device's EDID data.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hdmi_if.h
|
||||
*
|
||||
* @brief Declares the standard HDMI interface functions.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
#ifndef HDMI_IF_H
|
||||
#define HDMI_IF_H
|
||||
|
||||
#include "hdf_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @brief Indicates that maximum length of an HDMI sink device's EDID is 512 bytes.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
#define HDMI_EDID_MAX_LEN 512
|
||||
|
||||
/**
|
||||
* @brief Enumerates deep color,
|
||||
* see the section 6.2.4 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiDeepColor {
|
||||
HDMI_DEEP_COLOR_24BITS = 0,
|
||||
HDMI_DEEP_COLOR_30BITS = 1,
|
||||
HDMI_DEEP_COLOR_36BITS = 2,
|
||||
HDMI_DEEP_COLOR_48BITS = 3,
|
||||
HDMI_DEEP_COLOR_OFF = 0xff,
|
||||
HDMI_DEEP_COLOR_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates video bit depth
|
||||
* see the section 6.6 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiVideoBitDepth {
|
||||
HDMI_VIDEO_BIT_DEPTH_8 = 0,
|
||||
HDMI_VIDEO_BIT_DEPTH_10 = 1,
|
||||
HDMI_VIDEO_BIT_DEPTH_12 = 2,
|
||||
HDMI_VIDEO_BIT_DEPTH_16 = 3,
|
||||
HDMI_VIDEO_BIT_DEPTH_OFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates color space,
|
||||
* see the section 6 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiColorSpace {
|
||||
HDMI_COLOR_SPACE_RGB = 0,
|
||||
HDMI_COLOR_SPACE_YCBCR422 = 1,
|
||||
HDMI_COLOR_SPACE_YCBCR444 = 2,
|
||||
HDMI_COLOR_SPACE_YCBCR420 = 3,
|
||||
HDMI_COLOR_SPACE_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates colorimetry, see the section 6.7 of HDMI Specification 1.4 and
|
||||
* the section 7.2 of HDMI Specification 2.0 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiColorimetry {
|
||||
HDMI_COLORIMETRY_NO_DATA = 0,
|
||||
HDMI_COLORIMETRY_ITU601 = 1,
|
||||
HDMI_COLORIMETRY_ITU709 = 2,
|
||||
HDMI_COLORIMETRY_EXTENDED = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates extended colorimetry, see the section 6.7 of HDMI Specification 1.4 and
|
||||
* the section 7.2 of HDMI Specification 2.0 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiExtendedColorimetry {
|
||||
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601 = 0,
|
||||
HDMI_EXTENDED_COLORIMETRY_XV_YCC_709 = 1,
|
||||
HDMI_EXTENDED_COLORIMETRY_S_YCC_601 = 2,
|
||||
HDMI_EXTENDED_COLORIMETRY_OPYCC_601 = 3,
|
||||
HDMI_EXTENDED_COLORIMETRY_OPRGB = 4,
|
||||
HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM = 5,
|
||||
HDMI_EXTENDED_COLORIMETRY_BT2020 = 6,
|
||||
HDMI_EXTENDED_COLORIMETRY_ADDITIONAL = 7,
|
||||
HDMI_EXTENDED_COLORIMETRY_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates quantization range, see the section 6.6 of HDMI Specification 1.4 and
|
||||
* the section 7.3 of HDMI Specification 2.0 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiQuantizationRange {
|
||||
HDMI_QUANTIZATION_RANGE_DEFAULT = 0,
|
||||
HDMI_QUANTIZATION_RANGE_LIMITED = 1,
|
||||
HDMI_QUANTIZATION_RANGE_FULL = 2,
|
||||
HDMI_QUANTIZATION_RANGE_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates YCC quantization range, see the section 6.6 of HDMI Specification 1.4 and
|
||||
* the section 7.3 of HDMI Specification 2.0 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiYccQuantizationRange {
|
||||
HDMI_YCC_QUANTIZATION_RANGE_LIMITED = 0,
|
||||
HDMI_YCC_QUANTIZATION_RANGE_FULL = 1,
|
||||
HDMI_YCC_QUANTIZATION_RANGE_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates video 3d structure,
|
||||
* see the section 8.2.3 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiVideo3dStructure {
|
||||
HDMI_VS_VIDEO_3D_FRAME_PACKING = 0,
|
||||
HDMI_VS_VIDEO_3D_FIELD_ALTERNATIVE = 1,
|
||||
HDMI_VS_VIDEO_3D_LINE_ALTERNATIVE = 2,
|
||||
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_FULL = 3,
|
||||
HDMI_VS_VIDEO_3D_L_DEPTH = 4,
|
||||
HDMI_VS_VIDEO_3D_L_DEPTH_GFX_GFX_DEPTH = 5,
|
||||
HDMI_VS_VIDEO_3D_TOP_AND_BOTTOM = 6,
|
||||
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_HALF = 8,
|
||||
HDMI_VS_VIDEO_3D_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates video timing,
|
||||
* see the section 8.2.3 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiVideoTiming {
|
||||
HDMI_VIDEO_TIMING_NONE = 0,
|
||||
HDMI_VIDEO_TIMING_640X480P60 = 1,
|
||||
HDMI_VIDEO_TIMING_720X480P60 = 2,
|
||||
HDMI_VIDEO_TIMING_720X480P120 = 3,
|
||||
HDMI_VIDEO_TIMING_720X480P240 = 4,
|
||||
HDMI_VIDEO_TIMING_720X576P50 = 5,
|
||||
HDMI_VIDEO_TIMING_720X576P100 = 6,
|
||||
HDMI_VIDEO_TIMING_720X576P200 = 7,
|
||||
HDMI_VIDEO_TIMING_1280X720P24 = 8,
|
||||
HDMI_VIDEO_TIMING_1280X720P25 = 9,
|
||||
HDMI_VIDEO_TIMING_1280X720P30 = 10,
|
||||
HDMI_VIDEO_TIMING_1280X720P48 = 11,
|
||||
HDMI_VIDEO_TIMING_1280X720P50 = 12,
|
||||
HDMI_VIDEO_TIMING_1280X720P60 = 13,
|
||||
HDMI_VIDEO_TIMING_1280X720P100 = 14,
|
||||
HDMI_VIDEO_TIMING_1280X720P120 = 15,
|
||||
HDMI_VIDEO_TIMING_1440X240P60 = 16,
|
||||
HDMI_VIDEO_TIMING_1440X288P50 = 17,
|
||||
HDMI_VIDEO_TIMING_1440X480I60 = 18,
|
||||
HDMI_VIDEO_TIMING_1440X480P60 = 19,
|
||||
HDMI_VIDEO_TIMING_1440X480I120 = 20,
|
||||
HDMI_VIDEO_TIMING_1440X480I240 = 21,
|
||||
HDMI_VIDEO_TIMING_1440X576I50 = 22,
|
||||
HDMI_VIDEO_TIMING_1440X576P50 = 23,
|
||||
HDMI_VIDEO_TIMING_1440X576I60 = 24,
|
||||
HDMI_VIDEO_TIMING_1440X576I100 = 25,
|
||||
HDMI_VIDEO_TIMING_1440X576I200 = 26,
|
||||
HDMI_VIDEO_TIMING_2880X288P50 = 27,
|
||||
HDMI_VIDEO_TIMING_2880X480I60 = 28,
|
||||
HDMI_VIDEO_TIMING_2880X480P60 = 29,
|
||||
HDMI_VIDEO_TIMING_2880X240I60 = 30,
|
||||
HDMI_VIDEO_TIMING_2880X576I50 = 31,
|
||||
HDMI_VIDEO_TIMING_2880X576P50 = 32,
|
||||
HDMI_VIDEO_TIMING_1680X720P24 = 33,
|
||||
HDMI_VIDEO_TIMING_1680X720P25 = 34,
|
||||
HDMI_VIDEO_TIMING_1680X720P30 = 35,
|
||||
HDMI_VIDEO_TIMING_1680X720P48 = 36,
|
||||
HDMI_VIDEO_TIMING_1680X720P50 = 37,
|
||||
HDMI_VIDEO_TIMING_1680X720P60 = 38,
|
||||
HDMI_VIDEO_TIMING_1680X720P100 = 39,
|
||||
HDMI_VIDEO_TIMING_1680X720P120 = 40,
|
||||
HDMI_VIDEO_TIMING_2560X1080P24 = 41,
|
||||
HDMI_VIDEO_TIMING_2560X1080P25 = 42,
|
||||
HDMI_VIDEO_TIMING_2560X1080P30 = 43,
|
||||
HDMI_VIDEO_TIMING_2560X1080P48 = 44,
|
||||
HDMI_VIDEO_TIMING_2560X1080P50 = 45,
|
||||
HDMI_VIDEO_TIMING_2560X1080P60 = 46,
|
||||
HDMI_VIDEO_TIMING_2560X1080P100 = 47,
|
||||
HDMI_VIDEO_TIMING_2560X1080P120 = 48,
|
||||
HDMI_VIDEO_TIMING_1920X1080I60 = 49,
|
||||
HDMI_VIDEO_TIMING_1920X1080P60 = 50,
|
||||
HDMI_VIDEO_TIMING_1920X1080I50 = 51,
|
||||
HDMI_VIDEO_TIMING_1920X1080P50 = 52,
|
||||
HDMI_VIDEO_TIMING_1920X1080P24 = 53,
|
||||
HDMI_VIDEO_TIMING_1920X1080P25 = 54,
|
||||
HDMI_VIDEO_TIMING_1920X1080P30 = 55,
|
||||
HDMI_VIDEO_TIMING_1920X1080P48 = 56,
|
||||
HDMI_VIDEO_TIMING_1920X1080I100 = 57,
|
||||
HDMI_VIDEO_TIMING_1920X1080I120 = 58,
|
||||
HDMI_VIDEO_TIMING_1920X1080P120 = 59,
|
||||
HDMI_VIDEO_TIMING_1920X1080P100 = 60,
|
||||
HDMI_VIDEO_TIMING_3840X2160P24 = 61,
|
||||
HDMI_VIDEO_TIMING_3840X2160P25 = 62,
|
||||
HDMI_VIDEO_TIMING_3840X2160P30 = 63,
|
||||
HDMI_VIDEO_TIMING_3840X2160P48 = 64,
|
||||
HDMI_VIDEO_TIMING_3840X2160P50 = 65,
|
||||
HDMI_VIDEO_TIMING_3840X2160P60 = 66,
|
||||
HDMI_VIDEO_TIMING_3840X2160P100 = 67,
|
||||
HDMI_VIDEO_TIMING_3840X2160P120 = 68,
|
||||
HDMI_VIDEO_TIMING_4096X2160P24 = 69,
|
||||
HDMI_VIDEO_TIMING_4096X2160P25 = 70,
|
||||
HDMI_VIDEO_TIMING_4096X2160P30 = 71,
|
||||
HDMI_VIDEO_TIMING_4096X2160P48 = 72,
|
||||
HDMI_VIDEO_TIMING_4096X2160P50 = 73,
|
||||
HDMI_VIDEO_TIMING_4096X2160P60 = 74,
|
||||
HDMI_VIDEO_TIMING_4096X2160P100 = 75,
|
||||
HDMI_VIDEO_TIMING_4096X2160P120 = 76,
|
||||
HDMI_VIDEO_TIMING_5120X2160P24 = 77,
|
||||
HDMI_VIDEO_TIMING_5120X2160P25 = 78,
|
||||
HDMI_VIDEO_TIMING_5120X2160P30 = 79,
|
||||
HDMI_VIDEO_TIMING_5120X2160P48 = 80,
|
||||
HDMI_VIDEO_TIMING_5120X2160P50 = 81,
|
||||
HDMI_VIDEO_TIMING_5120X2160P60 = 82,
|
||||
HDMI_VIDEO_TIMING_5120X2160P100 = 83,
|
||||
HDMI_VIDEO_TIMING_5120X2160P120 = 84,
|
||||
HDMI_VIDEO_TIMING_7680X4320P24 = 85,
|
||||
HDMI_VIDEO_TIMING_7680X4320P25 = 86,
|
||||
HDMI_VIDEO_TIMING_7680X4320P30 = 87,
|
||||
HDMI_VIDEO_TIMING_7680X4320P48 = 88,
|
||||
HDMI_VIDEO_TIMING_7680X4320P50 = 89,
|
||||
HDMI_VIDEO_TIMING_7680X4320P60 = 90,
|
||||
HDMI_VIDEO_TIMING_7680X4320P100 = 91,
|
||||
HDMI_VIDEO_TIMING_7680X4320P120 = 92,
|
||||
HDMI_VIDEO_TIMING_10240X4320P24 = 93,
|
||||
HDMI_VIDEO_TIMING_10240X4320P25 = 94,
|
||||
HDMI_VIDEO_TIMING_10240X4320P30 = 95,
|
||||
HDMI_VIDEO_TIMING_10240X4320P48 = 96,
|
||||
HDMI_VIDEO_TIMING_10240X4320P50 = 97,
|
||||
HDMI_VIDEO_TIMING_10240X4320P60 = 98,
|
||||
HDMI_VIDEO_TIMING_10240X4320P100 = 99,
|
||||
HDMI_VIDEO_TIMING_10240X4320P120 = 100,
|
||||
HDMI_VIDEO_TIMING_VESA_DEFINE = 101,
|
||||
HDMI_VIDEO_TIMING_VESA_800X600_60 = 102,
|
||||
HDMI_VIDEO_TIMING_VESA_848X480_60 = 103,
|
||||
HDMI_VIDEO_TIMING_VESA_1024X768_60 = 104,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X720_60 = 105,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X768_60 = 106,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X768_60_RB = 107,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X800_60 = 108,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X800_60_RB = 109,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X960_60 = 110,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X1024_60 = 111,
|
||||
HDMI_VIDEO_TIMING_VESA_1360X768_60 = 112,
|
||||
HDMI_VIDEO_TIMING_VESA_1366X768_60 = 113,
|
||||
HDMI_VIDEO_TIMING_VESA_1400X1050_60 = 114,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X900_60 = 115,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X900_60_RB = 116,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X1050_60 = 117,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X1050_60_RB = 118,
|
||||
HDMI_VIDEO_TIMING_VESA_1600X900_60_RB = 119,
|
||||
HDMI_VIDEO_TIMING_VESA_1600X1200_60 = 120,
|
||||
HDMI_VIDEO_TIMING_VESA_1680X1050_60 = 113,
|
||||
HDMI_VIDEO_TIMING_VESA_1680X1050_60_RB = 114,
|
||||
HDMI_VIDEO_TIMING_VESA_1792X1344_60 = 115,
|
||||
HDMI_VIDEO_TIMING_VESA_1856X1392_60 = 116,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1080_60 = 117,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1200_60 = 118,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1200_60_RB = 119,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1440_60 = 120,
|
||||
HDMI_VIDEO_TIMING_VESA_2048X1152_60 = 121,
|
||||
HDMI_VIDEO_TIMING_VESA_2560X1440_60_RB = 122,
|
||||
HDMI_VIDEO_TIMING_VESA_2560X1600_60 = 123,
|
||||
HDMI_VIDEO_TIMING_VESA_2560X1600_60_RB = 124,
|
||||
HDMI_VIDEO_TIMING_USER_DEFINE = 125,
|
||||
HDMI_VIDEO_TIMING_USER_1920X2160_30 = 126,
|
||||
HDMI_VIDEO_TIMING_USER_2560X1440_30 = 127,
|
||||
HDMI_VIDEO_TIMING_USER_2560X1440_60 = 128,
|
||||
HDMI_VIDEO_TIMING_USER_1280X720_60 = 129,
|
||||
HDMI_VIDEO_TIMING_USER_1366X768_60 = 130,
|
||||
HDMI_VIDEO_TIMING_USER_1600X900_60_RB = 131,
|
||||
HDMI_VIDEO_TIMING_USER_1920X1080_60 = 132,
|
||||
HDMI_VIDEO_TIMING_USER_2048X1152_60 = 133,
|
||||
HDMI_VIDEO_TIMING_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates picture aspect ratio,
|
||||
* see the section 8.2.1 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiPictureAspectRatio {
|
||||
HDMI_PICTURE_ASPECT_NO_DATA = 0,
|
||||
HDMI_PICTURE_ASPECT_4_3 = 1,
|
||||
HDMI_PICTURE_ASPECT_16_9 = 2,
|
||||
HDMI_PICTURE_ASPECT_64_27 = 3,
|
||||
HDMI_PICTURE_ASPECT_256_135 = 4,
|
||||
HDMI_PICTURE_ASPECT_BUTT = 5,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates active format aspect ratio,
|
||||
* see the section 8.2.1 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiActiveFormatAspectRatio {
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_16_9_TOP = 2,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_14_9_TOP = 3,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_16_9_CENTER = 4,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_PICTURE = 8,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_4_3 = 9,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_16_9 = 10,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_14_9 = 11,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_4_3_SP_14_9 = 13,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_14_9 = 14,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_4_3 = 15,
|
||||
HDMI_ACTIVE_FORMAT_ASPECT_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates Nups(non-uniform picture scaling),
|
||||
* see the section 8.2.1 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiNups {
|
||||
HDMI_NUPS_UNKNOWN = 0, /* No Known non-uniform scaling */
|
||||
HDMI_NUPS_HORIZONTAL = 1, /* Picture has been scaled horizontally */
|
||||
HDMI_NUPS_VERTICAL = 2, /* Picture has been scaled vertically */
|
||||
HDMI_NUPS_BOTH = 3, /* Picture has been scaled horizontally and vertically */
|
||||
};
|
||||
|
||||
struct HdmiVideoAttr {
|
||||
uint32_t tmdsClock; /* unit: KHz */
|
||||
uint32_t pixelClock; /* unit: KHz */
|
||||
uint32_t pixelRepeat;
|
||||
enum HdmiColorSpace colorSpace;
|
||||
enum HdmiColorimetry colorimetry;
|
||||
enum HdmiExtendedColorimetry extColorimetry;
|
||||
enum HdmiQuantizationRange quantization;
|
||||
enum HdmiYccQuantizationRange yccQuantization;
|
||||
enum HdmiDeepColor deepColor;
|
||||
enum HdmiVideo3dStructure _3dStruct;
|
||||
enum HdmiVideoTiming timing;
|
||||
enum HdmiPictureAspectRatio aspect;
|
||||
enum HdmiActiveFormatAspectRatio activeAspect;
|
||||
enum HdmiNups nups;
|
||||
bool xvycc;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates audio coding type,
|
||||
* see the section 7 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiAudioCodingType {
|
||||
HDMI_AUDIO_CODING_TYPE_STREAM = 0,
|
||||
HDMI_AUDIO_CODING_TYPE_LPCM = 1,
|
||||
HDMI_AUDIO_CODING_TYPE_AC3 = 2,
|
||||
HDMI_AUDIO_CODING_TYPE_MPEG1 = 3,
|
||||
HDMI_AUDIO_CODING_TYPE_MP3 = 4,
|
||||
HDMI_AUDIO_CODING_TYPE_MPEG2 = 5,
|
||||
HDMI_AUDIO_CODING_TYPE_AAC_LC = 6,
|
||||
HDMI_AUDIO_CODING_TYPE_DTS = 7,
|
||||
HDMI_AUDIO_CODING_TYPE_ATRAC = 8,
|
||||
HDMI_AUDIO_CODING_TYPE_OBA =9,
|
||||
HDMI_AUDIO_CODING_TYPE_EAC3 = 10,
|
||||
HDMI_AUDIO_CODING_TYPE_DTS_HD = 11,
|
||||
HDMI_AUDIO_CODING_TYPE_MLP = 12,
|
||||
HDMI_AUDIO_CODING_TYPE_DST = 13,
|
||||
HDMI_AUDIO_CODING_TYPE_WMA_PRO = 14,
|
||||
HDMI_AUDIO_CODING_TYPE_CXT = 15,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates audio interface type.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiAudioInterfaceType {
|
||||
HDMI_AUDIO_IF_TYPE_I2S = 0, /* Inter-IC Sound */
|
||||
HDMI_AUDIO_IF_TYPE_SPDIF = 1, /* Sony/Philips Digital Interface */
|
||||
HDMI_AUDIO_IF_TYPE_OTHER,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates audio bit depth,
|
||||
* see the section 7 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiAudioBitDepth {
|
||||
HDMI_ADIO_BIT_DEPTH_UNKNOWN,
|
||||
HDMI_ADIO_BIT_DEPTH_8 = 8,
|
||||
HDMI_ADIO_BIT_DEPTH_16 = 16,
|
||||
HDMI_ADIO_BIT_DEPTH_18 = 18,
|
||||
HDMI_ADIO_BIT_DEPTH_20 = 20,
|
||||
HDMI_ADIO_BIT_DEPTH_24 = 24,
|
||||
HDMI_ADIO_BIT_DEPTH_32 = 32,
|
||||
HDMI_ADIO_BIT_DEPTH_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates sample rate used for audio,
|
||||
* see the section 7.3 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiSampleRate {
|
||||
HDMI_SAMPLE_RATE_UNKNOWN,
|
||||
HDMI_SAMPLE_RATE_8K = 8000,
|
||||
HDMI_SAMPLE_RATE_11K = 11025,
|
||||
HDMI_SAMPLE_RATE_12K = 12000,
|
||||
HDMI_SAMPLE_RATE_16K = 16000,
|
||||
HDMI_SAMPLE_RATE_22K = 22050,
|
||||
HDMI_SAMPLE_RATE_24K = 24000,
|
||||
HDMI_SAMPLE_RATE_32K = 32000,
|
||||
HDMI_SAMPLE_RATE_44K = 44100,
|
||||
HDMI_SAMPLE_RATE_48K = 48000,
|
||||
HDMI_SAMPLE_RATE_88K = 88200,
|
||||
HDMI_SAMPLE_RATE_96K = 96000,
|
||||
HDMI_SAMPLE_RATE_176K = 176400,
|
||||
HDMI_SAMPLE_RATE_192K = 192000,
|
||||
HDMI_SAMPLE_RATE_768K = 768000,
|
||||
HDMI_SAMPLE_RATE_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates audio format channel,
|
||||
* see the section 7 of HDMI Specification 1.4 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiAudioFormatChannel {
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_2 = 2,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_3,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_4,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_5,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_6,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_7,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_8,
|
||||
HDMI_AUDIO_FORMAT_CHANNEL_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the audio Attribute struct.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdmiAudioAttr {
|
||||
enum HdmiAudioCodingType codingType;
|
||||
enum HdmiAudioInterfaceType ifType;
|
||||
enum HdmiAudioBitDepth bitDepth;
|
||||
enum HdmiSampleRate sampleRate;
|
||||
bool downSample;
|
||||
enum HdmiAudioFormatChannel channels;
|
||||
};
|
||||
|
||||
/* Electro-Optical Transfer Function (EOTF) type define. */
|
||||
enum HdmiEotfType {
|
||||
HDMI_DRM_EOTF_SDR_LUMIN = 0, /* Traditional gamma - SDR Luminance Range */
|
||||
HDMI_DRM_EOTF_HDR_LUMIN = 1, /* Traditional gamma - HDR Luminance Range */
|
||||
HDMI_DRM_EOTF_SMPTE_ST_2048 = 2, /* SMPTE ST 2048 */
|
||||
HDMI_DRM_EOTF_HLG = 3, /* Hybrid Log-Gamma (HLG) based on ITU-R BT.2100-0 */
|
||||
HDMI_DRM_EOTF_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates hdr colormetry,
|
||||
* see HDMI Specification 2.1 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiHdrColormetry {
|
||||
HDMI_HDR_COLORIMETRY_NONE,
|
||||
HDMI_HDR_COLORIMETRY_ITU_601,
|
||||
HDMI_HDR_COLORIMETRY_ITU_709,
|
||||
HDMI_HDR_COLORIMETRY_EXTENDED,
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601,
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709,
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_S_YCC_601,
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_RGB,
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_2020_CONST_LUMINOUS, /* BT2020 c_ycc */
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_2020_NON_CONST_LUMINOUW
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates hdr mode,
|
||||
* see HDMI Specification 2.1 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiHdrMode {
|
||||
HDMI_HDR_MODE_DISABLE, /* HDR & dolby mode disable */
|
||||
HDMI_HDR_MODE_DOLBY_NORMAL, /* dolby normal(ycbcr422-12bit) mode enable */
|
||||
HDMI_HDR_MODE_DOLBY_TUNNELING, /* dolby tunneling(RGB-8bit) mode enable */
|
||||
HDMI_HDR_MODE_CEA_861_3, /* HDR standard mode enable(according to <CEA-861-3.2015>) */
|
||||
HDMI_HDR_MODE_CEA_861_3_AUTHEN, /* HDR authen mode */
|
||||
HDMI_HDR_MODE_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates hdr user mode,
|
||||
* see HDMI Specification 2.1 for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiHdrUserMode {
|
||||
HDMI_HDR_USERMODE_SDR,
|
||||
HDMI_HDR_USERMODE_HDR10,
|
||||
HDMI_HDR_USERMODE_DOLBY,
|
||||
HDMI_HDR_USERMODE_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates static metadata type,
|
||||
* see the section 6.9 of CTA-861-G for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
enum HdmiStaticMetadataType {
|
||||
HDMI_DRM_STATIC_METADATA_TYPE_1 = 0, /* Static Metadata Type 1 */
|
||||
HDMI_DRM_STATIC_METADATA_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumerates static metadata descriptor1st,
|
||||
* see the section 6.9 of CTA-861-G for details.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
struct HdmiStaticMetadataDescriptor1st {
|
||||
uint16_t displayPrimaries0X; /* display_primaries_x[0], in units of 0.00002 */
|
||||
uint16_t displayPrimaries0Y; /* display_primaries_y[0], in units of 0.00002 */
|
||||
uint16_t displayPrimaries1X; /* display_primaries_x[1], in units of 0.00002 */
|
||||
uint16_t displayPrimaries1Y; /* display_primaries_y[1], in units of 0.00002 */
|
||||
uint16_t displayPrimaries2X; /* display_primaries_x[2], in units of 0.00002 */
|
||||
uint16_t displayPrimaries2Y; /* display_primaries_y[2], in units of 0.00002 */
|
||||
uint16_t whitePointX; /* white_point_x, in units of 0.00002 */
|
||||
uint16_t whitePointY; /* white_point_y, in units of 0.00002 */
|
||||
uint16_t maxDisplayMasteringLuminance; /* max_display_mastering_luminance, in units of 1 cd/m^2 */
|
||||
uint16_t minDisplayMasteringLuminance; /* min_display_mastering_luminance, in units of 0.0001 cd/m^2 */
|
||||
uint16_t maxContentLightLevel; /* Maximum Content Light Level, in units of 1 cd/m^2 */
|
||||
uint16_t maxFrameAverageLightLevel; /* Maximum Frame-average Light Level, in units of 1 cd/m^2 */
|
||||
};
|
||||
|
||||
union HdmiStaticMetadataDescriptor {
|
||||
struct HdmiStaticMetadataDescriptor1st type1;
|
||||
};
|
||||
|
||||
struct HdmiHdrAttr {
|
||||
enum HdmiHdrMode mode;
|
||||
enum HdmiHdrUserMode userMode;
|
||||
/* The following members are valid, when mode is HDMI_HDR_MODE_CEA_861_3. */
|
||||
enum HdmiEotfType eotfType;
|
||||
enum HdmiStaticMetadataType metadataType;
|
||||
union HdmiStaticMetadataDescriptor descriptor;
|
||||
enum HdmiHdrColormetry colorimetry;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Opens an HDMI controller with a specified bus number.
|
||||
*
|
||||
* Before using the HDMI interface, you can obtain the device handle of the HDMI controller
|
||||
* by calling {@link HdmiOpen}. This function is used in pair with {@link HdmiClose}.
|
||||
*
|
||||
* @param busNum Indicates the bus number.
|
||||
*
|
||||
* @return Returns the device handle {@link DevHandle} of the HDMI controller if the operation is successful;
|
||||
* returns <b>NULL</b> otherwise.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
DevHandle HdmiOpen(uint16_t busNum);
|
||||
|
||||
/**
|
||||
* @brief HDMI transmission start.
|
||||
*
|
||||
* This function is used in pair with {@link HdmiStop}.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiStart(DevHandle handle);
|
||||
|
||||
/**
|
||||
* @brief HDMI transmission stop.
|
||||
*
|
||||
* This function is used in pair with {@link HdmiStart}.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiStop(DevHandle handle);
|
||||
|
||||
/**
|
||||
* @brief HDMI Avmute set.
|
||||
*
|
||||
* First put the display device into the black screen mute state, waitting for the HDMI output device switch,
|
||||
* and then send a Clear AVMute signal, so that the display device to boot, so that the switching process of
|
||||
* the screen will be shielded.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param enable Indicates whether to enable avmute.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiAvmuteSet(DevHandle handle, bool enable);
|
||||
|
||||
|
||||
/**
|
||||
* @brief HDMI deep color set.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param color Indicates the deep color to be set, see {@link HdmiDeepColor}.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color);
|
||||
|
||||
/**
|
||||
* @brief HDMI deep color get.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param color Indicates the pointer to the deep color to read, see {@link HdmiDeepColor}.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);
|
||||
|
||||
/**
|
||||
* @brief HDMI set video attribute.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param attr Indicates the pointer to the video attribute to set, see {@link HdmiVideoAttr}.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);
|
||||
|
||||
/**
|
||||
* @brief HDMI set audio attribute.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param attr Indicates the pointer to the audio attribute to set, see {@link HdmiAudioAttr}.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);
|
||||
|
||||
/**
|
||||
* @brief HDMI set hdr attribute.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param attr Indicates the pointer to the hdr attribute to set, see {@link HdmiHdrAttr}.
|
||||
*
|
||||
* @return Returns <b>0</b> if the operation is successful; returns a negative value if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);
|
||||
|
||||
/**
|
||||
* @brief HDMI read sink device's raw EDID data.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
* @param buffer Indicates the pointer to the data to read.
|
||||
* @param len Indicates the length of the data to read.
|
||||
*
|
||||
* @return Returns the length of the data read if the operation is successful;
|
||||
* returns a negative value or 0 if the operation fails.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Closes an HDMI controller.
|
||||
*
|
||||
* After the HDMI interface is used, you can close the HDMI controller by calling {@link HdmiClose}.
|
||||
* This function is used in pair with {@link HdmiOpen}.
|
||||
*
|
||||
* @param handle Indicates the pointer to the device handle of the HDMI controller.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void HdmiClose(DevHandle handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_IF_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_COMMON_H
|
||||
#define HDMI_COMMON_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "hdmi_if.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define HDMI_CEA_VIDEO_CODE_MAX 44
|
||||
#define HDMI_VESA_VIDEO_CODE_MAX 31
|
||||
#define HDMI_VIDEO_4K_CODES_MAX 4
|
||||
|
||||
#define HDMI_HDMI14_MAX_TMDS_RATE 340000 /* unit: KHz */
|
||||
#define HDMI_HDMI20_MAX_TMDS_RATE 600000 /* unit: KHz */
|
||||
#define HDMI_MULTIPLE_2P0(x) (2 * x)
|
||||
#define HDMI_MULTIPLE_1P5(x) (((x) * 3) >> 1)
|
||||
#define HDMI_MULTIPLE_1P25(x) (((x) * 5) >> 2)
|
||||
#define HDMI_MULTIPLE_0P5(x) ((x) >> 1)
|
||||
|
||||
enum HdmiTmdsModeType {
|
||||
HDMI_TMDS_MODE_NULL = 0,
|
||||
HDMI_TMDS_MODE_DVI = 1,
|
||||
HDMI_TMDS_MODE_HDMI_1_4 = 2,
|
||||
HDMI_TMDS_MODE_HDMI_2_0 = 3,
|
||||
HDMI_TMDS_MODE_AUTO = 4,
|
||||
HDMI_TMDS_MODE_HDMI_2_1 = 5,
|
||||
HDMI_TMDS_MODE_BUTT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Video Identification Code (VIC).
|
||||
* see CTA-861-G, table 3.
|
||||
*/
|
||||
enum HdmiVic {
|
||||
HDMI_VIC_NONE = 0, /* No Video Identification Code Avaiable(Used with AVI Infoframe only) */
|
||||
HDMI_VIC_640X480P60_4_3 = 1,
|
||||
HDMI_VIC_720X480P60_4_3 = 2,
|
||||
HDMI_VIC_720X480P60_16_9 = 3,
|
||||
HDMI_VIC_1280X720P60_16_9 = 4,
|
||||
HDMI_VIC_1920X1080I60_16_9 = 5,
|
||||
HDMI_VIC_1440X480I60_4_3 = 6,
|
||||
HDMI_VIC_1440X480I60_16_9 = 7,
|
||||
HDMI_VIC_1440X240P60_4_3 = 8,
|
||||
HDMI_VIC_1440X240P60_16_9 = 9,
|
||||
HDMI_VIC_2880X480I60_4_3 = 10,
|
||||
HDMI_VIC_2880X480I60_16_9 = 11,
|
||||
HDMI_VIC_2880X240P60_4_3 = 12,
|
||||
HDMI_VIC_2880X240P60_16_9 = 13,
|
||||
HDMI_VIC_1440X480P60_4_3 = 14,
|
||||
HDMI_VIC_1440X480P60_16_9 = 15,
|
||||
HDMI_VIC_1920X1080P60_16_9 = 16,
|
||||
HDMI_VIC_720X576P50_4_3 = 17,
|
||||
HDMI_VIC_720X576P50_16_9 = 18,
|
||||
HDMI_VIC_1280X720P50_16_9 = 19,
|
||||
HDMI_VIC_1920X1080I50_16_9 = 20,
|
||||
HDMI_VIC_1440X576I50_4_3 = 21,
|
||||
HDMI_VIC_1440X576I50_16_9 = 22,
|
||||
HDMI_VIC_1440X288P50_4_3 = 23,
|
||||
HDMI_VIC_1440X288P50_16_9 = 24,
|
||||
HDMI_VIC_2880X576I50_4_3 = 25,
|
||||
HDMI_VIC_2880X576I50_16_9 = 26,
|
||||
HDMI_VIC_2880X288P50_4_3 = 27,
|
||||
HDMI_VIC_2880X288P50_16_9 = 28,
|
||||
HDMI_VIC_1440X576P50_4_3 = 29,
|
||||
HDMI_VIC_1440X576P50_16_9 = 30,
|
||||
HDMI_VIC_1920X1080P50_16_9 = 31,
|
||||
HDMI_VIC_1920X1080P24_16_9 = 32,
|
||||
HDMI_VIC_1920X1080P25_16_9 = 33,
|
||||
HDMI_VIC_1920X1080P30_16_9 = 34,
|
||||
HDMI_VIC_2880X480P60_4_3 = 35,
|
||||
HDMI_VIC_2880X480P60_16_9 = 36,
|
||||
HDMI_VIC_2880X576P50_4_3 = 37,
|
||||
HDMI_VIC_2880X576P50_16_9 = 38,
|
||||
HDMI_VIC_1920X1080I50_1250_16_9 = 39,
|
||||
HDMI_VIC_1920X1080I100_16_9 = 40,
|
||||
HDMI_VIC_1280X720P100_16_9 = 41,
|
||||
HDMI_VIC_720X576P100_4_3 = 42,
|
||||
HDMI_VIC_720X576P100_16_9 = 43,
|
||||
HDMI_VIC_1440X576I100_4_3 = 44,
|
||||
HDMI_VIC_1440X576I100_16_9 = 45,
|
||||
HDMI_VIC_1920X1080I120_16_9 = 46,
|
||||
HDMI_VIC_1280X720P120_16_9 = 47,
|
||||
HDMI_VIC_720X480P120_4_3 = 48,
|
||||
HDMI_VIC_720X480P120_16_9 = 49,
|
||||
HDMI_VIC_1440X480I120_4_3 = 50,
|
||||
HDMI_VIC_1440X480I120_16_9 = 51,
|
||||
HDMI_VIC_720X576P200_4_3 = 52,
|
||||
HDMI_VIC_720X576P200_16_9 = 53,
|
||||
HDMI_VIC_1440X576I120_4_3 = 54,
|
||||
HDMI_VIC_1440X576I120_16_9 = 55,
|
||||
HDMI_VIC_720X480P240_4_3 = 56,
|
||||
HDMI_VIC_720X480P240_16_9 = 57,
|
||||
HDMI_VIC_1440X480I240_4_3 = 58,
|
||||
HDMI_VIC_1440X480I240_16_9 = 59,
|
||||
HDMI_VIC_1280X720P24_16_9 = 60,
|
||||
HDMI_VIC_1280X720P25_16_9 = 61,
|
||||
HDMI_VIC_1280X720P30_16_9 = 62,
|
||||
HDMI_VIC_1920X1080P120_16_9 = 63,
|
||||
HDMI_VIC_1920X1080P100_16_9 = 64,
|
||||
HDMI_VIC_1280X720P24_64_27 = 65,
|
||||
HDMI_VIC_1280X720P25_64_27 = 66,
|
||||
HDMI_VIC_1280X720P30_64_27 = 67,
|
||||
HDMI_VIC_1280X720P50_64_27 = 68,
|
||||
HDMI_VIC_1280X720P60_64_27 = 69,
|
||||
HDMI_VIC_1280X720P100_64_27 = 70,
|
||||
HDMI_VIC_1280X720P120_64_27 = 71,
|
||||
HDMI_VIC_1920X1080P24_64_27 = 72,
|
||||
HDMI_VIC_1920X1080P25_64_27 = 73,
|
||||
HDMI_VIC_1920X1080P30_64_27 = 74,
|
||||
HDMI_VIC_1920X1080P50_64_27 = 75,
|
||||
HDMI_VIC_1920X1080P60_64_27 = 76,
|
||||
HDMI_VIC_1920X1080P100_64_27 = 77,
|
||||
HDMI_VIC_1920X1080P120_64_27 = 78,
|
||||
HDMI_VIC_1680X720P24_64_27 = 79,
|
||||
HDMI_VIC_1680X720P25_64_27 = 80,
|
||||
HDMI_VIC_1680X720P30_64_27 = 81,
|
||||
HDMI_VIC_1680X720P50_64_27 = 82,
|
||||
HDMI_VIC_1680X720P60_64_27 = 83,
|
||||
HDMI_VIC_1680X720P100_64_27 = 84,
|
||||
HDMI_VIC_1680X720P120_64_27 = 85,
|
||||
HDMI_VIC_2560X1080P24_64_27 = 86,
|
||||
HDMI_VIC_2560X1080P25_64_27 = 87,
|
||||
HDMI_VIC_2560X1080P30_64_27 = 88,
|
||||
HDMI_VIC_2560X1080P50_64_27 = 89,
|
||||
HDMI_VIC_2560X1080P60_64_27 = 90,
|
||||
HDMI_VIC_2560X1080P100_64_27 = 91,
|
||||
HDMI_VIC_2560X1080P120_64_27 = 92,
|
||||
HDMI_VIC_3840X2160P24_16_9 = 93,
|
||||
HDMI_VIC_3840X2160P25_16_9 = 94,
|
||||
HDMI_VIC_3840X2160P30_16_9 = 95,
|
||||
HDMI_VIC_3840X2160P50_16_9 = 96,
|
||||
HDMI_VIC_3840X2160P60_16_9 = 97,
|
||||
HDMI_VIC_4096X2160P24_256_135 = 98,
|
||||
HDMI_VIC_4096X2160P25_256_135 = 99,
|
||||
HDMI_VIC_4096X2160P30_256_135 = 100,
|
||||
HDMI_VIC_4096X2160P50_256_135 = 101,
|
||||
HDMI_VIC_4096X2160P60_256_135 = 102,
|
||||
HDMI_VIC_3840X2160P24_64_27 = 103,
|
||||
HDMI_VIC_3840X2160P25_64_27 = 104,
|
||||
HDMI_VIC_3840X2160P30_64_27 = 105,
|
||||
HDMI_VIC_3840X2160P50_64_27 = 106,
|
||||
HDMI_VIC_3840X2160P60_64_27 = 107,
|
||||
HDMI_VIC_1280X720P48_16_9 = 108,
|
||||
HDMI_VIC_1280X720P48_64_27 = 109,
|
||||
HDMI_VIC_1680X720P48_64_27 = 110,
|
||||
HDMI_VIC_1920X1080P48_16_9 = 111,
|
||||
HDMI_VIC_1920X1080P48_64_27 = 112,
|
||||
HDMI_VIC_2560X1080P48_64_27 = 113,
|
||||
HDMI_VIC_3840X2160P48_16_9 = 114,
|
||||
HDMI_VIC_4096X2160P48_256_135 = 115,
|
||||
HDMI_VIC_3840X2160P48_64_27 = 116,
|
||||
HDMI_VIC_3840X2160P100_16_9 = 117,
|
||||
HDMI_VIC_3840X2160P120_16_9 = 118,
|
||||
HDMI_VIC_3840X2160P100_64_27 = 119,
|
||||
HDMI_VIC_3840X2160P120_64_27 = 120,
|
||||
HDMI_VIC_5120X2160P24_64_27 = 121,
|
||||
HDMI_VIC_5120X2160P25_64_27 = 122,
|
||||
HDMI_VIC_5120X2160P30_64_27 = 123,
|
||||
HDMI_VIC_5120X2160P48_64_27 = 124,
|
||||
HDMI_VIC_5120X2160P50_64_27 = 125,
|
||||
HDMI_VIC_5120X2160P60_64_27 = 126,
|
||||
HDMI_VIC_5120X2160P100_64_27 = 127,
|
||||
HDMI_VIC_5120X2160P120_64_27 = 193,
|
||||
HDMI_VIC_7680X4320P24_16_9 = 194,
|
||||
HDMI_VIC_7680X4320P25_16_9 = 195,
|
||||
HDMI_VIC_7680X4320P30_16_9 = 196,
|
||||
HDMI_VIC_7680X4320P48_16_9 = 197,
|
||||
HDMI_VIC_7680X4320P50_16_9 = 198,
|
||||
HDMI_VIC_7680X4320P60_16_9 = 199,
|
||||
HDMI_VIC_7680X4320P100_16_9 = 200,
|
||||
HDMI_VIC_7680X4320P120_16_9 = 201,
|
||||
HDMI_VIC_7680X4320P24_64_27 = 202,
|
||||
HDMI_VIC_7680X4320P25_164_27 = 203,
|
||||
HDMI_VIC_7680X4320P30_64_27 = 204,
|
||||
HDMI_VIC_7680X4320P48_64_27 = 205,
|
||||
HDMI_VIC_7680X4320P50_64_27 = 206,
|
||||
HDMI_VIC_7680X4320P60_64_27 = 207,
|
||||
HDMI_VIC_7680X4320P100_64_27 = 208,
|
||||
HDMI_VIC_7680X4320P120_64_27 = 209,
|
||||
HDMI_VIC_10240X4320P24_64_27 = 210,
|
||||
HDMI_VIC_10240X4320P25_64_27 = 211,
|
||||
HDMI_VIC_10240X4320P30_64_27 = 212,
|
||||
HDMI_VIC_10240X4320P48_64_27 = 213,
|
||||
HDMI_VIC_10240X4320P50_64_27 = 214,
|
||||
HDMI_VIC_10240X4320P60_64_27 = 215,
|
||||
HDMI_VIC_10240X4320P100_64_27 = 216,
|
||||
HDMI_VIC_10240X4320P120_64_27 = 217,
|
||||
HDMI_VIC_4096X2160P100_256_135 = 218,
|
||||
HDMI_VIC_4096X2160P120_256_135 = 219,
|
||||
};
|
||||
|
||||
enum HdmiVideoFormatType {
|
||||
HDMI_VIDEO_FORMAT_NULL = 0,
|
||||
HDMI_VIDEO_FORMAT_PROGRESSIVE = 1,
|
||||
HDMI_VIDEO_FORMA_INTERLACE = 2,
|
||||
HDMI_VIDEO_FORMA_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiColorDeep {
|
||||
HDMI_COLOR_DEEP_8BITS = 8,
|
||||
HDMI_COLOR_DEEP_10BITS = 10,
|
||||
HDMI_COLOR_DEEP_12BITS = 12,
|
||||
HDMI_COLOR_DEEP_16BITS = 16,
|
||||
HDMI_COLOR_DEEP_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiPhyModeCfg {
|
||||
HDMI_PHY_MODE_TMDS = 0,
|
||||
HDMI_PHY_MODE_FRL = 1,
|
||||
HDMI_PHY_MODE_TXFFE = 2,
|
||||
HDMI_PHY_MODE_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiHdcpMode {
|
||||
HDMI_HDCP_MODE_AUTO = 0,
|
||||
HDMI_HDCP_MODE_1_4 = 1,
|
||||
HDMI_HDCP_MODE_2_2 = 2,
|
||||
HDMI_HDCP_MODE_BUTT
|
||||
};
|
||||
|
||||
struct HdmiVideoDefInfo {
|
||||
enum HdmiVic vic;
|
||||
uint32_t pixclk;
|
||||
uint32_t rate;
|
||||
uint32_t hactive;
|
||||
uint32_t vactive;
|
||||
uint32_t hblank;
|
||||
uint32_t vblank;
|
||||
uint32_t hfront;
|
||||
uint32_t hsync;
|
||||
uint32_t hback;
|
||||
uint32_t vfront;
|
||||
uint32_t vsync;
|
||||
uint32_t vback;
|
||||
enum HdmiPictureAspectRatio aspect;
|
||||
enum HdmiVideoTiming timing;
|
||||
enum HdmiVideoFormatType formatType;
|
||||
};
|
||||
|
||||
/* see hdmi spec2.0 table 10-2. */
|
||||
enum Hdmi4kVic {
|
||||
HDMI_4K_VIC_3840X2160_30 = 1,
|
||||
HDMI_4K_VIC_3840X2160_25,
|
||||
HDMI_4K_VIC_3840X2160_24,
|
||||
HDMI_4K_VIC_4096X2160_24
|
||||
};
|
||||
|
||||
struct HdmiVideo4kInfo {
|
||||
enum Hdmi4kVic _4kVic;
|
||||
enum HdmiVic vic;
|
||||
uint32_t pixclk;
|
||||
uint32_t rate;
|
||||
uint32_t hactive;
|
||||
uint32_t vactive;
|
||||
enum HdmiPictureAspectRatio aspect;
|
||||
enum HdmiVideoTiming timing;
|
||||
enum HdmiVideoFormatType formatType;
|
||||
};
|
||||
|
||||
struct HdmiCommonStatus {
|
||||
bool hotplug;
|
||||
bool avmute;
|
||||
bool sinkPowerOn;
|
||||
enum HdmiTmdsModeType tmdsMode;
|
||||
};
|
||||
|
||||
struct HdmiAudioStatus {
|
||||
bool mute;
|
||||
bool enable;
|
||||
bool downSample;
|
||||
enum HdmiSampleRate sampleRate;
|
||||
enum HdmiAudioInterfaceType interface;
|
||||
enum HdmiAudioBitDepth bitDepth;
|
||||
enum HdmiAudioFormatChannel channel;
|
||||
uint32_t refN;
|
||||
uint32_t regN;
|
||||
uint32_t refCts;
|
||||
uint32_t regCts;
|
||||
};
|
||||
|
||||
struct HdmiVideoStatus {
|
||||
bool mute;
|
||||
bool ycbcr2Rgb;
|
||||
bool rgb2Ycbcr;
|
||||
bool ycbcr444422;
|
||||
bool ycbcr422420;
|
||||
bool ycbcr420422;
|
||||
bool ycbcr422444;
|
||||
bool in420Ydemux;
|
||||
bool out420Ydemux;
|
||||
bool vSyncPol;
|
||||
bool hSyncPol;
|
||||
bool syncPol;
|
||||
bool dePol;
|
||||
bool swapHsCs;
|
||||
enum HdmiColorSpace inColorSpace;
|
||||
enum HdmiColorSpace outColorSpace;
|
||||
enum HdmiVideoBitDepth outBitDepth;
|
||||
enum HdmiQuantizationRange quantization;
|
||||
};
|
||||
|
||||
struct HdmiCommonAttr {
|
||||
bool enableHdmi;
|
||||
bool enableVideo;
|
||||
bool enableAudio;
|
||||
bool xvyccMode;
|
||||
bool avi;
|
||||
bool spd;
|
||||
bool mpeg;
|
||||
bool audio;
|
||||
bool drm;
|
||||
bool hdcpEnable;
|
||||
bool vsifDolby;
|
||||
enum HdmiColorSpace colorSpace;
|
||||
enum HdmiQuantizationRange quantization;
|
||||
enum HdmiDeepColor deepColor;
|
||||
enum HdmiHdcpMode hdcpMode;
|
||||
};
|
||||
|
||||
enum HdmiVideoBitDepth HdmiCommonDeepClolorConvertToColorDepth(enum HdmiDeepColor deepColor);
|
||||
enum HdmiDeepColor HdmiCommonColorDepthConvertToDeepClolor(enum HdmiVideoBitDepth colorDepth);
|
||||
enum HdmiVic HdmiCommonGetVic(enum HdmiVideoTiming timing,
|
||||
enum HdmiPictureAspectRatio aspect, bool enable3d);
|
||||
struct HdmiVideoDefInfo *HdmiCommonGetVideoDefInfo(enum HdmiVideoTiming timing,
|
||||
enum HdmiPictureAspectRatio aspect, bool enable3d);
|
||||
struct HdmiVideo4kInfo *HdmiCommonGetVideo4kInfo(uint32_t _4kVic);
|
||||
enum HdmiVideoTiming HdmiCommonGetVideoTiming(enum HdmiVic vic, enum HdmiPictureAspectRatio aspect);
|
||||
enum HdmiVideoTiming HdmiCommonGetVideo4kTiming(uint32_t _4kVic);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_COMMON_H */
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_CORE_H
|
||||
#define HDMI_CORE_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "hdf_device_desc.h"
|
||||
#include "hdmi_cec.h"
|
||||
#include "hdmi_common.h"
|
||||
#include "hdmi_ddc.h"
|
||||
#include "hdmi_edid.h"
|
||||
#include "hdmi_event.h"
|
||||
#include "hdmi_frl.h"
|
||||
#include "hdmi_hdcp.h"
|
||||
#include "hdmi_hdr.h"
|
||||
#include "hdmi_if.h"
|
||||
#include "hdmi_infoframe.h"
|
||||
#include "hdmi_scdc.h"
|
||||
#include "osal_mutex.h"
|
||||
#include "platform_core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define HDMI_ONE_BYTE_MARK 0xFF
|
||||
#define HDMI_ONE_BYTE_SHIFT 8
|
||||
#define HDMI_TWO_BYTES_SHIFT 16
|
||||
|
||||
struct HdmiPhyCfg {
|
||||
uint32_t pixelClk;
|
||||
uint32_t tmdsClk; /* TMDS colck, KHz */
|
||||
enum HdmiDeepColor deepColor; /* deep color(color depth) */
|
||||
enum HdmiPhyModeCfg modeCfg; /* TMDS/FRL/tx_ffe */
|
||||
enum HdmiColorSpace colorSpace;
|
||||
enum HdmiFrlWorkMode rate; /* lane and rate */
|
||||
enum HdmiFrlTxffeMode txffe[4]; /* tx_ffe */
|
||||
};
|
||||
|
||||
struct HdmiTmdsConfig {
|
||||
uint32_t pixelClk;
|
||||
uint32_t tmdsClk;
|
||||
enum HdmiPhyModeCfg mode;
|
||||
enum HdmiDeepColor deepColor;
|
||||
};
|
||||
|
||||
struct HdmiCntlr;
|
||||
|
||||
union HdmiCap {
|
||||
uint32_t data;
|
||||
struct CapBitsData {
|
||||
uint32_t scdc : 1; /* bit0: support scdc */
|
||||
uint32_t frl : 1; /* bit1: support frl */
|
||||
uint32_t hdr : 1; /* bit2: support hdr */
|
||||
uint32_t hdcp: 1; /* bit3: support hdcp */
|
||||
uint32_t cec : 1; /* bit4: support cec */
|
||||
uint32_t hdmi14 : 1; /* bit5: support hdmi1.4 spec */
|
||||
uint32_t hdmi20 : 1; /* bit6: support hdmi2.0 spec */
|
||||
uint32_t hdmi21 : 1; /* bit7: support hdmi2.1 spec */
|
||||
uint32_t hdcp14 : 1; /* bit8: support hdcp1.4 spec */
|
||||
uint32_t hdcp22 : 1; /* bit9: support hdcp2.2 spec */
|
||||
uint32_t rgb444 : 1; /* bit10: support rgb444 */
|
||||
uint32_t ycbcr444 : 1; /* bit11: support ycbcr444 */
|
||||
uint32_t ycbcr422 : 1; /* bit12: support ycbcr422 */
|
||||
uint32_t ycbcr420 : 1; /* bit13: support ycbcr420 */
|
||||
uint32_t deepColor10bits: 1; /* bit14: support deep color 10 bits */
|
||||
uint32_t deepColor12bits: 1; /* bit15: support deep color 12 bits */
|
||||
uint32_t deepColor16bits: 1; /* bit16: support deep color 16 bits */
|
||||
uint32_t scramble : 1; /* bit17: support scramble */
|
||||
uint32_t cecRc : 1; /* bit18: support CEC Remote Control */
|
||||
uint32_t rev : 13; /* bit21~31: reserved */
|
||||
} bits;
|
||||
};
|
||||
|
||||
enum HdmiCapMark {
|
||||
HDMI_CAP_SCDC_MARK = (1 << 0),
|
||||
HDMI_CAP_FRL_MARK = (1 << 1),
|
||||
HDMI_CAP_HDR_MARK = (1 << 2),
|
||||
HDMI_CAP_HDCP_MARK = (1 << 3),
|
||||
HDMI_CAP_CEC_MARK = (1 << 4),
|
||||
HDMI_CAP_HDMI14_MARK = (1 << 5),
|
||||
HDMI_CAP_HDMI20_MARK = (1 << 6),
|
||||
HDMI_CAP_HDMI21_MARK = (1 << 7),
|
||||
HDMI_CAP_HDCP14_MARK = (1 << 8),
|
||||
HDMI_CAP_HDCP22_MARK = (1 << 9),
|
||||
HDMI_CAP_RGB444_MARK = (1 << 10),
|
||||
HDMI_CAP_YCBCR444_MARK = (1 << 11),
|
||||
HDMI_CAP_YCBCR422_MARK = (1 << 12),
|
||||
HDMI_CAP_YCBCR420_MARK = (1 << 13),
|
||||
HDMI_CAP_DEEP_COLOR_10BITES_MARK = (1 << 14),
|
||||
HDMI_CAP_DEEP_COLOR_12BITES_MARK = (1 << 15),
|
||||
HDMI_CAP_DEEP_COLOR_16BITES_MARK = (1 << 16),
|
||||
HDMI_CAP_SCRAMBLE_MARK = (1 << 17),
|
||||
};
|
||||
|
||||
struct HdmiCntlrCap {
|
||||
union HdmiCap baseCap;
|
||||
uint32_t maxTmdsClock;
|
||||
uint32_t defTmdsClock; /* unit: MHz */
|
||||
uint32_t maxFrlRate;
|
||||
uint32_t videoTiming;
|
||||
uint32_t quantization;
|
||||
uint32_t colorSpace;
|
||||
uint32_t colorimetry;
|
||||
uint32_t audioIfType;
|
||||
uint32_t audioBitDepth;
|
||||
uint32_t audioSampleRate;
|
||||
uint32_t audioChannels;
|
||||
uint32_t hdrColorimetry;
|
||||
uint32_t hdrUserMode;
|
||||
};
|
||||
|
||||
struct HdmiHardwareStatus {
|
||||
struct HdmiCommonStatus commonStatus;
|
||||
struct HdmiAudioStatus audioStatus;
|
||||
struct HdmiVideoStatus videoStatus;
|
||||
struct HdmiInfoframeStatus infoframeStatus;
|
||||
struct HdmiHdcpStatus hdcpstatus;
|
||||
};
|
||||
|
||||
struct HdmiAudioConfigInfo {
|
||||
bool enable;
|
||||
bool downSample;
|
||||
uint32_t tmdsClock;
|
||||
uint32_t pixelRepeat;
|
||||
enum HdmiAudioInterfaceType ifType;
|
||||
enum HdmiAudioBitDepth bitDepth;
|
||||
enum HdmiSampleRate sampleRate;
|
||||
enum HdmiAudioFormatChannel channels;
|
||||
};
|
||||
|
||||
struct HdmiCntlrOps {
|
||||
void (*hardWareInit)(struct HdmiCntlr *cntlr);
|
||||
void (*hardWareStatusGet)(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *status);
|
||||
void (*controllerReset)(struct HdmiCntlr *cntlr);
|
||||
bool (*hotPlugStateGet)(struct HdmiCntlr *cntlr);
|
||||
bool (*hotPlugInterruptStateGet)(struct HdmiCntlr *cntlr);
|
||||
void (*lowPowerSet)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*tmdsModeSet)(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode);
|
||||
int32_t (*tmdsConfigSet)(struct HdmiCntlr *cntlr, struct HdmiTmdsConfig mode);
|
||||
void (*infoframeEnable)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoframeType, bool enable);
|
||||
int32_t (*infoframeSend)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoframeType, uint8_t *data, uint32_t len);
|
||||
int32_t (*infoframeDataSet)(struct HdmiCntlr *cntlr, uint32_t type, uint8_t *data, uint32_t len);
|
||||
int32_t (*cecMsgSend)(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg);
|
||||
void (*audioPathEnable)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*audioPathSet)(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config);
|
||||
void (*phyOutputEnable)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*phyOutputSet)(struct HdmiCntlr *cntlr, struct HdmiPhyCfg *cfg);
|
||||
void (*blackDataSet)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*videoMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*videoPathSet)(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
|
||||
void (*audioMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*avmuteSet)(struct HdmiCntlr *cntlr, bool enable);
|
||||
int32_t (*ddcTransfer)(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg);
|
||||
bool (*scdcSourceScrambleGet)(struct HdmiCntlr *cntlr);
|
||||
int32_t (*scdcSourceScrambleSet)(struct HdmiCntlr *cntlr, bool enable);
|
||||
void (*frlSet)(struct HdmiCntlr *cntlr);
|
||||
int32_t (*frlEnable)(struct HdmiCntlr *cntlr, bool enable);
|
||||
int32_t (*audioNctsSet)(struct HdmiCntlr *cntlr, struct HdmiFrlAudioNctsConfig *cfg);
|
||||
void (*frlTrainingConfigSet)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainConfig *cfg);
|
||||
void (*frlTrainingStart)(struct HdmiCntlr *cntlr);
|
||||
void (*frlGetTriningRslt)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainRslt *rslt);
|
||||
void (*hdcpRegInit)(struct HdmiCntlr *cntlr);
|
||||
int32_t (*hdcpGenerateAksvAndAn)(struct HdmiCntlr *cntlr);
|
||||
int32_t (*hdcpOptReg)(struct HdmiCntlr *cntlr, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len);
|
||||
void (*hdrTimerSet)(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config);
|
||||
};
|
||||
|
||||
enum HdmiCntlrState {
|
||||
HDMI_CNTLR_STATE_NONE = 0,
|
||||
HDMI_CNTLR_STATE_OPEN = (1 << 0),
|
||||
HDMI_CNTLR_STATE_START = (1 << 1),
|
||||
HDMI_CNTLR_STATE_STOP = (1 << 2),
|
||||
HDMI_CNTLR_STATE_CLOSE = (1 << 3),
|
||||
};
|
||||
|
||||
struct HdmiDevice {
|
||||
struct HdmiEdid edid; /* device cap */
|
||||
struct HdmiCntlr *cntlr;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct HdmiAttr {
|
||||
struct HdmiCommonAttr commAttr;
|
||||
struct HdmiAudioAttr audioAttr;
|
||||
struct HdmiVideoAttr videoAttr;
|
||||
struct HdmiHdrAttr hdrAttr;
|
||||
};
|
||||
|
||||
struct HdmiCntlr {
|
||||
struct IDeviceIoService service;
|
||||
struct HdfDeviceObject *hdfDevObj;
|
||||
struct PlatformDevice device;
|
||||
struct OsalMutex mutex;
|
||||
struct PlatformQueue *msgQueue;
|
||||
struct HdmiCntlrCap cap;
|
||||
struct HdmiAttr attr;
|
||||
struct HdmiCntlrOps *ops;
|
||||
uint32_t deviceIndex;
|
||||
uint32_t state; /* cntlr state. */
|
||||
enum HdmiTmdsModeType tmdsMode;
|
||||
struct HdmiDevice *hdmi;
|
||||
struct HdmiInfoframe infoframe;
|
||||
struct HdmiScdc *scdc;
|
||||
struct HdmiDdc ddc;
|
||||
struct HdmiFrl *frl;
|
||||
struct HdmiHdcp *hdcp;
|
||||
struct HdmiCec *cec;
|
||||
struct HdmiEvent event;
|
||||
struct HdmiHdr *hdr;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
static inline void HdmiCntlrLock(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (cntlr != NULL) {
|
||||
(void)OsalMutexLock(&cntlr->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrUnlock(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (cntlr != NULL) {
|
||||
(void)OsalMutexUnlock(&cntlr->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct HdmiCntlr *HdmiCntlrGetByBusNum(uint16_t num)
|
||||
{
|
||||
struct PlatformDevice *device = PlatformManagerGetDeviceByMagic(PlatformManagerGet(PLATFORM_MODULE_HDMI), num);
|
||||
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return CONTAINER_OF(device, struct HdmiCntlr, device);
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrLowPowerSet(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->lowPowerSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->lowPowerSet(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrHardWareInit(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->hardWareInit != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->hardWareInit(cntlr);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrAudioPathEnable(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->audioPathEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->audioPathEnable(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrAudioPathSet(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->audioPathSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->audioPathSet(cntlr, config);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrAudioMuteEnable(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->audioMuteEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->audioMuteEnable(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrVideoPathSet(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->videoPathSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->videoPathSet(cntlr, attr);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrTmdsModeSet(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->tmdsModeSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->tmdsModeSet(cntlr, mode);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrReset(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->controllerReset != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->controllerReset(cntlr);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrBlackDataSet(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->blackDataSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->blackDataSet(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrPhyOutputEnablet(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->phyOutputEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputEnable(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrHdrTimerSet(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->hdrTimerSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->hdrTimerSet(cntlr, config);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HdmiCntlrAvmuteSet(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
if (cntlr->ops != NULL && cntlr->ops->avmuteSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->avmuteSet(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HdmiCntlrParse(struct HdmiCntlr *cntlr, struct HdfDeviceObject *obj);
|
||||
int32_t HdmiCntlrAdd(struct HdmiCntlr *cntlr);
|
||||
void HdmiCntlrRemove(struct HdmiCntlr *cntlr);
|
||||
|
||||
int32_t HdmiCntlrOpen(struct HdmiCntlr *cntlr);
|
||||
int32_t HdmiCntlrGetSinkEdid(struct HdmiCntlr *cntlr, uint8_t *buffer, uint32_t len);
|
||||
int32_t HdmiCntlrStart(struct HdmiCntlr *cntlr);
|
||||
int32_t HdmiCntlrStop(struct HdmiCntlr *cntlr);
|
||||
int32_t HdmiCntlrDeepColorSet(struct HdmiCntlr *cntlr, enum HdmiDeepColor color);
|
||||
int32_t HdmiCntlrDeepColorGet(struct HdmiCntlr *cntlr, enum HdmiDeepColor *color);
|
||||
int32_t HdmiCntlrSetVideoAttribute(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
|
||||
int32_t HdmiCntlrSetAudioAttribute(struct HdmiCntlr *cntlr, struct HdmiAudioAttr *attr);
|
||||
int32_t HdmiCntlrSetHdrAttribute(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *attr);
|
||||
int32_t HdmiCntlrInfoframeGet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoframeInfo *frame);
|
||||
int32_t HdmiCntlrInfoframeSet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoframeInfo *frame);
|
||||
void HdmiCntlrClose(struct HdmiCntlr *cntlr);
|
||||
|
||||
bool HdmiHpdStatusDelayGet(struct HdmiCntlr *cntlr);
|
||||
bool HdmiHpdStatusGet(struct HdmiCntlr *cntlr);
|
||||
int32_t HdmiEventHandle(struct HdmiCntlr *cntlr, enum HdmiEventType event, void *datat);
|
||||
int32_t HdmiEventMsgHandleDefault(struct PlatformQueue *queue, struct PlatformMsg *msg);
|
||||
|
||||
bool HdmiEdidSupportFrl(struct HdmiDevice *hdmi);
|
||||
uint8_t HdmiEdidGetMaxFrlRate(struct HdmiDevice *hdmi);
|
||||
bool HdmiEdidScdcSupport(struct HdmiDevice *hdmi);
|
||||
int32_t HdmiCntlrAllocDev(struct HdmiCntlr *cntlr);
|
||||
void HdmiCntlrFreeDev(struct HdmiCntlr *cntlr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_CORE_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_DDC_H
|
||||
#define HDMI_DDC_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "osal_mutex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* DDC(Display Data Channel)
|
||||
* The DDC channel is used by an HDMI Source to determine the capabilities and characteristics of
|
||||
* the Sink by reading the E-EDID data structure.
|
||||
* The DDC is also uesd to exchange point-to-point dynamic data between the Source and the Sink
|
||||
* using a new DDC address for the HDMI Status and Control Data Channel(SCDC).
|
||||
* In addition, The DDC is also uesd for HDCP to exchange key selection vector and other information.
|
||||
*/
|
||||
#define HDMI_DDC_EDID_DEV_ADDRESS 0xA0
|
||||
#define HDMI_DDC_SCDC_DEV_ADDRESS 0xA8
|
||||
#define HDMI_DDC_HDCP_DEV_ADDRESS 0x74
|
||||
|
||||
enum HdmiDdcDeviceType {
|
||||
HDMI_DDC_DEV_EDID = 0,
|
||||
HDMI_DDC_DEV_SCDC = 1,
|
||||
HDMI_DDC_DEV_HDCP = 2,
|
||||
HDMI_DDC_DEV_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiDdcMode {
|
||||
HDMI_DDC_MODE_READ_SINGLE_NO_ACK = 0,
|
||||
HDMI_DDC_MODE_READ_SINGLE_ACK = 1,
|
||||
HDMI_DDC_MODE_READ_MUTIL_NO_ACK = 2,
|
||||
HDMI_DDC_MODE_READ_MUTIL_ACK = 3,
|
||||
HDMI_DDC_MODE_READ_SEGMENT_NO_ACK = 4,
|
||||
HDMI_DDC_MODE_READ_SEGMENT_ACK = 5,
|
||||
HDMI_DDC_MODE_WRITE_MUTIL_NO_ACK = 6,
|
||||
HDMI_DDC_MODE_WRITE_MUTIL_ACK = 7,
|
||||
HDMI_DDC_MODE_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiDdcCfg {
|
||||
enum HdmiDdcDeviceType type;
|
||||
enum HdmiDdcMode mode;
|
||||
bool readFlag;
|
||||
uint32_t devAddr;
|
||||
uint8_t offset;
|
||||
uint8_t segment; /* see VESA spec. 1 segment is 256 bytes. */
|
||||
uint32_t dataLen;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
struct HdmiDdc {
|
||||
struct OsalMutex ddcMutex;
|
||||
bool init;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
int32_t HdmiDdcTransfer(struct HdmiDdc *ddc, struct HdmiDdcCfg *cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_DDC_H */
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_DFM_H
|
||||
#define HDMI_DFM_H
|
||||
|
||||
#include "hdmi_if.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* DFM(Data Flow Metering).
|
||||
* During data transmission in FRL mode, there is a lot of bandwidth redundancy (blanking period) or slight bandwidth
|
||||
* insufficiency (active video). In order for the link to tolerate these fluctuations, source and sink need to use
|
||||
* buffers. To limit the size of the buffer required, the protocol adds the Data Flow Metering requirement.
|
||||
*/
|
||||
#define HDMI_DFM_FRL_CHAR_NUM_PER_CB 502
|
||||
#define HDMI_DFM_RS_NUM_PER_CB 8
|
||||
/* A FRL Character Block(CB) contains 502 FRL Characters and 8 RS check characters. */
|
||||
#define HDMI_DFM_CHAR_NUM_PER_CB (HDMI_DFM_FRL_CHAR_NUM_PER_CB + HDMI_DFM_RS_NUM_PER_CB)
|
||||
|
||||
/*
|
||||
* A FRL Super Block(SB) contains four FRL Character Blocks.
|
||||
* Each FRL Super Block is preceded by a group of three or four Start Super Blocks (SSB) or a group of three or
|
||||
* four Scrambler Reset (SR) characters.
|
||||
*/
|
||||
#define HDMI_DFM_FRL_CB_NUM_PER_SB 4
|
||||
#define HDMI_DFM_FRL_SB_LEN(lane) (HDMI_DFM_FRL_CB_NUM_PER_SB * HDMI_DFM_CHAR_NUM_PER_CB + lane)
|
||||
|
||||
#define HDMI_DFM_FRL_PIXELCLK_TOLERANCE 5 /* 0.50% */
|
||||
#define HDMI_DFM_FRL_BITRATE_TOLERANCE 3 /* 300 */
|
||||
#define HDMI_DFM_FRL_AUDIOCLK_TOLERANCE 1
|
||||
#define HDMI_DFM_MAGNIFICATION_8 8
|
||||
#define HDMI_DFM_FRL_MAX_TB_BORROW 400
|
||||
#define HDMI_DFM_RATE_MAGNIFICATION 100000
|
||||
#define HDMI_DFM_OVERHEAD_SIZE 300
|
||||
|
||||
#define HDMI_AUDIO_CHANNEL_ALLOC_TYPE1 1
|
||||
#define HDMI_AUDIO_CHANNEL_ALLOC_TYPE2 2
|
||||
#define HDMI_AUDIO_CHANNEL_ALLOC_TYPE3 3
|
||||
|
||||
/*
|
||||
* Packets per sample.
|
||||
* This is the number of audio packets required to carry each sample.
|
||||
* x100.
|
||||
*/
|
||||
#define HDMI_AUDIO_AP_SIZE_25 25
|
||||
#define HDMI_AUDIO_AP_SIZE_100 100
|
||||
#define HDMI_AUDIO_AP_SIZE_200 200
|
||||
#define HDMI_AUDIO_AP_SIZE_300 300
|
||||
#define HDMI_AUDIO_AP_SIZE_400 400
|
||||
|
||||
enum HdmiAudioPacketType {
|
||||
HDMI_AUDIO_SAMPLE_PACKET = 0x02,
|
||||
HDMI_ONE_BIT_AUDIO_SAMPLE_PACKET = 0x07,
|
||||
HDMI_DTS_AUDIO_PACKET = 0x08,
|
||||
HDMI_HBR_AUDIO_PACKET = 0x09,
|
||||
HDMI_AUDIO_3D_SAMPLE_PACKET = 0x0B,
|
||||
HDMI_ONE_BIT_AUDIO_3D_SAMPLE_PACKET = 0x0C,
|
||||
HDMI_MULTI_STREAM_AUDIO_SAMPLE_PACKET = 0x0E,
|
||||
HDMI_ONE_BIT_MULTI_STREAM_AUDIO_SAMPLE_PACKET = 0x0F,
|
||||
};
|
||||
|
||||
enum HdmiDfmPixelFormatMode {
|
||||
HDMI_DFM_PIXEL_FORMAT_MODE_0 = 0,
|
||||
HDMI_DFM_PIXEL_FORMAT_MODE_1,
|
||||
HDMI_DFM_PIXEL_FORMAT_MODE_2,
|
||||
HDMI_DFM_PIXEL_FORMAT_MODE_3
|
||||
};
|
||||
|
||||
struct HdmiDfmInfo {
|
||||
bool audioSupport;
|
||||
bool videoSupport;
|
||||
bool uncompressSupport;
|
||||
bool isExtraMode;
|
||||
bool canbeTrans;
|
||||
uint32_t htotal;
|
||||
uint32_t vtotal;
|
||||
uint32_t bpp; /* Bits per Pixel */
|
||||
uint32_t cFrlSb; /* Total FRL Characters Per SuperBlock(include SSB/SR) */
|
||||
uint32_t overheadSb;
|
||||
uint32_t overheadRs;
|
||||
uint32_t overheadMap;
|
||||
uint32_t overheadMin;
|
||||
uint32_t overheadMax;
|
||||
uint32_t lineMinTime; /* minimum Video Line period */
|
||||
uint32_t lineMaxTime; /* maximum Video Line period */
|
||||
uint32_t audioAp; /* the number of audio packets required to carry each sample */
|
||||
uint32_t audioRap; /* Average Audio Related Packet Rate */
|
||||
uint32_t avgAudioPacketsPerLine; /* Average Required Packets per line */
|
||||
uint32_t audioPacketsLine; /* Packets per Hblank that must be supportable. */
|
||||
uint32_t hblankAudioMin; /* */
|
||||
uint32_t cFrlFree;
|
||||
uint32_t cFrlRcMargin;
|
||||
uint32_t cFrlRcSavings;
|
||||
uint32_t activeBytesPerLine; /* Video Bytes per line */
|
||||
uint32_t activeTbPerLine; /* Required Characters to carry Active Video per line */
|
||||
uint32_t hblankTbPerLine; /* Required Characters to carry H-Blank Video per line */
|
||||
uint32_t activeTimeRef;
|
||||
uint32_t blankTimeRef;
|
||||
uint32_t activeTimeMin;
|
||||
uint32_t blankTimeMin;
|
||||
int32_t tBorrow;
|
||||
int32_t tbBorrow;
|
||||
uint32_t cFrlActualPayload;
|
||||
uint32_t utilization;
|
||||
int32_t margin;
|
||||
uint32_t avgTbRate;
|
||||
uint64_t pixelClk;
|
||||
uint64_t maxPixelClk; /* maximum legal pixel rate */
|
||||
uint64_t minPixelClk; /* minimum legal pixel rate */
|
||||
uint64_t maxBitRate; /* FRL max bit rate */
|
||||
uint64_t minBitRate; /* FRL min bit rate */
|
||||
uint64_t maxFrlCharRate; /* max FRL Character Rate */
|
||||
uint64_t minFrlCharRate; /* min FRL Character Rate */
|
||||
uint32_t maxFrlCharsPerLine; /* max FRL Characters per line Period */
|
||||
uint32_t minFrlCharsPerLine; /* min FRL Characters per line Period */
|
||||
};
|
||||
|
||||
struct HdmiDfmParam {
|
||||
uint32_t hactive;
|
||||
uint32_t vactive;
|
||||
uint32_t hblank;
|
||||
uint32_t vblank;
|
||||
uint32_t hsync;
|
||||
uint32_t hback;
|
||||
uint32_t hfront;
|
||||
uint32_t vsync;
|
||||
uint32_t vback;
|
||||
uint32_t vfront;
|
||||
uint32_t vfreq;
|
||||
uint32_t colorDepth;
|
||||
uint32_t pixelFormat; /* 1:420, 2:422, 3:RGB444 */
|
||||
uint32_t laneNum;
|
||||
uint32_t bitRate;
|
||||
uint32_t audioRate;
|
||||
uint32_t packetType;
|
||||
uint32_t layout;
|
||||
uint32_t acat;
|
||||
};
|
||||
|
||||
uint32_t HdmiDfmGetPixelFormat(enum HdmiColorSpace colorSpace);
|
||||
void HdmiDfmFillParam(struct HdmiDfmParam *param, struct HdmiVideoDefInfo *videoInfo,
|
||||
struct HdmiAudioAttr *audioAttr, enum HdmiColorSpace colorSpace, enum HdmiDeepColor deepColor);
|
||||
bool HdmiDfmFormatSupport(struct HdmiDfmParam *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_DFM_H */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_DISPATCH_H
|
||||
#define HDMI_DISPATCH_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
|
||||
#ifndef __USER__
|
||||
#include "devsvc_manager_clnt.h"
|
||||
#endif
|
||||
|
||||
#ifdef __USER__
|
||||
#include "hdf_io_service_if.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef __USER__
|
||||
int32_t HdmiIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_NCTS_H */
|
||||
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_EDID_H
|
||||
#define HDMI_EDID_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "hdmi_ddc.h"
|
||||
#include "hdmi_if.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* (EDID)Extended Display Identification Data */
|
||||
#define HDMI_EDID_SINGLE_BLOCK_SIZE 128
|
||||
#define HDMI_EDID_MAX_BLOCK_NUM 4
|
||||
#define HDMI_EDID_TOTAL_SIZE (HDMI_EDID_SINGLE_BLOCK_SIZE * HDMI_EDID_MAX_BLOCK_NUM)
|
||||
#define HDMI_EDID_MAX_VIC_COUNT 128
|
||||
|
||||
#define HDMI_EDID_BIT0_MARK 0x01
|
||||
#define HDMI_EDID_BIT1_MARK 0x02
|
||||
#define HDMI_EDID_BIT2_MARK 0x04
|
||||
#define HDMI_EDID_BIT3_MARK 0x08
|
||||
#define HDMI_EDID_BIT4_MARK 0x10
|
||||
#define HDMI_EDID_BIT5_MARK 0x20
|
||||
#define HDMI_EDID_BIT6_MARK 0x40
|
||||
#define HDMI_EDID_BIT7_MARK 0x80
|
||||
#define HDMI_EDID_UPPER_NIBBLE_MARK 0xf0
|
||||
#define HDMI_EDID_LOWER_NIBBLE_MARK 0x0f
|
||||
#define HDMI_EDID_BITS_OF_ONE_BYTE 8
|
||||
#define HDMI_EDID_ONE_BYTE_SHIFT 8
|
||||
#define HDMI_EDID_6_BITS_SHIFT 6
|
||||
#define HDMI_EDID_NIBBLE_SHIFT 4
|
||||
#define HDMI_EDID_2_BITS_SHIFT 2
|
||||
|
||||
#define HDMI_EDID_CHECK_SUM_MARK 0xff
|
||||
|
||||
/* edid header */
|
||||
#define HDMI_EDID_BLOCK_HEADER_FIELD_LEN 8
|
||||
|
||||
/* edid vendor/product info */
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_FIELD_LEN 2
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_MAX_LEN 4
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_CHAR_MARK 0x1F /* 5 bits */
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_CHAR_SHIFT 5
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_LOW_INVALID 0
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_HIGH_INVALID 27
|
||||
#define HDMI_EDID_MANUFACRURER_NAME_SHIFT 8
|
||||
#define HDMI_EDID_PRODUCT_CODE_FIELD_LEN 2
|
||||
#define HDMI_EDID_PRODUCT_CODE_SHIFT 8
|
||||
#define HDMI_EDID_SERIAL_NUMBER_FIELD_LEN 4
|
||||
#define HDMI_EDID_SERIAL_NUMBER_SHIFT 8
|
||||
#define HDMI_EDID_WEEK_LOW_VALID 1
|
||||
#define HDMI_EDID_WEEK_HIGH_VALID 53
|
||||
#define HDMI_EDID_YEAR_VALID 0xFF
|
||||
#define HDMI_EDID_YEAR_BASE 1990
|
||||
|
||||
struct HdmiEdidVendorInfo {
|
||||
char mfrName[HDMI_EDID_MANUFACRURER_NAME_MAX_LEN];
|
||||
uint16_t productCode;
|
||||
uint32_t serialNumber;
|
||||
uint8_t week;
|
||||
uint8_t year;
|
||||
};
|
||||
|
||||
#define HDMI_EDID_VERSION_NUM 1
|
||||
#define HDMI_EDID_REVISION_NUM 3
|
||||
|
||||
/* edid version info */
|
||||
struct HdmiEdidVersionInfo {
|
||||
uint8_t version;
|
||||
uint8_t revision;
|
||||
};
|
||||
|
||||
/* edid basic display parameters and features */
|
||||
struct HdmiEdidBasicDispParamInfo {
|
||||
uint8_t width; /* unit: cm */
|
||||
uint8_t height; /* unit: cm */
|
||||
};
|
||||
|
||||
/* edid color characteristics */
|
||||
#define HDMI_EDID_COLOR_LOW_BITS_MARK 0x03
|
||||
#define HDMI_EDID_COLOR_RED_X_LOW_OFFSET 6
|
||||
#define HDMI_EDID_COLOR_RED_Y_LOW_OFFSET 4
|
||||
#define HDMI_EDID_COLOR_GREEN_X_LOW_OFFSET 2
|
||||
#define HDMI_EDID_COLOR_BLUE_X_LOW_OFFSET 6
|
||||
#define HDMI_EDID_COLOR_BLUE_Y_LOW_OFFSET 4
|
||||
#define HDMI_EDID_COLOR_WHITE_X_LOW_OFFSET 2
|
||||
#define HDMI_EDID_COLOR_HIGH_OFFSET 2
|
||||
|
||||
struct HdmiEdidColorInfo {
|
||||
uint16_t redX;
|
||||
uint16_t redY;
|
||||
uint16_t greenX;
|
||||
uint16_t greenY;
|
||||
uint16_t blueX;
|
||||
uint16_t blueY;
|
||||
uint16_t whiteX;
|
||||
uint16_t whiteY;
|
||||
};
|
||||
|
||||
/* edid established timings */
|
||||
#define HDMI_EDID_ESTABLISHED_TIMINGS_FIELD_LEN 3
|
||||
|
||||
enum HdmiEdidEstablishTiming {
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_60 = 0,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_56 = 1,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_640X480_75 = 2,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_640X480_72 = 3,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_640X480_67 = 4,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VGA_640X480_60 = 5,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_XGA_720X400_88 = 6,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VGA_720X400_70 = 7,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_1280X1024_75 = 8,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_1024X768_75 = 9,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_1024X768_70 = 10,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_1024X768_60 = 11,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_1024X768_87 = 12,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_832X624_75 = 13,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_75 = 14,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_800X600_72 = 15,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_VESA_1152X870_75 = 16,
|
||||
HDMI_EDID_ESTABLISHED_TIMING_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiEdidEstablishedTimingsInfo {
|
||||
uint32_t estTimingsNum;
|
||||
uint32_t estTimings[HDMI_EDID_ESTABLISHED_TIMING_BUTT];
|
||||
};
|
||||
|
||||
/* edid standard timing */
|
||||
#define HDMI_EDID_STANDARD_TIMING_FIELD_LEN 16
|
||||
#define HDMI_EDID_STANDARD_TIMING_COUNT 8
|
||||
#define HDMI_EDID_PER_STANDARD_TIMING_BYTE_NUM 2
|
||||
#define HDMI_EDID_STANDARD_TIMING_UNUSED_FLAG 0x01
|
||||
#define HDMI_EDID_STANDARD_TIMING_HORIZ_PIXEL_BASE 31
|
||||
#define HDMI_EDID_STANDARD_TIMING_HORIZ_PIXEL_FACTOR 8
|
||||
#define HDMI_EDID_STANDARD_TIMING_REFRESH_RATE_BASE 60
|
||||
#define HDMI_EDID_STANDARD_TIMING_REFRESH_RATE_MARK 0x3F
|
||||
|
||||
#define HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_MARK 0xC0
|
||||
#define HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_SHIFT 6
|
||||
|
||||
enum HdmiEdidStdTimingAspectRate {
|
||||
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_16_10 = 0,
|
||||
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_5_4 = 1,
|
||||
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_4_3 = 2,
|
||||
HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_16_9 = 3,
|
||||
};
|
||||
|
||||
struct HdmiEdidStdTimingInfo {
|
||||
uint32_t horizPixel;
|
||||
uint32_t vertPixel;
|
||||
uint32_t refreshRate;
|
||||
};
|
||||
|
||||
/* edid detailed timing descriptor */
|
||||
#define HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN 18
|
||||
#define HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_FIELD_LEN 2
|
||||
#define HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_KHZ_FACTOR 10
|
||||
#define HDMI_EDID_DETAILED_TIMING_UPPER_4BITS_MARK 0xF0
|
||||
#define HDMI_EDID_DETAILED_TIMING_LOWER_4BITS_MARK 0x0F
|
||||
#define HDMI_EDID_DETAILED_TIMING_HS_OFFSET_MARK 0xC0
|
||||
#define HDMI_EDID_DETAILED_TIMING_HS_PULSE_WIDTH_MARK 0x30
|
||||
#define HDMI_EDID_DETAILED_TIMING_VS_OFFSET_MARK 0x0C
|
||||
#define HDMI_EDID_DETAILED_TIMING_VS_PULSE_WIDTH_MARK 0x03
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_MARK 0x60
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_SEQUENTIAL_R 0x02
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_SEQUENTIAL_L 0x04
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_2R 0x03
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_2L 0x05
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_4 0x06
|
||||
#define HDMI_EDID_DETAILED_TIMING_STEREO_INTERLEAVED_SBS 0x07
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_SIGNAL_TYPE_MARK 0x0E
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_WS_0 0x00
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_WS_1 0x01
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_DS_2 0x02
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DCS_DS_3 0x03
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VN_HN_4 0x04
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VN_HP_5 0x05
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VP_HN_6 0x06
|
||||
#define HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VP_HP_7 0x07
|
||||
#define HDMI_EDID_MAX_DETAILED_TIMING_COUNT 10
|
||||
|
||||
struct HdmiEdidDetailedTimingBlockInfo {
|
||||
uint8_t pixelClk[HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_FIELD_LEN];
|
||||
uint8_t hActive;
|
||||
uint8_t hBlanking;
|
||||
uint8_t hActiveBlanking;
|
||||
uint8_t vActive;
|
||||
uint8_t vBlanking;
|
||||
uint8_t vActiveBlanking;
|
||||
uint8_t hSyncOffset;
|
||||
uint8_t hSyncPulseWidth;
|
||||
uint8_t vsOffesetPulseWidth;
|
||||
uint8_t hsOffsetVsOffset;
|
||||
uint8_t hImageSize;
|
||||
uint8_t vImageSize;
|
||||
uint8_t hvImageSize;
|
||||
uint8_t hBorder;
|
||||
uint8_t vBorder;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct HdmiEdidPreferredTimingInfo {
|
||||
uint32_t pixelClk; /* unit: KHz */
|
||||
uint32_t hActive; /* horizontal active area */
|
||||
uint32_t hBackBlank; /* horizontal back blank */
|
||||
uint32_t hFrontBlank; /* horizontal front blank */
|
||||
uint32_t hSyncPluseWidth; /* horizontal sync pluse width */
|
||||
uint32_t vActive; /* vertical active area */
|
||||
uint32_t vBackBlank; /* vertical back blank */
|
||||
uint32_t vFrontBlank; /* vertical front blank */
|
||||
uint32_t vSyncPluseWidth; /* vertical sync pluse width */
|
||||
uint32_t imageWidth; /* image width */
|
||||
uint32_t imageHeight; /* image height */
|
||||
bool interlaceFlag; /* interlace flag */
|
||||
bool idv; /* flag of data valid signal is needed flip */
|
||||
bool ihs; /* flag of horizontal sync pulse is needed flip */
|
||||
bool ivs; /* flag of vertical sync pulse is needed flip */
|
||||
};
|
||||
|
||||
|
||||
/* edid monitor descriptor */
|
||||
#define HDMI_EDID_MONITOR_FLAGS_FIELD_LEN 3
|
||||
#define HDMI_EDID_MONITOR_DATA_FIELD_LEN 13
|
||||
#define HDMI_EDID_MAX_SINK_NAME_COUNT 14
|
||||
|
||||
enum HdmiEdidMonitorDataType {
|
||||
HDMI_EDID_MONITOR_DATA_NAME = 0xFC,
|
||||
HDMI_EDID_MONITOR_DATA_RANGE_LIMIT = 0xFD,
|
||||
HDMI_EDID_MONITOR_DATA_STRING = 0xFE,
|
||||
HDMI_EDID_MONITOR_DATA_SERIAL_NUMBER = 0xFF,
|
||||
};
|
||||
|
||||
struct HdmiEdidMonitorBlockInfo {
|
||||
uint8_t flags[HDMI_EDID_MONITOR_FLAGS_FIELD_LEN];
|
||||
uint8_t dataTag;
|
||||
uint8_t flag;
|
||||
uint8_t data[HDMI_EDID_MONITOR_DATA_FIELD_LEN];
|
||||
};
|
||||
|
||||
/* edid extension flag and checksum */
|
||||
#define HDMI_EDID_EXTENSION_BLOCK_ADDR 0x7E
|
||||
#define HDMI_EDID_CHECKSUM_ADDR 0x7F
|
||||
|
||||
struct HdmiEdidFirstBlockInfo {
|
||||
uint8_t header[HDMI_EDID_BLOCK_HEADER_FIELD_LEN];
|
||||
uint8_t vendorName[HDMI_EDID_MANUFACRURER_NAME_FIELD_LEN];
|
||||
uint8_t productCode[HDMI_EDID_PRODUCT_CODE_FIELD_LEN];
|
||||
uint8_t serialNumber[HDMI_EDID_SERIAL_NUMBER_FIELD_LEN];
|
||||
uint8_t week; /*
|
||||
* The designated values for this field range from 1 to 53. If this field is unused, the value
|
||||
* should be set to 0. If the next field is used for Model Year, then 0xFF should be set.
|
||||
*/
|
||||
uint8_t year; /* This value is determined by the actual year of production minus 1990. */
|
||||
uint8_t version;
|
||||
uint8_t revision;
|
||||
uint8_t videoInput;
|
||||
uint8_t width; /* unit: cm */
|
||||
uint8_t height; /* unit: cm */
|
||||
uint8_t gamma; /* Display Transfer Characteristics */
|
||||
uint8_t features;
|
||||
uint8_t redGreenLow;
|
||||
uint8_t blueWhiteLow;
|
||||
uint8_t redX;
|
||||
uint8_t redY;
|
||||
uint8_t greenX;
|
||||
uint8_t greenY;
|
||||
uint8_t blueX;
|
||||
uint8_t blueY;
|
||||
uint8_t whiteX;
|
||||
uint8_t whiteY;
|
||||
uint8_t estTimings[HDMI_EDID_ESTABLISHED_TIMINGS_FIELD_LEN];
|
||||
uint8_t stdTiming[HDMI_EDID_STANDARD_TIMING_FIELD_LEN];
|
||||
uint8_t detailedTiming1[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
|
||||
uint8_t detailedTiming2[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
|
||||
uint8_t detailedTiming3[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
|
||||
uint8_t detailedTiming4[HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN];
|
||||
uint8_t extensionFlag;
|
||||
uint8_t checksum;
|
||||
};
|
||||
|
||||
/* edid extension block */
|
||||
#define HDMI_EDID_CTA_EXTENSION_TAG 0x02
|
||||
#define HDMI_EDID_CTA_EXTENSION3_REVISION 0x03
|
||||
#define HDMI_EDID_EXTENSION_DATA_BLOCK_LEN_MARK 0x1F
|
||||
#define HDMI_EDID_EXTENSION_DATA_BLOCK_TAG_CODE_MARK 0xE0
|
||||
#define HDMI_EDID_EXTENSION_DATA_BLOCK_TAG_CODE_SHIFT 5
|
||||
#define HDMI_EDID_EXTENSION_BLOCK_OFFSET 4
|
||||
#define HDMI_EDID_EXTENSION_D_INVALID_MIN_VAL 4
|
||||
|
||||
enum HdmiEdidExtDataBlockType {
|
||||
HDMI_EDID_NULL_DATA_BLOCK = 0,
|
||||
HDMI_EDID_AUDIO_DATA_BLOCK = 1,
|
||||
HDMI_EDID_VIDEO_DATA_BLOCK = 2,
|
||||
HDMI_EDID_VENDOR_SPECIFIC_DATA_BLOCK = 3,
|
||||
HDMI_EDID_SPEAKER_ALLOCATION_DATA_BLOCK = 4,
|
||||
HDMI_EDID_VESA_DTC_DATA_BLOCK = 5, /* VESA Display Transfer Characteristic Data Block */
|
||||
HDMI_EDID_USE_EXT_DATA_BLOCK = 7, /* Use Extended Tag */
|
||||
};
|
||||
|
||||
struct HdmiEdidColorSpace {
|
||||
bool rgb444;
|
||||
bool ycbcr422;
|
||||
bool ycbcr444;
|
||||
bool ycbcr420;
|
||||
};
|
||||
|
||||
/* edid extension block: Audio Data Block */
|
||||
#define HDMI_EDID_EXTENSION_SHORT_AUDIO_DESCRIPTOR_LEN 3
|
||||
#define HDMI_EDID_EXTENSION_MAX_SHORT_AUDIO_DESCRIPTOR_NUM 10
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_FORMAT_CODE_MARK 0x78
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_FORMAT_CODE_SHIFT 3
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_MAX_CHANNEL_MARK 0x07
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM 8
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM 6
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_BIT_RATE_FACTOR 8
|
||||
#define HDMI_EDID_EXTENSION_AUDIO_CAP_COUNT 16
|
||||
|
||||
|
||||
struct HdmiEdidAudioInfo {
|
||||
enum HdmiAudioCodingType formatCode;
|
||||
uint32_t sampleRateNum;
|
||||
enum HdmiSampleRate sampleRate[HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM];
|
||||
uint32_t bitDepthNum;
|
||||
enum HdmiAudioBitDepth bitDepth[HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM];
|
||||
uint8_t channels;
|
||||
uint32_t maxBitRate; /* unit: KHz */
|
||||
};
|
||||
|
||||
/* edid extension block: Video Data Block */
|
||||
#define HDMI_EDID_EXTENSION_VIC_NATIVE_MAX 64
|
||||
#define HDMI_EDID_EXTENSION_VIC_LOWER7_MARK 0x7F
|
||||
#define HDMI_EDID_EXTENSION_MAX_VIC_COUNT 128
|
||||
#define HDMI_EDID_EXTENSION_VIC_INVALID_LOW 128
|
||||
#define HDMI_EDID_EXTENSION_VIC_INVALID_HIGH 192
|
||||
|
||||
/*
|
||||
* Each supported Video Format is represented by a Short Video Descriptor (SVD) containing
|
||||
* a Video Identification Code (VIC) and, in the case of VICs 1 through 64, a Native Video Format indicator.
|
||||
*/
|
||||
struct HdmiEdidVideoInfo {
|
||||
uint32_t vicNum;
|
||||
uint32_t vic[HDMI_EDID_EXTENSION_MAX_VIC_COUNT];
|
||||
uint32_t nativeFormat;
|
||||
};
|
||||
|
||||
/* edid extension block: (VSDB)Vendor-Specific Data Block */
|
||||
#define HDMI_EDID_EXTENSION_VSDB_LEN 3
|
||||
#define HDMI_EDID_EXTENSION_VSDB_IEEE_1ST 0x03
|
||||
#define HDMI_EDID_EXTENSION_VSDB_IEEE_2ND 0x0C
|
||||
#define HDMI_EDID_EXTENSION_VSDB_IEEE_3RD 0x00
|
||||
#define HDMI_EDID_EXTENSION_VSDB_CEC_INVALID_ADDR 0xF
|
||||
#define HDMI_EDID_EXTENSION_MAX_HDMI14_TMDS_RATE 340 /* unit: Mcsc */
|
||||
#define HDMI_EDID_EXTENSION_TMDS_FACTOR 5 /* unit: MHz */
|
||||
#define HDMI_EDID_EXTENSION_VSDB_3D_LEN_MARK 0x1F
|
||||
#define HDMI_EDID_EXTENSION_VSDB_VIC_LEN_MARK 0xE0
|
||||
#define HDMI_EDID_EXTENSION_VSDB_VIC_LEN_SHIFT 5
|
||||
#define HDMI_EDID_EXTENSION_VSDB_3D_MULTI_PRESENT_MARK 0x60
|
||||
#define HDMI_EDID_EXTENSION_VSDB_3D_MULTI_PRESENT_SHIFT 5
|
||||
#define HDMI_EDID_EXTENSION_VSDB_3D_STR_INVALID_MARK 0x03
|
||||
|
||||
struct HdmiEdidVsdbCecAddr {
|
||||
bool addrValid;
|
||||
uint8_t phyAddrA;
|
||||
uint8_t phyAddrB;
|
||||
uint8_t phyAddrC;
|
||||
uint8_t phyAddrD;
|
||||
};
|
||||
|
||||
struct HdmiEdidDeepColor {
|
||||
bool dcY444;
|
||||
bool dc30bit;
|
||||
bool dc36bit;
|
||||
bool dc48bit;
|
||||
};
|
||||
|
||||
struct HdmiEdidExtVsdbInfo {
|
||||
struct HdmiEdidVsdbCecAddr cecAddr;
|
||||
struct HdmiEdidDeepColor deepColor;
|
||||
bool supportAi;
|
||||
bool supportDviDual;
|
||||
bool latencyFieldsPresent;
|
||||
bool iLatencyFieldsPresent;
|
||||
bool hdmiVideoPresent;
|
||||
uint8_t videoLatency;
|
||||
uint8_t audioLatency;
|
||||
uint8_t interlacedVideoLatency;
|
||||
uint8_t interlacedAudioLatency;
|
||||
bool _3dPresent;
|
||||
bool _3dMultiPresent;
|
||||
bool support3dType[HDMI_VS_VIDEO_3D_BUTT];
|
||||
};
|
||||
|
||||
/* edid extension block: (HF-VSDB)HDMI Forum Vendor-Specific Data Block */
|
||||
#define HDMI_EDID_EXTENSION_HFVSDB_IEEE_1ST 0xD8
|
||||
#define HDMI_EDID_EXTENSION_HFVSDB_IEEE_2ND 0x5D
|
||||
#define HDMI_EDID_EXTENSION_HFVSDB_IEEE_3RD 0xC4
|
||||
#define HDMI_EDID_EXTENSION_HFVSDB_VERSION 0x01
|
||||
#define HDMI_EDID_EXTENSION_HFVSDB_MIN_INVALID_LEN 7
|
||||
#define HDMI_EDID_EXTENSION_HFVSDB_MAX_INVALID_LEN 31
|
||||
|
||||
/* deep color Y420(4:2:0) */
|
||||
struct HdmiEdidExtHfVsdbDeepColor {
|
||||
bool dc30bit;
|
||||
bool dc36bit;
|
||||
bool dc48bit;
|
||||
};
|
||||
|
||||
/* dsc(Display Stream Compression ) */
|
||||
struct HdmiEdidExtHfVsdbDscInfo {
|
||||
bool dsc1p2;
|
||||
bool dscNative420;
|
||||
bool dscAllBpp;
|
||||
bool dsc10bpc;
|
||||
bool dsc20bpc;
|
||||
bool dsc16bpc;
|
||||
uint8_t dscMaxSlices;
|
||||
uint8_t dscMaxFrlRate;
|
||||
uint8_t dscTotalChunkKBytes;
|
||||
};
|
||||
|
||||
struct HdmiEdidExtHfVsdbInfo {
|
||||
bool scdcPresent;
|
||||
bool rrCapable; /* read request cap. */
|
||||
bool lte340McscScramble;
|
||||
bool independentView;
|
||||
bool dualView;
|
||||
bool _3dOsdDisparity;
|
||||
struct HdmiEdidExtHfVsdbDeepColor dc;
|
||||
/* hdmi 2.1 */
|
||||
uint8_t maxFrlRate;
|
||||
bool fapaStartLocation;
|
||||
bool allm;
|
||||
bool fva;
|
||||
bool cnmVrr;
|
||||
bool cinemaVrr;
|
||||
bool mDelta;
|
||||
uint8_t vrrMin;
|
||||
uint16_t vrrMax;
|
||||
struct HdmiEdidExtHfVsdbDscInfo dscInfo;
|
||||
};
|
||||
|
||||
/* edid extension block: Speaker Allocation Data Block */
|
||||
#define HDMI_EDID_EXTENSION_SADB_MIN_INVALID_LEN 2
|
||||
|
||||
enum HdmiEdidAudioSpeaker {
|
||||
HDMI_EDID_AUDIO_SPEAKER_FL_FR = 0,
|
||||
HDMI_EDID_AUDIO_SPEAKER_LFE = 1,
|
||||
HDMI_EDID_AUDIO_SPEAKER_FC = 2,
|
||||
HDMI_EDID_AUDIO_SPEAKER_BL_BR = 3,
|
||||
HDMI_EDID_AUDIO_SPEAKER_BC = 4,
|
||||
HDMI_EDID_AUDIO_SPEAKER_FLC_FRC = 5,
|
||||
HDMI_EDID_AUDIO_SPEAKER_RLC_RRC = 6,
|
||||
HDMI_EDID_AUDIO_SPEAKER_FLW_FRW = 7,
|
||||
HDMI_EDID_AUDIO_SPEAKER_TPFL_TPFH = 8,
|
||||
HDMI_EDID_AUDIO_SPEAKER_TPC = 9,
|
||||
HDMI_EDID_AUDIO_SPEAKER_TPFC = 10,
|
||||
HDMI_EDID_AUDIO_SPEAKER_BUTT,
|
||||
};
|
||||
|
||||
/*
|
||||
* If the Tag Code is 7 (Use Extended Tag) then the second byte of the data block contains the Extended
|
||||
* Tag Code, which indicates the actual type of the data block.
|
||||
*/
|
||||
enum HdmiEdidExtExtenedDataBlockType {
|
||||
HDMI_EDID_EXT_VCDB = 0, /* Video Capability Data Block */
|
||||
HDMI_EDID_EXT_VSVDB = 1, /* Vendor-Specific Video Data Block */
|
||||
HDMI_EDID_EXT_VESA_DDDB = 2, /* VESA Display Device Data Block */
|
||||
HDMI_EDID_EXT_VESA_VTBE = 3, /* VESA Video Timing Block Extension */
|
||||
HDMI_EDID_EXT_CDB = 5, /* Colorimetry Data Block */
|
||||
HDMI_EDID_EXT_HDR_SMDB = 6, /* HDR Static Metadata Data Block */
|
||||
HDMI_EDID_EXT_HDR_DMDB = 7, /* HDR Dynamic Metadata Data Block */
|
||||
HDMI_EDID_EXT_VFPDB = 13, /* Video Format Preference Data Block */
|
||||
HDMI_EDID_EXT_YCBCR420_VDB = 14, /* YCBCR 4:2:0 Video Data Block */
|
||||
HDMI_EDID_EXT_YCBCR420_CMDB = 15, /* YCBCR 4:2:0 Capability Map Data Block */
|
||||
HDMI_EDID_EXT_VSADB = 17, /* Vendor-Specific Audio Data Block */
|
||||
HDMI_EDID_EXT_RCDB = 19, /* Room Configuration Data Block */
|
||||
HDMI_EDID_EXT_SLDB = 20, /* Speaker Location Data Block */
|
||||
HDMI_EDID_EXT_INFOFRAME_DB = 32, /* InfoFrame Data Block (includes one or more Short InfoFrame Descriptors) */
|
||||
HDMI_EDID_EXT_BUTT,
|
||||
};
|
||||
|
||||
/* edid extension block: Colorimetry Data Block */
|
||||
#define HDMI_EDID_CDB_LEN 3
|
||||
|
||||
struct HdmiEdidColorimetry {
|
||||
bool xvYcc601;
|
||||
bool xvYcc709;
|
||||
bool sYcc601;
|
||||
bool opYcc601;
|
||||
bool opRgb;
|
||||
bool bt2020cYcc;
|
||||
bool bt2020Ycc;
|
||||
bool bt2020Rgb;
|
||||
bool dciP3;
|
||||
uint8_t md;
|
||||
};
|
||||
|
||||
/* edid extension block: Vendor-Specific Video Data Block */
|
||||
#define HDMI_EDID_VSVDB_DOLBY_OUI 0x00D046
|
||||
#define HDMI_EDID_VSVDB_DOLBY_VERSION_0 0x00
|
||||
#define HDMI_EDID_VSVDB_DOLBY_VERSION_1 0x01
|
||||
#define HDMI_EDID_VSVDB_DOLBY_VERSION_0_LEN 27
|
||||
#define HDMI_EDID_VSVDB_DOLBY_VERSION_1_LEN 14
|
||||
#define HDMI_EDID_VSVDB_DOLBY_LOWER_2BIT_MARK 0x03
|
||||
#define HDMI_EDID_VSVDB_DOLBY_LOWER_3BIT_MARK 0x07
|
||||
#define HDMI_EDID_VSVDB_DOLBY_LOWER_7BIT_MARK 0x7F
|
||||
#define HDMI_EDID_VSVDB_DOLBY_VERSION_MARK 0xE0
|
||||
#define HDMI_EDID_VSVDB_DOLBY_VERSION_SHIFT 5
|
||||
#define HDMI_EDID_VSVDB_DOLBY_DM_VER_MARK 0x1C
|
||||
#define HDMI_EDID_VSVDB_DOLBY_DM_VER_SHIFT 2
|
||||
|
||||
|
||||
struct HdmiEdidVsvdbDolbyCap {
|
||||
uint32_t oui;
|
||||
uint8_t version;
|
||||
bool yuv422;
|
||||
bool b2160p60; /* capable of processing a max timing 3840X2160p60. */
|
||||
bool globalDimming;
|
||||
uint16_t redX;
|
||||
uint16_t redY;
|
||||
uint16_t greenX;
|
||||
uint16_t greenY;
|
||||
uint16_t blueX;
|
||||
uint16_t blueY;
|
||||
uint16_t whiteX; /* only version0 support */
|
||||
uint16_t whiteY; /* only version0 support */
|
||||
uint16_t minLuminance;
|
||||
uint16_t maxLuminance;
|
||||
uint8_t dMajorVer; /* only version0 support */
|
||||
uint8_t dMinorVer; /* only version0 support */
|
||||
bool colorimetry; /* only version1 support */
|
||||
uint8_t dmVer; /* only version1 support */
|
||||
};
|
||||
|
||||
/* edid extension block: Video Capability Data Block */
|
||||
#define HDMI_EDID_VCDB_LEN 2
|
||||
|
||||
struct HdmiEdidVideoCapability {
|
||||
bool qy; /* Quantization Range(Applies to YCC only) */
|
||||
bool qs; /* Quantization Range Selectable(Applies to RGB only) */
|
||||
};
|
||||
|
||||
/* edid extension block: HDR Static Metadata Data Block */
|
||||
#define HDMI_EDID_HDR_SMDB_MIN_LEN 3
|
||||
|
||||
/* EOTF(Electro-Optical Transfer Functions) */
|
||||
struct HdmiEdidHdrSmdbEotf {
|
||||
bool sdr; /* Traditional gamma - SDR Luminance Range */
|
||||
bool hdr; /* Traditional gamma - HDR Luminance Range */
|
||||
bool smpteSt2048; /* SMPTE ST 2084 */
|
||||
bool hlg; /* Hybrid Log-Gamma (HLG) based on Recommendation ITU-R BT.2100-0 */
|
||||
};
|
||||
|
||||
struct HdmiEdidHdrCap {
|
||||
struct HdmiEdidHdrSmdbEotf eotf;
|
||||
bool smType1; /* Static Metadata Type 1 */
|
||||
uint8_t maxLuminancedata; /* Desired Content Max Luminance data */
|
||||
uint8_t maxFrameAverageLuminanceData; /* Desired Content Max Frame-average Luminance data */
|
||||
uint8_t minLuminanceData; /* Desired Content Min Luminance data */
|
||||
};
|
||||
|
||||
/* edid extension block: YCBCR 4:2:0 Capability Map Data Block */
|
||||
struct HdmiEdidYcbcr420Cap {
|
||||
uint32_t onlySupportY420VicNum;
|
||||
uint32_t onlySupportY420Format[HDMI_EDID_EXTENSION_MAX_VIC_COUNT];
|
||||
uint32_t SupportY420VicNum;
|
||||
uint32_t SupportY420Format[HDMI_EDID_EXTENSION_MAX_VIC_COUNT];
|
||||
};
|
||||
|
||||
/* sink device cap */
|
||||
struct HdmiSinkDeviceCapability {
|
||||
uint8_t extBlockNum;
|
||||
struct HdmiEdidVendorInfo vendorInfo;
|
||||
struct HdmiEdidVersionInfo verInfo;
|
||||
char sinkDeviceName[HDMI_EDID_MAX_SINK_NAME_COUNT];
|
||||
struct HdmiEdidBasicDispParamInfo disp;
|
||||
struct HdmiEdidEstablishedTimingsInfo establishedTimingsInfo;
|
||||
struct HdmiEdidStdTimingInfo stdTimingsInfo[HDMI_EDID_STANDARD_TIMING_COUNT];
|
||||
struct HdmiEdidColorInfo colorInfo;
|
||||
struct HdmiEdidColorSpace colorSpace;
|
||||
uint32_t preTimingCnt;
|
||||
struct HdmiEdidPreferredTimingInfo preTimingInfo[HDMI_EDID_MAX_DETAILED_TIMING_COUNT];
|
||||
uint32_t audioInfoCnt;
|
||||
struct HdmiEdidAudioInfo audioInfo[HDMI_EDID_EXTENSION_AUDIO_CAP_COUNT];
|
||||
struct HdmiEdidVideoInfo videoInfo;
|
||||
uint32_t maxTmdsClk;
|
||||
bool supportHdmi14;
|
||||
bool supportHdmi20;
|
||||
bool supportAudio;
|
||||
struct HdmiEdidExtVsdbInfo vsdbInfo;
|
||||
struct HdmiEdidExtHfVsdbInfo hfVsdbInfo;
|
||||
bool supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_BUTT];
|
||||
struct HdmiEdidColorimetry colorimetry;
|
||||
struct HdmiEdidVideoCapability videoCap;
|
||||
struct HdmiEdidYcbcr420Cap y420Cap;
|
||||
struct HdmiEdidHdrCap hdrCap;
|
||||
struct HdmiEdidVsvdbDolbyCap dolbyCap;
|
||||
};
|
||||
|
||||
/*
|
||||
* EDID(Extended Display Identification Data).
|
||||
* The Source read the Sink's EDID in order to discover the Sink's configuration and/or capabilities.
|
||||
*/
|
||||
struct HdmiEdid {
|
||||
bool edidPhase;
|
||||
uint32_t rawLen;
|
||||
uint8_t raw[HDMI_EDID_TOTAL_SIZE];
|
||||
struct HdmiSinkDeviceCapability sinkCap;
|
||||
};
|
||||
|
||||
typedef int32_t (*HdmiEdidPhaseFunc)(struct HdmiEdid *edid);
|
||||
|
||||
int32_t HdmiEdidReset(struct HdmiEdid *edid);
|
||||
int32_t HdmiEdidPhase(struct HdmiEdid *edid);
|
||||
int32_t HdmiEdidGetRaw(struct HdmiEdid *edid, uint8_t *raw, uint32_t len);
|
||||
int32_t HdmiEdidRawDataRead(struct HdmiEdid *edid, struct HdmiDdc *ddc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_EDID_H */
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_EVENT_H
|
||||
#define HDMI_EVENT_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "platform_core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* HPD(hot plug detect) */
|
||||
#define HDMI_READ_HPD_STATUS_DELAY 110 /* ms */
|
||||
|
||||
enum HdmiEventType {
|
||||
HDMI_EVENT_HOTPLUG = 0,
|
||||
HDMI_EVENT_HOTUNPLUG = 1,
|
||||
HDMI_EVENT_DETECT_SINK = 2,
|
||||
HDMI_EVENT_CEC_MSG = 3,
|
||||
HDMI_EVENT_HDCP_MSG = 4,
|
||||
HDMI_EVENT_ZERO_DRMIF_TIMEOUT = 5,
|
||||
HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT = 6,
|
||||
HDMI_EVENT_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiEventMsg {
|
||||
struct PlatformMsg msg;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct HdmiEvent {
|
||||
bool plugged;
|
||||
bool hpdDetected;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_EVENT_H */
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_FRL_H
|
||||
#define HDMI_FRL_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "osal_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* FRL(Fix Rate Link) */
|
||||
enum HdmiFrlMode {
|
||||
HDMI_FRL_MODE_TMDS = 0,
|
||||
HDMI_FRL_MODE_FRL = 1,
|
||||
HDMI_FRL_MODE_BUTT,
|
||||
};
|
||||
|
||||
#define HDMI_FRL_3_LANES 3
|
||||
#define HDMI_FRL_4_LANES 4
|
||||
|
||||
enum HdmiFrlWorkMode {
|
||||
HDMI_FRL_WORK_MODE_NONE = 0,
|
||||
HDMI_FRL_WORK_MODE_3L3G = 1, /* 3 lanes, 3Gbps per lane */
|
||||
HDMI_FRL_WORK_MODE_3L6G = 2, /* 3 lanes, 6Gbps per lane */
|
||||
HDMI_FRL_WORK_MODE_4L6G = 3, /* 4 lanes, 6Gbps per lane */
|
||||
HDMI_FRL_WORK_MODE_4L8G = 4, /* 4 lanes, 8Gbps per lane */
|
||||
HDMI_FRL_WORK_MODE_4L10G = 5, /* 4 lanes, 10Gbps per lane */
|
||||
HDMI_FRL_WORK_MODE_4L12G = 6, /* 4 lanes, 12Gbps per lane */
|
||||
HDMI_FRL_WORK_MODE_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlBitRate {
|
||||
HDMI_FRL_BIT_RATE_3 = 3,
|
||||
HDMI_FRL_BIT_RATE_6 = 6,
|
||||
HDMI_FRL_BIT_RATE_8 = 8,
|
||||
HDMI_FRL_BIT_RATE_10 = 10,
|
||||
HDMI_FRL_BIT_RATE_12 = 12,
|
||||
HDMI_FRL_BIT_RATE_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlTrainPattern {
|
||||
HDMI_FRL_TRAIN_PATTERN_NULL = 0,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP1 = 1,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP2 = 2,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP3 = 3,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP4 = 4,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP5 = 5,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP6 = 6,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP7 = 7,
|
||||
HDMI_FRL_TRAIN_PATTERN_LP8 = 8,
|
||||
HDMI_FRL_TRAIN_PATTERN_REV = 9,
|
||||
HDMI_FRL_TRAIN_PATTERN_0E = 14,
|
||||
HDMI_FRL_TRAIN_PATTERN_0F = 15,
|
||||
HDMI_FRL_TRAIN_PATTERN_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlTrainStatus {
|
||||
HDMI_FRL_TRAIN_STATUS_NULL = 0,
|
||||
HDMI_FRL_TRAIN_STATUS_FAIL = 1,
|
||||
HDMI_FRL_TRAIN_STATUS_SUCC = 2,
|
||||
HDMI_FRL_TRAIN_STATUS_BUSY = 3,
|
||||
HDMI_FRL_TRAIN_STATUS_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlTrainingFailReason {
|
||||
HDMI_FRL_TRAIN_FAIL_NORMAL,
|
||||
HDMI_FRL_TRAIN_FAIL_FLT_TIMEOUT,
|
||||
HDMI_FRL_TRAIN_FAIL_FLT_STEP_TIMEOUT,
|
||||
HDMI_FRL_TRAIN_FAIL_RATE_CHANGE,
|
||||
HDMI_FRL_TRAIN_FAIL_FFE_CHANGE,
|
||||
HDMI_FRL_TRAIN_FAIL_BUTT
|
||||
};
|
||||
|
||||
enum HdmiFrlTrainStep {
|
||||
HDMI_FRL_TRAIN_STEP_READR_CHECK = 0,
|
||||
HDMI_FRL_TRAIN_STEP_TRAIN_START = 1,
|
||||
HDMI_FRL_TRAIN_STEP_RESULT_CHECK = 2,
|
||||
HDMI_FRL_TRAIN_STEP_RATE_CHANGE = 3,
|
||||
HDMI_FRL_TRAIN_STEP_RESULT_HANDLE = 4,
|
||||
HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK = 5,
|
||||
HDMI_FRL_TRAIN_STEP_TRAIN_STOP = 6,
|
||||
HDMI_FRL_TRAIN_STEP_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlRateSelect {
|
||||
HDMI_FRL_RATE_LITTLE = 0,
|
||||
HDMI_FRL_RATE_BIG = 1,
|
||||
HDMI_FRL_RATE_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlPixelFormatMode {
|
||||
HDMI_FRL_PIXEL_FORMAT_MODE_0 = 0,
|
||||
HDMI_FRL_PIXEL_FORMAT_MODE_1 = 1,
|
||||
HDMI_FRL_PIXEL_FORMAT_MODE_2 = 2,
|
||||
HDMI_FRL_PIXEL_FORMAT_MODE_3 = 3,
|
||||
};
|
||||
|
||||
enum HdmiFrlBypass {
|
||||
HDMI_FRL_BYPASS_READ_CHECK = 0x01,
|
||||
HDMI_FRL_BYPASS_RESULT_CHECK = 0x02,
|
||||
HDMI_FRL_BYPASS_RETRAIN_CHECK = 0x04,
|
||||
};
|
||||
|
||||
/*
|
||||
* Feed Forward Equalizer(FFE)
|
||||
* Tx terminal will use 0=TxFFE0 FFE in Link Training. If higher rate signal needs to be transmitted,
|
||||
* Tx will decide higher FFE compensation through Link Training to ensure
|
||||
* that video and audio data can be completely transmitted to the Sink terminal.
|
||||
*/
|
||||
enum HdmiFrlTxffeMode {
|
||||
HDMI_FRL_TXFFE_MODE_0 = 0,
|
||||
HDMI_FRL_TXFFE_MODE_1 = 1,
|
||||
HDMI_FRL_TXFFE_MODE_2 = 2,
|
||||
HDMI_FRL_TXFFE_MODE_3 = 3,
|
||||
HDMI_FRL_TXFFE_MODE_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiFrlStrategyMode {
|
||||
HDMI_FRL_STRATEGY_MODE_1,
|
||||
HDMI_FRL_STRATEGY_MODE_2,
|
||||
HDMI_FRL_STRATEGY_MODE_3,
|
||||
HDMI_FRL_STRATEGY_MODE_BUTT
|
||||
};
|
||||
|
||||
enum HdmiFrlStateMachineRunningState {
|
||||
HDMI_FRL_STATE_MACHINE_NULL = 0,
|
||||
HDMI_FRL_STATE_MACHINE_START = 1,
|
||||
HDMI_FRL_STATE_MACHINE_STOP = 2,
|
||||
};
|
||||
|
||||
struct HdmiFrlStateMachineInfo {
|
||||
bool start;
|
||||
enum HdmiFrlTrainStep trainingState;
|
||||
enum HdmiFrlStateMachineRunningState machineState;
|
||||
uint64_t startTime; /* ms */
|
||||
uint32_t waitReadyTime; /* ms */
|
||||
uint32_t waitHandleTime; /* ms */
|
||||
uint32_t waitRetrainTime; /* ms */
|
||||
uint32_t trainTimeout; /* ms */
|
||||
uint32_t timeoutCnt;
|
||||
};
|
||||
|
||||
struct HdmiFrlInfo {
|
||||
uint8_t curFrlRate;
|
||||
uint8_t minFrlRate;
|
||||
uint8_t maxFrlRate;
|
||||
uint8_t preFrlRate;
|
||||
uint32_t trainFailCnt;
|
||||
uint32_t trainMaxFailTimes;
|
||||
uint32_t tmdsClock;
|
||||
enum HdmiFrlMode perMode;
|
||||
enum HdmiFrlMode mode;
|
||||
enum HdmiFrlStrategyMode strategy;
|
||||
enum HdmiFrlRateSelect rateSelect;
|
||||
bool scdc;
|
||||
bool ctsMode;
|
||||
bool start;
|
||||
bool work;
|
||||
struct HdmiFrlStateMachineInfo machineInfo;
|
||||
uint32_t trainingFailCnt;
|
||||
uint32_t trainingMaxFailTimes;
|
||||
};
|
||||
|
||||
struct HdmiFrl {
|
||||
struct HdmiFrlInfo info;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct HdmiFrlAudioNctsConfig {
|
||||
enum HdmiSampleRate sampleRate;
|
||||
enum HdmiFrlMode mode;
|
||||
uint8_t frlRate;
|
||||
uint32_t pixelClk;
|
||||
uint32_t n;
|
||||
uint32_t cts;
|
||||
};
|
||||
|
||||
struct HdmiFrlTrainConfig {
|
||||
bool frlNoTimeout;
|
||||
uint8_t frlRate;
|
||||
uint8_t txffe;
|
||||
uint32_t trainTimeout;
|
||||
};
|
||||
|
||||
struct HdmiFrlTrainRslt {
|
||||
enum HdmiFrlTrainStatus status;
|
||||
enum HdmiFrlTrainPattern pattern[HDMI_FRL_4_LANES];
|
||||
enum HdmiFrlTrainingFailReason failReason;
|
||||
};
|
||||
|
||||
void HdmiFrlEnable(struct HdmiFrl *frl, bool enable);
|
||||
bool HdmiFrlSupport(struct HdmiFrl *frl);
|
||||
int32_t HdmiFrlModeSelect(struct HdmiFrl *frl);
|
||||
bool HdmiFrlModeChanged(struct HdmiFrl *frl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_FRL_H */
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_HDCP_H
|
||||
#define HDMI_HDCP_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "osal_mutex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* HDCP(High-bandwidth Digital Content Protection) Sysytem. */
|
||||
|
||||
enum HdmiHdcpPortOffset {
|
||||
/* HDCP 1.4 Spec */
|
||||
HDMI_HDCP_BKSV = 0x00, /* Rd, 5 bytes */
|
||||
HDMI_HDCP_RI = 0x08, /* Rd, 2 bytes */
|
||||
HDMI_HDCP_PJ = 0x0A, /* Rd, 1 byte */
|
||||
HDMI_HDCP_AKSV = 0x10, /* Wr, 5 bytes */
|
||||
HDMI_HDCP_AINFO = 0x15, /* Wr, 1 byte */
|
||||
HDMI_HDCP_AN = 0x18, /* Wr, 8 bytes */
|
||||
HDMI_HDCP_V_H0 = 0x20, /* Rd, 4 bytes */
|
||||
HDMI_HDCP_V_H1 = 0x24, /* Rd, 4 bytes */
|
||||
HDMI_HDCP_V_H2 = 0x28, /* Rd, 4 bytes */
|
||||
HDMI_HDCP_V_H3 = 0x2C, /* Rd, 4 bytes */
|
||||
HDMI_HDCP_V_H4 = 0x30, /* Rd, 4 bytes */
|
||||
HDMI_HDCP_BCAPS = 0x40, /* Rd, 1 byte */
|
||||
HDMI_HDCP_BSTATUS = 0x41, /* Rd, 2 bytes */
|
||||
HDMI_HDCP_KSV_FIFO = 0x43, /* Rd, 1 byte */
|
||||
|
||||
/* HDCP 2.2 Spec */
|
||||
HDMI_HDCP_HDCP2VERSION = 0x50, /* Rd, 1 byte */
|
||||
HDMI_HDCP_WRITE_MSG = 0x60, /* Wr, 1 byte */
|
||||
HDMI_HDCP_RXSTATUS = 0x70, /* Rd, 2 bytes */
|
||||
HDMI_HDCP_READ_MSG = 0x80, /* Rd, 1 byte */
|
||||
};
|
||||
|
||||
/* HDCP 2.2 Read/Write Message Id */
|
||||
enum HdmiHdcpMsgId {
|
||||
HDMI_HDCP_MSG_AKE_INIT = 2, /* Write, 12 bytes */
|
||||
HDMI_HDCP_MSG_AKE_SEND_CERT = 3, /* Read, 534 bytes */
|
||||
HDMI_HDCP_MSG_AKE_NO_STORED_KM = 4, /* Write, 129 bytes */
|
||||
HDMI_HDCP_MSG_AKE_STORED_KM = 5, /* Write, 33 bytes */
|
||||
HDMI_HDCP_MSG_AKE_SEND_H_PRIME = 7, /* Read, 33 bytes */
|
||||
HDMI_HDCP_MSG_AKE_SEND_PAIRING_INFO = 8, /* Read, 17 bytes */
|
||||
HDMI_HDCP_MSG_LC_INIT = 9, /* Write, 9 bytes */
|
||||
HDMI_HDCP_MSG_LC_SEND_L_PRIME = 10, /* Read, 33 bytes */
|
||||
HDMI_HDCP_MSG_SKE_SEND_EKS = 11, /* Write, 25 bytes */
|
||||
HDMI_HDCP_MSG_REPEATER_AUTH_SEND_RCVID_LIST = 12, /* Read, 22 + 5 * device_count bytes */
|
||||
HDMI_HDCP_MSG_REPEATER_AUTH_SEND_ACK = 15, /* Write, 17 bytes */
|
||||
HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_MANAGE = 16, /* Write, 6 + 2 * k bytes */
|
||||
HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_READY = 17, /* Read, 33 bytes */
|
||||
};
|
||||
|
||||
enum HdmiHdcpRegOptType {
|
||||
/* HDCP 1.4 Spec */
|
||||
HDMI_HDCP_OPT_WRITE_BKSV = 0x00,
|
||||
HDMI_HDCP_OPT_WRITE_RI = 0x01,
|
||||
HDMI_HDCP_OPT_WRITE_PJ = 0x02,
|
||||
HDMI_HDCP_OPT_WRITE_V_H0 = 0x03,
|
||||
HDMI_HDCP_OPT_WRITE_V_H1 = 0x04,
|
||||
HDMI_HDCP_OPT_WRITE_V_H2 = 0x05,
|
||||
HDMI_HDCP_OPT_WRITE_V_H3 = 0x06,
|
||||
HDMI_HDCP_OPT_WRITE_V_H4 = 0x07,
|
||||
HDMI_HDCP_OPT_WRITE_V_H_ALL = 0x08,
|
||||
HDMI_HDCP_OPT_WRITE_BCAPS = 0x0C,
|
||||
HDMI_HDCP_OPT_WRITE_BSTATUS = 0x0D,
|
||||
HDMI_HDCP_OPT_WRITE_KSV_FIFO = 0x0E,
|
||||
HDMI_HDCP_OPT_RESET_SHA = 0x0F,
|
||||
HDMI_HDCP_OPT_CHECK_V = 0x10,
|
||||
HDMI_HDCP_OPT_CHECK_R = 0x11,
|
||||
HDMI_HDCP_OPT_AUTH_FAIL = 0x12,
|
||||
HDMI_HDCP_OPT_AUTH_DONE = 0x13,
|
||||
HDMI_HDCP_OPT_AUTH_CLOSE = 0x14,
|
||||
};
|
||||
|
||||
#define HDMI_HDCP_MSG_BKSV_LEN 5
|
||||
#define HDMI_HDCP_MSG_RI_LEN 2
|
||||
#define HDMI_HDCP_MSG_PJ_LEN 1
|
||||
#define HDMI_HDCP_MSG_AKSV_LEN 5
|
||||
#define HDMI_HDCP_MSG_AINFO_LEN 1
|
||||
#define HDMI_HDCP_MSG_AN_LEN 8
|
||||
#define HDMI_HDCP_MSG_PER_VH_LEN 4
|
||||
#define HDMI_HDCP_MSG_ALL_VH_LEN 20
|
||||
#define HDMI_HDCP_MSG_BCAPS_LEN 1
|
||||
#define HDMI_HDCP_MSG_BSTATUS_LEN 2
|
||||
#define HDMI_HDCP_MSG_KSV_FIFO_LEN 1
|
||||
#define HDMI_HDCP_DEVICE_COUNT_MAX 127
|
||||
#define HDMI_HDCP_MSG_KSV_MAX_LEN (5 * HDMI_HDCP_DEVICE_COUNT_MAX)
|
||||
#define HDMI_HDCP_GET_KSV_LEN(x) (5 * x)
|
||||
|
||||
#define HDMI_HDCP_AKSV_ONE_NUM 20
|
||||
#define HDMI_HDCP_BCAPS_REPEATER_MARK 0x40
|
||||
#define HDMI_HDCP_BCAPS_KSV_FIFO_READY_MARK 0x20
|
||||
#define HDMI_HDCP_DEFAULT_READ_REG_TRY 100
|
||||
#define HDMI_HDCP_WAIT_KSV_LIST_TIMES 5000 /* 5s */
|
||||
#define HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL 20 /* 20ms */
|
||||
#define HDMI_HDCP_WAIT_KSV_LIST_READ_REG_CNT \
|
||||
(HDMI_HDCP_WAIT_KSV_LIST_TIMES / HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL)
|
||||
|
||||
#define HDMI_HDCP_BSTATUS_DEVICE_COUNT_MARK 0x7F
|
||||
#define HDMI_HDCP_BSTATUS_MAX_DEVS_EXCEEDED_MARK (1 << 7)
|
||||
#define HDMI_HDCP_BSTATUS_MAX_CASCADE_EXCEEDED_MARK (1 << 11)
|
||||
#define HDMI_HDCP_BSTATUS_DEPTH_MARK 0x07
|
||||
#define HDMI_HDCP_BSTATUS_DEPTH_SHIFT 8
|
||||
|
||||
|
||||
#define HDMI_HDCP_MSG_HDCP2VERSION_LEN 1
|
||||
#define HDMI_HDCP_MSG_RXSTATUS_LEN 2
|
||||
#define HDMI_HDCP_MSG_AKE_INIT_LEN 12
|
||||
#define HDMI_HDCP_MSG_AKE_CERT_LEN 534
|
||||
#define HDMI_HDCP_MSG_AKE_NO_STORED_KM_LEN 129
|
||||
#define HDMI_HDCP_MSG_AKE_STORED_KM_LEN 33
|
||||
#define HDMI_HDCP_MSG_AKE_H_PRIME_LEN 33
|
||||
#define HDMI_HDCP_MSG_AKE_PAIRING_INFO 17
|
||||
#define HDMI_HDCP_MSG_LC_INIT_LEN 9
|
||||
#define HDMI_HDCP_MSG_LC_L_PRIME_LEN 33
|
||||
#define HDMI_HDCP_MSG_SKE_EKS_LEN 25
|
||||
#define HDMI_HDCP_MSG_AUTH_RCVID_LIST_LEN (22 + 5 * 31)
|
||||
#define HDMI_HDCP_MSG_REPEATER_AUTH_ACK_LEN 17
|
||||
#define HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_MANAGE_LEN (6 + 2 * 31)
|
||||
#define HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_READY_LEN 33
|
||||
|
||||
#define HDMI_HDCP_2_2_VERSION 2
|
||||
#define HDMI_HDCP_GET_AUTH_RCVID_LIST_LEN(x) (22 + 5 * x)
|
||||
|
||||
struct HdmiHdcpMsg {
|
||||
/* HDCP 1.4 message */
|
||||
uint8_t bksv[HDMI_HDCP_MSG_BKSV_LEN];
|
||||
uint8_t ri[HDMI_HDCP_MSG_RI_LEN];
|
||||
uint8_t pj;
|
||||
uint8_t aksv[HDMI_HDCP_MSG_AKSV_LEN];
|
||||
uint8_t ainfo;
|
||||
uint8_t an[HDMI_HDCP_MSG_AN_LEN];
|
||||
uint8_t vh[HDMI_HDCP_MSG_ALL_VH_LEN];
|
||||
uint8_t bcaps;
|
||||
uint8_t bstatus[HDMI_HDCP_MSG_BSTATUS_LEN];
|
||||
uint8_t ksvList[HDMI_HDCP_MSG_KSV_MAX_LEN];
|
||||
uint32_t ksvLen;
|
||||
|
||||
/* HDCP 2.2 Message */
|
||||
uint8_t Hdcp2Version;
|
||||
uint8_t rxStatus[HDMI_HDCP_MSG_RXSTATUS_LEN];
|
||||
uint8_t akeInit[HDMI_HDCP_MSG_AKE_INIT_LEN];
|
||||
uint8_t akeCert[HDMI_HDCP_MSG_AKE_CERT_LEN];
|
||||
uint8_t akeNoStoredKm[HDMI_HDCP_MSG_AKE_NO_STORED_KM_LEN];
|
||||
uint8_t akeStoredKm[HDMI_HDCP_MSG_AKE_STORED_KM_LEN];
|
||||
uint8_t akeHPrime[HDMI_HDCP_MSG_AKE_H_PRIME_LEN];
|
||||
uint8_t akePairingInfo[HDMI_HDCP_MSG_AKE_PAIRING_INFO];
|
||||
uint8_t lcInit[HDMI_HDCP_MSG_LC_INIT_LEN];
|
||||
uint8_t lcLPrime[HDMI_HDCP_MSG_LC_L_PRIME_LEN];
|
||||
uint8_t skeEks[HDMI_HDCP_MSG_SKE_EKS_LEN];
|
||||
uint8_t rxIdList[HDMI_HDCP_MSG_AUTH_RCVID_LIST_LEN];
|
||||
uint32_t rxIdListLen;
|
||||
uint8_t authAck[HDMI_HDCP_MSG_REPEATER_AUTH_ACK_LEN];
|
||||
uint8_t authStreamManage[HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_MANAGE_LEN];
|
||||
uint32_t authStreamManageLen;
|
||||
uint8_t authStreamReady[HDMI_HDCP_MSG_REPEATER_AUTH_STREAM_READY_LEN];
|
||||
};
|
||||
|
||||
enum HdmiHdcpAuthState {
|
||||
HDMI_HDCP_AUTH_INACTIVE = 0,
|
||||
HDMI_HDCP_AUTH_AKSV_INVALID = 1,
|
||||
HDMI_HDCP_AUTH_DOING = 2,
|
||||
HDMI_HDCP_AUTH_DONE = 3,
|
||||
HDMI_HDCP_AUTH_FAIL = 4,
|
||||
};
|
||||
|
||||
#define HDMI_HDCP_AUTH_MAX_RETRY_CNT 10
|
||||
struct HdmiHdcp {
|
||||
struct OsalMutex hdcpMutex;
|
||||
enum HdmiHdcpAuthState state;
|
||||
uint8_t authRetryCnt;
|
||||
/* HDCP 1.4 */
|
||||
uint8_t aksv[HDMI_HDCP_MSG_AKSV_LEN]; /* need driver to generate */
|
||||
uint8_t an[HDMI_HDCP_MSG_AN_LEN]; /* need driver to generate */
|
||||
uint8_t bksv[HDMI_HDCP_MSG_BKSV_LEN];
|
||||
uint8_t bcaps;
|
||||
uint8_t ri[HDMI_HDCP_MSG_RI_LEN];
|
||||
uint8_t bstatus[HDMI_HDCP_MSG_BSTATUS_LEN];
|
||||
uint8_t deviceCount;
|
||||
uint8_t ksvList[HDMI_HDCP_MSG_KSV_MAX_LEN];
|
||||
uint32_t ksvLen;
|
||||
uint8_t vh[HDMI_HDCP_MSG_ALL_VH_LEN];
|
||||
bool aksvValid;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct HdmiHdcpStatus {
|
||||
bool hdcp22;
|
||||
bool hdcp14;
|
||||
uint8_t bksv[HDMI_HDCP_MSG_BKSV_LEN];
|
||||
uint8_t aksv[HDMI_HDCP_MSG_AKSV_LEN];
|
||||
};
|
||||
|
||||
int32_t HdmiHdcpOpen(struct HdmiHdcp *hdcp);
|
||||
void HdmiHdcpClose(struct HdmiHdcp *hdcp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_HDCP_H */
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_HPR_H
|
||||
#define HDMI_HPR_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
#include "hdmi_if.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* HDR(High Dynamic Range) Sysytem. */
|
||||
#define HDMI_ZERO_DRMIF_SEND_TIME 2000
|
||||
#define HDMI_HDR_STATE_CHANGE_TIME 500
|
||||
|
||||
enum HdmiHdrTimerType {
|
||||
HDMI_HDR_TIMER_ZERO_DRMIF,
|
||||
HDMI_HDR_TIMER_SDR_TO_HDR10,
|
||||
HDMI_HDR_TIMER_TYPE_BUTT
|
||||
};
|
||||
|
||||
enum HdmiHdrState {
|
||||
HDMI_HDR_STATE_NONE, /* HDR state change, SDR->HDR10 don't change anything */
|
||||
HDMI_HDR_STATE_OE, /* HDR state change, SDR->HDR10 output disable and enable */
|
||||
HDMI_HDR_STATE_AVMUTE, /* HDR state change, SDR->HDR10 send avmute */
|
||||
HDMI_HDR_STATE_BUTT
|
||||
};
|
||||
|
||||
struct HdmiHdrTimerConfig {
|
||||
enum HdmiHdrTimerType timerType;
|
||||
bool start;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct HdmiHdrInfo {
|
||||
enum HdmiHdrState state; /* Make sure that switch smoothly from non-HDR10 to HDR10. */
|
||||
struct HdmiHdrTimerConfig zeroDrmIfTimer; /* Send zero DRM infoframe when the HDR mode from HDR10 to non-HDR10. */
|
||||
struct HdmiHdrTimerConfig stateChangeTimer; /* */
|
||||
};
|
||||
|
||||
struct HdmiHdr {
|
||||
struct HdmiHdrInfo info;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
int32_t HdmiHdrAttrHandle(struct HdmiHdr *hdr, struct HdmiHdrAttr *curAttr);
|
||||
int32_t HdmiHdrDrmInfoframeStop(struct HdmiHdr *hdr);
|
||||
int32_t HdmiHdrModeChangeTimeout(struct HdmiHdr *hdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_HPR_H */
|
||||
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_INFOFRAME_H
|
||||
#define HDMI_INFOFRAME_H
|
||||
|
||||
#include "hdmi_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* An InfoFrame packet carries one InfoFrame. The InfoFrame provided by HDMI is limited to 30
|
||||
* bytes plus a checksum byte. HDMI Sources are required, in some cases, to use the AVI InfoFrame and Audio InfoFrame
|
||||
* and recommended in other cases. Other InfoFrames specified in CEA-861 Spec are optional.
|
||||
*
|
||||
* TMDS is used to carry all audio and video data as well as auxiliary data, including AVI(Auxiliary Video information)
|
||||
* and Audio InfoFrames that describe the active audio and video streams.
|
||||
*
|
||||
*/
|
||||
#define HDMI_INFOFRAME_LEN 32
|
||||
#define HDMI_INFOFRAME_PACKET_HEADER_LEN 4
|
||||
#define HDMI_AVI_INFOFRAME_LEN 13
|
||||
#define HDMI_AUDIO_INFOFRAME_LEN 10
|
||||
#define HDMI_DRM_INFOFRAME_LEN 26
|
||||
#define HDMI_SPD_INFOFRAME_LEN 25
|
||||
#define HDMI_INFOFRAME_CHECKSUM 256
|
||||
|
||||
enum HdmiPacketType {
|
||||
HDMI_PACKET_TYPE_NULL = 0x00, /* Null Packet */
|
||||
HDMI_PACKET_TYPE_AUDIO_CLOCK_REGENERATION = 0x01, /* Audio Clock Regeneration(N/CTS) */
|
||||
HDMI_PACKET_TYPE_AUDIO_SAMPLE = 0x02, /* Audio Samlpe(L-PCM and IEC 61937 compressed formats) */
|
||||
HDMI_PACKET_TYPE_GENERAL_CONTROL = 0x03, /* General Control Packet */
|
||||
HDMI_PACKET_TYPE_ACP = 0x04, /* ACP(Audio Content Protection Packet) */
|
||||
HDMI_PACKET_TYPE_ISRC1 = 0x05, /* ISRC(International Standard Recording Code) */
|
||||
HDMI_PACKET_TYPE_ISRC2 = 0x06,
|
||||
HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE = 0x07, /* One Bit Audio Sample Packet */
|
||||
HDMI_PACKET_TYPE_DST_AUDIO = 0x08, /* DST(Diret Stream Transport) Audio Packet */
|
||||
HDMI_PACKET_TYPE_HBR_AUDIO_STREAM = 0x09, /* HBR(High Bitrate) Audio Stream Packet */
|
||||
HDMI_PACKET_TYPE_GAMUT_METADATA = 0x0a, /* gamut metadata packet */
|
||||
/* infoframe type */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_VS = 0x81, /* Verdor-Specific */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_AVI = 0x82, /* Auxiliary Video Information */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_SPD = 0x83, /* Source Product Description */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_AUDIO = 0x84, /* Audio */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_MPEG = 0x85, /* MPEG Source */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_GBD = 0x86, /* gamut boundary description */
|
||||
HDMI_INFOFRAME_PACKET_TYPE_DRM = 0x87, /* Dynamic Range and Mastering */
|
||||
HDMI_PACKET_TYPE_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiInfoframeHeader {
|
||||
enum HdmiPacketType type;
|
||||
uint8_t verNum;
|
||||
uint8_t len;
|
||||
};
|
||||
|
||||
/* Verdor-Specific infoframe details. */
|
||||
#define HDMI_VENDOR_1_4_MAX_3D_METADAT_LEN 20
|
||||
#define HDMI_VENDOR_USER_DATA_MAX_LEN 22
|
||||
#define HDMI_VENDOR_1_4_FORMAT_MARK 0x07
|
||||
#define HDMI_VENDOR_1_4_FORMAT_SHIFT 5
|
||||
#define HDMI_VENDOR_3D_STRUCTURE_MARK 0x0f
|
||||
#define HDMI_VENDOR_3D_STRUCTURE_SHIFT 4
|
||||
#define HDMI_VENDOR_3D_EXT_DATA_MARK 0x0f
|
||||
#define HDMI_VENDOR_3D_EXT_DATA_SHIFT 4
|
||||
#define HDMI_VSIF_VERSION 1
|
||||
|
||||
enum HdmiIeeeOui {
|
||||
HDMI_IEEE_OUI_1_4 = 0x000c03,
|
||||
HDMI_IEEE_OUI_2_0 = 0x045dd8,
|
||||
};
|
||||
|
||||
enum HdmiVsVideoFormat {
|
||||
HDMI_VS_VIDEO_FORMAT_NULL = 0,
|
||||
HDMI_VS_VIDEO_FORMAT_4K = 1,
|
||||
HDMI_VS_VIDEO_FORMAT_3D = 2,
|
||||
HDMI_VS_VIDEO_FORMAT_BUTT,
|
||||
};
|
||||
|
||||
enum HdmiVs3dExtData {
|
||||
HDMI_3D_PICTURE_HORIZONTAL_ODD_LEFT_ODD_RIGHT = 0,
|
||||
HDMI_3D_PICTURE_HORIZONTAL_ODD_LEFT_EVEN_RIGHT = 1,
|
||||
HDMI_3D_PICTURE_HORIZONTAL_EVEN_LEFT_ODD_RIGHT = 2,
|
||||
HDMI_3D_PICTURE_HORIZONTAL_EVEN_LEFT_EVEN_RIGHT = 3,
|
||||
HDMI_3D_PICTURE_MATRIX_ODD_LEFT_ODD_RIGHT = 4,
|
||||
HDMI_3D_PICTURE_MATRIX_ODD_LEFT_EVEN_RIGHT = 5,
|
||||
HDMI_3D_PICTURE_MATRIX_EVEN_LEFT_ODD_RIGHT = 6,
|
||||
HDMI_3D_PICTURE_MATRIX_EVEN_LEFT_EVEN_RIGHT = 7,
|
||||
HDMI_3D_PICTURE_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiVs14VsifContent {
|
||||
enum HdmiIeeeOui oui;
|
||||
enum HdmiVsVideoFormat format;
|
||||
enum Hdmi4kVic vic;
|
||||
bool _3dMetaPresent;
|
||||
enum HdmiVideo3dStructure _3dStruct;
|
||||
enum HdmiVs3dExtData _3dExtData;
|
||||
uint8_t _3dMetadataType;
|
||||
uint8_t _3dMetadataLen;
|
||||
uint8_t _3dMetadata[HDMI_VENDOR_1_4_MAX_3D_METADAT_LEN];
|
||||
};
|
||||
|
||||
struct HdmiVsUserVsifContent {
|
||||
enum HdmiIeeeOui oui;
|
||||
enum HdmiVsVideoFormat format;
|
||||
enum Hdmi4kVic vic;
|
||||
bool _3dMetaPresent;
|
||||
enum HdmiVideo3dStructure _3dStruct;
|
||||
uint8_t len;
|
||||
uint8_t data[HDMI_VENDOR_USER_DATA_MAX_LEN];
|
||||
};
|
||||
|
||||
struct HdmiForumVsifContent {
|
||||
enum HdmiIeeeOui oui;
|
||||
uint8_t version;
|
||||
bool _3dValid;
|
||||
uint8_t _3dFStructure;
|
||||
bool _3dAdditionalInfoPresent;
|
||||
bool _3dDisparityDataPresent;
|
||||
bool _3dMetaPresent;
|
||||
uint8_t _3dFExtData;
|
||||
uint8_t _3dDualView;
|
||||
uint8_t _3dViewDependency;
|
||||
uint8_t _3dPreferred2dView;
|
||||
uint8_t _3dDisparityDataVersion;
|
||||
uint8_t _3dDisparityDataLen;
|
||||
uint8_t _3dDisparityData[10];
|
||||
uint8_t _3dMetadataType;
|
||||
uint8_t _3dMetadataLen;
|
||||
uint8_t _3dMetadata[10];
|
||||
};
|
||||
|
||||
struct HdmiVsInfoframe {
|
||||
enum HdmiPacketType type;
|
||||
uint8_t verNum;
|
||||
uint8_t len;
|
||||
union {
|
||||
struct HdmiVs14VsifContent _14Vsif;
|
||||
struct HdmiVsUserVsifContent userVsif;
|
||||
struct HdmiForumVsifContent forumVsif;
|
||||
} vsifContent;
|
||||
};
|
||||
|
||||
/* AVI infoframe details. */
|
||||
#define HDMI_AVI_COLOR_SPACE_MARK 0x03
|
||||
#define HDMI_AVI_SCAN_MODE_MARK 0x03
|
||||
#define HDMI_AVI_COLOR_SPACE_SHIFT 5
|
||||
#define HDMI_AVI_ACTIVE_INFORMATION_SHIFT 4
|
||||
#define HDMI_AVI_HORIZONTAL_BAR_SHIFT 3
|
||||
#define HDMI_AVI_VERTICAL_BAR_SHIFT 2
|
||||
|
||||
#define HDMI_AVI_COLORIMETRY_MARK 0x03
|
||||
#define HDMI_AVI_PICTURE_ASPECT_RATE_MARK 0x03
|
||||
#define HDMI_AVI_ACTIVE_FORMAT_ASPECT_RATE_MARK 0x0f
|
||||
#define HDMI_AVI_COLORIMETRY_SHIFT 6
|
||||
#define HDMI_AVI_PICTURE_ASPECT_RATE_SHIFT 4
|
||||
|
||||
#define HDMI_AVI_EXT_COLORIMETRY_MARK 0x07
|
||||
#define HDMI_AVI_EXT_QUANTIZATION_RANGE_MARK 0x03
|
||||
#define HDMI_AVI_NUPS_RANGE_MARK 0x03
|
||||
#define HDMI_AVI_IT_CONTENT_SHIFT 7
|
||||
#define HDMI_AVI_EXT_COLORIMETRY_SHIFT 4
|
||||
#define HDMI_AVI_EXT_QUANTIZATION_RANGE_SHIFT 2
|
||||
|
||||
#define HDMI_AVI_YCC_QUANTIZATION_RANGE_MARK 0x03
|
||||
#define HDMI_AVI_IT_CONTENT_TYPE_MARK 0x03
|
||||
#define HDMI_AVI_PIXEL_REPETION_FACTOR_MARK 0x0f
|
||||
#define HDMI_AVI_YCC_QUANTIZATION_RANGE_SHIFT 6
|
||||
#define HDMI_AVI_IT_CONTENT_TYPE_SHIFT 4
|
||||
|
||||
#define HDMI_AVI_BAR_MODE_MARK 0xff
|
||||
#define HDMI_AVI_BAR_MODE_SHIFT 8
|
||||
|
||||
#define HDMI_AVI_VERSION2 2
|
||||
#define HDMI_AVI_VERSION3 3
|
||||
#define HDMI_AVI_VERSION4 4
|
||||
#define HDMI_AVI_Y2_MASK (0x1 << 2)
|
||||
|
||||
enum HdmiScanMode {
|
||||
HDMI_SCAN_MODE_NO_DATA = 0,
|
||||
HDMI_SCAN_MODE_OVERSCAN = 1,
|
||||
HDMI_SCAN_MODE_UNDERSCAN = 2,
|
||||
HDMI_SCAN_MODE_FUTURE = 3,
|
||||
};
|
||||
|
||||
enum HdmiItContentType {
|
||||
HDMI_IT_CONTENT_TYPE_GRAPHICS = 0,
|
||||
HDMI_IT_CONTENT_TYPE_PHOTO = 1,
|
||||
HDMI_IT_CONTENT_TYPE_CINEMA = 2,
|
||||
HDMI_IT_CONTENT_TYPE_GAME = 3,
|
||||
};
|
||||
|
||||
struct HdmiAviInfoframe {
|
||||
enum HdmiPacketType type;
|
||||
uint8_t verNum;
|
||||
uint8_t len;
|
||||
enum HdmiScanMode scanMode;
|
||||
bool vertBarInfoPresent;
|
||||
bool horizBarInfoPresent;
|
||||
bool activeFormatInformationPresent;
|
||||
enum HdmiColorSpace colorSpace;
|
||||
enum HdmiActiveFormatAspectRatio activeAspect;
|
||||
enum HdmiPictureAspectRatio pictureAspect;
|
||||
enum HdmiColorimetry colorimetry;
|
||||
enum HdmiNups nups;
|
||||
enum HdmiQuantizationRange range;
|
||||
enum HdmiExtendedColorimetry extColorimetry;
|
||||
bool itc; /* IT content */
|
||||
uint8_t vic;
|
||||
uint8_t pixelRepetitionFactor;
|
||||
enum HdmiItContentType itcType;
|
||||
enum HdmiYccQuantizationRange yccRange;
|
||||
uint16_t topBar;
|
||||
uint16_t bottomBar;
|
||||
uint16_t leftBar;
|
||||
uint16_t rightBar;
|
||||
};
|
||||
|
||||
/* Audio infoframe details. */
|
||||
#define HDMI_AUDIO_INFOFRAME_VERSION 1
|
||||
#define HDMI_AUDIO_CODING_TYPE_MARK 0x0f
|
||||
#define HDMI_AUDIO_CHANNEL_COUNT_MARK 0x07
|
||||
#define HDMI_AUDIO_CODING_TYPE_SHIFT 4
|
||||
|
||||
#define HDMI_AUDIO_SAMPLE_FREQUENCY_MARK 0x07
|
||||
#define HDMI_AUDIO_SAMPLE_SIZE_MARK 0x03
|
||||
#define HDMI_AUDIO_SAMPLE_FREQUENCY_SHIFT 2
|
||||
|
||||
#define HDMI_AUDIO_CXT_MARK 0x1f
|
||||
|
||||
#define HDMI_AUDIO_LEVEL_SHIFT_VALUE_MARK 0x0f
|
||||
#define HDMI_AUDIO_LEF_PLAYBACK_LEVEL_MARK 0x03
|
||||
#define HDMI_AUDIO_DM_INH_SHIFT 7
|
||||
#define HDMI_AUDIO_LEVEL_SHIFT_VALUE_SHIFT 3
|
||||
|
||||
enum HdmiAudioSampleSize {
|
||||
HDMI_AUDIO_SAMPLE_SIZE_STREAM = 0,
|
||||
HDMI_AUDIO_SAMPLE_SIZE_16_BIT = 1,
|
||||
HDMI_AUDIO_SAMPLE_SIZE_20_BIT = 2,
|
||||
HDMI_AUDIO_SAMPLE_SIZE_24_BIT = 3,
|
||||
};
|
||||
|
||||
enum HdmiAudioSampleFrequency {
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM = 0,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_32K = 1,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_44_1K = 2,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_48K = 3,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_88_2K = 4,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_96K = 5,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_176_4K = 6,
|
||||
HDMI_AUDIO_SAMPLE_FREQUENCY_192K = 7,
|
||||
};
|
||||
|
||||
enum HdmiAudioCodingExtType {
|
||||
/* Refer to Audio Coding Type (CT) field in Data Byte 1 */
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_CT = 0,
|
||||
|
||||
/*
|
||||
* The next three CXT values are defined in CEA-861-E only.
|
||||
* They do not exist in older versions, and in CEA-861-F they are
|
||||
* defined as 'Not in use'.
|
||||
*/
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_HE_AAC = 1,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_HE_AAC_V2 = 2,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEG_SURROUND = 3,
|
||||
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_HE_AAC = 4,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_HE_AAC_V2 = 5,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_AAC_LC = 6,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_DRA = 7,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_HE_AAC_SURROUND = 8,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_RESERVED = 9,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEG4_AAC_LC_SURROUND = 10,
|
||||
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_MPEGH_3D_AUDIO = 11,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_AC4 = 12,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_LPCM_3D_AUDIO = 13,
|
||||
HDMI_AUDIO_CODING_EXT_TYPET_BUTT,
|
||||
};
|
||||
|
||||
/* LEF(Low Frequency Effects) playback level. */
|
||||
enum HdmiAudioLfePlaybackLevel {
|
||||
HDMI_AUDIO_LFE_PLAYBACK_NULL = 0,
|
||||
HDMI_AUDIO_LFE_PLAYBACK_0DB = 1,
|
||||
HDMI_AUDIO_LFE_PLAYBACK_10DB = 2,
|
||||
HDMI_AUDIO_LFE_PLAYBAC_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiAudioInfoframe {
|
||||
enum HdmiPacketType type;
|
||||
uint8_t verNum;
|
||||
uint8_t len;
|
||||
uint8_t channelCount;
|
||||
enum HdmiAudioCodingType codingType;
|
||||
enum HdmiAudioSampleSize sampleSize;
|
||||
enum HdmiAudioSampleFrequency sampleFreq;
|
||||
enum HdmiAudioCodingExtType codingExtType;
|
||||
uint8_t channelAllocation;
|
||||
enum HdmiAudioLfePlaybackLevel playBackLevel;
|
||||
uint8_t levelShiftValue;
|
||||
bool dmInh; /* Down-mix Inhibit Flag */
|
||||
};
|
||||
|
||||
/* Source Product Description infoframe details. */
|
||||
#define HDMI_SPD_VENDOR_NAME_LEN 8
|
||||
#define HDMI_SPD_PRODUCT_DESCRIPTION_LEN 16
|
||||
#define HDMI_SPD_VERSION 1
|
||||
|
||||
/* SDI(Source Device Information) */
|
||||
enum HdmiSpdSdi {
|
||||
HDMI_SPD_SDI_NULL = 0,
|
||||
HDMI_SPD_SDI_DIGITAL_STB = 1,
|
||||
HDMI_SPD_SDI_DVD_PLAYER = 2,
|
||||
HDMI_SPD_SDI_D_VHS = 3,
|
||||
HDMI_SPD_SDI_HDD_VIDEORECORDER = 4,
|
||||
HDMI_SPD_SDI_DVC = 5,
|
||||
HDMI_SPD_SDI_DSC = 6,
|
||||
HDMI_SPD_SDI_VIDEO_CD = 7,
|
||||
HDMI_SPD_SDI_GAME = 8,
|
||||
HDMI_SPD_SDI_PC_GENERAL = 9,
|
||||
HDMI_SPD_SDI_BLU_RAY_DIS = 10,
|
||||
HDMI_SPD_SDI_SUPER_AUDIO_CD = 11,
|
||||
HDMI_SPD_SDI_HDDVD = 12,
|
||||
HDMI_SPD_SDI_PMP = 13,
|
||||
HDMI_SPD_SDI_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiSpdInfoframe {
|
||||
enum HdmiPacketType type;
|
||||
uint8_t verNum;
|
||||
uint8_t len;
|
||||
char vendorName[HDMI_SPD_VENDOR_NAME_LEN];
|
||||
char productDescription[HDMI_SPD_PRODUCT_DESCRIPTION_LEN];
|
||||
enum HdmiSpdSdi sdi;
|
||||
};
|
||||
|
||||
/* Dynamic Range and Mastering infoframe details. */
|
||||
#define HDMI_DRM_METADATA_MARK 0xff
|
||||
#define HDMI_DRM_METADATA_SHIFT 8
|
||||
#define HDMI_DRM_INFOFRAME_VERSION 1
|
||||
|
||||
struct HdmiDrmInfoframe {
|
||||
enum HdmiPacketType type;
|
||||
uint8_t verNum;
|
||||
uint8_t len;
|
||||
enum HdmiEotfType eotfType;
|
||||
enum HdmiStaticMetadataType metadataType;
|
||||
union HdmiStaticMetadataDescriptor des;
|
||||
};
|
||||
|
||||
/* GBD(gamut boundary description) */
|
||||
union HdmiGbdHb1{
|
||||
struct {
|
||||
uint8_t affectedGamutSeqNum : 4; /* [0:3] */
|
||||
uint8_t gbdProfil : 3; /* [4:5] */
|
||||
uint8_t reseverd: 1; /* [6] */
|
||||
uint8_t noCrntGbd : 1; /* [7] */
|
||||
} bits;
|
||||
uint8_t val;
|
||||
};
|
||||
|
||||
union HdmiGbdHb2{
|
||||
struct {
|
||||
uint8_t currentGamutSeqNum : 4; /* [0:3] */
|
||||
uint8_t packetSeq : 2; /* [4:5] */
|
||||
uint8_t nextField : 1; /* [7] */
|
||||
} bits;
|
||||
uint8_t val;
|
||||
};
|
||||
|
||||
union HdmiGbdRangeData0 {
|
||||
struct {
|
||||
uint8_t gbdColorSpace : 3; /* [0:2] */
|
||||
uint8_t gbdColorPercision : 2; /* [3:4] */
|
||||
uint8_t rsvd: 2; /* [5:6] */
|
||||
uint8_t formatFlag : 1; /* [7] */
|
||||
} bits;
|
||||
uint8_t val;
|
||||
};
|
||||
|
||||
struct HdmiGbdPacket {
|
||||
uint8_t hb0;
|
||||
union HdmiGbdHb1 hb1;
|
||||
union HdmiGbdHb2 hb2;
|
||||
union HdmiGbdRangeData0 data0;
|
||||
uint8_t minRedDataH;
|
||||
uint8_t midRedData; /* Min_Red_Data_L | Max_Red_Data_H */
|
||||
uint8_t maxRedDataL;
|
||||
uint8_t minGreenDataH;
|
||||
uint8_t midGreenData; /* Min_Green_Data_L | Max_Green_Data_H */
|
||||
uint8_t maxGreenDataL;
|
||||
uint8_t minBlueDataH;
|
||||
uint8_t midBlueData; /* Min_Blue_Data_L | Max_Blue_Data_H */
|
||||
uint8_t maxBlueDataL;
|
||||
};
|
||||
|
||||
union HdmiInfoframeInfo {
|
||||
struct HdmiInfoframeHeader header;
|
||||
struct HdmiVsInfoframe vs;
|
||||
struct HdmiAviInfoframe avi;
|
||||
struct HdmiAudioInfoframe audio;
|
||||
struct HdmiSpdInfoframe spd;
|
||||
struct HdmiDrmInfoframe drm;
|
||||
struct HdmiGbdPacket gbd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Infoframe: A data structure defined in CEA-861-D that is designed to carry a variety of auxiliary data items
|
||||
* regarding the audio or video streams or the source device and is carried from Source to Sink across HDMI.
|
||||
*/
|
||||
struct HdmiInfoframe {
|
||||
enum HdmiPacketType infoframeType;
|
||||
bool hdrSupport;
|
||||
struct HdmiVsInfoframe vs;
|
||||
struct HdmiAviInfoframe avi;
|
||||
struct HdmiAudioInfoframe audio;
|
||||
struct HdmiSpdInfoframe spd;
|
||||
struct HdmiDrmInfoframe drm;
|
||||
struct HdmiGbdPacket gbd;
|
||||
struct HdmiVsUserVsifContent userVsif;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct HdmiInfoframeStatus {
|
||||
bool vsifEnable;
|
||||
bool aviEnable;
|
||||
bool audioEnable;
|
||||
bool spdEnable;
|
||||
bool drmEnable;
|
||||
bool gdbEnable;
|
||||
uint8_t avi[HDMI_INFOFRAME_LEN];
|
||||
uint8_t audio[HDMI_INFOFRAME_LEN];
|
||||
uint8_t vsif[HDMI_INFOFRAME_LEN];
|
||||
uint8_t spd[HDMI_INFOFRAME_LEN];
|
||||
uint8_t drm[HDMI_INFOFRAME_LEN];
|
||||
uint8_t gdb[HDMI_INFOFRAME_LEN];
|
||||
};
|
||||
|
||||
int32_t HdmiAudioInfoframeSend(struct HdmiInfoframe *frame, bool enable);
|
||||
int32_t HdmiAviInfoframeSend(struct HdmiInfoframe *frame, bool enable);
|
||||
int32_t HdmiDrmInfoframeSend(struct HdmiInfoframe *frame, bool enable);
|
||||
int32_t HdmiVsInfoframeSend(struct HdmiInfoframe *frame, bool enable, bool dolbyEnable);
|
||||
int32_t HdmiSpdInfoframeSend(struct HdmiInfoframe *frame, bool enable,
|
||||
char *vendorName, char *productName, enum HdmiSpdSdi sdi);
|
||||
int32_t HdmiInfoframeGetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
|
||||
union HdmiInfoframeInfo *infoframe);
|
||||
int32_t HdmiInfoframeSetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
|
||||
union HdmiInfoframeInfo *infoframe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_INFOFRAME_H */
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_NCTS_H
|
||||
#define HDMI_NCTS_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* N/CTS(Cycle Time Stamp), see hdmi1.4 spec section 7.2. */
|
||||
#define HDMI_NCTS_FACTOR 128
|
||||
#define HDMI_NCTS_N_DEFAULT 6144
|
||||
#define HDMI_NCTS_TMDS_DEVIATION 20
|
||||
|
||||
struct HdmiAudioNCts {
|
||||
uint32_t sampleRate; /* audio sample rate(fs) */
|
||||
uint32_t tmdsClock;
|
||||
uint32_t n;
|
||||
uint32_t cts;
|
||||
};
|
||||
|
||||
uint32_t HdmiGetN(uint32_t sampleRate, uint32_t tmdsClock);
|
||||
uint32_t HdmiGetCts(uint32_t sampleRate, uint32_t tmdsClock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_NCTS_H */
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#ifndef HDMI_SCDC_H
|
||||
#define HDMI_SCDC_H
|
||||
|
||||
#include "hdf_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* SCDC(Status and Control Data Channel) */
|
||||
#define HDMI_SCDC_HDMI20_VERSION 1
|
||||
#define HDMI_SCDC_DEFAULT_SCRAMBLE_TIMEOUT 200 /* ms */
|
||||
|
||||
/*
|
||||
* SCDCS(Status and Control Data Channel Structure).
|
||||
* see hdmi2.0 spec table 10-15.
|
||||
*/
|
||||
enum HdmiScdcsOffset {
|
||||
HDMI_SCDCS_OFFSET_SINK_VERSION = 0x01,
|
||||
HDMI_SCDCS_OFFSET_SOURCE_VERSION = 0x02,
|
||||
HDMI_SCDCS_OFFSET_UPDATE_0 = 0x10,
|
||||
HDMI_SCDCS_OFFSET_UPDATE_1 = 0x11,
|
||||
HDMI_SCDCS_OFFSET_TMDS_CONFIG = 0x20,
|
||||
HDMI_SCDCS_OFFSET_SCRAMBLER_STATUS = 0x21,
|
||||
HDMI_SCDCS_OFFSET_CONFIG_0 = 0x30,
|
||||
HDMI_SCDCS_OFFSET_CONFIG_1 = 0x31,
|
||||
HDMI_SCDCS_OFFSET_TEST_CONFIG_1 = 0x35,
|
||||
HDMI_SCDCS_OFFSET_STASTUS_FLAG_0 = 0x40,
|
||||
HDMI_SCDCS_OFFSET_STASTUS_FLAG_1 = 0x41,
|
||||
HDMI_SCDCS_OFFSET_STASTUS_FLAG_2 = 0x42,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_0_L = 0x50,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_0_H = 0x51,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_1_L = 0x52,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_1_H = 0x53,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_2_L = 0x54,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_2_H = 0x55,
|
||||
HDMI_SCDCS_OFFSET_ERR_DET_CHECKSUM = 0x56,
|
||||
HDMI_SCDCS_OFFSET_TEST_CONFIG_0 = 0xC0,
|
||||
HDMI_SCDCS_OFFSET_IEEE_OUI_3TH = 0xD0,
|
||||
HDMI_SCDCS_OFFSET_IEEE_OUI_2ND = 0xD1,
|
||||
HDMI_SCDCS_OFFSET_IEEE_OUI_1ST = 0xD2,
|
||||
HDMI_SCDCS_OFFSET_DEVICE_ID_START = 0xD3,
|
||||
HDMI_SCDCS_OFFSET_DEVICE_ID_END = 0xDD,
|
||||
HDMI_SCDCS_OFFSET_SPECIFIC_START = 0xDE,
|
||||
HDMI_SCDCS_OFFSET_SPECIFIC_END = 0xFF,
|
||||
};
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.3.
|
||||
* All update flags are readable and writable.
|
||||
* The purpose of these flags is to provide a mechanism for the sink device to efficiently inform the source device
|
||||
* that additional source device action may be required.
|
||||
*/
|
||||
union HdmiScdcsUpdateFlag0 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t statusUpdate : 1; /* The sink shall set this bit when value is changed in the Status Flag register. */
|
||||
uint8_t cedUpdate : 1; /* ced(character error detection) register. */
|
||||
uint8_t rrTest : 1; /* rr(Read Request) */
|
||||
uint8_t srcTestUpdate : 1;
|
||||
uint8_t frlStart : 1;
|
||||
uint8_t fltUpdate : 1;
|
||||
uint8_t rsedUpdate : 1;
|
||||
uint8_t reserved : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
#define HDMI_SCDC_STATUS_UPDATE_MARK (1 << 0)
|
||||
#define HDMI_SCDC_CED_UPDATE_MARK (1 << 1)
|
||||
#define HDMI_SCDC_RR_TEST_MARK (1 << 2)
|
||||
#define HDMI_SCDC_SRC_TEST_UPDATE_MARK (1 << 3)
|
||||
#define HDMI_SCDC_FRL_START_MARK (1 << 4)
|
||||
#define HDMI_SCDC_FLT_UPDATE_MARK (1 << 5)
|
||||
#define HDMI_SCDC_RSED_UPDATE_MARK (1 << 6)
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.4.
|
||||
* All Configuration fields are readable and writable.
|
||||
*/
|
||||
union HdmiScdcsTmdsConfig {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t scramblingEnable : 1;
|
||||
uint8_t tmdsBitClockRatio: 1; /*
|
||||
* 0: TMDS_Bit_Period/TMDS_Clock_Period is 1/10;
|
||||
* 1: TMDS_Bit_Period/TMDS_Clock_Period is 1/40.
|
||||
*/
|
||||
uint8_t reserved : 6;
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.5.
|
||||
* The Status Flags are all Read Only.
|
||||
*/
|
||||
union HdmiScdcsScramblerStatus {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t scramblingStatus : 1;
|
||||
uint8_t reserved : 7;
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see hdmi2.0 spec table 10-21.
|
||||
* All Configuration fields are readable and writable.
|
||||
*/
|
||||
union HdmiScdcsConfig0 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t rrEnable : 1; /*
|
||||
* The source set this bit when the source supports Read Request.
|
||||
* The sink shall reset this bit when SCDC of the sink goes from the disabled to enabled.
|
||||
*/
|
||||
uint8_t fltNoRetrain : 1;
|
||||
uint8_t reserved : 6;
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.6.
|
||||
*/
|
||||
union HdmiScdcsConfig1 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t frlRate : 4; /*
|
||||
* Source select the FRL rate and Lane count by writing into this register.
|
||||
* This field is written by the Source during the Link Training protocol.
|
||||
*/
|
||||
uint8_t ffeLevels : 4;
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.6.
|
||||
*/
|
||||
union HdmiScdcsTestConfig1 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t reserved0 : 1;
|
||||
uint8_t preShootIOnly : 1;
|
||||
uint8_t deEmphasisOnly : 1;
|
||||
uint8_t noFfe : 1;
|
||||
uint8_t reserved1 : 1;
|
||||
uint8_t fltNoTimeout : 1;
|
||||
uint8_t dscFrlMax : 1;
|
||||
uint8_t frlMax : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
#define HDMI_SCDC_PRE_SHOOT_ONLY_MARK (1 << 1)
|
||||
#define HDMI_SCDC_DE_EMPHASIS_ONLY_MARK (1 << 2)
|
||||
#define HDMI_SCDC_NO_FFE_MARK (1 << 3)
|
||||
#define HDMI_SCDC_FLT_NO_TIMEOUT_MARK (1 << 5)
|
||||
#define HDMI_SCDC_DSC_FRL_MAX_MARK (1 << 6)
|
||||
#define HDMI_SCDC_FRL_MAX_MARK (1 << 7)
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.7.
|
||||
* The Status Flags are all Read Only.
|
||||
*/
|
||||
union HdmiScdcsStatusFlag0 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t clockDetected : 1; /* This bit shall be set by the sink when the sink detects a valid clock signal. */
|
||||
uint8_t ch0Locked : 1; /*
|
||||
* This bit shall be set by the sink when the sink is successfully decoding
|
||||
* data on HDMI Channel 0.
|
||||
*/
|
||||
uint8_t ch1Locked : 1; /*
|
||||
* This bit shall be set by the sink when the sink is successfully decoding
|
||||
* data on HDMI Channel 1.
|
||||
*/
|
||||
uint8_t ch2Locked : 1; /*
|
||||
* This bit shall be set by the sink when the sink is successfully decoding
|
||||
* data on HDMI Channel 2.
|
||||
*/
|
||||
uint8_t ch3Locked : 1;
|
||||
uint8_t reserved : 1;
|
||||
uint8_t fltReady : 1;
|
||||
uint8_t dscDecodeFail : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
#define HDMI_SCDC_CLOCK_DETECTED_MARK (1 << 0)
|
||||
#define HDMI_SCDC_CH0_LOCKED_MARK (1 << 1)
|
||||
#define HDMI_SCDC_CH1_LOCKED_MARK (1 << 2)
|
||||
#define HDMI_SCDC_CH2_LOCKED_MARK (1 << 3)
|
||||
#define HDMI_SCDC_CH3_LOCKED_MARK (1 << 4)
|
||||
#define HDMI_SCDC_FLT_READY_MARK (1 << 6)
|
||||
#define HDMI_SCDC_DSC_DECODE_FAIL_MARK (1 << 7)
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.7.
|
||||
* The Status Flags are all Read Only.
|
||||
*/
|
||||
union HdmiScdcsStatusFlag1 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t ln0LtpReq : 4;
|
||||
uint8_t ln1LtpReq : 4;
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see HDMI2.1 section 10.4.1.7.
|
||||
* The Status Flags are all Read Only.
|
||||
*/
|
||||
union HdmiScdcsStatusFlag2 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t ln2LtpReq : 4;
|
||||
uint8_t ln3LtpReq : 4;
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see hdmi2.0 spec table 10-23. Offeset 0x50~0x55.
|
||||
* The Character Error Detection counters are not writable by the source and are cleared on read by the source.
|
||||
*/
|
||||
union HdmiScdcsCharacterErrorDetection {
|
||||
uint16_t data;
|
||||
struct {
|
||||
uint16_t chErrCntLower : 8; /* Channel 0/1/2 Erroe Count bits 7->0 */
|
||||
uint16_t chErrCntUpper : 7; /* Channel 0/1/2 Erroe Count bits 14->8 */
|
||||
uint16_t chValid : 1; /* Channel 0/1/2 valid flag */
|
||||
} bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* see hdmi2.0 spec table 10-24.
|
||||
* The Test Configuration registers are privided to facilitate compliance testing.
|
||||
*/
|
||||
union HdmiScdcsTestConfig0 {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t testReadRequestDelay : 7;
|
||||
uint8_t testReadRequest : 1; /* Read/Write */
|
||||
} bits;
|
||||
};
|
||||
|
||||
struct HdmiScdcsRegStatus {
|
||||
uint8_t sinkVersion;
|
||||
uint8_t sourceVersion; /* R/W */
|
||||
union HdmiScdcsUpdateFlag0 upfate0; /* R/W */
|
||||
union HdmiScdcsTmdsConfig tmdsCfg; /* R/W */
|
||||
union HdmiScdcsScramblerStatus scramblerStatus;
|
||||
union HdmiScdcsConfig0 cfg0; /* R/W */
|
||||
union HdmiScdcsStatusFlag0 statusFlag0;
|
||||
union HdmiScdcsCharacterErrorDetection errDet0;
|
||||
union HdmiScdcsCharacterErrorDetection errDet1;
|
||||
union HdmiScdcsCharacterErrorDetection errDet2;
|
||||
uint8_t errDetChecksum;
|
||||
union HdmiScdcsTestConfig0 testCfg0; /* R/W */
|
||||
uint8_t ieeeOui[HDMI_SCDCS_OFFSET_IEEE_OUI_1ST - HDMI_SCDCS_OFFSET_IEEE_OUI_3TH + 1];
|
||||
uint8_t deviceId[HDMI_SCDCS_OFFSET_DEVICE_ID_END - HDMI_SCDCS_OFFSET_DEVICE_ID_START + 1];
|
||||
};
|
||||
|
||||
struct HdmiScdcScrambleCap {
|
||||
bool sinkScramble;
|
||||
bool sourceScramble;
|
||||
bool tmdsBitClockRatio40;
|
||||
};
|
||||
|
||||
struct HdmiScdcAttribute {
|
||||
bool sinkReadRequest;
|
||||
bool srcScramble;
|
||||
bool sinkScramble;
|
||||
bool tmdsBitClockRatio40;
|
||||
uint32_t ScrambleTimeOut;
|
||||
uint32_t ScrambleInterval;
|
||||
};
|
||||
|
||||
struct HdmiScdc {
|
||||
struct HdmiScdcsRegStatus status;
|
||||
struct HdmiScdcAttribute attr;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* used for frl. */
|
||||
enum HdmiScdcOptMsg {
|
||||
HDMI_SCDC_OPT_SET_SOURCE_VER = 0,
|
||||
HDMI_SCDC_OPT_GET_SOURCE_VER = 1,
|
||||
HDMI_SCDC_OPT_GET_SINK_VER = 2,
|
||||
HDMI_SCDC_OPT_SET_FLT_UPDATE = 3,
|
||||
HDMI_SCDC_OPT_GET_FLT_UPDATE = 4,
|
||||
HDMI_SCDC_OPT_SET_FRL_START = 5,
|
||||
HDMI_SCDC_OPT_GET_FRL_START = 6,
|
||||
HDMI_SCDC_OPT_SET_CONFIG1 = 7,
|
||||
HDMI_SCDC_OPT_GET_CONFIG1 = 8,
|
||||
HDMI_SCDC_OPT_GET_TEST_CONFIG_1 = 9,
|
||||
HDMI_SCDC_OPT_GET_FLT_READY = 10,
|
||||
HDMI_SCDC_OPT_GET_LTP_REQ = 11,
|
||||
HDMI_SCDC_OPT_BUTT,
|
||||
};
|
||||
|
||||
int32_t HdmiScdcScrambleSet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble);
|
||||
int32_t HdmiScdcScrambleGet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble);
|
||||
bool HdmiScdcSinkSupport(struct HdmiScdc *scdc);
|
||||
void HdmiScdcReset(struct HdmiScdc *scdc);
|
||||
int32_t HdmiScdcOptMsgHandle(struct HdmiScdc *scdc, enum HdmiScdcOptMsg msg, uint8_t *buffer, uint32_t len);
|
||||
int32_t HdmiScdcFillScrambleCap(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble,
|
||||
enum HdmiTmdsModeType *tmdsMode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HDMI_SCDC_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_common.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_common_c
|
||||
|
||||
/*
|
||||
* vic, pixel clk, vfreq, hactive, vactive, hblank, vblank, hfront, hsync, hback, vfront, vsync, vback, aspect,
|
||||
* timing, I/P
|
||||
*/
|
||||
struct HdmiVideoDefInfo g_ceaVideoDefInfoMap[HDMI_CEA_VIDEO_CODE_MAX] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
HDMI_PICTURE_ASPECT_NO_DATA, HDMI_VIDEO_TIMING_NONE, HDMI_VIDEO_FORMAT_NULL },
|
||||
{ HDMI_VIC_640X480P60_4_3, 25175, 59940, 640, 480, 160, 45, 16, 96, 48, 10, 2, 33,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_640X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_720X480P60_4_3, 27000, 59940, 720, 480, 138, 45, 16, 62, 60, 9, 6, 30,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_720X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_720X480P60_16_9, 27000, 59940, 720, 480, 138, 45, 16, 62, 60, 9, 6, 30,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_720X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1280X720P60_16_9, 74250, 60000, 1280, 720, 370, 30, 110, 40, 220, 5, 5, 20,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1280X720P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080I60_16_9, 74250, 60000, 1920, 1080, 280, 22, 88, 44, 148, 2, 5, 15,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080I60, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_1440X480I60_4_3, 27000, 59940, 1440, 480, 276, 22, 38, 124, 114, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X480I60, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_1440X480I60_16_9, 27000, 59940, 1440, 480, 276, 22, 38, 124, 114, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X480I60, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_1440X240P60_4_3, 27000, 60054, 1440, 240, 276, 22, 38, 124, 114, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X240P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1440X240P60_16_9, 27000, 60054, 1440, 240, 276, 22, 38, 124, 114, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X240P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_2880X480I60_4_3, 54000, 59940, 2880, 480, 552, 22, 76, 248, 228, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_2880X480I60, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_2880X480I60_16_9, 54000, 59940, 2880, 480, 552, 22, 76, 248, 228, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_2880X480I60, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_2880X240P60_4_3, 54000, 60054, 2880, 240, 552, 22, 76, 248, 228, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_2880X240I60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_2880X240P60_16_9, 54000, 60054, 2880, 240, 552, 23, 76, 248, 228, 4, 3, 15,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_2880X240I60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1440X480P60_4_3, 54000, 59940, 1440, 480, 276, 45, 32, 124, 120, 9, 6, 30,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1440X480P60_16_9, 54000, 59940, 1440, 480, 276, 45, 32, 124, 120, 9, 6, 30,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X480P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080P60_16_9, 148500, 60000, 1920, 1080, 280, 45, 88, 44, 148, 4, 5, 36,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_720X576P50_4_3, 27000, 50000, 720, 576, 144, 49, 12, 64, 68, 5, 5, 39,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_720X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_720X576P50_16_9, 27000, 50000, 720, 576, 144, 49, 12, 64, 68, 5, 5, 39,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_720X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1280X720P50_16_9, 74250, 50000, 1280, 720, 700, 30, 440, 40, 220, 5, 5, 20,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1280X720P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080I50_16_9, 74250, 50000, 1920, 1080, 720, 24, 528, 44, 148, 2, 5, 15,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080I50, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_1440X576I50_4_3, 27000, 50000, 1440, 576, 288, 24, 24, 126, 138, 2, 3, 19,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X576I50, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_1440X576I50_16_9, 27000, 50000, 1440, 576, 288, 24, 24, 126, 138, 2, 3, 19,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X576I50, HDMI_VIDEO_FORMA_INTERLACE },
|
||||
{ HDMI_VIC_1440X576P50_4_3, 54000, 50000, 1440, 576, 288, 49, 24, 128, 136, 5, 5, 39,
|
||||
HDMI_PICTURE_ASPECT_4_3, HDMI_VIDEO_TIMING_1440X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1440X576P50_16_9, 54000, 50000, 1440, 576, 288, 49, 24, 128, 136, 5, 5, 39,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1440X576P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080P50_16_9, 148500, 50000, 1920, 1080, 720, 45, 528, 44, 148, 4, 5, 36,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080P24_16_9, 742500, 24000, 1920, 1080, 830, 45, 638, 44, 148, 4, 5, 36,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080P25_16_9, 742500, 25000, 1920, 1080, 720, 45, 528, 44, 148, 4, 5, 36,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_1920X1080P30_16_9, 742500, 30000, 1920, 1080, 280, 45, 88, 44, 148, 4, 5, 36,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_1920X1080P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_3840X2160P24_16_9, 297000, 24000, 3840, 2160, 1660, 90, 1276, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_3840X2160P25_16_9, 297000, 25000, 3840, 2160, 1440, 90, 1056, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_3840X2160P30_16_9, 297000, 30000, 3840, 2160, 560, 90, 176, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_3840X2160P50_16_9, 594000, 50000, 3840, 2160, 1440, 90, 1056, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_3840X2160P60_16_9, 594000, 60000, 3840, 2160, 560, 90, 176, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_4096X2160P24_256_135, 297000, 24000, 4096, 2160, 1404, 90, 1020, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_4096X2160P25_256_135, 297000, 25000, 4096, 2160, 1184, 90, 968, 88, 128, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_4096X2160P30_256_135, 297000, 30000, 4096, 2160, 304, 90, 88, 88, 128, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_4096X2160P50_256_135, 594000, 50000, 4096, 2160, 1184, 90, 968, 88, 128, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P50, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_4096X2160P60_256_135, 594000, 60000, 4096, 2160, 304, 90, 88, 88, 128, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_3840X2160P120_16_9, 1188000, 120000, 3840, 2160, 560, 90, 176, 88, 296, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P120, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_7680X4320P24_16_9, 1188000, 24000, 7680, 4320, 3320, 180, 2552, 176, 592, 16, 20, 144,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_7680X4320P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_7680X4320P25_16_9, 1188000, 25000, 7680, 4320, 3120, 80, 2352, 176, 592, 16, 20, 44,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_7680X4320P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_7680X4320P30_16_9, 1188000, 30000, 7680, 4320, 1320, 80, 552, 176, 592, 16, 20, 44,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_7680X4320P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_VIC_4096X2160P120_256_135, 1188000, 120000, 4096, 2160, 304, 90, 88, 88, 128, 8, 10, 72,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P120, HDMI_VIDEO_FORMAT_PROGRESSIVE }
|
||||
};
|
||||
|
||||
struct HdmiVideoDefInfo g_vesaVideoDefInfoMap[HDMI_VESA_VIDEO_CODE_MAX] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, HDMI_PICTURE_ASPECT_NO_DATA,
|
||||
HDMI_VIDEO_TIMING_NONE, HDMI_VIDEO_FORMAT_NULL },
|
||||
{ 0, 40000, 60317, 800, 600, 256, 28, 40, 128, 88, 1, 4, 23, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_800X600_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 33750, 60000, 848, 480, 240, 37, 16, 112, 112, 6, 8, 23, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_848X480_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 65000, 60004, 1024, 768, 320, 38, 24, 136, 160, 3, 6, 29, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1024X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 74250, 60000, 1280, 720, 370, 30, 110, 40, 220, 5, 5, 20, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X720_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 68250, 59995, 1280, 768, 160, 22, 48, 32, 80, 3, 7, 12, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X768_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 79500, 59870, 1280, 768, 384, 30, 64, 128, 192, 3, 7, 20, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 71001, 59910, 1280, 800, 160, 23, 48, 32, 80, 3, 6, 14, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X800_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 83500, 59810, 1280, 800, 400, 31, 72, 128, 200, 3, 6, 22, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X800_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 108000, 60000, 1280, 960, 520, 40, 96, 112, 312, 1, 3, 36, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X960_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 108000, 60020, 1280, 1024, 408, 42, 48, 112, 248, 1, 3, 38, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1280X1024_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 85500, 60015, 1360, 768, 432, 27, 64, 112, 256, 3, 6, 18, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1360X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 85501, 59790, 1366, 768, 426, 30, 70, 143, 213, 3, 3, 24, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1366X768_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 121749, 59978, 1400, 1050, 464, 39, 88, 144, 232, 3, 4, 32, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1400X1050_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 88749, 59901, 1440, 900, 160, 26, 48, 32, 80, 3, 6, 17, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X900_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 106499, 59887, 1440, 900, 464, 34, 80, 152, 232, 3, 6, 25, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X900_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 108000, 60000, 1440, 1050, 144, 49, 12, 64, 68, 3, 6, 25, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X1050_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 108000, 60000, 1440, 1050, 144, 49, 12, 64, 68, 3, 6, 25, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1440X1050_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 108000, 60000, 1600, 900, 200, 100, 24, 80, 96, 1, 3, 96, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1600X900_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 162000, 60000, 1600, 1200, 560, 50, 64, 192, 304, 1, 3, 46, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1600X1200_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 118999, 59883, 1680, 1050, 160, 30, 48, 32, 80, 3, 6, 21, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1680X1050_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 146249, 59954, 1680, 1050, 560, 39, 104, 176, 280, 3, 6, 30, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1680X1050_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 204751, 60000, 1792, 1344, 656, 50, 128, 200, 328, 1, 3, 46, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1792X1344_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 218249, 59995, 1856, 1392, 672, 47, 96, 224, 352, 1, 3, 43, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1856X1392_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 148500, 60000, 1920, 1080, 280, 45, 88, 44, 148, 4, 5, 36, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1080_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 154000, 59950, 1920, 1200, 160, 35, 48, 32, 80, 3, 6, 26, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1200_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 193251, 59885, 1920, 1200, 672, 45, 136, 200, 336, 3, 6, 36, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1200_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 234000, 60000, 1920, 1440, 680, 60, 128, 208, 344, 1, 3, 56, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_1920X1440_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 162000, 60000, 2048, 1152, 202, 48, 26, 80, 96, 1, 3, 44, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_2048X1152_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 82500, 50000, 2560, 1440, 520, 30, 260, 40, 220, 3, 3, 24, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_2560X1440_60_RB, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ 0, 348502, 59987, 2560, 1600, 944, 58, 192, 280, 472, 3, 6, 49, HDMI_PICTURE_ASPECT_16_9,
|
||||
HDMI_VIDEO_TIMING_VESA_2560X1600_60, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
};
|
||||
|
||||
struct HdmiVideo4kInfo g_video4kInfoMap[HDMI_VIDEO_4K_CODES_MAX] = {
|
||||
{ HDMI_4K_VIC_3840X2160_30, HDMI_VIC_3840X2160P30_16_9, 296703, 30, 3840, 2160,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P30, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_4K_VIC_3840X2160_25, HDMI_VIC_3840X2160P25_16_9, 297000, 25, 3840, 2160,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P25, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_4K_VIC_3840X2160_24, HDMI_VIC_3840X2160P24_16_9, 296703, 24, 3840, 2160,
|
||||
HDMI_PICTURE_ASPECT_16_9, HDMI_VIDEO_TIMING_3840X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE },
|
||||
{ HDMI_4K_VIC_4096X2160_24, HDMI_VIC_4096X2160P24_256_135, 297000, 24, 4096, 2160,
|
||||
HDMI_PICTURE_ASPECT_256_135, HDMI_VIDEO_TIMING_4096X2160P24, HDMI_VIDEO_FORMAT_PROGRESSIVE }
|
||||
};
|
||||
|
||||
enum HdmiVideoBitDepth HdmiCommonDeepClolorConvertToColorDepth(enum HdmiDeepColor deepColor)
|
||||
{
|
||||
enum HdmiVideoBitDepth colorDepth;
|
||||
|
||||
switch (deepColor) {
|
||||
case HDMI_DEEP_COLOR_24BITS :
|
||||
colorDepth = HDMI_VIDEO_BIT_DEPTH_8;
|
||||
break;
|
||||
case HDMI_DEEP_COLOR_30BITS :
|
||||
colorDepth = HDMI_VIDEO_BIT_DEPTH_10;
|
||||
break;
|
||||
case HDMI_DEEP_COLOR_36BITS :
|
||||
colorDepth = HDMI_VIDEO_BIT_DEPTH_12;
|
||||
break;
|
||||
case HDMI_DEEP_COLOR_48BITS :
|
||||
colorDepth = HDMI_VIDEO_BIT_DEPTH_16;
|
||||
break;
|
||||
default :
|
||||
HDF_LOGD("deep color %d is not support, use default value.", deepColor);
|
||||
colorDepth = HDMI_VIDEO_BIT_DEPTH_8;
|
||||
break;
|
||||
}
|
||||
return colorDepth;
|
||||
}
|
||||
|
||||
enum HdmiDeepColor HdmiCommonColorDepthConvertToDeepClolor(enum HdmiVideoBitDepth colorDepth)
|
||||
{
|
||||
enum HdmiDeepColor deepColor;
|
||||
|
||||
switch (colorDepth) {
|
||||
case HDMI_VIDEO_BIT_DEPTH_8 :
|
||||
deepColor = HDMI_DEEP_COLOR_24BITS;
|
||||
break;
|
||||
case HDMI_VIDEO_BIT_DEPTH_10 :
|
||||
deepColor = HDMI_DEEP_COLOR_30BITS;
|
||||
break;
|
||||
case HDMI_VIDEO_BIT_DEPTH_12 :
|
||||
deepColor = HDMI_DEEP_COLOR_36BITS;
|
||||
break;
|
||||
case HDMI_VIDEO_BIT_DEPTH_16 :
|
||||
deepColor = HDMI_DEEP_COLOR_48BITS;
|
||||
break;
|
||||
case HDMI_VIDEO_BIT_DEPTH_OFF :
|
||||
deepColor = HDMI_DEEP_COLOR_OFF;
|
||||
break;
|
||||
default :
|
||||
deepColor = HDMI_DEEP_COLOR_BUTT;
|
||||
break;
|
||||
}
|
||||
return deepColor;
|
||||
}
|
||||
|
||||
enum HdmiVic HdmiCommonGetVic(enum HdmiVideoTiming timing,
|
||||
enum HdmiPictureAspectRatio aspect, bool enable3d)
|
||||
{
|
||||
uint32_t i, len;
|
||||
enum HdmiVic vic = 0;
|
||||
|
||||
len = sizeof(g_ceaVideoDefInfoMap) / sizeof(g_ceaVideoDefInfoMap[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (timing == g_ceaVideoDefInfoMap[i].timing && aspect == g_ceaVideoDefInfoMap[i].aspect) {
|
||||
vic = g_ceaVideoDefInfoMap[i].vic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enable3d == true) {
|
||||
/* see hdmi spec 10.2. */
|
||||
if (vic == HDMI_VIC_3840X2160P24_16_9 || vic == HDMI_VIC_3840X2160P25_16_9 ||
|
||||
vic == HDMI_VIC_3840X2160P30_16_9 || vic == HDMI_VIC_4096X2160P24_256_135) {
|
||||
HDF_LOGI("4k x 2k 2D vic:%d.", vic);
|
||||
vic = HDMI_VIC_NONE;
|
||||
}
|
||||
}
|
||||
return vic;
|
||||
}
|
||||
|
||||
static struct HdmiVideoDefInfo *HdmiCommonGetCommFormatInfo(enum HdmiVic vic)
|
||||
{
|
||||
uint32_t i, len;
|
||||
|
||||
len = sizeof(g_ceaVideoDefInfoMap) / sizeof(g_ceaVideoDefInfoMap[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (vic == g_ceaVideoDefInfoMap[i].vic) {
|
||||
return &g_ceaVideoDefInfoMap[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct HdmiVideoDefInfo *HdmiCommonGetVesaFormatInfo(enum HdmiVideoTiming timing)
|
||||
{
|
||||
uint32_t i, len;
|
||||
|
||||
len = sizeof(g_vesaVideoDefInfoMap) / sizeof(g_vesaVideoDefInfoMap[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (timing == g_vesaVideoDefInfoMap[i].timing) {
|
||||
return &g_vesaVideoDefInfoMap[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct HdmiVideoDefInfo *HdmiCommonGetVideoDefInfo(enum HdmiVideoTiming timing,
|
||||
enum HdmiPictureAspectRatio aspect, bool enable3d)
|
||||
{
|
||||
enum HdmiVic vic;
|
||||
struct HdmiVideoDefInfo *info = NULL;
|
||||
|
||||
if (timing < HDMI_VIDEO_TIMING_VESA_DEFINE) {
|
||||
vic = HdmiCommonGetVic(timing, aspect, enable3d);
|
||||
info = HdmiCommonGetCommFormatInfo(vic);
|
||||
} else if (timing < HDMI_VIDEO_TIMING_USER_DEFINE) {
|
||||
info = HdmiCommonGetVesaFormatInfo(timing);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
enum HdmiVideoTiming HdmiCommonGetVideoTiming(enum HdmiVic vic, enum HdmiPictureAspectRatio aspect)
|
||||
{
|
||||
uint32_t i, len;
|
||||
enum HdmiVideoTiming timing = HDMI_VIDEO_TIMING_NONE;
|
||||
|
||||
len = sizeof(g_ceaVideoDefInfoMap) / sizeof(g_ceaVideoDefInfoMap[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (vic == g_ceaVideoDefInfoMap[i].vic && aspect == g_ceaVideoDefInfoMap[i].aspect) {
|
||||
timing = g_ceaVideoDefInfoMap[i].timing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return timing;
|
||||
}
|
||||
|
||||
struct HdmiVideo4kInfo *HdmiCommonGetVideo4kInfo(uint32_t _4kVic)
|
||||
{
|
||||
uint32_t i, len;
|
||||
|
||||
len = sizeof(g_video4kInfoMap) / sizeof(g_video4kInfoMap[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (_4kVic == g_video4kInfoMap[i]._4kVic) {
|
||||
return &g_video4kInfoMap[i];
|
||||
}
|
||||
}
|
||||
HDF_LOGD("4k not support vic = %u", _4kVic);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum HdmiVideoTiming HdmiCommonGetVideo4kTiming(uint32_t _4kVic)
|
||||
{
|
||||
uint32_t i, len;
|
||||
enum HdmiVideoTiming timing = HDMI_VIDEO_TIMING_NONE;
|
||||
|
||||
len = sizeof(g_video4kInfoMap) / sizeof(g_video4kInfoMap[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (_4kVic == g_video4kInfoMap[i]._4kVic) {
|
||||
timing = g_video4kInfoMap[i].timing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return timing;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdmi_core.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_ddc_c
|
||||
|
||||
int32_t HdmiCntlrDdcTransfer(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->ddcTransfer == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
if (ddcCfg == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
HdmiCntlrLock(cntlr);
|
||||
ret = cntlr->ops->ddcTransfer(cntlr, ddcCfg);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdmiDdcTransfer(struct HdmiDdc *ddc, struct HdmiDdcCfg *cfg)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (ddc == NULL || cfg == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (cfg->mode >= HDMI_DDC_MODE_BUTT) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
(void)OsalMutexLock(&(ddc->ddcMutex));
|
||||
ret = HdmiCntlrDdcTransfer(ddc->priv, cfg);
|
||||
(void)OsalMutexUnlock(&(ddc->ddcMutex));
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_common.h"
|
||||
#include "hdmi_dfm.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_dfm_c
|
||||
|
||||
#define HDMI_DFM_THOUSAND 1000
|
||||
#define HDMI_DFM_INVALID_VAL (-1)
|
||||
|
||||
uint32_t HdmiDfmGetPixelFormat(enum HdmiColorSpace colorSpace)
|
||||
{
|
||||
uint32_t pixelFormat;
|
||||
|
||||
switch (colorSpace) {
|
||||
case HDMI_COLOR_SPACE_RGB :
|
||||
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_0;
|
||||
break;
|
||||
case HDMI_COLOR_SPACE_YCBCR420 :
|
||||
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_1;
|
||||
break;
|
||||
case HDMI_COLOR_SPACE_YCBCR422 :
|
||||
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_2;
|
||||
break;
|
||||
case HDMI_COLOR_SPACE_YCBCR444 :
|
||||
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_3;
|
||||
break;
|
||||
default :
|
||||
pixelFormat = HDMI_DFM_PIXEL_FORMAT_MODE_0;
|
||||
break;
|
||||
}
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
void HdmiDfmFillParam(struct HdmiDfmParam *param, struct HdmiVideoDefInfo *videoInfo,
|
||||
struct HdmiAudioAttr *audioAttr, enum HdmiColorSpace colorSpace, enum HdmiDeepColor deepColor)
|
||||
{
|
||||
if (param == NULL || videoInfo == NULL || audioAttr == NULL) {
|
||||
return;
|
||||
}
|
||||
param->hactive = videoInfo->hactive;
|
||||
param->vactive = videoInfo->vactive;
|
||||
param->hblank = videoInfo->hblank;
|
||||
param->vblank = videoInfo->vblank;
|
||||
param->hsync = videoInfo->hsync;
|
||||
param->hback = videoInfo->hback;
|
||||
param->hfront = videoInfo->hfront;
|
||||
param->vsync = videoInfo->vsync;
|
||||
param->vback = videoInfo->vback;
|
||||
param->vfront = videoInfo->vfront;
|
||||
param->vfreq = videoInfo->rate;
|
||||
param->colorDepth = HdmiCommonDeepClolorConvertToColorDepth(deepColor);
|
||||
param->pixelFormat = HdmiDfmGetPixelFormat(colorSpace);
|
||||
param->audioRate = (uint32_t)audioAttr->sampleRate;
|
||||
param->layout = (audioAttr->channels > HDMI_AUDIO_FORMAT_CHANNEL_2) ? true : false;
|
||||
/* ACAT packet_type */
|
||||
param->acat = HDMI_AUDIO_CHANNEL_ALLOC_TYPE3;
|
||||
param->packetType = HDMI_AUDIO_SAMPLE_PACKET;
|
||||
}
|
||||
|
||||
static void HdmiDfmBaseInfoInit(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
|
||||
{
|
||||
info->htotal = param->hactive + param->hblank;
|
||||
info->vtotal = param->vactive + param->vblank;
|
||||
info->pixelClk = (uint64_t)(info->htotal) * info->vtotal * param->vfreq / HDMI_DFM_THOUSAND;
|
||||
|
||||
/* 1. Determine the maximum legal pixel rate. */
|
||||
info->maxPixelClk = info->pixelClk * (HDMI_DFM_THOUSAND + HDMI_DFM_FRL_PIXELCLK_TOLERANCE) / HDMI_DFM_THOUSAND;
|
||||
info->minPixelClk = info->pixelClk * (HDMI_DFM_THOUSAND - HDMI_DFM_FRL_PIXELCLK_TOLERANCE) / HDMI_DFM_THOUSAND;
|
||||
if (info->maxPixelClk == 0 || info->minPixelClk == 0) {
|
||||
HDF_LOGE("max or min pixel clock is 0!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 2. Determine the minimum Video Line period. */
|
||||
info->lineMinTime = (uint64_t)info->htotal * 1000000000000 / info->maxPixelClk;
|
||||
info->lineMaxTime = (uint64_t)info->htotal * 1000000000000 / info->minPixelClk;
|
||||
|
||||
/* 3. Determine the Worst Case Slow Bit Rate. x10000 */
|
||||
info->minBitRate = (uint64_t)param->bitRate * 1000000000 * (10000 - HDMI_DFM_FRL_BITRATE_TOLERANCE) / 10000;
|
||||
info->maxBitRate = (uint64_t)param->bitRate * 1000000000 * (10000 + HDMI_DFM_FRL_BITRATE_TOLERANCE) / 10000;
|
||||
|
||||
/* 4. Determine the FRL Character Rate */
|
||||
info->minFrlCharRate = info->minBitRate / 18;
|
||||
info->maxFrlCharRate = info->maxBitRate / 18;
|
||||
|
||||
/* 5. Determine the Total FRL Characters per line Period. */
|
||||
info->minFrlCharsPerLine = (uint32_t)(info->lineMinTime * info->minFrlCharRate * param->laneNum / 1000000000000);
|
||||
info->maxFrlCharsPerLine = (uint32_t)(info->lineMaxTime * info->maxFrlCharRate * param->laneNum / 1000000000000);
|
||||
|
||||
info->cFrlSb = HDMI_DFM_FRL_SB_LEN(param->laneNum);
|
||||
info->overheadSb = param->laneNum * 100000 / info->cFrlSb;
|
||||
info->overheadRs = HDMI_DFM_RS_NUM_PER_CB * HDMI_DFM_FRL_CB_NUM_PER_SB * 100000 / info->cFrlSb;
|
||||
info->overheadMap = 25 * 10000 / info->cFrlSb; /* FRL map chars per blk. */
|
||||
info->overheadMin = info->overheadSb + info->overheadRs + info->overheadMap;
|
||||
info->overheadMax = info->overheadMin + HDMI_DFM_OVERHEAD_SIZE;
|
||||
}
|
||||
|
||||
static uint32_t HdmiDfmGetAudioPackets(struct HdmiDfmParam *param)
|
||||
{
|
||||
uint32_t ap = 0;
|
||||
|
||||
switch (param->packetType) {
|
||||
case HDMI_AUDIO_SAMPLE_PACKET :
|
||||
case HDMI_ONE_BIT_AUDIO_SAMPLE_PACKET :
|
||||
ap = HDMI_AUDIO_AP_SIZE_100;
|
||||
if (param->layout == false) {
|
||||
ap = HDMI_AUDIO_AP_SIZE_25;
|
||||
}
|
||||
break;
|
||||
case HDMI_DTS_AUDIO_PACKET :
|
||||
case HDMI_HBR_AUDIO_PACKET :
|
||||
case HDMI_MULTI_STREAM_AUDIO_SAMPLE_PACKET :
|
||||
case HDMI_ONE_BIT_MULTI_STREAM_AUDIO_SAMPLE_PACKET :
|
||||
ap = HDMI_AUDIO_AP_SIZE_100;
|
||||
break;
|
||||
case HDMI_AUDIO_3D_SAMPLE_PACKET :
|
||||
case HDMI_ONE_BIT_AUDIO_3D_SAMPLE_PACKET :
|
||||
if (param->acat == HDMI_AUDIO_CHANNEL_ALLOC_TYPE1) {
|
||||
ap = HDMI_AUDIO_AP_SIZE_200;
|
||||
} else if (param->acat == HDMI_AUDIO_CHANNEL_ALLOC_TYPE2) {
|
||||
ap = HDMI_AUDIO_AP_SIZE_300;
|
||||
} else if (param->acat == HDMI_AUDIO_CHANNEL_ALLOC_TYPE3) {
|
||||
ap = HDMI_AUDIO_AP_SIZE_400;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
HDF_LOGE("audio packet type 0x%x, is not support.", param->packetType);
|
||||
break;
|
||||
}
|
||||
|
||||
return ap;
|
||||
}
|
||||
|
||||
static void HdmiDfmCaculateAudioInfo(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
|
||||
{
|
||||
/* 1. Determine the number of audio packets required to carry each sample. */
|
||||
info->audioAp = HdmiDfmGetAudioPackets(param);
|
||||
|
||||
/* 2. Determine Average Audio Related Packet Rate. */
|
||||
info->audioRap = (uint32_t)((uint64_t)param->audioRate * (1000 + HDMI_DFM_FRL_AUDIOCLK_TOLERANCE) *
|
||||
info->audioAp / 100000);
|
||||
|
||||
/* 3. Determine Average Required Packets per line. */
|
||||
info->avgAudioPacketsPerLine = (uint32_t)((uint64_t)info->audioRap * info->lineMinTime / 1000000000);
|
||||
|
||||
/* 4. Determine the Packets per Hblank that must be supportable. */
|
||||
info->audioPacketsLine = (info->avgAudioPacketsPerLine + HDMI_DFM_THOUSAND - 1) / HDMI_DFM_THOUSAND;
|
||||
|
||||
/*
|
||||
* 5. Determine The c_frl_blank_min(64(guard bands, two 12-character control periods, c_frl_active_extra)
|
||||
* and 32 audio_packets).
|
||||
*/
|
||||
info->hblankAudioMin = 64 + 32 * info->audioPacketsLine;
|
||||
}
|
||||
|
||||
static void HdmiDfmCaculateVideoBorrowInfo(struct HdmiDfmInfo *info)
|
||||
{
|
||||
if (info->activeTimeRef >= info->activeTimeMin && info->blankTimeRef >= info->blankTimeMin) {
|
||||
info->tBorrow = 0;
|
||||
} else if (info->activeTimeRef < info->activeTimeMin && info->blankTimeRef >= info->blankTimeMin) {
|
||||
info->tBorrow = info->activeTimeMin - info->activeTimeRef;
|
||||
} else {
|
||||
info->tBorrow = HDMI_DFM_INVALID_VAL;
|
||||
}
|
||||
if (info->tBorrow == HDMI_DFM_INVALID_VAL) {
|
||||
info->tbBorrow = HDMI_DFM_INVALID_VAL;
|
||||
} else {
|
||||
info->tbBorrow = ((int32_t)(info->tBorrow * info->avgTbRate / 100000000000) + 10 - 1) / 10;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiDfmCaculateVideoInfo(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
|
||||
{
|
||||
uint32_t kcd, k420;
|
||||
|
||||
/*
|
||||
* 1. if 4:2:2 pixels, kcd is 1. Otherwise, kcd is CD / 8.
|
||||
* if 4:2:0 pixels, k420 is 2. Otherwise, k420 is 1.
|
||||
*/
|
||||
kcd = (param->pixelFormat == 2) ? HDMI_DFM_MAGNIFICATION_8 : param->colorDepth;
|
||||
k420 = (param->pixelFormat == 1) ? 2 : 1;
|
||||
|
||||
/* 2. Determine Bits per Pixel */
|
||||
info->bpp = ((24 * kcd) / k420) / HDMI_DFM_MAGNIFICATION_8;
|
||||
|
||||
/* 3. Determine Video Bytes per line. */
|
||||
info->activeBytesPerLine = info->bpp * param->hactive / HDMI_DFM_MAGNIFICATION_8;
|
||||
|
||||
/*
|
||||
* 4. Determine Required Characters to carry Active Video per line.
|
||||
* 3 is means active_bytes_per_line need 3 characters.
|
||||
*/
|
||||
info->activeTbPerLine = (info->activeBytesPerLine + 3 - 1) / 3;
|
||||
|
||||
/* 5. Determine Required Characters to carry H-Blank Video per line. */
|
||||
info->hblankTbPerLine = (param->hblank * kcd / k420 + HDMI_DFM_MAGNIFICATION_8 - 1) / HDMI_DFM_MAGNIFICATION_8;
|
||||
|
||||
/* 6. 32 is FRL characters each packet, 7 is guard bands island(4 FRL char) + video(3 FRL char) */
|
||||
if (((param->hblank * kcd) / k420) / HDMI_DFM_MAGNIFICATION_8 > 32 * (1 + info->audioPacketsLine) + 7) {
|
||||
info->cFrlFree = ((param->hblank * kcd) / k420) / HDMI_DFM_MAGNIFICATION_8 -
|
||||
32 * (1 + info->audioPacketsLine) - 7;
|
||||
}
|
||||
|
||||
/* 7. add 1 character each for RC break caused by 4 */
|
||||
info->cFrlRcMargin = 4;
|
||||
/* 8. RC compression transmit control characters reduce 7/8th total characters. */
|
||||
if (7 * info->cFrlFree / HDMI_DFM_MAGNIFICATION_8 > info->cFrlRcMargin) {
|
||||
info->cFrlRcSavings = 7 * info->cFrlFree / HDMI_DFM_MAGNIFICATION_8 - info->cFrlRcMargin;
|
||||
}
|
||||
|
||||
if (info->htotal == 0) {
|
||||
HDF_LOGE("htotal is 0!");
|
||||
return;
|
||||
}
|
||||
info->avgTbRate = info->maxPixelClk * (info->activeTbPerLine + info->hblankTbPerLine) / info->htotal;
|
||||
info->activeTimeRef = (uint64_t)info->lineMinTime * param->hactive / info->htotal;
|
||||
info->blankTimeRef = (uint64_t)info->lineMinTime * param->hblank / info->htotal;
|
||||
|
||||
/* 9. (3 / 2) is active_tb coefficient in protocol */
|
||||
info->activeTimeMin = (uint64_t)info->activeTbPerLine * 3 * 100000000000000 /
|
||||
(2 * param->laneNum * info->minFrlCharRate * (HDMI_DFM_RATE_MAGNIFICATION - info->overheadMax) /
|
||||
HDMI_DFM_THOUSAND);
|
||||
info->blankTimeMin = (uint64_t)info->hblankTbPerLine * 100000000000000 /
|
||||
(param->laneNum * info->minFrlCharRate * (HDMI_DFM_RATE_MAGNIFICATION - info->overheadMax) /
|
||||
HDMI_DFM_THOUSAND);
|
||||
|
||||
/* 10. Determine Borrow Info */
|
||||
HdmiDfmCaculateVideoBorrowInfo(info);
|
||||
|
||||
/* 11. (3 / 2) is active_tb coefficient in protocol */
|
||||
info->cFrlActualPayload =
|
||||
(3 * info->activeTbPerLine + 2 - 1) / 2 + info->hblankTbPerLine - info->cFrlRcSavings;
|
||||
|
||||
if (info->minFrlCharsPerLine == 0) {
|
||||
HDF_LOGE("min FRL Characters per line is 0!");
|
||||
return;
|
||||
}
|
||||
info->utilization = (uint64_t)info->cFrlActualPayload * 100000 / (uint64_t)info->minFrlCharsPerLine;
|
||||
info->margin = 100000 - (info->utilization + info->overheadMax);
|
||||
}
|
||||
|
||||
static void HdmiDfmFillInfo(struct HdmiDfmInfo *info, struct HdmiDfmParam *param)
|
||||
{
|
||||
HdmiDfmBaseInfoInit(info, param);
|
||||
HdmiDfmCaculateAudioInfo(info, param);
|
||||
HdmiDfmCaculateVideoInfo(info, param);
|
||||
|
||||
/* Check Audio Cap. */
|
||||
info->audioSupport = (info->hblankTbPerLine >= info->hblankAudioMin) ? true : false;
|
||||
/* Check Video Cap. */
|
||||
if (info->tbBorrow == HDMI_DFM_INVALID_VAL) {
|
||||
info->videoSupport = false;
|
||||
} else {
|
||||
info->videoSupport = (info->tbBorrow <= HDMI_DFM_FRL_MAX_TB_BORROW) ? true : false;
|
||||
}
|
||||
|
||||
info->uncompressSupport = (info->margin >= 0) ? true : false;
|
||||
info->canbeTrans = (info->audioSupport && info->videoSupport && info->uncompressSupport) ? true : false;
|
||||
info->isExtraMode = (info->canbeTrans && (info->tbBorrow > 0)) ? true : false;
|
||||
}
|
||||
|
||||
bool HdmiDfmFormatSupport(struct HdmiDfmParam *param)
|
||||
{
|
||||
struct HdmiDfmInfo info = {0};
|
||||
|
||||
HdmiDfmFillInfo(&info, param);
|
||||
if (info.audioSupport == true && info.videoSupport == true && info.uncompressSupport == true) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_dispatch.h"
|
||||
#include "hdmi_core.h"
|
||||
#include "hdmi_if.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_dispatch_c
|
||||
|
||||
enum HdmiIoCmd {
|
||||
HDMI_CMD_OPEN,
|
||||
HDMI_CMD_CLOSE,
|
||||
HDMI_CMD_START,
|
||||
HDMI_CMD_STOP,
|
||||
HDMI_CMD_AVMUTE_SET,
|
||||
HDMI_CMD_DEEP_COLOR_SET,
|
||||
HDMI_CMD_DEEP_COLOR_GET,
|
||||
HDMI_CMD_VIDEO_ATTR_SET,
|
||||
HDMI_CMD_AUDIO_ATTR_SET,
|
||||
HDMI_CMD_HDR_ATTR_SET,
|
||||
HDMI_CMD_READ_SINK_EDID,
|
||||
HDMI_CMD_INFOFRAME_SET,
|
||||
HDMI_CMD_INFOFRAME_GET,
|
||||
HDMI_CMD_BUTT,
|
||||
};
|
||||
|
||||
struct HdmiDispatchFunc {
|
||||
int32_t cmd;
|
||||
int32_t (*func)(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply);
|
||||
};
|
||||
|
||||
static int32_t HdmiCmdOpen(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
(void)data;
|
||||
(void)reply;
|
||||
|
||||
return HdmiCntlrOpen(cntlr);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdClose(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
(void)data;
|
||||
(void)reply;
|
||||
|
||||
HdmiCntlrClose(cntlr);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdStart(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
(void)data;
|
||||
(void)reply;
|
||||
|
||||
return HdmiCntlrStart(cntlr);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdStop(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
(void)data;
|
||||
(void)reply;
|
||||
|
||||
return HdmiCntlrStop(cntlr);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdAvmuteSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
bool *enable = NULL;
|
||||
size_t size;
|
||||
(void)reply;
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&enable, &size)) {
|
||||
HDF_LOGE("HdmiCmdAvmuteSet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
HdmiCntlrAvmuteSet(cntlr, *enable);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdDeepColorSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
enum HdmiDeepColor *color = NULL;
|
||||
size_t size;
|
||||
(void)reply;
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&color, &size)) {
|
||||
HDF_LOGE("HdmiCmdDeepColorSet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HdmiCntlrDeepColorSet(cntlr, *color);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdDeepColorGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
int32_t ret;
|
||||
enum HdmiDeepColor color;
|
||||
(void)data;
|
||||
|
||||
if (reply == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = HdmiCntlrDeepColorGet(cntlr, &color);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HdfSbufWriteBuffer(reply, &color, sizeof(color)) == false) {
|
||||
HDF_LOGE("HdmiCmdDeepColorGet: write back color fail!");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdVideoAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
struct HdmiVideoAttr *attr = NULL;
|
||||
size_t size;
|
||||
(void)reply;
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
|
||||
HDF_LOGE("HdmiCmdVideoAttrSet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HdmiCntlrSetVideoAttribute(cntlr, attr);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdAudioAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
struct HdmiAudioAttr *attr = NULL;
|
||||
size_t size;
|
||||
(void)reply;
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
|
||||
HDF_LOGE("HdmiCmdAudioAttrSet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HdmiCntlrSetAudioAttribute(cntlr, attr);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdHdrAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
struct HdmiHdrAttr *attr = NULL;
|
||||
size_t size;
|
||||
(void)reply;
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
|
||||
HDF_LOGE("HdmiCmdHdrAttrSet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HdmiCntlrSetHdrAttribute(cntlr, attr);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdReadSinkEdid(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
int32_t ret;
|
||||
uint8_t edid[HDMI_EDID_TOTAL_SIZE] = {0};
|
||||
(void)data;
|
||||
|
||||
if (reply == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = HdmiCntlrGetSinkEdid(cntlr, edid, HDMI_EDID_TOTAL_SIZE);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HdfSbufWriteBuffer(reply, edid, HDMI_EDID_TOTAL_SIZE) == false) {
|
||||
HDF_LOGE("HdmiCmdReadSinkEdid: write back edid fail!");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdInfoframeSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
enum HdmiPacketType type;
|
||||
union HdmiInfoframeInfo *frame = NULL;
|
||||
size_t size;
|
||||
|
||||
if (!HdfSbufReadUint16(data, (uint16_t *)&type)) {
|
||||
HDF_LOGE("HdmiCmdInfoframeSet: sbuf read uint16 failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&frame, &size)) {
|
||||
HDF_LOGE("HdmiCmdInfoframeSet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HdmiCntlrInfoframeSet(cntlr, type, frame);
|
||||
}
|
||||
|
||||
static int32_t HdmiCmdInfoframeGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
size_t size;
|
||||
int32_t ret;
|
||||
enum HdmiPacketType *type = NULL;
|
||||
union HdmiInfoframeInfo frame = {0};
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&type, &size)) {
|
||||
HDF_LOGE("HdmiCmdInfoframeGet: sbuf read buffer failed");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = HdmiCntlrInfoframeGet(cntlr, *type, &frame);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HdfSbufWriteBuffer(reply, &frame, sizeof(frame)) == false) {
|
||||
HDF_LOGE("HdmiCmdInfoframeGet: write back frame fail!");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdmiIoDispatch(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
uint32_t i, len;
|
||||
struct HdmiDispatchFunc dispatchFunc[] = {
|
||||
{ HDMI_CMD_OPEN, HdmiCmdOpen },
|
||||
{ HDMI_CMD_CLOSE, HdmiCmdClose },
|
||||
{ HDMI_CMD_START, HdmiCmdStart },
|
||||
{ HDMI_CMD_STOP, HdmiCmdStop },
|
||||
{ HDMI_CMD_AVMUTE_SET, HdmiCmdAvmuteSet },
|
||||
{ HDMI_CMD_DEEP_COLOR_SET, HdmiCmdDeepColorSet },
|
||||
{ HDMI_CMD_DEEP_COLOR_GET, HdmiCmdDeepColorGet },
|
||||
{ HDMI_CMD_VIDEO_ATTR_SET, HdmiCmdVideoAttrSet },
|
||||
{ HDMI_CMD_AUDIO_ATTR_SET, HdmiCmdAudioAttrSet },
|
||||
{ HDMI_CMD_HDR_ATTR_SET, HdmiCmdHdrAttrSet },
|
||||
{ HDMI_CMD_READ_SINK_EDID, HdmiCmdReadSinkEdid },
|
||||
{ HDMI_CMD_INFOFRAME_SET, HdmiCmdInfoframeSet },
|
||||
{ HDMI_CMD_INFOFRAME_GET, HdmiCmdInfoframeGet },
|
||||
};
|
||||
|
||||
if (client == NULL || client->device == NULL) {
|
||||
HDF_LOGE("HdmiIoDispatch: client or hdf dev obj is NULL");
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)client->device->service;
|
||||
if (cntlr == NULL) {
|
||||
HDF_LOGE("HdmiIoDispatch: service is NULL");
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
len = sizeof(dispatchFunc) / sizeof(dispatchFunc[0]);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (dispatchFunc[i].cmd == cmd) {
|
||||
return dispatchFunc[i].func(cntlr, data, reply);
|
||||
}
|
||||
}
|
||||
|
||||
HDF_LOGE("HdmiIoDispatch: cmd %d is not support", cmd);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_core.h"
|
||||
#include "osal_mem.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_event_c
|
||||
|
||||
static int32_t HdmiEventPostMsg(struct HdmiCntlr *cntlr, struct HdmiEventMsg *event)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (cntlr == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
if (event == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
PlatformQueueAddMsg(cntlr->msgQueue, &event->msg);
|
||||
ret = PlatformMsgWait(&event->msg);
|
||||
if (event->msg.block == true) {
|
||||
(void)OsalSemDestroy(&event->msg.sem);
|
||||
OsalMemFree(event);
|
||||
}
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiEventPostMsg: wait hdmi event msg fail!");
|
||||
return ret;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
bool HdmiHpdStatusGet(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->hotPlugStateGet == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HdmiCntlrLock(cntlr);
|
||||
ret = cntlr->ops->hotPlugStateGet(cntlr);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool HdmiHpdStatusDelayGet(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
/*
|
||||
* An HDMI Sink shall indicate any change to the contents of the EDID by driving a low voltage level pulse
|
||||
* on the Hot Plug Detect pin. This pluse shall be at least 100 msec.
|
||||
*/
|
||||
for (i = 0; i < HDMI_READ_HPD_STATUS_DELAY; i++) {
|
||||
if (HdmiHpdStatusGet(cntlr) == true) {
|
||||
return true;
|
||||
}
|
||||
OsalMSleep(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t HdmiAddEventMsgToQueue(struct HdmiCntlr *cntlr, int32_t code, bool block, void *data)
|
||||
{
|
||||
struct HdmiEventMsg *event = NULL;
|
||||
|
||||
if (cntlr == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
event = (struct HdmiEventMsg *)OsalMemCalloc(sizeof(struct HdmiEventMsg));
|
||||
if (event == NULL) {
|
||||
HDF_LOGE("HdmiAddEventMsgToQueue: OsalMemCalloc fail!n");
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
event->msg.code = code;
|
||||
event->msg.data = (void *)cntlr;
|
||||
event->msg.block = block;
|
||||
event->priv = data;
|
||||
return HdmiEventPostMsg(cntlr, event);
|
||||
}
|
||||
|
||||
static int32_t HdmiEventHotPlugHandleComm(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
cntlr->event.plugged = true;
|
||||
if (cntlr->hdmi == NULL) {
|
||||
ret = HdmiCntlrAllocDev(cntlr);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
goto __END;
|
||||
}
|
||||
HDF_LOGE("HdmiEventHotPlugHandleComm HdmiCntlrAllocDev success.");
|
||||
}
|
||||
|
||||
/* Update EDID. */
|
||||
if (memset_s(cntlr->hdmi, sizeof(struct HdmiDevice), 0, sizeof(struct HdmiDevice)) != EOK) {
|
||||
HDF_LOGE("memcpy_s fail.");
|
||||
ret = HDF_ERR_IO;
|
||||
goto __END;
|
||||
}
|
||||
ret = HdmiEdidRawDataRead(&(cntlr->hdmi->edid), &(cntlr->ddc));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
goto __END;
|
||||
}
|
||||
ret = HdmiEdidPhase(&(cntlr->hdmi->edid));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
goto __END;
|
||||
}
|
||||
|
||||
__END:
|
||||
if (ret != HDF_SUCCESS) {
|
||||
cntlr->event.plugged = false;
|
||||
cntlr->event.hpdDetected = false;
|
||||
return ret;
|
||||
}
|
||||
cntlr->event.hpdDetected = true;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiEventHotPlugHandle(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (HdmiHpdStatusDelayGet(cntlr) == false) {
|
||||
HDF_LOGD("not detect HPD.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
if (cntlr->event.plugged == true) {
|
||||
HDF_LOGD("hdp state not change");
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
return HdmiEventHotPlugHandleComm(cntlr);
|
||||
}
|
||||
|
||||
static int32_t HdmiEventHotUnplugHandle(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (cntlr->event.plugged == false) {
|
||||
HDF_LOGD("plug state not change");
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
HdmiCntlrClose(cntlr);
|
||||
HdmiCntlrFreeDev(cntlr);
|
||||
cntlr->event.plugged = false;
|
||||
cntlr->event.hpdDetected = false;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiEventDetectSinkHandle(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
if (HdmiHpdStatusDelayGet(cntlr) == false) {
|
||||
HDF_LOGD("not detect HPD.");
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
return HdmiEventHotPlugHandleComm(cntlr);
|
||||
}
|
||||
|
||||
static int32_t HdmiEventCecMsgHandle(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
return HdmiCecReceivedMsg(cntlr->cec, msg);
|
||||
}
|
||||
|
||||
static int32_t HdmiEventHdrZeroDrmIfTimeout(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
return HdmiHdrDrmInfoframeStop(cntlr->hdr);
|
||||
}
|
||||
|
||||
static int32_t HdmiEventSwitchToHdrModeTimeout(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
return HdmiHdrModeChangeTimeout(cntlr->hdr);
|
||||
}
|
||||
|
||||
int32_t HdmiEventMsgHandleDefault(struct PlatformQueue *queue, struct PlatformMsg *msg)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
struct HdmiEventMsg *event = NULL;
|
||||
|
||||
if (queue == NULL || msg == NULL) {
|
||||
HDF_LOGE("HdmiEventMsgHandleDefault: msg or queue is null!");
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)queue->data;
|
||||
if (cntlr == NULL) {
|
||||
HDF_LOGE("HdmiEventMsgHandleDefault: cntlr is null!");
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
event = (struct HdmiEventMsg *)msg;
|
||||
switch (msg->code) {
|
||||
case HDMI_EVENT_HOTPLUG :
|
||||
ret = HdmiEventHotPlugHandle(cntlr);
|
||||
break;
|
||||
case HDMI_EVENT_HOTUNPLUG :
|
||||
ret = HdmiEventHotUnplugHandle(cntlr);
|
||||
break;
|
||||
case HDMI_EVENT_DETECT_SINK :
|
||||
ret = HdmiEventDetectSinkHandle(cntlr);
|
||||
break;
|
||||
case HDMI_EVENT_CEC_MSG:
|
||||
ret = HdmiEventCecMsgHandle(cntlr, event->priv);
|
||||
break;
|
||||
case HDMI_EVENT_ZERO_DRMIF_TIMEOUT :
|
||||
ret = HdmiEventHdrZeroDrmIfTimeout(cntlr);
|
||||
break;
|
||||
case HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT :
|
||||
ret = HdmiEventSwitchToHdrModeTimeout(cntlr);
|
||||
break;
|
||||
default:
|
||||
ret = HDF_ERR_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (event->msg.block == false) {
|
||||
OsalMemFree(event);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdmiEventHandle(struct HdmiCntlr *cntlr, enum HdmiEventType event, void *data)
|
||||
{
|
||||
int32_t ret = HDF_SUCCESS;
|
||||
|
||||
if (cntlr == NULL) {
|
||||
HDF_LOGE("HdmiEventHandleIrq: cntlr is null!");
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
switch (event) {
|
||||
case HDMI_EVENT_HOTPLUG :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_HOTPLUG, false, data);
|
||||
break;
|
||||
case HDMI_EVENT_HOTUNPLUG :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_HOTUNPLUG, false, data);
|
||||
break;
|
||||
case HDMI_EVENT_DETECT_SINK :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_DETECT_SINK, false, data);
|
||||
break;
|
||||
case HDMI_EVENT_CEC_MSG :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_CEC_MSG, false, data);
|
||||
break;
|
||||
case HDMI_EVENT_HDCP_MSG :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_HDCP_MSG, false, data);
|
||||
break;
|
||||
case HDMI_EVENT_ZERO_DRMIF_TIMEOUT :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_ZERO_DRMIF_TIMEOUT, false, data);
|
||||
break;
|
||||
case HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT :
|
||||
ret = HdmiAddEventMsgToQueue(cntlr, HDMI_EVENT_SWITCH_TO_HDRMODE_TIMEOUT, false, data);
|
||||
break;
|
||||
default :
|
||||
HDF_LOGE("event %d is not support", event);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,869 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_core.h"
|
||||
#include "hdmi_common.h"
|
||||
#include "hdmi_dfm.h"
|
||||
#include "hdmi_ncts.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_frl_c
|
||||
|
||||
static uint8_t HdmiFrlGetSinkVersion(struct HdmiScdc *scdc)
|
||||
{
|
||||
uint8_t version = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_SINK_VER, &version, sizeof(version)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get sink version fail");
|
||||
return 0;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
static bool HdmiFrlGetFltUpdate(struct HdmiScdc *scdc)
|
||||
{
|
||||
bool fltUpdate = false;
|
||||
uint8_t flag = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get flt update fail");
|
||||
return fltUpdate;
|
||||
}
|
||||
|
||||
fltUpdate = (flag & HDMI_SCDC_FLT_UPDATE_MARK) ? true : false;
|
||||
return fltUpdate;
|
||||
}
|
||||
|
||||
static bool HdmiFrlGetFrlStart(struct HdmiScdc *scdc)
|
||||
{
|
||||
bool frlStart = false;
|
||||
uint8_t flag = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get frl start fail");
|
||||
return frlStart;
|
||||
}
|
||||
|
||||
frlStart = (flag & HDMI_SCDC_FRL_START_MARK) ? true : false;
|
||||
return frlStart;
|
||||
}
|
||||
|
||||
static bool HdmiFrlGetFltReady(struct HdmiScdc *scdc)
|
||||
{
|
||||
bool fltReady = false;
|
||||
uint8_t flag = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_READY, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get flt ready fail");
|
||||
return fltReady;
|
||||
}
|
||||
|
||||
fltReady = (flag & HDMI_SCDC_FLT_READY_MARK) ? true : false;
|
||||
return fltReady;
|
||||
}
|
||||
|
||||
static uint8_t HdmiFrlGetTestConfig1(struct HdmiScdc *scdc)
|
||||
{
|
||||
uint8_t cfg = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_TEST_CONFIG_1, &cfg, sizeof(cfg)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get test cfg1 fail");
|
||||
return 0;
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static void HdmiFrlSetFltUpdate(struct HdmiScdc *scdc, bool fltUpdate)
|
||||
{
|
||||
uint8_t flag = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get flt update fail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fltUpdate == true) {
|
||||
flag |= HDMI_SCDC_FLT_UPDATE_MARK;
|
||||
} else {
|
||||
flag &= (~HDMI_SCDC_FLT_UPDATE_MARK);
|
||||
}
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_SET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl set flt update fail");
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlSetFrlStart(struct HdmiScdc *scdc, bool frlStart)
|
||||
{
|
||||
uint8_t flag = 0;
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl get frl start fail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (frlStart == true) {
|
||||
flag |= HDMI_SCDC_FRL_START_MARK;
|
||||
} else {
|
||||
flag &= (~HDMI_SCDC_FRL_START_MARK);
|
||||
}
|
||||
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_GET_FLT_UPDATE, &flag, sizeof(flag)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl set frl start fail");
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlSetConfig1(struct HdmiScdc *scdc, uint8_t *data)
|
||||
{
|
||||
if (HdmiScdcOptMsgHandle(scdc, HDMI_SCDC_OPT_SET_CONFIG1, data, sizeof(*data)) != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl set cfg1 fail");
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlSetTrainRate(struct HdmiFrl *frl)
|
||||
{
|
||||
union HdmiScdcsConfig1 cfg = {0};
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr == NULL) {
|
||||
HDF_LOGE("frl set train rate fail");
|
||||
return;
|
||||
}
|
||||
|
||||
if (frl->info.mode == HDMI_FRL_MODE_FRL) {
|
||||
cfg.bits.frlRate = frl->info.curFrlRate;
|
||||
cfg.bits.ffeLevels = HDMI_FRL_TXFFE_MODE_0;
|
||||
}
|
||||
HdmiFrlSetConfig1(cntlr->scdc, &(cfg.data));
|
||||
}
|
||||
|
||||
static bool HdmiFrlCheckFrlCapability(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
uint8_t sinkScdcVerion;
|
||||
uint8_t sinkMaxFrlRate;
|
||||
|
||||
sinkScdcVerion = HdmiFrlGetSinkVersion(cntlr->scdc);
|
||||
if (HdmiEdidSupportFrl(cntlr->hdmi) != true ||
|
||||
cntlr->cap.baseCap.bits.hdmi21 == 0 ||
|
||||
cntlr->cap.baseCap.bits.frl == 0 ||
|
||||
sinkScdcVerion == 0) {
|
||||
frl->info.maxFrlRate = 0;
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
sinkMaxFrlRate = HdmiEdidGetMaxFrlRate(cntlr->hdmi);
|
||||
frl->info.maxFrlRate = (sinkMaxFrlRate > cntlr->cap.maxFrlRate) ? cntlr->cap.maxFrlRate : sinkMaxFrlRate;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static bool HdmiFrlCheckFrlStrategy(enum HdmiFrlStrategyMode strategy, uint32_t pixelClock,
|
||||
uint32_t tmdsClock, enum HdmiVideoFormatType formatType)
|
||||
{
|
||||
bool support = true;
|
||||
|
||||
switch (strategy) {
|
||||
case HDMI_FRL_STRATEGY_MODE_1 :
|
||||
if (pixelClock <= HDMI_HDMI20_MAX_TMDS_RATE && tmdsClock <= HDMI_HDMI20_MAX_TMDS_RATE) {
|
||||
support = false;
|
||||
}
|
||||
break;
|
||||
case HDMI_FRL_STRATEGY_MODE_2 :
|
||||
if (tmdsClock <= HDMI_HDMI14_MAX_TMDS_RATE) {
|
||||
support = false;
|
||||
}
|
||||
break;
|
||||
case HDMI_FRL_STRATEGY_MODE_3 :
|
||||
if (formatType == HDMI_VIDEO_FORMA_INTERLACE) {
|
||||
support = false;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
HDF_LOGE("strategy %d is not support", strategy);
|
||||
break;
|
||||
}
|
||||
return support;
|
||||
}
|
||||
|
||||
static void HdmiFrlFillRateInfo(uint32_t *frlBitRate, uint32_t *frlLaneNum, uint32_t frlRate)
|
||||
{
|
||||
*frlLaneNum = HDMI_FRL_4_LANES;
|
||||
if (frlRate <= HDMI_FRL_WORK_MODE_3L6G) {
|
||||
*frlLaneNum = HDMI_FRL_3_LANES;
|
||||
}
|
||||
|
||||
switch (frlRate) {
|
||||
case HDMI_FRL_WORK_MODE_3L3G :
|
||||
*frlBitRate = HDMI_FRL_BIT_RATE_3;
|
||||
break;
|
||||
case HDMI_FRL_WORK_MODE_3L6G :
|
||||
case HDMI_FRL_WORK_MODE_4L6G :
|
||||
*frlBitRate = HDMI_FRL_BIT_RATE_6;
|
||||
break;
|
||||
case HDMI_FRL_WORK_MODE_4L8G :
|
||||
*frlBitRate = HDMI_FRL_BIT_RATE_8;
|
||||
break;
|
||||
case HDMI_FRL_WORK_MODE_4L10G :
|
||||
*frlBitRate = HDMI_FRL_BIT_RATE_10;
|
||||
break;
|
||||
case HDMI_FRL_WORK_MODE_4L12G :
|
||||
*frlBitRate = HDMI_FRL_BIT_RATE_12;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool HdnmiFrlCheckFrlMode(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
struct HdmiVideoDefInfo *videoInfo = NULL;
|
||||
struct HdmiDfmParam param = {0};
|
||||
bool enable3d;
|
||||
uint32_t i;
|
||||
|
||||
enable3d = (cntlr->attr.videoAttr._3dStruct >= HDMI_VS_VIDEO_3D_BUTT) ? false : true;
|
||||
videoInfo = HdmiCommonGetVideoDefInfo(cntlr->attr.videoAttr.timing, cntlr->attr.videoAttr.aspect, enable3d);
|
||||
if (videoInfo == NULL) {
|
||||
HDF_LOGD("have no this video param, use tmds to transmit.");
|
||||
return false;
|
||||
}
|
||||
HDF_LOGD("use frl to transmit, vic is %d.", videoInfo->vic);
|
||||
|
||||
frl->info.tmdsClock = cntlr->attr.videoAttr.tmdsClock;
|
||||
if (HdmiFrlCheckFrlStrategy(frl->info.strategy, cntlr->attr.videoAttr.pixelClock,
|
||||
frl->info.tmdsClock, videoInfo->formatType) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frl->info.maxFrlRate > HDMI_FRL_WORK_MODE_4L12G) {
|
||||
HDF_LOGD("max frl rate is wrong(%u)", frl->info.maxFrlRate);
|
||||
frl->info.maxFrlRate = HDMI_FRL_WORK_MODE_4L12G;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check whether a particular video format can be transmitted in a particular FRL configuration. */
|
||||
HdmiDfmFillParam(¶m, videoInfo, &(cntlr->attr.audioAttr), cntlr->attr.commAttr.colorSpace,
|
||||
cntlr->attr.commAttr.deepColor);
|
||||
for (i = frl->info.maxFrlRate; i > 0; i--) {
|
||||
HdmiFrlFillRateInfo(&(param.bitRate), &(param.laneNum), i);
|
||||
if (HdmiDfmFormatSupport(¶m) == true) {
|
||||
frl->info.minFrlRate = i;
|
||||
HDF_LOGD("min_rate: %d", i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == frl->info.maxFrlRate) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HdmiFrlIsCtsMode(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
union HdmiScdcsTestConfig1 cfg = {0};
|
||||
|
||||
cfg.data = HdmiFrlGetTestConfig1(cntlr->scdc);
|
||||
if ((cfg.bits.frlMax > 0 && cfg.bits.dscFrlMax == 0) ||
|
||||
(cfg.bits.frlMax == 0 && cfg.bits.dscFrlMax > 0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t HdmiFrlGetCurRate(struct HdmiFrl *frl)
|
||||
{
|
||||
uint8_t curFrlrate = frl->info.curFrlRate;
|
||||
|
||||
if (frl->info.ctsMode == true) {
|
||||
frl->info.preFrlRate = curFrlrate;
|
||||
curFrlrate = frl->info.maxFrlRate;
|
||||
} else {
|
||||
if (frl->info.preFrlRate != 0) {
|
||||
curFrlrate = frl->info.preFrlRate;
|
||||
frl->info.preFrlRate = 0;
|
||||
} else {
|
||||
if (frl->info.rateSelect == HDMI_FRL_RATE_BIG) {
|
||||
curFrlrate--;
|
||||
} else {
|
||||
curFrlrate++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((curFrlrate > frl->info.maxFrlRate) ||
|
||||
(curFrlrate < frl->info.minFrlRate)) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
frl->info.curFrlRate = curFrlrate;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void HdmiFrlAudioNctsSet(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiFrlAudioNctsConfig cfg = {0};
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->audioNctsSet == NULL) {
|
||||
HDF_LOGD("not support set frl audio ncts.");
|
||||
return;
|
||||
}
|
||||
|
||||
cfg.mode = frl->info.mode;
|
||||
cfg.sampleRate = cntlr->attr.audioAttr.sampleRate;
|
||||
if (cfg.mode == HDMI_FRL_MODE_FRL) {
|
||||
cfg.frlRate = frl->info.curFrlRate;
|
||||
} else {
|
||||
cfg.pixelClk = cntlr->attr.videoAttr.pixelClock;
|
||||
cfg.n = HdmiGetN(cfg.sampleRate, cfg.pixelClk);
|
||||
cfg.cts = HdmiGetCts(cfg.sampleRate, cfg.pixelClk);
|
||||
}
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->audioNctsSet(cntlr, &cfg);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
|
||||
static void HdmiFrlTxffeSet(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
struct HdmiPhyCfg cfg = {0};
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->phyOutputSet == NULL) {
|
||||
HDF_LOGD("not support phy output set.");
|
||||
return;
|
||||
}
|
||||
|
||||
cfg.modeCfg = HDMI_PHY_MODE_TXFFE;
|
||||
cfg.rate = (enum HdmiFrlWorkMode)frl->info.curFrlRate;
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputSet(cntlr, &cfg);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
|
||||
static void HdmiFrlphyConfigSet(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
struct HdmiPhyCfg cfg = {0};
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
cfg.tmdsClk = cntlr->attr.videoAttr.tmdsClock;
|
||||
cfg.pixelClk = cntlr->attr.videoAttr.pixelClock;
|
||||
cfg.deepColor = cntlr->attr.videoAttr.deepColor;
|
||||
cfg.colorSpace = cntlr->attr.commAttr.colorSpace;
|
||||
if (frl->info.mode == HDMI_FRL_MODE_FRL) {
|
||||
cfg.modeCfg = HDMI_PHY_MODE_FRL;
|
||||
cfg.rate = (enum HdmiFrlWorkMode)frl->info.curFrlRate;
|
||||
}
|
||||
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputEnable(cntlr, false);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
if (cntlr->ops->phyOutputSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputSet(cntlr, &cfg);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputEnable(cntlr, true);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlStateMachineChangeState(struct HdmiFrl *frl, enum HdmiFrlTrainStep state)
|
||||
{
|
||||
/* change state machine's state */
|
||||
frl->info.machineInfo.trainingState = state;
|
||||
/* restart timer */
|
||||
frl->info.machineInfo.startTime = OsalGetSysTimeMs();
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingReadyCheck(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (HdmiFrlGetFltReady(cntlr->scdc) == true) {
|
||||
HDF_LOGD("step, ready chack pass, start training.");
|
||||
HdmiFrlphyConfigSet(frl);
|
||||
HdmiFrlSetTrainRate(frl);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlConfigAndStartTraining(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiFrlTrainConfig cfg = {0};
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
union HdmiScdcsTestConfig1 testCfg = {0};
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
cfg.frlRate = frl->info.curFrlRate;
|
||||
cfg.txffe = HDMI_FRL_TXFFE_MODE_0;
|
||||
testCfg.data = HdmiFrlGetTestConfig1(cntlr->scdc);
|
||||
if (testCfg.bits.fltNoTimeout > 0) {
|
||||
cfg.frlNoTimeout = true;
|
||||
}
|
||||
cfg.trainTimeout = frl->info.machineInfo.trainTimeout;
|
||||
|
||||
if (cntlr->ops->frlTrainingConfigSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->frlTrainingConfigSet(cntlr, &cfg);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
if (cntlr->ops->frlEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->frlEnable(cntlr, false);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
if (cntlr->ops->frlTrainingStart != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->frlTrainingStart(cntlr);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RESULT_CHECK);
|
||||
return;
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingResultCheck(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
struct HdmiFrlTrainRslt rslt = {0};
|
||||
|
||||
if (cntlr != NULL && cntlr->ops != NULL && cntlr->ops->frlGetTriningRslt != NULL) {
|
||||
cntlr->ops->frlGetTriningRslt(cntlr, &rslt);
|
||||
}
|
||||
|
||||
if (rslt.status == HDMI_FRL_TRAIN_STATUS_SUCC) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RESULT_HANDLE);
|
||||
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_FFE_CHANGE) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlTxffeSet(frl);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_RATE_CHANGE) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RATE_CHANGE);
|
||||
} else {
|
||||
(frl->info.trainingFailCnt)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingException(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
struct HdmiPhyCfg cfg = {0};
|
||||
|
||||
if (cntlr != NULL || cntlr->ops != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
cntlr->ops->phyOutputEnable(cntlr, false);
|
||||
}
|
||||
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_STOP);
|
||||
frl->info.start = false;
|
||||
/* TMDS config. */
|
||||
cfg.pixelClk = cntlr->attr.videoAttr.pixelClock;
|
||||
cfg.tmdsClk = cntlr->attr.videoAttr.tmdsClock;
|
||||
cfg.deepColor = cntlr->attr.videoAttr.deepColor;
|
||||
cfg.modeCfg = HDMI_PHY_MODE_TMDS;
|
||||
cfg.colorSpace = cntlr->attr.commAttr.colorSpace;
|
||||
HDF_LOGD("FRL change to TMDS.");
|
||||
if (cfg.tmdsClk > HDMI_HDMI20_MAX_TMDS_RATE) {
|
||||
HDF_LOGE("TMDS clk > 600M. can't work TMDS mode.");
|
||||
return;
|
||||
}
|
||||
frl->info.mode = HDMI_FRL_MODE_TMDS;
|
||||
HdmiFrlSetTrainRate(frl);
|
||||
HdmiFrlAudioNctsSet(frl);
|
||||
|
||||
if (cntlr->ops->phyOutputSet != NULL) {
|
||||
cntlr->ops->phyOutputSet(cntlr, &cfg);
|
||||
}
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
cntlr->ops->phyOutputEnable(cntlr, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingRateChange(struct HdmiFrl *frl)
|
||||
{
|
||||
frl->info.ctsMode = HdmiFrlIsCtsMode(frl);
|
||||
if (HdmiFrlGetCurRate(frl) != HDF_SUCCESS) {
|
||||
HDF_LOGE("FRL rate %u get failed!\n", frl->info.curFrlRate);
|
||||
HdmiFrlTrainingException(frl);
|
||||
return;
|
||||
}
|
||||
/* FRL rate change */
|
||||
HdmiFrlphyConfigSet(frl);
|
||||
HdmiFrlSetTrainRate(frl);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingPassedCheck(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr != NULL || cntlr->ops != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frl->info.start == false ||
|
||||
HdmiFrlGetFrlStart(cntlr->scdc) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
HDF_LOGD("FRL training passed.");
|
||||
frl->info.work = true;
|
||||
/* n/cts config */
|
||||
HdmiFrlAudioNctsSet(frl);
|
||||
OsalMSleep(1);
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
OsalMSleep(1);
|
||||
HdmiFrlSetFrlStart(cntlr->scdc, true);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK);
|
||||
}
|
||||
|
||||
static void HdmiFrlRetrainingCheck(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr != NULL || cntlr->ops != NULL) {
|
||||
return;
|
||||
}
|
||||
if (HdmiFrlGetFltUpdate(cntlr->scdc) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
HDF_LOGD("FRL retraining flt_update get OK");
|
||||
HdmiFrlSetFltUpdate(cntlr->scdc, true);
|
||||
frl->info.work = false;
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingStop(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr != NULL || cntlr->ops != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
frl->info.work = false;
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_BUTT);
|
||||
}
|
||||
|
||||
void HdmiFrlTrainingStateMachineHandle(struct HdmiFrl *frl)
|
||||
{
|
||||
if (frl == NULL) {
|
||||
HDF_LOGE("FRL trining, not support FRL.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (frl->info.machineInfo.trainingState) {
|
||||
case HDMI_FRL_TRAIN_STEP_READR_CHECK :
|
||||
HdmiFrlTrainingReadyCheck(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_TRAIN_START :
|
||||
HdmiFrlConfigAndStartTraining(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RESULT_CHECK :
|
||||
HdmiFrlTrainingResultCheck(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RATE_CHANGE :
|
||||
HdmiFrlTrainingRateChange(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RESULT_HANDLE :
|
||||
HdmiFrlTrainingPassedCheck(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK :
|
||||
HdmiFrlRetrainingCheck(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_TRAIN_STOP :
|
||||
HdmiFrlTrainingStop(frl);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingReadyCheckTimeout(struct HdmiFrl *frl)
|
||||
{
|
||||
uint64_t curTime = OsalGetSysTimeMs();
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if ((curTime - frl->info.machineInfo.startTime) > frl->info.machineInfo.waitReadyTime) {
|
||||
if (HdmiFrlGetFltReady(cntlr->scdc) == true) {
|
||||
HDF_LOGD("step, ready chack pass, start training.");
|
||||
frl->info.machineInfo.timeoutCnt = 0;
|
||||
HdmiFrlphyConfigSet(frl);
|
||||
HdmiFrlSetTrainRate(frl);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
} else {
|
||||
(frl->info.machineInfo.timeoutCnt)++;
|
||||
/* */
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_READR_CHECK);
|
||||
}
|
||||
} else {
|
||||
/* wait for a maximum of 10 times, (wait_ready_ms * 10) ms */
|
||||
if (frl->info.machineInfo.timeoutCnt < 10) {
|
||||
return;
|
||||
}
|
||||
HDF_LOGD("FRL training READY_CHECK exception.");
|
||||
frl->info.machineInfo.timeoutCnt = 0;
|
||||
HdmiFrlTrainingException(frl);
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingResultCheckTimeout(struct HdmiFrl *frl)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
struct HdmiFrlTrainRslt rslt = {0};
|
||||
|
||||
if (cntlr != NULL && cntlr->ops != NULL && cntlr->ops->frlGetTriningRslt != NULL) {
|
||||
cntlr->ops->frlGetTriningRslt(cntlr, &rslt);
|
||||
}
|
||||
|
||||
if (rslt.status == HDMI_FRL_TRAIN_STATUS_SUCC) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RESULT_HANDLE);
|
||||
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_FFE_CHANGE) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlTxffeSet(frl);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
} else if (rslt.failReason == HDMI_FRL_TRAIN_FAIL_RATE_CHANGE) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RATE_CHANGE);
|
||||
} else {
|
||||
(frl->info.trainingFailCnt)++;
|
||||
if (frl->info.trainingFailCnt > frl->info.trainingMaxFailTimes) {
|
||||
frl->info.trainingFailCnt = 0;
|
||||
HdmiFrlTrainingException(frl);
|
||||
} else {
|
||||
/* not reach max fail times, re-training. */
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlTrainingResultHandleTimeout(struct HdmiFrl *frl)
|
||||
{
|
||||
uint64_t curTime;
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr != NULL || cntlr->ops != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
if (HdmiFrlGetFrlStart(cntlr->scdc) == true) {
|
||||
if (frl->info.start == true) {
|
||||
frl->info.work = true;
|
||||
/* n/cts config */
|
||||
HdmiFrlAudioNctsSet(frl);
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
|
||||
}
|
||||
HdmiFrlSetFrlStart(cntlr->scdc, true);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK);
|
||||
break;
|
||||
}
|
||||
} else if (HdmiFrlGetFltUpdate(cntlr->scdc) == true) {
|
||||
HdmiFrlSetFltUpdate(cntlr->scdc, true);
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
break;
|
||||
}
|
||||
|
||||
curTime = OsalGetSysTimeMs();
|
||||
if ((curTime - frl->info.machineInfo.startTime) > frl->info.machineInfo.waitHandleTime) {
|
||||
(frl->info.machineInfo.timeoutCnt)++;
|
||||
break;
|
||||
}
|
||||
/* check the sink's status every 2ms required by protocol */
|
||||
OsalUDelay(2000);
|
||||
} while (true);
|
||||
|
||||
if (frl->info.machineInfo.timeoutCnt >= 3) {
|
||||
HDF_LOGE("FRL training timeout.");
|
||||
frl->info.machineInfo.timeoutCnt = 0;
|
||||
HdmiFrlTrainingException(frl);
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFrlRetrainingCheckTimeout(struct HdmiFrl *frl)
|
||||
{
|
||||
uint64_t curTime = OsalGetSysTimeMs();
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
|
||||
if (cntlr != NULL || cntlr->ops != NULL) {
|
||||
return;
|
||||
}
|
||||
if ((curTime - frl->info.machineInfo.startTime) <= frl->info.machineInfo.waitRetrainTime) {
|
||||
return;
|
||||
}
|
||||
if (HdmiFrlGetFltUpdate(cntlr->scdc) != true) {
|
||||
return;
|
||||
}
|
||||
|
||||
HdmiFrlSetFltUpdate(cntlr->scdc, true);
|
||||
frl->info.work = true;
|
||||
if (cntlr->ops->phyOutputEnable != NULL) {
|
||||
cntlr->ops->phyOutputEnable(cntlr, frl->info.work);
|
||||
}
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_TRAIN_START);
|
||||
}
|
||||
|
||||
void HdmiFrlTrainingStateMachineTimeoutHandle(struct HdmiFrl *frl)
|
||||
{
|
||||
if (frl == NULL || frl->priv == NULL) {
|
||||
HDF_LOGE("FRL trining, not support FRL.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (frl->info.machineInfo.trainingState) {
|
||||
case HDMI_FRL_TRAIN_STEP_READR_CHECK :
|
||||
HdmiFrlTrainingReadyCheckTimeout(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_TRAIN_START :
|
||||
HdmiFrlConfigAndStartTraining(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RESULT_CHECK :
|
||||
HdmiFrlTrainingResultCheckTimeout(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RATE_CHANGE :
|
||||
HdmiFrlTrainingRateChange(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RESULT_HANDLE :
|
||||
HdmiFrlTrainingResultHandleTimeout(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_RETRAIN_CHECK :
|
||||
HdmiFrlRetrainingCheckTimeout(frl);
|
||||
break;
|
||||
case HDMI_FRL_TRAIN_STEP_TRAIN_STOP :
|
||||
HdmiFrlTrainingStop(frl);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HdmiFrlEnable(struct HdmiFrl *frl, bool enable)
|
||||
{
|
||||
if (frl == NULL || frl->priv == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
frl->info.start = enable;
|
||||
frl->info.machineInfo.start = enable;
|
||||
frl->info.machineInfo.machineState = (enable == true) ? HDMI_FRL_STATE_MACHINE_START : HDMI_FRL_STATE_MACHINE_STOP;
|
||||
frl->info.ctsMode = HdmiFrlIsCtsMode(frl);
|
||||
if (frl->info.ctsMode == true) {
|
||||
HdmiFrlGetCurRate(frl);
|
||||
HDF_LOGD("frl cur rate %d", frl->info.curFrlRate);
|
||||
}
|
||||
HdmiFrlStateMachineChangeState(frl, HDMI_FRL_TRAIN_STEP_READR_CHECK);
|
||||
}
|
||||
|
||||
int32_t HdmiFrlModeSelect(struct HdmiFrl *frl)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
struct HdmiVideoAttr *videoAttr = NULL;
|
||||
|
||||
if (frl == NULL || frl->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = HdmiFrlCheckFrlCapability(frl);
|
||||
if (ret == HDF_FAILURE) {
|
||||
return ret;
|
||||
} else if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGD("frl check capability fail, change to TMDS.");
|
||||
frl->info.mode = HDMI_FRL_MODE_TMDS;
|
||||
} else {
|
||||
if (HdnmiFrlCheckFrlMode(frl) == true) {
|
||||
HDF_LOGD("frl check frl mode succ.");
|
||||
frl->info.mode = HDMI_FRL_MODE_FRL;
|
||||
} else {
|
||||
HDF_LOGD("frl check frl mode fail, change to TMDS.");
|
||||
frl->info.mode = HDMI_FRL_MODE_TMDS;
|
||||
}
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)frl->priv;
|
||||
videoAttr = &(cntlr->attr.videoAttr);
|
||||
if (frl->info.mode == HDMI_FRL_MODE_TMDS) {
|
||||
if (videoAttr->tmdsClock > HDMI_HDMI20_MAX_TMDS_RATE) {
|
||||
HDF_LOGE("FRL mode select, tmds Clock exceed max.");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
if (HdmiEdidScdcSupport(cntlr->hdmi) == true) {
|
||||
HdmiFrlSetTrainRate(frl);
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
/* FRL mode. */
|
||||
frl->info.curFrlRate = (frl->info.rateSelect == HDMI_FRL_RATE_BIG) ?
|
||||
frl->info.maxFrlRate : frl->info.minFrlRate;
|
||||
cntlr->tmdsMode = HDMI_TMDS_MODE_HDMI_2_0;
|
||||
if (cntlr->ops != NULL && cntlr->ops->tmdsModeSet != NULL) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->tmdsModeSet(cntlr, cntlr->tmdsMode);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
}
|
||||
frl->info.ctsMode = false;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
bool HdmiFrlModeChanged(struct HdmiFrl *frl)
|
||||
{
|
||||
if (frl == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frl->info.perMode != frl->info.mode) {
|
||||
frl->info.perMode = frl->info.mode;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HdmiFrlSupport(struct HdmiFrl *frl)
|
||||
{
|
||||
if (frl == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frl->info.mode == HDMI_FRL_MODE_FRL) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_core.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_hdcp_c
|
||||
|
||||
static int32_t HdmiHdcpRead(struct HdmiHdcp *hdcp, enum HdmiHdcpPortOffset offset, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
struct HdmiDdcCfg cfg = {0};
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
|
||||
if (hdcp == NULL || hdcp->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)hdcp->priv;
|
||||
cfg.type = HDMI_DDC_DEV_HDCP;
|
||||
cfg.readFlag = true;
|
||||
cfg.devAddr = HDMI_DDC_HDCP_DEV_ADDRESS;
|
||||
cfg.data = buffer;
|
||||
cfg.dataLen = len;
|
||||
cfg.offset = offset;
|
||||
cfg.mode = HDMI_DDC_MODE_READ_MUTIL_NO_ACK;
|
||||
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpWrite(struct HdmiHdcp *hdcp, enum HdmiHdcpPortOffset offset, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
struct HdmiDdcCfg cfg = {0};
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
|
||||
if (hdcp == NULL || hdcp->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)hdcp->priv;
|
||||
cfg.type = HDMI_DDC_DEV_HDCP;
|
||||
cfg.readFlag = false;
|
||||
cfg.devAddr = HDMI_DDC_HDCP_DEV_ADDRESS;
|
||||
cfg.data = buffer;
|
||||
cfg.dataLen = len;
|
||||
cfg.offset = offset;
|
||||
cfg.mode = HDMI_DDC_MODE_WRITE_MUTIL_ACK;
|
||||
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
|
||||
}
|
||||
|
||||
static bool HdmiHdcpCheckKvs(uint8_t *ksv, uint32_t len)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
for (j = 0; j < HDMI_ONE_BYTE_SHIFT; j++) {
|
||||
if (((ksv[i] >> j) & 0x01) > 0) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* KSV contains 20 ones and 20 zeros. */
|
||||
if (cnt != HDMI_HDCP_AKSV_ONE_NUM) {
|
||||
HDF_LOGE("HdmiHdcpCheckKvs: cnt = %d.", cnt);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpWriteMsgToReg(struct HdmiHdcp *hdcp, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)hdcp->priv;
|
||||
|
||||
if (cntlr->ops == NULL || cntlr->ops->hdcpOptReg == NULL) {
|
||||
HDF_LOGD("not support hdcp write reg.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
return cntlr->ops->hdcpOptReg(cntlr, type, data, len);
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpReadMsgBksv(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BKSV, hdcp->bksv, sizeof(hdcp->bksv));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if (HdmiHdcpCheckKvs(hdcp->bksv, sizeof(hdcp->bksv)) == false) {
|
||||
HDF_LOGE("auth part I: bksv check fail.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BKSV, hdcp->bksv, sizeof(hdcp->bksv));
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpReadMsgRi(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_RI, hdcp->ri, sizeof(hdcp->ri));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_RI, hdcp->ri, sizeof(hdcp->ri));
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpWriteMsgAksv(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
if (HdmiHdcpCheckKvs(hdcp->aksv, sizeof(hdcp->aksv)) == false) {
|
||||
HDF_LOGE("auth part I: aksv check fail.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
return HdmiHdcpWrite(hdcp, HDMI_HDCP_AN, hdcp->aksv, sizeof(hdcp->aksv));
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpWriteMsgAn(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
return HdmiHdcpWrite(hdcp, HDMI_HDCP_AN, hdcp->an, sizeof(hdcp->an));
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpReadMsgHv(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
uint8_t offset, i;
|
||||
uint8_t vhNum = HDMI_HDCP_MSG_ALL_VH_LEN / HDMI_HDCP_MSG_PER_VH_LEN;
|
||||
int32_t ret;
|
||||
|
||||
if (hdcp == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
for (i = 0; i < vhNum; i++) {
|
||||
offset = HDMI_HDCP_V_H0 + i * HDMI_HDCP_MSG_PER_VH_LEN;
|
||||
ret = HdmiHdcpRead(hdcp, offset, &(hdcp->vh[i]), HDMI_HDCP_MSG_PER_VH_LEN);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_V_H_ALL, hdcp->vh, sizeof(hdcp->vh));
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpReadMsgBcaps(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
return HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationGenerateAksvAn(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)hdcp->priv;
|
||||
|
||||
if (cntlr->ops == NULL || cntlr->ops->hdcpGenerateAksvAndAn == NULL) {
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
return cntlr->ops->hdcpGenerateAksvAndAn(cntlr);
|
||||
}
|
||||
|
||||
static void HdmiHdcpRegPrepare(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = (struct HdmiCntlr *)hdcp->priv;
|
||||
|
||||
if (cntlr->ops == NULL || cntlr->ops->hdcpRegInit == NULL) {
|
||||
return;
|
||||
}
|
||||
cntlr->ops->hdcpRegInit(cntlr);
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationPrepare(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
HdmiHdcpRegPrepare(hdcp);
|
||||
if (hdcp->aksvValid == false) {
|
||||
ret = HdmiHdcpAuthenticationGenerateAksvAn(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
hdcp->state = HDMI_HDCP_AUTH_AKSV_INVALID;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
hdcp->aksvValid = true;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationFirstPart(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
hdcp->state = HDMI_HDCP_AUTH_DOING;
|
||||
/*
|
||||
* Authentication is initiated by the HDCP Transmitter by sendind an initiation massage containing its KSV(aksv)
|
||||
* and a 64-bit pseudo-random value(An) generated by the HDCP Cipher function hdcpRngCipher to the HDCP Reciever.
|
||||
*/
|
||||
ret = HdmiHdcpWriteMsgAksv(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = HdmiHdcpWriteMsgAn(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The HDCP Reciever responds by sending a response message containing the receiver's KSV(bksv) and
|
||||
* the REPEATER bit, which indicates if the reciever is an HDCP Repeater.
|
||||
*/
|
||||
ret = HdmiHdcpReadMsgBksv(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = HdmiHdcpReadMsgBcaps(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The HDCP Transmitter must not read the R0' value sooner than 100ms after writing Aksv.
|
||||
*/
|
||||
OsalMSleep(120);
|
||||
/* Read R0' */
|
||||
ret = HdmiHdcpReadMsgRi(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify R0/R0' matched or not */
|
||||
ret = HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_CHECK_R, NULL, 0);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("hdcp auth, check V fail.");
|
||||
return ret;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationCheckBstatus(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
uint16_t bstatus;
|
||||
bool maxDevExceeded, maxCascadeExceeded;
|
||||
|
||||
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BSTATUS, hdcp->bstatus, sizeof(hdcp->bstatus));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* phase bstatus. */
|
||||
bstatus = (hdcp->bstatus[1] << 8) | hdcp->bstatus[0];
|
||||
hdcp->deviceCount = bstatus & HDMI_HDCP_BSTATUS_DEVICE_COUNT_MARK;
|
||||
maxDevExceeded = (bstatus & HDMI_HDCP_BSTATUS_MAX_DEVS_EXCEEDED_MARK) ? true : false;
|
||||
maxCascadeExceeded = (bstatus & HDMI_HDCP_BSTATUS_MAX_CASCADE_EXCEEDED_MARK) ? true : false;
|
||||
if (hdcp->deviceCount == 0) {
|
||||
HDF_LOGE("hdcp auth, check bstatus, no device attached to the repeater.");
|
||||
return HDF_DEV_ERR_NO_DEVICE;
|
||||
}
|
||||
if (maxDevExceeded == true) {
|
||||
HDF_LOGE("hdcp auth, check bstatus, exceeds max allowed connected devices.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
if (maxCascadeExceeded == true) {
|
||||
HDF_LOGE("hdcp auth, check bstatus, exceeds max allowed cascade.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationWaitKsvListReady(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
uint32_t i;
|
||||
int32_t ret;
|
||||
bool ready = false;
|
||||
|
||||
/* Set up 5s timer, poll for KSV list ready. Fail if timer expires prior to ready. */
|
||||
for (i = 0; i < HDMI_HDCP_WAIT_KSV_LIST_READ_REG_CNT; i++) {
|
||||
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((hdcp->bcaps & HDMI_HDCP_BCAPS_KSV_FIFO_READY_MARK) > 0) {
|
||||
ready = true;
|
||||
break;
|
||||
}
|
||||
OsalMSleep(HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL);
|
||||
}
|
||||
if (ready == false) {
|
||||
return HDF_ERR_TIMEOUT;
|
||||
}
|
||||
/* */
|
||||
ret = HdmiHdcpAuthenticationCheckBstatus(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BCAPS, &(hdcp->bcaps), sizeof(hdcp->bcaps));
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_BSTATUS, hdcp->bstatus, sizeof(hdcp->bstatus));
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationReadKsvList(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t try = HDMI_HDCP_DEFAULT_READ_REG_TRY;
|
||||
|
||||
hdcp->ksvLen = HDMI_HDCP_GET_KSV_LEN(hdcp->deviceCount);
|
||||
do {
|
||||
ret = HdmiHdcpRead(hdcp, HDMI_HDCP_KSV_FIFO, hdcp->ksvList, hdcp->ksvLen);
|
||||
if (ret == HDF_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
OsalMSleep(HDMI_HDCP_WAIT_KSV_LIST_READ_REG_INTERVAL);
|
||||
try--;
|
||||
} while (try > 0);
|
||||
|
||||
ret = HdmiHdcpReadMsgHv(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
/* We may need to reset SHA before write ksv list. */
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_RESET_SHA, NULL, 0);
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_WRITE_KSV_FIFO, hdcp->ksvList, hdcp->ksvLen);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationSecondPart(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
/* Poll: KSV list ready. */
|
||||
ret = HdmiHdcpAuthenticationWaitKsvListReady(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("hdcp auth, wait ksv list ready fail.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read KSV list */
|
||||
ret = HdmiHdcpAuthenticationReadKsvList(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("hdcp auth, read ksv list fail.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify V/V' matched or not */
|
||||
ret = HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_CHECK_V, NULL, 0);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("hdcp auth, check V fail.");
|
||||
return ret;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void HdmiHdcpAuthenticationSucc(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_AUTH_DONE, NULL, 0);
|
||||
hdcp->state = HDMI_HDCP_AUTH_DONE;
|
||||
hdcp->authRetryCnt = 0;
|
||||
}
|
||||
|
||||
static void HdmiHdcpAuthenticationFail(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_AUTH_FAIL, NULL, 0);
|
||||
hdcp->state = HDMI_HDCP_AUTH_FAIL;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthentication(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (hdcp == NULL || hdcp->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* auth prepare, get aksv and driver clear registers. */
|
||||
ret = HdmiHdcpAuthenticationPrepare(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
goto _END;
|
||||
}
|
||||
|
||||
/*
|
||||
* First part of the authentication exchange.
|
||||
*/
|
||||
ret = HdmiHdcpAuthenticationFirstPart(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
goto _END;
|
||||
}
|
||||
HDF_LOGD("hdcp auth Part I success.");
|
||||
/* receiver (0), repeater (1) */
|
||||
if ((hdcp->bcaps & HDMI_HDCP_BCAPS_REPEATER_MARK) == 0) {
|
||||
goto _END;
|
||||
}
|
||||
|
||||
/*
|
||||
* The second part of the authentication protocol is required if the HDCP Reciever is an HDCP Repeater.
|
||||
*/
|
||||
ret = HdmiHdcpAuthenticationSecondPart(hdcp);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
goto _END;
|
||||
}
|
||||
|
||||
_END:
|
||||
if (ret == HDF_SUCCESS) {
|
||||
HdmiHdcpAuthenticationSucc(hdcp);
|
||||
} else {
|
||||
HdmiHdcpAuthenticationFail(hdcp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiHdcpAuthenticationRetry(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
if (hdcp == NULL || hdcp->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (hdcp->authRetryCnt > HDMI_HDCP_AUTH_MAX_RETRY_CNT) {
|
||||
HDF_LOGE("hdcp auth reach to max cnt, auth fail");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
return HdmiHdcpAuthentication(hdcp);
|
||||
}
|
||||
|
||||
int32_t HdmiHdcpOpen(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
(void)OsalMutexLock(&(hdcp->hdcpMutex));
|
||||
hdcp->state = HDMI_HDCP_AUTH_INACTIVE;
|
||||
hdcp->authRetryCnt = 0;
|
||||
ret = HdmiHdcpAuthentication(hdcp);
|
||||
if (ret == HDF_SUCCESS) {
|
||||
HDF_LOGD("hdcp Authentication success!");
|
||||
goto __END;
|
||||
}
|
||||
|
||||
while (hdcp->authRetryCnt <= HDMI_HDCP_AUTH_MAX_RETRY_CNT) {
|
||||
ret = HdmiHdcpAuthenticationRetry(hdcp);
|
||||
if (ret == HDF_SUCCESS) {
|
||||
goto __END;
|
||||
}
|
||||
hdcp->authRetryCnt++;
|
||||
}
|
||||
__END :
|
||||
(void)OsalMutexUnlock(&(hdcp->hdcpMutex));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void HdmiHdcpClose(struct HdmiHdcp *hdcp)
|
||||
{
|
||||
if (hdcp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdcp->state == HDMI_HDCP_AUTH_INACTIVE ||
|
||||
hdcp->state == HDMI_HDCP_AUTH_AKSV_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void)HdmiHdcpWriteMsgToReg(hdcp, HDMI_HDCP_OPT_AUTH_CLOSE, NULL, 0);
|
||||
hdcp->state = HDMI_HDCP_AUTH_INACTIVE;
|
||||
hdcp->authRetryCnt = 0;
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_core.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_hdr_c
|
||||
|
||||
static bool HdmiHdrAttrChange(struct HdmiHdrAttr *curAttr, struct HdmiHdrAttr *oldAttr)
|
||||
{
|
||||
if (memcmp(curAttr, oldAttr, sizeof(struct HdmiHdrAttr)) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void HdmiHdrColorimetryUpdate(struct HdmiVideoAttr *videoAttr, enum HdmiHdrColormetry colorimetry)
|
||||
{
|
||||
if (colorimetry >= HDMI_HDR_COLORIMETRY_EXTENDED) {
|
||||
videoAttr->colorimetry = HDMI_COLORIMETRY_EXTENDED;
|
||||
videoAttr->extColorimetry = (enum HdmiExtendedColorimetry)(colorimetry -
|
||||
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601);
|
||||
} else {
|
||||
videoAttr->colorimetry = (enum HdmiColorimetry)colorimetry;
|
||||
videoAttr->extColorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiHdrZeroDrmInfoframeTimerSet(struct HdmiCntlr *cntlr, bool start)
|
||||
{
|
||||
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
|
||||
struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
|
||||
|
||||
hdrInfo->zeroDrmIfTimer.start = false;
|
||||
hdrInfo->zeroDrmIfTimer.timerType = HDMI_HDR_TIMER_ZERO_DRMIF;
|
||||
hdrInfo->zeroDrmIfTimer.time = HDMI_ZERO_DRMIF_SEND_TIME;
|
||||
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->zeroDrmIfTimer));
|
||||
if (start == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
hdrAttr->eotfType = HDMI_DRM_EOTF_SDR_LUMIN;
|
||||
hdrAttr->metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;
|
||||
if (memset_s(&(hdrAttr->descriptor), sizeof(hdrAttr->descriptor), 0, sizeof(hdrAttr->descriptor)) != EOK) {
|
||||
HDF_LOGE("memset_s fail");
|
||||
return;
|
||||
}
|
||||
(void)HdmiDrmInfoframeSend(&(cntlr->infoframe), true);
|
||||
|
||||
hdrInfo->zeroDrmIfTimer.start = true;
|
||||
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->zeroDrmIfTimer));
|
||||
}
|
||||
|
||||
static void HdmiHdrModeChangeTimerSet(struct HdmiCntlr *cntlr, bool start)
|
||||
{
|
||||
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
|
||||
|
||||
hdrInfo->stateChangeTimer.start = false;
|
||||
hdrInfo->stateChangeTimer.timerType = HDMI_HDR_TIMER_SDR_TO_HDR10;
|
||||
hdrInfo->stateChangeTimer.time = HDMI_HDR_STATE_CHANGE_TIME;
|
||||
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
|
||||
if (start == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
hdrInfo->stateChangeTimer.start = true;
|
||||
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
|
||||
}
|
||||
|
||||
static int32_t HdmiDisableHdr(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *curAttr)
|
||||
{
|
||||
int32_t ret = HDF_SUCCESS;
|
||||
struct HdmiHdrAttr *oldAttr = &(cntlr->attr.hdrAttr);
|
||||
struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
|
||||
struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
|
||||
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
|
||||
|
||||
switch (oldAttr->mode) {
|
||||
case HDMI_HDR_MODE_DISABLE:
|
||||
break;
|
||||
case HDMI_HDR_MODE_CEA_861_3:
|
||||
*oldAttr = *curAttr;
|
||||
if (hdrInfo->state != HDMI_HDR_STATE_NONE) {
|
||||
/* to solve the problem of some TV can not switch smoothly from HDR10 to non-HDR10. */
|
||||
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
|
||||
HdmiCntlrAudioMuteEnable(cntlr, false);
|
||||
HdmiCntlrBlackDataSet(cntlr, true);
|
||||
}
|
||||
HdmiCntlrAvmuteSet(cntlr, true);
|
||||
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
|
||||
HdmiCntlrPhyOutputEnablet(cntlr, false);
|
||||
}
|
||||
HdmiHdrModeChangeTimerSet(cntlr, true);
|
||||
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
|
||||
(void)HdmiDrmInfoframeSend(&(cntlr->infoframe), false);
|
||||
} else {
|
||||
/* start timer, send zero DRMIF and stop after 2 seconds. */
|
||||
HdmiHdrZeroDrmInfoframeTimerSet(cntlr, true);
|
||||
}
|
||||
break;
|
||||
case HDMI_HDR_MODE_CEA_861_3_AUTHEN:
|
||||
case HDMI_HDR_MODE_DOLBY_NORMAL:
|
||||
case HDMI_HDR_MODE_DOLBY_TUNNELING:
|
||||
if (oldAttr->mode != HDMI_HDR_MODE_DOLBY_NORMAL) {
|
||||
commAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
|
||||
}
|
||||
videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
|
||||
videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
|
||||
break;
|
||||
default:
|
||||
ret = HDF_FAILURE;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void HdmiChangeToHdr(struct HdmiCntlr *cntlr, struct HdmiCommonAttr *commAttr)
|
||||
{
|
||||
struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
|
||||
struct HdmiHdrInfo *hdrInfo = &(cntlr->hdr->info);
|
||||
|
||||
HdmiHdrZeroDrmInfoframeTimerSet(cntlr,false);
|
||||
if (hdrAttr->userMode != HDMI_HDR_USERMODE_HDR10) {
|
||||
HDF_LOGE("usermode is not HDR10/HLG.");
|
||||
return;
|
||||
}
|
||||
commAttr->drm = true;
|
||||
|
||||
if (hdrInfo->state != HDMI_HDR_STATE_NONE) {
|
||||
/* to solve the problem of some TV can not switch smoothly from non-HDR10 to HDR10. */
|
||||
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
|
||||
HdmiCntlrAudioMuteEnable(cntlr, false);
|
||||
HdmiCntlrBlackDataSet(cntlr, true);
|
||||
}
|
||||
HdmiCntlrAvmuteSet(cntlr, true);
|
||||
if (hdrInfo->state == HDMI_HDR_STATE_OE) {
|
||||
HdmiCntlrPhyOutputEnablet(cntlr, false);
|
||||
}
|
||||
hdrInfo->stateChangeTimer.start = true;
|
||||
hdrInfo->stateChangeTimer.timerType = HDMI_HDR_TIMER_SDR_TO_HDR10;
|
||||
hdrInfo->stateChangeTimer.time = HDMI_HDR_STATE_CHANGE_TIME;
|
||||
HdmiCntlrHdrTimerSet(cntlr, &(hdrInfo->stateChangeTimer));
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t HdmiHdrModeSelect(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
|
||||
struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
|
||||
|
||||
switch (hdrAttr->mode) {
|
||||
case HDMI_HDR_MODE_CEA_861_3:
|
||||
HdmiChangeToHdr(cntlr, commAttr);
|
||||
commAttr->vsifDolby = false;
|
||||
break;
|
||||
case HDMI_HDR_MODE_CEA_861_3_AUTHEN:
|
||||
/* HDR10 authen mode, HDMI must bypass. */
|
||||
if (hdrAttr->userMode != HDMI_HDR_USERMODE_DOLBY) {
|
||||
HDF_LOGE("user mode is not dolby");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
commAttr->drm = true;
|
||||
commAttr->vsifDolby = false;
|
||||
break;
|
||||
case HDMI_HDR_MODE_DOLBY_NORMAL:
|
||||
case HDMI_HDR_MODE_DOLBY_TUNNELING:
|
||||
if (hdrAttr->userMode != HDMI_HDR_USERMODE_DOLBY) {
|
||||
HDF_LOGE("user mode is not dolby");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
commAttr->drm = false;
|
||||
commAttr->vsifDolby = true;
|
||||
break;
|
||||
default:
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdmiHdrAttrHandle(struct HdmiHdr *hdr, struct HdmiHdrAttr *curAttr)
|
||||
{
|
||||
struct HdmiHdrAttr *oldAttr = NULL;
|
||||
struct HdmiCommonAttr *commAttr = NULL;
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
int32_t ret = HDF_FAILURE;
|
||||
|
||||
if (hdr == NULL || hdr->priv == NULL) {
|
||||
HDF_LOGE("hdr attr handle, input param invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)hdr->priv;
|
||||
oldAttr = &(cntlr->attr.hdrAttr);
|
||||
commAttr = &(cntlr->attr.commAttr);
|
||||
if (HdmiHdrAttrChange(curAttr, oldAttr) == false) {
|
||||
HDF_LOGD("hdr attr not change");
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
if (oldAttr->colorimetry != curAttr->colorimetry) {
|
||||
HdmiHdrColorimetryUpdate(&(cntlr->attr.videoAttr), curAttr->colorimetry);
|
||||
}
|
||||
|
||||
/* change to SDR */
|
||||
if (curAttr->mode == HDMI_HDR_MODE_DISABLE) {
|
||||
if (HdmiDisableHdr(cntlr, curAttr) == HDF_SUCCESS) {
|
||||
commAttr->vsifDolby = false;
|
||||
cntlr->attr.hdrAttr = *curAttr;
|
||||
goto _SEND_INFOFRAME;
|
||||
} else {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* change to HDR */
|
||||
cntlr->attr.hdrAttr = *curAttr;
|
||||
ret = HdmiHdrModeSelect(cntlr);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
(void)HdmiDrmInfoframeSend(&(cntlr->infoframe), (commAttr->enableHdmi & commAttr->drm));
|
||||
|
||||
_SEND_INFOFRAME:
|
||||
(void)HdmiAviInfoframeSend(&(cntlr->infoframe), (commAttr->enableHdmi && commAttr->avi));
|
||||
(void)HdmiVsInfoframeSend(&(cntlr->infoframe), commAttr->enableHdmi, commAttr->vsifDolby);
|
||||
HdmiCntlrVideoPathSet(cntlr, &(cntlr->attr.videoAttr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdmiHdrDrmInfoframeStop(struct HdmiHdr *hdr)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
|
||||
HDF_LOGD("zero DRM infoframe send timeout.");
|
||||
if (hdr == NULL || hdr->priv == NULL) {
|
||||
HDF_LOGE("hdr stop drm, input param invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)hdr->priv;
|
||||
|
||||
if (cntlr->attr.hdrAttr.mode != HDMI_HDR_MODE_CEA_861_3) {
|
||||
return HdmiDrmInfoframeSend(&(cntlr->infoframe), false);
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdmiHdrModeChangeTimeout(struct HdmiHdr *hdr)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
|
||||
HDF_LOGD("hdr mode change timeout.");
|
||||
if (hdr == NULL || hdr->priv == NULL) {
|
||||
HDF_LOGE("hdr mode change timeout, input param invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)hdr->priv;
|
||||
|
||||
if (hdr->info.state == HDMI_HDR_STATE_OE) {
|
||||
HdmiCntlrPhyOutputEnablet(cntlr, true);
|
||||
}
|
||||
HdmiCntlrAvmuteSet(cntlr, false);
|
||||
if (hdr->info.state == HDMI_HDR_STATE_OE) {
|
||||
HdmiCntlrBlackDataSet(cntlr, false);
|
||||
HdmiCntlrAudioMuteEnable(cntlr, true);
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,494 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdmi_if.h"
|
||||
#ifndef __USER__
|
||||
#include "hdmi_core.h"
|
||||
#endif
|
||||
#include "hdf_base.h"
|
||||
#include "hdf_log.h"
|
||||
#include "osal_mem.h"
|
||||
#ifdef __USER__
|
||||
#include "hdf_io_service_if.h"
|
||||
#include "securec.h"
|
||||
#endif
|
||||
|
||||
#define HDF_LOG_TAG hdmi_if_c
|
||||
|
||||
#define HDMI_SERVICE_NAME_LEN 32
|
||||
|
||||
#ifdef __USER__
|
||||
|
||||
enum HdmiIoCmd {
|
||||
HDMI_CMD_OPEN,
|
||||
HDMI_CMD_CLOSE,
|
||||
HDMI_CMD_START,
|
||||
HDMI_CMD_STOP,
|
||||
HDMI_CMD_AVMUTE_SET,
|
||||
HDMI_CMD_DEEP_COLOR_SET,
|
||||
HDMI_CMD_DEEP_COLOR_GET,
|
||||
HDMI_CMD_VIDEO_ATTR_SET,
|
||||
HDMI_CMD_AUDIO_ATTR_SET,
|
||||
HDMI_CMD_HDR_ATTR_SET,
|
||||
HDMI_CMD_READ_SINK_EDID,
|
||||
HDMI_CMD_INFOFRAME_SET,
|
||||
HDMI_CMD_INFOFRAME_GET,
|
||||
HDMI_CMD_BUTT,
|
||||
};
|
||||
|
||||
static int32_t HdmiGetDataFromReply(struct HdfSBuf *reply, uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t rLen;
|
||||
const void *rBuf = NULL;
|
||||
|
||||
if (HdfSbufReadBuffer(reply, &rBuf, &rLen) == false) {
|
||||
HDF_LOGE("HdmiGetDataFromReply: read rBuf fail!");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
if (size != rLen) {
|
||||
HDF_LOGE("HdmiGetDataFromReply: err len:%u, rLen:%u", size, rLen);
|
||||
if (rLen > size) {
|
||||
rLen = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcpy_s(data, size, rBuf, rLen) != EOK) {
|
||||
HDF_LOGE("HdmiGetDataFromReply: memcpy rBuf fail!");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void HdmiUserClose(DevHandle handle)
|
||||
{
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
int32_t ret;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserClose: service is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_CLOSE, NULL, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserClose: failed to send service call:%d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t HdmiUserStart(DevHandle handle)
|
||||
{
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
int32_t ret;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserStart: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_START, NULL, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserStart: failed to send service call:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserStop(DevHandle handle)
|
||||
{
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
int32_t ret;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserStop: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_STOP, NULL, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserStop: failed to send service call:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserAvmuteSet(DevHandle handle, bool enable)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *buf = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserAvmuteSet: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
buf = HdfSBufObtain(sizeof(enable));
|
||||
if (buf == NULL) {
|
||||
HDF_LOGE("HdmiUserAvmuteSet: failed to obtain buf");
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
if (!HdfSbufWriteBuffer(buf, &enable, sizeof(enable))) {
|
||||
HDF_LOGE("HdmiUserAvmuteSet: sbuf write buffer failed");
|
||||
HdfSBufRecycle(buf);
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_AVMUTE_SET, buf, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserAvmuteSet: failed to write, ret %d", ret);
|
||||
}
|
||||
HdfSBufRecycle(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserDeepColorSet(DevHandle handle, enum HdmiDeepColor color)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *buf = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserDeepColorSet: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
buf = HdfSBufObtain(sizeof(color));
|
||||
if (buf == NULL) {
|
||||
HDF_LOGE("HdmiUserDeepColorSet: failed to obtain buf");
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
if (!HdfSbufWriteBuffer(buf, &color, sizeof(color))) {
|
||||
HDF_LOGE("HdmiUserDeepColorSet: sbuf write color failed");
|
||||
HdfSBufRecycle(buf);
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_DEEP_COLOR_SET, buf, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserDeepColorSet: failed to write, ret %d", ret);
|
||||
}
|
||||
HdfSBufRecycle(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *buf = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserSetVideoAttribute: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (attr == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
buf = HdfSBufObtain(sizeof(struct HdmiVideoAttr));
|
||||
if (buf == NULL) {
|
||||
HDF_LOGE("HdmiUserSetVideoAttribute: failed to obtain buf");
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
if (!HdfSbufWriteBuffer(buf, attr, sizeof(struct HdmiVideoAttr))) {
|
||||
HDF_LOGE("HdmiUserSetVideoAttribute: sbuf write attr failed");
|
||||
HdfSBufRecycle(buf);
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_VIDEO_ATTR_SET, buf, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserSetVideoAttribute: failed to write, ret %d", ret);
|
||||
}
|
||||
HdfSBufRecycle(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *buf = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserSetAudioAttribute: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (attr == NULL) {
|
||||
HDF_LOGE("HdmiUserSetAudioAttribute: attr is NULL");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
buf = HdfSBufObtain(sizeof(struct HdmiAudioAttr));
|
||||
if (buf == NULL) {
|
||||
HDF_LOGE("HdmiUserSetAudioAttribute: failed to obtain buf");
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
if (!HdfSbufWriteBuffer(buf, attr, sizeof(struct HdmiAudioAttr))) {
|
||||
HDF_LOGE("HdmiUserSetAudioAttribute: sbuf write attr failed");
|
||||
HdfSBufRecycle(buf);
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_AUDIO_ATTR_SET, buf, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserSetAudioAttribute: failed to write, ret %d", ret);
|
||||
}
|
||||
HdfSBufRecycle(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *buf = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserSetHdrAttribute: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (attr == NULL) {
|
||||
HDF_LOGE("HdmiUserSetHdrAttribute: attr is NULL");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
buf = HdfSBufObtain(sizeof(struct HdmiHdrAttr));
|
||||
if (buf == NULL) {
|
||||
HDF_LOGE("HdmiUserSetHdrAttribute: failed to obtain buf");
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
if (!HdfSbufWriteBuffer(buf, attr, sizeof(struct HdmiHdrAttr))) {
|
||||
HDF_LOGE("HdmiUserSetHdrAttribute: sbuf write attr failed");
|
||||
HdfSBufRecycle(buf);
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_HDR_ATTR_SET, buf, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserSetAudioAttribute: failed to write, ret %d", ret);
|
||||
}
|
||||
HdfSBufRecycle(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserDeepColorGet(DevHandle handle, enum HdmiDeepColor *color)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *reply = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserDeepColorGet: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (color == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Four bytes are used to store the buffer length, and four bytes are used to align the memory. */
|
||||
reply = HdfSBufObtain(sizeof(*color) + sizeof(uint64_t));
|
||||
if (reply == NULL) {
|
||||
HDF_LOGE("HdmiUserDeepColorGet: failed to obtain reply");
|
||||
ret = HDF_ERR_MALLOC_FAIL;
|
||||
goto __EXIT;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_DEEP_COLOR_GET, NULL, reply);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiUserDeepColorGet: failed to write, ret %d", ret);
|
||||
} else {
|
||||
ret = HdmiGetDataFromReply(reply, (uint8_t *)color, sizeof(*color));
|
||||
}
|
||||
|
||||
__EXIT :
|
||||
if (reply != NULL) {
|
||||
HdfSBufRecycle(reply);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiUserGetSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfSBuf *reply = NULL;
|
||||
struct HdfIoService *service = (struct HdfIoService *)handle;
|
||||
|
||||
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiUserGetSinkEdid: service is invalid");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (buffer == NULL || len == 0) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
reply = HdfSBufObtain(len);
|
||||
if (reply == NULL) {
|
||||
HDF_LOGE("HdmiUserGetSinkEdid: failed to obtain reply");
|
||||
ret = HDF_ERR_MALLOC_FAIL;
|
||||
goto __EXIT;
|
||||
}
|
||||
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_READ_SINK_EDID, NULL, reply);
|
||||
if (ret <= 0) {
|
||||
HDF_LOGE("HdmiUserGetSinkEdid: failed to write, ret %d", ret);
|
||||
} else {
|
||||
ret = HdmiGetDataFromReply(reply, buffer, len);
|
||||
}
|
||||
|
||||
__EXIT :
|
||||
if (reply != NULL) {
|
||||
HdfSBufRecycle(reply);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *HdmiCntlrObjGet(uint16_t busNum)
|
||||
{
|
||||
char *serviceName = NULL;
|
||||
void *obj = NULL;
|
||||
|
||||
serviceName = (char *)OsalMemCalloc(HDMI_SERVICE_NAME_LEN + 1);
|
||||
if (serviceName == NULL) {
|
||||
HDF_LOGE("HDMI service name malloc fail.");
|
||||
return NULL;
|
||||
}
|
||||
if (snprintf_s(serviceName, (HDMI_SERVICE_NAME_LEN + 1),
|
||||
HDMI_SERVICE_NAME_LEN, "HDF_PLATFORM_HDMI_%d", busNum) < 0) {
|
||||
HDF_LOGE("get HDMI service name fail.");
|
||||
goto __ERR;
|
||||
}
|
||||
#ifdef __USER__
|
||||
obj = (void *)HdfIoServiceBind(serviceName);
|
||||
#else
|
||||
obj = (void *)HdmiCntlrGetByBusNum(busNum);
|
||||
#endif
|
||||
__ERR:
|
||||
OsalMemFree(serviceName);
|
||||
return obj;
|
||||
}
|
||||
|
||||
DevHandle HdmiOpen(uint16_t busNum)
|
||||
{
|
||||
DevHandle *obj = (DevHandle *)HdmiCntlrObjGet(busNum);
|
||||
int32_t ret;
|
||||
|
||||
if (obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#ifdef __USER__
|
||||
struct HdfIoService *service = (struct HdfIoService *)obj;
|
||||
if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
|
||||
HDF_LOGE("HdmiOpen: dispatcher or Dispatch is NULL!");
|
||||
return NULL;
|
||||
}
|
||||
ret = service->dispatcher->Dispatch(&service->object, HDMI_CMD_OPEN, NULL, NULL);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("HdmiOpen: failed to send service call:%d", ret);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
ret = HdmiCntlrOpen((struct HdmiCntlr *)obj);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
int32_t HdmiStart(DevHandle handle)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserStart(handle);
|
||||
#else
|
||||
return HdmiCntlrStart((struct HdmiCntlr *)handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiStop(DevHandle handle)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserStop(handle);
|
||||
#else
|
||||
return HdmiCntlrStop((struct HdmiCntlr *)handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiAvmuteSet(DevHandle handle, bool enable)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserAvmuteSet(handle, enable);
|
||||
#else
|
||||
HdmiCntlrAvmuteSet((struct HdmiCntlr *)handle, enable);
|
||||
return HDF_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserDeepColorSet(handle, color);
|
||||
#else
|
||||
return HdmiCntlrDeepColorSet((struct HdmiCntlr *)handle, color);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserDeepColorGet(handle, color);
|
||||
#else
|
||||
return HdmiCntlrDeepColorGet((struct HdmiCntlr *)handle, color);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserSetVideoAttribute(handle, attr);
|
||||
#else
|
||||
return HdmiCntlrSetVideoAttribute((struct HdmiCntlr *)handle, attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserSetAudioAttribute(handle, attr);
|
||||
#else
|
||||
return HdmiCntlrSetAudioAttribute((struct HdmiCntlr *)handle, attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserSetHdrAttribute(handle, attr);
|
||||
#else
|
||||
return HdmiCntlrSetHdrAttribute((struct HdmiCntlr *)handle, attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
#ifdef __USER__
|
||||
return HdmiUserGetSinkEdid(handle, buffer, len);
|
||||
#else
|
||||
return HdmiCntlrGetSinkEdid((struct HdmiCntlr *)handle, buffer, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
void HdmiClose(DevHandle handle)
|
||||
{
|
||||
#ifdef __USER__
|
||||
HdmiUserClose(handle);
|
||||
#else
|
||||
HdmiCntlrClose((struct HdmiCntlr *)handle);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,806 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_core.h"
|
||||
#include "securec.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_infoframe_c
|
||||
|
||||
#define HDMI_IEEE_OUI_1_4_1ST 0x03
|
||||
#define HDMI_IEEE_OUI_1_4_2ND 0x0C
|
||||
#define HDMI_IEEE_OUI_1_4_3RD 0x00
|
||||
|
||||
static void HdmiInfoframeFillCheckSum(uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t checkSum = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
checkSum += data[i];
|
||||
}
|
||||
if (checkSum > 0) {
|
||||
/*
|
||||
* The checksum shall be calculated such that a byte-wide sum of all three bytes of the Packet Header and
|
||||
* all valid bytes of the InfoFrame Packet contents(determined by InfoFrame_length), plus the checksum itself,
|
||||
* equals zero.
|
||||
*/
|
||||
data[3] = HDMI_INFOFRAME_CHECKSUM - checkSum;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiInfoframeFillHeader(struct HdmiInfoframeHeader *header, uint8_t *data, uint32_t len)
|
||||
{
|
||||
if (len < HDMI_INFOFRAME_PACKET_HEADER_LEN) {
|
||||
HDF_LOGE("len = %d, val is too small.", len);
|
||||
return;
|
||||
}
|
||||
data[0] = header->type;
|
||||
data[1] = header->verNum;
|
||||
data[2] = header->len;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframePacketVsEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t lenght;
|
||||
struct HdmiVs14VsifContent *vsifContent = NULL;
|
||||
struct HdmiVsUserVsifContent *userContent = NULL;
|
||||
struct HdmiVsInfoframe *vs = &(infoframe->vs);
|
||||
|
||||
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + vs->len;
|
||||
if (len < lenght) {
|
||||
HDF_LOGE("len = %d, val is too small.", len);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (memset_s(data, len, 0, len) != EOK) {
|
||||
HDF_LOGE("memset_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
|
||||
if (vs->vsifContent._14Vsif.oui == HDMI_IEEE_OUI_1_4) {
|
||||
data[4] = HDMI_IEEE_OUI_1_4_1ST;
|
||||
data[5] = HDMI_IEEE_OUI_1_4_2ND;
|
||||
data[6] = HDMI_IEEE_OUI_1_4_3RD;
|
||||
vsifContent = &(vs->vsifContent._14Vsif);
|
||||
userContent = &(vs->vsifContent.userVsif);
|
||||
data[7] = (vsifContent->format & HDMI_VENDOR_1_4_FORMAT_MARK) << HDMI_VENDOR_1_4_FORMAT_SHIFT;
|
||||
if (vsifContent->format == HDMI_VS_VIDEO_FORMAT_4K) {
|
||||
data[8] = vsifContent->vic;
|
||||
return HDF_SUCCESS;
|
||||
} else if (vsifContent->format == HDMI_VS_VIDEO_FORMAT_3D) {
|
||||
data[8] = (vsifContent->_3dStruct & HDMI_VENDOR_3D_STRUCTURE_MARK) << HDMI_VENDOR_3D_STRUCTURE_SHIFT;
|
||||
}
|
||||
data[9] = (vsifContent->_3dExtData & HDMI_VENDOR_3D_EXT_DATA_MARK) << HDMI_VENDOR_3D_EXT_DATA_SHIFT;
|
||||
if (vsifContent->_3dMetaPresent == false) {
|
||||
if (userContent->len == 0 || (userContent->len + lenght) > len) {
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
if (memcpy_s(&data[lenght], (len - lenght), userContent->data, userContent->len) != EOK) {
|
||||
HDF_LOGE("memcpy_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
lenght += userContent->len;
|
||||
}
|
||||
}
|
||||
HdmiInfoframeFillCheckSum(data, lenght);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframePacketAviEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t lenght;
|
||||
uint8_t *buff = data;
|
||||
struct HdmiAviInfoframe *avi = &(infoframe->avi);
|
||||
|
||||
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + avi->len;
|
||||
if (len < lenght) {
|
||||
HDF_LOGE("len = %d, val is too small.", len);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (memset_s(buff, len, 0, len) != EOK) {
|
||||
HDF_LOGE("memset_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
|
||||
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
|
||||
/* PB1 */
|
||||
buff[0] |= (avi->colorSpace & HDMI_AVI_COLOR_SPACE_MARK) << HDMI_AVI_COLOR_SPACE_SHIFT;
|
||||
buff[0] |= (avi->scanMode & HDMI_AVI_SCAN_MODE_MARK);
|
||||
if (avi->activeFormatInformationPresent == true) {
|
||||
buff[0] |= (1 << HDMI_AVI_ACTIVE_INFORMATION_SHIFT);
|
||||
}
|
||||
if (avi->horizBarInfoPresent == true) {
|
||||
buff[0] |= (1 << HDMI_AVI_HORIZONTAL_BAR_SHIFT);
|
||||
}
|
||||
if (avi->vertBarInfoPresent == true) {
|
||||
buff[0] |= (1 << HDMI_AVI_VERTICAL_BAR_SHIFT);
|
||||
}
|
||||
/* PB2 */
|
||||
buff[1] |= (avi->colorimetry & HDMI_AVI_COLORIMETRY_MARK) << HDMI_AVI_COLORIMETRY_SHIFT;
|
||||
buff[1] |= (avi->pictureAspect & HDMI_AVI_PICTURE_ASPECT_RATE_MARK) << HDMI_AVI_PICTURE_ASPECT_RATE_SHIFT;
|
||||
buff[1] |= (avi->activeAspect & HDMI_AVI_ACTIVE_FORMAT_ASPECT_RATE_MARK);
|
||||
/* PB3 */
|
||||
buff[2] |= (avi->extColorimetry & HDMI_AVI_EXT_COLORIMETRY_MARK) << HDMI_AVI_EXT_COLORIMETRY_SHIFT;
|
||||
buff[2] |= (avi->range & HDMI_AVI_EXT_QUANTIZATION_RANGE_MARK) << HDMI_AVI_EXT_QUANTIZATION_RANGE_SHIFT;
|
||||
buff[2] |= (avi->nups & HDMI_AVI_NUPS_RANGE_MARK);
|
||||
if (avi->itc == true) {
|
||||
buff[2] |= (1 << HDMI_AVI_IT_CONTENT_SHIFT);
|
||||
}
|
||||
/* PB4 */
|
||||
buff[3] = avi->vic;
|
||||
/* PB5 */
|
||||
buff[4] |= (avi->yccRange & HDMI_AVI_YCC_QUANTIZATION_RANGE_MARK) << HDMI_AVI_YCC_QUANTIZATION_RANGE_SHIFT;
|
||||
buff[4] |= (avi->itcType & HDMI_AVI_IT_CONTENT_TYPE_MARK) << HDMI_AVI_IT_CONTENT_TYPE_SHIFT;
|
||||
buff[4] |= (avi->pixelRepetitionFactor & HDMI_AVI_PIXEL_REPETION_FACTOR_MARK);
|
||||
/* PB6 */
|
||||
buff[5] = (uint8_t)(avi->topBar & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB7 */
|
||||
buff[6] = (uint8_t)((avi->topBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB8 */
|
||||
buff[7] = (uint8_t)(avi->bottomBar & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB9 */
|
||||
buff[8] = (uint8_t)((avi->bottomBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB10 */
|
||||
buff[9] = (uint8_t)(avi->leftBar & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB11 */
|
||||
buff[10] = (uint8_t)((avi->leftBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB12 */
|
||||
buff[11] = (uint8_t)(avi->rightBar & HDMI_AVI_BAR_MODE_MARK);
|
||||
/* PB13 */
|
||||
buff[12] = (uint8_t)((avi->rightBar >> HDMI_AVI_BAR_MODE_SHIFT) & HDMI_AVI_BAR_MODE_MARK);
|
||||
HdmiInfoframeFillCheckSum(data, lenght);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframePacketSpdEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t lenght;
|
||||
uint8_t *buff = data;
|
||||
struct HdmiSpdInfoframe *spd = &(infoframe->spd);
|
||||
|
||||
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + spd->len;
|
||||
if (len < lenght) {
|
||||
HDF_LOGE("len = %d, val is too small.", len);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (memset_s(buff, len, 0, len) != EOK) {
|
||||
HDF_LOGE("memset_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
|
||||
/* PB1~PB8 */
|
||||
if (memcpy_s(buff, (len - HDMI_INFOFRAME_PACKET_HEADER_LEN), spd->vendorName, sizeof(spd->vendorName)) != EOK) {
|
||||
HDF_LOGE("memcpy_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
buff += HDMI_SPD_VENDOR_NAME_LEN;
|
||||
/* PB9~PB24 */
|
||||
if (memcpy_s(buff, (len - HDMI_INFOFRAME_PACKET_HEADER_LEN - HDMI_SPD_VENDOR_NAME_LEN),
|
||||
spd->productDescription, sizeof(spd->productDescription)) != EOK) {
|
||||
HDF_LOGE("memcpy_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
buff += HDMI_SPD_PRODUCT_DESCRIPTION_LEN;
|
||||
/* PB25 */
|
||||
buff[0] = spd->sdi;
|
||||
HdmiInfoframeFillCheckSum(data, lenght);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframePacketAudioEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t lenght;
|
||||
uint8_t *buff = data;
|
||||
struct HdmiAudioInfoframe *audio = &(infoframe->audio);
|
||||
|
||||
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + audio->len;
|
||||
if (len < lenght) {
|
||||
HDF_LOGE("len = %d, val is too small.", len);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (memset_s(buff, len, 0, len) != EOK) {
|
||||
HDF_LOGE("memset_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
|
||||
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
|
||||
/* PB1 */
|
||||
buff[0] |= (audio->codingType & HDMI_AUDIO_CODING_TYPE_MARK) << HDMI_AUDIO_CODING_TYPE_SHIFT;
|
||||
buff[0] |= (audio->channelCount & HDMI_AUDIO_CHANNEL_COUNT_MARK);
|
||||
/* PB2 */
|
||||
buff[1] |= (audio->sampleFreq & HDMI_AUDIO_SAMPLE_FREQUENCY_MARK) << HDMI_AUDIO_SAMPLE_FREQUENCY_SHIFT;
|
||||
buff[1] |= (audio->sampleSize & HDMI_AUDIO_SAMPLE_SIZE_MARK);
|
||||
/* PB3 */
|
||||
buff[2] |= (audio->codingExtType & HDMI_AUDIO_CXT_MARK);
|
||||
/* PB4 */
|
||||
buff[3] |= audio->channelAllocation;
|
||||
/* PB5 */
|
||||
buff[4] |= (audio->levelShiftValue & HDMI_AUDIO_LEVEL_SHIFT_VALUE_MARK) << HDMI_AUDIO_LEVEL_SHIFT_VALUE_SHIFT;
|
||||
buff[4] |= (audio->playBackLevel & HDMI_AUDIO_LEF_PLAYBACK_LEVEL_MARK);
|
||||
if (audio->dmInh == true) {
|
||||
buff[4] |= (1 << HDMI_AUDIO_DM_INH_SHIFT);
|
||||
}
|
||||
HdmiInfoframeFillCheckSum(data, lenght);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframePacketDrmEncoding(union HdmiInfoframeInfo *infoframe, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t lenght;
|
||||
uint8_t *buff = data;
|
||||
struct HdmiDrmInfoframe *drm = &(infoframe->drm);
|
||||
struct HdmiStaticMetadataDescriptor1st *des = &(drm->des.type1);
|
||||
|
||||
lenght = HDMI_INFOFRAME_PACKET_HEADER_LEN + drm->len;
|
||||
if (len < lenght) {
|
||||
HDF_LOGE("len = %d, val is too small.", len);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
if (memset_s(buff, len, 0, len) != EOK) {
|
||||
HDF_LOGE("memset_s fail.");
|
||||
return HDF_ERR_IO;
|
||||
}
|
||||
|
||||
HdmiInfoframeFillHeader(&(infoframe->header), data, len);
|
||||
buff += HDMI_INFOFRAME_PACKET_HEADER_LEN;
|
||||
/* PB1 */
|
||||
buff[0] = drm->eotfType;
|
||||
/* PB2 */
|
||||
buff[1] = drm->metadataType;
|
||||
/* PB3 */
|
||||
buff[2] = (uint8_t)(des->displayPrimaries0X & HDMI_DRM_METADATA_MARK);
|
||||
/* PB4 */
|
||||
buff[3] = (uint8_t)((des->displayPrimaries0X >> HDMI_DRM_METADATA_SHIFT) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB5 */
|
||||
buff[4] = (uint8_t)(des->displayPrimaries0Y & HDMI_DRM_METADATA_MARK);
|
||||
/* PB6 */
|
||||
buff[5] = (uint8_t)((des->displayPrimaries0Y & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB7 */
|
||||
buff[6] = (uint8_t)(des->displayPrimaries1X & HDMI_DRM_METADATA_MARK);
|
||||
/* PB8 */
|
||||
buff[7] = (uint8_t)((des->displayPrimaries1X & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB9 */
|
||||
buff[8] = (uint8_t)(des->displayPrimaries1Y & HDMI_DRM_METADATA_MARK);
|
||||
/* PB10 */
|
||||
buff[9] = (uint8_t)((des->displayPrimaries1Y & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB11 */
|
||||
buff[10] = (uint8_t)(des->displayPrimaries2X & HDMI_DRM_METADATA_MARK);
|
||||
/* PB12 */
|
||||
buff[11] = (uint8_t)((des->displayPrimaries2X & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB13 */
|
||||
buff[12] = (uint8_t)(des->displayPrimaries2Y & HDMI_DRM_METADATA_MARK);
|
||||
/* PB14 */
|
||||
buff[13] = (uint8_t)((des->displayPrimaries2Y & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB15 */
|
||||
buff[14] = (uint8_t)(des->whitePointX & HDMI_DRM_METADATA_MARK);
|
||||
/* PB16 */
|
||||
buff[15] = (uint8_t)((des->whitePointX & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB17 */
|
||||
buff[16] = (uint8_t)(des->whitePointY & HDMI_DRM_METADATA_MARK);
|
||||
/* PB18 */
|
||||
buff[17] = (uint8_t)((des->whitePointY & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB19 */
|
||||
buff[18] = (uint8_t)(des->maxDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK);
|
||||
/* PB20 */
|
||||
buff[19] = (uint8_t)((des->maxDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB21 */
|
||||
buff[20] = (uint8_t)(des->minDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK);
|
||||
/* PB22 */
|
||||
buff[21] = (uint8_t)((des->minDisplayMasteringLuminance & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB23 */
|
||||
buff[22] = (uint8_t)(des->maxContentLightLevel & HDMI_DRM_METADATA_MARK);
|
||||
/* PB24 */
|
||||
buff[23] = (uint8_t)((des->maxContentLightLevel & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
/* PB25 */
|
||||
buff[24] = (uint8_t)(des->maxFrameAverageLightLevel & HDMI_DRM_METADATA_MARK);
|
||||
/* PB26 */
|
||||
buff[25] = (uint8_t)((des->maxFrameAverageLightLevel & HDMI_DRM_METADATA_MARK) & HDMI_DRM_METADATA_MARK);
|
||||
HdmiInfoframeFillCheckSum(data, lenght);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframePacketEncoding(union HdmiInfoframeInfo *infoframe,
|
||||
enum HdmiPacketType type, uint8_t *data, uint32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (infoframe == NULL || data == NULL) {
|
||||
HDF_LOGE("input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_VS:
|
||||
ret = HdmiInfoframePacketVsEncoding(infoframe, data, len);
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_AVI:
|
||||
ret = HdmiInfoframePacketAviEncoding(infoframe, data, len);
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_SPD:
|
||||
ret = HdmiInfoframePacketSpdEncoding(infoframe, data, len);
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_AUDIO:
|
||||
ret = HdmiInfoframePacketAudioEncoding(infoframe, data, len);
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_DRM:
|
||||
ret = HdmiInfoframePacketDrmEncoding(infoframe, data, len);
|
||||
break;
|
||||
default:
|
||||
HDF_LOGD("type %d not support.", type);
|
||||
ret = HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t HdmiInfoframeSend(struct HdmiInfoframe *frame, union HdmiInfoframeInfo *infoframe)
|
||||
{
|
||||
uint8_t buffer[HDMI_INFOFRAME_LEN] = {0};
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
int32_t ret;
|
||||
|
||||
if (frame == NULL || frame->priv == NULL || infoframe == NULL) {
|
||||
HDF_LOGE("HdmiInfoframeSend: input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)frame->priv;
|
||||
if (cntlr->ops == NULL || cntlr->ops->infoframeSend == NULL || cntlr->ops->infoframeEnable == NULL) {
|
||||
HDF_LOGD("HdmiInfoframeSend not support.");
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
ret = HdmiInfoframePacketEncoding(infoframe, infoframe->header.type, buffer, HDMI_INFOFRAME_LEN);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("encding infoframe %d fail", infoframe->header.type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->infoframeEnable(cntlr, infoframe->header.type, false);
|
||||
ret = cntlr->ops->infoframeSend(cntlr, infoframe->header.type, buffer, HDMI_INFOFRAME_LEN);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("send infoframe %d fail", infoframe->header.type);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return ret;
|
||||
}
|
||||
cntlr->ops->infoframeEnable(cntlr, infoframe->header.type, true);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void HdmiFillAviHdrInfoframe(struct HdmiAviInfoframe *avi,
|
||||
struct HdmiVideoAttr *videoAttr, struct HdmiHdrAttr *HdrAttr, struct HdmiCommonAttr *commAttr)
|
||||
{
|
||||
switch (HdrAttr->mode) {
|
||||
case HDMI_HDR_MODE_CEA_861_3:
|
||||
case HDMI_HDR_MODE_CEA_861_3_AUTHEN:
|
||||
avi->colorimetry = videoAttr->colorimetry;
|
||||
avi->extColorimetry = videoAttr->extColorimetry;
|
||||
avi->colorSpace = commAttr->colorSpace;
|
||||
if (HdrAttr->mode == HDMI_HDR_MODE_CEA_861_3_AUTHEN) {
|
||||
avi->colorSpace = HDMI_COLOR_SPACE_YCBCR422;
|
||||
}
|
||||
avi->range = videoAttr->quantization;
|
||||
avi->yccRange = videoAttr->yccQuantization;
|
||||
break;
|
||||
case HDMI_HDR_MODE_DOLBY_NORMAL:
|
||||
avi->colorSpace = HDMI_COLOR_SPACE_YCBCR422;
|
||||
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
|
||||
avi->extColorimetry = videoAttr->extColorimetry;
|
||||
avi->range = videoAttr->quantization;
|
||||
avi->yccRange = HDMI_YCC_QUANTIZATION_RANGE_FULL;
|
||||
break;
|
||||
case HDMI_HDR_MODE_DOLBY_TUNNELING:
|
||||
avi->colorSpace = HDMI_COLOR_SPACE_RGB;
|
||||
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
|
||||
avi->extColorimetry = videoAttr->extColorimetry;
|
||||
avi->range = HDMI_QUANTIZATION_RANGE_FULL;
|
||||
avi->yccRange = videoAttr->yccQuantization;
|
||||
break;
|
||||
default:
|
||||
avi->colorSpace = commAttr->colorSpace;
|
||||
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
|
||||
avi->extColorimetry = videoAttr->extColorimetry;
|
||||
avi->range = videoAttr->quantization;
|
||||
avi->yccRange = videoAttr->yccQuantization;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFillAviInfoframeVersion(struct HdmiAviInfoframe *avi)
|
||||
{
|
||||
/*
|
||||
* see hdmi spec2.0 10.1.
|
||||
* The Y2 and VIC7 bits are simply set to zero in a Version 2 AVI InfoFrame and might not be decoded by
|
||||
* some Sinks. A Version 3 AVI InfoFrame shall be used and the Version field set to 0x03 (indicating that
|
||||
* the Sink shall decode the additional most-significant bits) whenever either of the most-significant bits
|
||||
* Y2 or VIC7 are set to '1'. If both Y2 and VIC7 are set to '0', then a Version 2 AVI InfoFrame shall be used
|
||||
* and the Version field shall be set to 0x02 (indicating that the Sink does not have to decode the additional
|
||||
* most-significant bits).
|
||||
*/
|
||||
avi->verNum = HDMI_AVI_VERSION2;
|
||||
if (((uint32_t)avi->colorSpace & HDMI_AVI_Y2_MASK) > 0 ||
|
||||
(avi->vic > HDMI_VIC_5120X2160P100_64_27)) {
|
||||
avi->verNum = HDMI_AVI_VERSION3;
|
||||
} else if (avi->colorimetry == HDMI_COLORIMETRY_EXTENDED &&
|
||||
avi->extColorimetry == HDMI_EXTENDED_COLORIMETRY_ADDITIONAL) {
|
||||
/*
|
||||
* (C1,C0) is (1,1) and (EC2,EC1,EC0) is (1,1,1), version shall be 4.
|
||||
* All fields of the Version 4 AVI InfoFrame are the same as Version 3 AVI InfoFrame,
|
||||
* except for the InfoFrame Version Number, Length of AVI InfoFrame, and additional Data Byte 14.
|
||||
*/
|
||||
avi->verNum = HDMI_AVI_VERSION4;
|
||||
(avi->len)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFillAviInfoframe(struct HdmiAviInfoframe *avi,
|
||||
struct HdmiVideoAttr *videoAttr, struct HdmiHdrAttr *HdrAttr, struct HdmiCommonAttr *commAttr)
|
||||
{
|
||||
bool enable3d;
|
||||
|
||||
if (memset_s(avi, sizeof(struct HdmiAviInfoframe), 0, sizeof(struct HdmiAviInfoframe)) != EOK) {
|
||||
HDF_LOGE("fill vsif, memset_s fail.");
|
||||
return;
|
||||
}
|
||||
avi->type = HDMI_INFOFRAME_PACKET_TYPE_AVI;
|
||||
avi->len = HDMI_AVI_INFOFRAME_LEN;
|
||||
|
||||
avi->activeFormatInformationPresent = true;
|
||||
avi->colorSpace = commAttr->colorSpace;
|
||||
avi->activeAspect = videoAttr->activeAspect;
|
||||
avi->pictureAspect = videoAttr->aspect;
|
||||
avi->colorimetry = (videoAttr->xvycc == true) ? HDMI_COLORIMETRY_EXTENDED : videoAttr->colorimetry;
|
||||
avi->nups = videoAttr->nups;
|
||||
|
||||
avi->range = videoAttr->quantization;
|
||||
avi->extColorimetry = videoAttr->extColorimetry;
|
||||
enable3d = (videoAttr->_3dStruct >= HDMI_VS_VIDEO_3D_BUTT) ? false : true;
|
||||
avi->vic = HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, enable3d);
|
||||
avi->pixelRepetitionFactor = (uint8_t)videoAttr->pixelRepeat;
|
||||
avi->yccRange = videoAttr->yccQuantization;
|
||||
HdmiFillAviHdrInfoframe(avi, videoAttr, HdrAttr, commAttr);
|
||||
HdmiFillAviInfoframeVersion(avi);
|
||||
}
|
||||
|
||||
int32_t HdmiAviInfoframeSend(struct HdmiInfoframe *frame, bool enable)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
union HdmiInfoframeInfo infoframe = {0};
|
||||
|
||||
if (frame == NULL || frame->priv == NULL) {
|
||||
HDF_LOGE("HdmiAviInfoframeSend: input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)frame->priv;
|
||||
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL || cntlr->ops->infoframeSend == NULL) {
|
||||
HDF_LOGD("HdmiAviInfoframeSend not support.");
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (enable == false) {
|
||||
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_AVI, false);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
HdmiFillAviInfoframe(&(frame->avi), &(cntlr->attr.videoAttr), &(cntlr->attr.hdrAttr), &(cntlr->attr.commAttr));
|
||||
infoframe.avi = frame->avi;
|
||||
return HdmiInfoframeSend(frame, &infoframe);
|
||||
}
|
||||
|
||||
void HdmiFillAudioInfoframe(struct HdmiAudioInfoframe *audio, struct HdmiAudioAttr *audioAttr)
|
||||
{
|
||||
if (memset_s(audio, sizeof(struct HdmiAudioInfoframe), 0, sizeof(struct HdmiAudioInfoframe)) != EOK) {
|
||||
HDF_LOGE("fill vsif, memset_s fail.");
|
||||
return;
|
||||
}
|
||||
audio->type = HDMI_INFOFRAME_PACKET_TYPE_AUDIO;
|
||||
audio->len = HDMI_AUDIO_INFOFRAME_LEN;
|
||||
audio->verNum = HDMI_AUDIO_INFOFRAME_VERSION;
|
||||
|
||||
/* fill channels. */
|
||||
if (audioAttr->ifType != HDMI_AUDIO_IF_TYPE_I2S) {
|
||||
HDF_LOGI("audio channel refer to stream.");
|
||||
} else {
|
||||
HDF_LOGI("audio channel %u \n", audioAttr->channels);
|
||||
audio->channelCount = (audioAttr->channels >= 2) ? (audioAttr->channels - 1) : 0;
|
||||
}
|
||||
|
||||
/* fill coding type. */
|
||||
if (audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_AC3 || audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_DTS ||
|
||||
audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_EAC3 || audioAttr->codingType == HDMI_AUDIO_CODING_TYPE_DTS_HD) {
|
||||
audio->codingType = audioAttr->codingType;
|
||||
} else {
|
||||
audio->codingType = HDMI_AUDIO_CODING_TYPE_STREAM;
|
||||
}
|
||||
|
||||
/* fill CA field. see CEA-861-D table 20. */
|
||||
switch (audioAttr->channels) {
|
||||
case HDMI_AUDIO_FORMAT_CHANNEL_3:
|
||||
audio->channelAllocation = 0x01; /* 1 channel */
|
||||
break;
|
||||
case HDMI_AUDIO_FORMAT_CHANNEL_6:
|
||||
audio->channelAllocation = 0x0b; /* 3, 4 channel */
|
||||
break;
|
||||
case HDMI_AUDIO_FORMAT_CHANNEL_8:
|
||||
audio->channelAllocation = 0x13; /* 1, 2, 5 channel */
|
||||
break;
|
||||
default:
|
||||
audio->channelAllocation = 0x00; /* 0 channel */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HdmiAudioInfoframeSend(struct HdmiInfoframe *frame, bool enable)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
union HdmiInfoframeInfo infoframe = {0};
|
||||
|
||||
if (frame == NULL || frame->priv == NULL) {
|
||||
HDF_LOGE("HdmiAudioInfoframeSend: input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)frame->priv;
|
||||
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
|
||||
HDF_LOGD("HdmiAudioInfoframeSend not support.");
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (enable == false) {
|
||||
HdmiCntlrLock(cntlr);
|
||||
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_AUDIO, false);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
HdmiFillAudioInfoframe(&(frame->audio), &(cntlr->attr.audioAttr));
|
||||
infoframe.audio = frame->audio;
|
||||
return HdmiInfoframeSend(frame, &infoframe);
|
||||
}
|
||||
|
||||
static void HdmiFillDrmInfoframe(struct HdmiDrmInfoframe *drm, struct HdmiHdrAttr *HdrAttr)
|
||||
{
|
||||
if (memset_s(drm, sizeof(struct HdmiDrmInfoframe), 0, sizeof(struct HdmiDrmInfoframe)) != EOK) {
|
||||
HDF_LOGE("fill vsif, memset_s fail.");
|
||||
return;
|
||||
}
|
||||
drm->type = HDMI_INFOFRAME_PACKET_TYPE_DRM;
|
||||
drm->len = HDMI_DRM_INFOFRAME_LEN;
|
||||
drm->verNum = HDMI_DRM_INFOFRAME_VERSION;
|
||||
drm->eotfType = HdrAttr->eotfType;
|
||||
drm->metadataType = HdrAttr->metadataType;
|
||||
drm->des = HdrAttr->descriptor;
|
||||
}
|
||||
|
||||
int32_t HdmiDrmInfoframeSend(struct HdmiInfoframe *frame, bool enable)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
union HdmiInfoframeInfo infoframe = {0};
|
||||
|
||||
if (frame == NULL || frame->priv == NULL) {
|
||||
HDF_LOGE("HdmiDrmInfoframeSend: input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)frame->priv;
|
||||
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
|
||||
HDF_LOGD("HdmiDrmInfoframeSend not support.");
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (enable == false) {
|
||||
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_DRM, false);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
HdmiFillDrmInfoframe(&(frame->drm), &(cntlr->attr.hdrAttr));
|
||||
infoframe.drm = frame->drm;
|
||||
return HdmiInfoframeSend(frame, &infoframe);
|
||||
}
|
||||
|
||||
static uint8_t HdmiGetVsifLength(struct HdmiVs14VsifContent *_14Vsif, bool dolbyEnable, bool hdrSupport)
|
||||
{
|
||||
uint8_t length = 0x07;
|
||||
|
||||
if (hdrSupport == true) {
|
||||
if (dolbyEnable == true) {
|
||||
length = 0x18;
|
||||
} else if (_14Vsif->format == HDMI_VS_VIDEO_FORMAT_4K) {
|
||||
length = 0x05;
|
||||
} else if (_14Vsif->format == HDMI_VS_VIDEO_FORMAT_3D) {
|
||||
length = 0x07;
|
||||
} else {
|
||||
length = 0x04;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
static void HdmiFill14Vsif(struct HdmiVsInfoframe *vs, struct HdmiVideoAttr *videoAttr)
|
||||
{
|
||||
struct HdmiVideo4kInfo *_4kInfo = NULL;
|
||||
struct HdmiVs14VsifContent *_14Vsif = &(vs->vsifContent._14Vsif);
|
||||
enum HdmiVic vic;
|
||||
uint32_t cnt;
|
||||
|
||||
_14Vsif->oui = HDMI_IEEE_OUI_1_4;
|
||||
vic = HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, false);
|
||||
if ((vic == HDMI_VIC_3840X2160P24_16_9 || vic == HDMI_VIC_3840X2160P25_16_9 ||
|
||||
vic == HDMI_VIC_3840X2160P30_16_9 || vic == HDMI_VIC_4096X2160P24_256_135) &&
|
||||
videoAttr->_3dStruct == HDMI_VS_VIDEO_3D_BUTT) {
|
||||
_14Vsif->format = HDMI_VS_VIDEO_FORMAT_4K;
|
||||
for (cnt = 0; cnt <= HDMI_VIDEO_4K_CODES_MAX; cnt++) {
|
||||
_4kInfo = HdmiCommonGetVideo4kInfo(cnt);
|
||||
if (_4kInfo != NULL && _4kInfo->timing == videoAttr->timing) {
|
||||
_14Vsif->vic = _4kInfo->_4kVic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (videoAttr->_3dStruct < HDMI_VS_VIDEO_3D_BUTT) { // common 3D
|
||||
_14Vsif->format = HDMI_VS_VIDEO_FORMAT_3D;
|
||||
_14Vsif->_3dStruct = videoAttr->_3dStruct;
|
||||
} else {
|
||||
_14Vsif->format = HDMI_VS_VIDEO_FORMAT_NULL;
|
||||
_14Vsif->_3dStruct = videoAttr->_3dStruct;
|
||||
}
|
||||
}
|
||||
|
||||
static void HdmiFillVsInfoframe(struct HdmiInfoframe *frame, struct HdmiVideoAttr *videoAttr,
|
||||
bool dolbyEnable, bool hdrSupport)
|
||||
{
|
||||
struct HdmiVsInfoframe *vs = &(frame->vs);
|
||||
int32_t ret;
|
||||
|
||||
ret = memset_s(vs, sizeof(struct HdmiVsInfoframe), 0, sizeof(struct HdmiVsInfoframe));
|
||||
if (ret != EOK) {
|
||||
HDF_LOGE("fill vsif, memset_s fail.");
|
||||
return;
|
||||
}
|
||||
vs->type = HDMI_INFOFRAME_PACKET_TYPE_VS;
|
||||
vs->verNum = HDMI_VSIF_VERSION;
|
||||
HdmiFill14Vsif(vs, videoAttr);
|
||||
vs->len = HdmiGetVsifLength(&(vs->vsifContent._14Vsif), dolbyEnable, hdrSupport);
|
||||
/* fill user vendor data */
|
||||
vs->vsifContent.userVsif.len = frame->userVsif.len;
|
||||
ret = memcpy_s(vs->vsifContent.userVsif.data, HDMI_VENDOR_USER_DATA_MAX_LEN,
|
||||
frame->userVsif.data, frame->userVsif.len);
|
||||
if (ret != EOK) {
|
||||
HDF_LOGE("fill vsif, memcpy_s fail.");
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HdmiVsInfoframeSend(struct HdmiInfoframe *frame, bool enable, bool dolbyEnable)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
union HdmiInfoframeInfo infoframe = {0};
|
||||
|
||||
if (frame == NULL || frame->priv == NULL) {
|
||||
HDF_LOGE("HdmiVsInfoframeSend: input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)frame->priv;
|
||||
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
|
||||
HDF_LOGD("HdmiVsInfoframeSend not support.");
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (enable == false) {
|
||||
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_VS, false);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
HdmiFillVsInfoframe(frame, &(cntlr->attr.videoAttr), dolbyEnable, frame->hdrSupport);
|
||||
infoframe.vs = frame->vs;
|
||||
return HdmiInfoframeSend(frame, &infoframe);
|
||||
}
|
||||
|
||||
static void HdmiFillSpdInfoframe(struct HdmiSpdInfoframe *spd, char *vendorName,
|
||||
char *productName, enum HdmiSpdSdi sdi)
|
||||
{
|
||||
uint32_t len, length;
|
||||
|
||||
if (memset_s(spd, sizeof(struct HdmiSpdInfoframe), 0, sizeof(struct HdmiSpdInfoframe)) != EOK) {
|
||||
HDF_LOGE("fill spd infoframe, memset_s fail.");
|
||||
return;
|
||||
}
|
||||
spd->type = HDMI_INFOFRAME_PACKET_TYPE_SPD;
|
||||
spd->len = HDMI_SPD_INFOFRAME_LEN;
|
||||
spd->verNum = HDMI_SPD_VERSION;
|
||||
spd->sdi = sdi;
|
||||
|
||||
len = (uint32_t)strlen(vendorName);
|
||||
length = (uint32_t)sizeof(spd->vendorName);
|
||||
length = (length > len) ? len : length;
|
||||
if (memcpy_s(spd->vendorName, length, vendorName, length) != EOK) {
|
||||
HDF_LOGE("fill spd infoframe vendor name, memcpy_s fail.");
|
||||
}
|
||||
|
||||
len = (uint32_t)strlen(productName);
|
||||
length = (uint32_t)sizeof(spd->productDescription);
|
||||
length = (length > len) ? len : length;
|
||||
if (memcpy_s(spd->productDescription, length, productName, length) != EOK) {
|
||||
HDF_LOGE("fill spd infoframe product name, memcpy_s fail.");
|
||||
}
|
||||
}
|
||||
|
||||
int32_t HdmiSpdInfoframeSend(struct HdmiInfoframe *frame, bool enable,
|
||||
char *vendorName, char *productName, enum HdmiSpdSdi sdi)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
union HdmiInfoframeInfo infoframe = {0};
|
||||
|
||||
if (frame == NULL || frame->priv == NULL) {
|
||||
HDF_LOGE("HdmiSpdInfoframeSend: input param is invalid.");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
cntlr = (struct HdmiCntlr *)frame->priv;
|
||||
if (cntlr->ops == NULL || cntlr->ops->infoframeEnable == NULL) {
|
||||
HDF_LOGD("HdmiSpdInfoframeSend not support.");
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (enable == false) {
|
||||
cntlr->ops->infoframeEnable(cntlr, HDMI_INFOFRAME_PACKET_TYPE_SPD, false);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
HdmiFillSpdInfoframe(&(frame->spd), vendorName, productName, sdi);
|
||||
infoframe.spd = frame->spd;
|
||||
return HdmiInfoframeSend(frame, &infoframe);
|
||||
}
|
||||
|
||||
int32_t HdmiInfoframeGetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
|
||||
union HdmiInfoframeInfo *infoframe)
|
||||
{
|
||||
if (frame == NULL || infoframe == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_VS :
|
||||
infoframe->vs = frame->vs;
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_AVI :
|
||||
infoframe->avi = frame->avi;
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_AUDIO :
|
||||
infoframe->audio = frame->audio;
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_DRM :
|
||||
infoframe->drm = frame->drm;
|
||||
break;
|
||||
default :
|
||||
HDF_LOGD("infoframe %d not support get", type);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdmiInfoframeSetInfo(struct HdmiInfoframe *frame, enum HdmiPacketType type,
|
||||
union HdmiInfoframeInfo *infoframe)
|
||||
{
|
||||
if (frame == NULL || infoframe == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_VS :
|
||||
frame->vs = infoframe->vs;
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_AVI :
|
||||
frame->avi = infoframe->avi;
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_AUDIO :
|
||||
frame->audio = infoframe->audio;
|
||||
break;
|
||||
case HDMI_INFOFRAME_PACKET_TYPE_DRM :
|
||||
frame->drm = infoframe->drm;
|
||||
break;
|
||||
default :
|
||||
HDF_LOGD("infoframe %d not support set", type);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdmi_ncts.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_ncts_c
|
||||
|
||||
#define HDMI_NCTS_INVALID_VALUE 0xffffffff
|
||||
|
||||
/*
|
||||
* see hdmi1.4 table 7-1¡¢7-2¡¢7-3.
|
||||
* The exact relationship: 128 * fs = tmdsClock * N / CTS.
|
||||
*/
|
||||
static struct HdmiAudioNCts g_audioNctsMap[] = {
|
||||
{ 32000, 25174, 4576, 28125 },
|
||||
{ 32000, 25200, 4096, 25200 },
|
||||
{ 32000, 27000, 4096, 27000 },
|
||||
{ 32000, 27027, 4096, 27027 },
|
||||
{ 32000, 54000, 4096, 54000 },
|
||||
{ 32000, 54054, 4096, 54054 },
|
||||
{ 32000, 74175, 11648, 210937},
|
||||
{ 32000, 74250, 4096, 74250 },
|
||||
{ 32000, 148351, 11648, 421875 },
|
||||
{ 32000, 148500, 4096, 148500 },
|
||||
{ 32000, 296703, 5824, 421875 },
|
||||
{ 32000, 297000, 3072, 222750 },
|
||||
{ 32000, 593406, 5824, 843750 },
|
||||
{ 32000, 594000, 3072, 445500 },
|
||||
{ 32000, 0, 4096, 0 },
|
||||
{ 44100, 25174, 7007, 31250 },
|
||||
{ 44100, 25200, 6272, 28000 },
|
||||
{ 44100, 27000, 6272, 30000 },
|
||||
{ 44100, 27027, 6272, 30030 },
|
||||
{ 44100, 54000, 6272, 60000 },
|
||||
{ 44100, 54054, 6272, 60060 },
|
||||
{ 44100, 74175, 17836, 234375 },
|
||||
{ 44100, 74250, 6272, 82500 },
|
||||
{ 44100, 148351, 8918, 234375 },
|
||||
{ 44100, 148500, 6272, 165000 },
|
||||
{ 44100, 296703, 4459, 234375 },
|
||||
{ 44100, 297000, 4704, 247500 },
|
||||
{ 44100, 593406, 8918, 937500 },
|
||||
{ 44100, 594000, 9408, 990000 },
|
||||
{ 44100, 0, 6272, 0 },
|
||||
{ 48000, 25174, 6864, 28125 },
|
||||
{ 48000, 25200, 6144, 25200 },
|
||||
{ 48000, 27000, 6144, 27000 },
|
||||
{ 48000, 27027, 6144, 27027 },
|
||||
{ 48000, 54000, 6144, 54000 },
|
||||
{ 48000, 54054, 6144, 54054 },
|
||||
{ 48000, 74175, 11648, 140625 },
|
||||
{ 48000, 74250, 6144, 74250 },
|
||||
{ 48000, 148351, 5824, 140625 },
|
||||
{ 48000, 148500, 6144, 148500 },
|
||||
{ 48000, 296703, 5824, 281250 },
|
||||
{ 48000, 297000, 5120, 247500 },
|
||||
{ 48000, 593406, 5824, 562500 },
|
||||
{ 48000, 594000, 6144, 594000 },
|
||||
{ 48000, 0, 6144, 0 }
|
||||
};
|
||||
|
||||
uint32_t HdmiGetN(uint32_t sampleRate, uint32_t tmdsClock)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0;i < sizeof(g_audioNctsMap) / sizeof(g_audioNctsMap[0]); i++) {
|
||||
if (g_audioNctsMap[i].sampleRate == sampleRate &&
|
||||
g_audioNctsMap[i].tmdsClock == tmdsClock) {
|
||||
return g_audioNctsMap[i].n;
|
||||
}
|
||||
if (g_audioNctsMap[i].sampleRate == sampleRate &&
|
||||
g_audioNctsMap[i].tmdsClock >= (tmdsClock - HDMI_NCTS_TMDS_DEVIATION) &&
|
||||
g_audioNctsMap[i].tmdsClock <= (tmdsClock + HDMI_NCTS_TMDS_DEVIATION)) {
|
||||
return g_audioNctsMap[i].n;
|
||||
}
|
||||
if (g_audioNctsMap[i].sampleRate == sampleRate &&
|
||||
g_audioNctsMap[i].tmdsClock == 0) {
|
||||
return g_audioNctsMap[i].n;
|
||||
}
|
||||
}
|
||||
return HDMI_NCTS_N_DEFAULT;
|
||||
}
|
||||
|
||||
uint32_t HdmiGetCts(uint32_t sampleRate, uint32_t tmdsClock)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t tmpN = HDMI_NCTS_INVALID_VALUE;
|
||||
uint32_t tmpCts = HDMI_NCTS_INVALID_VALUE;
|
||||
|
||||
for (i = 0;i < sizeof(g_audioNctsMap) / sizeof(g_audioNctsMap[0]); i++) {
|
||||
if (g_audioNctsMap[i].sampleRate == sampleRate &&
|
||||
g_audioNctsMap[i].tmdsClock == tmdsClock) {
|
||||
tmpN = g_audioNctsMap[i].n;
|
||||
tmpCts = g_audioNctsMap[i].cts;
|
||||
break;
|
||||
}
|
||||
if (g_audioNctsMap[i].sampleRate == sampleRate &&
|
||||
g_audioNctsMap[i].tmdsClock >= (tmdsClock - HDMI_NCTS_TMDS_DEVIATION) &&
|
||||
g_audioNctsMap[i].tmdsClock <= (tmdsClock + HDMI_NCTS_TMDS_DEVIATION)) {
|
||||
tmpN = g_audioNctsMap[i].n;
|
||||
tmpCts = g_audioNctsMap[i].cts;
|
||||
break;
|
||||
}
|
||||
if (g_audioNctsMap[i].sampleRate == sampleRate &&
|
||||
g_audioNctsMap[i].tmdsClock == 0) {
|
||||
tmpN = g_audioNctsMap[i].n;
|
||||
tmpCts = g_audioNctsMap[i].cts;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmpCts == 0 && sampleRate >= 1000) {
|
||||
tmpCts = (tmpN / HDMI_NCTS_FACTOR) * tmdsClock * 10 / (sampleRate / 1000);
|
||||
} else if (tmpCts == HDMI_NCTS_INVALID_VALUE && sampleRate >= 1000) {
|
||||
tmpCts = (HDMI_NCTS_N_DEFAULT / HDMI_NCTS_FACTOR) * tmdsClock * 10 / (sampleRate / 1000);
|
||||
}
|
||||
return tmpCts;
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
||||
*
|
||||
* HDF is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
* See the LICENSE file in the root of this repository for complete details.
|
||||
*/
|
||||
|
||||
#include "hdf_log.h"
|
||||
#include "hdmi_core.h"
|
||||
|
||||
#define HDF_LOG_TAG hdmi_scdc_c
|
||||
|
||||
#define HDMI_SCDC_READ_SOURCE_VERSION_TIMES 2
|
||||
|
||||
int32_t HdmiScdcRead(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
struct HdmiDdcCfg cfg = {0};
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
|
||||
if (scdc == NULL || scdc->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)scdc->priv;
|
||||
cfg.type = HDMI_DDC_DEV_SCDC;
|
||||
cfg.readFlag = true;
|
||||
cfg.devAddr = HDMI_DDC_SCDC_DEV_ADDRESS;
|
||||
cfg.data = buffer;
|
||||
cfg.dataLen = len;
|
||||
cfg.offset = offset;
|
||||
cfg.mode = HDMI_DDC_MODE_READ_MUTIL_NO_ACK;
|
||||
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWrite(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
struct HdmiDdcCfg cfg = {0};
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
|
||||
if (scdc == NULL || scdc->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)scdc->priv;
|
||||
cfg.type = HDMI_DDC_DEV_SCDC;
|
||||
cfg.readFlag = false;
|
||||
cfg.devAddr = HDMI_DDC_SCDC_DEV_ADDRESS;
|
||||
cfg.data = buffer;
|
||||
cfg.dataLen = len;
|
||||
cfg.offset = offset;
|
||||
cfg.mode = HDMI_DDC_MODE_WRITE_MUTIL_ACK;
|
||||
return HdmiDdcTransfer(&(cntlr->ddc), &cfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadByte(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *byte)
|
||||
{
|
||||
return HdmiScdcRead(scdc, offset, byte, sizeof(*byte));
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWriteByte(struct HdmiScdc *scdc, enum HdmiScdcsOffset offset, uint8_t *byte)
|
||||
{
|
||||
return HdmiScdcWrite(scdc, offset, byte, sizeof(*byte));
|
||||
}
|
||||
|
||||
/* read opt */
|
||||
int32_t HdmiScdcReadSinkVersion(struct HdmiScdc *scdc, uint8_t *sinkVer)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_SINK_VERSION, sinkVer);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadSourceVersion(struct HdmiScdc *scdc, uint8_t *srcVer)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_SOURCE_VERSION, srcVer);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadUpdate0(struct HdmiScdc *scdc, uint8_t *flag)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_UPDATE_0, flag);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadScramblerStatus(struct HdmiScdc *scdc, uint8_t *status)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_SCRAMBLER_STATUS, status);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadTmdsConfig(struct HdmiScdc *scdc, uint8_t *tmdsCfg)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_TMDS_CONFIG, tmdsCfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadConfig0(struct HdmiScdc *scdc, uint8_t *cfg)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_0, cfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadConfig1(struct HdmiScdc *scdc, uint8_t *cfg)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_1, cfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadTestConfig0(struct HdmiScdc *scdc, uint8_t *testCfg)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_TEST_CONFIG_0, testCfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadTestConfig1(struct HdmiScdc *scdc, uint8_t *testCfg)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_TEST_CONFIG_1, testCfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadStatusFlag0(struct HdmiScdc *scdc, uint8_t *flag)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_0, flag);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadStatusFlag1(struct HdmiScdc *scdc, uint8_t *flag)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_1, flag);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcReadStatusFlag2(struct HdmiScdc *scdc, uint8_t *flag)
|
||||
{
|
||||
return HdmiScdcReadByte(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_2, flag);
|
||||
}
|
||||
|
||||
/* write opt */
|
||||
int32_t HdmiScdcWriteSourceVersion(struct HdmiScdc *scdc, uint8_t *srcVer)
|
||||
{
|
||||
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_SOURCE_VERSION, srcVer);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWriteUpdate0(struct HdmiScdc *scdc, uint8_t *flag)
|
||||
{
|
||||
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_UPDATE_0, flag);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWriteTmdsConfig(struct HdmiScdc *scdc, uint8_t *tmdsCfg)
|
||||
{
|
||||
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_TMDS_CONFIG, tmdsCfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWriteConfig0(struct HdmiScdc *scdc, uint8_t *cfg)
|
||||
{
|
||||
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_0, cfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWriteConfig1(struct HdmiScdc *scdc, uint8_t *cfg)
|
||||
{
|
||||
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_CONFIG_1, cfg);
|
||||
}
|
||||
|
||||
int32_t HdmiScdcWriteTestConfig0(struct HdmiScdc *scdc, uint8_t *testCfg)
|
||||
{
|
||||
return HdmiScdcWriteByte(scdc, HDMI_SCDCS_OFFSET_TEST_CONFIG_0, testCfg);
|
||||
}
|
||||
|
||||
/* cntlr ops */
|
||||
bool HdmiCntlrScdcSourceScrambleGet(struct HdmiCntlr *cntlr)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->scdcSourceScrambleGet == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
HdmiCntlrLock(cntlr);
|
||||
ret = cntlr->ops->scdcSourceScrambleGet(cntlr);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdmiCntlrScdcSourceScrambleSet(struct HdmiCntlr *cntlr, bool enable)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->scdcSourceScrambleSet == NULL) {
|
||||
return HDF_ERR_INVALID_OBJECT;
|
||||
}
|
||||
HdmiCntlrLock(cntlr);
|
||||
ret = cntlr->ops->scdcSourceScrambleSet(cntlr, enable);
|
||||
HdmiCntlrUnlock(cntlr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* scdc opt */
|
||||
int32_t HdmiScdcRrDisable(struct HdmiScdc *scdc)
|
||||
{
|
||||
union HdmiScdcsConfig0 cfg = {0};
|
||||
union HdmiScdcsTestConfig0 testCfg = {0};
|
||||
int32_t ret;
|
||||
|
||||
if (scdc == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = HdmiScdcWriteConfig0(scdc, &(cfg.data));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc write config0 fail");
|
||||
return ret;
|
||||
}
|
||||
scdc->status.cfg0 = cfg;
|
||||
|
||||
ret = HdmiScdcWriteTestConfig0(scdc, &(testCfg.data));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc write test config0 fail");
|
||||
return ret;
|
||||
}
|
||||
scdc->status.testCfg0 = testCfg;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdmiScdcScrambleSet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble)
|
||||
{
|
||||
union HdmiScdcsTmdsConfig cfg = {0};
|
||||
int32_t ret;
|
||||
|
||||
if (scdc == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = HdmiCntlrScdcSourceScrambleSet((struct HdmiCntlr *)scdc->priv, scramble->sourceScramble);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc source scrambler set fail");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (scramble->sinkScramble == true) {
|
||||
cfg.bits.scramblingEnable = 1;
|
||||
}
|
||||
if (scramble->tmdsBitClockRatio40 == true) {
|
||||
cfg.bits.tmdsBitClockRatio = 1;
|
||||
}
|
||||
ret = HdmiScdcWriteTmdsConfig(scdc, &(cfg.data));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc write tmds config fail");
|
||||
return ret;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdmiScdcScrambleGet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble)
|
||||
{
|
||||
union HdmiScdcsScramblerStatus status = {0};
|
||||
union HdmiScdcsTmdsConfig cfg = {0};
|
||||
int32_t ret;
|
||||
|
||||
if (scdc == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = HdmiScdcReadScramblerStatus(scdc, &(status.data));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc read scrambler status fail");
|
||||
return ret;
|
||||
}
|
||||
scramble->sinkScramble = (status.bits.scramblingStatus ? true : false);
|
||||
|
||||
ret = HdmiScdcReadTmdsConfig(scdc, &(cfg.data));
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc read tmds config fail");
|
||||
return ret;
|
||||
}
|
||||
scramble->tmdsBitClockRatio40 = (cfg.bits.tmdsBitClockRatio ? true : false);
|
||||
scramble->sourceScramble = HdmiCntlrScdcSourceScrambleGet(scdc->priv);
|
||||
|
||||
scdc->status.tmdsCfg = cfg;
|
||||
scdc->status.scramblerStatus = status;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
bool HdmiScdcSinkSupport(struct HdmiScdc *scdc)
|
||||
{
|
||||
uint8_t srcVer, i;
|
||||
int32_t ret;
|
||||
|
||||
if (scdc == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
for (i = 0; i < HDMI_SCDC_READ_SOURCE_VERSION_TIMES; i++) {
|
||||
srcVer = HDMI_SCDC_HDMI20_VERSION;
|
||||
ret = HdmiScdcWriteSourceVersion(scdc, &srcVer);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc write source version fail");
|
||||
return false;
|
||||
}
|
||||
ret = HdmiScdcReadSourceVersion(scdc, &srcVer);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("scdc read source version fail");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
scdc->status.sourceVersion = HDMI_SCDC_HDMI20_VERSION;
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t HdmiScdcOptMsgHandle(struct HdmiScdc *scdc, enum HdmiScdcOptMsg msg, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (scdc == NULL || buffer == NULL || len == 0) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (msg) {
|
||||
case HDMI_SCDC_OPT_SET_SOURCE_VER :
|
||||
ret = HdmiScdcWriteSourceVersion(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_SOURCE_VER :
|
||||
ret = HdmiScdcReadSourceVersion(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_SINK_VER :
|
||||
ret = HdmiScdcReadSinkVersion(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_SET_FLT_UPDATE :
|
||||
case HDMI_SCDC_OPT_SET_FRL_START :
|
||||
ret = HdmiScdcWriteUpdate0(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_FLT_UPDATE :
|
||||
case HDMI_SCDC_OPT_GET_FRL_START :
|
||||
ret = HdmiScdcReadUpdate0(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_SET_CONFIG1 :
|
||||
ret = HdmiScdcWriteConfig1(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_CONFIG1 :
|
||||
ret = HdmiScdcReadConfig1(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_TEST_CONFIG_1 :
|
||||
ret = HdmiScdcReadTestConfig1(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_FLT_READY :
|
||||
ret = HdmiScdcReadStatusFlag0(scdc, buffer);
|
||||
break;
|
||||
case HDMI_SCDC_OPT_GET_LTP_REQ :
|
||||
ret = HdmiScdcRead(scdc, HDMI_SCDCS_OFFSET_STASTUS_FLAG_1, buffer, len);
|
||||
break;
|
||||
default :
|
||||
HDF_LOGE("scdc msg handle, msg %d not support.", msg);
|
||||
ret = HDF_ERR_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdmiScdcFillScrambleCap(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble,
|
||||
enum HdmiTmdsModeType *tmdsMode)
|
||||
{
|
||||
struct HdmiCntlr *cntlr = NULL;
|
||||
struct HdmiCommonAttr *commAttr = NULL;
|
||||
struct HdmiVideoAttr *videoAttr = NULL;
|
||||
|
||||
if (scdc == NULL || scdc->priv == NULL || scramble == NULL || tmdsMode == NULL) {
|
||||
HDF_LOGD("scdc fill scramble cap: param is null");
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cntlr = (struct HdmiCntlr *)scdc->priv;
|
||||
commAttr = &(cntlr->attr.commAttr);
|
||||
videoAttr = &(cntlr->attr.videoAttr);
|
||||
if (commAttr->enableHdmi == false) {
|
||||
/* DVI mode */
|
||||
*tmdsMode = HDMI_TMDS_MODE_DVI;
|
||||
scramble->sinkScramble = false;
|
||||
scramble->sourceScramble = false;
|
||||
scramble->tmdsBitClockRatio40 = false;
|
||||
if (videoAttr->tmdsClock > HDMI_HDMI14_MAX_TMDS_RATE) {
|
||||
HDF_LOGE("tmds clock %u can't support in DVI mode.", videoAttr->tmdsClock);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
} else if (videoAttr->tmdsClock > HDMI_HDMI14_MAX_TMDS_RATE) {
|
||||
*tmdsMode = HDMI_TMDS_MODE_HDMI_2_0;
|
||||
scramble->sinkScramble = true;
|
||||
scramble->sourceScramble = true;
|
||||
scramble->tmdsBitClockRatio40 = true;
|
||||
} else {
|
||||
*tmdsMode = HDMI_TMDS_MODE_HDMI_1_4;
|
||||
scramble->sinkScramble = false;
|
||||
scramble->sourceScramble = false;
|
||||
scramble->tmdsBitClockRatio40 = false;
|
||||
}
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user