diff options
Diffstat (limited to 'power/power_tuna.c')
-rw-r--r-- | power/power_tuna.c | 85 |
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: |