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 "proximity.h"
66 #include "display-info.h"
67 #include "display-signal.h"
68 #include "display-lock.h"
69 #include "display-backlight.h"
70 #include "display-misc.h"
71 #include "display-panel.h"
72 #include "display-config.h"
73 #include "display-state-transition.h"
74 #include "shared/plugin.h"
77 * @addtogroup POWER_MANAGER
81 #define LOCK_SCREEN_INPUT_TIMEOUT 10000
82 #define LOCK_SCREEN_CONTROL_TIMEOUT 5000
83 #define ALWAYS_ON_TIMEOUT 360000000
85 #define GESTURE_STR "gesture"
86 #define POWER_KEY_STR "powerkey"
87 #define TOUCH_STR "touch"
88 #define EVENT_STR "event"
89 #define TIMEOUT_STR "timeout"
90 #define PROXI_STR "proximity"
91 #define PALM_STR "palm"
92 #define UNKNOWN_STR "unknown"
94 extern void init_save_userlock(void);
96 static struct display_plugin *disp_plgn;
97 static struct display_backlight_ops *backlight_ops;
98 static struct battery_plugin *battery_plgn;
99 static int (*fp_get_charging_status) (int *val);
101 static void (*power_saving_func) (int onoff);
102 static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
104 static int system_wakeup_flag = false;
105 static unsigned int custom_normal_timeout = 0;
106 static unsigned int custom_dim_timeout = 0;
107 static char *custom_change_name;
108 static guint lock_timeout_id;
109 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
110 static struct timeval lcdon_tv;
112 * The two variables(lcdon_broadcast, pmstate_suspend) must be set initial
113 * state because it should be sent from previous state at booting time.
115 static bool lcdon_broadcast = true;
117 static bool touch_blocked = false;
119 /* default transition, action fuctions */
120 static int default_trans(int evt);
121 static int default_action(int timeout);
122 static int default_check(int curr, int next);
124 static gboolean del_normal_cond(void *data);
125 static gboolean del_dim_cond(void *data);
126 static gboolean del_off_cond(void *data);
128 static int default_proc_change_state(unsigned int cond, pid_t pid);
129 static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
131 static struct state states[S_END] = {
132 { S_START, "S_START", NULL, NULL, NULL, NULL },
133 { S_NORMAL, "S_NORMAL", default_trans, default_action, default_check, del_normal_cond },
134 { S_LCDDIM, "S_LCDDIM", default_trans, default_action, default_check, del_dim_cond },
135 { S_LCDOFF, "S_LCDOFF", default_trans, default_action, default_check, del_off_cond },
136 { S_STANDBY, "S_STANDBY", NULL, NULL, NULL, NULL },
137 { S_SLEEP, "S_SLEEP", default_trans, default_action, default_check, NULL },
138 { S_POWEROFF, "S_POWEROFF", NULL, NULL, NULL, NULL },
141 #define SHIFT_UNLOCK 4
142 #define SHIFT_CHANGE_STATE 7
143 #define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
144 #define SHIFT_LOCK_FLAG 16
145 #define SHIFT_CHANGE_TIMEOUT 20
146 #define CUSTOM_TIMEOUT_BIT 0x1
147 #define CUSTOM_HOLDKEY_BIT 0x2
148 #define HOLD_KEY_BLOCK_BIT 0x1
149 #define TIMEOUT_NONE (-1)
151 #define S_COVER_TIMEOUT 8000
152 #define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
153 #define DELAYED_INIT_WATING_TIME 60000 /* 1 minute */
155 #define LOCK_SCREEN_WATING_TIME 300 /* 0.3 second */
156 #define LONG_PRESS_INTERVAL 400 /* 0.4 seconds */
157 #define SAMPLING_INTERVAL 1 /* 1 sec */
158 #define BRIGHTNESS_CHANGE_STEP 10
159 #define LCD_ALWAYS_ON 0
160 #define ACCEL_SENSOR_ON 1
161 #define CONTINUOUS_SAMPLING 1
162 #define LCDOFF_TIMEOUT 300 /* milli second */
164 #define DIFF_TIMEVAL_MS(a, b) \
165 (((a.tv_sec * 1000000 + a.tv_usec) - \
166 (b.tv_sec * 1000000 + b.tv_usec)) \
169 static struct display_config display_conf = {
170 .lock_wait_time = LOCK_SCREEN_WATING_TIME,
171 .longpress_interval = LONG_PRESS_INTERVAL,
172 .lightsensor_interval = SAMPLING_INTERVAL,
173 .lcdoff_timeout = LCDOFF_TIMEOUT,
174 .pm_default_brightness = 80,
175 .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
176 .lcd_always_on = LCD_ALWAYS_ON,
178 .framerate_app = {0, 0, 0, 0},
179 .control_display = 0,
180 .powerkey_doublepress = 0,
181 .accel_sensor_on = ACCEL_SENSOR_ON,
182 .continuous_sampling = CONTINUOUS_SAMPLING,
183 .timeout_enable = true,
184 .input_support = true,
185 .lockcheck_timeout = 600,
186 .display_init_direction = DISPLAY_INIT_DIRECTION_HORIZONTAL,
187 .aod_enter_level = 40,
189 .touch_wakeup = false,
190 .display_on_usb_conn_changed = true,
191 .display_dpms_type = DISPLAY_DPMS_TYPE_WINDOW_MANAGER,
194 struct display_function_info display_info = {
195 .update_auto_brightness = NULL,
196 .set_autobrightness_min = NULL,
197 .reset_autobrightness_min = NULL,
198 .face_detection = NULL,
201 inline const struct display_config* get_var_display_config()
203 return &display_conf;
206 inline struct state* state_st(enum state_t state)
208 return &states[state];
211 static const char* __device_flags_to_string(enum device_flags flags)
214 if (flags & (LCD_ON_BY_GESTURE | LCD_OFF_BY_GESTURE))
216 else if (flags & (LCD_ON_BY_POWER_KEY | LCD_OFF_BY_POWER_KEY))
217 return POWER_KEY_STR;
218 else if (flags & (LCD_ON_BY_EVENT | LCD_OFF_BY_EVENT))
220 else if (flags & LCD_ON_BY_TOUCH)
222 else if (flags & LCD_OFF_BY_TIMEOUT)
224 else if (flags & LCD_OFF_BY_PROXIMITY)
226 else if (flags & LCD_OFF_BY_PALM)
232 bool touch_event_blocked(void)
234 return touch_blocked;
237 void lcd_on_procedure(int state, enum device_flags flag)
239 unsigned long flags = NORMAL_MODE;
240 display_plugin_get_device_flags(&flags);
244 * Display on procedure
246 * step 2. broadcast lcd on signal with cause
247 * step 3. set brightness
248 * step 4. set pmstate of vconf
249 * step 5. display on operate
251 * - b. TSP(touch screen) and touchkey enable
252 * step 6. broadcast lcd on complete signal
253 * step 7. key backlight enable
257 _I("[lcdstep] 0x%lx", flags);
259 /* send LCDOn dbus signal */
260 if (!lcdon_broadcast)
261 broadcast_lcd_on(SIGNAL_PRE, flags);
263 /* Update brightness level */
264 if (state == LCD_DIM)
265 display_backlight_set_brightness_by_dim_brightness();
266 else if (state == LCD_NORMAL)
267 display_backlight_update_by_default_brightness();
269 if (state == LCD_NORMAL)
270 set_setting_pmstate(S_NORMAL);
271 else if (state == LCD_DIM)
272 set_setting_pmstate(S_LCDDIM);
274 display_start_dependent_device(flags);
276 if (!lcdon_broadcast) {
277 broadcast_lcd_on(SIGNAL_POST, flags);
278 lcdon_broadcast = true;
281 if (CHECK_OPS(keyfilter_ops, backlight_enable))
282 keyfilter_ops->backlight_enable(true);
284 touch_blocked = false;
287 inline void lcd_off_procedure(enum device_flags flag)
289 unsigned long flags = NORMAL_MODE;
290 display_plugin_get_device_flags(&flags);
294 * Display off procedure
295 * step 0. enhance mode off using nofity (e.g mdnie, HBM, LBM)
296 * step 1. broadcast lcd off signal with cause
297 * step 2. set pmstate of vconf
298 * step 3. display off operate
300 * - b. TSP(touch screen) and touchkey disable
301 * step 4. broadcast lcd off complete siganl
302 * step 5. enter doze mode if it is enabled
304 _I("[lcdstep] 0x%lx", flags);
308 device_notify(DEVICE_NOTIFIER_LCD_OFF, NULL);
310 if (lcdon_broadcast) {
311 broadcast_lcd_off(SIGNAL_PRE, flags);
312 lcdon_broadcast = false;
317 touch_blocked = true;
319 set_setting_pmstate(S_LCDOFF);
321 if (CHECK_OPS(keyfilter_ops, backlight_enable))
322 keyfilter_ops->backlight_enable(false);
324 display_stop_dependent_device(flags);
326 broadcast_lcd_off(SIGNAL_POST, flags);
327 device_notify(DEVICE_NOTIFIER_LCD_OFF_COMPLETE, NULL);
332 static void del_state_cond(void *data, enum state_t state)
334 PmLockNode *tmp = NULL;
340 /* A passed data is a pid_t type data, not a 64bit data. */
341 pid = (pid_t)((intptr_t)data);
342 _I("delete prohibit %s condition by timeout (%d)", states[state].name, pid);
344 tmp = find_node(state, pid);
345 del_node(state, tmp);
346 set_unlock_time(pid, state);
348 /* Change state only when the two conditions below are satisfied.
349 * 1. There should be no running state-transition timer
350 * 2. Released lock is one of the pm_cur_state's lock
351 * This emulates already expired transition timer */
352 if (!display_state_transition_is_there_state_transition_timer() && (get_pm_cur_state() == state))
353 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
355 if (state == S_LCDOFF)
356 set_process_active(false, pid);
359 static gboolean del_normal_cond(void *data)
361 del_state_cond(data, S_NORMAL);
362 return G_SOURCE_REMOVE;
365 static gboolean del_dim_cond(void *data)
367 del_state_cond(data, S_LCDDIM);
368 return G_SOURCE_REMOVE;
371 static gboolean del_off_cond(void *data)
373 del_state_cond(data, S_LCDOFF);
374 return G_SOURCE_REMOVE;
377 /* get configurations from setting */
378 static int get_lcd_timeout_from_settings(void)
383 for (i = 0; i < S_END; i++) {
384 switch (states[i].state) {
386 get_run_timeout(&val);
389 get_dim_timeout(&val);
392 val = display_conf.lcdoff_timeout;
395 /* This state doesn't need to set time out. */
400 states[i].timeout = val;
402 _I("State(%s) timeout(%d) ms", states[i].name,
409 static void update_display_time(void)
411 int run_timeout, val;
413 /* first priority : custom timeout */
414 if (custom_normal_timeout > 0) {
415 states[S_NORMAL].timeout = custom_normal_timeout;
416 states[S_LCDDIM].timeout = custom_dim_timeout;
417 _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
418 custom_normal_timeout, custom_dim_timeout);
422 /* second priority : lock state */
423 if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
424 !get_lock_screen_bg_state()) {
425 /* timeout is different according to key or event. */
426 states[S_NORMAL].timeout = lock_screen_timeout;
427 _I("LOCK: Timeout(%d ms) is set by normal.",
428 lock_screen_timeout);
432 /* default setting */
433 get_run_timeout(&run_timeout);
436 * if the run_timeout is zero, it regards AlwaysOn state
438 if (run_timeout == 0 || display_conf.lcd_always_on) {
439 run_timeout = ALWAYS_ON_TIMEOUT;
440 _I("LCD always on.");
443 states[S_NORMAL].timeout = run_timeout;
445 get_dim_timeout(&val);
446 states[S_LCDDIM].timeout = val;
448 _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
449 _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
452 static void update_display_locktime(int time)
454 lock_screen_timeout = time;
455 update_display_time();
458 void set_dim_state(bool on)
460 _I("Dim state is %d.", on);
461 update_display_time();
462 states[get_pm_cur_state()].trans(EVENT_INPUT);
465 void lcd_on_direct(enum device_flags flags)
467 enum hal_device_power_transition_reason reason;
469 if (flags & LCD_ON_BY_POWER_KEY)
470 reason = HAL_DEVICE_POWER_TRANSITION_REASON_POWER_KEY;
471 else if (flags & LCD_ON_BY_TOUCH)
472 reason = HAL_DEVICE_POWER_TRANSITION_REASON_TOUCH_SCREEN;
474 reason = HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN;
476 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL, reason, NULL);
477 set_pm_cur_state(S_NORMAL);
479 _D("lcd is on directly");
480 gettimeofday(&lcdon_tv, NULL);
481 lcd_on_procedure(LCD_NORMAL, flags);
483 update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
486 static inline bool check_lcd_is_on(void)
488 if (display_panel_get_dpms_cached_state() != DPMS_ON)
494 static gboolean timer_refresh_cb(gpointer data)
498 /* state transition */
499 set_pm_old_state(get_pm_cur_state());
500 set_pm_cur_state(S_NORMAL);
501 st = &states[get_pm_cur_state()];
504 st->action(st->timeout);
509 int custom_lcdon(int timeout)
516 if (check_lcd_is_on() == false)
517 lcd_on_direct(LCD_ON_BY_GESTURE);
519 _I("Custom lcd on timeout(%d ms).", timeout);
520 if (set_custom_lcdon_timeout(timeout) == true)
521 update_display_time();
523 /* state transition */
524 set_pm_old_state(get_pm_cur_state());
525 set_pm_cur_state(S_NORMAL);
526 st = &states[get_pm_cur_state()];
530 st->action(st->timeout);
532 g_idle_add(timer_refresh_cb, NULL);
537 int custom_lcdoff(enum device_flags flag)
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)) {
547 * When another proccess is normal lock, device is received call then,
548 * call app can be changed to lcd state by proximity.
549 * If proximity is near then normal lock will be unlocked.
551 if (flag & LCD_OFF_BY_PROXIMITY) {
552 _I("custom lcd off by proximity, delete normal lock");
553 delete_condition(S_NORMAL);
555 _I("skip custom lcd off");
560 _I("custom lcd off by flag(%d)", flag);
561 if (display_panel_get_dpms_cached_state() == DPMS_ON)
562 lcd_off_procedure(flag);
564 if (set_custom_lcdon_timeout(0) == true)
565 update_display_time();
567 /* state transition */
568 set_pm_old_state(get_pm_cur_state());
569 set_pm_cur_state(S_LCDOFF);
570 st = &states[get_pm_cur_state()];
574 st->action(st->timeout);
579 int display_on_by_reason(const char *reason, int timeout)
585 str_len = strlen(reason);
587 if (!strncmp(reason, GESTURE_STR, str_len))
588 flag = LCD_ON_BY_GESTURE;
589 else if (!strncmp(reason, EVENT_STR, str_len))
590 flag = LCD_ON_BY_EVENT;
592 _E("Reason is unknown(%s)", reason);
597 _E("Cannot setting timeout %d", timeout);
601 if (check_lcd_is_on() == false)
604 _I("platform lcd on by %s (%d ms)", reason, timeout);
605 if (set_custom_lcdon_timeout(timeout) == true)
606 update_display_time();
608 /* state transition */
609 set_pm_old_state(get_pm_cur_state());
610 set_pm_cur_state(S_NORMAL);
611 st = &states[get_pm_cur_state()];
615 st->action(st->timeout);
620 int display_off_by_reason(const char *reason)
626 str_len = strlen(reason);
628 if (!strncmp(reason, GESTURE_STR, str_len)) {
629 check_processes(S_NORMAL);
630 check_processes(S_LCDDIM);
632 /* check holdkey block flag in lock node */
633 if (check_lock_condition(S_NORMAL) || check_lock_condition(S_LCDDIM)) {
634 _I("skip platform lcd off by gesture");
637 flag = LCD_OFF_BY_GESTURE;
638 } else if (!strncmp(reason, PALM_STR, str_len)) {
639 delete_condition(S_NORMAL);
640 delete_condition(S_LCDDIM);
642 flag = LCD_OFF_BY_PALM;
644 _E("Reason is unknown(%s)", reason);
648 _I("platform lcd off by %s", reason);
649 if (display_panel_get_dpms_cached_state() == DPMS_ON)
650 lcd_off_procedure(flag);
652 /* state transition */
653 set_pm_old_state(get_pm_cur_state());
654 set_pm_cur_state(S_LCDOFF);
655 st = &states[get_pm_cur_state()];
659 st->action(st->timeout);
664 static void default_proc_change_state_action(enum state_t next, int timeout)
668 set_pm_old_state(get_pm_cur_state());
669 set_pm_cur_state(next);
671 st = &states[get_pm_cur_state()];
673 if (st && st->action) {
675 st->action(st->timeout);
681 static int default_proc_change_state(unsigned int cond, pid_t pid)
685 next = GET_COND_STATE(cond);
686 _I("Change process(%d) state to %s.", pid, states[next].name);
690 if (check_lcd_is_on() == false)
691 lcd_on_direct(LCD_ON_BY_EVENT);
692 update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
693 default_proc_change_state_action(next, -1);
696 default_proc_change_state_action(next, -1);
699 if (display_panel_get_dpms_cached_state() == DPMS_ON) {
700 if (get_proximity_state() == SENSOR_PROXIMITY_NEAR)
701 lcd_off_procedure(LCD_OFF_BY_PROXIMITY);
703 lcd_off_procedure(LCD_OFF_BY_EVENT);
705 if (set_custom_lcdon_timeout(0))
706 update_display_time();
707 default_proc_change_state_action(next, -1);
710 _I("Dangerous requests.");
711 /* at first LCD_OFF and then goto sleep */
712 /* state transition */
713 default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
714 delete_condition(S_NORMAL);
715 delete_condition(S_LCDDIM);
716 delete_condition(S_LCDOFF);
717 if (lcdon_broadcast) {
718 _I("broadcast lcd off signal at non-lcd device");
719 broadcast_lcd_off(SIGNAL_PRE, 0);
720 broadcast_lcd_off(SIGNAL_POST, 0);
722 default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
732 static void proc_condition_lock(PMMsg *data)
735 guint cond_timeout_id = 0;
736 char pname[PATH_MAX];
737 pid_t pid = data->pid;
739 int holdkey_block, ret;
742 const char *lock_type = NULL;
744 state = GET_COND_STATE(data->cond);
745 if (state == S_START)
748 flags = GET_COND_FLAG(data->cond);
749 display_misc_get_process_name(pid, pname);
751 if ((state == S_LCDOFF) && (get_pm_cur_state() == S_SLEEP) &&
752 (pm_get_power_lock() == POWER_UNLOCK))
753 proc_change_state(data->cond, INTERNAL_LOCK_PM);
755 if (data->timeout > 0) {
756 /* To pass a pid_t data through the timer infrastructure
757 * without memory allocation, a pid_t data becomes typecast
758 * to intptr_t and void *(64bit) type. */
759 cond_timeout_id = g_timeout_add(
761 states[state].timeout_cb,
762 (void*)((intptr_t)pid));
763 if (!cond_timeout_id)
764 _E("Failed to register display timer.");
767 holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
769 tmp = find_node(state, pid);
771 tmp = add_node(state, pid, cond_timeout_id, holdkey_block);
773 _E("Failed to acquire lock, state: %d, pid: %d.", state, pid);
777 update_lock_timer(data, tmp, cond_timeout_id);
778 tmp->holdkey_block = holdkey_block;
781 if (state == S_LCDOFF)
782 set_process_active(true, pid);
784 _I("[%s] locked by %5d with %u ms", states[state].name, pid, data->timeout);
786 if (pid < INTERNAL_LOCK_BASE) {
788 if (state == S_LCDOFF)
789 lock_type = PM_LCDOFF_STR;
790 else if (state == S_LCDDIM)
791 lock_type = PM_LCDDIM_STR;
792 else if (state == S_NORMAL)
793 lock_type = PM_LCDON_STR;
796 /* power lock signal */
797 ret = gdbus_signal_emit(NULL,
798 DEVICED_PATH_DISPLAY,
799 DEVICED_INTERFACE_DISPLAY,
801 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
803 _E("Failed to send dbus signal PowerLock.");
806 _SD("be requested LOCK info pname(%s), holdkeyblock(%d) flags(%d)",
807 pname, holdkey_block, flags);
808 set_lock_time(pid, pname, state);
810 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
813 static void proc_condition_unlock(PMMsg *data)
815 pid_t pid = data->pid;
818 char pname[PATH_MAX];
822 const char *lock_type = NULL;
824 state = GET_COND_STATE(data->cond);
828 flags = GET_COND_FLAG(data->cond);
829 display_misc_get_process_name(pid, pname);
831 tmp = find_node(state, pid);
832 del_node(state, tmp);
834 if (state == S_LCDOFF)
835 set_process_active(false, pid);
837 _I("[%s] unlocked by %5d", states[state].name, pid);
839 if (pid < INTERNAL_LOCK_BASE) {
841 if (state == S_LCDOFF)
842 lock_type = PM_LCDOFF_STR;
843 else if (state == S_LCDDIM)
844 lock_type = PM_LCDDIM_STR;
845 else if (state == S_NORMAL)
846 lock_type = PM_LCDON_STR;
849 /* power unlock signal */
850 ret = gdbus_signal_emit(NULL,
851 DEVICED_PATH_DISPLAY,
852 DEVICED_INTERFACE_DISPLAY,
854 g_variant_new("(sii)", lock_type, pid, (int)data->timeout));
856 _E("Failed to send dbus signal PowerUnlock.");
860 _SD("be requested UNLOCK info pname(%s) flag(%d)", pname, flags);
861 set_unlock_time(pid, state);
863 device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)&value);
866 static int proc_condition(PMMsg *data)
870 if (IS_COND_REQUEST_LOCK(data->cond))
871 proc_condition_lock(data);
873 if (IS_COND_REQUEST_UNLOCK(data->cond))
874 proc_condition_unlock(data);
876 if (!display_conf.timeout_enable)
879 flags = GET_COND_FLAG(data->cond);
881 /* guard time for suspend */
882 if (get_pm_cur_state() == S_LCDOFF)
883 display_state_transition_reset_state_transition_timeout(states[S_LCDOFF].timeout);
885 if (flags & PM_FLAG_RESET_TIMER)
886 display_state_transition_reset_state_transition_timeout(states[get_pm_cur_state()].timeout);
889 if (!display_state_transition_is_there_state_transition_timer())
890 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
895 void update_lcdoff_source(int source)
900 case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
901 _I("LCD OFF by timeout.");
903 case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
904 _I("LCD OFF by powerkey.");
907 _E("Invalid value(%d).", source);
910 ret = vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
912 _E("Failed to set vconf value for lcd off source: %d", vconf_get_ext_errno());
915 /* SIGHUP signal handler
916 * For debug... print info to syslog
918 static void sig_hup(int signo)
920 _I("received sig hub %d", signo);
925 int check_lcdoff_direct(void)
927 int ret, lock, cradle;
930 if (get_pm_old_state() != S_NORMAL)
933 if (get_pm_cur_state() != S_LCDDIM)
936 if (!display_conf.dimming)
939 lock = __get_lock_screen_state();
940 if (lock != VCONFKEY_IDLE_LOCK)
943 hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
947 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
948 if (ret >= 0 && cradle == DOCK_SOUND)
951 _E("Failed to get vconf value for cradle status: %d", vconf_get_ext_errno());
953 _D("Goto LCDOFF direct: lock(%d) hdmi(%d) cradle(%d).", lock, hdmi_state, cradle);
959 * default transition function
962 * 3. call enter action function
964 static int default_trans(int evt)
966 struct state *st = &states[get_pm_cur_state()];
967 enum state_t next_state;
969 display_state_transition_get_next_transition_display_state(get_pm_cur_state(), &next_state, evt);
971 /* check conditions */
972 if (st->check && !st->check(get_pm_cur_state(), next_state)) {
973 /* There is a condition. */
974 _I("%s locked. Trans to %s failed.", states[get_pm_cur_state()].name,
975 states[next_state].name);
979 /* state transition */
980 set_pm_old_state(get_pm_cur_state());
981 set_pm_cur_state(next_state);
982 st = &states[get_pm_cur_state()];
986 if (get_pm_cur_state() == S_LCDOFF)
987 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
989 if ((get_pm_cur_state() == S_NORMAL) || (get_pm_cur_state() == S_LCDOFF))
990 if (set_custom_lcdon_timeout(0) == true)
991 update_display_time();
993 if (check_lcdoff_direct() == true) {
994 /* enter next state directly */
995 states[get_pm_cur_state()].trans(EVENT_TIMEOUT);
997 if ((get_pm_cur_state() == S_SLEEP)
998 && (is_emulator() == true || timeout_sleep_support == false))
1001 st->action(st->timeout);
1008 static gboolean lcd_on_expired(void *data)
1010 int lock_state, ret;
1012 if (lock_timeout_id)
1013 lock_timeout_id = 0;
1015 /* check state of lock */
1016 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1017 if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
1018 return G_SOURCE_REMOVE;
1020 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1022 /* lock screen is not launched yet, but lcd is on */
1023 if (check_lcd_is_on() == false)
1024 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1026 return G_SOURCE_REMOVE;
1029 static inline void stop_lock_timer(void)
1031 if (lock_timeout_id) {
1032 g_source_remove(lock_timeout_id);
1033 lock_timeout_id = 0;
1037 static void check_lock_screen(void)
1039 int lock_state, ret;
1043 /* check state of lock */
1044 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1045 if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
1048 /* Use time to check lock is done. */
1049 lock_timeout_id = g_timeout_add(display_conf.lock_wait_time,
1050 lcd_on_expired, NULL);
1053 /* default enter action function */
1054 static int default_action(int timeout)
1056 int wakeup_count = -1, pm_cur_state;
1059 static time_t last_update_time = 0;
1060 static int last_timeout = 0;
1061 struct timeval now_tv;
1064 bool lcd_paneloff_mode = false;
1066 if (status != DEVICE_OPS_STATUS_START) {
1067 _E("Display is not started.");
1071 if (get_pm_cur_state() != S_SLEEP) {
1072 if ((get_pm_cur_state() == S_NORMAL) &&
1073 lcdon_tv.tv_sec != 0) {
1074 gettimeofday(&now_tv, NULL);
1075 timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
1076 lcdon_tv.tv_sec = 0;
1078 /* set timer with current state timeout */
1079 display_state_transition_reset_state_transition_timeout(timeout);
1081 if (get_pm_cur_state() == S_NORMAL) {
1082 time(&last_update_time);
1083 last_timeout = timeout;
1085 _I("Timout set: %s state %d ms",
1086 states[get_pm_cur_state()].name, timeout);
1090 if ((get_pm_cur_state() != get_pm_old_state()) && (get_pm_cur_state() != S_SLEEP)) {
1091 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1092 power_get_wakeup_reason(), NULL);
1093 set_setting_pmstate(get_pm_cur_state());
1094 pm_cur_state = get_pm_cur_state();
1095 device_notify(DEVICE_NOTIFIER_LCD, (void *)&pm_cur_state);
1098 if ((get_pm_old_state() == S_NORMAL) && (get_pm_cur_state() != S_NORMAL)) {
1100 diff = difftime(now, last_update_time);
1101 _I("S_NORMAL is changed to %s (timeout=%d ms diff=%.0f s).",
1102 states[get_pm_cur_state()].name, last_timeout, diff);
1105 switch (get_pm_cur_state()) {
1108 * normal state : backlight on and restore
1109 * the previous brightness
1111 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1112 check_lock_screen();
1113 else if (get_pm_old_state() == S_LCDDIM)
1114 display_backlight_update_by_default_brightness();
1116 if (check_lcd_is_on() == false)
1117 lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
1121 display_backlight_get_custom_status(&custom_status);
1122 if ((get_pm_old_state() == S_NORMAL) && custom_status) {
1123 display_backlight_get_brightness(&brightness);
1124 display_backlight_set_custom_brightness(brightness);
1126 /* lcd dim state : dim the brightness */
1127 display_backlight_set_brightness_by_dim_brightness();
1129 if ((get_pm_old_state() == S_LCDOFF) || (get_pm_old_state() == S_SLEEP))
1130 lcd_on_procedure(LCD_DIM, NORMAL_MODE);
1134 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF)) {
1136 /* lcd off state : turn off the backlight */
1137 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1138 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1141 display_panel_get_lcd_paneloff_mode(&lcd_paneloff_mode);
1142 if (display_panel_get_dpms_cached_state() == DPMS_ON
1143 || lcd_paneloff_mode)
1144 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1148 if ((get_pm_old_state() != S_SLEEP) && (get_pm_old_state() != S_LCDOFF))
1151 if (display_panel_get_dpms_cached_state() == DPMS_ON)
1152 lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
1154 if (!pm_get_power_lock_support()) {
1155 /* sleep state : set system mode to SUSPEND */
1156 if (get_wakeup_count(&wakeup_count) < 0)
1157 _E("Wakeup count read error.");
1159 if (wakeup_count < 0) {
1160 _I("Wakup Event. Can not enter suspend mode.");
1164 if (set_wakeup_count(wakeup_count) < 0) {
1165 _E("Wakeup count write error.");
1175 #ifdef ENABLE_PM_LOG
1176 pm_history_save(PM_LOG_SLEEP, get_pm_cur_state());
1178 power_request_change_state(DEVICED_POWER_STATE_SLEEP, HAL_DEVICE_POWER_TRANSITION_REASON_DISPLAY_OFF_TIMEOUT);
1182 if (!pm_get_power_lock_support()) {
1184 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1190 * default check function
1192 * 0 : can't transit, others : transitable
1194 static int default_check(int curr, int next)
1198 makeup_trans_condition();
1200 trans_cond = get_trans_condition() & MASK_BIT;
1202 if (next == S_NORMAL) /* S_NORMAL is exceptional */
1207 trans_cond = trans_cond & MASK_NORMAL;
1210 trans_cond = trans_cond & MASK_DIM;
1213 trans_cond = trans_cond & MASK_OFF;
1220 if (trans_cond != 0) {
1225 return 1; /* transitable */
1228 static void default_saving_mode(int onoff)
1231 set_pm_status_flag(PWRSV_FLAG);
1233 clear_pm_status_flag(PWRSV_FLAG);
1235 if (get_pm_cur_state() == S_NORMAL)
1236 display_backlight_update_by_default_brightness();
1239 int poll_callback(int condition, PMMsg *data)
1241 static time_t last_t;
1244 if (status != DEVICE_OPS_STATUS_START) {
1245 _E("Display logic is not started.");
1249 if (condition == INPUT_POLL_EVENT) {
1250 if ((get_pm_cur_state() == S_LCDOFF) || (get_pm_cur_state() == S_SLEEP))
1251 _I("Input event signal at Display Off");
1253 if ((last_t != now) ||
1254 (get_pm_cur_state() == S_LCDOFF) ||
1255 (get_pm_cur_state() == S_SLEEP)) {
1256 states[get_pm_cur_state()].trans(EVENT_INPUT);
1261 if (condition == PM_CONTROL_EVENT) {
1262 proc_condition(data);
1264 if (IS_COND_REQUEST_CHANGE(data->cond))
1265 proc_change_state(data->cond, data->pid);
1271 static int update_setting(int key_idx, int val)
1276 case SETTING_TO_NORMAL:
1277 update_display_time();
1278 states[get_pm_cur_state()].trans(EVENT_INPUT);
1280 case SETTING_LOW_BATT:
1281 if (display_misc_is_low_battery_state(val)) {
1282 if (!(get_pm_status_flag() & CHRGR_FLAG))
1283 power_saving_func(true);
1284 set_pm_status_flag(LOWBT_FLAG);
1286 if (get_pm_status_flag() & PWRSV_FLAG)
1287 power_saving_func(false);
1288 clear_pm_status_flag(LOWBT_FLAG);
1289 clear_pm_status_flag(BRTCH_FLAG);
1290 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, false);
1292 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1295 case SETTING_CHARGING:
1297 if (get_pm_status_flag() & LOWBT_FLAG) {
1298 power_saving_func(false);
1299 clear_pm_status_flag(LOWBT_FLAG);
1301 set_pm_status_flag(CHRGR_FLAG);
1304 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
1307 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1308 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1310 if (display_misc_is_low_battery_state(bat_state)) {
1311 power_saving_func(true);
1312 set_pm_status_flag(LOWBT_FLAG);
1314 clear_pm_status_flag(CHRGR_FLAG);
1317 case SETTING_BRT_LEVEL:
1318 if (get_pm_status_flag() & PWRSV_FLAG) {
1319 set_pm_status_flag(BRTCH_FLAG);
1320 ret = vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
1322 _E("Failed to set vconf value for brightness changed in lpm: %d", vconf_get_ext_errno());
1323 _I("Brightness changed in low battery,"
1324 "escape dim state.");
1326 display_backlight_set_default_brightness(val);
1328 case SETTING_LOCK_SCREEN:
1329 set_lock_screen_state(val);
1330 if (val == VCONFKEY_IDLE_UNLOCK) {
1331 if (CHECK_OPS(keyfilter_ops, backlight_enable))
1332 keyfilter_ops->backlight_enable(false);
1335 /* LCD on if lock screen show before waiting time */
1336 if ((get_pm_cur_state() == S_NORMAL) &&
1337 val == VCONFKEY_IDLE_LOCK &&
1338 display_panel_get_dpms_cached_state() != DPMS_ON &&
1339 is_lcdon_blocked() == LCDON_BLOCK_NONE)
1340 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1342 update_display_time();
1343 if (get_pm_cur_state() == S_NORMAL)
1344 states[get_pm_cur_state()].trans(EVENT_INPUT);
1346 case SETTING_LOCK_SCREEN_BG:
1347 set_lock_screen_bg_state(val);
1348 update_display_time();
1349 if (get_pm_cur_state() == S_NORMAL)
1350 states[get_pm_cur_state()].trans(EVENT_INPUT);
1352 case SETTING_POWER_CUSTOM_BRIGHTNESS:
1353 if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
1354 display_backlight_set_custom_status(true);
1356 display_backlight_set_custom_status(false);
1365 static void check_seed_status(void)
1373 /* Charging check */
1374 if (fp_get_charging_status && (fp_get_charging_status(&tmp) == 0) && (tmp > 0))
1375 set_pm_status_flag(CHRGR_FLAG);
1377 ret = get_setting_brightness(&tmp);
1378 if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
1379 _I("Failed to read vconf value for brightness.");
1380 brt = display_conf.pm_default_brightness;
1381 if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS) {
1382 ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
1384 _E("Failed to set vconf value for lcd brightness: %d", vconf_get_ext_errno());
1388 _I("Set brightness(%d) from setting app.", tmp);
1389 display_backlight_set_default_brightness(tmp);
1390 display_backlight_set_brightness(tmp);
1392 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
1394 bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
1395 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
1397 if (display_misc_is_low_battery_state(bat_state)) {
1398 if (!(get_pm_status_flag() & CHRGR_FLAG)) {
1399 power_saving_func(true);
1400 set_pm_status_flag(LOWBT_FLAG);
1404 /* lock screen check */
1405 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
1408 _E("Failed to get vconf value for idle lock state: %d", vconf_get_ext_errno());
1410 set_lock_screen_state(lock_state);
1411 if (lock_state == VCONFKEY_IDLE_LOCK) {
1412 states[S_NORMAL].timeout = lock_screen_timeout;
1413 _I("LCD NORMAL timeout(%d ms) is set"
1414 " for lock screen.", lock_screen_timeout);
1420 static void init_lcd_operation(void)
1422 const struct device_ops *ops = NULL;
1424 ops = find_device("display");
1425 if (!check_default(ops))
1426 display_register_dependent_device(ops);
1428 ops = find_device("touchkey");
1429 if (!check_default(ops))
1430 display_register_dependent_device(ops);
1432 ops = find_device("touchscreen");
1433 if (!check_default(ops))
1434 display_register_dependent_device(ops);
1437 static void exit_lcd_operation(void)
1439 display_unregister_dependent_device();
1451 static const char *errMSG[INIT_END] = {
1452 [INIT_SETTING] = "setting init error",
1453 [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
1454 [INIT_POLL] = "input devices poll init error",
1455 [INIT_FIFO] = "FIFO poll init error",
1456 [INIT_DBUS] = "d-bus init error",
1459 int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
1461 if (on == 0 && dim == 0) {
1462 _I("LCD timeout changed: default setting");
1463 custom_normal_timeout = custom_dim_timeout = 0;
1464 } else if (on < 0 || dim < 0) {
1465 _E("Failed to set value(on=%d dim=%d).", on, dim);
1468 _I("LCD timeout changed: on=%ds dim=%ds", on, dim);
1469 custom_normal_timeout = SEC_TO_MSEC(on);
1470 custom_dim_timeout = SEC_TO_MSEC(dim);
1472 /* Apply new backlight time */
1473 update_display_time();
1474 if (get_pm_cur_state() == S_NORMAL)
1475 states[get_pm_cur_state()].trans(EVENT_INPUT);
1477 if (holdkey_block) {
1478 display_lock_set_custom_holdkey_block(true);
1479 _I("Hold key disabled.");
1481 display_lock_set_custom_holdkey_block(false);
1482 _I("Hold key enabled.");
1485 if (custom_change_name) {
1486 free(custom_change_name);
1487 custom_change_name = 0;
1490 if (custom_normal_timeout == 0 &&
1491 custom_dim_timeout == 0 &&
1495 custom_change_name = strndup(name, strlen(name));
1496 if (!custom_change_name) {
1497 _E("Failed to malloc.");
1498 custom_normal_timeout = custom_dim_timeout = 0;
1499 display_lock_set_custom_holdkey_block(false);
1506 void reset_lcd_timeout(GDBusConnection *conn,
1507 const gchar *sender,
1508 const gchar *unique_name,
1514 if (!custom_change_name)
1517 if (strcmp(sender, custom_change_name))
1520 _I("reset lcd timeout: Set default timeout. sender=%s", sender);
1522 free(custom_change_name);
1523 custom_change_name = 0;
1524 custom_normal_timeout = custom_dim_timeout = 0;
1525 display_lock_set_custom_holdkey_block(false);
1527 update_display_time();
1528 if (get_pm_cur_state() == S_NORMAL)
1529 states[get_pm_cur_state()].trans(EVENT_INPUT);
1532 static int delayed_init_done(void *data)
1534 static bool done = false;
1543 _I("Booting done, release booting lock.");
1544 if (disp_plgn->pm_unlock_internal) {
1545 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
1546 disp_plgn->pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
1552 static gboolean delayed_dpms_init_done(gpointer data)
1556 if (!display_panel_init_dpms())
1557 return G_SOURCE_CONTINUE;
1559 switch (get_pm_cur_state()) {
1562 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1563 if (display_conf.timeout_enable) {
1564 timeout = states[S_NORMAL].timeout;
1565 /* check minimun lcd on time */
1566 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1567 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1568 display_state_transition_reset_state_transition_timeout(timeout);
1572 lcd_off_procedure(LCD_OFF_BY_EVENT);
1573 timeout = display_conf.lcdoff_timeout;
1574 display_state_transition_reset_state_transition_timeout(timeout);
1580 return G_SOURCE_REMOVE;
1583 static void add_timer_for_dpms_init(void)
1585 guint id = g_timeout_add(500/* milliseconds */, delayed_dpms_init_done, NULL);
1587 _E("Failed to add display_panel_init_dpms timeout.");
1590 static void init_display_states(void *data)
1592 struct display_plugin *dp = (struct display_plugin *) data;
1593 for(int i = 0; i < S_END; i++)
1594 dp->display_states[i] = &states[i];
1597 * Power manager Main
1600 static int display_probe(void *data)
1603 struct display_plugin *dp = (struct display_plugin *) data;
1606 dp->config = &display_conf;
1607 init_display_states(dp);
1608 setup_display_plugin_backlight_ops(dp);
1609 dp->delete_state_cond = del_state_cond;
1610 dp->set_dim_state = set_dim_state;
1611 dp->get_device_flags = NULL;
1612 setup_display_plugin_backlight_ops(dp);
1615 * load display service
1616 * if there is no display shared library,
1617 * deviced does not provide any method and function of display.
1619 ret = display_service_load();
1623 /* display_plugin instance initialization */
1624 init_pm_internal(data);
1625 disp_plgn->device_flags_to_string = __device_flags_to_string;
1627 if (battery_plgn->handle) {
1628 fp_get_charging_status = dlsym(battery_plgn->handle, "get_charging_status");
1629 if (!fp_get_charging_status)
1630 _E("Failed to obtain address of get_charging_status");
1632 _I("There is no battery module.");
1637 static int input_init_handler(void)
1639 if (!display_conf.input_support)
1640 remove_device_by_devname("input");
1645 static int power_resume_from_echomem_callback(void *data)
1647 system_wakeup_flag = true;
1648 if (check_wakeup_src() == EVENT_DEVICE)
1649 /* system waked up by devices */
1650 states[get_pm_cur_state()].trans(EVENT_DEVICE);
1652 /* system waked up by user input */
1653 states[get_pm_cur_state()].trans(EVENT_INPUT);
1658 static int poweroff_triggered_callback(void *udata)
1660 int val = (int)(intptr_t) udata;
1663 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
1664 clear_pm_status_flag(PWROFF_FLAG);
1666 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
1667 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
1668 set_pm_status_flag(PWROFF_FLAG);
1675 static void esd_action(void)
1677 const struct device_ops *touchscreen_ops = NULL;
1681 touchscreen_ops = find_device("touchscreen");
1683 if (!check_default(touchscreen_ops))
1684 touchscreen_ops->stop(NORMAL_MODE);
1685 display_panel_set_panel_state_by_off_state(NORMAL_MODE);
1686 display_panel_set_panel_state_by_on_state(NORMAL_MODE);
1687 if (!check_default(touchscreen_ops))
1688 touchscreen_ops->start(NORMAL_MODE);
1691 static void lcd_uevent_changed(struct udev_device *dev)
1693 const char *devpath;
1696 devpath = udev_device_get_devpath(dev);
1700 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
1701 action = udev_device_get_action(dev);
1702 if (!strcmp(action, UDEV_CHANGE))
1707 static const struct uevent_handler lcd_uevent_ops = {
1708 .subsystem = LCD_EVENT_SUBSYSTEM,
1709 .uevent_func = lcd_uevent_changed,
1713 static void display_init(void *data)
1716 unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
1719 _I("Start power manager.");
1721 signal(SIGHUP, sig_hup);
1723 power_saving_func = default_saving_mode;
1725 /* load configutation */
1726 ret = display_load_config(&display_conf);
1728 _W("Failed to load '%s', use default value: %d",
1729 DISPLAY_CONF_FILE, ret);
1731 register_kernel_uevent_control(&lcd_uevent_ops);
1733 register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1734 register_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1735 register_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1736 register_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1737 register_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1738 register_notifier(DEVICE_NOTIFIER_POWEROFF_TRIGGERED, poweroff_triggered_callback);
1740 init_save_userlock();
1742 for (i = INIT_SETTING; i < INIT_END; i++) {
1745 ret = init_setting(update_setting);
1747 case INIT_INTERFACE:
1748 if (display_conf.timeout_enable)
1749 get_lcd_timeout_from_settings();
1750 ret = init_sysfs(flags);
1754 ret = input_init_handler();
1756 pm_lock_detector_init();
1760 ret = init_pm_dbus();
1764 _E("Failed to init: %s", errMSG[i]);
1769 if (i == INIT_END) {
1770 display_ops_init(NULL);
1771 #ifdef ENABLE_PM_LOG
1774 init_lcd_operation();
1775 check_seed_status();
1777 /* In smd test, TSP should be turned off if display panel is not existed. */
1778 if (display_panel_get_dpms_cached_state() == -ENOENT) {
1779 _I("Display panel is not existed.");
1780 lcd_direct_control(DPMS_OFF, NORMAL_MODE);
1781 exit_lcd_operation();
1784 /* wm_ready needs to be checked
1785 * since display manager can be launched later than deviced.
1786 * In the case, display cannot be turned on at the first booting */
1787 // wm_ready = check_wm_ready();
1788 if (display_panel_init_dpms()) {
1789 if (is_lcdon_blocked() != LCDON_BLOCK_NONE)
1790 lcd_off_procedure(LCD_OFF_BY_EVENT);
1792 lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
1794 add_timer_for_dpms_init();
1797 if (display_conf.lcd_always_on) {
1798 _I("LCD always on.");
1799 display_state_transition_set_transition_table_display_state(S_NORMAL, S_NORMAL, EVENT_TIMEOUT);
1802 if (flags & WITHOUT_STARTNOTI) { /* start without noti */
1803 _I("Start Power managing without noti");
1804 power_request_change_state_strict(DEVICED_POWER_STATE_SLEEP, DEVICED_POWER_STATE_NORMAL,
1805 HAL_DEVICE_POWER_TRANSITION_REASON_UNKNOWN, NULL);
1807 * Lock lcd off until booting is done.
1808 * deviced guarantees all booting script is executing.
1809 * Last script of booting unlocks this suspend blocking state.
1811 if (disp_plgn->pm_lock_internal)
1812 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
1813 STAY_CUR_STATE, DELAYED_INIT_WATING_TIME);
1815 /* Initial display state right after the booting done */
1816 if (is_lcdon_blocked())
1817 set_pm_cur_state(S_LCDOFF);
1819 set_pm_cur_state(S_NORMAL);
1820 ret = vconf_set_int(VCONFKEY_PM_STATE, get_pm_cur_state());
1822 _E("Failed to set vconf value for pm cur state: %d", vconf_get_ext_errno());
1824 status = DEVICE_OPS_STATUS_START;
1825 if (display_conf.timeout_enable) {
1826 timeout = states[S_NORMAL].timeout;
1827 /* check minimun lcd on time */
1828 if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
1829 timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
1831 if (disp_plgn->pm_lock_internal)
1832 disp_plgn->pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
1833 STAY_CUR_STATE, timeout);
1838 if (display_conf.input_support)
1839 if (CHECK_OPS(keyfilter_ops, init))
1840 keyfilter_ops->init();
1842 set_display_init_direction(display_conf.display_init_direction);
1846 static void display_exit(void *data)
1850 status = DEVICE_OPS_STATUS_STOP;
1852 /* Set current state to S_NORMAL */
1853 set_pm_cur_state(S_NORMAL);
1854 set_setting_pmstate(get_pm_cur_state());
1855 /* timeout is not needed */
1856 display_state_transition_reset_state_transition_timeout(TIMEOUT_NONE);
1858 if (CHECK_OPS(keyfilter_ops, exit))
1859 keyfilter_ops->exit();
1861 unregister_kernel_uevent_control(&lcd_uevent_ops);
1863 display_ops_exit(NULL);
1865 for (i = i - 1; i >= INIT_SETTING; i--) {
1870 case INIT_INTERFACE:
1874 unregister_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
1875 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_BACKGROUND, display_app_background);
1876 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_FOREGROUND, display_app_foreground);
1877 unregister_notifier(DEVICE_NOTIFIER_APPLICATION_TERMINATED, display_app_terminated);
1878 unregister_notifier(DEVICE_NOTIFIER_POWER_RESUME_FROM_ECHO_MEM, power_resume_from_echomem_callback);
1884 exit_lcd_operation();
1885 free_lock_info_list();
1887 /* free display service */
1888 display_service_free();
1890 _I("Stop power manager.");
1893 static int display_start(enum device_flags flags)
1895 const struct display_ops *enhance_ops = NULL;
1899 if (flags & NORMAL_MODE) {
1900 if (flags & LCD_PANEL_OFF_MODE)
1902 display_panel_set_panel_state_by_standby_state(true);
1905 display_panel_set_panel_state_by_on_state(flags);
1906 FIND_DISPLAY(enhance_ops, "enhance");
1907 if (enhance_ops && enhance_ops->func)
1908 enhance_ops->func(RESTORE_ENHANCE_OUTDOOR, &on);
1912 /* CORE LOGIC MODE */
1913 if (!(flags & CORE_LOGIC_MODE))
1916 if (status == DEVICE_OPS_STATUS_START)
1919 if (display_probe(NULL) < 0)
1927 static int display_stop(enum device_flags flags)
1930 if (flags & NORMAL_MODE || flags & FORCE_OFF_MODE) {
1931 display_panel_set_panel_state_by_off_state(flags);
1935 /* CORE LOGIC MODE */
1936 if (!(flags & CORE_LOGIC_MODE))
1939 if (status == DEVICE_OPS_STATUS_STOP)
1947 static int display_status(void)
1952 static const struct device_ops display_plugin_device_ops = {
1953 .disable_auto_init = true,
1954 DECLARE_NAME_LEN("display-plugin"),
1955 .probe = display_probe,
1956 .init = display_init,
1957 .exit = display_exit,
1958 .start = display_start,
1959 .stop = display_stop,
1960 .status = display_status,
1963 DEVICE_OPS_REGISTER(&display_plugin_device_ops)
1965 static void __CONSTRUCTOR__ initialize(void)
1967 disp_plgn = get_var_display_plugin();
1969 _E("Failed to get display plugin variable.");
1971 backlight_ops = get_var_backlight_ops();
1973 _E("Failed to get backlight operator variable.");
1975 battery_plgn = get_var_battery_plugin();
1977 _E("Failed to get battery plugin variable.");