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