display: add getter/setter function for white balance
[platform/core/system/deviced.git] / plugins / mobile / display / device-interface.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdbool.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <limits.h>
29 #include <math.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <dlfcn.h>
33 #include <hal/device/hal-display.h>
34
35 #include "ambient-mode.h"
36 #include "core/log.h"
37 #include "shared/devices.h"
38 #include "shared/common.h"
39 #include "shared/device-notifier.h"
40 #include "util.h"
41 #include "device-interface.h"
42 #include "vconf.h"
43 #include "core.h"
44 #include "display/display-dpms.h"
45 #include "display/display.h"
46 #include "display/display-lock.h"
47 #include "power/power-boot.h"
48 #include "power/power-suspend.h"
49
50 #define TOUCH_ON        1
51 #define TOUCH_OFF       0
52
53 #define LCD_PHASED_MIN_BRIGHTNESS       1
54 #define LCD_PHASED_MAX_BRIGHTNESS       100
55 #define LCD_PHASED_CHANGE_STEP          5
56 #define LCD_PHASED_DELAY                10000   /* microsecond */
57 #define DUMP_MODE_WAITING_TIME          600000  /* milisecond */
58
59 #define MAX_WHITE_BALANCE_GAIN                  2047
60 #define MAX_WHITE_BALANCE_OFFSET                2047
61 #define DEFAULT_WHITE_BALANCE_GAIN              1024
62 #define DEFAULT_WHITE_BALANCE_OFFSET            0
63
64 #define DISPLAY_HAL_LIB_PATH "/usr/lib/libdisplay-hal.so"
65
66 #define GESTURE_STR                     "gesture"
67 #define POWERKEY_STR                    "powerkey"
68 #define EVENT_STR                       "event"
69 #define TOUCH_STR                       "touch"
70 #define TIMEOUT_STR                     "timeout"
71 #define PROXIMITY_STR                   "proximity"
72 #define PALM_STR                        "palm"
73 #define UNKNOWN_STR                     "unknown"
74
75 static struct _backlight_ops backlight_ops;
76 static struct _display_white_balance_ops display_white_balance_ops;
77 static bool custom_status;
78 static int custom_brightness;
79 static int force_brightness;
80 static int default_brightness;
81 static int dpms_running_state = DPMS_SETTING_DONE;
82 static bool display_dev_available = false;
83 static guint release_timer;
84 static struct display_config *display_conf;
85
86 inline struct _backlight_ops *get_var_backlight_ops(void)
87 {
88         return &backlight_ops;
89 }
90
91 inline struct _display_white_balance_ops *get_var_display_white_balance_ops(void)
92 {
93         return &display_white_balance_ops;
94 }
95
96 bool display_dev_ready(void)
97 {
98         return display_dev_available;
99 }
100
101 void dpms_set_running_state(int val)
102 {
103         dpms_running_state = val;
104 }
105
106 static int bl_onoff(int on, enum device_flags flags)
107 {
108         dpms_set_state(on);
109
110 #ifdef ENABLE_PM_LOG
111         if (on == DPMS_ON)
112                 pm_history_save(PM_LOG_LCD_ON_COMPLETE, get_pm_cur_state());
113         else if (on == DPMS_OFF || on == DPMS_FORCE_OFF)
114                 pm_history_save(PM_LOG_LCD_OFF_COMPLETE, get_pm_cur_state());
115         else
116                 pm_history_save(PM_LOG_LCD_CONTROL_FAIL, on);
117 #endif
118
119         return 0;
120 }
121
122 static int bl_brt(int brightness, int delay)
123 {
124         int ret = -1;
125
126         if (delay > 0)
127                 usleep(delay);
128
129         /* Update device brightness */
130         ret = backlight_ops.set_brightness(brightness);
131
132         _I("Set brightness(%d): %d", brightness, ret);
133
134         return ret;
135 }
136
137 static int get_lcd_power_node(void)
138 {
139         int ret;
140         enum display_state val;
141
142         ret = hal_device_display_get_state(&val);
143         if (ret < 0)
144                 return ret;
145
146         if (val == DISPLAY_ON && ambient_get_state())
147                 return DPMS_OFF;
148
149         if (dpms_running_state != DPMS_SETTING_DONE)
150                 return dpms_running_state;
151
152         switch (val) {
153                 case DISPLAY_ON:
154                         return DPMS_ON;
155                 case DISPLAY_STANDBY:
156                         return DPMS_STANDBY;
157                 case DISPLAY_SUSPEND:
158                         return DPMS_SUSPEND;
159                 case DISPLAY_OFF:
160                         return DPMS_OFF;
161                 default:
162                         return -EINVAL;
163         }
164 }
165
166 bool display_dimstay_check(void)
167 {
168         if (get_pm_status_flag() & DIM_FLAG)
169                 return true;
170
171         if ((get_pm_status_flag() & PWRSV_FLAG) && !(get_pm_status_flag() & BRTCH_FLAG))
172                 return true;
173
174         return false;
175 }
176
177 static void change_brightness(int start, int end, int step)
178 {
179         int diff, val;
180         int ret = -1;
181         int prev;
182
183         if (display_dimstay_check())
184                 return;
185
186         ret = backlight_ops.get_brightness(&prev);
187         if (ret < 0) {
188                 _E("Failed to get brightness: %d", ret);
189                 return;
190         }
191
192         if (prev == end)
193                 return;
194
195         if (get_pm_status_flag() & DIM_MASK)
196                 end = 0;
197
198         _I("start %d end %d step %d", start, end, step);
199
200         if (display_dev_available) {
201                 ret = hal_device_display_set_multi_brightness(end, step, LCD_PHASED_DELAY);
202                 if (ret != -ENODEV) {
203                         if (ret < 0)
204                                 _E("Failed to set_multi_brightness (%d)", ret);
205
206                         backlight_ops.set_brightness(end);
207
208                         return;
209                 }
210         }
211
212         diff = end - start;
213
214         if (abs(diff) < step)
215                 val = (diff > 0 ? 1 : -1);
216         else
217                 val = (int)ceil((double)diff / step);
218
219         while (start != end) {
220                 if (val == 0) break;
221
222                 start += val;
223                 if ((val > 0 && start > end) ||
224                     (val < 0 && start < end))
225                         start = end;
226
227                 bl_brt(start, LCD_PHASED_DELAY);
228         }
229 }
230
231 static int backlight_on(enum device_flags flags)
232 {
233         int ret = -1;
234         static int cnt;
235
236         _I("[DPMS XLIB Backlight] LCD on %#x cnt:%d", flags, cnt);
237
238         cnt++;
239         ret = bl_onoff(DPMS_ON, flags);
240 #ifdef ENABLE_PM_LOG
241         pm_history_save(PM_LOG_LCD_ON, get_pm_cur_state());
242 #endif
243
244         return ret;
245 }
246
247 static int backlight_off(enum device_flags flags)
248 {
249         int ret = -1;
250         static int cnt, ambient_cnt;
251
252         if (flags & AMBIENT_MODE) {
253                 _I("[DPMS XLIB Backlight] LCD suspend %#x cnt:%d", flags, ambient_cnt);
254                 ambient_cnt++;
255
256                 return 0;
257         }
258
259         _I("[DPMS XLIB Backlight] LCD off %#x cnt:%d", flags, cnt);
260         cnt++;
261
262         if (flags & LCD_PHASED_TRANSIT_MODE)
263                 backlight_ops.transit_brt(default_brightness,
264                     LCD_PHASED_MIN_BRIGHTNESS, LCD_PHASED_CHANGE_STEP);
265
266         if (flags & FORCE_OFF_MODE)
267                 ret = bl_onoff(DPMS_FORCE_OFF, flags);
268         else
269                 ret = bl_onoff(DPMS_OFF, flags);
270
271 #ifdef ENABLE_PM_LOG
272         pm_history_save(PM_LOG_LCD_OFF, get_pm_cur_state());
273 #endif
274
275         return ret;
276 }
277
278 static int backlight_dim(void)
279 {
280         int ret;
281
282         ret = backlight_ops.set_brightness(PM_DIM_BRIGHTNESS);
283 #ifdef ENABLE_PM_LOG
284         if (!ret)
285                 pm_history_save(PM_LOG_LCD_DIM, get_pm_cur_state());
286         else
287                 pm_history_save(PM_LOG_LCD_DIM_FAIL, get_pm_cur_state());
288 #endif
289         return ret;
290 }
291
292 static int set_custom_status(bool on)
293 {
294         custom_status = on;
295         return 0;
296 }
297
298 static bool get_custom_status(void)
299 {
300         return custom_status;
301 }
302
303 static int save_custom_brightness(void)
304 {
305         int ret, brightness;
306
307         ret = backlight_ops.get_brightness(&brightness);
308
309         custom_brightness = brightness;
310
311         return ret;
312 }
313
314 static int custom_backlight_update(void)
315 {
316         int ret = 0;
317
318         if (custom_brightness < PM_MIN_BRIGHTNESS ||
319             custom_brightness > PM_MAX_BRIGHTNESS)
320                 return -EINVAL;
321
322         if (display_dimstay_check())
323                 ret = backlight_dim();
324         else {
325                 _I("custom brightness restored! %d", custom_brightness);
326                 ret = backlight_ops.set_brightness(custom_brightness);
327         }
328
329         return ret;
330 }
331
332 static int set_force_brightness(int level)
333 {
334         if (level < 0 ||  level > PM_MAX_BRIGHTNESS)
335                 return -EINVAL;
336
337         force_brightness = level;
338
339         return 0;
340 }
341
342 static int backlight_update(void)
343 {
344         int ret = 0;
345         int brt;
346
347         if (get_custom_status()) {
348                 _I("custom brightness mode! brt no updated");
349                 return 0;
350         }
351         if (display_dimstay_check())
352                 ret = backlight_dim();
353         else {
354                 brt = backlight_ops.get_default_brt();
355                 ret = backlight_ops.set_brightness(brt);
356         }
357         return ret;
358 }
359
360 static int backlight_standby(int force)
361 {
362         int ret = -1;
363
364         if ((dpms_get_cached_state() == DPMS_ON) || force) {
365                 _I("LCD standby");
366                 ret = bl_onoff(DPMS_STANDBY, 0);
367         }
368
369         return ret;
370 }
371
372 static int set_default_brt(int level)
373 {
374         if (level < PM_MIN_BRIGHTNESS || level > PM_MAX_BRIGHTNESS)
375                 level = display_conf->pm_default_brightness;
376
377         default_brightness = level;
378
379         return 0;
380 }
381
382 static int get_default_brt(void)
383 {
384         return default_brightness;
385 }
386
387 static int get_max_brightness(void)
388 {
389         static int max = -1;
390         int ret;
391
392         if (max > 0)
393                 return max;
394
395         if (!display_dev_available) {
396                 _E("There is no HAL for display.");
397                 return -ENOENT;
398         }
399
400         ret = hal_device_display_get_max_brightness(&max);
401         if (ret < 0) {
402                 if (ret == -ENODEV) {
403                         _E("Get max brightness is not supported.");
404                         max = DEFAULT_DISPLAY_MAX_BRIGHTNESS;
405                         return max;
406                 } else {
407                         _E("Failed to get max brightness: %d", ret);
408                         return ret;
409                 }
410         }
411
412         return max;
413 }
414
415 static int set_brightness(int val)
416 {
417         int max;
418
419         if (!display_dev_available) {
420                 _E("There is no display device.");
421                 return -ENOENT;
422         }
423
424         max = get_max_brightness();
425         if (max < 0) {
426                 _E("Failed to get max brightness.");
427                 return max;
428         }
429
430         if (force_brightness > 0 && val != PM_DIM_BRIGHTNESS) {
431                 _I("brightness(%d), force brightness(%d)",
432                     val, force_brightness);
433                 val = force_brightness;
434         }
435
436         if (get_pm_status_flag() & DIM_MASK)
437                 val = 0;
438
439         /* Maximum Brightness to users is 100.
440          * Thus real brightness need to be calculated */
441         val = val * max / 100;
442
443         _I("set brightness %d (default:%d)", val, default_brightness);
444         device_notify(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, (void *)&val);
445
446         return hal_device_display_set_brightness(val);
447 }
448
449 static int get_brt_normalized(int brt_raw)
450 {
451         int quotient, remainder;
452         int max;
453
454         max = get_max_brightness();
455         if (max < 0) {
456                 _E("Failed to get max brightness.");
457                 return max;
458         }
459
460         /* Maximum Brightness to users is 100.
461          * Thus the brightness value need to be calculated using real brightness.
462          *    ex) Let's suppose that the maximum brightness of driver is 255.
463          *      case 1) When the user sets the brightness to 41,
464          *              real brightness is
465          *                 41 * 255 / 100 = 104.55 = 104 (rounded off)
466          *      case 2) When the user gets the brightness,
467          *              the driver returns the brightness 104.
468          *              Thus the brightness to users is
469          *                 104 * 100 / 255 = 40.7843.... = 41 (rounded up)
470          */
471         quotient = brt_raw * 100 / max;
472         remainder = brt_raw * 100 % max;
473         if (remainder > 0)
474                 quotient++;
475
476         return quotient;
477 }
478
479 static int get_brightness(int *val)
480 {
481         int brt, ret;
482
483         if (!display_dev_available) {
484                 _E("There is no display device.");
485                 return -ENOENT;
486         }
487
488         ret = hal_device_display_get_brightness(&brt);
489         if (ret < 0) {
490                 if (ret == -ENODEV)
491                         _E("Get brightness is not supported.");
492                 else
493                         _E("Failed to get brightness: %d", ret);
494
495                 return ret;
496         }
497
498         *val = get_brt_normalized(brt);
499         return 0;
500 }
501
502 static int get_brightness_by_light_sensor(float lmax, float lmin, float light, int *brt)
503 {
504         int brt_raw;
505         int ret;
506
507         if (!display_dev_available)
508                 return -ENOTSUP;
509
510         ret = hal_device_display_get_auto_brightness(lmax, lmin, light, &brt_raw);
511         if (ret < 0) {
512                 if (ret == -ENODEV)
513                         _E("Get auto brightness is not supported.");
514                 else
515                         _E("Failed to get brightness by light sensor: %d", ret);
516
517                 return ret;
518         }
519
520         *brt = get_brt_normalized(brt_raw);
521         return 0;
522 }
523
524 static int get_image_effect(enum display_image_effect *effect)
525 {
526         int ret;
527         enum display_image_effect val;
528
529         if (!display_dev_available) {
530                 _E("There is no display device.");
531                 return -ENOENT;
532         }
533
534         ret = hal_device_display_get_image_effect(&val);
535         if (ret < 0) {
536                 if (ret == -ENODEV)
537                         _E("Get image effect is not supported.");
538                 else
539                         _E("Failed to get image effect: %d", ret);
540
541                 return ret;
542         }
543
544         *effect = val;
545
546         return 0;
547 }
548
549 static int set_image_effect(enum display_image_effect effect)
550 {
551         int ret;
552
553         if (!display_dev_available) {
554                 _E("There is no display device.");
555                 return -ENOENT;
556         }
557
558         ret = hal_device_display_set_image_effect(effect);
559         if (ret < 0) {
560                 if (ret == -ENODEV)
561                         _E("Set image effect is not supported.");
562                 else
563                         _E("Failed to set image effect: %d", ret);
564
565                 return ret;
566         }
567
568         return 0;
569 }
570
571 static int get_panel_mode(enum display_panel_mode *mode)
572 {
573         int ret;
574         enum display_panel_mode val;
575
576         if (!display_dev_available) {
577                 _E("There is no display device.");
578                 return -ENOENT;
579         }
580
581         ret = hal_device_display_get_panel_mode(&val);
582         if (ret < 0) {
583                 if (ret == -ENODEV)
584                         _E("Get panel mode is not supported.");
585                 else
586                         _E("Failed to get panel mode(%d)", ret);
587
588                 return ret;
589         }
590
591         *mode = val;
592
593         return 0;
594 }
595
596 static int set_panel_mode(enum display_panel_mode mode)
597 {
598         int ret;
599
600         if (!display_dev_available) {
601                 _E("There is no display device.");
602                 return -ENOENT;
603         }
604
605         ret = hal_device_display_set_panel_mode(mode);
606         if (ret < 0) {
607                 if (ret == -ENODEV)
608                         _E("Set panel mode is not supported.");
609                 else
610                         _E("Failed to set panel mode(%d)", ret);
611
612                 return ret;
613         }
614
615         return 0;
616 }
617
618 static int get_frame_rate(int *rate)
619 {
620         if (!rate)
621                 return -EINVAL;
622
623         if (!display_dev_available)
624                 return -ENOTSUP;
625
626         return hal_device_display_get_frame_rate(rate);
627 }
628
629 static int set_frame_rate(int rate)
630 {
631         int ret = 0;
632         static int fmin = -1, fmax = -1;
633
634         if (!display_dev_available)
635                 return -ENOTSUP;
636
637         if (fmin < 0) {
638                 ret = hal_device_display_get_min_frame_rate(&fmin);
639                 if (ret < 0) {
640                         _E("Failed to get min frate rate: %d", ret);
641                         return ret;
642                 }
643         }
644         if ((ret != -ENODEV) && (rate < fmin)) {
645                 _E("Invalid rate(%d). (Valid rate: %d <= rate)", rate, fmin);
646                 return -EINVAL;
647         }
648
649         if (fmax < 0) {
650                 ret = hal_device_display_get_max_frame_rate(&fmax);
651                 if (ret < 0) {
652                         _E("Failed to get max frate rate: %d", ret);
653                         return ret;
654                 }
655         }
656         if ((ret != -ENODEV) && (rate > fmax)) {
657                 _E("Invalid rate(%d). (Valid rate: rate <= %d)", rate, fmax);
658                 return -EINVAL;
659         }
660
661         return hal_device_display_set_frame_rate(rate);
662 }
663
664 /* It was operated only AOD enter & leave */
665 static int backlight_transit_state(int state)
666 {
667         int brt, val;
668         int start, end;
669
670         backlight_ops.get_brightness(&brt);
671
672         if (state == DPMS_OFF) {
673                 start = brt;
674                 end = display_conf->aod_enter_level;
675
676                 /*
677                  * The value of backlight_ops.get_brightness is system brightness.
678                  * But when device is LBM, the value is not same with real brightness.
679                  * So it should be read exactly value for transit smooth effect
680                  */
681                 get_brightness(&val);
682
683                 if (val > display_conf->aod_enter_level)
684                         backlight_ops.transit_brt(start, end, display_conf->brightness_change_step);
685         } else {
686                 /* prevent transit effect when another effect is already executed */
687                 if (brt != display_conf->aod_enter_level) {
688                         _W("effect is already executed brt(%d) aod_level(%d)",
689                                         brt, display_conf->aod_enter_level);
690                         return 0;
691                 }
692
693                 start = display_conf->aod_enter_level;
694                 end = default_brightness;
695                 backlight_ops.transit_brt(start, end, display_conf->brightness_change_step);
696         }
697
698         return 0;
699 }
700
701 static gboolean blink_cb(gpointer data)
702 {
703         static bool flag;
704
705         set_brightness(flag ? PM_MAX_BRIGHTNESS : PM_MIN_BRIGHTNESS);
706
707         flag = !flag;
708
709         return G_SOURCE_CONTINUE;
710 }
711
712 static void blink(int timeout)
713 {
714         static guint timer;
715
716         if (timer) {
717                 g_source_remove(timer);
718                 timer = 0;
719         }
720
721         if (timeout < 0) {
722                 _E("timeout value is invalid %d", timeout);
723                 return;
724         }
725
726         if (timeout == 0) {
727                 backlight_update();
728                 return;
729         }
730
731         timer = g_timeout_add(timeout, blink_cb, NULL);
732 }
733
734 static gboolean release_blink_cb(gpointer data)
735 {
736         blink(0);
737
738         release_timer = 0;
739         return G_SOURCE_REMOVE;
740 }
741
742 static void release_blink(void)
743 {
744         if (release_timer) {
745                 g_source_remove(release_timer);
746                 release_timer = 0;
747         }
748
749         release_timer = g_timeout_add(DUMP_MODE_WAITING_TIME, release_blink_cb, NULL);
750 }
751
752 static int set_white_balance(enum hal_display_white_balance white_balance_type, int value)
753 {
754         int ret = 0;
755
756         if (!display_dev_available) {
757                 _E("There is no display device.");
758                 return -ENOENT;
759         }
760
761         switch (white_balance_type) {
762         case HAL_DISPLAY_WHITE_BALANCE_R_GAIN:
763         case HAL_DISPLAY_WHITE_BALANCE_G_GAIN:
764         case HAL_DISPLAY_WHITE_BALANCE_B_GAIN:
765                 if (value > MAX_WHITE_BALANCE_GAIN)
766                         value = DEFAULT_WHITE_BALANCE_GAIN;
767                 break;
768         case HAL_DISPLAY_WHITE_BALANCE_R_OFFSET:
769         case HAL_DISPLAY_WHITE_BALANCE_G_OFFSET:
770         case HAL_DISPLAY_WHITE_BALANCE_B_OFFSET:
771                 if (value > MAX_WHITE_BALANCE_OFFSET)
772                         value = DEFAULT_WHITE_BALANCE_OFFSET;
773                 break;
774         default:
775                 _E("Unknown white balance type");
776                 return -EINVAL;
777         }
778
779         ret = hal_device_display_set_white_balance(white_balance_type, value);
780         if (ret < 0) {
781                 if (ret == -ENODEV)
782                         _E("Set white balance is not supported.");
783                 else
784                         _E("Failed to set white balance value.");
785         }
786
787         return ret;
788 }
789
790 static int get_white_balance(enum hal_display_white_balance white_balance_type, int* value)
791 {
792         int ret = 0;
793
794         if (!display_dev_available) {
795                 _E("There is no display device.");
796                 return -ENOENT;
797         }
798
799         switch (white_balance_type) {
800         case HAL_DISPLAY_WHITE_BALANCE_R_GAIN:
801         case HAL_DISPLAY_WHITE_BALANCE_G_GAIN:
802         case HAL_DISPLAY_WHITE_BALANCE_B_GAIN:
803         case HAL_DISPLAY_WHITE_BALANCE_R_OFFSET:
804         case HAL_DISPLAY_WHITE_BALANCE_G_OFFSET:
805         case HAL_DISPLAY_WHITE_BALANCE_B_OFFSET:
806                 break;
807         default:
808                 _E("Unknown white balance type");
809                 return -EINVAL;
810         }
811
812         ret = hal_device_display_get_white_balance(white_balance_type, value);
813         if (ret < 0) {
814                 if (ret == -ENODEV)
815                         _E("Get white balance is not supported.");
816                 else
817                         _E("Failed to get white balance value.");
818         }
819
820         return ret;
821 }
822
823 static void restore_brightness_func(void)
824 {
825         backlight_ops.set_brightness = set_brightness;
826         backlight_ops.get_brightness = get_brightness;
827         backlight_ops.transit_brt = change_brightness;
828 }
829
830 static struct _backlight_ops backlight_ops = {
831         .off = backlight_off,
832         .dim = backlight_dim,
833         .on = backlight_on,
834         .update = backlight_update,
835         .standby = backlight_standby,
836         .set_default_brt = set_default_brt,
837         .get_default_brt = get_default_brt,
838         .get_lcd_power = dpms_get_cached_state,
839         .get_lcd_power_node = get_lcd_power_node,
840         .set_custom_status = set_custom_status,
841         .get_custom_status = get_custom_status,
842         .save_custom_brightness = save_custom_brightness,
843         .custom_update = custom_backlight_update,
844         .set_force_brightness = set_force_brightness,
845         .set_brightness = set_brightness,
846         .get_brightness = get_brightness,
847         .restore_brightness_func = restore_brightness_func,
848         .get_brightness_by_light_sensor = get_brightness_by_light_sensor,
849         .get_image_effect = get_image_effect,
850         .set_image_effect = set_image_effect,
851         .get_panel_mode = get_panel_mode,
852         .set_panel_mode = set_panel_mode,
853         .get_frame_rate = get_frame_rate,
854         .set_frame_rate = set_frame_rate,
855         .transit_state = backlight_transit_state,
856         .transit_brt = change_brightness,
857         .blink = blink,
858         .release_blink = release_blink,
859 };
860
861 static struct _display_white_balance_ops display_white_balance_ops = {
862         .set_white_balance = set_white_balance,
863         .get_white_balance = get_white_balance,
864 };
865
866 int display_service_load(void)
867 {
868         int r;
869
870         if (display_dev_available)
871                 return 0;
872
873         r = hal_device_display_get_backend();
874         if (r < 0) {
875                 _E("There is no HAL for display.");
876                 display_dev_available = false;
877                 return 0;
878         }
879
880         display_dev_available = true;
881         _D("Display device structure load success.");
882         return 0;
883 }
884
885 int display_service_free(void)
886 {
887         display_dev_available = false;
888         return hal_device_display_put_backend();
889 }
890
891 static int delayed_init_done(void *data)
892 {
893         static int done = false;
894
895         if (!data)
896                 return done;
897
898         done = *(int *)data;
899
900         return done;
901 }
902
903 int is_lcdon_blocked(void)
904 {
905         /* block lcdon until booting done in silent boot mode */
906         if (silent_boot && !delayed_init_done(NULL))
907                 return LCDON_BLOCK_DURING_SILENT_BOOT;
908
909         return LCDON_BLOCK_NONE;
910 }
911
912 int init_sysfs(unsigned int flags)
913 {
914         register_notifier(DEVICE_NOTIFIER_VITAL_STATE, vital_state_changed);
915         register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
916
917         return 0;
918 }
919
920 int exit_sysfs(void)
921 {
922         const struct device_ops *ops = NULL;
923
924         backlight_update();
925
926         exit_dpms();
927
928         ops = find_device("touchscreen");
929         if (!check_default(ops))
930                 ops->start(NORMAL_MODE);
931
932         ops = find_device("touchkey");
933         if (!check_default(ops))
934                 ops->start(NORMAL_MODE);
935
936         unregister_notifier(DEVICE_NOTIFIER_VITAL_STATE, vital_state_changed);
937
938         return 0;
939 }
940
941 static void __CONSTRUCTOR__ initialize(void)
942 {
943         display_conf = get_var_display_config();
944         if (!display_conf)
945                 _E("Failed to get display configuration variable.");
946 }
947