• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 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 "hdf_bl.h"
10 #include <securec.h>
11 #include "hdf_base.h"
12 #include "hdf_log.h"
13 #include "osal.h"
14 
15 #define OFFSET_TWO_BYTE       16
16 #define MAX_BL_NAME_LEN       32
17 #define MAX_BL_DEV            32
18 #define NAME_BUFFER_LEN       1220   // 32 * 38
19 #define MAX_DEST_STRING_LEN   38  // MAX_BL_NAME_LEN(32) + 6
20 
21 enum BrightnessType {
22     MIN_BRIGHTNESS,
23     CURRENT_BRIGHTNESS,
24     DEFAULT_BRIGHTNESS,
25     MAX_BRIGHTNESS,
26 };
27 
28 typedef int32_t (*BlCmdHandle)(struct HdfDeviceObject *device,
29     struct HdfSBuf *reqData, struct HdfSBuf *rspData);
30 
31 struct BacklightDev {
32     char name[MAX_BL_NAME_LEN];
33     struct BacklightProperties props;
34     struct BacklightOps *ops;
35     struct OsalMutex mutex;
36     bool isRegister;
37     void *priv;
38 };
39 
40 struct BlDevManager {
41     struct BacklightDev *blDev[MAX_BL_DEV];
42     uint32_t devNum;
43 };
44 
45 static struct BlDevManager g_blDevManager;
46 
GetBlDevManager(void)47 static struct BlDevManager *GetBlDevManager(void)
48 {
49     return &g_blDevManager;
50 }
51 
BlDevInstance(const char * devName,struct BacklightProperties * props,struct BacklightOps * ops)52 static struct BacklightDev *BlDevInstance(const char *devName,
53     struct BacklightProperties *props, struct BacklightOps *ops)
54 {
55     int32_t ret;
56     struct BacklightDev *blDev = NULL;
57 
58     blDev = (struct BacklightDev *)OsalMemCalloc(sizeof(struct BacklightDev));
59     if (blDev == NULL) {
60         HDF_LOGE("%s blDev malloc fail", __func__);
61         return NULL;
62     }
63     blDev->ops = ops;
64     ret = memcpy_s(blDev->name, MAX_BL_NAME_LEN - 1, devName, strlen(devName) + 1);
65     if (ret != 0) {
66         HDF_LOGE("%s blDev->name %s", __func__, blDev->name);
67         goto FAIL;
68     }
69     ret = memcpy_s(&blDev->props, sizeof(struct BacklightProperties),
70         props, sizeof(struct BacklightProperties));
71     if (ret != 0) {
72         HDF_LOGE("%s props memcpy fail", __func__);
73         goto FAIL;
74     }
75     return blDev;
76 FAIL:
77     OsalMemFree(blDev);
78     return NULL;
79 }
80 
RegisterBlDev(const char * name,struct BacklightProperties * props,struct BacklightOps * ops,void * priv)81 struct BacklightDev *RegisterBlDev(const char *name, struct BacklightProperties *props,
82     struct BacklightOps *ops, void *priv)
83 {
84     uint32_t devNum;
85     int32_t i;
86     struct BacklightDev *blDev = NULL;
87     struct BlDevManager *blDevManager = NULL;
88 
89     if ((name == NULL) || (ops == NULL) || (props == NULL)) {
90         HDF_LOGE("%s: name , ops or props is null", __func__);
91         return NULL;
92     }
93     blDevManager = GetBlDevManager();
94     devNum = blDevManager->devNum;
95     if (devNum >= MAX_BL_DEV) {
96         HDF_LOGE("%s: number of backlight device registrations exceeded", __func__);
97         return NULL;
98     }
99     for (i = 0; i < devNum; i++) {
100         if (strcmp(name, blDevManager->blDev[i]->name) == 0) {
101             HDF_LOGE("%s: backlight name should be unique", __func__);
102             return NULL;
103         }
104     }
105     blDev = BlDevInstance(name, props, ops);
106     if (blDev == NULL) {
107         HDF_LOGE("%s: BlDevInstance fail", __func__);
108         return NULL;
109     }
110     blDev->priv = priv;
111     blDevManager->blDev[devNum] = blDev;
112     blDevManager->devNum++;
113     OsalMutexInit(&blDev->mutex);
114     HDF_LOGE("%s: success", __func__);
115     return blDev;
116 }
117 
ToBlDevPriv(struct BacklightDev * blDev)118 void *ToBlDevPriv(struct BacklightDev *blDev)
119 {
120     if (blDev == NULL) {
121         HDF_LOGE("%s blDev is null", __func__);
122         return NULL;
123     }
124     return blDev->priv;
125 }
126 
GetBacklightDev(const char * name)127 struct BacklightDev *GetBacklightDev(const char *name)
128 {
129     struct BlDevManager *blDevManager = NULL;
130     int32_t i;
131 
132     if (name == NULL) {
133         HDF_LOGE("%s name is null", __func__);
134         return NULL;
135     }
136     blDevManager = GetBlDevManager();
137     for (i = 0; i < blDevManager->devNum; i++) {
138         if (strcmp(name, blDevManager->blDev[i]->name) == 0) {
139             return blDevManager->blDev[i];
140         }
141     }
142     return NULL;
143 }
144 
UpdateBacklightState(struct BacklightDev * blDev,enum FbPowerStatus status)145 int32_t UpdateBacklightState(struct BacklightDev *blDev, enum FbPowerStatus status)
146 {
147     if (blDev == NULL) {
148         HDF_LOGE("%s blDev is null", __func__);
149         return HDF_FAILURE;
150     }
151     if ((status < FB_POWER_ON) || (status > FB_POWER_OFF)) {
152         HDF_LOGE("%s the status is illegal", __func__);
153         return HDF_FAILURE;
154     }
155     OsalMutexLock(&blDev->mutex);
156     blDev->props.fbStatus = status;
157     OsalMutexUnlock(&blDev->mutex);
158     return HDF_SUCCESS;
159 }
160 
UpdateBrightness(struct BacklightDev * blDev,uint32_t brightness)161 int32_t UpdateBrightness(struct BacklightDev *blDev, uint32_t brightness)
162 {
163     int32_t ret = HDF_FAILURE;
164 
165     if (blDev == NULL) {
166         HDF_LOGE("%s blDev is null", __func__);
167         return HDF_FAILURE;
168     }
169     if (brightness > blDev->props.maxBrightness) {
170         brightness = blDev->props.maxBrightness;
171     }
172     if (brightness < blDev->props.minBrightness) {
173         brightness = blDev->props.minBrightness;
174     }
175     OsalMutexLock(&blDev->mutex);
176     if (brightness == blDev->props.brightness) {
177         HDF_LOGI("%s brightness does not change", __func__);
178         OsalMutexUnlock(&blDev->mutex);
179         return HDF_SUCCESS;
180     }
181     if ((blDev->props.fbStatus == FB_POWER_STANDBY) ||
182         (blDev->props.fbStatus == FB_POWER_SUSPEND) ||
183         (blDev->props.fbStatus == FB_POWER_OFF)) {
184         brightness = 0;
185     }
186     if (blDev->ops != NULL && blDev->ops->updateBrightness != NULL) {
187         ret = blDev->ops->updateBrightness(blDev, brightness);
188         if (ret == HDF_SUCCESS) {
189             blDev->props.brightness = brightness;
190         } else {
191             HDF_LOGE("%s: fail", __func__);
192         }
193     }
194     OsalMutexUnlock(&blDev->mutex);
195     return ret;
196 }
197 
GetBlDevBrightness(struct BacklightDev * blDev,enum BrightnessType type)198 static uint32_t GetBlDevBrightness(struct BacklightDev *blDev, enum BrightnessType type)
199 {
200     uint32_t brightness;
201 
202     OsalMutexLock(&blDev->mutex);
203     switch (type) {
204         case MIN_BRIGHTNESS:
205             brightness = blDev->props.minBrightness;
206             break;
207         case CURRENT_BRIGHTNESS:
208             if ((blDev->props.fbStatus == FB_POWER_STANDBY) ||
209                 (blDev->props.fbStatus == FB_POWER_SUSPEND) ||
210                 (blDev->props.fbStatus == FB_POWER_OFF)) {
211                 blDev->props.brightness = 0;
212             }
213             if ((blDev->ops != NULL) && (blDev->ops->getBrightness != NULL)) {
214                 brightness = blDev->ops->getBrightness(blDev);
215             } else {
216                 brightness = blDev->props.brightness;
217             }
218             break;
219         case DEFAULT_BRIGHTNESS:
220             brightness = blDev->props.defBrightness;
221             break;
222         case MAX_BRIGHTNESS:
223             brightness = blDev->props.maxBrightness;
224             break;
225     }
226     OsalMutexUnlock(&blDev->mutex);
227     return brightness;
228 }
229 
GetMinBrightness(struct BacklightDev * blDev,uint32_t * brightness)230 int32_t GetMinBrightness(struct BacklightDev *blDev, uint32_t *brightness)
231 {
232     if (blDev == NULL || brightness == NULL) {
233         HDF_LOGE("%s: blDev or brightness is null", __func__);
234         return HDF_FAILURE;
235     }
236     *brightness = GetBlDevBrightness(blDev, MIN_BRIGHTNESS);
237     return HDF_SUCCESS;
238 }
239 
GetCurrBrightness(struct BacklightDev * blDev,uint32_t * brightness)240 int32_t GetCurrBrightness(struct BacklightDev *blDev, uint32_t *brightness)
241 {
242     if (blDev == NULL || brightness == NULL) {
243         HDF_LOGE("%s: blDev or brightness is null", __func__);
244         return HDF_FAILURE;
245     }
246     *brightness = GetBlDevBrightness(blDev, CURRENT_BRIGHTNESS);
247     return HDF_SUCCESS;
248 }
249 
GetDefBrightness(struct BacklightDev * blDev,uint32_t * brightness)250 int32_t GetDefBrightness(struct BacklightDev *blDev, uint32_t *brightness)
251 {
252     if (blDev == NULL || brightness == NULL) {
253         HDF_LOGE("%s: blDev or brightness is null", __func__);
254         return HDF_FAILURE;
255     }
256     *brightness = GetBlDevBrightness(blDev, DEFAULT_BRIGHTNESS);
257     return HDF_SUCCESS;
258 }
259 
GetMaxBrightness(struct BacklightDev * blDev,uint32_t * brightness)260 int32_t GetMaxBrightness(struct BacklightDev *blDev, uint32_t *brightness)
261 {
262     if (blDev == NULL || brightness == NULL) {
263         HDF_LOGE("%s: blDev or brightness is null", __func__);
264         return HDF_FAILURE;
265     }
266     *brightness = GetBlDevBrightness(blDev, MAX_BRIGHTNESS);
267     return HDF_SUCCESS;
268 }
269 
HdfGetBrightness(enum BrightnessType type,struct HdfSBuf * reqData,struct HdfSBuf * rspData)270 static int32_t HdfGetBrightness(enum BrightnessType type,
271     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
272 {
273     uint32_t devId;
274     uint32_t brightness;
275     struct BlDevManager *blDevManager = NULL;
276     struct BacklightDev *blDev = NULL;
277 
278     if (reqData == NULL) {
279         return HDF_ERR_INVALID_PARAM;
280     }
281     if (!HdfSbufReadUint32(reqData, &devId)) {
282         HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__);
283         return HDF_FAILURE;
284     }
285     blDevManager = GetBlDevManager();
286     if (devId >= blDevManager->devNum) {
287         HDF_LOGE("%s: devId is illegal", __func__);
288         return HDF_FAILURE;
289     }
290     blDev = blDevManager->blDev[devId];
291     brightness = GetBlDevBrightness(blDev, type);
292     if (!HdfSbufWriteUint32(rspData, brightness)) {
293         HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
294         return HDF_FAILURE;
295     }
296     return HDF_SUCCESS;
297 }
298 
HdfGetMinBrightness(struct HdfDeviceObject * device,struct HdfSBuf * reqData,struct HdfSBuf * rspData)299 static int32_t HdfGetMinBrightness(struct HdfDeviceObject *device,
300     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
301 {
302     (void)device;
303     return HdfGetBrightness(MIN_BRIGHTNESS, reqData, rspData);
304 }
305 
HdfGetCurrBrightness(struct HdfDeviceObject * device,struct HdfSBuf * reqData,struct HdfSBuf * rspData)306 static int32_t HdfGetCurrBrightness(struct HdfDeviceObject *device,
307     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
308 {
309     (void)device;
310     return HdfGetBrightness(CURRENT_BRIGHTNESS, reqData, rspData);
311 }
312 
HdfGetDefBrightness(struct HdfDeviceObject * device,struct HdfSBuf * reqData,struct HdfSBuf * rspData)313 static int32_t HdfGetDefBrightness(struct HdfDeviceObject *device,
314     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
315 {
316     (void)device;
317     return HdfGetBrightness(DEFAULT_BRIGHTNESS, reqData, rspData);
318 }
319 
HdfGetMaxBrightness(struct HdfDeviceObject * device,struct HdfSBuf * reqData,struct HdfSBuf * rspData)320 static int32_t HdfGetMaxBrightness(struct HdfDeviceObject *device,
321     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
322 {
323     (void)device;
324     return HdfGetBrightness(MAX_BRIGHTNESS, reqData, rspData);
325 }
326 
HdfSetBrightness(struct HdfDeviceObject * device,struct HdfSBuf * reqData,struct HdfSBuf * rspData)327 static int32_t HdfSetBrightness(struct HdfDeviceObject *device,
328     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
329 {
330     struct BlDevManager *blDevManager = NULL;
331     struct BacklightDev *blDev = NULL;
332 
333     (void)device;
334     (void)rspData;
335     if (reqData == NULL) {
336         return HDF_ERR_INVALID_PARAM;
337     }
338     uint32_t para = 0;
339     if (!HdfSbufReadUint32(reqData, &para)) {
340         HDF_LOGE("%s: HdfSbufReadBuffer failed", __func__);
341         return HDF_FAILURE;
342     }
343     uint32_t devId = (para >> OFFSET_TWO_BYTE) & 0xffff;
344     uint32_t level = para & 0xffff;
345     blDevManager = GetBlDevManager();
346     if (devId >= blDevManager->devNum) {
347         HDF_LOGE("%s: devId is illegal", __func__);
348         return HDF_FAILURE;
349     }
350     blDev = blDevManager->blDev[devId];
351     return UpdateBrightness(blDev, level);
352 }
353 
HdfGetBlDevList(struct HdfDeviceObject * device,struct HdfSBuf * reqData,struct HdfSBuf * rspData)354 static int32_t HdfGetBlDevList(struct HdfDeviceObject *device,
355     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
356 {
357     (void)device;
358     (void)reqData;
359     int32_t ret;
360     int32_t i;
361     char *devName = NULL;
362     char *tmp = NULL;
363     char buffer[NAME_BUFFER_LEN] = {0};
364     struct BlDevManager *blDevManager = NULL;
365 
366     blDevManager = GetBlDevManager();
367     tmp = buffer;
368     for (i = 0; i < blDevManager->devNum; i++) {
369         devName = blDevManager->blDev[i]->name;
370         if ((tmp + MAX_DEST_STRING_LEN) > &buffer[NAME_BUFFER_LEN]) {
371             HDF_LOGE("%s: Memory out of bounds", __func__);
372             break;
373         }
374         // strlen("%d : \n") = 6
375         ret = snprintf_s(tmp, MAX_DEST_STRING_LEN, strlen(devName) + 6, "%d : %s\n", i, devName);
376         if (ret < 0) {
377             HDF_LOGE("%s: snprintf_s fail", __func__);
378             return HDF_FAILURE;
379         }
380         tmp = tmp + strlen(tmp) + 1;
381     }
382     if (!HdfSbufWriteBuffer(rspData, buffer, strlen(buffer) + 1) != 0) {
383         HDF_LOGE("%s: copy info failed", __func__);
384         return HDF_FAILURE;
385     }
386     return HDF_SUCCESS;
387 }
388 
389 static BlCmdHandle g_blDevCmdHandle[] = {
390     HdfGetMinBrightness,
391     HdfGetCurrBrightness,
392     HdfGetDefBrightness,
393     HdfGetMaxBrightness,
394     HdfGetBlDevList,
395     HdfSetBrightness,
396 };
397 
BacklightDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)398 static int32_t BacklightDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data,
399     struct HdfSBuf *reply)
400 {
401     BlCmdHandle blCmdHandle = NULL;
402 
403     if (client == NULL) {
404         return HDF_ERR_INVALID_PARAM;
405     }
406     if ((cmd < 0) || (cmd >= sizeof(g_blDevCmdHandle) / sizeof(BlCmdHandle))) {
407         HDF_LOGE("%s: cmd is illegal", __func__);
408         return HDF_FAILURE;
409     }
410     blCmdHandle = g_blDevCmdHandle[cmd];
411     return blCmdHandle(client->device, data, reply);
412 }
413 
BacklightBind(struct HdfDeviceObject * dev)414 static int BacklightBind(struct HdfDeviceObject *dev)
415 {
416     if (dev == NULL) {
417         return HDF_FAILURE;
418     }
419     static struct IDeviceIoService blService = {
420         .Dispatch = BacklightDispatch,
421     };
422     dev->service = &blService;
423     return HDF_SUCCESS;
424 }
425 
BacklightInit(struct HdfDeviceObject * object)426 static int32_t BacklightInit(struct HdfDeviceObject *object)
427 {
428     if (object == NULL) {
429         HDF_LOGE("%s: object is null!", __func__);
430         return HDF_FAILURE;
431     }
432     HDF_LOGI("%s success", __func__);
433     return HDF_SUCCESS;
434 }
435 
436 struct HdfDriverEntry g_blDevEntry = {
437     .moduleVersion = 1,
438     .moduleName = "HDF_BL",
439     .Init = BacklightInit,
440     .Bind = BacklightBind,
441 };
442 
443 HDF_INIT(g_blDevEntry);
444