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 "gpio_if.h"
11 #include "hdf_device_desc.h"
12 #include "hdf_log.h"
13 #include "mipi_dsi_if.h"
14 #include "osal.h"
15 #include "pwm_if.h"
16 #include "lite_lcdkit.h"
17
GetPanelCfg(void)18 static struct PanelConfig *GetPanelCfg(void)
19 {
20 static struct PanelConfig panelCfg;
21 return &panelCfg;
22 }
23
PowerInit(void)24 static int32_t PowerInit(void)
25 {
26 int32_t ret;
27 int32_t count;
28 int32_t i;
29 struct PanelConfig *panelCfg = GetPanelCfg();
30
31 count = panelCfg->setting.count;
32 for (i = 0; i < count; i++) {
33 if (panelCfg->setting.power[i].type == GPIO_POWER) {
34 ret = GpioSetDir(panelCfg->setting.power[i].num, GPIO_DIR_OUT);
35 if (ret != HDF_SUCCESS) {
36 HDF_LOGE("%s:GpioSetDir failed", __func__);
37 return HDF_FAILURE;
38 }
39 }
40 }
41 return HDF_SUCCESS;
42 }
43
LcdkitInit(void)44 static int32_t LcdkitInit(void)
45 {
46 int32_t ret;
47 struct PanelConfig *panelCfg = GetPanelCfg();
48
49 if (panelCfg->info.intfType != MIPI_DSI) {
50 HDF_LOGE("%s:not support intf: %u", __func__, panelCfg->info.intfType);
51 return HDF_FAILURE;
52 }
53 ret = PowerInit();
54 if (ret != HDF_SUCCESS) {
55 HDF_LOGE("%s:PowerInit failed", __func__);
56 return HDF_FAILURE;
57 }
58
59 panelCfg->dsiHandle = MipiDsiOpen(panelCfg->dsiDev);
60 if (panelCfg->dsiHandle == NULL) {
61 HDF_LOGE("%s:MipiDsiOpen failed", __func__);
62 return HDF_FAILURE;
63 }
64
65 if (panelCfg->info.blk.type == BLK_PWM) {
66 panelCfg->pwmHandle = PwmOpen(panelCfg->info.pwm.dev);
67 if (panelCfg->pwmHandle == NULL) {
68 MipiDsiClose(panelCfg->dsiHandle);
69 panelCfg->dsiHandle = NULL;
70 HDF_LOGE("%s: PwmOpen failed", __func__);
71 return HDF_FAILURE;
72 }
73 }
74 return HDF_SUCCESS;
75 }
76
MipiDsiOn(void)77 static int32_t MipiDsiOn(void)
78 {
79 int32_t ret;
80 struct PanelConfig *panelCfg = GetPanelCfg();
81 int32_t i;
82
83 if (panelCfg->dsiHandle == NULL) {
84 HDF_LOGE("%s:dsiHandle is null", __func__);
85 return HDF_FAILURE;
86 }
87 /* send mipi init code */
88 int32_t count = panelCfg->onCmd.count;
89 for (i = 0; i < count; i++) {
90 ret = MipiDsiTx(panelCfg->dsiHandle, &(panelCfg->onCmd.dsiCmd[i]));
91 if (ret != HDF_SUCCESS) {
92 HDF_LOGE("%s:MipiDsiTx failed", __func__);
93 return ret;
94 }
95 }
96 /* set mipi to hs mode */
97 MipiDsiSetHsMode(panelCfg->dsiHandle);
98 return HDF_SUCCESS;
99 }
100
MipiDsiOff(void)101 static int32_t MipiDsiOff(void)
102 {
103 int32_t ret;
104 struct PanelConfig *panelCfg = GetPanelCfg();
105 int32_t i;
106
107 if (panelCfg->dsiHandle == NULL) {
108 HDF_LOGE("%s:dsiHandle is null", __func__);
109 return HDF_FAILURE;
110 }
111 /* send mipi panel off code */
112 int32_t count = panelCfg->offCmd.count;
113 for (i = 0; i < count; i++) {
114 ret = MipiDsiTx(panelCfg->dsiHandle, &(panelCfg->offCmd.dsiCmd[i]));
115 if (ret != HDF_SUCCESS) {
116 HDF_LOGE("%s:MipiDsiTx failed", __func__);
117 return ret;
118 }
119 }
120 /* set mipi to lp mode */
121 MipiDsiSetLpMode(panelCfg->dsiHandle);
122 return HDF_SUCCESS;
123 }
124
PowerOn(void)125 static int32_t PowerOn(void)
126 {
127 int32_t ret;
128 struct PanelConfig *panelCfg = GetPanelCfg();
129 int32_t i;
130
131 for (i = 0; i < panelCfg->onSeq.count; i++) {
132 if (panelCfg->onSeq.pwCtrl[i].type == GPIO_POWER) {
133 ret = GpioWrite(panelCfg->onSeq.pwCtrl[i].num, panelCfg->onSeq.pwCtrl[i].opt);
134 if (ret != HDF_SUCCESS) {
135 HDF_LOGE("%s:GpioWrite failed", __func__);
136 return HDF_FAILURE;
137 }
138 OsalMSleep(panelCfg->onSeq.pwCtrl[i].delay);
139 }
140 }
141 return HDF_SUCCESS;
142 }
143
PowerOff(void)144 static int32_t PowerOff(void)
145 {
146 int32_t ret;
147 struct PanelConfig *panelCfg = GetPanelCfg();
148 int32_t i;
149
150 for (i = 0; i < panelCfg->offSeq.count; i++) {
151 if (panelCfg->offSeq.pwCtrl[i].type == GPIO_POWER) {
152 ret = GpioWrite(panelCfg->offSeq.pwCtrl[i].num, panelCfg->offSeq.pwCtrl[i].opt);
153 if (ret != HDF_SUCCESS) {
154 HDF_LOGE("%s:GpioWrite failed", __func__);
155 return HDF_FAILURE;
156 }
157 OsalMSleep(panelCfg->offSeq.pwCtrl[i].delay);
158 }
159 }
160 return HDF_SUCCESS;
161 }
162
LcdkitOn(void)163 static int32_t LcdkitOn(void)
164 {
165 int32_t ret;
166
167 ret = PowerOn();
168 if (ret != HDF_SUCCESS) {
169 HDF_LOGE("%s:MipiPowerOn failed", __func__);
170 return HDF_FAILURE;
171 }
172 ret = MipiDsiOn();
173 if (ret != HDF_SUCCESS) {
174 HDF_LOGE("%s:MipiDsiOn failed", __func__);
175 return HDF_FAILURE;
176 }
177 return HDF_SUCCESS;
178 }
179
LcdkitOff(void)180 static int32_t LcdkitOff(void)
181 {
182 int32_t ret;
183
184 ret = MipiDsiOff();
185 if (ret != HDF_SUCCESS) {
186 HDF_LOGE("%s:MipiDsiOff failed", __func__);
187 return HDF_FAILURE;
188 }
189 ret = PowerOff();
190 if (ret != HDF_SUCCESS) {
191 HDF_LOGE("%s:PanelPowerOff failed", __func__);
192 return HDF_FAILURE;
193 }
194 return HDF_SUCCESS;
195 }
196
SetBacklightByPwm(uint32_t level)197 static int32_t SetBacklightByPwm(uint32_t level)
198 {
199 struct PanelConfig *panelCfg = GetPanelCfg();
200 int32_t ret;
201 uint32_t duty;
202
203 if (panelCfg->pwmHandle == NULL) {
204 HDF_LOGE("%s:pwmHandle is null", __func__);
205 return HDF_FAILURE;
206 }
207 duty = (level * panelCfg->info.pwm.period) / panelCfg->info.blk.maxLevel;
208 ret = PwmSetDuty(panelCfg->pwmHandle, duty);
209 if (ret != HDF_SUCCESS) {
210 HDF_LOGE("%s: PwmSetDuty failed", __func__);
211 return HDF_FAILURE;
212 }
213 static uint32_t lastLevel = 0;
214 if (level != 0 && lastLevel == 0) {
215 ret = PwmEnable(panelCfg->pwmHandle);
216 } else if (level == 0 && lastLevel != 0) {
217 ret = PwmDisable(panelCfg->pwmHandle);
218 }
219 lastLevel = level;
220 return ret;
221 }
222
SetBacklightByMipi(uint32_t level)223 static int32_t SetBacklightByMipi(uint32_t level)
224 {
225 int32_t ret;
226 struct PanelConfig *panelCfg = GetPanelCfg();
227 uint8_t payLoad[] = { 0x51, 0x00 }; // panel backlight cmd
228 struct DsiCmdDesc bklCmd = { 0x15, 0, sizeof(payLoad), payLoad }; // dsi backlight cmd
229
230 if (panelCfg->dsiHandle == NULL) {
231 HDF_LOGE("%s: dsiHandle is null", __func__);
232 return HDF_FAILURE;
233 }
234 payLoad[1] = level;
235 ret = MipiDsiTx(panelCfg->dsiHandle, &bklCmd);
236 if (ret != HDF_SUCCESS) {
237 HDF_LOGE("%s: MipiDsiTx failed", __func__);
238 return HDF_FAILURE;
239 }
240 return HDF_SUCCESS;
241 }
242
LcdkitSetBkl(uint32_t level)243 static int32_t LcdkitSetBkl(uint32_t level)
244 {
245 struct PanelConfig *panelCfg = GetPanelCfg();
246 int32_t ret = HDF_SUCCESS;
247 if (panelCfg->info.blk.type == BLK_PWM) {
248 ret = SetBacklightByPwm(level);
249 } else if (panelCfg->info.blk.type == BLK_MIPI) {
250 ret = SetBacklightByMipi(level);
251 } else {
252 HDF_LOGE("%s: not support backlight type:%d", __func__, panelCfg->info.blk.type);
253 return HDF_FAILURE;
254 }
255 return ret;
256 }
257
258 static struct PanelData g_panelData = {
259 .init = LcdkitInit,
260 .on = LcdkitOn,
261 .off = LcdkitOff,
262 .setBacklight = LcdkitSetBkl,
263 };
264
LcdkitEntryInit(struct HdfDeviceObject * object)265 static int32_t LcdkitEntryInit(struct HdfDeviceObject *object)
266 {
267 struct PanelConfig *panelCfg = GetPanelCfg();
268
269 if (object == NULL) {
270 HDF_LOGE("%s: param is null", __func__);
271 return HDF_FAILURE;
272 }
273 if (ParseLcdConfig(object->property, panelCfg)) {
274 HDF_LOGE("%s: ParseLcdConfig failed", __func__);
275 return HDF_FAILURE;
276 }
277 g_panelData.info = &panelCfg->info;
278 if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) {
279 HDF_LOGE("%s: PanelDataRegister failed", __func__);
280 return HDF_FAILURE;
281 }
282 HDF_LOGI("%s: exit succ", __func__);
283 return HDF_SUCCESS;
284 }
285
286 struct HdfDriverEntry g_lcdkitDevEntry = {
287 .moduleVersion = 1,
288 .moduleName = "LITE_LCDKIT",
289 .Init = LcdkitEntryInit,
290 };
291
292 HDF_INIT(g_lcdkitDevEntry);
293