Initialize Tizen 2.3
[framework/system/deviced.git] / src / display / device-interface.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdbool.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <limits.h>
29
30 #include "core/log.h"
31 #include "util.h"
32 #include "device-interface.h"
33 #include "vconf.h"
34 #include "core.h"
35 #include "device-node.h"
36 #include "weaks.h"
37
38 #define TOUCH_ON        1
39 #define TOUCH_OFF       0
40
41 typedef struct _PMSys PMSys;
42 struct _PMSys {
43         int def_brt;
44         int dim_brt;
45
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);
52 };
53
54 static PMSys *pmsys;
55 struct _backlight_ops backlight_ops;
56 struct _touch_ops touch_ops;
57 struct _power_ops power_ops;
58
59 static char *touchscreen_node;
60 static char *touchkey_node;
61
62 #ifdef ENABLE_X_LCD_ONOFF
63 #include "x-lcd-on.c"
64 static bool x_dpms_enable = false;
65 #endif
66
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;
71
72 static int _bl_onoff(PMSys *p, int on)
73 {
74         int cmd;
75
76         cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY);
77         return device_set_property(DEVICE_TYPE_DISPLAY, cmd, on);
78 }
79
80 static int _bl_brt(PMSys *p, int brightness)
81 {
82         int ret = -1;
83         int cmd;
84         int prev;
85
86         if (force_brightness > 0 && brightness != p->dim_brt) {
87                 _I("brightness(%d), force brightness(%d)",
88                     brightness, force_brightness);
89                 brightness = force_brightness;
90         }
91
92         cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
93         ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev);
94
95         /* Update new brightness to vconf */
96         if (!ret && (brightness != prev)) {
97                 vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, brightness);
98         }
99
100         /* Update device brightness */
101         ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brightness);
102
103         _I("set brightness %d, %d", brightness, ret);
104
105         return ret;
106 }
107
108 static int _sys_power_state(PMSys *p, int state)
109 {
110         if (state < POWER_STATE_SUSPEND || state > POWER_STATE_POST_RESUME)
111                 return 0;
112         return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_STATE, state);
113 }
114
115 static int _sys_power_lock(PMSys *p, int state)
116 {
117         if (state != POWER_LOCK && state != POWER_UNLOCK)
118                 return -1;
119         return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_LOCK, state);
120 }
121
122 static int _sys_get_power_lock_support(PMSys *p)
123 {
124         int value = 0;
125         int ret = -1;
126
127         ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_LOCK_SUPPORT,
128             &value);
129
130         if (ret < 0)
131                 return -1;
132
133         if (value < 0)
134                 return 0;
135
136         return value;
137 }
138
139 static int _sys_get_lcd_power(PMSys *p)
140 {
141         int value = -1;
142         int ret = -1;
143         int cmd;
144
145         cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY);
146         ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &value);
147
148         if (ret < 0 || value < 0)
149                 return -1;
150
151         return value;
152 }
153
154 static void _init_bldev(PMSys *p, unsigned int flags)
155 {
156         int ret;
157         //_update_curbrt(p);
158         p->bl_brt = _bl_brt;
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;
164         }
165 #endif
166 }
167
168 static void _init_pmsys(PMSys *p)
169 {
170         char *val;
171
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;
178 }
179
180 static void *_system_suspend_cb(void *data)
181 {
182         int ret;
183
184         _I("enter system suspend");
185         if (pmsys && pmsys->sys_power_state)
186                 ret = pmsys->sys_power_state(pmsys, POWER_STATE_SUSPEND);
187         else
188                 ret = -EFAULT;
189
190         if (ret < 0)
191                 _E("Failed to system suspend! %d", ret);
192
193         return (void *)ret;
194 }
195
196 static int system_suspend(void)
197 {
198         pthread_t pth;
199         int ret;
200
201         ret = pthread_create(&pth, 0, _system_suspend_cb, (void*)NULL);
202         if (ret < 0) {
203                 _E("pthread creation failed!, suspend directly!");
204                 _system_suspend_cb((void*)NULL);
205         } else {
206                 pthread_join(pth, NULL);
207         }
208
209         return 0;
210 }
211
212 static int system_pre_suspend(void)
213 {
214         _I("enter system pre suspend");
215         if (pmsys && pmsys->sys_power_state)
216                 return pmsys->sys_power_state(pmsys, POWER_STATE_PRE_SUSPEND);
217
218         return 0;
219 }
220
221 static int system_post_resume(void)
222 {
223         _I("enter system post resume");
224         if (pmsys && pmsys->sys_power_state)
225                 return pmsys->sys_power_state(pmsys, POWER_STATE_POST_RESUME);
226
227         return 0;
228 }
229
230 static int system_power_lock(void)
231 {
232         _I("system power lock");
233         if (pmsys && pmsys->sys_power_lock)
234                 return pmsys->sys_power_lock(pmsys, POWER_LOCK);
235
236         return 0;
237 }
238
239 static int system_power_unlock(void)
240 {
241         _I("system power unlock");
242         if (pmsys && pmsys->sys_power_lock)
243                 return pmsys->sys_power_lock(pmsys, POWER_UNLOCK);
244
245         return 0;
246 }
247
248 static int system_get_power_lock_support(void)
249 {
250         int value = -1;
251
252         if (power_lock_support == -1) {
253                 if (pmsys && pmsys->sys_get_power_lock_support) {
254                         value = pmsys->sys_get_power_lock_support(pmsys);
255                         if (value == 1) {
256                                         _I("system power lock : support");
257                                         power_lock_support = 1;
258                         } else {
259                                 _E("system power lock : not support");
260                                 power_lock_support = 0;
261                         }
262                 } else {
263                         _E("system power lock : read fail");
264                         power_lock_support = 0;
265                 }
266         }
267
268         return power_lock_support;
269 }
270
271 static int get_lcd_power(void)
272 {
273         if (pmsys && pmsys->sys_get_lcd_power) {
274                 return pmsys->sys_get_lcd_power(pmsys);
275         }
276
277         return -1;
278 }
279
280 static int backlight_hbm_off(void)
281 {
282 #ifdef MICRO_DD
283         return -EINVAL;
284 #else
285         int ret, state;
286
287         ret = device_get_property(DEVICE_TYPE_DISPLAY,
288             PROP_DISPLAY_HBM_CONTROL, &state);
289         if (ret < 0)
290                 return ret;
291
292         if (state) {
293                 ret = device_set_property(DEVICE_TYPE_DISPLAY,
294                     PROP_DISPLAY_HBM_CONTROL, 0);
295                 if (ret < 0)
296                         return ret;
297                 _D("hbm is off!");
298         }
299         return 0;
300 #endif
301 }
302
303 static int touchscreen_on(void)
304 {
305         int ret;
306
307         if (!touchscreen_node)
308                 return -ENOENT;
309
310         ret = sys_set_int(touchscreen_node, TOUCH_ON);
311         if (ret < 0)
312                 _E("Failed to on touch screen!");
313
314         return ret;
315
316 }
317
318 static int touchscreen_off(void)
319 {
320         int ret;
321
322         if (!touchscreen_node)
323                 return -ENOENT;
324
325         if (display_conf.alpm_on == true)
326                 return -EPERM;
327
328         ret = sys_set_int(touchscreen_node, TOUCH_OFF);
329         if (ret < 0)
330                 _E("Failed to off touch screen!");
331
332         return ret;
333 }
334
335 static int touchkey_on(void)
336 {
337         int ret;
338
339         if (!touchkey_node)
340                 return -ENOENT;
341
342         ret = sys_set_int(touchkey_node, TOUCH_ON);
343         if (ret < 0)
344                 _E("Failed to on touch key!");
345
346         return ret;
347
348 }
349
350 static int touchkey_off(void)
351 {
352         int ret;
353
354         if (!touchkey_node)
355                 return -ENOENT;
356
357         ret = sys_set_int(touchkey_node, TOUCH_OFF);
358         if (ret < 0)
359                 _E("Failed to off touch key!");
360
361         return ret;
362 }
363
364 static int backlight_on(void)
365 {
366         int ret = -1;
367         int i;
368
369         _D("LCD on");
370
371         if (!pmsys || !pmsys->bl_onoff)
372                 return -1;
373
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) {
377 #ifdef ENABLE_PM_LOG
378                         pm_history_save(PM_LOG_LCD_ON, pm_cur_state);
379 #endif
380                         break;
381                 } else {
382 #ifdef ENABLE_PM_LOG
383                         pm_history_save(PM_LOG_LCD_ON_FAIL, pm_cur_state);
384 #endif
385 #ifdef ENABLE_X_LCD_ONOFF
386                         _E("Failed to LCD on, through xset");
387 #else
388                         _E("Failed to LCD on, through OAL");
389 #endif
390                         ret = -1;
391                 }
392         }
393
394         return ret;
395 }
396
397 static int backlight_off(void)
398 {
399         int ret = -1;
400         int i;
401
402         _D("LCD off");
403
404         if (!pmsys || !pmsys->bl_onoff)
405                 return -1;
406
407         for (i = 0; i < PM_LCD_RETRY_CNT; i++) {
408 #ifdef ENABLE_X_LCD_ONOFF
409                 if (x_dpms_enable == false)
410 #endif
411                         usleep(30000);
412                 ret = pmsys->bl_onoff(pmsys, STATUS_OFF);
413                 if (get_lcd_power() == PM_LCD_POWER_OFF) {
414 #ifdef ENABLE_PM_LOG
415                         pm_history_save(PM_LOG_LCD_OFF, pm_cur_state);
416 #endif
417                         break;
418                 } else {
419 #ifdef ENABLE_PM_LOG
420                         pm_history_save(PM_LOG_LCD_OFF_FAIL, pm_cur_state);
421 #endif
422 #ifdef ENABLE_X_LCD_ONOFF
423                         _E("Failed to LCD off, through xset");
424 #else
425                         _E("Failed to LCD off, through OAL");
426 #endif
427                         ret = -1;
428                 }
429         }
430         return ret;
431 }
432
433 static int backlight_dim(void)
434 {
435         int ret = 0;
436         if (pmsys && pmsys->bl_brt) {
437                 ret = pmsys->bl_brt(pmsys, pmsys->dim_brt);
438 #ifdef ENABLE_PM_LOG
439                 if (!ret)
440                         pm_history_save(PM_LOG_LCD_DIM, pm_cur_state);
441                 else
442                         pm_history_save(PM_LOG_LCD_DIM_FAIL, pm_cur_state);
443 #endif
444         }
445         return ret;
446 }
447
448 static int set_custom_status(bool on)
449 {
450         custom_status = on;
451         return 0;
452 }
453
454 static bool get_custom_status(void)
455 {
456         return custom_status;
457 }
458
459 static int save_custom_brightness(void)
460 {
461         int cmd, ret, brightness;
462
463         cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
464         ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brightness);
465
466         custom_brightness = brightness;
467
468         return ret;
469 }
470
471 static int custom_backlight_update(void)
472 {
473         int ret = 0;
474
475         if (custom_brightness < PM_MIN_BRIGHTNESS ||
476             custom_brightness > PM_MAX_BRIGHTNESS)
477                 return -EINVAL;
478
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);
484         }
485
486         return ret;
487 }
488
489 static int set_force_brightness(int level)
490 {
491         if (level < 0 ||  level > PM_MAX_BRIGHTNESS)
492                 return -EINVAL;
493
494         force_brightness = level;
495
496         return 0;
497 }
498
499 static int backlight_update(void)
500 {
501         int ret = 0;
502
503         if (hbm_get_state != NULL && hbm_get_state() == true) {
504                 _I("HBM is on, backlight is not updated!");
505                 return 0;
506         }
507
508         if (get_custom_status()) {
509                 _I("custom brightness mode! brt no updated");
510                 return 0;
511         }
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);
516         }
517         return ret;
518 }
519
520 static int backlight_standby(void)
521 {
522         int ret = -1;
523         if (!pmsys || !pmsys->bl_onoff)
524                 return -1;
525
526         if (get_lcd_power() == PM_LCD_POWER_ON) {
527                 _I("LCD standby");
528                 ret = pmsys->bl_onoff(pmsys, STATUS_STANDBY);
529         }
530
531         return ret;
532 }
533
534 static int set_default_brt(int level)
535 {
536         if (!pmsys)
537                 return -EFAULT;
538
539         if (level < PM_MIN_BRIGHTNESS || level > PM_MAX_BRIGHTNESS)
540                 level = PM_DEFAULT_BRIGHTNESS;
541         pmsys->def_brt = level;
542
543         return 0;
544 }
545
546
547
548 static int check_wakeup_src(void)
549 {
550         /*  TODO if nedded.
551          * return wackeup source. user input or device interrupts? (EVENT_DEVICE or EVENT_INPUT)
552          */
553         return EVENT_DEVICE;
554 }
555
556 void _init_ops(void)
557 {
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;
571
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;
576
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;
584 }
585
586 int init_sysfs(unsigned int flags)
587 {
588         int ret;
589
590         pmsys = (PMSys *) malloc(sizeof(PMSys));
591         if (pmsys == NULL) {
592                 _E("Not enough memory to alloc PM Sys");
593                 return -1;
594         }
595
596         memset(pmsys, 0x0, sizeof(PMSys));
597
598         _init_pmsys(pmsys);
599         _init_bldev(pmsys, flags);
600
601         if (pmsys->bl_onoff == NULL || pmsys->sys_power_state == NULL) {
602                 _E("We have no managable resource to reduce the power consumption");
603                 return -1;
604         }
605
606         touchscreen_node = getenv("PM_TOUCHSCREEN");
607         _D("touchscreen node : %s", touchscreen_node);
608
609         touchkey_node = getenv("PM_TOUCHKEY");
610         _D("touchkey node : %s", touchkey_node);
611
612         _init_ops();
613
614         return 0;
615 }
616
617 int exit_sysfs(void)
618 {
619         int fd;
620
621         fd = open("/tmp/sem.pixmap_1", O_RDONLY);
622         if (fd == -1) {
623                 _E("X server disable");
624                 backlight_on();
625         }
626
627         backlight_update();
628         touchscreen_on();
629         touchkey_on();
630
631         free(pmsys);
632         pmsys = NULL;
633         if(fd != -1)
634                 close(fd);
635
636         return 0;
637 }