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