1 /*
2 * Copyright (c) 2021-2023 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 "mipi_dsi_core.h"
10 #include "hdf_log.h"
11 #include "osal_mem.h"
12 #include "osal_time.h"
13
14 #define HDF_LOG_TAG mipi_dsi_core
15
16 struct MipiDsiHandle {
17 struct MipiDsiCntlr *cntlr;
18 struct OsalMutex lock;
19 void *priv;
20 };
21
22 static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT];
23
MipiDsiRegisterCntlr(struct MipiDsiCntlr * cntlr,struct HdfDeviceObject * device)24 int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
25 {
26 if (cntlr == NULL) {
27 HDF_LOGE("MipiDsiRegisterCntlr: cntlr is null!");
28 return HDF_ERR_INVALID_OBJECT;
29 }
30 if (cntlr->devNo >= MAX_CNTLR_CNT) {
31 HDF_LOGE("MipiDsiRegisterCntlr: cntlr->devNo is error!");
32 return HDF_ERR_INVALID_PARAM;
33 }
34
35 if (device == NULL) {
36 HDF_LOGE("MipiDsiRegisterCntlr: device is null!");
37 return HDF_ERR_INVALID_OBJECT;
38 }
39
40 if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
41 (void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
42 (void)OsalMutexInit(&(cntlr->lock));
43
44 g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;
45 g_mipiDsihandle[cntlr->devNo].priv = NULL;
46 cntlr->device = device;
47 device->service = &(cntlr->service);
48 cntlr->priv = NULL;
49 HDF_LOGI("MipiDsiRegisterCntlr: success!");
50
51 return HDF_SUCCESS;
52 }
53
54 HDF_LOGE("MipiDsiRegisterCntlr: cntlr already exists!");
55 return HDF_FAILURE;
56 }
57
MipiDsiUnregisterCntlr(struct MipiDsiCntlr * cntlr)58 void MipiDsiUnregisterCntlr(struct MipiDsiCntlr *cntlr)
59 {
60 if (cntlr == NULL) {
61 HDF_LOGE("MipiDsiUnregisterCntlr: cntlr is null!");
62 return;
63 }
64
65 (void)OsalMutexDestroy(&(cntlr->lock));
66 (void)OsalMutexDestroy(&(g_mipiDsihandle[cntlr->devNo].lock));
67
68 HDF_LOGI("MipiDsiUnregisterCntlr: success!");
69 return;
70 }
71
MipiDsiCntlrFromDevice(const struct HdfDeviceObject * device)72 struct MipiDsiCntlr *MipiDsiCntlrFromDevice(const struct HdfDeviceObject *device)
73 {
74 return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
75 }
76
MipiDsiCntlrOpen(uint8_t number)77 struct MipiDsiCntlr *MipiDsiCntlrOpen(uint8_t number)
78 {
79 struct MipiDsiCntlr *cntlr = NULL;
80
81 if (number >= MAX_CNTLR_CNT) {
82 HDF_LOGE("MipiDsiCntlrOpen: invalid number!");
83 return NULL;
84 }
85
86 if (g_mipiDsihandle[number].cntlr == NULL) {
87 HDF_LOGE("MipiDsiCntlrOpen: g_mipiDsihandle[number].cntlr is null!");
88 return NULL;
89 }
90
91 (void)OsalMutexLock(&(g_mipiDsihandle[number].lock));
92 g_mipiDsihandle[number].cntlr->devNo = number;
93 cntlr = g_mipiDsihandle[number].cntlr;
94 (void)OsalMutexUnlock(&(g_mipiDsihandle[number].lock));
95
96 return cntlr;
97 }
98
MipiDsiCntlrClose(struct MipiDsiCntlr * cntlr)99 void MipiDsiCntlrClose(struct MipiDsiCntlr *cntlr)
100 {
101 uint8_t number;
102
103 if (cntlr == NULL) {
104 HDF_LOGE("MipiDsiCntlrClose: cntlr is null!");
105 return;
106 }
107
108 number = cntlr->devNo;
109 if (number >= MAX_CNTLR_CNT) {
110 HDF_LOGE("MipiDsiCntlrClose: invalid number!");
111 return;
112 }
113
114 HDF_LOGI("MipiDsiCntlrClose: success!");
115 }
116
MipiDsiCntlrSetCfg(struct MipiDsiCntlr * cntlr,const struct MipiCfg * cfg)117 int32_t MipiDsiCntlrSetCfg(struct MipiDsiCntlr *cntlr, const struct MipiCfg *cfg)
118 {
119 int32_t ret;
120
121 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
122 HDF_LOGE("MipiDsiCntlrSetCfg: cntlr or ops is null!");
123 return HDF_ERR_INVALID_OBJECT;
124 }
125
126 if (cfg == NULL) {
127 HDF_LOGE("MipiDsiCntlrSetCfg: cfg is null!");
128 return HDF_ERR_INVALID_OBJECT;
129 }
130
131 if (cntlr->ops->setCntlrCfg == NULL) {
132 HDF_LOGE("MipiDsiCntlrSetCfg: setCntlrCfg is null!");
133 return HDF_ERR_NOT_SUPPORT;
134 }
135
136 (void)OsalMutexLock(&(cntlr->lock));
137 cntlr->cfg = *cfg;
138 ret = cntlr->ops->setCntlrCfg(cntlr);
139 (void)OsalMutexUnlock(&(cntlr->lock));
140
141 if (ret != HDF_SUCCESS) {
142 HDF_LOGE("MipiDsiCntlrSetCfg: fail!");
143 }
144
145 return ret;
146 }
147
MipiDsiCntlrGetCfg(struct MipiDsiCntlr * cntlr,struct MipiCfg * cfg)148 int32_t MipiDsiCntlrGetCfg(struct MipiDsiCntlr *cntlr, struct MipiCfg *cfg)
149 {
150 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
151 HDF_LOGE("MipiDsiCntlrGetCfg: cntlr or ops is null!");
152 return HDF_ERR_INVALID_OBJECT;
153 }
154 if (cfg == NULL) {
155 HDF_LOGE("MipiDsiCntlrGetCfg: cfg is null!");
156 return HDF_ERR_INVALID_OBJECT;
157 }
158
159 (void)OsalMutexLock(&(cntlr->lock));
160 *cfg = cntlr->cfg;
161 (void)OsalMutexUnlock(&(cntlr->lock));
162
163 return HDF_SUCCESS;
164 }
165
MipiDsiCntlrSetLpMode(struct MipiDsiCntlr * cntlr)166 void MipiDsiCntlrSetLpMode(struct MipiDsiCntlr *cntlr)
167 {
168 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
169 HDF_LOGE("MipiDsiCntlrSetLpMode: cntlr or ops is null!");
170 return;
171 }
172
173 if (cntlr->ops->toLp == NULL) {
174 HDF_LOGE("MipiDsiCntlrSetLpMode: toLp is null!");
175 return;
176 }
177
178 (void)OsalMutexLock(&(cntlr->lock));
179 cntlr->ops->toLp(cntlr);
180 (void)OsalMutexUnlock(&(cntlr->lock));
181 }
182
MipiDsiCntlrSetHsMode(struct MipiDsiCntlr * cntlr)183 void MipiDsiCntlrSetHsMode(struct MipiDsiCntlr *cntlr)
184 {
185 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
186 HDF_LOGE("MipiDsiCntlrSetHsMode: cntlr or ops is null!");
187 return;
188 }
189
190 if (cntlr->ops->toHs == NULL) {
191 HDF_LOGE("MipiDsiCntlrSetHsMode: toHs is null!");
192 return;
193 }
194
195 (void)OsalMutexLock(&(cntlr->lock));
196 cntlr->ops->toHs(cntlr);
197 (void)OsalMutexUnlock(&(cntlr->lock));
198 }
199
MipiDsiCntlrEnterUlps(struct MipiDsiCntlr * cntlr)200 void MipiDsiCntlrEnterUlps(struct MipiDsiCntlr *cntlr)
201 {
202 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
203 HDF_LOGE("MipiDsiCntlrEnterUlps: cntlr or ops is null!");
204 return;
205 }
206
207 if (cntlr->ops->enterUlps == NULL) {
208 HDF_LOGE("MipiDsiCntlrEnterUlps: enterUlps is null!");
209 return;
210 }
211
212 (void)OsalMutexLock(&(cntlr->lock));
213 cntlr->ops->enterUlps(cntlr);
214 (void)OsalMutexUnlock(&(cntlr->lock));
215 }
216
MipiDsiCntlrExitUlps(struct MipiDsiCntlr * cntlr)217 void MipiDsiCntlrExitUlps(struct MipiDsiCntlr *cntlr)
218 {
219 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
220 HDF_LOGE("MipiDsiCntlrExitUlps: cntlr, ops or exitUlps is null!");
221 return;
222 }
223
224 if (cntlr->ops->exitUlps == NULL) {
225 HDF_LOGE("MipiDsiCntlrExitUlps: exitUlps is null!");
226 return;
227 }
228
229 (void)OsalMutexLock(&(cntlr->lock));
230 cntlr->ops->exitUlps(cntlr);
231 (void)OsalMutexUnlock(&(cntlr->lock));
232 }
233
MipiDsiCntlrTx(struct MipiDsiCntlr * cntlr,struct DsiCmdDesc * cmd)234 int32_t MipiDsiCntlrTx(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd)
235 {
236 int32_t ret;
237
238 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
239 HDF_LOGE("MipiDsiCntlrTx: cntlr or ops is null!");
240 return HDF_ERR_INVALID_OBJECT;
241 }
242 if (cmd == NULL) {
243 HDF_LOGE("MipiDsiCntlrTx: cmd is null!");
244 return HDF_ERR_INVALID_OBJECT;
245 }
246
247 if (cntlr->ops->setCmd == NULL) {
248 HDF_LOGE("MipiDsiCntlrTx: setCmd is null!");
249 return HDF_ERR_NOT_SUPPORT;
250 }
251
252 (void)OsalMutexLock(&(cntlr->lock));
253 ret = cntlr->ops->setCmd(cntlr, cmd);
254 if (cmd->delay > 0) {
255 OsalMSleep(cmd->delay);
256 }
257 (void)OsalMutexUnlock(&(cntlr->lock));
258
259 if (ret != HDF_SUCCESS) {
260 HDF_LOGE("MipiDsiCntlrTx: fail!");
261 }
262
263 return ret;
264 }
265
MipiDsiCntlrRx(struct MipiDsiCntlr * cntlr,struct DsiCmdDesc * cmd,int32_t readLen,uint8_t * out)266 int32_t MipiDsiCntlrRx(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, int32_t readLen, uint8_t *out)
267 {
268 int32_t ret;
269
270 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
271 HDF_LOGE("MipiDsiCntlrRx: cntlr or ops is null!");
272 return HDF_ERR_INVALID_OBJECT;
273 }
274 if ((cmd == NULL) || (out == NULL)) {
275 HDF_LOGE("MipiDsiCntlrRx: cmd or out is null!");
276 return HDF_ERR_INVALID_OBJECT;
277 }
278
279 if (cntlr->ops->getCmd == NULL) {
280 HDF_LOGE("MipiDsiCntlrRx: getCmd is null!");
281 return HDF_ERR_NOT_SUPPORT;
282 }
283
284 (void)OsalMutexLock(&(cntlr->lock));
285 ret = cntlr->ops->getCmd(cntlr, cmd, readLen, out);
286 (void)OsalMutexUnlock(&(cntlr->lock));
287
288 if (ret != HDF_SUCCESS) {
289 HDF_LOGE("MipiDsiCntlrRx: fail!");
290 }
291
292 return ret;
293 }
294
MipiDsiCntlrPowerControl(struct MipiDsiCntlr * cntlr,uint8_t enable)295 int32_t MipiDsiCntlrPowerControl(struct MipiDsiCntlr *cntlr, uint8_t enable)
296 {
297 int32_t ret;
298
299 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
300 HDF_LOGE("MipiDsiCntlrPowerControl: cntlr or ops is null!");
301 return HDF_ERR_INVALID_OBJECT;
302 }
303
304 if (cntlr->ops->powerControl == NULL) {
305 HDF_LOGE("MipiDsiCntlrPowerControl: powerControl is null!");
306 return HDF_ERR_NOT_SUPPORT;
307 }
308
309 (void)OsalMutexLock(&(cntlr->lock));
310 ret = cntlr->ops->powerControl(cntlr, enable);
311 (void)OsalMutexUnlock(&(cntlr->lock));
312
313 if (ret != HDF_SUCCESS) {
314 HDF_LOGE("MipiDsiCntlrPowerControl: fail!");
315 }
316
317 return ret;
318 }
319
MipiDsiCntlrAttach(struct MipiDsiCntlr * cntlr,uint8_t * name)320 int32_t MipiDsiCntlrAttach(struct MipiDsiCntlr *cntlr, uint8_t *name)
321 {
322 int32_t ret;
323
324 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
325 HDF_LOGE("MipiDsiCntlrAttach: cntlr or ops is null!");
326 return HDF_ERR_INVALID_OBJECT;
327 }
328
329 if (cntlr->ops->attach == NULL) {
330 HDF_LOGE("MipiDsiCntlrAttach: attach is null!");
331 return HDF_ERR_NOT_SUPPORT;
332 }
333
334 (void)OsalMutexLock(&(cntlr->lock));
335 ret = cntlr->ops->attach(cntlr, name);
336 (void)OsalMutexUnlock(&(cntlr->lock));
337
338 if (ret != HDF_SUCCESS) {
339 HDF_LOGE("MipiDsiCntlrAttach: fail!");
340 }
341
342 return ret;
343 }
344
MipiDsiCntlrSetDrvData(struct MipiDsiCntlr * cntlr,void * panelData)345 int32_t MipiDsiCntlrSetDrvData(struct MipiDsiCntlr *cntlr, void *panelData)
346 {
347 int32_t ret;
348
349 if ((cntlr == NULL) || (cntlr->ops == NULL)) {
350 HDF_LOGE("MipiDsiCntlrSetDrvData: cntlr or ops is null!");
351 return HDF_ERR_INVALID_OBJECT;
352 }
353
354 if (cntlr->ops->setDrvData == NULL) {
355 HDF_LOGE("MipiDsiCntlrSetDrvData: setDrvData is null!");
356 return HDF_ERR_NOT_SUPPORT;
357 }
358
359 (void)OsalMutexLock(&(cntlr->lock));
360 ret = cntlr->ops->setDrvData(cntlr, panelData);
361 (void)OsalMutexUnlock(&(cntlr->lock));
362
363 if (ret != HDF_SUCCESS) {
364 HDF_LOGE("MipiDsiCntlrSetDrvData: fail!");
365 }
366
367 return ret;
368 }
369