mirror of
https://github.com/team-infusion-developers/android_hardware_samsung.git
synced 2024-11-06 21:55:41 +00:00
samsung: remove old power hal
* a hidl replacement exist Change-Id: I2df55148c1492a93f321e3b3a31f0704c071b9aa
This commit is contained in:
parent
eeb666cf00
commit
9a8c691ced
4 changed files with 0 additions and 663 deletions
|
@ -47,6 +47,5 @@ include $(SAM_ROOT)/doze/Android.mk
|
|||
include $(SAM_ROOT)/dtbhtool/Android.mk
|
||||
include $(SAM_ROOT)/hidl/Android.mk
|
||||
include $(SAM_ROOT)/modemloader/Android.mk
|
||||
include $(SAM_ROOT)/power/Android.mk
|
||||
include $(SAM_ROOT)/ril/Android.mk
|
||||
endif
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
# Copyright (C) 2015 The CyanogenMod Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ifeq ($(TARGET_POWERHAL_VARIANT),samsung)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := power.c
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/../hidl/light/include
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils
|
||||
|
||||
LOCAL_MODULE := power.$(TARGET_BOOTLOADER_BOARD_NAME)
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
ifneq ($(TARGET_TAP_TO_WAKE_NODE),)
|
||||
LOCAL_CFLAGS := -DTARGET_TAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\"
|
||||
endif
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
endif
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SAMSUNG_POWER_H
|
||||
#define SAMSUNG_POWER_H
|
||||
|
||||
/*
|
||||
* Board specific nodes
|
||||
*
|
||||
* If your kernel exposes these controls in another place, you can either
|
||||
* symlink to the locations given here, or override this header in your
|
||||
* device tree.
|
||||
*/
|
||||
|
||||
static const char* CPU_SYSFS_PATHS[2] = {
|
||||
"/sys/devices/system/cpu/cpu0",
|
||||
"/sys/devices/system/cpu/cpu4"
|
||||
};
|
||||
|
||||
static const char* CPU_INTERACTIVE_PATHS[2] = {
|
||||
"/sys/devices/system/cpu/cpu0/cpufreq/interactive",
|
||||
"/sys/devices/system/cpu/cpu4/cpufreq/interactive"
|
||||
};
|
||||
|
||||
#endif // SAMSUNG_POWER_H
|
585
power/power.c
585
power/power.c
|
@ -1,585 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
* Copyright (C) 2014 The CyanogenMod Project
|
||||
* Copyright (C) 2014-2015 Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (C) 2014-2017 Christopher N. Hesse <raymanfx@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define LOG_TAG "SamsungPowerHAL"
|
||||
/* #define LOG_NDEBUG 0 */
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/power.h>
|
||||
#include "samsung_lights.h"
|
||||
|
||||
#include "samsung_power.h"
|
||||
|
||||
#define BOOST_PATH "/boost"
|
||||
#define BOOSTPULSE_PATH "/boostpulse"
|
||||
|
||||
#define IO_IS_BUSY_PATH "/io_is_busy"
|
||||
#define HISPEED_FREQ_PATH "/hispeed_freq"
|
||||
|
||||
#define MAX_FREQ_PATH "/cpufreq/scaling_max_freq"
|
||||
|
||||
#define CLUSTER_COUNT ARRAY_SIZE(CPU_SYSFS_PATHS)
|
||||
#define PARAM_MAXLEN 10
|
||||
|
||||
#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
|
||||
|
||||
struct samsung_power_module {
|
||||
struct power_module base;
|
||||
pthread_mutex_t lock;
|
||||
int boost_fd;
|
||||
int boostpulse_fd;
|
||||
char hispeed_freqs[CLUSTER_COUNT][PARAM_MAXLEN];
|
||||
char max_freqs[CLUSTER_COUNT][PARAM_MAXLEN];
|
||||
char* touchscreen_power_path;
|
||||
char* touchkey_power_path;
|
||||
};
|
||||
|
||||
enum power_profile_e {
|
||||
PROFILE_POWER_SAVE = 0,
|
||||
PROFILE_BALANCED,
|
||||
PROFILE_HIGH_PERFORMANCE,
|
||||
PROFILE_MAX
|
||||
};
|
||||
|
||||
static enum power_profile_e current_power_profile = PROFILE_BALANCED;
|
||||
|
||||
// Custom Lineage hints
|
||||
const static power_hint_t POWER_HINT_CPU_BOOST = (power_hint_t)0x00000110;
|
||||
const static power_hint_t POWER_HINT_SET_PROFILE = (power_hint_t)0x00000111;
|
||||
|
||||
/**********************************************************
|
||||
*** HELPER FUNCTIONS
|
||||
**********************************************************/
|
||||
|
||||
static int sysfs_read(char *path, char *s, int num_bytes)
|
||||
{
|
||||
char errno_str[64];
|
||||
int len;
|
||||
int ret = 0;
|
||||
int fd;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Error opening %s: %s", path, errno_str);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = read(fd, s, num_bytes - 1);
|
||||
if (len < 0) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Error reading from %s: %s", path, errno_str);
|
||||
|
||||
ret = -1;
|
||||
} else {
|
||||
// do not store newlines, but terminate the string instead
|
||||
if (s[len-1] == '\n') {
|
||||
s[len-1] = '\0';
|
||||
} else {
|
||||
s[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sysfs_write(const char *path, char *s)
|
||||
{
|
||||
char errno_str[64];
|
||||
int len;
|
||||
int fd;
|
||||
|
||||
fd = open(path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Error opening %s: %s", path, errno_str);
|
||||
return;
|
||||
}
|
||||
|
||||
len = write(fd, s, strlen(s));
|
||||
if (len < 0) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Error writing to %s: %s", path, errno_str);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void cpu_sysfs_read(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN])
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(CPU_SYSFS_PATHS); i++) {
|
||||
sprintf(path, "%s%s", CPU_SYSFS_PATHS[i], param);
|
||||
sysfs_read(path, s[i], PARAM_MAXLEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_sysfs_write(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN])
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(CPU_SYSFS_PATHS); i++) {
|
||||
sprintf(path, "%s%s", CPU_SYSFS_PATHS[i], param);
|
||||
sysfs_write(path, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_interactive_read(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN])
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(CPU_INTERACTIVE_PATHS); i++) {
|
||||
sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[i], param);
|
||||
sysfs_read(path, s[i], PARAM_MAXLEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_interactive_write(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN])
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(CPU_INTERACTIVE_PATHS); i++) {
|
||||
sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[i], param);
|
||||
sysfs_write(path, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_boost(int boost_fd, int32_t duration_us)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (boost_fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = write(boost_fd, "1", 1);
|
||||
if (len < 0) {
|
||||
ALOGE("Error writing to %s%s: %s", CPU_INTERACTIVE_PATHS[0], BOOST_PATH, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
usleep(duration_us);
|
||||
len = write(boost_fd, "0", 1);
|
||||
}
|
||||
|
||||
static void send_boostpulse(int boostpulse_fd)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (boostpulse_fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = write(boostpulse_fd, "1", 1);
|
||||
if (len < 0) {
|
||||
ALOGE("Error writing to %s%s: %s", CPU_INTERACTIVE_PATHS[0], BOOSTPULSE_PATH,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static int get_cur_panel_brightness() {
|
||||
int ret = 0;
|
||||
int read_status;
|
||||
// brightness can range from 0 to 255, so max. 3 chars + '\0'
|
||||
char panel_brightness[4];
|
||||
// for strtol
|
||||
char *dummy;
|
||||
const int base = 10;
|
||||
|
||||
read_status = sysfs_read(PANEL_BRIGHTNESS_NODE, panel_brightness, sizeof(PANEL_BRIGHTNESS_NODE));
|
||||
if (read_status < 0) {
|
||||
ALOGE("%s: Failed to read panel brightness from %s!\n", __func__, PANEL_BRIGHTNESS_NODE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = strtol(panel_brightness, &dummy, base);
|
||||
ALOGV("%s: Panel brightness is: %d", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*** POWER FUNCTIONS
|
||||
**********************************************************/
|
||||
|
||||
static void set_power_profile(struct samsung_power_module *samsung_pwr,
|
||||
int profile)
|
||||
{
|
||||
if (profile < 0 || profile >= PROFILE_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_power_profile == profile) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGV("%s: profile=%d", __func__, profile);
|
||||
|
||||
switch (profile) {
|
||||
case PROFILE_POWER_SAVE:
|
||||
// Grab value set by init.*.rc
|
||||
cpu_interactive_read(HISPEED_FREQ_PATH, samsung_pwr->hispeed_freqs);
|
||||
// Limit to hispeed freq
|
||||
cpu_sysfs_write(MAX_FREQ_PATH, samsung_pwr->hispeed_freqs);
|
||||
ALOGV("%s: set powersave mode", __func__);
|
||||
break;
|
||||
case PROFILE_BALANCED:
|
||||
// Restore normal max freq
|
||||
cpu_sysfs_write(MAX_FREQ_PATH, samsung_pwr->max_freqs);
|
||||
ALOGV("%s: set balanced mode", __func__);
|
||||
break;
|
||||
case PROFILE_HIGH_PERFORMANCE:
|
||||
// Restore normal max freq
|
||||
cpu_sysfs_write(MAX_FREQ_PATH, samsung_pwr->max_freqs);
|
||||
ALOGV("%s: set performance mode", __func__);
|
||||
break;
|
||||
default:
|
||||
ALOGW("%s: Unknown power profile: %d", __func__, profile);
|
||||
return;
|
||||
}
|
||||
|
||||
current_power_profile = profile;
|
||||
}
|
||||
|
||||
static void find_input_nodes(struct samsung_power_module *samsung_pwr, char *dir)
|
||||
{
|
||||
const char filename[] = "name";
|
||||
char errno_str[64];
|
||||
struct dirent *de;
|
||||
char file_content[20];
|
||||
char *path = NULL;
|
||||
char *node_path = NULL;
|
||||
size_t pathsize;
|
||||
size_t node_pathsize;
|
||||
DIR *d;
|
||||
|
||||
d = opendir(dir);
|
||||
if (d == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
if (strncmp(filename, de->d_name, sizeof(filename)) == 0) {
|
||||
pathsize = strlen(dir) + strlen(de->d_name) + 2;
|
||||
node_pathsize = strlen(dir) + strlen("enabled") + 2;
|
||||
|
||||
path = malloc(pathsize);
|
||||
node_path = malloc(node_pathsize);
|
||||
if (path == NULL || node_path == NULL) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Out of memory: %s", errno_str);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(path, pathsize, "%s/%s", dir, filename);
|
||||
sysfs_read(path, file_content, sizeof(file_content));
|
||||
|
||||
snprintf(node_path, node_pathsize, "%s/%s", dir, "enabled");
|
||||
|
||||
if (strncmp(file_content, "sec_touchkey", 12) == 0) {
|
||||
ALOGV("%s: found touchkey path: %s", __func__, node_path);
|
||||
samsung_pwr->touchkey_power_path = malloc(node_pathsize);
|
||||
if (samsung_pwr->touchkey_power_path == NULL) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Out of memory: %s", errno_str);
|
||||
return;
|
||||
}
|
||||
snprintf(samsung_pwr->touchkey_power_path, node_pathsize,
|
||||
"%s", node_path);
|
||||
}
|
||||
|
||||
if (strncmp(file_content, "sec_touchscreen", 15) == 0) {
|
||||
ALOGV("%s: found touchscreen path: %s", __func__, node_path);
|
||||
samsung_pwr->touchscreen_power_path = malloc(node_pathsize);
|
||||
if (samsung_pwr->touchscreen_power_path == NULL) {
|
||||
strerror_r(errno, errno_str, sizeof(errno_str));
|
||||
ALOGE("Out of memory: %s", errno_str);
|
||||
return;
|
||||
}
|
||||
snprintf(samsung_pwr->touchscreen_power_path, node_pathsize,
|
||||
"%s", node_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path)
|
||||
free(path);
|
||||
if (node_path)
|
||||
free(node_path);
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*** INIT FUNCTIONS
|
||||
**********************************************************/
|
||||
|
||||
static void init_cpufreqs(struct samsung_power_module *samsung_pwr)
|
||||
{
|
||||
cpu_interactive_read(HISPEED_FREQ_PATH, samsung_pwr->hispeed_freqs);
|
||||
cpu_sysfs_read(MAX_FREQ_PATH, samsung_pwr->max_freqs);
|
||||
}
|
||||
|
||||
static void init_touch_input_power_path(struct samsung_power_module *samsung_pwr)
|
||||
{
|
||||
char dir[1024];
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
snprintf(dir, sizeof(dir), "/sys/class/input/input%d", i);
|
||||
find_input_nodes(samsung_pwr, dir);
|
||||
}
|
||||
}
|
||||
|
||||
static void boost_open(struct samsung_power_module *samsung_pwr)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
// the boost node is only valid for the LITTLE cluster
|
||||
sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[0], BOOST_PATH);
|
||||
|
||||
samsung_pwr->boost_fd = open(path, O_WRONLY);
|
||||
if (samsung_pwr->boost_fd < 0) {
|
||||
ALOGE("Error opening %s: %s\n", path, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void boostpulse_open(struct samsung_power_module *samsung_pwr)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
// the boostpulse node is only valid for the LITTLE cluster
|
||||
sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[0], BOOSTPULSE_PATH);
|
||||
|
||||
samsung_pwr->boostpulse_fd = open(path, O_WRONLY);
|
||||
if (samsung_pwr->boostpulse_fd < 0) {
|
||||
ALOGE("Error opening %s: %s\n", path, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void samsung_power_init(struct power_module *module)
|
||||
{
|
||||
struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
|
||||
|
||||
init_cpufreqs(samsung_pwr);
|
||||
|
||||
// keep interactive boost fds opened
|
||||
boost_open(samsung_pwr);
|
||||
boostpulse_open(samsung_pwr);
|
||||
|
||||
samsung_pwr->touchscreen_power_path = NULL;
|
||||
samsung_pwr->touchkey_power_path = NULL;
|
||||
init_touch_input_power_path(samsung_pwr);
|
||||
|
||||
ALOGI("Initialized settings:");
|
||||
char max_freqs[PATH_MAX];
|
||||
sprintf(max_freqs, "max_freqs: cluster[0]: %s", samsung_pwr->max_freqs[0]);
|
||||
for (unsigned int i = 1; i < CLUSTER_COUNT; i++) {
|
||||
sprintf(max_freqs, "%s, %s[%d]: %s", max_freqs, "cluster", i, samsung_pwr->max_freqs[i]);
|
||||
}
|
||||
ALOGI("%s", max_freqs);
|
||||
char hispeed_freqs[PATH_MAX];
|
||||
sprintf(hispeed_freqs, "hispeed_freqs: cluster[0]: %s", samsung_pwr->hispeed_freqs[0]);
|
||||
for (unsigned int i = 1; i < CLUSTER_COUNT; i++) {
|
||||
sprintf(hispeed_freqs, "%s, %s[%d]: %s", hispeed_freqs, "cluster", i,
|
||||
samsung_pwr->hispeed_freqs[i]);
|
||||
}
|
||||
ALOGI("%s", hispeed_freqs);
|
||||
ALOGI("boostpulse_fd: %d", samsung_pwr->boostpulse_fd);
|
||||
ALOGI("touchscreen_power_path: %s",
|
||||
samsung_pwr->touchscreen_power_path ? samsung_pwr->touchscreen_power_path : "NULL");
|
||||
ALOGI("touchkey_power_path: %s",
|
||||
samsung_pwr->touchkey_power_path ? samsung_pwr->touchkey_power_path : "NULL");
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*** API FUNCTIONS
|
||||
***
|
||||
*** Refer to power.h for documentation.
|
||||
**********************************************************/
|
||||
|
||||
static void samsung_power_set_interactive(struct power_module *module, int on)
|
||||
{
|
||||
struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
|
||||
int panel_brightness;
|
||||
char button_state[2];
|
||||
int rc;
|
||||
static bool touchkeys_blocked = false;
|
||||
char ON[CLUSTER_COUNT][PARAM_MAXLEN] = {"1", "1"};
|
||||
char OFF[CLUSTER_COUNT][PARAM_MAXLEN] = {"0", "0"};
|
||||
|
||||
ALOGV("power_set_interactive: %d", on);
|
||||
|
||||
/*
|
||||
* Do not disable any input devices if the screen is on but we are in a non-interactive
|
||||
* state.
|
||||
*/
|
||||
if (!on) {
|
||||
panel_brightness = get_cur_panel_brightness();
|
||||
if (panel_brightness < 0) {
|
||||
ALOGE("%s: Failed to read panel brightness", __func__);
|
||||
} else if (panel_brightness > 0) {
|
||||
ALOGV("%s: Moving to non-interactive state, but screen is still on,"
|
||||
" not disabling input devices", __func__);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check the touchscreen path */
|
||||
if (samsung_pwr->touchscreen_power_path) {
|
||||
sysfs_write(samsung_pwr->touchscreen_power_path, on ? "1" : "0");
|
||||
}
|
||||
|
||||
/* Bail out if the device does not have touchkeys */
|
||||
if (samsung_pwr->touchkey_power_path == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!on) {
|
||||
rc = sysfs_read(samsung_pwr->touchkey_power_path, button_state, ARRAY_SIZE(button_state));
|
||||
if (rc < 0) {
|
||||
ALOGE("%s: Failed to read touchkey state", __func__);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* If button_state is 0, the keys have been disabled by another component
|
||||
* (for example cmhw), which means we don't want them to be enabled when resuming
|
||||
* from suspend.
|
||||
*/
|
||||
if (button_state[0] == '0') {
|
||||
touchkeys_blocked = true;
|
||||
} else {
|
||||
touchkeys_blocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!touchkeys_blocked) {
|
||||
sysfs_write(samsung_pwr->touchkey_power_path, on ? "1" : "0");
|
||||
}
|
||||
|
||||
out:
|
||||
cpu_interactive_write(IO_IS_BUSY_PATH, on ? ON : OFF);
|
||||
|
||||
ALOGV("power_set_interactive: %d done", on);
|
||||
}
|
||||
|
||||
static void samsung_power_hint(struct power_module *module,
|
||||
power_hint_t hint,
|
||||
void *data)
|
||||
{
|
||||
struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
|
||||
|
||||
/* Bail out if low-power mode is active */
|
||||
if (current_power_profile == PROFILE_POWER_SAVE && hint != POWER_HINT_LOW_POWER
|
||||
&& hint != POWER_HINT_SET_PROFILE && hint != POWER_HINT_DISABLE_TOUCH) {
|
||||
ALOGV("%s: PROFILE_POWER_SAVE active, ignoring hint %d", __func__, hint);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (hint) {
|
||||
case POWER_HINT_VSYNC:
|
||||
ALOGV("%s: POWER_HINT_VSYNC", __func__);
|
||||
break;
|
||||
case POWER_HINT_INTERACTION:
|
||||
ALOGV("%s: POWER_HINT_INTERACTION", __func__);
|
||||
send_boostpulse(samsung_pwr->boostpulse_fd);
|
||||
break;
|
||||
case POWER_HINT_LOW_POWER:
|
||||
ALOGV("%s: POWER_HINT_LOW_POWER", __func__);
|
||||
set_power_profile(samsung_pwr, data ? PROFILE_POWER_SAVE : PROFILE_BALANCED);
|
||||
break;
|
||||
case POWER_HINT_LAUNCH:
|
||||
ALOGV("%s: POWER_HINT_LAUNCH", __func__);
|
||||
send_boostpulse(samsung_pwr->boostpulse_fd);
|
||||
break;
|
||||
case POWER_HINT_CPU_BOOST:
|
||||
ALOGV("%s: POWER_HINT_CPU_BOOST", __func__);
|
||||
int32_t duration_us = *((int32_t *)data);
|
||||
send_boost(samsung_pwr->boost_fd, duration_us);
|
||||
break;
|
||||
case POWER_HINT_SET_PROFILE:
|
||||
ALOGV("%s: POWER_HINT_SET_PROFILE", __func__);
|
||||
int profile = *((intptr_t *)data);
|
||||
set_power_profile(samsung_pwr, profile);
|
||||
break;
|
||||
case POWER_HINT_DISABLE_TOUCH:
|
||||
ALOGV("%s: POWER_HINT_DISABLE_TOUCH", __func__);
|
||||
sysfs_write(samsung_pwr->touchscreen_power_path, data ? "0" : "1");
|
||||
break;
|
||||
default:
|
||||
ALOGW("%s: Unknown power hint: %d", __func__, hint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void samsung_set_feature(struct power_module *module __unused, feature_t feature, int state __unused)
|
||||
{
|
||||
switch (feature) {
|
||||
#ifdef TARGET_TAP_TO_WAKE_NODE
|
||||
case POWER_FEATURE_DOUBLE_TAP_TO_WAKE:
|
||||
ALOGV("%s: %s double tap to wake", __func__, state ? "enabling" : "disabling");
|
||||
sysfs_write(TARGET_TAP_TO_WAKE_NODE, state > 0 ? "1" : "0");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_module_methods_t power_module_methods = {
|
||||
.open = NULL,
|
||||
};
|
||||
|
||||
struct samsung_power_module HAL_MODULE_INFO_SYM = {
|
||||
.base = {
|
||||
.common = {
|
||||
.tag = HARDWARE_MODULE_TAG,
|
||||
.module_api_version = POWER_MODULE_API_VERSION_0_2,
|
||||
.hal_api_version = HARDWARE_HAL_API_VERSION,
|
||||
.id = POWER_HARDWARE_MODULE_ID,
|
||||
.name = "Samsung Power HAL",
|
||||
.author = "The LineageOS Project",
|
||||
.methods = &power_module_methods,
|
||||
},
|
||||
|
||||
.init = samsung_power_init,
|
||||
.setInteractive = samsung_power_set_interactive,
|
||||
.powerHint = samsung_power_hint,
|
||||
.setFeature = samsung_set_feature
|
||||
},
|
||||
|
||||
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||||
.boostpulse_fd = -1,
|
||||
};
|
Loading…
Reference in a new issue