blob: d4185628f3fd03ac3233fa37617afe2535d3f2d3 [file] [log] [blame]
Pawit Pornkitprasan5bff9ac2012-09-25 21:17:58 +07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 * Copyright (C) 2012 The CyanogenMod Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include <errno.h>
18#include <string.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22
23#define LOG_TAG "PowerHAL"
24#include <cutils/properties.h>
25#include <utils/Log.h>
26
27#include <hardware/hardware.h>
28#include <hardware/power.h>
29
30#define BOOSTPULSE_PATH "/sys/devices/system/cpu/cpufreq/ondemand/boostpulse"
31#define SAMPLING_RATE_ONDEMAND "/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate"
32#define SAMPLING_RATE_SCREEN_ON "40000"
33#define SAMPLING_RATE_SCREEN_OFF "400000"
34
35struct s5pc110_power_module {
36 struct power_module base;
37 pthread_mutex_t lock;
38 int boostpulse_fd;
39 int boostpulse_warned;
40 char sampling_rate_screen_on[PROPERTY_VALUE_MAX];
41 char sampling_rate_screen_off[PROPERTY_VALUE_MAX];
42};
43
44static void sysfs_write(char *path, char *s)
45{
46 char buf[80];
47 int len;
48 int fd = open(path, O_WRONLY);
49
50 if (fd < 0) {
51 strerror_r(errno, buf, sizeof(buf));
52 ALOGE("Error opening %s: %s\n", path, buf);
53 return;
54 }
55
56 len = write(fd, s, strlen(s));
57 if (len < 0) {
58 strerror_r(errno, buf, sizeof(buf));
59 ALOGE("Error writing to %s: %s\n", path, buf);
60 }
61
62 close(fd);
63}
64
65static int boostpulse_open(struct s5pc110_power_module *s5pc110)
66{
67 char buf[80];
68
69 pthread_mutex_lock(&s5pc110->lock);
70
71 if (s5pc110->boostpulse_fd < 0) {
72 s5pc110->boostpulse_fd = open(BOOSTPULSE_PATH, O_WRONLY);
73
74 if (s5pc110->boostpulse_fd < 0) {
75 if (!s5pc110->boostpulse_warned) {
76 strerror_r(errno, buf, sizeof(buf));
77 ALOGE("Error opening %s: %s\n", BOOSTPULSE_PATH, buf);
78 s5pc110->boostpulse_warned = 1;
79 }
80 }
81 }
82
83 pthread_mutex_unlock(&s5pc110->lock);
84 return s5pc110->boostpulse_fd;
85}
86
87static void s5pc110_power_hint(struct power_module *module, power_hint_t hint,
88 void *data)
89{
90 struct s5pc110_power_module *s5pc110 = (struct s5pc110_power_module *) module;
91 char buf[80];
92 int len;
93 int duration = 1;
94
95 switch (hint) {
96 case POWER_HINT_INTERACTION:
97 case POWER_HINT_CPU_BOOST:
98 if (boostpulse_open(s5pc110) >= 0) {
99 if (data != NULL)
100 duration = (int) data;
101
102 snprintf(buf, sizeof(buf), "%d", duration);
103 len = write(s5pc110->boostpulse_fd, buf, strlen(buf));
104
105 if (len < 0) {
106 strerror_r(errno, buf, sizeof(buf));
107 ALOGE("Error writing to %s: %s\n", BOOSTPULSE_PATH, buf);
108 }
109 }
110 break;
111
112 case POWER_HINT_VSYNC:
113 break;
114
115 default:
116 break;
117 }
118}
119
120static void s5pc110_power_set_interactive(struct power_module *module, int on)
121{
122 struct s5pc110_power_module *s5pc110 = (struct s5pc110_power_module *) module;
123 sysfs_write(SAMPLING_RATE_ONDEMAND,
124 on ? s5pc110->sampling_rate_screen_on : s5pc110->sampling_rate_screen_off);
125}
126
127static void s5pc110_power_init(struct power_module *module)
128{
129 struct s5pc110_power_module *s5pc110 = (struct s5pc110_power_module *) module;
130 property_get("ro.sys.sampling_rate_on", s5pc110->sampling_rate_screen_on, SAMPLING_RATE_SCREEN_ON);
131 property_get("ro.sys.sampling_rate_off", s5pc110->sampling_rate_screen_off, SAMPLING_RATE_SCREEN_OFF);
132 sysfs_write(SAMPLING_RATE_ONDEMAND, s5pc110->sampling_rate_screen_on);
133}
134
135static struct hw_module_methods_t power_module_methods = {
136 .open = NULL,
137};
138
139struct s5pc110_power_module HAL_MODULE_INFO_SYM = {
140 base: {
141 common: {
142 tag: HARDWARE_MODULE_TAG,
143 module_api_version: POWER_MODULE_API_VERSION_0_2,
144 hal_api_version: HARDWARE_HAL_API_VERSION,
145 id: POWER_HARDWARE_MODULE_ID,
146 name: "S5PC110 Power HAL",
147 author: "The Android Open Source Project",
148 methods: &power_module_methods,
149 },
150 init: s5pc110_power_init,
151 setInteractive: s5pc110_power_set_interactive,
152 powerHint: s5pc110_power_hint,
153 },
154
155 lock: PTHREAD_MUTEX_INITIALIZER,
156 boostpulse_fd: -1,
157 boostpulse_warned: 0,
158};