From 02bd515cea2659d84adb825afd5a1d3a1fd2481b Mon Sep 17 00:00:00 2001 From: taeyoung Date: Mon, 21 Nov 2016 19:28:22 +0900 Subject: [PATCH] thermal: add thermal HAL Thermal HAL is newly added. Change-Id: I8fe3937422360df0edbb793c7f44c5002552e9f0 Signed-off-by: taeyoung --- CMakeLists.txt | 1 + hw/thermal/CMakeLists.txt | 19 ++++++ hw/thermal/thermal.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 hw/thermal/CMakeLists.txt create mode 100644 hw/thermal/thermal.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c05e559..35b74da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,5 +9,6 @@ ADD_SUBDIRECTORY(hw/led) ADD_SUBDIRECTORY(hw/external_connection) ADD_SUBDIRECTORY(hw/touchscreen) ADD_SUBDIRECTORY(hw/ir) +ADD_SUBDIRECTORY(hw/thermal) ADD_SUBDIRECTORY(hw/usb_gadget) ADD_SUBDIRECTORY(hw/usb_client) diff --git a/hw/thermal/CMakeLists.txt b/hw/thermal/CMakeLists.txt new file mode 100644 index 0000000..352f375 --- /dev/null +++ b/hw/thermal/CMakeLists.txt @@ -0,0 +1,19 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(thermal C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(thermal_pkgs REQUIRED hwcommon dlog glib-2.0) + +FOREACH(flag ${thermal_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_LIBRARY(${PROJECT_NAME} MODULE thermal.c ../shared.c ../udev.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${thermal_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/hw COMPONENT RuntimeLibraries) diff --git a/hw/thermal/thermal.c b/hw/thermal/thermal.c new file mode 100644 index 0000000..bdb47c8 --- /dev/null +++ b/hw/thermal/thermal.c @@ -0,0 +1,163 @@ +/* + * device-node + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include +#include +#include + +#include +#include "../shared.h" + +#define THERMAL_PATH "/sys/class/sec/temperature/ap_therm" + +static struct event_data { + ThermalUpdated updated_cb; + void *data; +} edata = { 0, }; + +static guint timer; + +static int thermal_get_state(struct thermal_info *info) +{ + int ret, value; + + if (!info) + return -EINVAL; + + ret = sys_get_int(THERMAL_PATH, &value); + if (ret < 0) { + _E("Failed to read %s (%d)", THERMAL_PATH, ret); + return ret; + } + + if (value < 30) { + info->state = THERMAL_STATE_LOW; + info->level = THERMAL_LEVEL_NORMAL; + return 0; + } + + if (value < 40) { + info->state = THERMAL_STATE_NORMAL; + info->level = THERMAL_LEVEL_NORMAL; + return 0; + } + + info->state = THERMAL_STATE_HIGH; + + if (value < 42) + info->level = THERMAL_LEVEL_WARNING; + else if (value < 43) + info->level = THERMAL_LEVEL_CRITICAL; + else + info->level = THERMAL_LEVEL_POWEROFF; + + return 0; +} + +static gboolean thermal_timeout(gpointer data) +{ + struct thermal_info info; + int ret; + + ret = thermal_get_state(&info); + if (ret < 0) { + _E("Failed to read thermal state (%d)", ret); + return G_SOURCE_CONTINUE; + } + + if (edata.updated_cb) + edata.updated_cb(&info, edata.data); + + return G_SOURCE_CONTINUE; +} + +static int thermal_register_changed_event(ThermalUpdated updated_cb, void *data) +{ + if (timer) + g_source_remove(timer); + + timer = g_timeout_add(10000, thermal_timeout, NULL); + if (timer == 0) { + _E("Failed to add timer for thermal"); + return -ENOENT; + } + + edata.updated_cb = updated_cb; + edata.data = data; + + return 0; +} + +static int thermal_unregister_changed_event(ThermalUpdated updated_cb) +{ + if (timer) { + g_source_remove(timer); + timer = 0; + } + + edata.updated_cb = NULL; + edata.data = NULL; + + return 0; +} + +static int thermal_open(struct hw_info *info, + const char *id, struct hw_common **common) +{ + struct thermal_device *thermal_dev; + + if (!info || !common) + return -EINVAL; + + thermal_dev = calloc(1, sizeof(struct thermal_device)); + if (!thermal_dev) + return -ENOMEM; + + thermal_dev->common.info = info; + thermal_dev->register_changed_event + = thermal_register_changed_event; + thermal_dev->unregister_changed_event + = thermal_unregister_changed_event; + thermal_dev->get_state + = thermal_get_state; + + *common = (struct hw_common *)thermal_dev; + return 0; +} + +static int thermal_close(struct hw_common *common) +{ + if (!common) + return -EINVAL; + + free(common); + return 0; +} + +HARDWARE_MODULE_STRUCTURE = { + .magic = HARDWARE_INFO_TAG, + .hal_version = HARDWARE_INFO_VERSION, + .device_version = THERMAL_HARDWARE_DEVICE_VERSION, + .id = THERMAL_HARDWARE_DEVICE_ID, + .name = "thermal", + .open = thermal_open, + .close = thermal_close, +}; -- 2.7.4