• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_dispatch.h"
10 #include "hdf_log.h"
11 #include "hdmi_core.h"
12 #include "hdmi_if.h"
13 
14 #define HDF_LOG_TAG hdmi_dispatch_c
15 
16 enum HdmiIoCmd {
17     HDMI_CMD_OPEN,
18     HDMI_CMD_CLOSE,
19     HDMI_CMD_START,
20     HDMI_CMD_STOP,
21     HDMI_CMD_AVMUTE_SET,
22     HDMI_CMD_DEEP_COLOR_SET,
23     HDMI_CMD_DEEP_COLOR_GET,
24     HDMI_CMD_VIDEO_ATTR_SET,
25     HDMI_CMD_AUDIO_ATTR_SET,
26     HDMI_CMD_HDR_ATTR_SET,
27     HDMI_CMD_READ_SINK_EDID,
28     HDMI_CMD_INFOFRAME_SET,
29     HDMI_CMD_INFOFRAME_GET,
30     HDMI_CMD_REGISTER_HPD_CALLBACK_FUNC,
31     HDMI_CMD_UNREGISTER_HPD_CALLBACK_FUNC,
32     HDMI_CMD_BUTT,
33 };
34 
35 struct HdmiDispatchFunc {
36     uint32_t cmd;
37     int32_t (*func)(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply);
38 };
39 
HdmiCmdOpen(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)40 static int32_t HdmiCmdOpen(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
41 {
42     (void)data;
43     (void)reply;
44 
45     return HdmiCntlrOpen(cntlr);
46 }
47 
HdmiCmdClose(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)48 static int32_t HdmiCmdClose(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
49 {
50     (void)data;
51     (void)reply;
52 
53     HdmiCntlrClose(cntlr);
54     return HDF_SUCCESS;
55 }
56 
HdmiCmdStart(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)57 static int32_t HdmiCmdStart(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
58 {
59     (void)data;
60     (void)reply;
61 
62     return HdmiCntlrStart(cntlr);
63 }
64 
HdmiCmdStop(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)65 static int32_t HdmiCmdStop(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
66 {
67     (void)data;
68     (void)reply;
69 
70     return HdmiCntlrStop(cntlr);
71 }
72 
HdmiCmdAvmuteSet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)73 static int32_t HdmiCmdAvmuteSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
74 {
75     bool *enable = NULL;
76     size_t size;
77     (void)reply;
78 
79     if (!HdfSbufReadBuffer(data, (const void **)&enable, &size)) {
80         HDF_LOGE("HdmiCmdAvmuteSet: sbuf read buffer failed");
81         return HDF_ERR_IO;
82     }
83     HdmiCntlrAvmuteSet(cntlr, *enable);
84     return HDF_SUCCESS;
85 }
86 
HdmiCmdDeepColorSet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)87 static int32_t HdmiCmdDeepColorSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
88 {
89     enum HdmiDeepColor *color = NULL;
90     size_t size;
91     (void)reply;
92 
93     if (!HdfSbufReadBuffer(data, (const void **)&color, &size)) {
94         HDF_LOGE("HdmiCmdDeepColorSet: sbuf read buffer failed");
95         return HDF_ERR_IO;
96     }
97     return HdmiCntlrDeepColorSet(cntlr, *color);
98 }
99 
HdmiCmdDeepColorGet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)100 static int32_t HdmiCmdDeepColorGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
101 {
102     int32_t ret;
103     enum HdmiDeepColor color;
104     (void)data;
105 
106     if (reply == NULL) {
107         return HDF_ERR_INVALID_PARAM;
108     }
109 
110     ret = HdmiCntlrDeepColorGet(cntlr, &color);
111     if (ret != HDF_SUCCESS) {
112         return ret;
113     }
114 
115     if (HdfSbufWriteBuffer(reply, &color, sizeof(color)) == false) {
116         HDF_LOGE("HdmiCmdDeepColorGet: write back color fail!");
117         return HDF_ERR_IO;
118     }
119     return HDF_SUCCESS;
120 }
121 
HdmiCmdVideoAttrSet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)122 static int32_t HdmiCmdVideoAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
123 {
124     struct HdmiVideoAttr *attr = NULL;
125     size_t size;
126     (void)reply;
127 
128     if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
129         HDF_LOGE("HdmiCmdVideoAttrSet: sbuf read buffer failed");
130         return HDF_ERR_IO;
131     }
132     return HdmiCntlrSetVideoAttribute(cntlr, attr);
133 }
134 
HdmiCmdAudioAttrSet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)135 static int32_t HdmiCmdAudioAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
136 {
137     struct HdmiAudioAttr *attr = NULL;
138     size_t size;
139     (void)reply;
140 
141     if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
142         HDF_LOGE("HdmiCmdAudioAttrSet: sbuf read buffer failed");
143         return HDF_ERR_IO;
144     }
145     return HdmiCntlrSetAudioAttribute(cntlr, attr);
146 }
147 
HdmiCmdHdrAttrSet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)148 static int32_t HdmiCmdHdrAttrSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
149 {
150     struct HdmiHdrAttr *attr = NULL;
151     size_t size;
152     (void)reply;
153 
154     if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) {
155         HDF_LOGE("HdmiCmdHdrAttrSet: sbuf read buffer failed");
156         return HDF_ERR_IO;
157     }
158     return HdmiCntlrSetHdrAttribute(cntlr, attr);
159 }
160 
HdmiCmdReadSinkEdid(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)161 static int32_t HdmiCmdReadSinkEdid(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
162 {
163     int32_t ret;
164     uint8_t edid[HDMI_EDID_TOTAL_SIZE] = {0};
165     (void)data;
166 
167     if (reply == NULL) {
168         return HDF_ERR_INVALID_PARAM;
169     }
170 
171     ret = HdmiCntlrGetSinkEdid(cntlr, edid, HDMI_EDID_TOTAL_SIZE);
172     if (ret != HDF_SUCCESS) {
173         return ret;
174     }
175 
176     if (HdfSbufWriteBuffer(reply, edid, HDMI_EDID_TOTAL_SIZE) == false) {
177         HDF_LOGE("HdmiCmdReadSinkEdid: write back edid fail!");
178         return HDF_ERR_IO;
179     }
180 
181     return HDF_SUCCESS;
182 }
183 
HdmiCmdInfoFrameSet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)184 static int32_t HdmiCmdInfoFrameSet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
185 {
186     enum HdmiPacketType type;
187     union HdmiInfoFrameInfo *frame = NULL;
188     size_t size;
189 
190     (void)reply;
191     if (!HdfSbufReadUint16(data, (uint16_t *)&type)) {
192         HDF_LOGE("HdmiCmdInfoFrameSet: sbuf read uint16 failed");
193         return HDF_ERR_IO;
194     }
195 
196     if (!HdfSbufReadBuffer(data, (const void **)&frame, &size)) {
197         HDF_LOGE("HdmiCmdInfoFrameSet: sbuf read buffer failed");
198         return HDF_ERR_IO;
199     }
200     return HdmiCntlrInfoFrameSet(cntlr, type, frame);
201 }
202 
HdmiCmdInfoFrameGet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)203 static int32_t HdmiCmdInfoFrameGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
204 {
205     size_t size;
206     int32_t ret;
207     enum HdmiPacketType *type = NULL;
208     union HdmiInfoFrameInfo frame = {0};
209 
210     if (!HdfSbufReadBuffer(data, (const void **)&type, &size)) {
211         HDF_LOGE("HdmiCmdInfoFrameGet: sbuf read buffer failed");
212         return HDF_ERR_IO;
213     }
214 
215     ret = HdmiCntlrInfoFrameGet(cntlr, *type, &frame);
216     if (ret != HDF_SUCCESS) {
217         return ret;
218     }
219 
220     if (HdfSbufWriteBuffer(reply, &frame, sizeof(frame)) == false) {
221         HDF_LOGE("HdmiCmdInfoFrameGet: write back frame fail!");
222         return HDF_ERR_IO;
223     }
224 
225     return HDF_SUCCESS;
226 }
227 
HdmiCmdRegisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)228 static int32_t HdmiCmdRegisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
229 {
230     uint32_t *addr = NULL;
231     size_t size;
232     (void)reply;
233 
234     if (!HdfSbufReadBuffer(data, (const void **)&addr, &size)) {
235         HDF_LOGE("HdmiCmdRegisterHpdCallbackFunc: sbuf read buffer failed");
236         return HDF_ERR_IO;
237     }
238     return HdmiCntlrRegisterHpdCallbackFunc(cntlr, (struct HdmiHpdCallbackInfo *)(uintptr_t)(*addr));
239 }
240 
HdmiCmdUnregisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)241 static int32_t HdmiCmdUnregisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
242 {
243     (void)data;
244     (void)reply;
245 
246     return HdmiCntlrUnregisterHpdCallbackFunc(cntlr);
247 }
248 
HdmiIoDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)249 int32_t HdmiIoDispatch(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
250 {
251     struct HdmiCntlr *cntlr = NULL;
252     uint32_t i;
253     uint32_t len;
254     struct HdmiDispatchFunc dispatchFunc[] = {
255         { HDMI_CMD_OPEN, HdmiCmdOpen },
256         { HDMI_CMD_CLOSE, HdmiCmdClose },
257         { HDMI_CMD_START, HdmiCmdStart },
258         { HDMI_CMD_STOP, HdmiCmdStop },
259         { HDMI_CMD_AVMUTE_SET, HdmiCmdAvmuteSet },
260         { HDMI_CMD_DEEP_COLOR_SET, HdmiCmdDeepColorSet },
261         { HDMI_CMD_DEEP_COLOR_GET, HdmiCmdDeepColorGet },
262         { HDMI_CMD_VIDEO_ATTR_SET, HdmiCmdVideoAttrSet },
263         { HDMI_CMD_AUDIO_ATTR_SET, HdmiCmdAudioAttrSet },
264         { HDMI_CMD_HDR_ATTR_SET, HdmiCmdHdrAttrSet },
265         { HDMI_CMD_READ_SINK_EDID, HdmiCmdReadSinkEdid },
266         { HDMI_CMD_INFOFRAME_SET, HdmiCmdInfoFrameSet },
267         { HDMI_CMD_INFOFRAME_GET, HdmiCmdInfoFrameGet },
268         { HDMI_CMD_REGISTER_HPD_CALLBACK_FUNC, HdmiCmdRegisterHpdCallbackFunc },
269         { HDMI_CMD_UNREGISTER_HPD_CALLBACK_FUNC, HdmiCmdUnregisterHpdCallbackFunc },
270     };
271 
272     if (client == NULL || client->device == NULL) {
273         HDF_LOGE("HdmiIoDispatch: client or hdf dev obj is NULL");
274         return HDF_ERR_INVALID_OBJECT;
275     }
276 
277     cntlr = (struct HdmiCntlr *)client->device->service;
278     if (cntlr == NULL) {
279         HDF_LOGE("HdmiIoDispatch: service is NULL");
280         return HDF_ERR_INVALID_OBJECT;
281     }
282 
283     len = sizeof(dispatchFunc) / sizeof(dispatchFunc[0]);
284     for (i = 0; i < len; i++) {
285         if (dispatchFunc[i].cmd == cmd) {
286             return dispatchFunc[i].func(cntlr, data, reply);
287         }
288     }
289 
290     HDF_LOGE("HdmiIoDispatch: cmd %d is not support", cmd);
291     return HDF_ERR_NOT_SUPPORT;
292 }
293