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