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