1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "disp_hal.h"
17094332d3Sopenharmony_ci#include <securec.h>
18094332d3Sopenharmony_ci#include "hdf_io_service_if.h"
19094332d3Sopenharmony_ci#include "hdf_log.h"
20094332d3Sopenharmony_ci#include "hdf_sbuf.h"
21094332d3Sopenharmony_ci
22094332d3Sopenharmony_ci#define OFFSET_TWO_BYTE    16
23094332d3Sopenharmony_ci#define MASK_TWO_BYTE      0xffff
24094332d3Sopenharmony_ci
25094332d3Sopenharmony_cistatic int32_t DispCmdSend(const uint32_t cmd, struct HdfSBuf *reqData, struct HdfSBuf *respData)
26094332d3Sopenharmony_ci{
27094332d3Sopenharmony_ci    struct HdfIoService *dispService = NULL;
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_ci    dispService = HdfIoServiceBind(DISP_SERVICE_NAME);
30094332d3Sopenharmony_ci    if ((dispService == NULL) || (dispService->dispatcher == NULL) || (dispService->dispatcher->Dispatch == NULL)) {
31094332d3Sopenharmony_ci        HDF_LOGE("%s:bad remote service found", __func__);
32094332d3Sopenharmony_ci        goto EXIT;
33094332d3Sopenharmony_ci    }
34094332d3Sopenharmony_ci    int32_t ret = dispService->dispatcher->Dispatch(&dispService->object, cmd, reqData, respData);
35094332d3Sopenharmony_ci    if (ret != DISPLAY_SUCCESS) {
36094332d3Sopenharmony_ci        HDF_LOGE("%s: cmd=%u, ret=%d", __func__, cmd, ret);
37094332d3Sopenharmony_ci        goto EXIT;
38094332d3Sopenharmony_ci    }
39094332d3Sopenharmony_ci    HDF_LOGI("%s: cmd=%u, ret=%d", __func__, cmd, ret);
40094332d3Sopenharmony_ci    HdfIoServiceRecycle(dispService);
41094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_ciEXIT:
44094332d3Sopenharmony_ci    HdfIoServiceRecycle(dispService);
45094332d3Sopenharmony_ci    return DISPLAY_FAILURE;
46094332d3Sopenharmony_ci}
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_cistatic int32_t GetInfo(uint32_t devId, struct DispInfo *info)
49094332d3Sopenharmony_ci{
50094332d3Sopenharmony_ci    struct DispInfo *tmpInfo = NULL;
51094332d3Sopenharmony_ci    struct HdfSBuf *data = NULL;
52094332d3Sopenharmony_ci    struct HdfSBuf *reply = NULL;
53094332d3Sopenharmony_ci
54094332d3Sopenharmony_ci    if (info == NULL) {
55094332d3Sopenharmony_ci        HDF_LOGE("%s: invalid param", __func__);
56094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
57094332d3Sopenharmony_ci    }
58094332d3Sopenharmony_ci
59094332d3Sopenharmony_ci    data = HdfSbufObtainDefaultSize();
60094332d3Sopenharmony_ci    if (data == NULL) {
61094332d3Sopenharmony_ci        HDF_LOGE("%s: obtain data sbuf fail", __func__);
62094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
63094332d3Sopenharmony_ci    }
64094332d3Sopenharmony_ci    reply = HdfSbufObtainDefaultSize();
65094332d3Sopenharmony_ci    if (reply == NULL) {
66094332d3Sopenharmony_ci        HDF_LOGE("%s: obtain reply sbuf fail", __func__);
67094332d3Sopenharmony_ci        goto EXIT;
68094332d3Sopenharmony_ci    }
69094332d3Sopenharmony_ci    if (!HdfSbufWriteUint32(data, devId)) {
70094332d3Sopenharmony_ci        HDF_LOGE("HdfSbufWriteUint32 failure");
71094332d3Sopenharmony_ci        goto EXIT;
72094332d3Sopenharmony_ci    }
73094332d3Sopenharmony_ci    if (DispCmdSend(DISP_CMD_GET_PANELINFO, data, reply) != DISPLAY_SUCCESS) {
74094332d3Sopenharmony_ci        HDF_LOGE("cmd:DISP_CMD_GET_PANEL_INFO failure");
75094332d3Sopenharmony_ci        goto EXIT;
76094332d3Sopenharmony_ci    }
77094332d3Sopenharmony_ci    uint32_t dataSize = 0;
78094332d3Sopenharmony_ci    if (!HdfSbufReadBuffer(reply, (const void **)(&tmpInfo), &dataSize) || dataSize != sizeof(struct DispInfo)) {
79094332d3Sopenharmony_ci        HDF_LOGE("HdfSbufReadBuffer failure");
80094332d3Sopenharmony_ci        goto EXIT;
81094332d3Sopenharmony_ci    }
82094332d3Sopenharmony_ci    if (memcpy_s(info, sizeof(struct DispInfo), tmpInfo, dataSize) != EOK) {
83094332d3Sopenharmony_ci        HDF_LOGE("memcpy_s failure");
84094332d3Sopenharmony_ci        goto EXIT;
85094332d3Sopenharmony_ci    }
86094332d3Sopenharmony_ci    HDF_LOGI("tmpInfo->width = %u, tmpInfo->height = %u", tmpInfo->width, tmpInfo->height);
87094332d3Sopenharmony_ci    HDF_LOGI("tmpInfo->hbp = %u, tmpInfo->hfp = %u", tmpInfo->hbp, tmpInfo->hfp);
88094332d3Sopenharmony_ci    HDF_LOGI("tmpInfo->frameRate = %u", tmpInfo->frameRate);
89094332d3Sopenharmony_ci    HDF_LOGI("tmpInfo->intfSync = %d", tmpInfo->intfSync);
90094332d3Sopenharmony_ci    HdfSbufRecycle(data);
91094332d3Sopenharmony_ci    HdfSbufRecycle(reply);
92094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
93094332d3Sopenharmony_ci
94094332d3Sopenharmony_ciEXIT:
95094332d3Sopenharmony_ci    HdfSbufRecycle(data);
96094332d3Sopenharmony_ci    HdfSbufRecycle(reply);
97094332d3Sopenharmony_ci    return DISPLAY_FAILURE;
98094332d3Sopenharmony_ci}
99094332d3Sopenharmony_ci
100094332d3Sopenharmony_cistatic int32_t DispGetParaProcess(uint32_t devId, const uint32_t cmd, uint32_t *value)
101094332d3Sopenharmony_ci{
102094332d3Sopenharmony_ci    int32_t ret;
103094332d3Sopenharmony_ci    struct HdfSBuf *data = NULL;
104094332d3Sopenharmony_ci    struct HdfSBuf *reply = NULL;
105094332d3Sopenharmony_ci
106094332d3Sopenharmony_ci    if (value == NULL) {
107094332d3Sopenharmony_ci        HDF_LOGE("%s: invalid param", __func__);
108094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
109094332d3Sopenharmony_ci    }
110094332d3Sopenharmony_ci
111094332d3Sopenharmony_ci    data = HdfSbufObtainDefaultSize();
112094332d3Sopenharmony_ci    if (data == NULL) {
113094332d3Sopenharmony_ci        HDF_LOGE("%s: obtain data sbuf fail", __func__);
114094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
115094332d3Sopenharmony_ci    }
116094332d3Sopenharmony_ci    reply = HdfSbufObtainDefaultSize();
117094332d3Sopenharmony_ci    if (reply == NULL) {
118094332d3Sopenharmony_ci        HDF_LOGE("%s: obtain reply sbuf fail", __func__);
119094332d3Sopenharmony_ci        goto EXIT;
120094332d3Sopenharmony_ci    }
121094332d3Sopenharmony_ci    if (!HdfSbufWriteUint32(data, devId)) {
122094332d3Sopenharmony_ci        HDF_LOGE("HdfSbufWriteUint32 failure");
123094332d3Sopenharmony_ci        goto EXIT;
124094332d3Sopenharmony_ci    }
125094332d3Sopenharmony_ci    ret = DispCmdSend(cmd, data, reply);
126094332d3Sopenharmony_ci    if (ret != DISPLAY_SUCCESS) {
127094332d3Sopenharmony_ci        HDF_LOGE("cmd:DISP_CMD_GET_PANEL_INFO failure");
128094332d3Sopenharmony_ci        goto EXIT;
129094332d3Sopenharmony_ci    }
130094332d3Sopenharmony_ci    if (!HdfSbufReadUint32(reply, value)) {
131094332d3Sopenharmony_ci        HDF_LOGE("HdfSbufReadUint32 failure");
132094332d3Sopenharmony_ci        goto EXIT;
133094332d3Sopenharmony_ci    }
134094332d3Sopenharmony_ci    HdfSbufRecycle(data);
135094332d3Sopenharmony_ci    HdfSbufRecycle(reply);
136094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
137094332d3Sopenharmony_ci
138094332d3Sopenharmony_ciEXIT:
139094332d3Sopenharmony_ci    HdfSbufRecycle(data);
140094332d3Sopenharmony_ci    HdfSbufRecycle(reply);
141094332d3Sopenharmony_ci    return DISPLAY_FAILURE;
142094332d3Sopenharmony_ci}
143094332d3Sopenharmony_ci
144094332d3Sopenharmony_cistatic int32_t DispEventProcess(uint32_t devId, const uint32_t cmd, uint32_t val)
145094332d3Sopenharmony_ci{
146094332d3Sopenharmony_ci    int32_t ret;
147094332d3Sopenharmony_ci
148094332d3Sopenharmony_ci    struct HdfSBuf *data = HdfSbufObtainDefaultSize();
149094332d3Sopenharmony_ci    if (data == NULL) {
150094332d3Sopenharmony_ci        HDF_LOGE("%s: obtain data sbuf fail", __func__);
151094332d3Sopenharmony_ci        return DISPLAY_FAILURE;
152094332d3Sopenharmony_ci    }
153094332d3Sopenharmony_ci    uint32_t para = (devId << OFFSET_TWO_BYTE) | (val & 0xffff);
154094332d3Sopenharmony_ci    if (!HdfSbufWriteUint32(data, para)) {
155094332d3Sopenharmony_ci        HDF_LOGE("HdfSbufWriteUint32 failure\n");
156094332d3Sopenharmony_ci        goto EXIT;
157094332d3Sopenharmony_ci    }
158094332d3Sopenharmony_ci    ret = DispCmdSend(cmd, data, NULL);
159094332d3Sopenharmony_ci    if (ret != DISPLAY_SUCCESS) {
160094332d3Sopenharmony_ci        HDF_LOGE("cmd:DISP_CMD_SET_%s failure\n", (cmd == DISP_CMD_SET_POWERSTATUS) ? "POWERMODE" : "BACKLIGHT");
161094332d3Sopenharmony_ci        goto EXIT;
162094332d3Sopenharmony_ci    }
163094332d3Sopenharmony_ci    HdfSbufRecycle(data);
164094332d3Sopenharmony_ci    return DISPLAY_SUCCESS;
165094332d3Sopenharmony_ci
166094332d3Sopenharmony_ciEXIT:
167094332d3Sopenharmony_ci    HdfSbufRecycle(data);
168094332d3Sopenharmony_ci    return DISPLAY_FAILURE;
169094332d3Sopenharmony_ci}
170094332d3Sopenharmony_ci
171094332d3Sopenharmony_cistatic int32_t SetPowerStatus(uint32_t devId,  DispPowerStatus status)
172094332d3Sopenharmony_ci{
173094332d3Sopenharmony_ci    return DispEventProcess(devId, DISP_CMD_SET_POWERSTATUS, status);
174094332d3Sopenharmony_ci}
175094332d3Sopenharmony_ci
176094332d3Sopenharmony_cistatic int32_t GetPowerStatus(uint32_t devId,  DispPowerStatus *pStatus)
177094332d3Sopenharmony_ci{
178094332d3Sopenharmony_ci    return DispGetParaProcess(devId, DISP_CMD_GET_POWERSTATUS, pStatus);
179094332d3Sopenharmony_ci}
180094332d3Sopenharmony_ci
181094332d3Sopenharmony_cistatic int32_t SetBacklight(uint32_t devId, uint32_t level)
182094332d3Sopenharmony_ci{
183094332d3Sopenharmony_ci    return DispEventProcess(devId, DISP_CMD_SET_BACKLIGHT, level);
184094332d3Sopenharmony_ci}
185094332d3Sopenharmony_ci
186094332d3Sopenharmony_cistatic int32_t GetBacklight(uint32_t devId, uint32_t *level)
187094332d3Sopenharmony_ci{
188094332d3Sopenharmony_ci    return DispGetParaProcess(devId, DISP_CMD_GET_BACKLIGHT, level);
189094332d3Sopenharmony_ci}
190094332d3Sopenharmony_ci
191094332d3Sopenharmony_ciHalFuncs *GetHalFuncs(void)
192094332d3Sopenharmony_ci{
193094332d3Sopenharmony_ci    static HalFuncs *hFuncs = NULL;
194094332d3Sopenharmony_ci
195094332d3Sopenharmony_ci    if (hFuncs == NULL) {
196094332d3Sopenharmony_ci        hFuncs = (HalFuncs *)malloc(sizeof(HalFuncs));
197094332d3Sopenharmony_ci        if (hFuncs == NULL) {
198094332d3Sopenharmony_ci            HDF_LOGE("%s: malloc fail", __func__);
199094332d3Sopenharmony_ci            return NULL;
200094332d3Sopenharmony_ci        }
201094332d3Sopenharmony_ci        (void)memset_s(hFuncs, sizeof(HalFuncs), 0, sizeof(HalFuncs));
202094332d3Sopenharmony_ci        hFuncs->SetPowerStatus = SetPowerStatus;
203094332d3Sopenharmony_ci        hFuncs->GetPowerStatus = GetPowerStatus;
204094332d3Sopenharmony_ci        hFuncs->SetBacklight = SetBacklight;
205094332d3Sopenharmony_ci        hFuncs->GetBacklight = GetBacklight;
206094332d3Sopenharmony_ci        hFuncs->GetInfo = GetInfo;
207094332d3Sopenharmony_ci    }
208094332d3Sopenharmony_ci    return hFuncs;
209094332d3Sopenharmony_ci}
210