• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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     if (!HdfSbufReadUint16(data, (uint16_t *)&type)) {
191         HDF_LOGE("HdmiCmdInfoFrameSet: sbuf read uint16 failed");
192         return HDF_ERR_IO;
193     }
194 
195     if (!HdfSbufReadBuffer(data, (const void **)&frame, &size)) {
196         HDF_LOGE("HdmiCmdInfoFrameSet: sbuf read buffer failed");
197         return HDF_ERR_IO;
198     }
199     return HdmiCntlrInfoFrameSet(cntlr, type, frame);
200 }
201 
HdmiCmdInfoFrameGet(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)202 static int32_t HdmiCmdInfoFrameGet(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
203 {
204     size_t size;
205     int32_t ret;
206     enum HdmiPacketType *type = NULL;
207     union HdmiInfoFrameInfo frame = {0};
208 
209     if (!HdfSbufReadBuffer(data, (const void **)&type, &size)) {
210         HDF_LOGE("HdmiCmdInfoFrameGet: sbuf read buffer failed");
211         return HDF_ERR_IO;
212     }
213 
214     ret = HdmiCntlrInfoFrameGet(cntlr, *type, &frame);
215     if (ret != HDF_SUCCESS) {
216         return ret;
217     }
218 
219     if (HdfSbufWriteBuffer(reply, &frame, sizeof(frame)) == false) {
220         HDF_LOGE("HdmiCmdInfoFrameGet: write back frame fail!");
221         return HDF_ERR_IO;
222     }
223 
224     return HDF_SUCCESS;
225 }
226 
HdmiCmdRegisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)227 static int32_t HdmiCmdRegisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
228 {
229     uint32_t *addr = NULL;
230     size_t size;
231     (void)reply;
232 
233     if (!HdfSbufReadBuffer(data, (const void **)&addr, &size)) {
234         HDF_LOGE("HdmiCmdRegisterHpdCallbackFunc: sbuf read buffer failed");
235         return HDF_ERR_IO;
236     }
237     return HdmiCntlrRegisterHpdCallbackFunc(cntlr, (struct HdmiHpdCallbackInfo *)(uintptr_t)(*addr));
238 }
239 
HdmiCmdUnregisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)240 static int32_t HdmiCmdUnregisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
241 {
242     (void)data;
243     (void)reply;
244 
245     return HdmiCntlrUnregisterHpdCallbackFunc(cntlr);
246 }
247 
HdmiIoDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)248 int32_t HdmiIoDispatch(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
249 {
250     struct HdmiCntlr *cntlr = NULL;
251     uint32_t i, len;
252     struct HdmiDispatchFunc dispatchFunc[] = {
253         { HDMI_CMD_OPEN, HdmiCmdOpen },
254         { HDMI_CMD_CLOSE, HdmiCmdClose },
255         { HDMI_CMD_START, HdmiCmdStart },
256         { HDMI_CMD_STOP, HdmiCmdStop },
257         { HDMI_CMD_AVMUTE_SET, HdmiCmdAvmuteSet },
258         { HDMI_CMD_DEEP_COLOR_SET, HdmiCmdDeepColorSet },
259         { HDMI_CMD_DEEP_COLOR_GET, HdmiCmdDeepColorGet },
260         { HDMI_CMD_VIDEO_ATTR_SET, HdmiCmdVideoAttrSet },
261         { HDMI_CMD_AUDIO_ATTR_SET, HdmiCmdAudioAttrSet },
262         { HDMI_CMD_HDR_ATTR_SET, HdmiCmdHdrAttrSet },
263         { HDMI_CMD_READ_SINK_EDID, HdmiCmdReadSinkEdid },
264         { HDMI_CMD_INFOFRAME_SET, HdmiCmdInfoFrameSet },
265         { HDMI_CMD_INFOFRAME_GET, HdmiCmdInfoFrameGet },
266         { HDMI_CMD_REGISTER_HPD_CALLBACK_FUNC, HdmiCmdRegisterHpdCallbackFunc },
267         { HDMI_CMD_UNREGISTER_HPD_CALLBACK_FUNC, HdmiCmdUnregisterHpdCallbackFunc },
268     };
269 
270     if (client == NULL || client->device == NULL) {
271         HDF_LOGE("HdmiIoDispatch: client or hdf dev obj is NULL");
272         return HDF_ERR_INVALID_OBJECT;
273     }
274 
275     cntlr = (struct HdmiCntlr *)client->device->service;
276     if (cntlr == NULL) {
277         HDF_LOGE("HdmiIoDispatch: service is NULL");
278         return HDF_ERR_INVALID_OBJECT;
279     }
280 
281     len = sizeof(dispatchFunc) / sizeof(dispatchFunc[0]);
282     for (i = 0; i < len; i++) {
283         if (dispatchFunc[i].cmd == cmd) {
284             return dispatchFunc[i].func(cntlr, data, reply);
285         }
286     }
287 
288     HDF_LOGE("HdmiIoDispatch: cmd %d is not support", cmd);
289     return HDF_ERR_NOT_SUPPORT;
290 }
291