summaryrefslogtreecommitdiffstats
path: root/power/power_tuna.c
diff options
context:
space:
mode:
Diffstat (limited to 'power/power_tuna.c')
-rw-r--r--power/power_tuna.c85
1 files changed, 75 insertions, 10 deletions
diff --git a/power/power_tuna.c b/power/power_tuna.c
index 7d06093..455137d 100644
--- a/power/power_tuna.c
+++ b/power/power_tuna.c
@@ -25,8 +25,19 @@
#include <hardware/hardware.h>
#include <hardware/power.h>
+#define SCALINGMAXFREQ_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
+#define SCREENOFFMAXFREQ_PATH "/sys/devices/system/cpu/cpu0/cpufreq/screen_off_max_freq"
#define BOOSTPULSE_PATH "/sys/devices/system/cpu/cpufreq/interactive/boostpulse"
+#define MAX_BUF_SZ 10
+
+/* initialize to something safe */
+static char screen_off_max_freq[MAX_BUF_SZ] = "700000";
+static char scaling_max_freq[MAX_BUF_SZ] = "1200000";
+
+/* for tracking previous screen state */
+static int previous_state = 0;
+
struct tuna_power_module {
struct power_module base;
pthread_mutex_t lock;
@@ -55,6 +66,23 @@ static void sysfs_write(char *path, char *s)
close(fd);
}
+int sysfs_read(const char *path, char *buf, size_t size)
+{
+ int fd, len;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ do {
+ len = read(fd, buf, size);
+ } while (len < 0 && errno == EINTR);
+
+ close(fd);
+
+ return len;
+}
+
static void tuna_power_init(struct power_module *module)
{
/*
@@ -99,12 +127,43 @@ static int boostpulse_open(struct tuna_power_module *tuna)
static void tuna_power_set_interactive(struct power_module *module, int on)
{
/*
- * Lower maximum frequency when screen is off. CPU 0 and 1 share a
- * cpufreq policy.
+ * Lower maximum frequency when screen changes from on to off.
+ * Return it to previous value when screen changes from off to on.
+ * CPU 0 and 1 share a cpufreq policy.
*/
- sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq",
- on ? "1200000" : "700000");
+ //screen state has changed since last call
+ if (on != previous_state)
+ {
+ char buf_screen_off_max[MAX_BUF_SZ], buf_scaling_max[MAX_BUF_SZ];
+ int screen_off_max, scaling_max;
+
+ previous_state = on;
+
+ //read value of screen-off max from sysfs, and convert to int for comparison
+ if (sysfs_read(SCREENOFFMAXFREQ_PATH, buf_screen_off_max, sizeof(buf_screen_off_max)) != -1)
+ screen_off_max = atoi(buf_screen_off_max);
+
+ //read value of max from sysfs, and convert to int for comparison
+ if (sysfs_read(SCALINGMAXFREQ_PATH, buf_scaling_max, sizeof(buf_scaling_max)) != -1)
+ scaling_max = atoi(buf_scaling_max);
+
+ /* If scaling_max_freq > screen_off_max_freq, then scaling_max_freq is really the maximum frequency, so save it for the next time the screen comes on.
+ * If screen_off_max_freq == 0, then we're just going to write our saved scalin_max_freq back to sysfs no matter what
+ * If scaling_max_freq == screen_off_max_freq, then scaling_max_freq has the screen_off_max in it, so DON'T SAVE IT TO OUR MAX VARIABLE!
+ */
+ if (scaling_max > screen_off_max)
+ memcpy(scaling_max_freq,
+ (scaling_max > screen_off_max) ? buf_scaling_max : buf_screen_off_max,
+ strlen((scaling_max > screen_off_max) ? buf_scaling_max : buf_screen_off_max));
+
+ memcpy(screen_off_max_freq,
+ (scaling_max <= screen_off_max && screen_off_max > 0) ? buf_scaling_max : buf_screen_off_max,
+ strlen((scaling_max <= screen_off_max && screen_off_max > 0) ? buf_scaling_max : buf_screen_off_max));
+
+ //write the appropriate value for scaling_max back to sysfs
+ sysfs_write(SCALINGMAXFREQ_PATH, on?scaling_max_freq:screen_off_max_freq);
+ }
}
static void tuna_power_hint(struct power_module *module, power_hint_t hint,
@@ -113,17 +172,23 @@ static void tuna_power_hint(struct power_module *module, power_hint_t hint,
struct tuna_power_module *tuna = (struct tuna_power_module *) module;
char buf[80];
int len;
+ int duration = 1;
switch (hint) {
case POWER_HINT_INTERACTION:
+ case POWER_HINT_CPU_BOOST:
+ if (data != NULL)
+ duration = (int) data;
+
if (boostpulse_open(tuna) >= 0) {
- len = write(tuna->boostpulse_fd, "1", 1);
+ snprintf(buf, sizeof(buf), "%d", duration);
+ len = write(tuna->boostpulse_fd, buf, strlen(buf));
- if (len < 0) {
- strerror_r(errno, buf, sizeof(buf));
- ALOGE("Error writing to %s: %s\n", BOOSTPULSE_PATH, buf);
- }
- }
+ if (len < 0) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error writing to %s: %s\n", BOOSTPULSE_PATH, buf);
+ }
+ }
break;
case POWER_HINT_VSYNC: