summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorOmprakash Dhyade <odhyade@codeaurora.org>2014-08-24 21:32:38 -0700
committerIliyan Malchev <malchev@google.com>2014-09-02 20:08:59 -0700
commit4f7ef69436beb05de28ca7a54d60cdf9eea63d61 (patch)
treef71d0082a3a095111d2e7c7ce7563788c181ff55 /power
parent0e5cd855662ae24b0a716c9ecd07a1fa4fc76e62 (diff)
downloadshamu-4f7ef69436beb05de28ca7a54d60cdf9eea63d61.tar.gz
PowerHal: Add perflock usage to power hal
-- Add perflock usage to power hal. -- Add touch boost, encoder boost and low power mode hints. Also, make 2 cores online by default when display is ON , while 1 core online when display is OFF. -- Modify mpdecision, system_server and media sepolicy files required for the communication. Change-Id: Idb8958a634a8c8c4b63f7f73a6e1074c845752c0 Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'power')
-rw-r--r--power/power_shamu.c244
1 files changed, 243 insertions, 1 deletions
diff --git a/power/power_shamu.c b/power/power_shamu.c
index 63da2ece..2dfd3601 100644
--- a/power/power_shamu.c
+++ b/power/power_shamu.c
@@ -16,9 +16,16 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <dlfcn.h>
+#include <cutils/uevent.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <pthread.h>
+#include <linux/netlink.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -29,6 +36,29 @@
#include <hardware/power.h>
#define TOUCH_INTERACTIVE_PATH "/sys/bus/i2c/devices/1-004a/tsp"
+#define STATE_ON "state=1"
+#define STATE_OFF "state=0"
+#define STATE_HDR_ON "state=2"
+#define STATE_HDR_OFF "state=3"
+#define MAX_LENGTH 50
+#define BOOST_SOCKET "/dev/socket/mpdecision/pb"
+static int client_sockfd;
+static struct sockaddr_un client_addr;
+static int last_state = -1;
+
+static void socket_init()
+{
+ if (!client_sockfd) {
+ client_sockfd = socket(PF_UNIX, SOCK_DGRAM, 0);
+ if (client_sockfd < 0) {
+ ALOGE("%s: failed to open: %s", __func__, strerror(errno));
+ return;
+ }
+ memset(&client_addr, 0, sizeof(struct sockaddr_un));
+ client_addr.sun_family = AF_UNIX;
+ snprintf(client_addr.sun_path, UNIX_PATH_MAX, BOOST_SOCKET);
+ }
+}
static int sysfs_write(const char *path, char *s)
{
@@ -57,18 +87,230 @@ static int sysfs_write(const char *path, char *s)
static void power_init(__attribute__((unused)) struct power_module *module)
{
ALOGI("%s", __func__);
+ socket_init();
+}
+
+static void sync_thread(int off)
+{
+ int rc;
+ pid_t client;
+ char data[MAX_LENGTH];
+
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ client = getpid();
+
+ if (!off) {
+ snprintf(data, MAX_LENGTH, "2:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0,
+ (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ } else {
+ snprintf(data, MAX_LENGTH, "3:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0,
+ (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ }
+
+ if (rc < 0) {
+ ALOGE("%s: failed to send: %s", __func__, strerror(errno));
+ }
+}
+
+static void coresonline(int off)
+{
+ int rc;
+ pid_t client;
+ char data[MAX_LENGTH];
+
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ client = getpid();
+
+ if (!off) {
+ snprintf(data, MAX_LENGTH, "8:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ } else {
+ snprintf(data, MAX_LENGTH, "7:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ }
+
+ if (rc < 0) {
+ ALOGE("%s: failed to send: %s", __func__, strerror(errno));
+ }
+}
+
+static void enc_boost(int off)
+{
+ int rc;
+ pid_t client;
+ char data[MAX_LENGTH];
+
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ client = getpid();
+
+ if (!off) {
+ snprintf(data, MAX_LENGTH, "5:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0,
+ (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ } else {
+ snprintf(data, MAX_LENGTH, "6:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0,
+ (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ }
+
+ if (rc < 0) {
+ ALOGE("%s: failed to send: %s", __func__, strerror(errno));
+ }
+}
+
+static void process_video_encode_hint(void *metadata)
+{
+
+ socket_init();
+
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ if (metadata) {
+ if (!strncmp(metadata, STATE_ON, sizeof(STATE_ON))) {
+ /* Video encode started */
+ sync_thread(1);
+ enc_boost(1);
+ } else if (!strncmp(metadata, STATE_OFF, sizeof(STATE_OFF))) {
+ /* Video encode stopped */
+ sync_thread(0);
+ enc_boost(0);
+ } else if (!strncmp(metadata, STATE_HDR_ON, sizeof(STATE_HDR_ON))) {
+ /* HDR usecase started */
+ } else if (!strncmp(metadata, STATE_HDR_OFF, sizeof(STATE_HDR_OFF))) {
+ /* HDR usecase stopped */
+ }else
+ return;
+ } else {
+ return;
+ }
+}
+
+
+static void touch_boost()
+{
+ int rc, fd;
+ pid_t client;
+ char data[MAX_LENGTH];
+ char buf[MAX_LENGTH];
+
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ client = getpid();
+
+ snprintf(data, MAX_LENGTH, "1:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0,
+ (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ if (rc < 0) {
+ ALOGE("%s: failed to send: %s", __func__, strerror(errno));
+ }
+}
+
+static void low_power(int on)
+{
+ int rc;
+ pid_t client;
+ char data[MAX_LENGTH];
+
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ client = getpid();
+
+ if (on) {
+ snprintf(data, MAX_LENGTH, "10:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ if (rc < 0) {
+ ALOGE("%s: failed to send: %s", __func__, strerror(errno));
+ }
+ } else {
+ snprintf(data, MAX_LENGTH, "9:%d", client);
+ rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
+ if (rc < 0) {
+ ALOGE("%s: failed to send: %s", __func__, strerror(errno));
+ }
+ }
+}
+
+static void process_low_power_hint(void* data)
+{
+ int on = (long) data;
+ if (client_sockfd < 0) {
+ ALOGE("%s: boost socket not created", __func__);
+ return;
+ }
+
+ low_power(on);
}
static void power_set_interactive(__attribute__((unused)) struct power_module *module, int on)
{
- ALOGV("%s %s", __func__, (on ? "ON" : "OFF"));
sysfs_write(TOUCH_INTERACTIVE_PATH, on ? "AUTO" : "ON");
+
+ if (last_state == -1) {
+ last_state = on;
+ } else {
+ if (last_state == on)
+ return;
+ else
+ last_state = on;
+ }
+
+ ALOGV("%s %s", __func__, (on ? "ON" : "OFF"));
+ if (on) {
+ coresonline(0);
+ sync_thread(0);
+ touch_boost();
+ } else {
+ sync_thread(1);
+ coresonline(1);
+ }
}
static void power_hint( __attribute__((unused)) struct power_module *module,
__attribute__((unused)) power_hint_t hint,
__attribute__((unused)) void *data)
{
+ switch (hint) {
+ case POWER_HINT_INTERACTION:
+ ALOGV("POWER_HINT_INTERACTION");
+ touch_boost();
+ break;
+#if 0
+ case POWER_HINT_VSYNC:
+ ALOGV("POWER_HINT_VSYNC %s", (data ? "ON" : "OFF"));
+ break;
+#endif
+ case POWER_HINT_VIDEO_ENCODE:
+ process_video_encode_hint(data);
+ break;
+ case POWER_HINT_LOW_POWER:
+ process_low_power_hint(data);
+ break;
+ default:
+ break;
+ }
}
static struct hw_module_methods_t power_module_methods = {