1 /*
2 * Copyright (c) 2021 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)(struct HdmiTester *tester);
21 };
22
HdmiTestGetHandle(struct HdmiTester * tester)23 static DevHandle HdmiTestGetHandle(struct HdmiTester *tester)
24 {
25 if (tester == NULL) {
26 HDF_LOGE("%s: tester is null", __func__);
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("%s: sdio handle is null", __func__);
36 return;
37 }
38 HdmiClose(handle);
39 }
40
TestHdmiStartAndStop(struct HdmiTester * tester)41 static int32_t TestHdmiStartAndStop(struct HdmiTester *tester)
42 {
43 int32_t ret;
44
45 ret = HdmiStart(tester->handle);
46 if (ret != HDF_SUCCESS) {
47 HDF_LOGE("%s: HdmiStart failed ret = %d.", __func__, ret);
48 return ret;
49 }
50 ret = HdmiStop(tester->handle);
51 if (ret != HDF_SUCCESS) {
52 HDF_LOGE("%s: HdmiStop failed ret = %d.", __func__, ret);
53 }
54 return ret;
55 }
56
TestHdmiSetAudioAttr(struct HdmiTester * tester)57 static int32_t TestHdmiSetAudioAttr(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("%s: HdmiSetAudioAttribute failed ret = %d.", __func__, ret);
70 }
71 return ret;
72 }
73
TestHdmiSetVideoAttr(struct HdmiTester * tester)74 static int32_t TestHdmiSetVideoAttr(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("%s: HdmiSetAudioAttribute failed ret = %d.", __func__, ret);
87 }
88 return ret;
89 }
90
TestHdmiSetHdrAttr(struct HdmiTester * tester)91 static int32_t TestHdmiSetHdrAttr(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("%s: HdmiSetHdrAttribute failed ret=%d.", __func__, ret);
104 }
105 return ret;
106 }
107
TestHdmiSetAvmute(struct HdmiTester * tester)108 static int32_t TestHdmiSetAvmute(struct HdmiTester *tester)
109 {
110 int32_t ret;
111
112 ret = HdmiAvmuteSet(tester->handle, true);
113 if (ret != HDF_SUCCESS) {
114 HDF_LOGE("%s: HdmiAvmuteSet failed ret = %d.", __func__, ret);
115 return ret;
116 }
117
118 ret = HdmiAvmuteSet(tester->handle, false);
119 if (ret != HDF_SUCCESS) {
120 HDF_LOGE("%s: HdmiAvmuteSet failed ret = %d.", __func__, ret);
121 }
122 return ret;
123 }
124
TestHdmiEdidRawDataGet(struct HdmiTester * tester)125 static int32_t TestHdmiEdidRawDataGet(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("%s: HdmiReadSinkEdid failed len = %d.", __func__, len);
133 return HDF_FAILURE;
134 }
135 HDF_LOGD("%s: HdmiReadSinkEdid success, len = %d, edid[1] = 0x%x.", __func__, len, edid[1]);
136 return HDF_SUCCESS;
137 }
138
TestHdmiDeepColorSetAndGet(struct HdmiTester * tester)139 static int32_t TestHdmiDeepColorSetAndGet(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("%s: HdmiDeepColorSet failed ret = %d.", __func__, ret);
147 }
148 ret = HdmiDeepColorGet(tester->handle, &color);
149 if (ret != HDF_SUCCESS) {
150 HDF_LOGE("%s: HdmiDeepColorGet failed ret = %d.", __func__, ret);
151 } else {
152 HDF_LOGE("%s: HdmiDeepColorGet success, color = %d.", __func__, 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 printf("data is null");
161 }
162
163 if (hdp == true) {
164 HDF_LOGE("TestHdmiHdpHandle: hdp.");
165 } else {
166 HDF_LOGE("TestHdmiHdpHandle: unhdp.");
167 }
168 }
169
TestHdmiHpdRegisterAndUnregister(struct HdmiTester * tester)170 static int32_t TestHdmiHpdRegisterAndUnregister(struct HdmiTester *tester)
171 {
172 int32_t ret;
173 struct HdmiHpdCallbackInfo info;
174
175 info.data = NULL;
176 info.callbackFunc = TestHdmiHdpHandle;
177 ret = HdmiRegisterHpdCallbackFunc(tester->handle, &info);
178 if (ret != HDF_SUCCESS) {
179 HDF_LOGE("%s: TestHdmiHpdRegisterAndUnregister failed ret = %d.", __func__, ret);
180 }
181 ret = HdmiUnregisterHpdCallbackFunc(tester->handle);
182 if (ret != HDF_SUCCESS) {
183 HDF_LOGE("%s: HdmiUnregisterHpdCallbackFunc failed ret = %d.", __func__, ret);
184 }
185 return ret;
186 }
187
188 struct HdmiTestFunc g_hdmiTestFunc[] = {
189 { HDMI_START_AND_STOP_01, TestHdmiStartAndStop },
190 { HDMI_SET_AUDIO_ATTR_01, TestHdmiSetAudioAttr },
191 { HDMI_SET_VIDEO_ATTR_01, TestHdmiSetVideoAttr },
192 { HDMI_SET_HDR_ATTR_01, TestHdmiSetHdrAttr },
193 { HDMI_SET_AVMUTE_01, TestHdmiSetAvmute },
194 { HDMI_EDID_RAW_DATA_GET_01, TestHdmiEdidRawDataGet },
195 { HDMI_DEEP_COLOR_SET_AND_GET_01, TestHdmiDeepColorSetAndGet },
196 { HDMI_HPD_REGISTER_AND_UNREGISTER_01, TestHdmiHpdRegisterAndUnregister },
197 };
198
HdmiTestEntry(struct HdmiTester * tester,int32_t cmd)199 static int32_t HdmiTestEntry(struct HdmiTester *tester, int32_t cmd)
200 {
201 int32_t i;
202 int32_t ret = HDF_SUCCESS;
203 bool isFind = false;
204
205 if (tester == NULL) {
206 HDF_LOGE("%s: tester is NULL", __func__);
207 return HDF_ERR_INVALID_OBJECT;
208 }
209 tester->handle = HdmiTestGetHandle(tester);
210 if (tester->handle == NULL) {
211 HDF_LOGE("%s: hdmi test get handle failed", __func__);
212 return HDF_FAILURE;
213 }
214 for (i = 0; i < sizeof(g_hdmiTestFunc) / sizeof(g_hdmiTestFunc[0]); i++) {
215 if (cmd == g_hdmiTestFunc[i].type && g_hdmiTestFunc[i].Func != NULL) {
216 ret = g_hdmiTestFunc[i].Func(tester);
217 isFind = true;
218 break;
219 }
220 }
221 if (!isFind) {
222 ret = HDF_ERR_NOT_SUPPORT;
223 HDF_LOGE("%s: cmd %d not supported", __func__, cmd);
224 }
225 HdmiTestReleaseHandle(tester->handle);
226 return ret;
227 }
228
HdmiTestFillConfig(struct HdmiTester * tester,const struct DeviceResourceNode * node)229 static int32_t HdmiTestFillConfig(struct HdmiTester *tester, const struct DeviceResourceNode *node)
230 {
231 int32_t ret;
232 struct DeviceResourceIface *drsOps = NULL;
233
234 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
235 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
236 HDF_LOGE("%s: invalid drs ops", __func__);
237 return HDF_FAILURE;
238 }
239
240 ret = drsOps->GetUint32(node, "busNum", &(tester->busNum), 0);
241 if (ret != HDF_SUCCESS) {
242 HDF_LOGE("%s: fill bus num failed", __func__);
243 return ret;
244 }
245
246 HDF_LOGE("%s: busNum:%d.", __func__, tester->busNum);
247 return HDF_SUCCESS;
248 }
249
HdmiTestBind(struct HdfDeviceObject * device)250 static int32_t HdmiTestBind(struct HdfDeviceObject *device)
251 {
252 static struct HdmiTester tester;
253
254 if (device == NULL) {
255 HDF_LOGE("%s: device or config is null!", __func__);
256 return HDF_ERR_IO;
257 }
258
259 device->service = &tester.service;
260 HDF_LOGE("%s: HDMI_TEST service init success!", __func__);
261 return HDF_SUCCESS;
262 }
263
HdmiTestInit(struct HdfDeviceObject * device)264 static int32_t HdmiTestInit(struct HdfDeviceObject *device)
265 {
266 struct HdmiTester *tester = NULL;
267 int32_t ret;
268
269 if (device == NULL || device->service == NULL || device->property == NULL) {
270 HDF_LOGE("%s: invalid parameter", __func__);
271 return HDF_ERR_INVALID_PARAM;
272 }
273
274 tester = (struct HdmiTester *)device->service;
275 if (tester == NULL) {
276 HDF_LOGE("%s: tester is NULL", __func__);
277 return HDF_ERR_INVALID_PARAM;
278 }
279 ret = HdmiTestFillConfig(tester, device->property);
280 if (ret != HDF_SUCCESS) {
281 HDF_LOGE("%s: read config failed", __func__);
282 return ret;
283 }
284 tester->TestEntry = HdmiTestEntry;
285 HDF_LOGE("%s: success", __func__);
286 return HDF_SUCCESS;
287 }
288
HdmiTestRelease(struct HdfDeviceObject * device)289 static void HdmiTestRelease(struct HdfDeviceObject *device)
290 {
291 if (device != NULL) {
292 device->service = NULL;
293 }
294 }
295
296 struct HdfDriverEntry g_hdmiTestEntry = {
297 .moduleVersion = 1,
298 .Bind = HdmiTestBind,
299 .Init = HdmiTestInit,
300 .Release = HdmiTestRelease,
301 .moduleName = "PLATFORM_HDMI_TEST",
302 };
303 HDF_INIT(g_hdmiTestEntry);
304