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