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