4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * @brief Power manager main loop.
24 * This file includes Main loop, the FSM, signal processing.
35 #include <sys/types.h>
40 #include <vconf-keys.h>
42 #include <libsyscommon/list.h>
43 #include <hal/device/hal-device-power.h>
45 #include "ambient-mode.h"
49 #include "lock-detector.h"
50 #include "display-ops.h"
51 #include "shared/devices.h"
52 #include "shared/device-notifier.h"
53 #include "core/udev.h"
54 #include "shared/common.h"
55 #include "shared/apps.h"
56 #include "extcon/extcon.h"
57 #include "battery/power-supply.h"
58 #include "power/power.h"
59 #include "power/power-off.h"
60 #include "power/power-suspend.h"
61 #include "power/power-boot.h"
62 #include "power/power-doze.h"
63 #include "device-interface.h"
64 #include "display-plugin.h"
65 #include "display-signal.h"
66 #include "display-lock.h"
67 #include "display-backlight.h"
68 #include "display-misc.h"
69 #include "display-panel.h"
70 #include "display-config.h"
71 #include "display-state-transition.h"
72 #include "shared/plugin.h"
75 * @addtogroup POWER_MANAGER
79 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
80 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
81 #define ALWAYS_ON_TIMEOUT 360000000
83 #define GESTURE_STR "gesture"
84 #define POWER_KEY_STR "powerkey"
85 #define TOUCH_STR "touch"
86 #define EVENT_STR "event"
87 #define TIMEOUT_STR "timeout"
88 #define PROXI_STR "proximity"
89 #define PALM_STR "palm"
90 #define UNKNOWN_STR "unknown"
92 extern void init_save_userlock(void);
94 static struct display_plugin *disp_plgn;
95 static struct display_backlight_ops *backlight_ops;
96 static struct battery_plugin *battery_plgn;
97 static int (*fp_get_charging_status) (int *val);
99 static void (*power_saving_func) (int onoff);
100 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
102 static int system_wakeup_flag = false;
103 static unsigned int custom_normal_timeout = 0;
104 static unsigned int custom_dim_timeout = 0;
105 static char *custom_change_name;
106 static guint lock_timeout_id;
107 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
108 static struct timeval lcdon_tv;
110 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
111 * state because it should be sent from previous state at booting time.
113 static bool lcdon_broadcast = true;
115 static bool touch_blocked = false;
117 /* default transition, action fuctions */
118 static int default_trans(int evt);
119 static int default_action(int timeout);
120 static int default_check(int curr, int next);
122 static int default_proc_change_state(unsigned int cond, pid_t pid);
123 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
125 static struct state states[S_END] = {
126 { S_START, "S_START", NULL, NULL, NULL, NULL },
127 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, NULL },
128 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, NULL },
129 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, NULL },
130 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
131 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
132 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
135 #define SHIFT_UNLOCK 4
136 #define SHIFT_CHANGE_STATE 7
137 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
138 #define SHIFT_LOCK_FLAG 16
139 #define SHIFT_CHANGE_TIMEOUT 20
140 #define CUSTOM_TIMEOUT_BIT 0x1
141 #define CUSTOM_HOLDKEY_BIT 0x2
142 #define HOLD_KEY_BLOCK_BIT 0x1
143 #define TIMEOUT_NONE (-1)
145 #define S_COVER_TIMEOUT 8000
146 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
147 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
149 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
150 #define LONG_PRESS_INTERVAL 2 /* 2 seconds */
151 #define SAMPLING_INTERVAL 1 /* 1 sec */
152 #define BRIGHTNESS_CHANGE_STEP 10
153 #define LCD_ALWAYS_ON 0
154 #define ACCEL_SENSOR_ON 1
155 #define CONTINUOUS_SAMPLING 1
156 #define LCDOFF_TIMEOUT 300 /* milli second */
158 #define DIFF_TIMEVAL_MS(a, b) \
159 (((a.tv_sec * 1000000 + a.tv_usec) - \
160 (b.tv_sec * 1000000 + b.tv_usec)) \
163 static struct display_config display_conf = {
164 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
165 .longpress_interval = LONG_PRESS_INTERVAL,
166 .lightsensor_interval = SAMPLING_INTERVAL,
167 .lcdoff_timeout = LCDOFF_TIMEOUT,
168 .pm_default_brightness = 80,
169 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
170 .lcd_always_on = LCD_ALWAYS_ON,
172 .framerate_app = {0, 0, 0, 0},
173 .control_display = 0,
174 .powerkey_doublepress = 0,
175 .accel_sensor_on = ACCEL_SENSOR_ON,
176 .continuous_sampling = CONTINUOUS_SAMPLING,
177 .timeout_enable = true,
178 .input_support = true,
179 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
180 .lockcheck_timeout = 600,
181 .aod_enter_level = 40,
183 .touch_wakeup = false,
184 .display_on_usb_conn_changed = true,
185 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
188 struct display_function_info display_info = {
189 .update_auto_brightness = NULL,
190 .set_autobrightness_min = NULL,
191 .reset_autobrightness_min = NULL,
192 .face_detection = NULL,
195 inline const struct display_config* get_var_display_config()
197 return &display_conf;
200 inline struct state* state_st(enum state_t state)
202 return &states[state];
205 static const char* __device_flags_to_string(enum device_flags flags)
207 if (flags & LCD_ON_BY_GESTURE)
209 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
210 return POWER_KEY_STR;
211 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
213 else if (flags & LCD_ON_BY_TOUCH)
215 else if (flags & LCD_OFF_BY_TIMEOUT)
221 bool touch_event_blocked(void)
223 return touch_blocked;
226 void lcd_on_procedure(int state, enum device_flags flag)
228 unsigned long flags = NORMAL_MODE;
229 display_plugin_get_device_flags(&flags);
233 * Display on procedure
235 * step 2. broadcast lcd on signal with cause
236 * step 3. set brightness
237 * step 4. set pmstate of vconf
238 * step 5. display on operate
240 * - b. TSP(touch screen) and touchkey enable
241 * step 6. broadcast lcd on complete signal
242 * step 7. key backlight enable
246 _I("[lcdstep] 0x%lx", flags);
248 /* send LCDOn dbus signal */
249 if (!lcdon_broadcast)
250 broadcast_lcd_on(SIGNAL_PRE, flags);
252 /* Update brightness level */
253 if (state == LCD_DIM)
254 display_backlight_set_brightness_by_dim_brightness();
255 else if (state == LCD_NORMAL)
256 display_backlight_update_by_default_brightness();
258 if (state == LCD_NORMAL)
259 set_setting_pmstate(S_NORMAL);
260 else if (state == LCD_DIM)
261 set_setting_pmstate(S_LCDDIM);
263 display_start_dependent_device(flags);
265 if (!lcdon_broadcast) {
266 broadcast_lcd_on(SIGNAL_POST, flags);
267 lcdon_broadcast = true;
270 if (CHECK_OPS(keyfilter_ops, backlight_enable))
271 keyfilter_ops->backlight_enable(true);
273 touch_blocked = false;
276 inline void lcd_off_procedure(enum device_flags flag)
278 unsigned long flags = NORMAL_MODE;
279 display_plugin_get_device_flags(&flags);
283 * Display off procedure
284 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
285 * step 1. broadcast lcd off signal with cause
286 * step 2. set pmstate of vconf
287 * step 3. display off operate
289 * - b. TSP(touch screen) and touchkey disable
290 * step 4. broadcast lcd off complete siganl
291 * step 5. enter doze mode if it is enabled
293 _I("[lcdstep] 0x%lx", flags);
297 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
299 if (lcdon_broadcast) {
300 broadcast_lcd_off(SIGNAL_PRE, flags);
301 lcdon_broadcast = false;
306 touch_blocked = true;
308 set_setting_pmstate(S_LCDOFF);
310 if (CHECK_OPS(keyfilter_ops, backlight_enable))
311 keyfilter_ops->backlight_enable(false);
313 display_stop_dependent_device(flags);
315 broadcast_lcd_off(SIGNAL_POST, flags);
316 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
321 static void update_display_time(void)
323 int run_timeout, val;
325 /* first priority : custom timeout */
326 if (custom_normal_timeout > 0) {
327 states[S_NORMAL].timeout = custom_normal_timeout;
328 states[S_LCDDIM].timeout = custom_dim_timeout;
329 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
330 custom_normal_timeout, custom_dim_timeout);
334 /* second priority : lock state */
335 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
336 !get_lock_screen_bg_state()) {
337 /* timeout is different according to key or event. */
338 states[S_NORMAL].timeout = lock_screen_timeout;
339 _I("LOCK: Timeout(%d ms) is set by normal.",
340 lock_screen_timeout);
344 /* default setting */
345 get_run_timeout(&run_timeout);
348 * if the run_timeout is zero, it regards AlwaysOn state
350 if (run_timeout == 0 || display_conf.lcd_always_on) {
351 run_timeout = ALWAYS_ON_TIMEOUT;
352 _I("LCD always on.");
355 states[S_NORMAL].timeout = run_timeout;
357 get_dim_timeout(&val);
358 states[S_LCDDIM].timeout = val;
360 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
361 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
364 static void update_display_locktime(int time)
366 lock_screen_timeout = time;
367 update_display_time();
370 void set_dim_state(bool on)
372 _I("Dim state is %d.", on);
373 update_display_time();
374 states[get_pm_cur_state()].trans(EVENT_INPUT);
377 void lcd_on_direct(enum device_flags flags)
379 enum hal_device_power_transition_reason reason;
381 if (flags & LCD_ON_BY_POWER_KEY)
382 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
383 else if (flags & LCD_ON_BY_TOUCH)
384 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
386 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
388 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
389 set_pm_cur_state(S_NORMAL);
391 _D("lcd is on directly");
392 gettimeofday(&lcdon_tv, NULL);
393 lcd_on_procedure(LCD_NORMAL, flags);
395 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
398 static inline bool check_lcd_is_on(void)
400 if (display_panel_get_dpms_cached_state() != DPMS_ON)
406 static gboolean timer_refresh_cb(gpointer data)
410 /* state transition */
411 set_pm_old_state(get_pm_cur_state());
412 set_pm_cur_state(S_NORMAL);
413 st = &states[get_pm_cur_state()];
416 st->action(st->timeout);
421 int custom_lcdon(int timeout)
428 if (check_lcd_is_on() == false)
429 lcd_on_direct(LCD_ON_BY_GESTURE);
431 _I("Custom lcd on timeout(%d ms).", timeout);
432 if (set_custom_lcdon_timeout(timeout) == true)
433 update_display_time();
435 /* state transition */
436 set_pm_old_state(get_pm_cur_state());
437 set_pm_cur_state(S_NORMAL);
438 st = &states[get_pm_cur_state()];
442 st->action(st->timeout);
444 g_idle_add(timer_refresh_cb, NULL);
449 int custom_lcdoff(enum device_flags flag)
453 check_processes(S_NORMAL);
454 check_processes(S_LCDDIM);
456 /* check holdkey block flag in lock node */
457 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
459 * When another proccess is normal lock, device is received call then,
460 * call app can be changed to lcd state by proximity.
461 * If proximity is near then normal lock will be unlocked.
463 if (flag & LCD_OFF_BY_PROXIMITY) {
464 _I("custom lcd off by proximity, delete normal lock");
465 delete_condition(S_NORMAL);
467 _I("skip custom lcd off");
472 _I("custom lcd off by flag(%d)", flag);
473 if (display_panel_get_dpms_cached_state() == DPMS_ON)
474 lcd_off_procedure(flag);
476 if (set_custom_lcdon_timeout(0) == true)
477 update_display_time();
479 /* state transition */
480 set_pm_old_state(get_pm_cur_state());
481 set_pm_cur_state(S_LCDOFF);
482 st = &states[get_pm_cur_state()];
486 st->action(st->timeout);
491 int display_on_by_reason(const char *reason, int timeout)
497 str_len = strlen(reason);
499 if (!strncmp(reason, GESTURE_STR, str_len))
500 flag = LCD_ON_BY_GESTURE;
501 else if (!strncmp(reason, EVENT_STR, str_len))
502 flag = LCD_ON_BY_EVENT;
504 _E("Reason is unknown(%s)", reason);
509 _E("Cannot setting timeout %d", timeout);
513 if (check_lcd_is_on() == false)
516 _I("platform lcd on by %s (%d ms)", reason, timeout);
517 if (set_custom_lcdon_timeout(timeout) == true)
518 update_display_time();
520 /* state transition */
521 set_pm_old_state(get_pm_cur_state());
522 set_pm_cur_state(S_NORMAL);
523 st = &states[get_pm_cur_state()];
527 st->action(st->timeout);
532 int display_off_by_reason(const char *reason)
538 str_len = strlen(reason);
540 if (!strncmp(reason, GESTURE_STR, str_len)) {
541 check_processes(S_NORMAL);
542 check_processes(S_LCDDIM);
544 /* check holdkey block flag in lock node */
545 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
546 _I("skip platform lcd off by gesture");
549 flag = LCD_OFF_BY_GESTURE;
550 } else if (!strncmp(reason, PALM_STR, str_len)) {
551 delete_condition(S_NORMAL);
552 delete_condition(S_LCDDIM);
554 flag = LCD_OFF_BY_PALM;
556 _E("Reason is unknown(%s)", reason);
560 _I("platform lcd off by %s", reason);
561 if (display_panel_get_dpms_cached_state() == DPMS_ON)
562 lcd_off_procedure(flag);
564 /* state transition */
565 set_pm_old_state(get_pm_cur_state());
566 set_pm_cur_state(S_LCDOFF);
567 st = &states[get_pm_cur_state()];
571 st->action(st->timeout);
576 static void default_proc_change_state_action(enum state_t next, int timeout)
580 set_pm_old_state(get_pm_cur_state());
581 set_pm_cur_state(next);
583 st = &states[get_pm_cur_state()];
585 if (st && st->action) {
587 st->action(st->timeout);
593 static int default_proc_change_state(unsigned int cond, pid_t pid)
597 next = GET_COND_STATE(cond);
598 _I("Change process(%d) state to %s.", pid, states[next].name);
602 if (check_lcd_is_on() == false)
603 lcd_on_direct(LCD_ON_BY_EVENT);
604 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
605 default_proc_change_state_action(next, -1);
608 default_proc_change_state_action(next, -1);
611 if (display_panel_get_dpms_cached_state() == DPMS_ON)
612 lcd_off_procedure(LCD_OFF_BY_EVENT);
613 if (set_custom_lcdon_timeout(0))
614 update_display_time();
615 default_proc_change_state_action(next, -1);
618 _I("Dangerous requests.");
619 /* at first LCD_OFF and then goto sleep */
620 /* state transition */
621 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
622 delete_condition(S_NORMAL);
623 delete_condition(S_LCDDIM);
624 delete_condition(S_LCDOFF);
625 if (lcdon_broadcast) {
626 _I("broadcast lcd off signal at non-lcd device");
627 broadcast_lcd_off(SIGNAL_PRE, 0);
628 broadcast_lcd_off(SIGNAL_POST, 0);
630 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
640 static void proc_condition_lock(PMMsg *data)
643 char pname[PATH_MAX];
644 pid_t pid = data->pid;
646 int holdkey_block, ret;
649 const char *lock_type = NULL;
651 state = GET_COND_STATE(data->cond);
652 if (state == S_START)
655 flags = GET_COND_FLAG(data->cond);
656 display_misc_get_process_name(pid, pname);
658 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
659 (pm_get_power_lock() == POWER_UNLOCK))
660 proc_change_state(data->cond, INTERNAL_LOCK_PM);
662 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
663 tmp = display_lock_add_pmlock_node(state, pid, holdkey_block, data->timeout);
665 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
669 if (state == S_LCDOFF)
670 set_process_active(true, pid);
672 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
674 if (pid < INTERNAL_LOCK_BASE) {
676 if (state == S_LCDOFF)
677 lock_type = PM_LCDOFF_STR;
678 else if (state == S_LCDDIM)
679 lock_type = PM_LCDDIM_STR;
680 else if (state == S_NORMAL)
681 lock_type = PM_LCDON_STR;
684 /* power lock signal */
685 ret = gdbus_signal_emit(NULL,
686 DEVICED_PATH_DISPLAY,
687 DEVICED_INTERFACE_DISPLAY,
689 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
691 _E("Failed to send dbus signal PowerLock.");
695 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
696 pname, holdkey_block, flags);
697 set_lock_time(pid, pname, state);
699 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
702 static void proc_condition_unlock(PMMsg *data)
704 pid_t pid = data->pid;
707 char pname[PATH_MAX];
711 const char *lock_type = NULL;
713 state = GET_COND_STATE(data->cond);
717 flags = GET_COND_FLAG(data->cond);
718 display_misc_get_process_name(pid, pname);
720 tmp = find_node(state, pid);
721 del_node(state, tmp);
723 if (state == S_LCDOFF)
724 set_process_active(false, pid);
726 _I("[%s] unlocked by %5d", states[state].name, pid);
728 if (pid < INTERNAL_LOCK_BASE) {
730 if (state == S_LCDOFF)
731 lock_type = PM_LCDOFF_STR;
732 else if (state == S_LCDDIM)
733 lock_type = PM_LCDDIM_STR;
734 else if (state == S_NORMAL)
735 lock_type = PM_LCDON_STR;
738 /* power unlock signal */
739 ret = gdbus_signal_emit(NULL,
740 DEVICED_PATH_DISPLAY,
741 DEVICED_INTERFACE_DISPLAY,
743 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
745 _E("Failed to send dbus signal PowerUnlock.");
749 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
750 set_unlock_time(pid, state);
752 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
755 static int proc_condition(PMMsg *data)
759 if (IS_COND_REQUEST_LOCK(data->cond))
760 proc_condition_lock(data);
762 if (IS_COND_REQUEST_UNLOCK(data->cond))
763 proc_condition_unlock(data);
765 if (!display_conf.timeout_enable)
768 flags = GET_COND_FLAG(data->cond);
770 /* guard time for suspend */
771 if (get_pm_cur_state() == S_LCDOFF)
772 display_state_transition_reset_state_transition_timeout(states[S_LCDOFF].timeout);
774 if (flags & PM_FLAG_RESET_TIMER)
775 display_state_transition_reset_state_transition_timeout(states[get_pm_cur_state()].timeout);
778 if (!display_state_transition_is_there_state_transition_timer())
779 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
784 void update_lcdoff_source(int source)
789 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
790 _I("LCD OFF by timeout.");
792 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
793 _I("LCD OFF by powerkey.");
796 _E("Invalid value(%d).", source);
799 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
801 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
804 /* SIGHUP signal handler
805 * For debug... print info to syslog
807 static void sig_hup(int signo)
809 _I("received sig hub %d", signo);
814 int check_lcdoff_direct(void)
816 int ret, lock, cradle;
819 if (get_pm_old_state() != S_NORMAL)
822 if (get_pm_cur_state() != S_LCDDIM)
825 if (!display_conf.dimming)
828 lock = __get_lock_screen_state();
829 if (lock != VCONFKEY_IDLE_LOCK)
832 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
836 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
837 if (ret >= 0 && cradle == DOCK_SOUND)
840 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
842 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
848 * default transition function
851 * 3. call enter action function
853 static int default_trans(int evt)
855 struct state *st = &states[get_pm_cur_state()];
856 enum state_t next_state;
858 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, evt);
860 /* check conditions */
861 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
862 /* There is a condition. */
863 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
864 states[next_state].name);
868 /* state transition */
869 set_pm_old_state(get_pm_cur_state());
870 set_pm_cur_state(next_state);
871 st = &states[get_pm_cur_state()];
875 if (get_pm_cur_state() == S_LCDOFF)
876 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
878 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
879 if (set_custom_lcdon_timeout(0) == true)
880 update_display_time();
882 if (check_lcdoff_direct() == true) {
883 /* enter next state directly */
884 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
886 if ((get_pm_cur_state() == S_SLEEP)
887 && (is_emulator() == true || timeout_sleep_support == false))
890 st->action(st->timeout);
897 static gboolean lcd_on_expired(void *data)
904 /* check state of lock */
905 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
906 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
907 return G_SOURCE_REMOVE;
909 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
911 /* lock screen is not launched yet, but lcd is on */
912 if (check_lcd_is_on() == false)
913 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
915 return G_SOURCE_REMOVE;
918 static inline void stop_lock_timer(void)
920 if (lock_timeout_id) {
921 g_source_remove(lock_timeout_id);
926 static void check_lock_screen(void)
932 /* check state of lock */
933 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
934 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
937 /* Use time to check lock is done. */
938 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
939 lcd_on_expired, NULL);
942 /* default enter action function */
943 static int default_action(int timeout)
945 int wakeup_count = -1, pm_cur_state;
948 static time_t last_update_time = 0;
949 static int last_timeout = 0;
950 struct timeval now_tv;
953 bool lcd_paneloff_mode = false;
955 if (status != DEVICE_OPS_STATUS_START) {
956 _E("Display is not started.");
960 if (get_pm_cur_state() != S_SLEEP) {
961 if ((get_pm_cur_state() == S_NORMAL) &&
962 lcdon_tv.tv_sec != 0) {
963 gettimeofday(&now_tv, NULL);
964 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
967 /* set timer with current state timeout */
968 display_state_transition_reset_state_transition_timeout(timeout);
970 if (get_pm_cur_state() == S_NORMAL) {
971 time(&last_update_time);
972 last_timeout = timeout;
974 _I("Timout set: %s state %d ms",
975 states[get_pm_cur_state()].name, timeout);
979 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
980 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
981 power_get_wakeup_reason(), NULL);
982 set_setting_pmstate(get_pm_cur_state());
983 pm_cur_state = get_pm_cur_state();
984 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
987 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
989 diff = difftime(now, last_update_time);
990 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
991 states[get_pm_cur_state()].name, last_timeout, diff);
994 switch (get_pm_cur_state()) {
997 * normal state : backlight on and restore
998 * the previous brightness
1000 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1001 check_lock_screen();
1002 else if (get_pm_old_state() == S_LCDDIM)
1003 display_backlight_update_by_default_brightness();
1005 if (check_lcd_is_on() == false)
1006 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1010 display_backlight_get_custom_status(&custom_status);
1011 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1012 display_backlight_get_brightness(&brightness);
1013 display_backlight_set_custom_brightness(brightness);
1015 /* lcd dim state : dim the brightness */
1016 display_backlight_set_brightness_by_dim_brightness();
1018 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1019 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1023 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1025 /* lcd off state : turn off the backlight */
1026 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1027 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1030 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1031 if (display_panel_get_dpms_cached_state() == DPMS_ON
1032 || lcd_paneloff_mode)
1033 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1037 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1040 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1041 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1043 if (!pm_get_power_lock_support()) {
1044 /* sleep state : set system mode to SUSPEND */
1045 if (get_wakeup_count(&wakeup_count) < 0)
1046 _E("Wakeup count read error.");
1048 if (wakeup_count < 0) {
1049 _I("Wakup Event. Can not enter suspend mode.");
1053 if (set_wakeup_count(wakeup_count) < 0) {
1054 _E("Wakeup count write error.");
1064 #ifdef ENABLE_PM_LOG
1065 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1067 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1071 if (!pm_get_power_lock_support()) {
1073 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1079 * default check function
1081 * 0 : can't transit, others : transitable
1083 static int default_check(int curr, int next)
1087 makeup_trans_condition();
1089 trans_cond = get_trans_condition() & MASK_BIT;
1091 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1096 trans_cond = trans_cond & MASK_NORMAL;
1099 trans_cond = trans_cond & MASK_DIM;
1102 trans_cond = trans_cond & MASK_OFF;
1109 if (trans_cond != 0) {
1114 return 1; /* transitable */
1117 static void default_saving_mode(int onoff)
1120 set_pm_status_flag(PWRSV_FLAG);
1122 clear_pm_status_flag(PWRSV_FLAG);
1124 if (get_pm_cur_state() == S_NORMAL)
1125 display_backlight_update_by_default_brightness();
1128 int poll_callback(int condition, PMMsg *data)
1130 static time_t last_t;
1133 if (status != DEVICE_OPS_STATUS_START) {
1134 _E("Display logic is not started.");
1138 if (condition == INPUT_POLL_EVENT) {
1139 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1140 _I("Input event signal at Display Off");
1142 if ((last_t != now) ||
1143 (get_pm_cur_state() == S_LCDOFF) ||
1144 (get_pm_cur_state() == S_SLEEP)) {
1145 states[get_pm_cur_state()].trans(EVENT_INPUT);
1150 if (condition == PM_CONTROL_EVENT) {
1151 proc_condition(data);
1153 if (IS_COND_REQUEST_CHANGE(data->cond))
1154 proc_change_state(data->cond, data->pid);
1160 static int update_setting(int key_idx, int val)
1165 case SETTING_TO_NORMAL:
1166 update_display_time();
1167 states[get_pm_cur_state()].trans(EVENT_INPUT);
1169 case SETTING_LOW_BATT:
1170 if (display_misc_is_low_battery_state(val)) {
1171 if (!(get_pm_status_flag() & CHRGR_FLAG))
1172 power_saving_func(true);
1173 set_pm_status_flag(LOWBT_FLAG);
1175 if (get_pm_status_flag() & PWRSV_FLAG)
1176 power_saving_func(false);
1177 clear_pm_status_flag(LOWBT_FLAG);
1178 clear_pm_status_flag(BRTCH_FLAG);
1179 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1181 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1184 case SETTING_CHARGING:
1186 if (get_pm_status_flag() & LOWBT_FLAG) {
1187 power_saving_func(false);
1188 clear_pm_status_flag(LOWBT_FLAG);
1190 set_pm_status_flag(CHRGR_FLAG);
1193 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1196 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1197 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1199 if (display_misc_is_low_battery_state(bat_state)) {
1200 power_saving_func(true);
1201 set_pm_status_flag(LOWBT_FLAG);
1203 clear_pm_status_flag(CHRGR_FLAG);
1206 case SETTING_BRT_LEVEL:
1207 if (get_pm_status_flag() & PWRSV_FLAG) {
1208 set_pm_status_flag(BRTCH_FLAG);
1209 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1211 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1212 _I("Brightness changed in low battery,"
1213 "escape dim state.");
1215 display_backlight_set_default_brightness(val);
1217 case SETTING_LOCK_SCREEN:
1218 set_lock_screen_state(val);
1219 if (val == VCONFKEY_IDLE_UNLOCK) {
1220 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1221 keyfilter_ops->backlight_enable(false);
1224 /* LCD on if lock screen show before waiting time */
1225 if ((get_pm_cur_state() == S_NORMAL) &&
1226 val == VCONFKEY_IDLE_LOCK &&
1227 display_panel_get_dpms_cached_state() != DPMS_ON &&
1228 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1229 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1231 update_display_time();
1232 if (get_pm_cur_state() == S_NORMAL)
1233 states[get_pm_cur_state()].trans(EVENT_INPUT);
1235 case SETTING_LOCK_SCREEN_BG:
1236 set_lock_screen_bg_state(val);
1237 update_display_time();
1238 if (get_pm_cur_state() == S_NORMAL)
1239 states[get_pm_cur_state()].trans(EVENT_INPUT);
1241 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1242 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1243 display_backlight_set_custom_status(true);
1245 display_backlight_set_custom_status(false);
1254 static void check_seed_status(void)
1262 /* Charging check */
1263 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1264 set_pm_status_flag(CHRGR_FLAG);
1266 ret = get_setting_brightness(&tmp);
1267 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1268 _I("Failed to read vconf value for brightness.");
1269 brt = display_conf.pm_default_brightness;
1270 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1271 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1273 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1277 _I("Set brightness(%d) from setting app.", tmp);
1278 display_backlight_set_default_brightness(tmp);
1279 display_backlight_set_brightness(tmp);
1281 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1283 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1284 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1286 if (display_misc_is_low_battery_state(bat_state)) {
1287 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1288 power_saving_func(true);
1289 set_pm_status_flag(LOWBT_FLAG);
1293 /* lock screen check */
1294 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1297 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1299 set_lock_screen_state(lock_state);
1300 if (lock_state == VCONFKEY_IDLE_LOCK) {
1301 states[S_NORMAL].timeout = lock_screen_timeout;
1302 _I("LCD NORMAL timeout(%d ms) is set"
1303 " for lock screen.", lock_screen_timeout);
1309 static void init_lcd_operation(void)
1311 const struct device_ops *ops = NULL;
1313 ops = find_device("display");
1314 if (!check_default(ops))
1315 display_register_dependent_device(ops);
1317 ops = find_device("touchkey");
1318 if (!check_default(ops))
1319 display_register_dependent_device(ops);
1321 ops = find_device("touchscreen");
1322 if (!check_default(ops))
1323 display_register_dependent_device(ops);
1326 static void exit_lcd_operation(void)
1328 display_unregister_dependent_device();
1340 static const char *errMSG[INIT_END] = {
1341 [INIT_SETTING] = "setting init error",
1342 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1343 [INIT_POLL] = "input devices poll init error",
1344 [INIT_FIFO] = "FIFO poll init error",
1345 [INIT_DBUS] = "d-bus init error",
1348 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1350 if (on == 0 && dim == 0) {
1351 _I("LCD timeout changed: default setting");
1352 custom_normal_timeout = custom_dim_timeout = 0;
1353 } else if (on < 0 || dim < 0) {
1354 _E("Failed to set value(on=%d dim=%d).", on, dim);
1357 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1358 custom_normal_timeout = SEC_TO_MSEC(on);
1359 custom_dim_timeout = SEC_TO_MSEC(dim);
1361 /* Apply new backlight time */
1362 update_display_time();
1363 if (get_pm_cur_state() == S_NORMAL)
1364 states[get_pm_cur_state()].trans(EVENT_INPUT);
1366 if (holdkey_block) {
1367 display_lock_set_custom_holdkey_block(true);
1368 _I("Hold key disabled.");
1370 display_lock_set_custom_holdkey_block(false);
1371 _I("Hold key enabled.");
1374 if (custom_change_name) {
1375 free(custom_change_name);
1376 custom_change_name = 0;
1379 if (custom_normal_timeout == 0 &&
1380 custom_dim_timeout == 0 &&
1384 custom_change_name = strndup(name, strlen(name));
1385 if (!custom_change_name) {
1386 _E("Failed to malloc.");
1387 custom_normal_timeout = custom_dim_timeout = 0;
1388 display_lock_set_custom_holdkey_block(false);
1395 void reset_lcd_timeout(GDBusConnection *conn,
1396 const gchar *sender,
1397 const gchar *unique_name,
1403 if (!custom_change_name)
1406 if (strcmp(sender, custom_change_name))
1409 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1411 free(custom_change_name);
1412 custom_change_name = 0;
1413 custom_normal_timeout = custom_dim_timeout = 0;
1414 display_lock_set_custom_holdkey_block(false);
1416 update_display_time();
1417 if (get_pm_cur_state() == S_NORMAL)
1418 states[get_pm_cur_state()].trans(EVENT_INPUT);
1421 static int delayed_init_done(void *data)
1423 static bool done = false;
1432 _I("Booting done, release booting lock.");
1433 if (disp_plgn->pm_unlock_internal) {
1434 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1435 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1441 static gboolean delayed_dpms_init_done(gpointer data)
1445 if (!display_panel_init_dpms())
1446 return G_SOURCE_CONTINUE;
1448 switch (get_pm_cur_state()) {
1451 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1452 if (display_conf.timeout_enable) {
1453 timeout = states[S_NORMAL].timeout;
1454 /* check minimun lcd on time */
1455 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1456 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1457 display_state_transition_reset_state_transition_timeout(timeout);
1461 lcd_off_procedure(LCD_OFF_BY_EVENT);
1462 timeout = display_conf.lcdoff_timeout;
1463 display_state_transition_reset_state_transition_timeout(timeout);
1469 return G_SOURCE_REMOVE;
1472 static void add_timer_for_dpms_init(void)
1474 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
1476 _E("Failed to add display_panel_init_dpms timeout.");
1479 static void init_display_states(void *data)
1481 struct display_plugin *dp = (struct display_plugin *) data;
1482 for(int i = 0; i < S_END; i++)
1483 dp->display_states[i] = &states[i];
1486 * Power manager Main
1490 static int display_probe(void *data)
1493 struct display_plugin *dp = (struct display_plugin *) data;
1496 dp->config = &display_conf;
1497 init_display_states(dp);
1498 setup_display_plugin_backlight_ops(dp);
1499 dp->set_dim_state = set_dim_state;
1500 dp->get_device_flags = NULL;
1501 setup_display_plugin_backlight_ops(dp);
1504 * load display service
1505 * if there is no display shared library,
1506 * deviced does not provide any method and function of display.
1508 ret = display_service_load();
1512 /* display_plugin instance initialization */
1513 init_pm_internal(data);
1514 disp_plgn->device_flags_to_string = __device_flags_to_string;
1516 if (battery_plgn->handle) {
1517 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
1518 if (!fp_get_charging_status)
1519 _E("Failed to obtain address of get_charging_status");
1521 _I("There is no battery module.");
1526 static int input_init_handler(void)
1528 if (!display_conf.input_support)
1529 remove_device_by_devname("input");
1534 static int power_resume_from_echomem_callback(void *data)
1536 system_wakeup_flag = true;
1537 if (check_wakeup_src() == EVENT_DEVICE)
1538 /* system waked up by devices */
1539 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1541 /* system waked up by user input */
1542 states[get_pm_cur_state()].trans(EVENT_INPUT);
1547 static int poweroff_triggered_callback(void *udata)
1549 int val = (int)(intptr_t) udata;
1552 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
1553 clear_pm_status_flag(PWROFF_FLAG);
1555 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
1556 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
1557 set_pm_status_flag(PWROFF_FLAG);
1564 static void esd_action(void)
1566 const struct device_ops *touchscreen_ops = NULL;
1570 touchscreen_ops = find_device("touchscreen");
1572 if (!check_default(touchscreen_ops))
1573 touchscreen_ops->stop(NORMAL_MODE);
1574 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
1575 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
1576 if (!check_default(touchscreen_ops))
1577 touchscreen_ops->start(NORMAL_MODE);
1580 static void lcd_uevent_changed(struct udev_device *dev)
1582 const char *devpath;
1585 devpath = udev_device_get_devpath(dev);
1589 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
1590 action = udev_device_get_action(dev);
1591 if (!strcmp(action, UDEV_CHANGE))
1596 static const struct uevent_handler lcd_uevent_ops = {
1597 .subsystem = LCD_EVENT_SUBSYSTEM,
1598 .uevent_func = lcd_uevent_changed,
1602 static void display_init(void *data)
1605 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
1608 _I("Start power manager.");
1610 signal(SIGHUP, sig_hup);
1612 power_saving_func = default_saving_mode;
1614 /* load configutation */
1615 ret = display_load_config(&display_conf);
1617 _W("Failed to load '%s', use default value: %d",
1618 DISPLAY_CONF_FILE, ret);
1620 register_kernel_uevent_control(&lcd_uevent_ops);
1622 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1623 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1624 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1625 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1626 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1627 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
1629 init_save_userlock();
1631 for (i = INIT_SETTING; i < INIT_END; i++) {
1634 ret = init_setting(update_setting);
1636 case INIT_INTERFACE:
1637 if (display_conf.timeout_enable)
1638 display_initialize_display_state_timeout_from_setting();
1639 ret = init_sysfs(flags);
1643 ret = input_init_handler();
1645 pm_lock_detector_init();
1649 ret = init_pm_dbus();
1653 _E("Failed to init: %s", errMSG[i]);
1658 if (i == INIT_END) {
1659 display_ops_init(NULL);
1660 #ifdef ENABLE_PM_LOG
1663 init_lcd_operation();
1664 check_seed_status();
1666 /* In smd test, TSP should be turned off if display panel is not existed. */
1667 if (display_panel_get_dpms_cached_state() == -ENOENT) {
1668 _I("Display panel is not existed.");
1669 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
1670 exit_lcd_operation();
1673 /* wm_ready needs to be checked
1674 * since display manager can be launched later than deviced.
1675 * In the case, display cannot be turned on at the first booting */
1676 // wm_ready = check_wm_ready();
1677 if (display_panel_init_dpms()) {
1678 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
1679 lcd_off_procedure(LCD_OFF_BY_EVENT);
1681 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1683 add_timer_for_dpms_init();
1686 if (display_conf.lcd_always_on) {
1687 _I("LCD always on.");
1688 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
1691 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
1692 _I("Start Power managing without noti");
1693 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1694 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
1696 * Lock lcd off until booting is done.
1697 * deviced guarantees all booting script is executing.
1698 * Last script of booting unlocks this suspend blocking state.
1700 if (disp_plgn->pm_lock_internal)
1701 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
1702 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
1704 /* Initial display state right after the booting done */
1705 if (is_lcdon_blocked())
1706 set_pm_cur_state(S_LCDOFF);
1708 set_pm_cur_state(S_NORMAL);
1709 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
1711 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
1713 status = DEVICE_OPS_STATUS_START;
1714 if (display_conf.timeout_enable) {
1715 timeout = states[S_NORMAL].timeout;
1716 /* check minimun lcd on time */
1717 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1718 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1720 if (disp_plgn->pm_lock_internal)
1721 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
1722 STAY_CUR_STATE, timeout);
1727 if (display_conf.input_support)
1728 if (CHECK_OPS(keyfilter_ops, init))
1729 keyfilter_ops->init();
1731 set_display_init_direction(display_conf.display_init_direction);
1735 static void display_exit(void *data)
1739 status = DEVICE_OPS_STATUS_STOP;
1741 /* Set current state to S_NORMAL */
1742 set_pm_cur_state(S_NORMAL);
1743 set_setting_pmstate(get_pm_cur_state());
1744 /* timeout is not needed */
1745 display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
1747 if (CHECK_OPS(keyfilter_ops, exit))
1748 keyfilter_ops->exit();
1750 unregister_kernel_uevent_control(&lcd_uevent_ops);
1752 display_ops_exit(NULL);
1754 for (i = i - 1; i >= INIT_SETTING; i--) {
1759 case INIT_INTERFACE:
1763 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1764 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1765 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1766 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1767 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1773 exit_lcd_operation();
1774 free_lock_info_list();
1776 /* free display service */
1777 display_service_free();
1779 _I("Stop power manager.");
1782 static int display_start(enum device_flags flags)
1785 if (flags & NORMAL_MODE) {
1786 if (flags & LCD_PANEL_OFF_MODE)
1788 display_panel_set_panel_state_by_standby_state(true);
1791 display_panel_set_panel_state_by_on_state(flags);
1796 /* CORE LOGIC MODE */
1797 if (!(flags & CORE_LOGIC_MODE))
1800 if (status == DEVICE_OPS_STATUS_START)
1803 if (display_probe(NULL) < 0)
1811 static int display_stop(enum device_flags flags)
1814 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
1815 display_panel_set_panel_state_by_off_state(flags);
1819 /* CORE LOGIC MODE */
1820 if (!(flags & CORE_LOGIC_MODE))
1823 if (status == DEVICE_OPS_STATUS_STOP)
1831 static int display_status(void)
1836 static const struct device_ops display_plugin_device_ops = {
1837 .disable_auto_init = true,
1838 DECLARE_NAME_LEN("display-plugin"),
1839 .probe = display_probe,
1840 .init = display_init,
1841 .exit = display_exit,
1842 .start = display_start,
1843 .stop = display_stop,
1844 .status = display_status,
1847 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
1849 static void __CONSTRUCTOR__ initialize(void)
1851 disp_plgn = get_var_display_plugin();
1853 _E("Failed to get display plugin variable.");
1855 backlight_ops = get_var_backlight_ops();
1857 _E("Failed to get backlight operator variable.");
1859 battery_plgn = get_var_battery_plugin();
1861 _E("Failed to get battery plugin variable.");