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.
23 #include <sys/types.h>
32 #include "device-interface.h"
35 #include "device-node.h"
41 typedef struct _PMSys PMSys;
46 int (*sys_power_state) (PMSys *, int);
47 int (*sys_power_lock) (PMSys *, int);
48 int (*sys_get_power_lock_support) (PMSys *);
49 int (*sys_get_lcd_power) (PMSys *);
50 int (*bl_onoff) (PMSys *, int);
51 int (*bl_brt) (PMSys *, int);
55 struct _backlight_ops backlight_ops;
56 struct _touch_ops touch_ops;
57 struct _power_ops power_ops;
59 static char *touchscreen_node;
60 static char *touchkey_node;
62 #ifdef ENABLE_X_LCD_ONOFF
64 static bool x_dpms_enable = false;
67 static int power_lock_support = -1;
68 static bool custom_status = false;
69 static int custom_brightness = 0;
70 static int force_brightness = 0;
72 static int _bl_onoff(PMSys *p, int on)
76 cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY);
77 return device_set_property(DEVICE_TYPE_DISPLAY, cmd, on);
80 static int _bl_brt(PMSys *p, int brightness)
86 if (force_brightness > 0 && brightness != p->dim_brt) {
87 _I("brightness(%d), force brightness(%d)",
88 brightness, force_brightness);
89 brightness = force_brightness;
92 cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
93 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev);
95 /* Update new brightness to vconf */
96 if (!ret && (brightness != prev)) {
97 vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, brightness);
100 /* Update device brightness */
101 ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brightness);
103 _I("set brightness %d, %d", brightness, ret);
108 static int _sys_power_state(PMSys *p, int state)
110 if (state < POWER_STATE_SUSPEND || state > POWER_STATE_POST_RESUME)
112 return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_STATE, state);
115 static int _sys_power_lock(PMSys *p, int state)
117 if (state != POWER_LOCK && state != POWER_UNLOCK)
119 return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_LOCK, state);
122 static int _sys_get_power_lock_support(PMSys *p)
127 ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_LOCK_SUPPORT,
139 static int _sys_get_lcd_power(PMSys *p)
145 cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY);
146 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &value);
148 if (ret < 0 || value < 0)
154 static void _init_bldev(PMSys *p, unsigned int flags)
159 p->bl_onoff = _bl_onoff;
160 #ifdef ENABLE_X_LCD_ONOFF
161 if (flags & FLAG_X_DPMS) {
162 p->bl_onoff = pm_x_set_lcd_backlight;
163 x_dpms_enable = true;
168 static void _init_pmsys(PMSys *p)
172 val = getenv("PM_SYS_DIMBRT");
173 p->dim_brt = (val ? atoi(val) : 0);
174 p->sys_power_state = _sys_power_state;
175 p->sys_power_lock = _sys_power_lock;
176 p->sys_get_power_lock_support = _sys_get_power_lock_support;
177 p->sys_get_lcd_power = _sys_get_lcd_power;
180 static void *_system_suspend_cb(void *data)
184 _I("enter system suspend");
185 if (pmsys && pmsys->sys_power_state)
186 ret = pmsys->sys_power_state(pmsys, POWER_STATE_SUSPEND);
191 _E("Failed to system suspend! %d", ret);
196 static int system_suspend(void)
201 ret = pthread_create(&pth, 0, _system_suspend_cb, (void*)NULL);
203 _E("pthread creation failed!, suspend directly!");
204 _system_suspend_cb((void*)NULL);
206 pthread_join(pth, NULL);
212 static int system_pre_suspend(void)
214 _I("enter system pre suspend");
215 if (pmsys && pmsys->sys_power_state)
216 return pmsys->sys_power_state(pmsys, POWER_STATE_PRE_SUSPEND);
221 static int system_post_resume(void)
223 _I("enter system post resume");
224 if (pmsys && pmsys->sys_power_state)
225 return pmsys->sys_power_state(pmsys, POWER_STATE_POST_RESUME);
230 static int system_power_lock(void)
232 _I("system power lock");
233 if (pmsys && pmsys->sys_power_lock)
234 return pmsys->sys_power_lock(pmsys, POWER_LOCK);
239 static int system_power_unlock(void)
241 _I("system power unlock");
242 if (pmsys && pmsys->sys_power_lock)
243 return pmsys->sys_power_lock(pmsys, POWER_UNLOCK);
248 static int system_get_power_lock_support(void)
252 if (power_lock_support == -1) {
253 if (pmsys && pmsys->sys_get_power_lock_support) {
254 value = pmsys->sys_get_power_lock_support(pmsys);
256 _I("system power lock : support");
257 power_lock_support = 1;
259 _E("system power lock : not support");
260 power_lock_support = 0;
263 _E("system power lock : read fail");
264 power_lock_support = 0;
268 return power_lock_support;
271 static int get_lcd_power(void)
273 if (pmsys && pmsys->sys_get_lcd_power) {
274 return pmsys->sys_get_lcd_power(pmsys);
280 static int backlight_hbm_off(void)
287 ret = device_get_property(DEVICE_TYPE_DISPLAY,
288 PROP_DISPLAY_HBM_CONTROL, &state);
293 ret = device_set_property(DEVICE_TYPE_DISPLAY,
294 PROP_DISPLAY_HBM_CONTROL, 0);
303 static int touchscreen_on(void)
307 if (!touchscreen_node)
310 ret = sys_set_int(touchscreen_node, TOUCH_ON);
312 _E("Failed to on touch screen!");
318 static int touchscreen_off(void)
322 if (!touchscreen_node)
325 if (display_conf.alpm_on == true)
328 ret = sys_set_int(touchscreen_node, TOUCH_OFF);
330 _E("Failed to off touch screen!");
335 static int touchkey_on(void)
342 ret = sys_set_int(touchkey_node, TOUCH_ON);
344 _E("Failed to on touch key!");
350 static int touchkey_off(void)
357 ret = sys_set_int(touchkey_node, TOUCH_OFF);
359 _E("Failed to off touch key!");
364 static int backlight_on(void)
371 if (!pmsys || !pmsys->bl_onoff)
374 for (i = 0; i < PM_LCD_RETRY_CNT; i++) {
375 ret = pmsys->bl_onoff(pmsys, STATUS_ON);
376 if (get_lcd_power() == PM_LCD_POWER_ON) {
378 pm_history_save(PM_LOG_LCD_ON, pm_cur_state);
383 pm_history_save(PM_LOG_LCD_ON_FAIL, pm_cur_state);
385 #ifdef ENABLE_X_LCD_ONOFF
386 _E("Failed to LCD on, through xset");
388 _E("Failed to LCD on, through OAL");
397 static int backlight_off(void)
404 if (!pmsys || !pmsys->bl_onoff)
407 for (i = 0; i < PM_LCD_RETRY_CNT; i++) {
408 #ifdef ENABLE_X_LCD_ONOFF
409 if (x_dpms_enable == false)
412 ret = pmsys->bl_onoff(pmsys, STATUS_OFF);
413 if (get_lcd_power() == PM_LCD_POWER_OFF) {
415 pm_history_save(PM_LOG_LCD_OFF, pm_cur_state);
420 pm_history_save(PM_LOG_LCD_OFF_FAIL, pm_cur_state);
422 #ifdef ENABLE_X_LCD_ONOFF
423 _E("Failed to LCD off, through xset");
425 _E("Failed to LCD off, through OAL");
433 static int backlight_dim(void)
436 if (pmsys && pmsys->bl_brt) {
437 ret = pmsys->bl_brt(pmsys, pmsys->dim_brt);
440 pm_history_save(PM_LOG_LCD_DIM, pm_cur_state);
442 pm_history_save(PM_LOG_LCD_DIM_FAIL, pm_cur_state);
448 static int set_custom_status(bool on)
454 static bool get_custom_status(void)
456 return custom_status;
459 static int save_custom_brightness(void)
461 int cmd, ret, brightness;
463 cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
464 ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brightness);
466 custom_brightness = brightness;
471 static int custom_backlight_update(void)
475 if (custom_brightness < PM_MIN_BRIGHTNESS ||
476 custom_brightness > PM_MAX_BRIGHTNESS)
479 if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) {
480 ret = backlight_dim();
481 } else if (pmsys && pmsys->bl_brt) {
482 _I("custom brightness restored! %d", custom_brightness);
483 ret = pmsys->bl_brt(pmsys, custom_brightness);
489 static int set_force_brightness(int level)
491 if (level < 0 || level > PM_MAX_BRIGHTNESS)
494 force_brightness = level;
499 static int backlight_update(void)
503 if (hbm_get_state != NULL && hbm_get_state() == true) {
504 _I("HBM is on, backlight is not updated!");
508 if (get_custom_status()) {
509 _I("custom brightness mode! brt no updated");
512 if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) {
513 ret = backlight_dim();
514 } else if (pmsys && pmsys->bl_brt) {
515 ret = pmsys->bl_brt(pmsys, pmsys->def_brt);
520 static int backlight_standby(void)
523 if (!pmsys || !pmsys->bl_onoff)
526 if (get_lcd_power() == PM_LCD_POWER_ON) {
528 ret = pmsys->bl_onoff(pmsys, STATUS_STANDBY);
534 static int set_default_brt(int level)
539 if (level < PM_MIN_BRIGHTNESS || level > PM_MAX_BRIGHTNESS)
540 level = PM_DEFAULT_BRIGHTNESS;
541 pmsys->def_brt = level;
548 static int check_wakeup_src(void)
551 * return wackeup source. user input or device interrupts? (EVENT_DEVICE or EVENT_INPUT)
558 backlight_ops.off = backlight_off;
559 backlight_ops.dim = backlight_dim;
560 backlight_ops.on = backlight_on;
561 backlight_ops.update = backlight_update;
562 backlight_ops.standby = backlight_standby;
563 backlight_ops.hbm_off = backlight_hbm_off;
564 backlight_ops.set_default_brt = set_default_brt;
565 backlight_ops.get_lcd_power = get_lcd_power;
566 backlight_ops.set_custom_status = set_custom_status;
567 backlight_ops.get_custom_status = get_custom_status;
568 backlight_ops.save_custom_brightness = save_custom_brightness;
569 backlight_ops.custom_update = custom_backlight_update;
570 backlight_ops.set_force_brightness = set_force_brightness;
572 touch_ops.screen_on = touchscreen_on;
573 touch_ops.screen_off = touchscreen_off;
574 touch_ops.key_on = touchkey_on;
575 touch_ops.key_off = touchkey_off;
577 power_ops.suspend = system_suspend;
578 power_ops.pre_suspend = system_pre_suspend;
579 power_ops.post_resume = system_post_resume;
580 power_ops.power_lock = system_power_lock;
581 power_ops.power_unlock = system_power_unlock;
582 power_ops.get_power_lock_support = system_get_power_lock_support;
583 power_ops.check_wakeup_src = check_wakeup_src;
586 int init_sysfs(unsigned int flags)
590 pmsys = (PMSys *) malloc(sizeof(PMSys));
592 _E("Not enough memory to alloc PM Sys");
596 memset(pmsys, 0x0, sizeof(PMSys));
599 _init_bldev(pmsys, flags);
601 if (pmsys->bl_onoff == NULL || pmsys->sys_power_state == NULL) {
602 _E("We have no managable resource to reduce the power consumption");
606 touchscreen_node = getenv("PM_TOUCHSCREEN");
607 _D("touchscreen node : %s", touchscreen_node);
609 touchkey_node = getenv("PM_TOUCHKEY");
610 _D("touchkey node : %s", touchkey_node);
621 fd = open("/tmp/sem.pixmap_1", O_RDONLY);
623 _E("X server disable");