1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <stddef.h>
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #define LOG_TAG "libsuspend"
26 #include <cutils/log.h>
27 
28 #include "autosuspend_ops.h"
29 
30 #define SYS_POWER_AUTOSLEEP "/sys/power/autosleep"
31 
32 static int autosleep_fd;
33 static const char *sleep_state = "mem";
34 static const char *on_state = "off";
35 
autosuspend_autosleep_enable(void)36 static int autosuspend_autosleep_enable(void)
37 {
38     char buf[80];
39     int ret;
40 
41     ALOGV("autosuspend_autosleep_enable\n");
42 
43     ret = write(autosleep_fd, sleep_state, strlen(sleep_state));
44     if (ret < 0) {
45         strerror_r(errno, buf, sizeof(buf));
46         ALOGE("Error writing to %s: %s\n", SYS_POWER_AUTOSLEEP, buf);
47         goto err;
48     }
49 
50     ALOGV("autosuspend_autosleep_enable done\n");
51 
52     return 0;
53 
54 err:
55     return ret;
56 }
57 
autosuspend_autosleep_disable(void)58 static int autosuspend_autosleep_disable(void)
59 {
60     char buf[80];
61     int ret;
62 
63     ALOGV("autosuspend_autosleep_disable\n");
64 
65     ret = write(autosleep_fd, on_state, strlen(on_state));
66     if (ret < 0) {
67         strerror_r(errno, buf, sizeof(buf));
68         ALOGE("Error writing to %s: %s\n", SYS_POWER_AUTOSLEEP, buf);
69         goto err;
70     }
71 
72     ALOGV("autosuspend_autosleep_disable done\n");
73 
74     return 0;
75 
76 err:
77     return ret;
78 }
79 
80 struct autosuspend_ops autosuspend_autosleep_ops = {
81         .enable = autosuspend_autosleep_enable,
82         .disable = autosuspend_autosleep_disable,
83 };
84 
autosuspend_autosleep_init(void)85 struct autosuspend_ops *autosuspend_autosleep_init(void)
86 {
87     int ret;
88     char buf[80];
89 
90     autosleep_fd = open(SYS_POWER_AUTOSLEEP, O_WRONLY);
91     if (autosleep_fd < 0) {
92         strerror_r(errno, buf, sizeof(buf));
93         ALOGE("Error opening %s: %s\n", SYS_POWER_AUTOSLEEP, buf);
94         return NULL;
95     }
96 
97     ALOGI("Selected autosleep\n");
98 
99     autosuspend_autosleep_disable();
100 
101     return &autosuspend_autosleep_ops;
102 }
103