• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 <securec.h>
10 #include "lite_lcdkit.h"
11 #include "hdf_log.h"
12 
13 #define PARSE_PANEL_SYMBOL(node, ops, symbol, out) do { \
14     if ((ops)->GetUint32((node), (symbol), (out), 0)) { \
15         HDF_LOGE("%s: get symbol:%s failed", __func__, (symbol)); \
16         return HDF_FAILURE; \
17     } \
18 } while (0)
19 
GetDsiCmdCount(uint8_t * array,int32_t len,uint32_t * count)20 static int32_t GetDsiCmdCount(uint8_t *array, int32_t len, uint32_t *count)
21 {
22     int32_t cnt = 0;
23     uint8_t dlen;
24 
25     while (len > 0) {
26         dlen = array[DATA_LEN];
27         array = array + DSI_CMD_HEAD + dlen;
28         len = len - (dlen + DSI_CMD_HEAD);
29         cnt++;
30     }
31     if (len != 0) {
32         HDF_LOGE("%s: dsi cmd count error", __func__);
33         return HDF_FAILURE;
34     }
35     *count = cnt;
36     return HDF_SUCCESS;
37 }
38 
ParseDsiCmd(struct PanelCmd * cmd,int32_t count,uint8_t * array,int32_t len)39 static int32_t ParseDsiCmd(struct PanelCmd *cmd, int32_t count, uint8_t *array, int32_t len)
40 {
41     struct DsiCmdDesc *dsiCmd = (struct DsiCmdDesc *)OsalMemCalloc(count * sizeof(struct DsiCmdDesc));
42     if (dsiCmd == NULL) {
43         HDF_LOGE("%s: OsalMemCalloc failed", __func__);
44         OsalMemFree(array);
45         return HDF_FAILURE;
46     }
47     int32_t ret;
48     int32_t i;
49     int32_t num = 0;
50     cmd->count = count;
51     cmd->dsiCmd = dsiCmd;
52     uint8_t *tmpArray = array;
53     struct DsiCmdDesc *tmpCmd = dsiCmd;
54     while (count > 0 && len > 0) {
55         tmpCmd->dataType = tmpArray[DATA_TYPE];
56         tmpCmd->delay = tmpArray[CMD_DELAY];
57         tmpCmd->dataLen = tmpArray[DATA_LEN];
58         tmpCmd->payload = (uint8_t *)OsalMemCalloc(tmpCmd->dataLen * sizeof(uint8_t));
59         if (tmpCmd->payload == NULL) {
60             HDF_LOGE("%s: OsalMemCalloc failed", __func__);
61             for (i = 0; i < num; i++) {
62                 OsalMemFree(dsiCmd[i]->payload);
63             }
64             OsalMemFree(array);
65             OsalMemFree(dsiCmd);
66             cmd->dsiCmd = NULL;
67             cmd->count = 0;
68             return HDF_FAILURE;
69         }
70 
71         ret = memcpy_s(tmpCmd->payload, tmpCmd->dataLen, &tmpArray[DSI_CMD_HEAD], DSI_CMD_HEAD);
72         if (ret != EOK) {
73             HDF_LOGE("%s: memcpy_s failed, ret %d", __func__, ret);
74             for (i = 0; i < num; i++) {
75                 OsalMemFree(dsiCmd[i]->payload);
76             }
77             OsalMemFree(array);
78             OsalMemFree(dsiCmd);
79             cmd->dsiCmd = NULL;
80             cmd->count = 0;
81             return ret;
82         }
83 
84         tmpArray += DSI_CMD_HEAD + tmpCmd->dataLen;
85         tmpCmd++;
86         count--;
87         num++;
88         len -= DSI_CMD_HEAD + tmpCmd->dataLen;
89     }
90     OsalMemFree(array);
91     return HDF_SUCCESS;
92 }
93 
ParseCmdConfig(const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps,const char * name,struct PanelCmd * cmd)94 static int32_t ParseCmdConfig(const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps,
95     const char *name, struct PanelCmd *cmd)
96 {
97     int32_t len = drsOps->GetElemNum(node, name);
98     uint8_t *array = (uint8_t *)OsalMemCalloc(len * sizeof(uint8_t));
99     if (array == NULL) {
100         HDF_LOGE("%s: OsalMemCalloc failed", __func__);
101         return HDF_FAILURE;
102     }
103     if (drsOps->GetUint8Array(node, name, array, len, 0) != HDF_SUCCESS) {
104         HDF_LOGE("%s: GetUint8Array failed", __func__);
105         OsalMemFree(array);
106         return HDF_FAILURE;
107     }
108     uint32_t count = 0;
109     if (GetDsiCmdCount(array, len, &count) != HDF_SUCCESS) {
110         HDF_LOGE("%s: GetDsiCmdCount failed", __func__);
111         OsalMemFree(array);
112         return HDF_FAILURE;
113     }
114     return ParseDsiCmd(cmd, count, array, len);
115 }
116 
ParsePanelInfo(const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps,struct PanelInfo * info)117 static int32_t ParsePanelInfo(const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps,
118     struct PanelInfo *info)
119 {
120     /* panel setting */
121     PARSE_PANEL_SYMBOL(node, drsOps, "width", &info->width);
122     PARSE_PANEL_SYMBOL(node, drsOps, "height", &info->height);
123     PARSE_PANEL_SYMBOL(node, drsOps, "hbp", &info->hbp);
124     PARSE_PANEL_SYMBOL(node, drsOps, "hfp", &info->hfp);
125     PARSE_PANEL_SYMBOL(node, drsOps, "hsw", &info->hsw);
126     PARSE_PANEL_SYMBOL(node, drsOps, "vbp", &info->vbp);
127     PARSE_PANEL_SYMBOL(node, drsOps, "vfp", &info->vfp);
128     PARSE_PANEL_SYMBOL(node, drsOps, "vsw", &info->vsw);
129     PARSE_PANEL_SYMBOL(node, drsOps, "frameRate", &info->frameRate);
130     PARSE_PANEL_SYMBOL(node, drsOps, "intfType", &info->intfType);
131     PARSE_PANEL_SYMBOL(node, drsOps, "intfSync", &info->intfSync);
132     /* mipi setting */
133     PARSE_PANEL_SYMBOL(node, drsOps, "dsiLane", &info->mipi.lane);
134     PARSE_PANEL_SYMBOL(node, drsOps, "mode", &info->mipi.mode);
135     PARSE_PANEL_SYMBOL(node, drsOps, "burstMode", &info->mipi.burstMode);
136     PARSE_PANEL_SYMBOL(node, drsOps, "pixelFmt", &info->mipi.format);
137     /* backlight setting */
138     PARSE_PANEL_SYMBOL(node, drsOps, "blkType", &info->blk.type);
139     PARSE_PANEL_SYMBOL(node, drsOps, "minLevel", &info->blk.minLevel);
140     PARSE_PANEL_SYMBOL(node, drsOps, "maxLevel", &info->blk.maxLevel);
141     PARSE_PANEL_SYMBOL(node, drsOps, "defLevel", &info->blk.defLevel);
142     /* pwm setting */
143     if (info->blk.type == BLK_PWM) {
144         PARSE_PANEL_SYMBOL(node, drsOps, "pwmDev", &info->pwm.dev);
145         PARSE_PANEL_SYMBOL(node, drsOps, "pwmPeriod", &info->pwm.period);
146     }
147     return HDF_SUCCESS;
148 }
149 
ParsePowerSetting(const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps,struct PowerSetting * setting)150 static int32_t ParsePowerSetting(const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps,
151     struct PowerSetting *setting)
152 {
153     int32_t count = drsOps->GetElemNum(node, "powerSetting");
154     if ((count % POWER_SETTING_SIZE) != 0) {
155         HDF_LOGE("%s: count invalid", __func__);
156         return HDF_FAILURE;
157     }
158     uint32_t *array = (uint32_t *)OsalMemCalloc(count * sizeof(uint32_t));
159     if (array == NULL) {
160         HDF_LOGE("%s: OsalMemCalloc failed", __func__);
161         return HDF_FAILURE;
162     }
163     if (drsOps->GetUint32Array(node, "powerSetting", array, count, 0) != HDF_SUCCESS) {
164         HDF_LOGE("%s: GetUint32Array failed", __func__);
165         OsalMemFree(array);
166         return HDF_FAILURE;
167     }
168     uint32_t *tmp = array;
169     setting->power = (struct PowerDesc *)OsalMemCalloc((count / POWER_SETTING_SIZE) * sizeof(struct PowerDesc));
170     if (setting->power == NULL) {
171         HDF_LOGE("%s: OsalMemCalloc failed", __func__);
172         OsalMemFree(array);
173         return HDF_FAILURE;
174     }
175     int32_t i;
176     for (i = 0; i < (count / POWER_SETTING_SIZE); i++) {
177         setting->power[i].type = tmp[i];        // get power type
178         setting->power[i].num = tmp[i + 1];     // 1-get power num
179         setting->power[i].vol = tmp[i + 2];     // 2-get power vol
180         tmp += POWER_SETTING_SIZE;              // next power setting
181     }
182     setting->count = count / POWER_SETTING_SIZE;
183     OsalMemFree(array);
184     return HDF_SUCCESS;
185 }
186 
ParsePowerSequeue(const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps,const char * name,struct PowerSequeue * seq)187 static int32_t ParsePowerSequeue(const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps,
188     const char *name, struct PowerSequeue *seq)
189 {
190     int32_t count = drsOps->GetElemNum(node, name);
191     if ((count % POWER_SEQUEUE_SIZE) != 0) {
192         HDF_LOGE("%s: count invalid", __func__);
193         return HDF_FAILURE;
194     }
195     uint32_t *array = (uint32_t *)OsalMemCalloc(count * sizeof(uint32_t));
196     if (array == NULL) {
197         HDF_LOGE("%s: OsalMemCalloc failed", __func__);
198         return HDF_FAILURE;
199     }
200     if (drsOps->GetUint32Array(node, name, array, count, 0) != HDF_SUCCESS) {
201         HDF_LOGE("%s: GetUint32Array failed", __func__);
202         OsalMemFree(array);
203         return HDF_FAILURE;
204     }
205     uint32_t *tmp = array;
206     seq->pwCtrl = (struct PowerCtrl *)OsalMemCalloc((count / POWER_SEQUEUE_SIZE) * sizeof(struct PowerCtrl));
207     if (seq->pwCtrl == NULL) {
208         HDF_LOGE("%s: OsalMemCalloc failed", __func__);
209         OsalMemFree(array);
210         return HDF_FAILURE;
211     }
212     int32_t i;
213     for (i = 0; i < (count / POWER_SEQUEUE_SIZE); i++) {
214         seq->pwCtrl[i].num = tmp[i];          // get power num
215         seq->pwCtrl[i].opt = tmp[i + 1];      // 1-get power operate
216         seq->pwCtrl[i].delay = tmp[i + 2];    // 2-get power delay
217         tmp += POWER_SEQUEUE_SIZE;                    // next power setting
218     }
219     seq->count = count / POWER_SEQUEUE_SIZE;
220     OsalMemFree(array);
221     return HDF_SUCCESS;
222 }
223 
ParsePanelConfig(const struct DeviceResourceNode * node,struct PanelConfig * cfg)224 static int32_t ParsePanelConfig(const struct DeviceResourceNode *node, struct PanelConfig *cfg)
225 {
226     struct DeviceResourceIface *drsOps = NULL;
227     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
228     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint32Array == NULL ||
229         drsOps->GetElemNum == NULL || drsOps->GetUint8Array == NULL) {
230         HDF_LOGE("%s: invalid drs ops", __func__);
231         return HDF_FAILURE;
232     }
233     if (ParsePanelInfo(node, drsOps, &cfg->info)) {
234         HDF_LOGE("%s: ParsePanelInfo failed", __func__);
235         return HDF_FAILURE;
236     }
237     PARSE_PANEL_SYMBOL(node, drsOps, "dsiDev", &cfg->dsiDev);
238     if (ParsePowerSetting(node, drsOps, &cfg->setting)) {
239         HDF_LOGE("%s: Parse power setting failed", __func__);
240         return HDF_FAILURE;
241     }
242     if (ParseCmdConfig(node, drsOps, "panelOnCmd", &cfg->onCmd)) {
243         HDF_LOGE("%s: Parse panel on command failed", __func__);
244         return HDF_FAILURE;
245     }
246     if (ParseCmdConfig(node, drsOps, "panelOffCmd", &cfg->offCmd)) {
247         HDF_LOGE("%s: Parse panel off command failed", __func__);
248         return HDF_FAILURE;
249     }
250     if (ParsePowerSequeue(node, drsOps, "powerOnSeq", &cfg->onSeq)) {
251         HDF_LOGE("%s: Parse power on seq failed", __func__);
252         return HDF_FAILURE;
253     }
254     if (ParsePowerSequeue(node, drsOps, "powerOffSeq", &cfg->offSeq)) {
255         HDF_LOGE("%s: Parse power off seq failed", __func__);
256         return HDF_FAILURE;
257     }
258     return HDF_SUCCESS;
259 }
260 
ParseLcdConfig(const struct DeviceResourceNode * node,struct PanelConfig * cfg)261 int32_t ParseLcdConfig(const struct DeviceResourceNode *node, struct PanelConfig *cfg)
262 {
263     if (node == NULL || cfg == NULL) {
264         HDF_LOGE("%s: node or cfg is null", __func__);
265         return HDF_FAILURE;
266     }
267     struct DeviceResourceIface *drsOps = NULL;
268     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
269     if (drsOps == NULL || drsOps->GetChildNode == NULL || drsOps->GetString == NULL) {
270         HDF_LOGE("%s: invalid drs ops", __func__);
271         return HDF_FAILURE;
272     }
273     if (drsOps->GetString(node, "active_panel", &cfg->actPanel, NULL) != HDF_SUCCESS) {
274         HDF_LOGE("%s: get active panel failed", __func__);
275         return HDF_FAILURE;
276     }
277     HDF_LOGI("%s: actPanel = %s", __func__, cfg->actPanel);
278     const struct DeviceResourceNode *panelConfigNode = drsOps->GetChildNode(node, cfg->actPanel);
279     if (panelConfigNode == NULL) {
280         HDF_LOGE("%s: panelConfigNode is null", __func__);
281         return HDF_FAILURE;
282     }
283     return ParsePanelConfig(panelConfigNode, cfg);
284 }
285 
286