1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdmi_test.h"
10 #include "device_resource_if.h"
11 #include "hdf_base.h"
12 #include "hdf_log.h"
13 #include "hdmi_if.h"
14 #include "osal_time.h"
15
16 #define HDF_LOG_TAG hdmi_test_c
17
18 struct HdmiTestFunc {
19 enum HdmiTestCmd type;
20 int32_t (*Func)(const struct HdmiTester *tester);
21 };
22
HdmiTestGetHandle(const struct HdmiTester * tester)23 static DevHandle HdmiTestGetHandle(const struct HdmiTester *tester)
24 {
25 if (tester == NULL) {
26 HDF_LOGE("HdmiTestGetHandle: tester is null!");
27 return NULL;
28 }
29 return HdmiOpen(tester->busNum);
30 }
31
HdmiTestReleaseHandle(DevHandle handle)32 static void HdmiTestReleaseHandle(DevHandle handle)
33 {
34 if (handle == NULL) {
35 HDF_LOGE("HdmiTestReleaseHandle: sdio handle is null!");
36 return;
37 }
38 HdmiClose(handle);
39 }
40
TestHdmiStartAndStop(const struct HdmiTester * tester)41 static int32_t TestHdmiStartAndStop(const struct HdmiTester *tester)
42 {
43 int32_t ret;
44
45 ret = HdmiStart(tester->handle);
46 if (ret != HDF_SUCCESS) {
47 HDF_LOGE("TestHdmiStartAndStop: HdmiStart fail, ret = %d!", ret);
48 return ret;
49 }
50 ret = HdmiStop(tester->handle);
51 if (ret != HDF_SUCCESS) {
52 HDF_LOGE("TestHdmiStartAndStop: HdmiStop fail, ret = %d!", ret);
53 }
54 return ret;
55 }
56
TestHdmiSetAudioAttr(const struct HdmiTester * tester)57 static int32_t TestHdmiSetAudioAttr(const struct HdmiTester *tester)
58 {
59 int32_t ret;
60 struct HdmiAudioAttr attr = {0};
61
62 attr.codingType = HDMI_AUDIO_CODING_TYPE_STREAM;
63 attr.ifType = HDMI_AUDIO_IF_TYPE_I2S;
64 attr.bitDepth = HDMI_ADIO_BIT_DEPTH_20;
65 attr.sampleRate = HDMI_SAMPLE_RATE_12K;
66 attr.channels = HDMI_AUDIO_FORMAT_CHANNEL_5;
67 ret = HdmiSetAudioAttribute(tester->handle, &attr);
68 if (ret != HDF_SUCCESS) {
69 HDF_LOGE("TestHdmiSetAudioAttr: HdmiSetAudioAttribute fail, ret = %d!", ret);
70 }
71 return ret;
72 }
73
TestHdmiSetVideoAttr(const struct HdmiTester * tester)74 static int32_t TestHdmiSetVideoAttr(const struct HdmiTester *tester)
75 {
76 int32_t ret;
77 struct HdmiVideoAttr attr = {0};
78
79 attr.xvycc = true;
80 attr.nups = HDMI_NUPS_HORIZONTAL;
81 attr.colorSpace = HDMI_COLOR_SPACE_YCBCR420;
82 attr.colorimetry = HDMI_COLORIMETRY_ITU709;
83 attr.quantization = HDMI_QUANTIZATION_RANGE_FULL;
84 ret = HdmiSetVideoAttribute(tester->handle, &attr);
85 if (ret != HDF_SUCCESS) {
86 HDF_LOGE("TestHdmiSetVideoAttr: HdmiSetAudioAttribute fail, ret = %d!", ret);
87 }
88 return ret;
89 }
90
TestHdmiSetHdrAttr(const struct HdmiTester * tester)91 static int32_t TestHdmiSetHdrAttr(const struct HdmiTester *tester)
92 {
93 int32_t ret;
94 struct HdmiHdrAttr attr = {0};
95
96 attr.mode = HDMI_HDR_MODE_DOLBY_NORMAL;
97 attr.userMode = HDMI_HDR_USERMODE_DOLBY;
98 attr.eotfType = HDMI_EOTF_HLG;
99 attr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_S_YCC_601;
100 attr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;
101 ret = HdmiSetHdrAttribute(tester->handle, &attr);
102 if (ret != HDF_SUCCESS) {
103 HDF_LOGE("TestHdmiSetHdrAttr: HdmiSetHdrAttribute fail, ret = %d!", ret);
104 }
105 return ret;
106 }
107
TestHdmiSetAvmute(const struct HdmiTester * tester)108 static int32_t TestHdmiSetAvmute(const struct HdmiTester *tester)
109 {
110 int32_t ret;
111
112 ret = HdmiAvmuteSet(tester->handle, true);
113 if (ret != HDF_SUCCESS) {
114 HDF_LOGE("TestHdmiSetAvmute: HdmiAvmuteSet fail, ret = %d!", ret);
115 return ret;
116 }
117
118 ret = HdmiAvmuteSet(tester->handle, false);
119 if (ret != HDF_SUCCESS) {
120 HDF_LOGE("TestHdmiSetAvmute: HdmiAvmuteSet fail, ret = %d!", ret);
121 }
122 return ret;
123 }
124
TestHdmiEdidRawDataGet(const struct HdmiTester * tester)125 static int32_t TestHdmiEdidRawDataGet(const struct HdmiTester *tester)
126 {
127 int32_t len;
128 uint8_t edid[HDMI_EDID_MAX_LEN] = {0};
129
130 len = HdmiReadSinkEdid(tester->handle, edid, HDMI_EDID_MAX_LEN);
131 if (len < 0) {
132 HDF_LOGE("TestHdmiEdidRawDataGet: HdmiReadSinkEdid fail, len = %d!", len);
133 return HDF_FAILURE;
134 }
135 HDF_LOGD("TestHdmiEdidRawDataGet: HdmiReadSinkEdid success, len = %d, edid[1] = 0x%x!", len, edid[1]);
136 return HDF_SUCCESS;
137 }
138
TestHdmiDeepColorSetAndGet(const struct HdmiTester * tester)139 static int32_t TestHdmiDeepColorSetAndGet(const struct HdmiTester *tester)
140 {
141 int32_t ret;
142 enum HdmiDeepColor color = HDMI_DEEP_COLOR_BUTT;
143
144 ret = HdmiDeepColorSet(tester->handle, HDMI_DEEP_COLOR_48BITS);
145 if (ret != HDF_SUCCESS) {
146 HDF_LOGE("TestHdmiDeepColorSetAndGet: HdmiDeepColorSet fail, ret = %d!", ret);
147 }
148 ret = HdmiDeepColorGet(tester->handle, &color);
149 if (ret != HDF_SUCCESS) {
150 HDF_LOGE("TestHdmiDeepColorSetAndGet: HdmiDeepColorGet fail, ret = %d!", ret);
151 } else {
152 HDF_LOGD("TestHdmiDeepColorSetAndGet: HdmiDeepColorGet success, color = %d!", color);
153 }
154 return ret;
155 }
156
TestHdmiHdpHandle(void * data,bool hdp)157 static void TestHdmiHdpHandle(void *data, bool hdp)
158 {
159 if (data == NULL) {
160 HDF_LOGE("TestHdmiHdpHandle: data is null!");
161 return;
162 }
163
164 if (hdp == true) {
165 HDF_LOGD("TestHdmiHdpHandle: hdp.");
166 } else {
167 HDF_LOGD("TestHdmiHdpHandle: unhdp.");
168 }
169 }
170
TestHdmiHpdRegisterAndUnregister(const struct HdmiTester * tester)171 static int32_t TestHdmiHpdRegisterAndUnregister(const struct HdmiTester *tester)
172 {
173 int32_t ret;
174 struct HdmiHpdCallbackInfo info;
175
176 info.data = NULL;
177 info.callbackFunc = TestHdmiHdpHandle;
178 ret = HdmiRegisterHpdCallbackFunc(tester->handle, &info);
179 if (ret != HDF_SUCCESS) {
180 HDF_LOGE("TestHdmiHpdRegisterAndUnregister: TestHdmiHpdRegisterAndUnregister fail, ret = %d!", ret);
181 }
182 ret = HdmiUnregisterHpdCallbackFunc(tester->handle);
183 if (ret != HDF_SUCCESS) {
184 HDF_LOGE("TestHdmiHpdRegisterAndUnregister: HdmiUnregisterHpdCallbackFunc fail, ret = %d!", ret);
185 }
186 return ret;
187 }
188
189 struct HdmiTestFunc g_hdmiTestFunc[] = {
190 { HDMI_START_AND_STOP_01, TestHdmiStartAndStop },
191 { HDMI_SET_AUDIO_ATTR_01, TestHdmiSetAudioAttr },
192 { HDMI_SET_VIDEO_ATTR_01, TestHdmiSetVideoAttr },
193 { HDMI_SET_HDR_ATTR_01, TestHdmiSetHdrAttr },
194 { HDMI_SET_AVMUTE_01, TestHdmiSetAvmute },
195 { HDMI_EDID_RAW_DATA_GET_01, TestHdmiEdidRawDataGet },
196 { HDMI_DEEP_COLOR_SET_AND_GET_01, TestHdmiDeepColorSetAndGet },
197 { HDMI_HPD_REGISTER_AND_UNREGISTER_01, TestHdmiHpdRegisterAndUnregister },
198 };
199
HdmiTestEntry(struct HdmiTester * tester,int32_t cmd)200 static int32_t HdmiTestEntry(struct HdmiTester *tester, int32_t cmd)
201 {
202 int32_t i;
203 int32_t ret = HDF_SUCCESS;
204 bool isFind = false;
205
206 if (tester == NULL) {
207 HDF_LOGE("HdmiTestEntry: tester is null!");
208 return HDF_ERR_INVALID_OBJECT;
209 }
210 tester->handle = HdmiTestGetHandle(tester);
211 if (tester->handle == NULL) {
212 HDF_LOGE("HdmiTestEntry: hdmi test get handle fail!");
213 return HDF_FAILURE;
214 }
215 for (i = 0; i < sizeof(g_hdmiTestFunc) / sizeof(g_hdmiTestFunc[0]); i++) {
216 if (cmd == g_hdmiTestFunc[i].type && g_hdmiTestFunc[i].Func != NULL) {
217 ret = g_hdmiTestFunc[i].Func(tester);
218 isFind = true;
219 break;
220 }
221 }
222 if (!isFind) {
223 ret = HDF_ERR_NOT_SUPPORT;
224 HDF_LOGE("HdmiTestEntry: cmd %d is not support!", cmd);
225 }
226 HdmiTestReleaseHandle(tester->handle);
227 return ret;
228 }
229
HdmiTestFillConfig(struct HdmiTester * tester,const struct DeviceResourceNode * node)230 static int32_t HdmiTestFillConfig(struct HdmiTester *tester, const struct DeviceResourceNode *node)
231 {
232 int32_t ret;
233 struct DeviceResourceIface *drsOps = NULL;
234
235 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
236 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
237 HDF_LOGE("HdmiTestFillConfig: invalid drs ops!");
238 return HDF_FAILURE;
239 }
240
241 ret = drsOps->GetUint32(node, "busNum", &(tester->busNum), 0);
242 if (ret != HDF_SUCCESS) {
243 HDF_LOGE("HdmiTestFillConfig: fill bus num fail!");
244 return ret;
245 }
246
247 HDF_LOGD("HdmiTestFillConfig: busNum:%d!", tester->busNum);
248 return HDF_SUCCESS;
249 }
250
HdmiTestBind(struct HdfDeviceObject * device)251 static int32_t HdmiTestBind(struct HdfDeviceObject *device)
252 {
253 static struct HdmiTester tester;
254
255 if (device == NULL) {
256 HDF_LOGE("HdmiTestBind: device is null!");
257 return HDF_ERR_IO;
258 }
259
260 device->service = &tester.service;
261 HDF_LOGD("HdmiTestBind: HDMI_TEST service bind success!");
262 return HDF_SUCCESS;
263 }
264
HdmiTestInit(struct HdfDeviceObject * device)265 static int32_t HdmiTestInit(struct HdfDeviceObject *device)
266 {
267 struct HdmiTester *tester = NULL;
268 int32_t ret;
269
270 if (device == NULL || device->service == NULL || device->property == NULL) {
271 HDF_LOGE("HdmiTestInit: invalid parameter!");
272 return HDF_ERR_INVALID_PARAM;
273 }
274
275 tester = (struct HdmiTester *)device->service;
276 ret = HdmiTestFillConfig(tester, device->property);
277 if (ret != HDF_SUCCESS) {
278 HDF_LOGE("HdmiTestInit: read config fail!");
279 return ret;
280 }
281 tester->TestEntry = HdmiTestEntry;
282 HDF_LOGD("HdmiTestInit: success!");
283 return HDF_SUCCESS;
284 }
285
HdmiTestRelease(struct HdfDeviceObject * device)286 static void HdmiTestRelease(struct HdfDeviceObject *device)
287 {
288 if (device != NULL) {
289 device->service = NULL;
290 }
291 }
292
293 struct HdfDriverEntry g_hdmiTestEntry = {
294 .moduleVersion = 1,
295 .Bind = HdmiTestBind,
296 .Init = HdmiTestInit,
297 .Release = HdmiTestRelease,
298 .moduleName = "PLATFORM_HDMI_TEST",
299 };
300 HDF_INIT(g_hdmiTestEntry);
301