mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 01:22:25 +00:00
qca-thermald-10.4: drop legacy package
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=qca-thermald-10.4
|
||||
PKG_RELEASE:=1
|
||||
|
||||
QCA_THERMALD_MAKE_OPTS:= \
|
||||
CROSS=$(TARGET_CROSS) \
|
||||
THERMALDIR=$(PKG_BUILD_DIR) \
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/qca-thermald-10.4
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
URL:=http://www.qca.qualcomm.com
|
||||
MAINTAINER:=Qualcomm Atheros
|
||||
DEPENDS:=+libpthread @TARGET_ipq807x
|
||||
TITLE:=Thermal Mitigation daemon
|
||||
endef
|
||||
|
||||
define Package/qca-thermald-10.4/description
|
||||
This package is IPQ Thermal Mitigation daemon.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCA_THERMALD_MAKE_OPTS))
|
||||
endef
|
||||
|
||||
define Package/qca-thermald-10.4/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/usr/sbin/thermald $(1)/usr/sbin
|
||||
$(INSTALL_DIR) $(1)/etc/thermal
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/etc/thermal/ipq-thermald-8064.conf $(1)/etc/thermal
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/etc/thermal/ipq-thermald-8066.conf $(1)/etc/thermal
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/etc/thermal/ipq-thermald-8069.conf $(1)/etc/thermal
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/thermal.init $(1)/etc/init.d/thermal
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_BIN) ./files/thermal.config $(1)/etc/config/thermal
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,qca-thermald-10.4))
|
||||
@@ -1,2 +0,0 @@
|
||||
config thermal config
|
||||
option Enabled '1'
|
||||
@@ -1,23 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=98
|
||||
|
||||
SERVICE_WRITE_PID=1
|
||||
SERVICE_DAEMONIZE=1
|
||||
|
||||
start() {
|
||||
. /lib/functions.sh
|
||||
|
||||
local enabled
|
||||
|
||||
config_load 'thermal'
|
||||
config_get_bool enabled config 'Enabled' '0'
|
||||
|
||||
[ "$enabled" -gt 0 ] || return 1
|
||||
|
||||
service_start /usr/sbin/thermald
|
||||
}
|
||||
|
||||
stop() {
|
||||
service_stop /usr/sbin/thermald
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
BOARD_PLATFORM_LIST := msm7630_surf
|
||||
BOARD_PLATFORM_LIST += msm7630_fusion
|
||||
BOARD_PLATFORM_LIST += msm8660
|
||||
BOARD_PLATFORM_LIST += msm8960
|
||||
BOARD_PLATFORM_LIST += msm7627a
|
||||
BOARD_PLATFORM_LIST += msm8974
|
||||
|
||||
ifeq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
|
||||
|
||||
IS_MSM7630:=$(strip $(call is-chipset-in-board-platform,msm7630))
|
||||
IS_MSM8660:=$(strip $(call is-board-platform,msm8660))
|
||||
IS_MSM8960:=$(strip $(call is-board-platform,msm8960))
|
||||
IS_MSM8625:=$(strip $(call is-board-platform,msm7627a))
|
||||
IS_MSM8974:=$(strip $(call is-board-platform,msm8974))
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
include $(QC_PROP_ROOT)/common/build/remote_api_makefiles/target_api_enables.mk
|
||||
include $(QC_PROP_ROOT)/common/build/remote_api_makefiles/remote_api_defines.mk
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(TARGET_OUT_HEADERS)/common/inc \
|
||||
$(TARGET_OUT_HEADERS)/oncrpc/inc \
|
||||
$(TARGET_OUT_HEADERS)/diag/include \
|
||||
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/
|
||||
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
thermal.c \
|
||||
thermal_config.c \
|
||||
thermal_monitor.c \
|
||||
thermal_actions.c \
|
||||
thermal_util.c \
|
||||
thermal_server.c \
|
||||
thermal_lib_common.c
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils
|
||||
|
||||
LOCAL_CFLAGS := -DCONFIG_FILE_DEFAULT='"/system/etc/thermald.conf"'
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/posix_types.h
|
||||
|
||||
ifneq ($(call is-platform-sdk-version-at-least,17),true)
|
||||
# Override socket-related kernel headers with Bionic version before JB MR1
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/byteorder.h
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/posix_types.h
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/types.h
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/socket.h
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/in.h
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/netlink.h
|
||||
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/un.h
|
||||
endif
|
||||
|
||||
ifneq ($(IS_MSM8625),)
|
||||
LOCAL_SRC_FILES += sensors-8x25.c
|
||||
LOCAL_CFLAGS += -DSENSORS_8625
|
||||
ifeq ($(ADC_ENABLE),1)
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/adc/inc
|
||||
LOCAL_SHARED_LIBRARIES += libadc liboncrpc
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(IS_MSM7630),)
|
||||
LOCAL_SRC_FILES += sensors-7x30.c
|
||||
LOCAL_CFLAGS += -DSENSORS_7630
|
||||
THERMALD_CONF := thermald-7x30.conf
|
||||
endif
|
||||
|
||||
ifneq ($(IS_MSM8660),)
|
||||
LOCAL_SRC_FILES += tsens-sensor.c sensors-8660.c
|
||||
LOCAL_CFLAGS += -DSENSORS_8660
|
||||
LOCAL_CFLAGS += -DENABLE_TSENS_INTERRUPT
|
||||
ENABLE_MODEM_MITIGATION_ONCRPC:=1
|
||||
ENABLE_FUSION_MODEM:=1
|
||||
THERMALD_CONF := thermald-8660.conf
|
||||
endif
|
||||
|
||||
ifneq ($(IS_MSM8960),)
|
||||
LOCAL_SRC_FILES += tsens-sensor.c adc-sensor.c sensors-8960.c gen-sensor.c bcl-sensor.c pm8821-sensor.c
|
||||
LOCAL_CFLAGS += -DSENSORS_8960
|
||||
LOCAL_CFLAGS += -DENABLE_TSENS_INTERRUPT
|
||||
ENABLE_MODEM_MITIGATION_QMI:=1
|
||||
ENABLE_MODEM_TS_QMI:=1
|
||||
endif
|
||||
|
||||
ifneq ($(IS_MSM8974),)
|
||||
LOCAL_SRC_FILES += tsens-sensor.c adc-sensor.c sensors-8974.c gen-sensor.c bcl-sensor.c
|
||||
LOCAL_CFLAGS += -DSENSORS_8974
|
||||
#ENABLE_MODEM_MITIGATION_QMI:=1
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_MODEM_MITIGATION_ONCRPC),)
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/thermal_mitigation/inc
|
||||
LOCAL_CFLAGS += -DENABLE_MODEM_MITIGATION
|
||||
LOCAL_SRC_FILES += modem_mitigation_oncrpc.c
|
||||
LOCAL_SHARED_LIBRARIES += liboncrpc
|
||||
LOCAL_SHARED_LIBRARIES += libthermal_mitigation
|
||||
|
||||
ifneq ($(ENABLE_FUSION_MODEM),)
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/thermal_mitigation_fusion/inc
|
||||
LOCAL_CFLAGS += -DENABLE_FUSION_MODEM
|
||||
LOCAL_SHARED_LIBRARIES += libthermal_mitigation_fusion
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_MODEM_MITIGATION_QMI),)
|
||||
LOCAL_CFLAGS += -DENABLE_MODEM_MITIGATION
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc
|
||||
LOCAL_SRC_FILES += modem_mitigation_qmi.c
|
||||
LOCAL_SRC_FILES += thermal_mitigation_device_service_v01.c
|
||||
LOCAL_SHARED_LIBRARIES += libqmi_cci libqmi_common_so
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_MODEM_TS_QMI),)
|
||||
LOCAL_CFLAGS += -DENABLE_MODEM_TS
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/inc
|
||||
LOCAL_SRC_FILES += modem_sensor_qmi.c qmi-ts-sensor.c
|
||||
LOCAL_SRC_FILES += thermal_sensor_service_v01.c
|
||||
LOCAL_SHARED_LIBRARIES += libqmi_cci libqmi_common_so
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
-DUSE_ANDROID_LOG \
|
||||
|
||||
LOCAL_MODULE := thermald
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
#Install thermal client library
|
||||
#include $(CLEAR_VARS)
|
||||
|
||||
#LOCAL_C_INCLUDES := \
|
||||
$(TARGET_OUT_HEADERS)/common/inc \
|
||||
$(TARGET_OUT_HEADERS)/diag/include
|
||||
|
||||
#LOCAL_SHARED_LIBRARIES := libcutils \
|
||||
libdiag
|
||||
|
||||
#LOCAL_SRC_FILES:= thermal_client.c thermal_lib_common.c
|
||||
#LOCAL_MODULE:= libthermalclient
|
||||
#LOCAL_MODULE_TAGS := optional
|
||||
#LOCAL_CFLAGS = \
|
||||
-DUSE_ANDROID_LOG
|
||||
#LOCAL_MODULE_OWNER := qcom
|
||||
#LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
#include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# Install thermal configuration
|
||||
ifneq ($(IS_MSM8974),)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8974.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8974.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
else ifneq ($(IS_MSM8960),)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8960.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8960.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8064.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8064.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8930.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8930.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8960ab.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8960ab.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8064ab.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8064ab.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8930ab.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8930ab.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
else ifneq ($(IS_MSM8625),)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8x25-msm1-pmic_therm.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8x25-msm1-pmic_therm.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8x25-msm2-pmic_therm.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8x25-msm2-pmic_therm.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald-8x25-msm2-msm_therm.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := thermald-8x25-msm2-msm_therm.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
else
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := thermald.conf
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := $(THERMALD_CONF)
|
||||
include $(BUILD_PREBUILT)
|
||||
endif
|
||||
|
||||
endif
|
||||
@@ -1,74 +0,0 @@
|
||||
#****************************************************************************
|
||||
#
|
||||
# Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
# All Rights Reserved.
|
||||
# Qualcomm Atheros Confidential and Proprietary.
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
ifneq ($(strip $(TOOLPREFIX)),)
|
||||
export CROSS:=$(TOOLPREFIX)
|
||||
endif
|
||||
|
||||
THERMALD_INSTALL_ROOT := $(THERMALDIR)/install
|
||||
|
||||
ifndef INSTALL_ROOT
|
||||
INSTALL_ROOT=$(THERMALD_INSTALL_ROOT)
|
||||
endif
|
||||
|
||||
export CC = $(CROSS)gcc
|
||||
export CFLAGS += -O2 -Wall -DIPQ_806x -c
|
||||
export STRIP = $(CROSS)strip
|
||||
export SOURCES= \
|
||||
thermal.c \
|
||||
thermal_config.c \
|
||||
thermal_util.c \
|
||||
thermal_monitor.c \
|
||||
thermal_actions.c \
|
||||
sensors-ipq.c \
|
||||
tsens-sensor.c
|
||||
export OBJECTS=$(SOURCES:.c=.o)
|
||||
export EXECUTABLE=thermald
|
||||
|
||||
LIBS += -lpthread -ldl
|
||||
CFLAGS += -L$(INSTALL_ROOT)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) \
|
||||
-fstack-protector-all -fpie
|
||||
LDFLAGS += $(TARGET_LDFLAGS) -pie
|
||||
|
||||
# What we build by default:
|
||||
ALL = $(EXECUTABLE)
|
||||
|
||||
# RULES ---------------------------------------------------------------
|
||||
|
||||
# Making default targets:
|
||||
all: local install
|
||||
@echo All done in `pwd`
|
||||
|
||||
$(EXECUTABLE): $(OBJECTS)
|
||||
$(CC) $(LIB_PATH) $(LIBS) $(LDFLAGS) $(OBJECTS) -o $@
|
||||
@echo Build $@ successufully...
|
||||
|
||||
.c.o:
|
||||
$(CC) $(INCLUDE) $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.d $(EXECUTABLE)
|
||||
|
||||
local: $(SOURCES) $(EXECUTABLE)
|
||||
@echo Build $@ successufully...
|
||||
|
||||
# Doing installation (see comments at top of this file)
|
||||
install: local
|
||||
mkdir -p $(INSTALL_ROOT)/usr/sbin/
|
||||
cp -a -f $(ALL) $(INSTALL_ROOT)/usr/sbin/
|
||||
mkdir -p $(INSTALL_ROOT)/etc/thermal
|
||||
cp -a -f ipq-thermald-806?.conf $(INSTALL_ROOT)/etc/thermal/
|
||||
@echo Installed outputs from `pwd`
|
||||
|
||||
# Remove all generated files
|
||||
#clean: default_clean # from Makefile.rules
|
||||
clean:
|
||||
rm -rf install/usr/sbin/thermal
|
||||
rm -rf ./$(ALL)
|
||||
|
||||
# END --------------------------------------------------------------------
|
||||
@@ -1,35 +0,0 @@
|
||||
AM_CFLAGS = -Wall \
|
||||
-Wundef \
|
||||
-Wstrict-prototypes \
|
||||
-Wno-trigraphs \
|
||||
-Werror
|
||||
|
||||
AM_CPPFLAGS = -DENABLE_TSENS_INTERRUPT \
|
||||
-DENABLE_MODEM_MITIGATION \
|
||||
-DSENSORS_8960 \
|
||||
-DCONFIG_FILE_DEFAULT='"/etc/thermald.conf"' \
|
||||
$(QMIF_CFLAGS)
|
||||
|
||||
thermald_SOURCES = \
|
||||
thermal.c \
|
||||
thermal_config.c \
|
||||
thermal_monitor.c \
|
||||
thermal_actions.c \
|
||||
thermal_util.c \
|
||||
adc-sensor.c \
|
||||
tsens-sensor.c \
|
||||
sensors-8960.c \
|
||||
modem_mitigation_qmi.c \
|
||||
thermal_mitigation_device_service_v01.c
|
||||
|
||||
if USE_GLIB
|
||||
thermald_CFLAGS = $(AM_CFLAGS) -DUSE_GLIB @GLIB_CFLAGS@
|
||||
thermald_LDFLAGS = -lpthread -lrt @GLIB_LIBS@ $(QMIF_LIBS)
|
||||
else
|
||||
thermald_LDFLAGS = -lpthread -lrt $(QMIF_LIBS)
|
||||
endif
|
||||
|
||||
bin_PROGRAMS = thermald
|
||||
sysconf_DATA = thermald-9x15.conf
|
||||
install-data-hook:
|
||||
mv $(DESTDIR)$(sysconfdir)/$(sysconf_DATA) $(DESTDIR)$(sysconfdir)/thermald.conf
|
||||
@@ -1,119 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
adc-sensor.c
|
||||
|
||||
DESCRIPTION
|
||||
ADC sensor access functions.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
setup() function should be called before get_temperature().
|
||||
shutdown() function should be called to clean up resources.
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
#define MSM_ADC_NODE_PM8921 "/sys/devices/platform/msm_ssbi.0/pm8921-core/pm8xxx-adc/%s"
|
||||
#define MSM_ADC_NODE_PM8038 "/sys/devices/platform/msm_ssbi.0/pm8038-core/pm8xxx-adc/%s"
|
||||
#define MSM_PM8921 "/sys/devices/platform/msm_ssbi.0/pm8921-core"
|
||||
#define MSM_PM8038 "/sys/devices/platform/msm_ssbi.0/pm8038-core"
|
||||
#define LVL_BUF_MAX (12)
|
||||
|
||||
static char *get_adc_sysfs()
|
||||
{
|
||||
struct stat filestat;
|
||||
|
||||
int msm_id = therm_get_msm_id();
|
||||
|
||||
switch (msm_id) {
|
||||
case THERM_MSM_8960AB:
|
||||
case THERM_MSM_8960:
|
||||
case THERM_MSM_8064AB:
|
||||
case THERM_MSM_8064:
|
||||
return MSM_ADC_NODE_PM8921;
|
||||
case THERM_MSM_8930AB:
|
||||
case THERM_MSM_8930AA:
|
||||
case THERM_MSM_8930:
|
||||
if (stat(MSM_PM8038, &filestat) > -1)
|
||||
return MSM_ADC_NODE_PM8038;
|
||||
else if(stat(MSM_PM8921, &filestat) > -1)
|
||||
return MSM_ADC_NODE_PM8921;
|
||||
else
|
||||
return NULL;
|
||||
default:
|
||||
dbgmsg("%s: ADC sensors unsupported on target %d",
|
||||
__func__, msm_id);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int adc_sensors_setup(sensor_setting_t *setting, sensor_t *sensor)
|
||||
{
|
||||
int fd = -1;
|
||||
int sensor_count = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
char *adc_sysfs = NULL;
|
||||
|
||||
/* We have nothing to do if there are no thresholds */
|
||||
if (!setting->num_thresholds) {
|
||||
dbgmsg("No thresholds for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
adc_sysfs = get_adc_sysfs();
|
||||
if (adc_sysfs == NULL) {
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
snprintf(name, MAX_PATH, adc_sysfs, sensor->name);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
sensor_count++;
|
||||
setting->disabled = 0;
|
||||
setting->chan_idx = fd;
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void adc_sensors_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->chan_idx > 0)
|
||||
close(setting->chan_idx);
|
||||
}
|
||||
|
||||
int adc_sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[3*LVL_BUF_MAX] = {0};
|
||||
int temp = 0;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1) {
|
||||
sscanf(buf, "Result:%d Raw:%*d\n", &temp);
|
||||
}
|
||||
|
||||
lseek(setting->chan_idx, 0, SEEK_SET);
|
||||
return CONV(temp);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#ifndef __ADC_SENSOR_H__
|
||||
#define __ADC_SENSOR_H__
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
int adc_sensors_setup(sensor_setting_t *settings, sensor_t * sensor);
|
||||
void adc_sensors_shutdown(sensor_setting_t *setting);
|
||||
int adc_sensor_get_temperature(sensor_setting_t *setting);
|
||||
|
||||
#endif /* __ADC_SENSOR_H__ */
|
||||
@@ -1,674 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
bcl-sensor.c
|
||||
|
||||
DESCRIPTION
|
||||
BCL sensor access functions.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
setup() function should be called before get_temperature().
|
||||
shutdown() function should be called to clean up resources.
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "bcl-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
#define LVL_BUF_MAX (12)
|
||||
|
||||
#ifndef BCL_DUMP_FILE_DEFAULT
|
||||
#define BCL_DUMP_FILE_DEFAULT "/data/bcl_dump.log"
|
||||
#endif
|
||||
|
||||
/* BCL sysfs defines */
|
||||
#define BCL_MODE "/sys/devices/platform/battery_current_limit/mode"
|
||||
#define BCL_TYPE "/sys/devices/platform/battery_current_limit/type"
|
||||
#define BCL_IBAT "/sys/devices/platform/battery_current_limit/ibat"
|
||||
#define BCL_IMAX "/sys/devices/platform/battery_current_limit/imax"
|
||||
#define BCL_VBAT "/sys/devices/platform/battery_current_limit/vbat"
|
||||
#define BCL_RBAT "/sys/devices/platform/battery_current_limit/rbat"
|
||||
#define BCL_OCV "/sys/devices/platform/battery_current_limit/ocv"
|
||||
#define BCL_SOC "/sys/class/power_supply/battery/capacity"
|
||||
#define BCL_POLL_INTERVAL "/sys/devices/platform/battery_current_limit/poll_interval"
|
||||
#define BCL_IBAT_IMAX_LOW_THRESHOLD_MODE "/sys/devices/platform/battery_current_limit/ibat_imax_low_threshold_mode"
|
||||
#define BCL_IBAT_IMAX_HIGH_THRESHOLD_MODE "/sys/devices/platform/battery_current_limit/ibat_imax_high_threshold_mode"
|
||||
#define BCL_IBAT_IMAX_LOW_THRESHOLD_VALUE "/sys/devices/platform/battery_current_limit/ibat_imax_low_threshold_value"
|
||||
#define BCL_IBAT_IMAX_HIGH_THRESHOLD_VALUE "/sys/devices/platform/battery_current_limit/ibat_imax_high_threshold_value"
|
||||
|
||||
typedef struct bcl_data {
|
||||
pthread_t bcl_thread;
|
||||
pthread_mutex_t bcl_mutex;
|
||||
pthread_cond_t bcl_condition;
|
||||
int threshold_reached;
|
||||
int hi_threshold, lo_threshold;
|
||||
int hi_idx, lo_idx;
|
||||
int sensor_shutdown;
|
||||
sensor_t *sensor;
|
||||
|
||||
FILE *dump_bcl_fd;
|
||||
unsigned int ibat_idx;
|
||||
unsigned int imax_idx;
|
||||
unsigned int vbat_idx;
|
||||
unsigned int rbat_idx;
|
||||
unsigned int soc_idx;
|
||||
unsigned int ocv_idx;
|
||||
int ibat;
|
||||
int imax;
|
||||
|
||||
} bcl_data;
|
||||
|
||||
static void *bcl_uevent(void *data)
|
||||
{
|
||||
int err = 0;
|
||||
sensor_t *sensor = (sensor_t *)data;
|
||||
struct pollfd fds;
|
||||
int fd;
|
||||
char uevent[MAX_PATH] = {0};
|
||||
char buf[MAX_PATH] = {0};
|
||||
bcl_data *bcl = NULL;
|
||||
|
||||
if (NULL == sensor ||
|
||||
NULL == sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return NULL;
|
||||
}
|
||||
bcl = (bcl_data *) sensor->data;
|
||||
|
||||
/* Looking for bcl uevent */
|
||||
strlcpy(uevent, BCL_TYPE, MAX_PATH);
|
||||
|
||||
fd = open(uevent, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("Unable to open %s to receive notifications.\n", uevent);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
while (!bcl->sensor_shutdown) {
|
||||
fds.fd = fd;
|
||||
fds.events = POLLERR|POLLPRI;
|
||||
fds.revents = 0;
|
||||
|
||||
err = poll(&fds, 1, -1);
|
||||
if (err == -1) {
|
||||
msg("Error in uevent poll.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
read(fd, buf, sizeof(buf));
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
dbgmsg("BCL uevent :%s", buf);
|
||||
|
||||
/* notify the waiting threads */
|
||||
pthread_mutex_lock(&(bcl->bcl_mutex));
|
||||
bcl->threshold_reached = 1;
|
||||
pthread_cond_broadcast(&(bcl->bcl_condition));
|
||||
pthread_mutex_unlock(&(bcl->bcl_mutex));
|
||||
}
|
||||
|
||||
if (fd > -1)
|
||||
close(fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void enable_bcl(bcl_data *bcl, int enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
|
||||
if (NULL == bcl ||
|
||||
NULL == bcl->sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(name, BCL_MODE, MAX_PATH);
|
||||
if (enabled)
|
||||
ret = write_to_file(name, "enabled", strlen("enabled"));
|
||||
else
|
||||
ret = write_to_file(name, "disabled", strlen("disabled"));
|
||||
|
||||
if (ret <= 0) {
|
||||
msg("BCL failed to set mode %d\n", enabled);
|
||||
} else {
|
||||
dbgmsg("BCL mode set to %d\n", enabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void enable_bcl_threshold_high(bcl_data *bcl, int enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
|
||||
if (NULL == bcl ||
|
||||
NULL == bcl->sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(name, BCL_IBAT_IMAX_HIGH_THRESHOLD_MODE, MAX_PATH);
|
||||
if (enabled)
|
||||
ret = write_to_file(name, "enabled", strlen("enabled"));
|
||||
else
|
||||
ret = write_to_file(name, "disabled", strlen("disabled"));
|
||||
|
||||
if (ret <= 0) {
|
||||
msg("BCL high threshold failed to %d\n", enabled);
|
||||
} else {
|
||||
dbgmsg("BCL high threshold enabled: %d\n", enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_bcl_threshold_low(bcl_data *bcl, int enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
|
||||
if (NULL == bcl ||
|
||||
NULL == bcl->sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(name, BCL_IBAT_IMAX_LOW_THRESHOLD_MODE, MAX_PATH);
|
||||
if (enabled)
|
||||
ret = write_to_file(name, "enabled", strlen("enabled"));
|
||||
else
|
||||
ret = write_to_file(name, "disabled", strlen("disabled"));
|
||||
|
||||
if (ret <= 0) {
|
||||
msg("BCL low threshold failed to %d\n", enabled);
|
||||
} else {
|
||||
dbgmsg("BCL low threshold enabled: %d\n", enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void set_bcl_thresholds(bcl_data *bcl, int lvl, int lvl_clr,
|
||||
int hi_enable, int lo_enable)
|
||||
{
|
||||
char highname[MAX_PATH]= {0};
|
||||
char lowname[MAX_PATH]= {0};
|
||||
char buf[LVL_BUF_MAX] = {0};
|
||||
int ret = 0;
|
||||
int lowbcl = 0;
|
||||
|
||||
if (NULL == bcl) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(highname, BCL_IBAT_IMAX_HIGH_THRESHOLD_VALUE, MAX_PATH);
|
||||
strlcpy(lowname, BCL_IBAT_IMAX_LOW_THRESHOLD_VALUE, MAX_PATH);
|
||||
|
||||
/* Set thresholds in legal order */
|
||||
if (read_line_from_file(lowname, buf, sizeof(buf)) > 0) {
|
||||
lowbcl = atoi(buf);
|
||||
}
|
||||
|
||||
if (lvl <= lowbcl) {
|
||||
/* set high threshold first */
|
||||
dbgmsg("Setting up BCL thresholds high: %d\n", lvl);
|
||||
enable_bcl_threshold_high(bcl, hi_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
|
||||
ret = write_to_file(highname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("BCL threshold high failed to set %d\n", lvl);
|
||||
|
||||
dbgmsg("Setting up BCL thresholds low: %d\n", lvl_clr);
|
||||
enable_bcl_threshold_low(bcl, lo_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
|
||||
ret = write_to_file(lowname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("BCL threshold low failed to set %d\n", lvl_clr);
|
||||
|
||||
} else {
|
||||
dbgmsg("Setting up BCL thresholds low: %d\n", lvl_clr);
|
||||
enable_bcl_threshold_low(bcl, lo_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
|
||||
ret = write_to_file(lowname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("BCL threshold low failed to set %d\n", lvl_clr);
|
||||
|
||||
dbgmsg("Setting up BCL thresholds high: %d\n", lvl);
|
||||
enable_bcl_threshold_high(bcl, hi_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
|
||||
ret = write_to_file(highname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("BCL threshold high failed to set %d\n", lvl);
|
||||
}
|
||||
|
||||
bcl->hi_threshold = lvl;
|
||||
bcl->lo_threshold = lvl_clr;
|
||||
}
|
||||
|
||||
void bcl_enable_thresholds(sensor_setting_t *setting, int enabled)
|
||||
{
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("bcl: unexpected NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
enable_bcl_threshold_high(setting->sensor->data, enabled);
|
||||
enable_bcl_threshold_low(setting->sensor->data, enabled);
|
||||
}
|
||||
|
||||
void bcl_enable(sensor_setting_t *setting, int enabled)
|
||||
{
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("bcl: unexpected NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
enable_bcl(setting->sensor->data, enabled);
|
||||
}
|
||||
|
||||
/* NOTE: bcl_setup() function does not enable the sensor
|
||||
* or set thresholds. This should be done in the target-specific setup */
|
||||
int bcl_setup(sensor_setting_t *setting, sensor_t *sensor)
|
||||
{
|
||||
int fd = -1;
|
||||
int sensor_count = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
bcl_data *bcl = NULL;
|
||||
char buf[LVL_BUF_MAX] = {0};
|
||||
int ret = 0;
|
||||
const char *dump_bcl_file = (dump_bcl_ibat_imax_file) ? dump_bcl_ibat_imax_file : BCL_DUMP_FILE_DEFAULT;
|
||||
|
||||
/* We have nothing to do if there are no thresholds */
|
||||
if (!setting->num_thresholds) {
|
||||
dbgmsg("No thresholds for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
/* Allocate BCL data */
|
||||
bcl = (bcl_data *) malloc(sizeof(bcl_data));
|
||||
if (NULL == bcl) {
|
||||
msg("%s: malloc failed", __func__);
|
||||
return sensor_count;
|
||||
}
|
||||
memset(bcl, 0, sizeof(bcl_data));
|
||||
sensor->data = (void *) bcl;
|
||||
|
||||
if (dump_bcl_ibat_imax) {
|
||||
bcl->dump_bcl_fd = fopen(dump_bcl_file, "w");
|
||||
if (bcl->dump_bcl_fd == NULL) {
|
||||
msg("Failed to open BCL dump file %s\n", dump_bcl_file);
|
||||
free(bcl);
|
||||
return sensor_count;
|
||||
}
|
||||
fprintf(bcl->dump_bcl_fd, "ibat(mA) imax(mA) vbat(mV) ocv(uV) rbat(mOhms) soc\n");
|
||||
fflush(bcl->dump_bcl_fd);
|
||||
}
|
||||
|
||||
sensor->tzn = 0;
|
||||
|
||||
strlcpy(name, BCL_IBAT, MAX_PATH);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
if (bcl->dump_bcl_fd != NULL)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
return sensor_count;
|
||||
}
|
||||
bcl->ibat_idx = fd;
|
||||
|
||||
strlcpy(name, BCL_IMAX, MAX_PATH);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
close(bcl->ibat_idx);
|
||||
if (bcl->dump_bcl_fd != NULL)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
return sensor_count;
|
||||
}
|
||||
bcl->imax_idx = fd;
|
||||
|
||||
strlcpy(name, BCL_VBAT, MAX_PATH);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
close(bcl->ibat_idx);
|
||||
close(bcl->imax_idx);
|
||||
if (bcl->dump_bcl_fd != NULL)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
return sensor_count;
|
||||
}
|
||||
bcl->vbat_idx = fd;
|
||||
|
||||
strlcpy(name, BCL_RBAT, MAX_PATH);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
close(bcl->ibat_idx);
|
||||
close(bcl->imax_idx);
|
||||
close(bcl->vbat_idx);
|
||||
if (bcl->dump_bcl_fd != NULL)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
return sensor_count;
|
||||
}
|
||||
bcl->rbat_idx = fd;
|
||||
|
||||
strlcpy(name, BCL_SOC, MAX_PATH);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
close(bcl->ibat_idx);
|
||||
close(bcl->imax_idx);
|
||||
close(bcl->vbat_idx);
|
||||
close(bcl->rbat_idx);
|
||||
if (bcl->dump_bcl_fd != NULL)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
return sensor_count;
|
||||
}
|
||||
bcl->soc_idx = fd;
|
||||
|
||||
strlcpy(name, BCL_OCV, MAX_PATH);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
close(bcl->ibat_idx);
|
||||
close(bcl->imax_idx);
|
||||
close(bcl->vbat_idx);
|
||||
close(bcl->rbat_idx);
|
||||
close(bcl->soc_idx);
|
||||
if (bcl->dump_bcl_fd != NULL)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
return sensor_count;
|
||||
}
|
||||
bcl->ocv_idx = fd;
|
||||
|
||||
sensor_count++;
|
||||
pthread_mutex_init(&(bcl->bcl_mutex), NULL);
|
||||
pthread_cond_init(&(bcl->bcl_condition), NULL);
|
||||
bcl->sensor_shutdown = 0;
|
||||
bcl->threshold_reached = 0;
|
||||
bcl->sensor = sensor;
|
||||
setting->disabled = 0;
|
||||
|
||||
if (sensor->interrupt_enable) {
|
||||
pthread_create(&(bcl->bcl_thread), NULL,
|
||||
bcl_uevent, sensor);
|
||||
}
|
||||
|
||||
strlcpy(name, BCL_POLL_INTERVAL, MAX_PATH);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", setting->sampling_period_us/1000);
|
||||
ret = write_to_file(name, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("BCL poll interval failed to set %d\n", setting->sampling_period_us);
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void bcl_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
bcl->sensor_shutdown = 1;
|
||||
|
||||
if (bcl->imax_idx > 0)
|
||||
close(bcl->imax_idx);
|
||||
|
||||
if (bcl->ibat_idx > 0)
|
||||
close(bcl->ibat_idx);
|
||||
|
||||
if (bcl->vbat_idx > 0)
|
||||
close(bcl->vbat_idx);
|
||||
|
||||
if (bcl->rbat_idx > 0)
|
||||
close(bcl->rbat_idx);
|
||||
|
||||
if (bcl->soc_idx > 0)
|
||||
close(bcl->soc_idx);
|
||||
|
||||
if (bcl->ocv_idx > 0)
|
||||
close(bcl->ocv_idx);
|
||||
|
||||
if (bcl->dump_bcl_fd)
|
||||
fclose(bcl->dump_bcl_fd);
|
||||
|
||||
if (setting->sensor->interrupt_enable)
|
||||
pthread_join(bcl->bcl_thread, NULL);
|
||||
free(bcl);
|
||||
}
|
||||
|
||||
int bcl_get_imax(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[64];
|
||||
int temp = 0;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
if (read(bcl->imax_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(bcl->imax_idx, 0, SEEK_SET);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
int bcl_get_vbat(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[64];
|
||||
int temp = 0;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
if (read(bcl->vbat_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(bcl->vbat_idx, 0, SEEK_SET);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
int bcl_get_rbat(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[64];
|
||||
int temp = 0;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
if (read(bcl->rbat_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(bcl->rbat_idx, 0, SEEK_SET);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
int bcl_get_soc(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[64];
|
||||
int temp = 0;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
if (read(bcl->soc_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(bcl->soc_idx, 0, SEEK_SET);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
int bcl_get_ocv(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[64];
|
||||
int temp = 0;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
if (read(bcl->ocv_idx, buf, sizeof(buf) -1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(bcl->ocv_idx, 0, SEEK_SET);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
int bcl_get_ibat(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[64];
|
||||
int temp = 0;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
if (read(bcl->ibat_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(bcl->ibat_idx, 0, SEEK_SET);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
int bcl_get_diff_imax_ibat(sensor_setting_t *setting)
|
||||
{
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (bcl_get_imax(setting) - bcl_get_ibat(setting));
|
||||
}
|
||||
|
||||
void bcl_interrupt_wait(sensor_setting_t *setting)
|
||||
{
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
|
||||
if (dump_bcl_ibat_imax == 1) {
|
||||
usleep(setting->sampling_period_us);
|
||||
/* Read all BCL related params for dumping to a file */
|
||||
bcl->ibat = bcl_get_ibat(setting);
|
||||
bcl->imax = bcl_get_imax(setting);
|
||||
|
||||
if (bcl->dump_bcl_fd) {
|
||||
fprintf(bcl->dump_bcl_fd, "%d %d %d %d %d %d\n", bcl->ibat, bcl->imax, bcl_get_vbat(setting),
|
||||
bcl_get_ocv(setting), bcl_get_rbat(setting), bcl_get_soc(setting));
|
||||
fflush(bcl->dump_bcl_fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (setting->sensor->interrupt_enable) {
|
||||
/* Wait for sensor threshold condition */
|
||||
pthread_mutex_lock(&(bcl->bcl_mutex));
|
||||
while (!bcl->threshold_reached) {
|
||||
pthread_cond_wait(&(bcl->bcl_condition),
|
||||
&(bcl->bcl_mutex));
|
||||
}
|
||||
bcl->threshold_reached = 0;
|
||||
pthread_mutex_unlock(&(bcl->bcl_mutex));
|
||||
/* Read all BCL related params after event is fired */
|
||||
bcl->ibat = bcl_get_ibat(setting);
|
||||
bcl->imax = bcl_get_imax(setting);
|
||||
}
|
||||
}
|
||||
|
||||
void bcl_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
int hi, lo;
|
||||
int hi_enable = 1;
|
||||
int lo_enable = 1;
|
||||
bcl_data *bcl;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
bcl = (bcl_data *) setting->sensor->data;
|
||||
|
||||
dbgmsg("%s: threshold_type %d, level %d", __func__,
|
||||
threshold_type, level);
|
||||
hi = setting->t[bcl->hi_idx].lvl_trig;
|
||||
lo = setting->t[bcl->lo_idx].lvl_clr;
|
||||
if (level >= setting->num_thresholds) {
|
||||
/* handle corner high case */
|
||||
hi = setting->t[setting->num_thresholds - 1].lvl_trig;
|
||||
bcl->hi_idx = setting->num_thresholds - 1;
|
||||
hi_enable = 0;
|
||||
} else {
|
||||
hi = setting->t[level].lvl_trig;
|
||||
bcl->hi_idx = level;
|
||||
}
|
||||
if (level <= 0) {
|
||||
/* handle corner low case */
|
||||
lo = setting->t[0].lvl_clr;
|
||||
bcl->lo_idx = 0;
|
||||
lo_enable = 0;
|
||||
} else {
|
||||
lo = setting->t[level - 1].lvl_clr;
|
||||
bcl->lo_idx = level - 1;
|
||||
}
|
||||
|
||||
set_bcl_thresholds(bcl, hi, lo, hi_enable, lo_enable);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#ifndef __BCL_SENSOR_H__
|
||||
#define __BCL_SENSOR_H__
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
int bcl_setup(sensor_setting_t *settings, sensor_t * sensor);
|
||||
void bcl_shutdown(sensor_setting_t *setting);
|
||||
int bcl_get_imax(sensor_setting_t *setting);
|
||||
int bcl_get_ibat(sensor_setting_t *setting);
|
||||
int bcl_get_diff_imax_ibat(sensor_setting_t *setting);
|
||||
void bcl_enable(sensor_setting_t *setting, int enabled);
|
||||
void bcl_interrupt_wait(sensor_setting_t *setting);
|
||||
void bcl_update_thresholds(sensor_setting_t *setting, int threshold_triggered, int level);
|
||||
|
||||
#endif /* __BCL_SENSOR_H__ */
|
||||
@@ -1,67 +0,0 @@
|
||||
# -*- Autoconf -*-
|
||||
|
||||
# configure.ac -- Autoconf script for diag
|
||||
#
|
||||
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([thermal],
|
||||
1.0.0)
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
AM_MAINTAINER_MODE
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
# Checks for libraries.
|
||||
PKG_CHECK_MODULES([QMIF], [qmi-framework])
|
||||
AC_SUBST([QMIF_CFLAGS])
|
||||
AC_SUBST([QMIF_LIBS])
|
||||
|
||||
AC_ARG_WITH([kernel],
|
||||
AC_HELP_STRING([--with-kernel=@<:@dir@:>@],
|
||||
[Specify the location of the Linux kernel headers]),
|
||||
[kerneldir=$withval],
|
||||
with_kernel=no)
|
||||
|
||||
if test "x$with_kernel" != "xno"; then
|
||||
CFLAGS="${CFLAGS} -I${kerneldir}/include -I${kerneldir}/arch/arm/include"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([glib],
|
||||
AC_HELP_STRING([--with-glib],
|
||||
[enable glib, building HLOS systems which use glib]))
|
||||
|
||||
if (test "x${with_glib}" = "xyes"); then
|
||||
AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
|
||||
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
|
||||
AC_MSG_ERROR(GThread >= 2.16 is required))
|
||||
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
|
||||
AC_MSG_ERROR(GLib >= 2.16 is required))
|
||||
GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
|
||||
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
|
||||
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
|
||||
|
||||
AC_SUBST([CFLAGS])
|
||||
AC_SUBST([CC])
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
gen-sensor.c
|
||||
|
||||
DESCRIPTION
|
||||
Generic thermal zone sensor access functions.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
setup() function should be called before get_temperature().
|
||||
shutdown() function should be called to clean up resources.
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include "thermal.h"
|
||||
|
||||
int gen_sensors_setup(sensor_setting_t *setting, sensor_t* s)
|
||||
{
|
||||
int fd = -1;
|
||||
int sensor_count = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
int tzn = 0;
|
||||
sensor_t *sensor = (sensor_t *)s;
|
||||
|
||||
tzn = get_tzn(sensor->name);
|
||||
if (tzn < 0) {
|
||||
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
/* We have nothing to do if there are no thresholds */
|
||||
if (!setting->num_thresholds) {
|
||||
dbgmsg("No thresholds for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
sensor->tzn = tzn;
|
||||
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
|
||||
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd > -1) {
|
||||
setting->disabled = 0;
|
||||
setting->chan_idx = fd;
|
||||
sensor_count++;
|
||||
} else {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void gen_sensors_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->chan_idx > 0)
|
||||
close(setting->chan_idx);
|
||||
}
|
||||
|
||||
int gen_sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[10] = {0};
|
||||
int temp = 0;
|
||||
|
||||
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(setting->chan_idx, 0, SEEK_SET);
|
||||
|
||||
return temp;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#ifndef __GEN_SENSOR_H__
|
||||
#define __GEN_SENSOR_H__
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
int gen_sensors_setup(sensor_setting_t *settings, sensor_t * sensor);
|
||||
void gen_sensors_shutdown(sensor_setting_t *setting);
|
||||
int gen_sensor_get_temperature(sensor_setting_t *setting);
|
||||
|
||||
#endif /* __GEN_SENSOR_H__ */
|
||||
@@ -1,77 +0,0 @@
|
||||
sampling 5000
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 105 110 115 120 125
|
||||
thresholds_clr 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu shutdown
|
||||
action_info 1200000 1000000 800000 384000 1000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor10]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
@@ -1,77 +0,0 @@
|
||||
sampling 5000
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 115 120 125
|
||||
thresholds_clr 105 110 115
|
||||
actions cpu cpu shutdown
|
||||
action_info 800000 384000 1000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor10]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
@@ -1,77 +0,0 @@
|
||||
sampling 5000
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 115 120 125
|
||||
thresholds_clr 105 110 115
|
||||
actions cpu cpu shutdown
|
||||
action_info 1400000 800000 1000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor10]
|
||||
sampling 1000
|
||||
thresholds 105
|
||||
thresholds_clr 100
|
||||
actions none
|
||||
action_info 0
|
||||
@@ -1,480 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
modem_mitigation_oncrpc.c
|
||||
|
||||
DESCRIPTION
|
||||
Modem mitigation action over ONCRPC.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
modem_communication_init() should be called before the modem_request().
|
||||
|
||||
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "thermal.h"
|
||||
|
||||
#include "oncrpc.h"
|
||||
#include "thermal_mitigation.h"
|
||||
#include "thermal_mitigation_rpc.h"
|
||||
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
#include "thermal_mitigation_fusion.h"
|
||||
#include "thermal_mitigation_fusion_rpc.h"
|
||||
#endif
|
||||
|
||||
/* Modem mitigative action */
|
||||
|
||||
#define MITIGATION_DEVICE "modem"
|
||||
#define MAX_MODEM_MITIGATION_LEVEL (3)
|
||||
#define MODEM_DEVICE 0
|
||||
#define FUSION_DEVICE 1
|
||||
|
||||
static int modem_exists;
|
||||
static int fusion_modem_exists;
|
||||
static unsigned int modem_oncrpc_handle;
|
||||
static unsigned int fusion_oncrpc_handle;
|
||||
static int modem_req[SENSOR_IDX_MAX];
|
||||
static int fusion_modem_req[SENSOR_IDX_MAX];
|
||||
static pthread_mutex_t modem_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t fusion_modem_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int modem_register(void);
|
||||
static int fusion_modem_register(void);
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_thermal_state_cb
|
||||
|
||||
Callback function when modem does its own thermal mitigation.
|
||||
Notifies the interested through the socket.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
None.
|
||||
===========================================================================*/
|
||||
static int modem_thermal_state_cb(const char *device, unsigned int state)
|
||||
{
|
||||
char tempBuf[60];
|
||||
|
||||
dbgmsg("Callback from modem (%s) with state %u", device, state);
|
||||
|
||||
snprintf(tempBuf, sizeof(tempBuf) -1, "%s\n%u", device, state);
|
||||
write_to_local_socket(UI_LOCALSOCKET_NAME, tempBuf, strlen(tempBuf));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION fusion_thermal_state_cb
|
||||
|
||||
Callback function when fusion modem does its own thermal mitigation.
|
||||
Notifies the interested through the socket.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
None.
|
||||
===========================================================================*/
|
||||
static int fusion_thermal_state_cb(const char *device, unsigned int state)
|
||||
{
|
||||
char tempBuf[60];
|
||||
|
||||
dbgmsg("Callback from fusion (%s) with state %u", device, state);
|
||||
|
||||
snprintf(tempBuf, sizeof(tempBuf) -1, "%s\n%u", device, state);
|
||||
write_to_local_socket(UI_LOCALSOCKET_NAME, tempBuf, strlen(tempBuf));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION thermald_oncrpc_cleanup_cb
|
||||
|
||||
Callback function for ONCRPC clean up.
|
||||
|
||||
ARGUMENTS
|
||||
handle : Passed from ONCRPC
|
||||
data: Userdata passed during callback register.
|
||||
|
||||
RETURN VALUE
|
||||
None.
|
||||
===========================================================================*/
|
||||
static void thermald_oncrpc_cleanup_cb(void *handle, void *data)
|
||||
{
|
||||
int type = (int)data;
|
||||
|
||||
switch (type) {
|
||||
case MODEM_DEVICE:
|
||||
info("Modem ONCRPC communication terminated.\n");
|
||||
modem_exists = 0;
|
||||
break;
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
case FUSION_DEVICE:
|
||||
info("Fusion modem ONCRPC communication terminated.\n");
|
||||
fusion_modem_exists = 0;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
msg("Unknown device in %s\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
oncrpc_cleanup_done(handle);
|
||||
dbgmsg("ONCRPC clean up done for %d.\n", type);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION thermald_oncrpc_restart_cb
|
||||
|
||||
Callback for modem/fusion modem restart.
|
||||
|
||||
ARGUMENTS
|
||||
handle : Passed from ONCRPC
|
||||
data: Userdata passed during callback register.
|
||||
|
||||
RETURN VALUE
|
||||
None.
|
||||
===========================================================================*/
|
||||
static void thermald_oncrpc_restart_cb(void *handle, void *data)
|
||||
{
|
||||
int type = (int)data;
|
||||
|
||||
switch (type) {
|
||||
case MODEM_DEVICE:
|
||||
info("Modem restart detected.\n");
|
||||
modem_exists = modem_register();
|
||||
break;
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
case FUSION_DEVICE:
|
||||
info("Fusion modem restart detected.\n");
|
||||
fusion_modem_exists = fusion_modem_register();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
msg("Unknown device in %s\n", __func__);
|
||||
break;
|
||||
}
|
||||
dbgmsg("ONCRPC restart re-registered for %d.\n", type);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_register
|
||||
|
||||
Register modem callbacks and server cleanup/restart callbacks
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
Returns if the server is available.
|
||||
1 if server is available, 0 if not.
|
||||
===========================================================================*/
|
||||
static int modem_register(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pthread_mutex_lock(&modem_mtx);
|
||||
ret = thermal_mitigation_null();
|
||||
if (ret) {
|
||||
info("Modem thermal mitigation available.\n");
|
||||
ret = thermal_mitigation_register_notify_cb(MITIGATION_DEVICE,
|
||||
&modem_oncrpc_handle, modem_thermal_state_cb);
|
||||
if (ret) {
|
||||
msg("Modem callback not registered\n");
|
||||
}
|
||||
oncrpc_register_server_exit_notification_cb(
|
||||
THERMAL_MITIGATIONPROG,
|
||||
THERMAL_MITIGATIONVERS,
|
||||
thermald_oncrpc_cleanup_cb, (void *)MODEM_DEVICE);
|
||||
oncrpc_register_server_restart_notification_cb(
|
||||
THERMAL_MITIGATIONPROG,
|
||||
THERMAL_MITIGATIONVERS,
|
||||
thermald_oncrpc_restart_cb, (void *)MODEM_DEVICE);
|
||||
/* We are still ok to continue as only the callback failed */
|
||||
dbgmsg("Modem thermal mitigation callbacks registered.\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
msg("Modem thermal mitigation not available.\n");
|
||||
ret = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&modem_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION fusion_modem_register
|
||||
|
||||
Register fusion modem callbacks and server cleanup/restart callbacks
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
Returns if the server is available.
|
||||
1 if server is available, 0 if not.
|
||||
===========================================================================*/
|
||||
static int fusion_modem_register(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
ret = thermal_mitigation_fusion_null();
|
||||
if (ret) {
|
||||
info("Fusion modem thermal mitigation available.\n");
|
||||
ret = thermal_mitigation_register_notify_cb_fusion(MITIGATION_DEVICE,
|
||||
&fusion_oncrpc_handle, fusion_thermal_state_cb);
|
||||
if (ret) {
|
||||
msg("Fusion modem callback not registered\n");
|
||||
}
|
||||
oncrpc_register_server_exit_notification_cb(
|
||||
THERMAL_MITIGATION_FUSIONPROG,
|
||||
THERMAL_MITIGATION_FUSIONVERS,
|
||||
thermald_oncrpc_cleanup_cb, (void *)FUSION_DEVICE);
|
||||
oncrpc_register_server_restart_notification_cb(
|
||||
THERMAL_MITIGATION_FUSIONPROG,
|
||||
THERMAL_MITIGATION_FUSIONVERS,
|
||||
thermald_oncrpc_restart_cb, (void *)FUSION_DEVICE);
|
||||
/* We are still ok to continue as only the callback failed */
|
||||
dbgmsg("Fusion modem thermal mitigation callbacks registered.\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
msg("Fusion modem thermal mitigation not available.\n");
|
||||
ret = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_request
|
||||
|
||||
Action function to throttle modem functionality.
|
||||
|
||||
ARGUMENTS
|
||||
requester - requesting sensor enum
|
||||
temperature - temperature reached
|
||||
level - 0-3 throttling level for modem mitigation
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int modem_request(int requester, int temperature, int level)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
static int prev;
|
||||
|
||||
if (!modem_exists)
|
||||
return ret;
|
||||
|
||||
/* Modem level: 0 - No action
|
||||
* 1 - Mitigation level 1
|
||||
* 2 - Mitigation level 2
|
||||
* 3 - Emergency
|
||||
*/
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level > MAX_MODEM_MITIGATION_LEVEL)
|
||||
level = MAX_MODEM_MITIGATION_LEVEL;
|
||||
|
||||
pthread_mutex_lock(&modem_mtx);
|
||||
|
||||
/* Aggregate modem mitigation level for all sensors */
|
||||
modem_req[requester] = level;
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (modem_req[i] > level)
|
||||
level = modem_req[i];
|
||||
}
|
||||
|
||||
if (level != prev) {
|
||||
ret = thermal_mitigation_set(MITIGATION_DEVICE, level);
|
||||
if (ret) {
|
||||
msg("Modem mitigation failed with %d for level %d\n", ret, level);
|
||||
} else {
|
||||
prev = level;
|
||||
info("ACTION: MODEM - "
|
||||
"Modem mitigation succeeded for level %d.\n", level);
|
||||
}
|
||||
} else {
|
||||
dbgmsg("Modem already at mitigation state %d\n", level);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&modem_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION fusion_modem_request
|
||||
|
||||
Action function to throttle fusion modem functionality.
|
||||
|
||||
ARGUMENTS
|
||||
requester - requesting sensor enum
|
||||
temperature - temperature reached
|
||||
level - 0-3 throttling level for modem mitigation
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int fusion_modem_request(int requester, int temperature, int level)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
static int prev;
|
||||
|
||||
if (!fusion_modem_exists)
|
||||
return ret;
|
||||
|
||||
/* Modem level: 0 - No action
|
||||
* 1 - Mitigation level 1
|
||||
* 2 - Mitigation level 2
|
||||
* 3 - Emergency
|
||||
*/
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level > MAX_MODEM_MITIGATION_LEVEL)
|
||||
level = MAX_MODEM_MITIGATION_LEVEL;
|
||||
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
|
||||
/* Aggregate modem mitigation level for all sensors */
|
||||
fusion_modem_req[requester] = level;
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (fusion_modem_req[i] > level)
|
||||
level = fusion_modem_req[i];
|
||||
}
|
||||
|
||||
if (level != prev) {
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
ret = thermal_mitigation_set_fusion(MITIGATION_DEVICE, level);
|
||||
#endif
|
||||
if (ret) {
|
||||
msg("Fusion modem mitigation failed with %d for level %d\n", ret, level);
|
||||
} else {
|
||||
prev = level;
|
||||
info("ACTION: FUSION - "
|
||||
"Fusion modem mitigation succeeded for level %d.\n", level);
|
||||
}
|
||||
} else {
|
||||
dbgmsg("Fusion modem already at mitigation state %d\n", level);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_communication_init
|
||||
|
||||
Initialization function for modem communication functionality.
|
||||
Needs to be called before modem_request() or fusion_modem_request()
|
||||
can be called.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int modem_communication_init(void)
|
||||
{
|
||||
oncrpc_init();
|
||||
oncrpc_task_start();
|
||||
info("Establishing ONCRPC communication.\n");
|
||||
|
||||
thermal_mitigationcb_app_init();
|
||||
modem_exists = modem_register();
|
||||
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
thermal_mitigation_fusioncb_app_init();
|
||||
fusion_modem_exists = fusion_modem_register();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION compare_fn
|
||||
|
||||
Comparator function for oncrpc
|
||||
|
||||
ARGUMENTS
|
||||
d1, d2: void pointers for comparison
|
||||
|
||||
RETURN VALUE
|
||||
1 if they are equal, 0 if they are not.
|
||||
===========================================================================*/
|
||||
static boolean compare_fn(void *d1, void *d2)
|
||||
{
|
||||
return (d1 == d2);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_communication_release
|
||||
|
||||
Release function for modem communication to clean up resources.
|
||||
Called after use of client handle is complete.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int modem_communication_release(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (modem_exists) {
|
||||
ret = thermal_mitigation_deregister_notify_cb(modem_oncrpc_handle);
|
||||
if (ret) {
|
||||
msg("Unable to de-register modem cb handle (%d).\n", ret);
|
||||
}
|
||||
oncrpc_unregister_server_exit_notification_cb(
|
||||
THERMAL_MITIGATIONPROG,
|
||||
THERMAL_MITIGATIONVERS,
|
||||
thermald_oncrpc_cleanup_cb, (void *)MODEM_DEVICE, compare_fn);
|
||||
oncrpc_unregister_server_restart_notification_cb(
|
||||
THERMAL_MITIGATIONPROG,
|
||||
THERMAL_MITIGATIONVERS,
|
||||
thermald_oncrpc_restart_cb, (void *)MODEM_DEVICE, compare_fn);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FUSION_MODEM
|
||||
if (fusion_modem_exists) {
|
||||
rc = thermal_mitigation_deregister_notify_cb_fusion(fusion_oncrpc_handle);
|
||||
if (rc) {
|
||||
msg("Unable to de-register fusion cb handle (%d).\n", rc);
|
||||
}
|
||||
oncrpc_unregister_server_exit_notification_cb(
|
||||
THERMAL_MITIGATION_FUSIONPROG,
|
||||
THERMAL_MITIGATION_FUSIONVERS,
|
||||
thermald_oncrpc_cleanup_cb, (void *)FUSION_DEVICE, compare_fn);
|
||||
oncrpc_unregister_server_restart_notification_cb(
|
||||
THERMAL_MITIGATION_FUSIONPROG,
|
||||
THERMAL_MITIGATION_FUSIONVERS,
|
||||
thermald_oncrpc_restart_cb, (void *)FUSION_DEVICE, compare_fn);
|
||||
}
|
||||
#endif
|
||||
oncrpc_task_stop();
|
||||
oncrpc_deinit();
|
||||
info("ONCRPC communication terminated.\n");
|
||||
|
||||
return (ret || rc) ? -1 : 0;
|
||||
}
|
||||
@@ -1,565 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
modem_mitigation_qmi.c
|
||||
|
||||
DESCRIPTION
|
||||
Modem mitigation action over QMI.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
modem_communication_init() should be called before the modem_request().
|
||||
|
||||
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
#include "thermal_mitigation_device_service_v01.h"
|
||||
#include "qmi_client.h"
|
||||
#include "qmi_idl_lib.h"
|
||||
#include "qmi_client_instance_defs.h"
|
||||
|
||||
#define QMI_MITIGATION_DEVICE_MODEM "pa"
|
||||
#define MAX_MODEM_MITIGATION_LEVEL (3)
|
||||
static void * modem_clnt;
|
||||
static void * fusion_modem_clnt;
|
||||
static int modem_req[SENSOR_IDX_MAX];
|
||||
static int fusion_modem_req[SENSOR_IDX_MAX];
|
||||
static int prev_modem;
|
||||
static int prev_fusion;
|
||||
static pthread_mutex_t modem_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t fusion_modem_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION modem_verify_tmd_device
|
||||
|
||||
Helper function to verify QMI_MITIGATION_DEVICE_MODEM thermal mitigation
|
||||
device on remote QMI TMD service.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
static int modem_verify_tmd_device(void *clnt)
|
||||
{
|
||||
int rc = -1;
|
||||
int ret = -1;
|
||||
unsigned int i;
|
||||
tmd_get_mitigation_device_list_resp_msg_v01 data_resp;
|
||||
|
||||
if (clnt == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&data_resp, 0, sizeof(data_resp));
|
||||
rc = qmi_client_send_msg_sync(clnt,
|
||||
QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01,
|
||||
NULL, 0,
|
||||
&data_resp, sizeof(data_resp), 0);
|
||||
if (rc == QMI_NO_ERR) {
|
||||
for (i = 0; i < data_resp.mitigation_device_list_len; i++) {
|
||||
if (0 == strncasecmp(QMI_MITIGATION_DEVICE_MODEM,
|
||||
data_resp.mitigation_device_list[i].mitigation_dev_id.mitigation_dev_id,
|
||||
strlen(QMI_MITIGATION_DEVICE_MODEM) + 1)) {
|
||||
/* found matching device name */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg("%s: QMI send_msg_sync failed with error %d", __func__, rc);
|
||||
}
|
||||
|
||||
return (!rc && !ret) ? 0 : -1;
|
||||
}
|
||||
|
||||
static qmi_idl_service_object_type tmd_service_object;
|
||||
static pthread_t qmi_register_thread;
|
||||
static pthread_t qmi_register_fusion_thread;
|
||||
|
||||
void modem_clnt_error_cb(qmi_client_type clnt,
|
||||
qmi_client_error_type error,
|
||||
void *error_cb_data);
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION modem_request_common_qmi
|
||||
|
||||
Common qmi modem request function.
|
||||
|
||||
ARGUMENTS
|
||||
clnt - client on which to request throttling
|
||||
mitigation_dev_id - name of mitigation_dev_id
|
||||
level - 0-3 throttling level for modem mitigation
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
static int modem_request_common_qmi(void *clnt, char *mitigation_dev_id,
|
||||
int level)
|
||||
{
|
||||
int ret = -1;
|
||||
tmd_set_mitigation_level_req_msg_v01 data_req;
|
||||
tmd_set_mitigation_level_resp_msg_v01 data_resp;
|
||||
|
||||
if (!clnt || !mitigation_dev_id)
|
||||
return ret;
|
||||
|
||||
strlcpy(data_req.mitigation_dev_id.mitigation_dev_id, mitigation_dev_id,
|
||||
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01);
|
||||
data_req.mitigation_level = level;
|
||||
ret = qmi_client_send_msg_sync((qmi_client_type) clnt,
|
||||
QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01,
|
||||
&data_req, sizeof(data_req),
|
||||
&data_resp, sizeof(data_resp), 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_register
|
||||
|
||||
Helper function to initialize qmi connection to modem service.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
static void *qmi_register(void *data)
|
||||
{
|
||||
int rc = -1;
|
||||
int ret = 0;
|
||||
int level = 0;
|
||||
int i;
|
||||
qmi_cci_os_signal_type os_params;
|
||||
qmi_service_info info;
|
||||
qmi_client_type notifier = NULL;
|
||||
void * modem_clnt_local = NULL;
|
||||
|
||||
/* release any old handles for modem_clnt */
|
||||
if (modem_clnt) {
|
||||
qmi_client_release(modem_clnt);
|
||||
modem_clnt = NULL;
|
||||
}
|
||||
|
||||
rc = qmi_client_notifier_init(tmd_service_object, &os_params, ¬ifier);
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("qmi: qmi_client_notifier_init failed.\n");
|
||||
ret = -1;
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
/* TODO: Assuming modem index is 0, depends on QMI implementation */
|
||||
while (1)
|
||||
{
|
||||
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
|
||||
rc = qmi_client_get_service_instance(tmd_service_object, 0, &info);
|
||||
if(rc == QMI_NO_ERR)
|
||||
break;
|
||||
/* wait for server to come up */
|
||||
QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
|
||||
};
|
||||
|
||||
rc = qmi_client_init(&info, tmd_service_object, NULL, NULL, NULL, (qmi_client_type *) (&modem_clnt_local));
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("Modem thermal mitigation not available.\n");
|
||||
ret = -1;
|
||||
goto handle_error;
|
||||
}
|
||||
/* Verify modem mitigation device present on modem */
|
||||
rc = modem_verify_tmd_device(modem_clnt_local);
|
||||
if (rc != 0) {
|
||||
qmi_client_release(modem_clnt_local);
|
||||
modem_clnt_local = NULL;
|
||||
ret = -1;
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
/* best effort register for error */
|
||||
qmi_client_register_error_cb(modem_clnt_local, modem_clnt_error_cb, NULL);
|
||||
modem_clnt = modem_clnt_local;
|
||||
info("Modem thermal mitigation available.\n");
|
||||
|
||||
/*Setting highest pending mitigation level if any */
|
||||
pthread_mutex_lock(&modem_mtx);
|
||||
/* Aggregate modem mitigation level for all sensors */
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (modem_req[i] > level)
|
||||
level = modem_req[i];
|
||||
}
|
||||
|
||||
if (level) {
|
||||
ret = modem_request_common_qmi(modem_clnt,
|
||||
QMI_MITIGATION_DEVICE_MODEM,
|
||||
level);
|
||||
if (ret) {
|
||||
msg("Modem mitigation failed with %d for level %d\n",
|
||||
ret, level);
|
||||
} else {
|
||||
prev_modem = level;
|
||||
info("ACTION: MODEM - "
|
||||
"Pending request:Modem mitigation succeeded for "
|
||||
"level %d.\n", level);
|
||||
}
|
||||
} else {
|
||||
dbgmsg("No pending request for Modem mitigation\n");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&modem_mtx);
|
||||
|
||||
handle_error:
|
||||
if (notifier != NULL) {
|
||||
qmi_client_release(notifier);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_register_fusion
|
||||
|
||||
Helper function to initialize qmi connection to fusion service.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
static void *qmi_register_fusion(void *data)
|
||||
{
|
||||
int rc = -1;
|
||||
int ret = 0;
|
||||
int level = 0;
|
||||
int i;
|
||||
qmi_cci_os_signal_type os_params;
|
||||
qmi_service_info info;
|
||||
qmi_client_type notifier = NULL;
|
||||
void * fusion_clnt_local = NULL;
|
||||
qmi_service_instance instance_id = QMI_CLIENT_QMUX_RMNET_USB_INSTANCE_0;
|
||||
|
||||
/* release any old handles for fusion_modem_clnt */
|
||||
if (fusion_modem_clnt) {
|
||||
qmi_client_release(fusion_modem_clnt);
|
||||
fusion_modem_clnt = NULL;
|
||||
}
|
||||
|
||||
rc = qmi_client_notifier_init(tmd_service_object, &os_params, ¬ifier);
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("qmi: qmi_client_notifier_init failed.\n");
|
||||
ret = -1;
|
||||
goto handle_error_fusion;
|
||||
}
|
||||
|
||||
info("qmi: Instance id %d for fusion TMD", instance_id);
|
||||
while (1)
|
||||
{
|
||||
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
|
||||
rc = qmi_client_get_service_instance(tmd_service_object,
|
||||
instance_id, &info);
|
||||
if(rc == QMI_NO_ERR)
|
||||
break;
|
||||
/* wait for server to come up */
|
||||
QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
|
||||
};
|
||||
|
||||
rc = qmi_client_init(&info, tmd_service_object, NULL, NULL, NULL, (qmi_client_type *) (&fusion_clnt_local));
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("Fusion modem thermal mitigation not available.\n");
|
||||
ret = -1;
|
||||
goto handle_error_fusion;
|
||||
}
|
||||
rc = modem_verify_tmd_device(fusion_clnt_local);
|
||||
if (rc != 0) {
|
||||
qmi_client_release(fusion_clnt_local);
|
||||
fusion_clnt_local = NULL;
|
||||
ret = -1;
|
||||
goto handle_error_fusion;
|
||||
}
|
||||
|
||||
/* best effort register for error */
|
||||
qmi_client_register_error_cb(fusion_clnt_local, modem_clnt_error_cb, NULL);
|
||||
fusion_modem_clnt = fusion_clnt_local;
|
||||
info("Fusion modem thermal mitigation available.\n");
|
||||
|
||||
/*Setting highest pending mitigation level if any */
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
|
||||
/* Aggregate modem mitigation level for all sensors */
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (fusion_modem_req[i] > level)
|
||||
level = fusion_modem_req[i];
|
||||
}
|
||||
|
||||
if (level) {
|
||||
ret = modem_request_common_qmi(fusion_modem_clnt,
|
||||
QMI_MITIGATION_DEVICE_MODEM,
|
||||
level);
|
||||
if (ret) {
|
||||
msg("Fusion modem mitigation failed with %d for "
|
||||
"level %d\n", ret, level);
|
||||
} else {
|
||||
prev_fusion = level;
|
||||
info("ACTION: FUSION - "
|
||||
"Pending request:Fusion modem mitigation succeeded "
|
||||
"for level %d.\n", level);
|
||||
}
|
||||
} else {
|
||||
dbgmsg("No pending request for Fusion modem mitigation\n");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
|
||||
handle_error_fusion:
|
||||
if (notifier != NULL) {
|
||||
qmi_client_release(notifier);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_clnt_error_cb
|
||||
|
||||
Callback function called by the QCCI infrastructure when it receives a
|
||||
REMOVE SERVER message from the modem.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
void modem_clnt_error_cb(qmi_client_type clnt,
|
||||
qmi_client_error_type error,
|
||||
void *error_cb_data)
|
||||
{
|
||||
info("%s: with %d called for clnt %p\n", __func__, error, (void *)clnt);
|
||||
if (clnt == NULL) {
|
||||
return;
|
||||
}
|
||||
if (clnt == modem_clnt) {
|
||||
pthread_join(qmi_register_thread, NULL);
|
||||
pthread_create(&qmi_register_thread, NULL,
|
||||
qmi_register, NULL);
|
||||
} else if (clnt == fusion_modem_clnt) {
|
||||
pthread_join(qmi_register_fusion_thread, NULL);
|
||||
pthread_create(&qmi_register_fusion_thread, NULL,
|
||||
qmi_register_fusion, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_communication_init
|
||||
|
||||
Helper function to initialize qmi communication to modem.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int modem_communication_init(void)
|
||||
{
|
||||
/* Get the service object for the tmd API */
|
||||
tmd_service_object = tmd_get_service_object_v01();
|
||||
if (!tmd_service_object) {
|
||||
msg("qmi: tmd_get_service_object failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* start thread to register with QMI services */
|
||||
pthread_create(&qmi_register_thread, NULL,
|
||||
qmi_register, NULL);
|
||||
|
||||
/* start thread to register with QMI services */
|
||||
pthread_create(&qmi_register_fusion_thread, NULL,
|
||||
qmi_register_fusion, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_request
|
||||
|
||||
Action function to throttle modem functionality.
|
||||
|
||||
ARGUMENTS
|
||||
requester - requesting sensor enum
|
||||
temperature - temperature reached
|
||||
level - 0-3 throttling level for modem mitigation
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int modem_request(int requester, int temperature, int level)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
|
||||
/* Modem level: 0 - No action
|
||||
* 1 - Mitigation level 1
|
||||
* 2 - Mitigation level 2
|
||||
* 3 - Emergency
|
||||
*/
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level > MAX_MODEM_MITIGATION_LEVEL)
|
||||
level = MAX_MODEM_MITIGATION_LEVEL;
|
||||
|
||||
pthread_mutex_lock(&modem_mtx);
|
||||
|
||||
/* Aggregate modem mitigation level for all sensors */
|
||||
modem_req[requester] = level;
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (modem_req[i] > level)
|
||||
level = modem_req[i];
|
||||
}
|
||||
|
||||
if (!modem_clnt) {
|
||||
info("Modem: Requested level is recorded and waiting for"
|
||||
"completing QMI registration");
|
||||
ret = 0;
|
||||
goto handle_return;
|
||||
}
|
||||
|
||||
if (level != prev_modem) {
|
||||
ret = modem_request_common_qmi(modem_clnt,
|
||||
QMI_MITIGATION_DEVICE_MODEM,
|
||||
level);
|
||||
if (ret) {
|
||||
msg("Modem mitigation failed with %d for level %d\n",
|
||||
ret, level);
|
||||
} else {
|
||||
prev_modem = level;
|
||||
info("ACTION: MODEM - "
|
||||
"Modem mitigation succeeded for level %d.\n",
|
||||
level);
|
||||
}
|
||||
} else {
|
||||
dbgmsg("Modem already at mitigation state %d\n", level);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
handle_return:
|
||||
pthread_mutex_unlock(&modem_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION fusion_modem_request
|
||||
|
||||
Action function to throttle fusion modem functionality.
|
||||
|
||||
ARGUMENTS
|
||||
requester - requesting sensor enum
|
||||
temperature - temperature reached
|
||||
level - 0-3 throttling level for modem mitigation
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int fusion_modem_request(int requester, int temperature, int level)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
|
||||
/* Modem level: 0 - No action
|
||||
* 1 - Mitigation level 1
|
||||
* 2 - Mitigation level 2
|
||||
* 3 - Emergency
|
||||
*/
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level > MAX_MODEM_MITIGATION_LEVEL)
|
||||
level = MAX_MODEM_MITIGATION_LEVEL;
|
||||
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
|
||||
/* Aggregate modem mitigation level for all sensors */
|
||||
fusion_modem_req[requester] = level;
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (fusion_modem_req[i] > level)
|
||||
level = fusion_modem_req[i];
|
||||
}
|
||||
|
||||
if (!fusion_modem_clnt) {
|
||||
info("Fusion: Requested level is recorded and waiting for"
|
||||
"completing QMI registration");
|
||||
ret = 0;
|
||||
goto handle_return;
|
||||
}
|
||||
|
||||
if (level != prev_fusion) {
|
||||
ret = modem_request_common_qmi(fusion_modem_clnt,
|
||||
QMI_MITIGATION_DEVICE_MODEM,
|
||||
level);
|
||||
if (ret) {
|
||||
msg("Fusion modem mitigation failed with %d for "
|
||||
"level %d\n", ret, level);
|
||||
} else {
|
||||
prev_fusion = level;
|
||||
info("ACTION: FUSION - "
|
||||
"Fusion modem mitigation succeeded for "
|
||||
"level %d.\n", level);
|
||||
}
|
||||
} else {
|
||||
dbgmsg("Fusion modem already at mitigation state %d\n", level);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
handle_return:
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_communication_release
|
||||
|
||||
Release function for modem communication to clean up resources.
|
||||
Called after use of client handles is complete.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -1 on failure.
|
||||
===========================================================================*/
|
||||
int modem_communication_release(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
pthread_join(qmi_register_thread, NULL);
|
||||
pthread_join(qmi_register_fusion_thread, NULL);
|
||||
|
||||
if (modem_clnt) {
|
||||
rc = qmi_client_release(modem_clnt);
|
||||
if (rc)
|
||||
msg("qmi: qmi_client_release modem clnt failed.\n");
|
||||
modem_clnt = 0;
|
||||
}
|
||||
if (fusion_modem_clnt) {
|
||||
rc = qmi_client_release(fusion_modem_clnt);
|
||||
if (rc)
|
||||
msg("qmi: qmi_client_release fusion clnt failed.\n");
|
||||
fusion_modem_clnt = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1,470 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
modem_sensor_qmi.c
|
||||
|
||||
DESCRIPTION
|
||||
Modem sensor action over QMI.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
modem_ts_qmi_init() should be called before the modem_ts_temp_request().
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "thermal.h"
|
||||
#include "qmi-ts-sensor.h"
|
||||
|
||||
#include "thermal_sensor_service_v01.h"
|
||||
#include "qmi_client.h"
|
||||
#include "qmi_idl_lib.h"
|
||||
#include "qmi_client_instance_defs.h"
|
||||
|
||||
#define QMI_SENSOR_MODEM "pa"
|
||||
static void *fusion_modem_clnt;
|
||||
|
||||
static pthread_mutex_t fusion_modem_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t fusion_modem_cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_t fusion_qmi_register_thread;
|
||||
static int fusion_modem_qmi_ts_ready;
|
||||
|
||||
static ts_temp_report_ind_msg_v01 ind_struct;
|
||||
|
||||
static qmi_idl_service_object_type ts_service_object;
|
||||
|
||||
static void modem_clnt_error_cb(qmi_client_type clnt,
|
||||
qmi_client_error_type error,
|
||||
void *error_cb_data);
|
||||
|
||||
static int modem_ts_reg_notify(void *clnt, const char *sensor_id,
|
||||
int send_current_temp_report,
|
||||
int high_valid,
|
||||
int high_thresh,
|
||||
int low_valid,
|
||||
int low_thresh);
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION qmi_ts_ind_cb
|
||||
|
||||
Handle QMI TS indication callbacks.
|
||||
|
||||
ARGUMENTS
|
||||
user_handle - QMI client user handle.
|
||||
msg_id - Indication message id.
|
||||
ind_buf - Indication encoded data.
|
||||
ind_buf_len - Indication encoded data length.
|
||||
ind_cb_data - TS provided callback data.
|
||||
|
||||
RETURN VALUE
|
||||
None.
|
||||
===========================================================================*/
|
||||
static void qmi_ts_ind_cb(qmi_client_type user_handle,
|
||||
unsigned int msg_id,
|
||||
void *ind_buf,
|
||||
unsigned int ind_buf_len,
|
||||
void *ind_cb_data)
|
||||
{
|
||||
qmi_client_error_type rc = QMI_NO_ERR;
|
||||
unsigned char *buf = ind_buf;
|
||||
|
||||
if (msg_id == QMI_TS_TEMP_REPORT_IND_V01) {
|
||||
memset((void *)&ind_struct, 0,
|
||||
sizeof(ts_temp_report_ind_msg_v01));
|
||||
rc = qmi_client_message_decode(user_handle, QMI_IDL_INDICATION,
|
||||
msg_id, ind_buf, ind_buf_len,
|
||||
&ind_struct,
|
||||
sizeof(ts_temp_report_ind_msg_v01));
|
||||
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("Error invalid indication message received.\n");
|
||||
} else {
|
||||
if (ind_struct.temp_valid) {
|
||||
qmi_ts_update_temperature(ind_struct.sensor_id.sensor_id,
|
||||
(int)ind_struct.temp);
|
||||
} else {
|
||||
msg("Error invalid temperature field.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("\nWarning invalid indication message received.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION modem_verify_ts_device
|
||||
|
||||
Helper function to verify QMI_SENSOR_MODEM thermal sensor exits on remote QMI
|
||||
TS service.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -(ERRNO) Code on failure.
|
||||
===========================================================================*/
|
||||
static int modem_verify_ts_device(void *clnt)
|
||||
{
|
||||
int rc;
|
||||
int ret = -(EPERM);
|
||||
unsigned int i;
|
||||
static int func_exec_count;
|
||||
|
||||
ts_get_sensor_list_resp_msg_v01 *list_resp = NULL;
|
||||
ts_register_notification_temp_req_msg_v01 *reg_notify_req = NULL;
|
||||
ts_register_notification_temp_resp_msg_v01 *reg_notify_resp = NULL;
|
||||
/* Large structs let's not put it on the stack. */
|
||||
|
||||
do {
|
||||
if (clnt == NULL) {
|
||||
ret = -(EINVAL);
|
||||
break;
|
||||
}
|
||||
|
||||
list_resp = malloc(sizeof(ts_get_sensor_list_resp_msg_v01));
|
||||
if (list_resp == NULL) {
|
||||
msg("%s: Malloc list_resp failure", __func__);
|
||||
ret = -(ENOMEM);
|
||||
break;
|
||||
}
|
||||
|
||||
reg_notify_req = malloc(sizeof(ts_register_notification_temp_req_msg_v01));
|
||||
if (reg_notify_req == NULL) {
|
||||
msg("%s: Malloc reg_notify_req failure", __func__);
|
||||
ret = -(ENOMEM);
|
||||
break;
|
||||
}
|
||||
|
||||
reg_notify_resp = malloc(sizeof(ts_register_notification_temp_resp_msg_v01));
|
||||
if (reg_notify_resp == NULL) {
|
||||
msg("%s: Malloc reg_notify_resp failure", __func__);
|
||||
ret = -(ENOMEM);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(list_resp, 0, sizeof(ts_get_sensor_list_resp_msg_v01));
|
||||
rc = qmi_client_send_msg_sync(clnt,
|
||||
QMI_TS_GET_SENSOR_LIST_REQ_V01,
|
||||
NULL, 0,
|
||||
list_resp, sizeof(ts_get_sensor_list_resp_msg_v01), 0);
|
||||
if (rc == QMI_NO_ERR) {
|
||||
for (i = 0; i < list_resp->sensor_list_len; i++) {
|
||||
if (0 == strncasecmp(QMI_SENSOR_MODEM,
|
||||
list_resp->sensor_list[i].sensor_id,
|
||||
QMI_TS_SENSOR_ID_LENGTH_MAX_V01)) {
|
||||
/* found matching device name */
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (func_exec_count) {
|
||||
/* Chances are the service reset, so send out
|
||||
current temp notify request to get clients to configure
|
||||
threshold triggers again.*/
|
||||
modem_ts_reg_notify(clnt, list_resp->sensor_list[i].sensor_id,
|
||||
1, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg("%s: QMI send_msg_sync failed with error %d", __func__, rc);
|
||||
ret = -(EFAULT);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (list_resp != NULL)
|
||||
free(list_resp);
|
||||
|
||||
if (reg_notify_req != NULL)
|
||||
free(reg_notify_req);
|
||||
|
||||
if (reg_notify_resp != NULL)
|
||||
free(reg_notify_resp);
|
||||
|
||||
func_exec_count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION fusion_qmi_register
|
||||
|
||||
Helper function to initialize QMI connection to modem service.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
NULL on exit
|
||||
===========================================================================*/
|
||||
static void *fusion_qmi_register(void *data)
|
||||
{
|
||||
int rc;
|
||||
qmi_cci_os_signal_type os_params;
|
||||
qmi_service_info info;
|
||||
qmi_client_type notifier = NULL;
|
||||
void *modem_clnt_local = NULL;
|
||||
qmi_service_instance instance_id = QMI_CLIENT_QMUX_RMNET_USB_INSTANCE_0;
|
||||
|
||||
/* release any old handles for fusion_modem_clnt */
|
||||
if (fusion_modem_clnt) {
|
||||
qmi_client_release(fusion_modem_clnt);
|
||||
fusion_modem_clnt = NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
rc = qmi_client_notifier_init(ts_service_object, &os_params, ¬ifier);
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("qmi: qmi_client_notifier_init failed.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
info("qmi: Instance id %d for fusion TS", instance_id);
|
||||
while (1) {
|
||||
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
|
||||
rc = qmi_client_get_service_instance(ts_service_object,
|
||||
instance_id,
|
||||
&info);
|
||||
if (rc == QMI_NO_ERR)
|
||||
break;
|
||||
/* wait for server to come up */
|
||||
QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
|
||||
};
|
||||
|
||||
rc = qmi_client_init(&info, ts_service_object, qmi_ts_ind_cb, NULL, NULL,
|
||||
(qmi_client_type *) (&modem_clnt_local));
|
||||
if (rc != QMI_NO_ERR) {
|
||||
msg("Modem thermal sensor service not available.\n");
|
||||
break;
|
||||
}
|
||||
/* Verify modem sensor service present on modem */
|
||||
rc = modem_verify_ts_device(modem_clnt_local);
|
||||
if (rc != 0) {
|
||||
qmi_client_release(modem_clnt_local);
|
||||
modem_clnt_local = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* best effort register for error */
|
||||
qmi_client_register_error_cb(modem_clnt_local, modem_clnt_error_cb, NULL);
|
||||
fusion_modem_clnt = modem_clnt_local;
|
||||
|
||||
/* notify waiting threads */
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
fusion_modem_qmi_ts_ready = 1;
|
||||
pthread_cond_broadcast(&fusion_modem_cond);
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
info("Modem thermal sensor service available.\n");
|
||||
} while (0);
|
||||
|
||||
if (notifier != NULL)
|
||||
qmi_client_release(notifier);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION modem_clnt_error_cb
|
||||
|
||||
Callback function called by the QCCI infrastructure when it receives a
|
||||
REMOVE SERVER message from the modem.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
None.
|
||||
===========================================================================*/
|
||||
static void modem_clnt_error_cb(qmi_client_type clnt,
|
||||
qmi_client_error_type error,
|
||||
void *error_cb_data)
|
||||
{
|
||||
info("%s: with %d called for clnt %p\n", __func__, error, (void *)clnt);
|
||||
if (clnt == NULL)
|
||||
return;
|
||||
|
||||
if (clnt == fusion_modem_clnt) {
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
fusion_modem_qmi_ts_ready = 0;
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
pthread_join(fusion_qmi_register_thread, NULL);
|
||||
pthread_create(&fusion_qmi_register_thread, NULL,
|
||||
fusion_qmi_register, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION modem_ts_reg_notify
|
||||
|
||||
Common TS qmi modem register notify function.
|
||||
|
||||
ARGUMENTS
|
||||
clnt - client on which to request throttling
|
||||
sensor_id - name of sensor_id
|
||||
send_current_temp_report - 1 for trigger and immediate sensor reading,
|
||||
0 for set threshold.
|
||||
high_thresh
|
||||
low_thresh
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -(ERRNO) on failure.
|
||||
===========================================================================*/
|
||||
static int modem_ts_reg_notify(void *clnt, const char *sensor_id,
|
||||
int send_current_temp_report,
|
||||
int high_valid,
|
||||
int high_thresh,
|
||||
int low_valid,
|
||||
int low_thresh)
|
||||
{
|
||||
int ret = -(EPERM);
|
||||
qmi_client_error_type qmi_error = QMI_NO_ERR;
|
||||
|
||||
ts_register_notification_temp_req_msg_v01 data_req;
|
||||
ts_register_notification_temp_resp_msg_v01 data_resp;
|
||||
|
||||
if (!clnt || !sensor_id)
|
||||
return -(EINVAL);
|
||||
|
||||
memset(&data_req, 0x0, sizeof(data_req));
|
||||
strlcpy(data_req.sensor_id.sensor_id, sensor_id,
|
||||
QMI_TS_SENSOR_ID_LENGTH_MAX_V01);
|
||||
|
||||
if (send_current_temp_report) {
|
||||
data_req.send_current_temp_report = 1;
|
||||
} else {
|
||||
data_req.temp_threshold_high_valid = high_valid;
|
||||
data_req.temp_threshold_high = (float)high_thresh;
|
||||
data_req.temp_threshold_low_valid = low_valid;
|
||||
data_req.temp_threshold_low = (float)low_thresh;
|
||||
}
|
||||
|
||||
qmi_error = qmi_client_send_msg_sync((qmi_client_type) clnt,
|
||||
QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01,
|
||||
&data_req, sizeof(data_req),
|
||||
&data_resp, sizeof(data_resp), 0);
|
||||
if (qmi_error == QMI_NO_ERR) {
|
||||
ret = 0;
|
||||
} else {
|
||||
msg("qmi: qmi_client_send_msg_sync failed. Error %d\n", qmi_error);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_ts_qmi_init
|
||||
|
||||
Helper function to initialize TS qmi communication to modem.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -(ERRNO) on failure.
|
||||
===========================================================================*/
|
||||
int modem_ts_qmi_init(void)
|
||||
{
|
||||
/* Get the service object for the ts API */
|
||||
ts_service_object = ts_get_service_object_v01();
|
||||
if (!ts_service_object) {
|
||||
msg("qmi: ts_get_service_object failed.\n");
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
/* start thread to register with QMI services */
|
||||
pthread_create(&fusion_qmi_register_thread, NULL, fusion_qmi_register, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_ts_temp_request
|
||||
|
||||
Function to request sensor read or notify threshold functionality.
|
||||
|
||||
ARGUMENTS
|
||||
sensor_id - name of sensor_id
|
||||
send_current_temp_report - 1 for trigger and immediate sensor reading, 0 for
|
||||
set threshold.
|
||||
high_valid
|
||||
high_thresh
|
||||
low_valid
|
||||
low_thresh
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -(ERRNO) on failure.
|
||||
===========================================================================*/
|
||||
int modem_ts_temp_request(const char *sensor_id,
|
||||
int send_current_temp_report,
|
||||
int high_valid,
|
||||
int high_thresh,
|
||||
int low_valid,
|
||||
int low_thresh)
|
||||
{
|
||||
int ret = -(EPERM);
|
||||
|
||||
if ((send_current_temp_report == 0) && ((high_valid == 1) &&
|
||||
(low_valid == 1)) &&
|
||||
(high_thresh <= low_thresh)) {
|
||||
msg("Invalid thresh level. High %d, Low %d", high_thresh,
|
||||
low_thresh);
|
||||
return -(EINVAL);
|
||||
}
|
||||
|
||||
/* Make sure the QMI connection is established before proceeding. */
|
||||
pthread_mutex_lock(&fusion_modem_mtx);
|
||||
while (!fusion_modem_qmi_ts_ready)
|
||||
pthread_cond_wait(&fusion_modem_cond, &fusion_modem_mtx);
|
||||
pthread_mutex_unlock(&fusion_modem_mtx);
|
||||
|
||||
if (!fusion_modem_clnt) {
|
||||
msg("Modem TS service failed - QMI registration incomplete");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = modem_ts_reg_notify(fusion_modem_clnt, sensor_id, send_current_temp_report,
|
||||
high_valid,
|
||||
high_thresh,
|
||||
low_valid,
|
||||
low_thresh);
|
||||
dbgmsg("%s %s, sensor %s, Get Immediate: %s, High valid: %s, High %d "
|
||||
"Low valid: %s, Low %d\n",
|
||||
__func__, (ret) ? ("Failed") : ("Success"), sensor_id,
|
||||
(send_current_temp_report) ? ("YES") : ("NO"),
|
||||
(high_valid) ? ("YES") : ("NO"), high_thresh,
|
||||
(low_valid) ? ("YES") : ("NO"), low_thresh);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION modem_qmi_ts_comm_release
|
||||
|
||||
Release function for modem communication to clean up resources.
|
||||
Called after use of client handles is complete.
|
||||
|
||||
ARGUMENTS
|
||||
None.
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, -(ERRNO) on failure.
|
||||
===========================================================================*/
|
||||
int modem_qmi_ts_comm_release(void)
|
||||
{
|
||||
int rc;
|
||||
int ret = 0;
|
||||
|
||||
pthread_join(fusion_qmi_register_thread, NULL);
|
||||
|
||||
if (fusion_modem_clnt) {
|
||||
rc = qmi_client_release(fusion_modem_clnt);
|
||||
if (rc) {
|
||||
msg("qmi: qmi_client_release modem clnt failed.\n");
|
||||
ret = -(EPERM);
|
||||
}
|
||||
fusion_modem_clnt = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
pm8821-sensor.c
|
||||
|
||||
DESCRIPTION
|
||||
pm8821 temperature alarm access functions.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
setup() function should be called before get_temperature().
|
||||
shutdown() function should be called to clean up resources.
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "pm8821-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
/* Stage 2 Alarm thresholds */
|
||||
#define PM8821_STAGE_2_TEMP_TRIG 127
|
||||
#define PM8821_STAGE_2_TEMP_CLR 123
|
||||
|
||||
struct pmic_data {
|
||||
pthread_t pmic_thread;
|
||||
pthread_mutex_t pmic_mutex;
|
||||
pthread_cond_t pmic_condition;
|
||||
int threshold_reached;
|
||||
int temp_idx;
|
||||
int sensor_shutdown;
|
||||
sensor_t *sensor;
|
||||
} pmic_data;
|
||||
|
||||
static void *pmic_uevent(void *data)
|
||||
{
|
||||
int err = 0;
|
||||
sensor_t *sensor = (sensor_t *)data;
|
||||
struct pollfd fds;
|
||||
int fd;
|
||||
char uevent[MAX_PATH] = {0};
|
||||
char buf[MAX_PATH] = {0};
|
||||
struct pmic_data *pmic = NULL;
|
||||
|
||||
if (NULL == sensor ||
|
||||
NULL == sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return NULL;
|
||||
}
|
||||
pmic = (struct pmic_data *) sensor->data;
|
||||
|
||||
/* Looking for pmic uevent */
|
||||
snprintf(uevent, MAX_PATH, TZ_TYPE, pmic->sensor->tzn);
|
||||
fd = open(uevent, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("Unable to open %s to receive notifications.\n", uevent);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
while (!pmic->sensor_shutdown) {
|
||||
fds.fd = fd;
|
||||
fds.events = POLLERR|POLLPRI;
|
||||
fds.revents = 0;
|
||||
err = poll(&fds, 1, -1);
|
||||
if (err == -1) {
|
||||
msg("Error in uevent poll.\n");
|
||||
break;
|
||||
}
|
||||
read(fd, buf, sizeof(buf));
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
dbgmsg("pmic uevent :%s", buf);
|
||||
|
||||
/* notify the waiting threads */
|
||||
pthread_mutex_lock(&(pmic->pmic_mutex));
|
||||
pmic->threshold_reached = 1;
|
||||
pthread_cond_broadcast(&(pmic->pmic_condition));
|
||||
pthread_mutex_unlock(&(pmic->pmic_mutex));
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pm8821_interrupt_wait(sensor_setting_t *setting)
|
||||
{
|
||||
struct pmic_data *pmic;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pmic = (struct pmic_data *) setting->sensor->data;
|
||||
|
||||
if (setting->sensor->interrupt_enable) {
|
||||
/* Wait for sensor threshold condition */
|
||||
pthread_mutex_lock(&(pmic->pmic_mutex));
|
||||
while (!pmic->threshold_reached) {
|
||||
pthread_cond_wait(&(pmic->pmic_condition),
|
||||
&(pmic->pmic_mutex));
|
||||
}
|
||||
pmic->threshold_reached = 0;
|
||||
pthread_mutex_unlock(&(pmic->pmic_mutex));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pm8821_hotpug_threshold_override_default(sensor_setting_t *setting)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (setting == NULL) {
|
||||
msg("pm8821_tz:unexpected NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (setting->desc == NULL)
|
||||
setting->desc = sensor_names[setting->id];
|
||||
|
||||
for (j = 0; hotplug_map[j].sensor_name != NULL; j++) {
|
||||
if (!strcmp(hotplug_map[j].sensor_name, setting->desc))
|
||||
break;
|
||||
}
|
||||
|
||||
if (hotplug_map[j].sensor_name == NULL) {
|
||||
msg("Hotplug_map for pm8821_tz is not configured");
|
||||
return;
|
||||
}
|
||||
|
||||
setting->hotplug_lvl_trig = PM8821_STAGE_2_TEMP_TRIG;
|
||||
setting->hotplug_lvl_clr = PM8821_STAGE_2_TEMP_CLR;
|
||||
dbgmsg("pm8821_tz hotplug thresholds Override default");
|
||||
|
||||
if (!setting->num_thresholds) {
|
||||
setting->num_thresholds = 1;
|
||||
setting->t[0].lvl_trig = CONV(PM8821_STAGE_2_TEMP_TRIG);
|
||||
setting->t[0].lvl_clr = CONV(PM8821_STAGE_2_TEMP_CLR);
|
||||
}
|
||||
}
|
||||
|
||||
/* pm8821_tz sensor specific set up */
|
||||
int pm8821_setup(sensor_setting_t *setting, sensor_t *sensor)
|
||||
{
|
||||
int fd = -1;
|
||||
int sensor_count = 0;
|
||||
int tzn = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
struct pmic_data *pmic = NULL;
|
||||
|
||||
if (setting == NULL) {
|
||||
msg("pm8821_tz:unexpected NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
tzn = get_tzn(sensor->name);
|
||||
if (tzn < 0) {
|
||||
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
sensor->tzn = tzn;
|
||||
|
||||
/* Allocate pmic data */
|
||||
pmic = (struct pmic_data *) malloc(sizeof(struct pmic_data));
|
||||
if (NULL == pmic) {
|
||||
msg("%s: malloc failed", __func__);
|
||||
return sensor_count;
|
||||
}
|
||||
memset(pmic, 0, sizeof(pmic_data));
|
||||
sensor->data = (void *) pmic;
|
||||
pmic->sensor = sensor;
|
||||
|
||||
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, name);
|
||||
free(pmic);
|
||||
return sensor_count;
|
||||
}
|
||||
pmic->temp_idx = fd;
|
||||
sensor_count++;
|
||||
pthread_mutex_init(&(pmic->pmic_mutex), NULL);
|
||||
pthread_cond_init(&(pmic->pmic_condition), NULL);
|
||||
pmic->sensor_shutdown = 0;
|
||||
pmic->threshold_reached = 0;
|
||||
setting->disabled = 0;
|
||||
|
||||
/* Override default hotplug thresholds with pm8821 stage 2 alarm values */
|
||||
pm8821_hotpug_threshold_override_default(setting);
|
||||
|
||||
if (sensor->interrupt_enable) {
|
||||
pthread_create(&(pmic->pmic_thread), NULL,
|
||||
pmic_uevent, sensor);
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
int pm8821_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
struct pmic_data *pmic;
|
||||
int temp = 0;
|
||||
char buf[MAX_PATH] = {0};
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pmic = (struct pmic_data *) setting->sensor->data;
|
||||
|
||||
if (read(pmic->temp_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(pmic->temp_idx, 0, SEEK_SET);
|
||||
temp /= 1000;
|
||||
|
||||
return CONV(temp);
|
||||
}
|
||||
|
||||
void pm8821_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
struct pmic_data *pmic;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
pmic = (struct pmic_data *) setting->sensor->data;
|
||||
pmic->sensor_shutdown = 1;
|
||||
if (setting->sensor->interrupt_enable)
|
||||
pthread_join(pmic->pmic_thread, NULL);
|
||||
free(pmic);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#ifndef __PM8821_SENSOR_H__
|
||||
#define __PM8821_SENSOR_H__
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
int pm8821_setup(sensor_setting_t *setting, sensor_t *sensor);
|
||||
void pm8821_shutdown(sensor_setting_t *setting);
|
||||
int pm8821_get_temperature(sensor_setting_t *setting);
|
||||
void pm8821_interrupt_wait(sensor_setting_t *setting);
|
||||
|
||||
extern hotplug_map_t *hotplug_map;
|
||||
|
||||
#endif /* __PM8821_SENSOR_H__ */
|
||||
@@ -1,372 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
qmi-ts-sensor.c
|
||||
|
||||
DESCRIPTION
|
||||
QMI TS sensor access functions.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
qmi_ts_setup() function should be called before qmi_ts_get_temperature().
|
||||
qmi_ts_shutdown() function should be called to clean up resources.
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
#include "thermal_sensor_service_v01.h"
|
||||
#include "qmi_client.h"
|
||||
#include "qmi_idl_lib.h"
|
||||
|
||||
/* Specific qmi_ts sensor data */
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t condition;
|
||||
int init_thresh_set;
|
||||
int threshold_reached;
|
||||
int hi_idx, lo_idx;
|
||||
sensor_t *sensor;
|
||||
} qmi_ts_data;
|
||||
|
||||
/* Help track individual sensors for setup, shutdown, and updates. */
|
||||
typedef struct {
|
||||
const char *thermald_name;
|
||||
const char *ts_qmi_name;
|
||||
int last_read;
|
||||
qmi_ts_data *data;
|
||||
} qmi_ts_thermald_data;
|
||||
|
||||
/* Used to protect access of thermald_info */
|
||||
static pthread_mutex_t qmi_ts_info_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* Add newly supported sensors here. */
|
||||
static qmi_ts_thermald_data thermald_info[] = {
|
||||
{"pa_therm0", "pa", 0, NULL},
|
||||
{"pa_therm1", "pa_1", 0, NULL}
|
||||
};
|
||||
|
||||
#define QMI_TS_MAX_STRING 16
|
||||
|
||||
void qmi_ts_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level);
|
||||
|
||||
/*===========================================================================
|
||||
LOCAL FUNCTION qmi_ts_get_thermald_info_idx
|
||||
|
||||
Helper function for finding thermald_info index of information based off of
|
||||
thermald sensor name..
|
||||
|
||||
ARGUMENTS
|
||||
sensor - Thermald version of sensor name.
|
||||
|
||||
RETURN VALUE
|
||||
-1 on Failure, thermald_info array idx on Success.
|
||||
===========================================================================*/
|
||||
static int qmi_ts_get_thermald_info_idx(const char *sensor)
|
||||
{
|
||||
int idx = -1;
|
||||
|
||||
/* Find corresponding qmi_ts_thermald_data */
|
||||
for (idx = 0; idx < ARRAY_SIZE(thermald_info); idx++) {
|
||||
if (strncmp(thermald_info[idx].thermald_name, sensor,
|
||||
QMI_TS_MAX_STRING) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == ARRAY_SIZE(thermald_info))
|
||||
idx = -1;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_ts_update_temperature
|
||||
|
||||
Updates the temperature for the thermald_info array.
|
||||
|
||||
ARGUMENTS
|
||||
sensor - QMI TS version of sensor name.
|
||||
|
||||
RETURN VALUE
|
||||
None
|
||||
===========================================================================*/
|
||||
void qmi_ts_update_temperature(const char *sensor, int temperature)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
if (NULL == sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find corresponding qmi_ts_data */
|
||||
for (idx = 0; idx < ARRAY_SIZE(thermald_info); idx++) {
|
||||
if (strncmp(thermald_info[idx].ts_qmi_name, sensor,
|
||||
QMI_TS_MAX_STRING) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx >= ARRAY_SIZE(thermald_info)) {
|
||||
msg("%s: unknown sensor %s\n", __func__, sensor);
|
||||
return;
|
||||
}
|
||||
|
||||
thermald_info[idx].last_read = temperature;
|
||||
|
||||
pthread_mutex_lock(&qmi_ts_info_mtx);
|
||||
if (thermald_info[idx].data != NULL) {
|
||||
qmi_ts_data *qmi_ts = thermald_info[idx].data;
|
||||
|
||||
dbgmsg("Sensor update recieved :%s %d", sensor, temperature);
|
||||
/* notify the waiting thread */
|
||||
pthread_mutex_lock(&(qmi_ts->mutex));
|
||||
qmi_ts->threshold_reached = 1;
|
||||
pthread_cond_broadcast(&(qmi_ts->condition));
|
||||
pthread_mutex_unlock(&(qmi_ts->mutex));
|
||||
}
|
||||
pthread_mutex_unlock(&qmi_ts_info_mtx);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_ts_setup
|
||||
|
||||
QMI TS setup sensor.
|
||||
|
||||
ARGUMENTS
|
||||
setting - thermald sensor setting
|
||||
sensor - thermald sensor data
|
||||
|
||||
RETURN VALUE
|
||||
0 on Failure, 1 on Success
|
||||
===========================================================================*/
|
||||
int qmi_ts_setup(sensor_setting_t *setting, sensor_t *sensor)
|
||||
{
|
||||
qmi_ts_data *qmi_ts = NULL;
|
||||
int idx;
|
||||
|
||||
/* We have nothing to do if there are no thresholds */
|
||||
if (!setting->num_thresholds) {
|
||||
dbgmsg("No thresholds for sensor %s\n", sensor->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = qmi_ts_get_thermald_info_idx(sensor->name);
|
||||
if (idx < 0) {
|
||||
msg("%s: invalid sensor name %s", __func__, sensor->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate QMI TS data */
|
||||
qmi_ts = (qmi_ts_data *) malloc(sizeof(qmi_ts_data));
|
||||
if (NULL == qmi_ts) {
|
||||
msg("%s: malloc failed", __func__);
|
||||
return 0;
|
||||
}
|
||||
memset(qmi_ts, 0, sizeof(qmi_ts_data));
|
||||
sensor->data = (void *) qmi_ts;
|
||||
|
||||
pthread_mutex_init(&(qmi_ts->mutex), NULL);
|
||||
pthread_cond_init(&(qmi_ts->condition), NULL);
|
||||
qmi_ts->threshold_reached = 0;
|
||||
qmi_ts->init_thresh_set = 0;
|
||||
qmi_ts->sensor = sensor;
|
||||
setting->disabled = 0;
|
||||
thermald_info[idx].data = qmi_ts;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_ts_shutdown
|
||||
|
||||
QMI TS shutdown sensor.
|
||||
|
||||
ARGUMENTS
|
||||
setting - thermald sensor setting
|
||||
|
||||
RETURN VALUE
|
||||
None
|
||||
===========================================================================*/
|
||||
void qmi_ts_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
qmi_ts_data *qmi_ts;
|
||||
int idx;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->name ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
idx = qmi_ts_get_thermald_info_idx(setting->sensor->name);
|
||||
if (idx < 0) {
|
||||
msg("%s: invalid sensor name %s", __func__,
|
||||
setting->sensor->name);
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&qmi_ts_info_mtx);
|
||||
/* Make sure an indication cannot be issued to a sensor being shutdown */
|
||||
qmi_ts = thermald_info[idx].data;
|
||||
thermald_info[idx].data = NULL;
|
||||
setting->sensor->data = NULL;
|
||||
pthread_mutex_unlock(&qmi_ts_info_mtx);
|
||||
|
||||
pthread_mutex_destroy(&qmi_ts->mutex);
|
||||
pthread_cond_destroy(&qmi_ts->condition);
|
||||
|
||||
free(qmi_ts);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_ts_get_temperature
|
||||
|
||||
QMI TS get sensor temperature.
|
||||
|
||||
ARGUMENTS
|
||||
setting - thermald sensor setting
|
||||
|
||||
RETURN VALUE
|
||||
Current temperature, CONV(-273) on failure
|
||||
===========================================================================*/
|
||||
int qmi_ts_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
int temp = -273;
|
||||
int idx;
|
||||
|
||||
qmi_ts_data *qmi_ts;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->name ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return CONV(temp);
|
||||
}
|
||||
|
||||
idx = qmi_ts_get_thermald_info_idx(setting->sensor->name);
|
||||
if (idx < 0) {
|
||||
msg("%s: invalid sensor name %s", __func__,
|
||||
setting->sensor->name);
|
||||
return CONV(temp);
|
||||
}
|
||||
|
||||
temp = thermald_info[idx].last_read;
|
||||
return CONV(temp);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_ts_interrupt_wait
|
||||
|
||||
QMI TS sensor wait for interrupt.
|
||||
|
||||
ARGUMENTS
|
||||
setting - thermald sensor setting
|
||||
|
||||
RETURN VALUE
|
||||
None
|
||||
===========================================================================*/
|
||||
void qmi_ts_interrupt_wait(sensor_setting_t *setting)
|
||||
{
|
||||
qmi_ts_data *qmi_ts;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setting->sensor->interrupt_enable) {
|
||||
qmi_ts = (qmi_ts_data *) setting->sensor->data;
|
||||
|
||||
if (qmi_ts->init_thresh_set == 0) {
|
||||
/* Set first threshold to trigger. */
|
||||
qmi_ts_update_thresholds(setting, THRESHOLD_NOCHANGE, 0);
|
||||
qmi_ts->init_thresh_set = 1;
|
||||
}
|
||||
|
||||
/* Wait for sensor threshold condition */
|
||||
pthread_mutex_lock(&(qmi_ts->mutex));
|
||||
while (!qmi_ts->threshold_reached) {
|
||||
pthread_cond_wait(&(qmi_ts->condition),
|
||||
&(qmi_ts->mutex));
|
||||
}
|
||||
qmi_ts->threshold_reached = 0;
|
||||
pthread_mutex_unlock(&(qmi_ts->mutex));
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION qmi_ts_update_thresholds
|
||||
|
||||
QMI TS sensor update interrupt thresholds.
|
||||
|
||||
ARGUMENTS
|
||||
setting - thermald sensor setting
|
||||
threshold_type - type of threshold change that triggered update
|
||||
level - current settings level
|
||||
|
||||
RETURN VALUE
|
||||
None
|
||||
===========================================================================*/
|
||||
void qmi_ts_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
int hi, lo;
|
||||
int hi_enable = 1;
|
||||
int lo_enable = 1;
|
||||
int idx;
|
||||
qmi_ts_data *qmi_ts;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data ||
|
||||
NULL == setting->sensor->name) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
qmi_ts = (qmi_ts_data *) setting->sensor->data;
|
||||
|
||||
idx = qmi_ts_get_thermald_info_idx(setting->sensor->name);
|
||||
if (idx < 0) {
|
||||
msg("%s: invalid sensor name %s", __func__, setting->sensor->name);
|
||||
return;
|
||||
}
|
||||
|
||||
dbgmsg("%s: threshold_type %d, level %d", __func__,
|
||||
threshold_type, level);
|
||||
hi = RCONV(setting->t[qmi_ts->hi_idx].lvl_trig);
|
||||
lo = RCONV(setting->t[qmi_ts->lo_idx].lvl_clr);
|
||||
if (level >= setting->num_thresholds) {
|
||||
/* handle corner high case */
|
||||
hi = RCONV(setting->t[setting->num_thresholds - 1].lvl_trig);
|
||||
qmi_ts->hi_idx = setting->num_thresholds - 1;
|
||||
hi_enable = 0;
|
||||
} else {
|
||||
hi = RCONV(setting->t[level].lvl_trig);
|
||||
qmi_ts->hi_idx = level;
|
||||
}
|
||||
if (level <= 0) {
|
||||
/* handle corner low case */
|
||||
lo = RCONV(setting->t[0].lvl_clr);
|
||||
qmi_ts->lo_idx = 0;
|
||||
lo_enable = 0;
|
||||
} else {
|
||||
lo = RCONV(setting->t[level - 1].lvl_clr);
|
||||
qmi_ts->lo_idx = level - 1;
|
||||
}
|
||||
|
||||
modem_ts_temp_request(thermald_info[idx].ts_qmi_name, 0,
|
||||
hi_enable, hi, lo_enable, lo);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#ifndef __QMI_TS_SENSOR_H__
|
||||
#define __QMI_TS_SENSOR_H__
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
int qmi_ts_setup(sensor_setting_t *settings, sensor_t * sensor);
|
||||
void qmi_ts_shutdown(sensor_setting_t *setting);
|
||||
int qmi_ts_get_temperature(sensor_setting_t *setting);
|
||||
void qmi_ts_interrupt_wait(sensor_setting_t *setting);
|
||||
void qmi_ts_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
|
||||
void qmi_ts_update_temperature(const char *sensor, int temperature);
|
||||
|
||||
#endif /* __QMI_TS_SENSOR_H__ */
|
||||
@@ -1,173 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2011-2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
Thermal Daemon
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This daemon monitors thermal/temperature sensor data and performs
|
||||
actions based on a configuration file (default is /etc/thermald.conf).
|
||||
|
||||
A sample configuration file is provided (thermald.conf_sample).
|
||||
|
||||
|
||||
|
||||
Configuration file format:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{debug}
|
||||
sampling <default sampling rate in ms>
|
||||
|
||||
[<temperature sensor section>]
|
||||
sampling <sampling rate in ms>
|
||||
thresholds <threshold values in degree Celsius> ...
|
||||
thresholds_clr <temperature value to clear thresholds> ...
|
||||
actions <action to perform at threshold;
|
||||
multiple actions separated by '+'> ...
|
||||
action_info <additional info for action;
|
||||
multiple action_info separated by '+'> ...
|
||||
|
||||
* Optional 'debug' flag determines if debug logging is enabled.
|
||||
* 'thresholds'/'thresholds_clr'/'actions'/'action_info' accepts a list of
|
||||
space separated values for up to 8 thresholds.
|
||||
|
||||
'actions' field
|
||||
---------------
|
||||
* 'none' ;
|
||||
- ACTION - Do nothing
|
||||
- ACTION_INFO - ignored
|
||||
|
||||
* 'report'
|
||||
- ACTION - Report threshold crossing to UI
|
||||
- ACTION_INFO - ignored
|
||||
- NOTES - The threshold crossing information is sent across an
|
||||
abstract local socket "THERMALD_UI" in newline-separated
|
||||
string format. Report action runs upon clearing or
|
||||
triggering a level, slightly different from the other
|
||||
actions which are run upon reaching the level, e.g.
|
||||
clearing level n+1 or triggering level n.
|
||||
|
||||
Parameters are sent in the following order.
|
||||
* sensorname - Name of sensor reporting
|
||||
* temperature - Current temperature
|
||||
* current_threshold_level - current threshold level triggered or cleared
|
||||
* is_trigger - "true" on level trigger, "false" on level clearing
|
||||
|
||||
Example Android code to listen to this notification is
|
||||
provided in the documentation folder.
|
||||
|
||||
* 'cpu'
|
||||
- ACTION - CPU frequency scaling
|
||||
- ACTION_INFO - Max CPU frequency in KHz
|
||||
|
||||
* 'lcd'
|
||||
- ACTION - LCD brightness throttling
|
||||
- ACTION_INFO - 0-255 value for max LCD brightness
|
||||
|
||||
* 'modem'
|
||||
- ACTION - Request throttling of modem functionality
|
||||
- ACTION_INFO - 0-3 throttling level for modem mitigation
|
||||
|
||||
* 'fusion'
|
||||
- ACTION - Request throttling of fusion modem functionality
|
||||
- ACTION_INFO - 0-3 throttling level for fusion modem mitigation
|
||||
|
||||
* 'battery'
|
||||
- ACTION - Battery charging current throttling
|
||||
- ACTION_INFO - 0-3 throttling level for battery charging current
|
||||
|
||||
* 'gpu'
|
||||
- ACTION - GPU frequency scaling
|
||||
- ACTION_INFO - Max GPU frequency in Hz
|
||||
|
||||
* 'wlan'
|
||||
- ACTION - WLAN throttling
|
||||
- ACTION_INFO - 0-4 throttling level for WLAN mitigation
|
||||
|
||||
* 'camera'
|
||||
- ACTION - CAMERA throttling
|
||||
- ACTION_INFO - 0-3 throttling level for CAMERA mitigation
|
||||
|
||||
* 'camcorder'
|
||||
- ACTION - CAMCORDER throttling
|
||||
- ACTION_INFO - 0-3 throttling level for CAMCORDER mitigation
|
||||
|
||||
* 'shutdown'
|
||||
- ACTION - Shutdown target
|
||||
- ACTION_INFO - Shutdown delay in ms
|
||||
|
||||
Example 1:
|
||||
----------
|
||||
sampling 1000
|
||||
|
||||
[PMIC_THERM]
|
||||
sampling 5000
|
||||
thresholds 40.2 45 50
|
||||
thresholds_clr 38 43 48
|
||||
actions cpu+report cpu cpu
|
||||
action_info 1188000+0 368640 245760
|
||||
|
||||
Description:
|
||||
1) Default sampling rate of 1 second.
|
||||
For sensor 'PMIC_THERM', sample at 5 second rate (overrides default):
|
||||
2) Threshold level 1 triggered at 40.2 deg C; clears if temperature drops
|
||||
to/below 38 deg C. When triggered, adjust maximum allowed CPU to
|
||||
1188000 KHz, which in this example is already the current maximum
|
||||
frequency, and results in no action.
|
||||
Also generate a report, action_info value 0 is ignored.
|
||||
3) Threshold level 2 triggered at 45 deg C; clears if temperature drops
|
||||
to/below 43 deg C. When triggered, adjust maximum allowed CPU to
|
||||
368640 KHz.
|
||||
4) When threshold level 2 cleared at 43 deg C; adjust CPU back to maximum
|
||||
frequency 1188000 KHz.
|
||||
5) When threshold level 1 cleared at 38 deg C; generate a report for level 1
|
||||
clearing, all mitigation is reset.
|
||||
|
||||
Example 2:
|
||||
----------
|
||||
debug
|
||||
sampling 2000
|
||||
|
||||
[PMIC_THERM]
|
||||
sampling 5000
|
||||
thresholds 40.2 45 50
|
||||
thresholds_clr 38 43 48
|
||||
actions cpu+report cpu report+shutdown
|
||||
action_info 768000+0 368640 0+6000
|
||||
|
||||
Description:
|
||||
1) Debug logging output is enabled.
|
||||
2) Default sampling rate of 2 second.
|
||||
For sensor 'PMIC_THERM', sample at 5 second rate (overrides default):
|
||||
3) Threshold level 1 triggered at 40.2 deg C; clears if temperature drops
|
||||
to/below 38 deg C. When triggered, adjust maximum allowed CPU to 768000 KHz,
|
||||
and generate a report (action_info value 0 is ignored).
|
||||
4) Threshold level 2 triggered at 45 deg C; clears if temperature drops
|
||||
to/below 43 deg C. When triggered, adjust maximum allowed CPU to 368640 KHz.
|
||||
5) Threshold level 3 triggered at 50 deg C; clears if temperature drops
|
||||
to/below 48 deg C. When triggered, generate a report and shutdown the
|
||||
target after a delay of 6 seconds.
|
||||
|
||||
Example 3:
|
||||
----------
|
||||
debug
|
||||
sampling 2000
|
||||
|
||||
[bcl]
|
||||
sampling 1000
|
||||
thresholds 100 0
|
||||
thresholds_clr 500 100
|
||||
actions report report
|
||||
action_info 0 0
|
||||
|
||||
Description:
|
||||
1) Debug logging output is enabled.
|
||||
2) Default sampling rate of 2 second.
|
||||
For battery current limit 'bcl', sample at 1 second rate (overrides default):
|
||||
3) Threshold level 1 triggered if ibat is at (imax - 100mA); clears if ibat drops
|
||||
to/below (imax - 500mA). When triggered, generate a report (action_info value 0 is ignored).
|
||||
4) Threshold level 2 triggered if ibat is at imax; clears if ibat drops
|
||||
to/below (imax - 100mA). When triggered, generate a report (action_info value 0 is ignored).
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2010-2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/msm_adc.h>
|
||||
#include "thermal.h"
|
||||
#include "sensors-hw.h"
|
||||
|
||||
#define MSM_ADC_NODE "/dev/msm_adc"
|
||||
#define POP_MEM_NODE "/sys/devices/virtual/thermal/thermal_zone0/temp"
|
||||
|
||||
char *sensor_names[] =
|
||||
{
|
||||
"PMIC_THERM",
|
||||
"XO_THERM",
|
||||
"XO_THERM_GPS",
|
||||
"POP_MEM_TZ",
|
||||
};
|
||||
|
||||
static int adc_fd = -1;
|
||||
static int pop_mem_fd = 0;
|
||||
|
||||
int sensors_setup(thermal_setting_t *settings)
|
||||
{
|
||||
struct msm_adc_lookup lookup;
|
||||
int i = 0;
|
||||
int rc, numEnabled = 0;
|
||||
|
||||
adc_fd = open(MSM_ADC_NODE, O_RDWR);
|
||||
if (adc_fd < 0) {
|
||||
msg("Error opening %s\n", MSM_ADC_NODE);
|
||||
i = POP_MEM_TZ;
|
||||
}
|
||||
|
||||
for (; i < POP_MEM_TZ; i++) {
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
strlcpy(lookup.name, sensor_names[i], MSM_ADC_MAX_CHAN_STR);
|
||||
lookup.name[MSM_ADC_MAX_CHAN_STR-1] = '\0';
|
||||
|
||||
rc = ioctl(adc_fd, MSM_ADC_LOOKUP, &lookup);
|
||||
if (rc < 0) {
|
||||
msg("Error looking up '%s', skipping\n", sensor_names[i]);
|
||||
settings->sensors[i].disabled = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
settings->sensors[i].chan_idx = lookup.chan_idx;
|
||||
settings->sensors[i].disabled = 0;
|
||||
numEnabled++;
|
||||
|
||||
dbgmsg("Sensor '%s' -> channel '%u'\n",
|
||||
sensor_names[i], lookup.chan_idx);
|
||||
}
|
||||
|
||||
pop_mem_fd = open(POP_MEM_NODE, O_RDONLY);
|
||||
if (pop_mem_fd > 0) {
|
||||
settings->sensors[i].chan_idx = pop_mem_fd;
|
||||
settings->sensors[i].disabled = 0;
|
||||
numEnabled++;
|
||||
} else {
|
||||
msg("Error(%d) opening %s\n", pop_mem_fd, POP_MEM_NODE);
|
||||
settings->sensors[i].chan_idx = -1;
|
||||
settings->sensors[i].disabled = 1;
|
||||
}
|
||||
|
||||
return (numEnabled > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
void sensors_shutdown()
|
||||
{
|
||||
if (adc_fd != -1)
|
||||
close(adc_fd);
|
||||
adc_fd = -1;
|
||||
|
||||
if (pop_mem_fd != -1)
|
||||
close(pop_mem_fd);
|
||||
pop_mem_fd = -1;
|
||||
}
|
||||
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value >= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value <= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_get_temperature(sensor_setting_t *sensor)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_adc_conversion conv;
|
||||
|
||||
if (sensor->id == POP_MEM_TZ) {
|
||||
char buf[30] = {0};
|
||||
int temp = 0;
|
||||
|
||||
lseek(sensor->chan_idx, 0, SEEK_SET);
|
||||
read(sensor->chan_idx, buf, sizeof(buf) - 1);
|
||||
temp = strtol(buf, NULL, 10);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
memset(&conv, 0, sizeof(conv));
|
||||
conv.chan = sensor->chan_idx;
|
||||
|
||||
if (adc_fd <= 0) {
|
||||
msg("Error opening sensor '%s'\n", sensor->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ioctl(adc_fd, MSM_ADC_REQUEST, &conv);
|
||||
if (rc) {
|
||||
msg("Error getting sensor info '%s'\n", sensor->desc);
|
||||
} else {
|
||||
dbgmsg("Sensor '%s' - %2.1f*C (%u)\n",
|
||||
sensor->desc, RCONV(conv.result), conv.result);
|
||||
}
|
||||
|
||||
return conv.result;
|
||||
}
|
||||
|
||||
|
||||
void sensor_wait(sensor_setting_t *setting)
|
||||
{
|
||||
static int is_first_poll = 1;
|
||||
if (setting == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_first_poll) {
|
||||
usleep(setting->sampling_period_us);
|
||||
} else {
|
||||
is_first_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2010-2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tsens-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
char *sensor_names[] =
|
||||
{
|
||||
"pm8058_tz",
|
||||
"tsens_tz_sensor0",
|
||||
};
|
||||
|
||||
int pmic_sensors_setup(sensor_setting_t *settings, sensor_t* sensor);
|
||||
void pmic_sensors_shutdown(sensor_setting_t *setting);
|
||||
int pmic_sensor_get_temperature(sensor_setting_t *setting);
|
||||
|
||||
static sensor_t g_sensors[] = {
|
||||
{
|
||||
.name = "pm8058_tz",
|
||||
.setup = pmic_sensors_setup,
|
||||
.shutdown = pmic_sensors_shutdown,
|
||||
.get_temperature = pmic_sensor_get_temperature,
|
||||
.interrupt_wait = NULL,
|
||||
.update_thresholds = NULL,
|
||||
.setting = NULL,
|
||||
.tzn = 1,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor0",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 3,
|
||||
.data = NULL,
|
||||
#ifdef ENABLE_TSENS_INTERRUPT
|
||||
.interrupt_enable = 1,
|
||||
#else
|
||||
.interrupt_enable = 0,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* PMIC sensor */
|
||||
int pmic_sensors_setup(sensor_setting_t *setting, sensor_t* s)
|
||||
{
|
||||
int adc_fd = -1;
|
||||
int sensor_count = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
int tzn = 0;
|
||||
sensor_t *sensor = (sensor_t *)s;
|
||||
|
||||
tzn = get_tzn(sensor->name);
|
||||
if (tzn < 0) {
|
||||
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
sensor->tzn = tzn;
|
||||
|
||||
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
|
||||
|
||||
adc_fd = open(name, O_RDONLY);
|
||||
if (adc_fd > 0) {
|
||||
setting->disabled = 0;
|
||||
setting->chan_idx = adc_fd;
|
||||
sensor_count++;
|
||||
} else {
|
||||
msg("pmic: Error opening %s\n", name);
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void pmic_sensors_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
if (setting->chan_idx > 0)
|
||||
close(setting->chan_idx);
|
||||
}
|
||||
|
||||
int pmic_sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[10] = {0};
|
||||
int temp = 0;
|
||||
|
||||
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(setting->chan_idx, 0, SEEK_SET);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
int sensors_setup(thermal_setting_t *settings)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int sensor_count = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!settings)
|
||||
return sensor_count;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
for (j = 0; j < SENSOR_IDX_MAX; j++) {
|
||||
if (settings->sensors[j].desc == NULL ||
|
||||
0 != strcmp(settings->sensors[j].desc, g_sensors[i].name))
|
||||
continue;
|
||||
|
||||
info("Sensor setup:[%s]\n", g_sensors[i].name);
|
||||
g_sensors[i].setting = &settings->sensors[j];
|
||||
settings->sensors[j].sensor = &g_sensors[i];
|
||||
|
||||
ret = g_sensors[i].setup(&settings->sensors[j],
|
||||
(sensor_t *)&g_sensors[i]);
|
||||
sensor_count += ret;
|
||||
|
||||
/* TSENS sensors need separate enabling and threshold set */
|
||||
if (!ret ||
|
||||
0 != strcmp(g_sensors[i].name, "tsens_tz_sensor0"))
|
||||
break;
|
||||
tsens_sensor_enable_sensor(g_sensors[i].setting, 1);
|
||||
if (g_sensors[i].interrupt_enable) {
|
||||
tsens_sensor_update_thresholds(g_sensors[i].setting,
|
||||
THRESHOLD_NOCHANGE, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void sensors_shutdown()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
|
||||
g_sensors[i].shutdown(g_sensors[i].setting);
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value >= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value <= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
int temp = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL ||
|
||||
setting->sensor->get_temperature == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
temp = setting->sensor->get_temperature(setting);
|
||||
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void sensor_wait(sensor_setting_t *setting)
|
||||
{
|
||||
static int is_first_poll = 1;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->sensor->interrupt_enable &&
|
||||
setting->sensor->interrupt_wait) {
|
||||
setting->sensor->interrupt_wait(setting);
|
||||
} else if (!is_first_poll) {
|
||||
usleep(setting->sampling_period_us);
|
||||
} else {
|
||||
is_first_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->sensor->interrupt_enable == 0 ||
|
||||
setting->sensor->update_thresholds == NULL)
|
||||
return;
|
||||
|
||||
setting->sensor->update_thresholds(setting, threshold_type, level);
|
||||
}
|
||||
@@ -1,991 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2011-2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qmi-ts-sensor.h"
|
||||
#include "tsens-sensor.h"
|
||||
#include "bcl-sensor.h"
|
||||
#include "adc-sensor.h"
|
||||
#include "gen-sensor.h"
|
||||
#include "pm8821-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
#define NUM_TSENS_SENSORS (11)
|
||||
|
||||
#define HOTPLUG_HIGH_THRESHOLD_8960 (100)
|
||||
#define HOTPLUG_LOW_THRESHOLD_8960 (HOTPLUG_HIGH_THRESHOLD_8960 - 20)
|
||||
#define HOTPLUG_HIGH_THRESHOLD_8064 (115)
|
||||
#define HOTPLUG_LOW_THRESHOLD_8064 (HOTPLUG_HIGH_THRESHOLD_8064 - 20)
|
||||
#define HOTPLUG_HIGH_THRESHOLD_8930 (110)
|
||||
#define HOTPLUG_LOW_THRESHOLD_8930 (HOTPLUG_HIGH_THRESHOLD_8930 - 20)
|
||||
#define MPDECISION_SOCKET "/dev/socket/mpdecision"
|
||||
|
||||
char *sensor_names[] =
|
||||
{
|
||||
"pm8921_tz",
|
||||
"pa_therm0",
|
||||
"pa_therm1",
|
||||
"tsens_tz_sensor0",
|
||||
"tsens_tz_sensor1",
|
||||
"tsens_tz_sensor2",
|
||||
"tsens_tz_sensor3",
|
||||
"tsens_tz_sensor4",
|
||||
"tsens_tz_sensor5",
|
||||
"tsens_tz_sensor6",
|
||||
"tsens_tz_sensor7",
|
||||
"tsens_tz_sensor8",
|
||||
"tsens_tz_sensor9",
|
||||
"tsens_tz_sensor10",
|
||||
"bcl",
|
||||
"pm8821_tz",
|
||||
};
|
||||
|
||||
enum hybrid_state_t {
|
||||
HYBRID_STATE_MAIN_INTERRUPT,
|
||||
HYBRID_STATE_POLLING
|
||||
};
|
||||
|
||||
enum sensor_type_8960_t {
|
||||
SENSOR_TYPE_NON_HYBRID,
|
||||
SENSOR_TYPE_HYBRID_MAIN,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_BCL,
|
||||
};
|
||||
|
||||
/* variables controlling hybrid polling */
|
||||
pthread_cond_t hybrid_condition;
|
||||
pthread_mutex_t hybrid_mutex;
|
||||
enum hybrid_state_t hybrid_state;
|
||||
pthread_cond_t finish_poll_condition;
|
||||
pthread_mutex_t poll_count_mutex;
|
||||
int poll_count = 0;
|
||||
|
||||
static void hybrid_main_interrupt_wait(sensor_setting_t *setting);
|
||||
static void hybrid_main_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
|
||||
static void hybrid_aux_interrupt_wait(sensor_setting_t *setting);
|
||||
static void hybrid_aux_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
|
||||
static int pa_sensor_setup(sensor_setting_t *settings, sensor_t *sensor);
|
||||
|
||||
static sensor_t g_sensors[] = {
|
||||
{
|
||||
.name = "pm8921_tz",
|
||||
.setup = gen_sensors_setup,
|
||||
.shutdown = gen_sensors_shutdown,
|
||||
.get_temperature = gen_sensor_get_temperature,
|
||||
.interrupt_wait = NULL,
|
||||
.update_thresholds = NULL,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "pa_therm0",
|
||||
.setup = pa_sensor_setup,
|
||||
.shutdown = NULL,
|
||||
.get_temperature = NULL,
|
||||
.interrupt_wait = NULL,
|
||||
.update_thresholds = NULL,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "pa_therm1",
|
||||
.setup = pa_sensor_setup,
|
||||
.shutdown = NULL,
|
||||
.get_temperature = NULL,
|
||||
.interrupt_wait = NULL,
|
||||
.update_thresholds = NULL,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor0",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_main_interrupt_wait,
|
||||
.update_thresholds = hybrid_main_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor1",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 1,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor2",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 2,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor3",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 3,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor4",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 4,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor5",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 5,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor6",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 6,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor7",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 7,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor8",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 8,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor9",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 9,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor10",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = hybrid_aux_interrupt_wait,
|
||||
.update_thresholds = hybrid_aux_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 10,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 0,
|
||||
},
|
||||
{
|
||||
.name = "bcl",
|
||||
.setup = bcl_setup,
|
||||
.shutdown = bcl_shutdown,
|
||||
.get_temperature = bcl_get_diff_imax_ibat,
|
||||
.interrupt_wait = bcl_interrupt_wait,
|
||||
.update_thresholds = bcl_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "pm8821_tz",
|
||||
.setup = pm8821_setup,
|
||||
.shutdown = pm8821_shutdown,
|
||||
.get_temperature = pm8821_get_temperature,
|
||||
.interrupt_wait = pm8821_interrupt_wait,
|
||||
.update_thresholds = NULL,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* NOTE: number of indexes in sensor_type should match g_sensors */
|
||||
static enum sensor_type_8960_t sensor_type[] = {
|
||||
SENSOR_TYPE_NON_HYBRID,
|
||||
SENSOR_TYPE_NON_HYBRID,
|
||||
SENSOR_TYPE_NON_HYBRID,
|
||||
SENSOR_TYPE_HYBRID_MAIN,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_HYBRID_AUX,
|
||||
SENSOR_TYPE_BCL,
|
||||
SENSOR_TYPE_NON_HYBRID,
|
||||
};
|
||||
|
||||
/* status of main sensor's threshold interrupt, toggle 0 and 1 */
|
||||
static int main_sensor_hi_threshold_enabled;
|
||||
/* are all sensor thresholds cleared? true/false */
|
||||
static int threshold_cleared[NUM_TSENS_SENSORS] = {1,1,1,1,1,1,1,1,1,1,1};
|
||||
|
||||
static hotplug_map_t hotplug_map_8960[] = {
|
||||
{"tsens_tz_sensor2", 0x2, TSENS_TZ_SENSOR2},
|
||||
{NULL, 0x0, 0},
|
||||
};
|
||||
|
||||
static hotplug_map_t hotplug_map_8930[] = {
|
||||
{"tsens_tz_sensor6", 0x2, TSENS_TZ_SENSOR6},
|
||||
{NULL, 0x0, 0},
|
||||
};
|
||||
|
||||
static hotplug_map_t hotplug_map_8064[] = {
|
||||
{"tsens_tz_sensor8", 0x2, TSENS_TZ_SENSOR8},
|
||||
{"tsens_tz_sensor9", 0x4, TSENS_TZ_SENSOR9},
|
||||
{"tsens_tz_sensor10", 0x8, TSENS_TZ_SENSOR10},
|
||||
{"pm8821_tz", 0xC, PM8821_TZ},
|
||||
{NULL, 0x0, 0},
|
||||
};
|
||||
hotplug_map_t *hotplug_map;
|
||||
static int hotplug_high_threshold;
|
||||
static int hotplug_low_threshold;
|
||||
|
||||
/* returns gsensor idx matching the sensor name, or -1 if error */
|
||||
static int get_gsensor_idx(char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
if (0 == strncmp(name, g_sensors[i].name,
|
||||
SENSOR_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
return (i >= ARRAY_SIZE(g_sensors)) ? -1 : i;
|
||||
}
|
||||
|
||||
static int all_hybrid_thresholds_cleared(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_TSENS_SENSORS; i++) {
|
||||
if (threshold_cleared[i] == 0)
|
||||
break;
|
||||
}
|
||||
if (i == NUM_TSENS_SENSORS) {
|
||||
dbgmsg("All hybrid_thresholds_cleared");
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hybrid_sensor_id(sensor_setting_t *setting)
|
||||
{
|
||||
int sensor_id = 0;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->desc) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (!sscanf(setting->desc, "tsens_tz_sensor%d", &sensor_id)) {
|
||||
return -1;
|
||||
} else {
|
||||
return sensor_id;
|
||||
}
|
||||
}
|
||||
|
||||
/* Manually disable sensors for unconfigured sensors */
|
||||
static void disable_sensor_manual(char *sensor_name)
|
||||
{
|
||||
int tzn = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
tzn = get_tzn(sensor_name);
|
||||
|
||||
if (tzn != -1) {
|
||||
snprintf(name, MAX_PATH, TZ_MODE, tzn);
|
||||
write_to_file(name, "disabled", strlen("disabled"));
|
||||
dbgmsg("Sensor '%s' not configured - set disabled\n",
|
||||
sensor_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int sensor_is_configured(sensor_t *sensor)
|
||||
{
|
||||
return (sensor->setting != NULL);
|
||||
}
|
||||
|
||||
static void hybrid_enable_auxiliary_sensors(int enabled)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
if (sensor_type[i] != SENSOR_TYPE_HYBRID_AUX)
|
||||
continue;
|
||||
|
||||
if (sensor_is_configured(&g_sensors[i]) &&
|
||||
g_sensors[i].setting->disabled == 0) {
|
||||
tsens_sensor_enable_sensor(g_sensors[i].setting,
|
||||
enabled);
|
||||
} else if (enabled == 0 &&
|
||||
!sensor_is_configured(&g_sensors[i])) {
|
||||
/* disable sensor manually if unconfigured */
|
||||
disable_sensor_manual(g_sensors[i].name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* request hotplug manually via sysfs.
|
||||
Fallback function for hotplugging CPUs
|
||||
This function should only be called in one thread per hotplug core */
|
||||
static int hotplug_request_manual(int cpu, int online)
|
||||
{
|
||||
char node_buf[MAX_PATH] = {0};
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
static int prev[MAX_CPUS] = {1, 1, 1, 1};
|
||||
|
||||
if (online != prev[cpu]) {
|
||||
/* Write to offline node if present */
|
||||
snprintf(node_buf, MAX_PATH, CPU_SYSFS(HOTPLUG_NODE), cpu);
|
||||
if (write_to_file(node_buf, online ? "1": "0", 2) > 0) {
|
||||
info("ACTION: Hotplugged %s CPU[%d]\n",
|
||||
online ? "ON" : "OFF", cpu);
|
||||
prev[cpu] = online;
|
||||
} else {
|
||||
msg("Failed to hotplug CPU[%d] at path %s\n",
|
||||
cpu, node_buf);
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
dbgmsg("Hotplug request already at %d\n", online);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Inform mpdecision to do hotplug, else hotplug cores manually */
|
||||
void hotplug_request_critical(sensor_setting_t *setting, int temp, int cpu,
|
||||
int requester, int set_offline)
|
||||
{
|
||||
static int hotplug_off_req[MAX_CPUS][SENSOR_IDX_MAX];
|
||||
static int done_hotplug[MAX_CPUS];
|
||||
char tempBuf[REPORT_MSG_MAX];
|
||||
static pthread_mutex_t hotplug_cpu_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
int rc = 0;
|
||||
int i;
|
||||
|
||||
if (setting == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&hotplug_cpu_mtx);
|
||||
|
||||
/* Aggregate vote for hotplug request for all sensors */
|
||||
/* While online core ensure all sensors threshold is cleared for that cpu */
|
||||
hotplug_off_req[cpu][requester] = set_offline;
|
||||
if (set_offline == 0) {
|
||||
for (i = 0; hotplug_map[i].sensor_name != NULL; i++) {
|
||||
if (hotplug_off_req[cpu][hotplug_map[i].sensor_idx] != 0) {
|
||||
dbgmsg("Waiting for other sensors to clear hotplug "
|
||||
"threshold for cpu[%d]", cpu);
|
||||
goto handle_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (set_offline != done_hotplug[cpu]) {
|
||||
info("ACTION: HOTPLUG CPU[%d] critical failsafe %s - "
|
||||
"Sensor %s - temperature %d", cpu, set_offline ? "triggered" : "cleared",
|
||||
setting->desc, temp);
|
||||
snprintf(tempBuf, REPORT_MSG_MAX, "hotplug %d %d", cpu, !set_offline);
|
||||
|
||||
if (write_to_local_file_socket(MPDECISION_SOCKET, tempBuf,
|
||||
strlen(tempBuf)) != (int) strlen(tempBuf)) {
|
||||
/* fallback to manual hotplug update */
|
||||
rc = hotplug_request_manual(cpu, !set_offline);
|
||||
}
|
||||
if (rc == 0)
|
||||
done_hotplug[cpu] = set_offline;
|
||||
}
|
||||
|
||||
handle_return:
|
||||
pthread_mutex_unlock(&hotplug_cpu_mtx);
|
||||
|
||||
}
|
||||
|
||||
void do_hotplug_critical(sensor_setting_t *setting, int cpu,
|
||||
int temperature)
|
||||
{
|
||||
int cpu_mask;
|
||||
|
||||
if (setting == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (cpu_mask = 0; cpu_mask < MAX_CPUS; cpu_mask++) {
|
||||
if ((cpu & (1 << cpu_mask)) == 0)
|
||||
continue;
|
||||
|
||||
if (temperature >= setting->hotplug_lvl_trig)
|
||||
hotplug_request_critical(setting, temperature,
|
||||
cpu_mask, setting->id, 1);
|
||||
else if (temperature <= setting->hotplug_lvl_clr)
|
||||
hotplug_request_critical(setting, temperature,
|
||||
cpu_mask, setting->id, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void setup_hotplug_map(thermal_setting_t *settings)
|
||||
{
|
||||
int j = 0;
|
||||
int msm_id = therm_get_msm_id();
|
||||
|
||||
switch (msm_id) {
|
||||
case THERM_MSM_8064AB:
|
||||
case THERM_MSM_8064:
|
||||
hotplug_map = hotplug_map_8064;
|
||||
hotplug_high_threshold = HOTPLUG_HIGH_THRESHOLD_8064;
|
||||
hotplug_low_threshold = HOTPLUG_LOW_THRESHOLD_8064;
|
||||
break;
|
||||
case THERM_MSM_8930AB:
|
||||
case THERM_MSM_8930AA:
|
||||
case THERM_MSM_8930:
|
||||
hotplug_map = hotplug_map_8930;
|
||||
hotplug_high_threshold = HOTPLUG_HIGH_THRESHOLD_8930;
|
||||
hotplug_low_threshold = HOTPLUG_LOW_THRESHOLD_8930;
|
||||
break;
|
||||
case THERM_MSM_8960AB:
|
||||
case THERM_MSM_8960:
|
||||
default:
|
||||
/* default to 8960 hotplug map */
|
||||
hotplug_map = hotplug_map_8960;
|
||||
hotplug_high_threshold = HOTPLUG_HIGH_THRESHOLD_8960;
|
||||
hotplug_low_threshold = HOTPLUG_LOW_THRESHOLD_8960;
|
||||
}
|
||||
/* Assign hotplug thresholds to hotplug_lvl_trg/clr of each sensor setting */
|
||||
while (hotplug_map[j].sensor_name != NULL) {
|
||||
if (hotplug_map[j].sensor_idx >= SENSOR_IDX_MAX) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
settings->sensors[hotplug_map[j].sensor_idx].hotplug_lvl_trig =
|
||||
hotplug_high_threshold;
|
||||
settings->sensors[hotplug_map[j].sensor_idx].hotplug_lvl_clr =
|
||||
hotplug_low_threshold;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
int sensors_setup(thermal_setting_t *settings)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int save_main_i = -1;
|
||||
int sensor_count = 0;
|
||||
int aux_sensor_count = 0;
|
||||
int save_bcl_i = -1;
|
||||
|
||||
if (!settings)
|
||||
return sensor_count;
|
||||
|
||||
pthread_mutex_init(&hybrid_mutex, NULL);
|
||||
pthread_cond_init(&hybrid_condition, NULL);
|
||||
pthread_cond_init(&finish_poll_condition, NULL);
|
||||
pthread_mutex_init(&poll_count_mutex, NULL);
|
||||
hybrid_state = HYBRID_STATE_MAIN_INTERRUPT;
|
||||
|
||||
setup_hotplug_map(settings);
|
||||
|
||||
/* override hotplug limit if requested on cmdline */
|
||||
if (new_corelimit) {
|
||||
hotplug_high_threshold = new_corelimit;
|
||||
hotplug_low_threshold = new_corelimit - 20;
|
||||
}
|
||||
|
||||
/* Set up sensors */
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
for (j = 0; j < SENSOR_IDX_MAX; j++) {
|
||||
if (settings->sensors[j].desc == NULL ||
|
||||
0 != strcmp(settings->sensors[j].desc, g_sensors[i].name))
|
||||
continue;
|
||||
info("Sensor setup:[%s]\n", g_sensors[i].name);
|
||||
g_sensors[i].setting = &settings->sensors[j];
|
||||
settings->sensors[j].sensor = &g_sensors[i];
|
||||
|
||||
if (g_sensors[i].setup(&settings->sensors[j],
|
||||
(sensor_t *)&g_sensors[i])) {
|
||||
sensor_count++;
|
||||
if (sensor_type[i] == SENSOR_TYPE_HYBRID_MAIN) {
|
||||
save_main_i = i;
|
||||
} else if (sensor_type[i] == SENSOR_TYPE_HYBRID_AUX) {
|
||||
aux_sensor_count++;
|
||||
} else if (sensor_type[i] == SENSOR_TYPE_BCL) {
|
||||
save_bcl_i = i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* set up hotplug sensors if not configured */
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
int g_idx;
|
||||
if (settings->sensors[i].disabled == 0)
|
||||
continue;
|
||||
|
||||
j = 0;
|
||||
while (hotplug_map[j].sensor_name != NULL) {
|
||||
if (i != hotplug_map[j].sensor_idx) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
settings->sensors[i].desc = sensor_names[i];
|
||||
settings->sensors[i].num_thresholds = 1;
|
||||
settings->sensors[i].disabled = 0;
|
||||
settings->sensors[i].sampling_period_us = 1000000; /* 1 sec */
|
||||
settings->sensors[i].t[0].lvl_trig = CONV(hotplug_high_threshold);
|
||||
settings->sensors[i].t[0].lvl_clr = CONV(hotplug_low_threshold);
|
||||
settings->sensors[i].t[0].actions[0].action = NONE;
|
||||
settings->sensors[i].t[0].actions[0].info = 0;
|
||||
g_idx = get_gsensor_idx(settings->sensors[i].desc);
|
||||
if (g_idx == -1) {
|
||||
msg("Invalid sensor name %s", settings->sensors[i].desc);
|
||||
break;
|
||||
}
|
||||
|
||||
g_sensors[g_idx].setting = &settings->sensors[i];
|
||||
settings->sensors[i].sensor = &g_sensors[g_idx];
|
||||
if (g_sensors[g_idx].setup(&settings->sensors[i],
|
||||
(sensor_t *)&g_sensors[g_idx])) {
|
||||
sensor_count++;
|
||||
if (sensor_type[g_idx] == SENSOR_TYPE_HYBRID_MAIN) {
|
||||
save_main_i = g_idx;
|
||||
} else if (sensor_type[g_idx] == SENSOR_TYPE_HYBRID_AUX) {
|
||||
aux_sensor_count++;
|
||||
}
|
||||
}
|
||||
|
||||
info("Sensor '%s' enabled for CPU%d "
|
||||
"core-control failsafe", sensor_names[i],
|
||||
hotplug_map[j].cpu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
poll_count = aux_sensor_count;
|
||||
|
||||
/* Enable main sensors, disable auxiliary sensors, setup threshold */
|
||||
if (save_main_i > -1 && save_main_i < ARRAY_SIZE(g_sensors)) {
|
||||
tsens_sensor_enable_sensor(g_sensors[save_main_i].setting, 1);
|
||||
hybrid_enable_auxiliary_sensors(0);
|
||||
|
||||
tsens_sensor_update_thresholds(g_sensors[save_main_i].setting,
|
||||
THRESHOLD_NOCHANGE, 0);
|
||||
/* mark threshold_enabled */
|
||||
main_sensor_hi_threshold_enabled = 1;
|
||||
} else {
|
||||
info("Hybrid main sensor not configured, disabling any auxiliary sensors found");
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
if (!sensor_is_configured(&g_sensors[i]) ||
|
||||
g_sensors[i].setting->disabled != 0 ||
|
||||
sensor_type[i] != SENSOR_TYPE_HYBRID_AUX)
|
||||
continue;
|
||||
|
||||
info("Disabling auxiliary sensor:[%s]\n", g_sensors[i].name);
|
||||
g_sensors[i].setting->disabled = 1;
|
||||
|
||||
j = 0;
|
||||
while (hotplug_map[j].sensor_name != NULL) {
|
||||
if (g_sensors[i].setting->id == hotplug_map[j].sensor_idx)
|
||||
info("Core-control failsafe auxiliary sensor '%s' disabled, "
|
||||
"failsafe for CPU%d will NOT work", g_sensors[i].name,
|
||||
hotplug_map[j].cpu);
|
||||
j++;
|
||||
}
|
||||
sensor_count--;
|
||||
}
|
||||
poll_count = 0;
|
||||
}
|
||||
|
||||
/* TODO : if hotplug sensor is enabled, ensure that it will still be
|
||||
polled at the HOTPLUG_LOW_THRESHOLD, ie. existing thresholds are not
|
||||
t[0].lvl_clr > LOW_THRESHOLD || t[0].lvl_trig > HIGH_THRESHOLD
|
||||
corner case where polling will stop and our hotplug failsafe won't
|
||||
get executed since we're in interrupt mode */
|
||||
|
||||
// Enable and Setup Threshold for BCL
|
||||
if (save_bcl_i > -1 && save_bcl_i < ARRAY_SIZE(g_sensors)) {
|
||||
bcl_enable(g_sensors[save_bcl_i].setting, 1);
|
||||
bcl_update_thresholds(g_sensors[save_bcl_i].setting, 0, 0);
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void sensors_shutdown()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
|
||||
g_sensors[i].shutdown(g_sensors[i].setting);
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (sensor->id == BCL) {
|
||||
if (value <= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
if (value >= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (sensor->id == BCL) {
|
||||
if (value >= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
if (value <= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
int temp = 0;
|
||||
int i = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL ||
|
||||
setting->sensor->get_temperature == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
temp = setting->sensor->get_temperature(setting);
|
||||
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
|
||||
|
||||
i = 0;
|
||||
while (hotplug_map[i].sensor_name != NULL) {
|
||||
if (setting->id == hotplug_map[i].sensor_idx) {
|
||||
do_hotplug_critical(setting, hotplug_map[i].cpu,
|
||||
(int) RCONV(temp));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static void hybrid_main_interrupt_wait(sensor_setting_t *setting)
|
||||
{
|
||||
int performed_wait = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->desc == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If main sensor in interrupt mode */
|
||||
if (hybrid_state == HYBRID_STATE_MAIN_INTERRUPT) {
|
||||
if (main_sensor_hi_threshold_enabled == 0) {
|
||||
/* wait for auxiliary sensors to finish polling */
|
||||
pthread_mutex_lock(&poll_count_mutex);
|
||||
while (poll_count > 0) {
|
||||
pthread_cond_wait(&finish_poll_condition,
|
||||
&poll_count_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&poll_count_mutex);
|
||||
|
||||
/* disable auxiliary sensors first, then
|
||||
reenable main sensor hi threshold */
|
||||
hybrid_enable_auxiliary_sensors(0);
|
||||
|
||||
tsens_sensor_enable_thresholds(setting, 1, 0);
|
||||
main_sensor_hi_threshold_enabled = 1;
|
||||
}
|
||||
tsens_sensor_interrupt_wait(setting);
|
||||
performed_wait = 1;
|
||||
}
|
||||
|
||||
/* Don't sleep on first poll */
|
||||
if (!performed_wait) {
|
||||
usleep(setting->sampling_period_us);
|
||||
}
|
||||
}
|
||||
|
||||
static void hybrid_aux_interrupt_wait(sensor_setting_t *setting)
|
||||
{
|
||||
int performed_wait = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->desc == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Auxiliary sensors should block on main sensor interrupt */
|
||||
if (hybrid_state != HYBRID_STATE_POLLING) {
|
||||
|
||||
/* check that all auxiliary sensors are ready to wait before
|
||||
completing polling */
|
||||
pthread_mutex_lock(&poll_count_mutex);
|
||||
poll_count--;
|
||||
if (poll_count == 0) {
|
||||
pthread_cond_broadcast(&finish_poll_condition);
|
||||
}
|
||||
pthread_mutex_unlock(&poll_count_mutex);
|
||||
|
||||
/* Wait for sensor threshold condition */
|
||||
pthread_mutex_lock(&hybrid_mutex);
|
||||
while (HYBRID_STATE_POLLING != hybrid_state) {
|
||||
pthread_cond_wait(&hybrid_condition,
|
||||
&hybrid_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&hybrid_mutex);
|
||||
|
||||
pthread_mutex_lock(&poll_count_mutex);
|
||||
poll_count++;
|
||||
pthread_mutex_unlock(&poll_count_mutex);
|
||||
|
||||
performed_wait = 1;
|
||||
}
|
||||
|
||||
/* Don't sleep on first poll */
|
||||
if (!performed_wait) {
|
||||
usleep(setting->sampling_period_us);
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_wait(sensor_setting_t *setting)
|
||||
{
|
||||
static int is_first_poll = 1;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setting->sensor->interrupt_wait) {
|
||||
setting->sensor->interrupt_wait(setting);
|
||||
} else if (!is_first_poll) {
|
||||
usleep(setting->sampling_period_us);
|
||||
} else {
|
||||
is_first_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void hybrid_main_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TSENS thresholds don't need updating for 8960
|
||||
sensor_setup sets threshold 0 */
|
||||
/* Update state for hybrid polling */
|
||||
if (threshold_type == THRESHOLD_CROSS) {
|
||||
threshold_cleared[0] = 0;
|
||||
} else if (threshold_type == THRESHOLD_CLEAR && level == 0) {
|
||||
threshold_cleared[0] = 1;
|
||||
}
|
||||
|
||||
if (hybrid_state == HYBRID_STATE_MAIN_INTERRUPT &&
|
||||
threshold_type == THRESHOLD_NOCHANGE) {
|
||||
/* Rearm threshold if we didn't actually cross hi threshold */
|
||||
tsens_sensor_enable_thresholds(setting, 1, 0);
|
||||
} else if (hybrid_state == HYBRID_STATE_MAIN_INTERRUPT &&
|
||||
threshold_type == THRESHOLD_CROSS) {
|
||||
/* Enable auxiliary hybrid polling on threshold crossing */
|
||||
dbgmsg("Hybrid state -> polling enabled");
|
||||
/* transition to polling expected,
|
||||
disable interrupts, enable aux sensors */
|
||||
tsens_sensor_enable_thresholds(setting, 0, 0);
|
||||
main_sensor_hi_threshold_enabled = 0;
|
||||
hybrid_enable_auxiliary_sensors(1);
|
||||
|
||||
pthread_mutex_lock(&hybrid_mutex);
|
||||
hybrid_state = HYBRID_STATE_POLLING;
|
||||
pthread_cond_broadcast(&hybrid_condition);
|
||||
pthread_mutex_unlock(&hybrid_mutex);
|
||||
} else if (hybrid_state == HYBRID_STATE_POLLING &&
|
||||
all_hybrid_thresholds_cleared()) {
|
||||
/* disable polling on threshold clearing */
|
||||
pthread_mutex_lock(&hybrid_mutex);
|
||||
dbgmsg("Hybrid state -> interrupt");
|
||||
hybrid_state = HYBRID_STATE_MAIN_INTERRUPT;
|
||||
pthread_mutex_unlock(&hybrid_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void hybrid_aux_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
int hybrid_id = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
hybrid_id = hybrid_sensor_id(setting);
|
||||
if (hybrid_id <= 0 || hybrid_id >= NUM_TSENS_SENSORS) {
|
||||
msg("%s: Bad hybrid sensor_id", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update state for hybrid polling */
|
||||
if (threshold_type == THRESHOLD_CROSS) {
|
||||
threshold_cleared[hybrid_id] = 0;
|
||||
} else if (threshold_type == THRESHOLD_CLEAR && level == 0) {
|
||||
threshold_cleared[hybrid_id] = 1;
|
||||
}
|
||||
|
||||
/* disable polling on threshold clearing */
|
||||
if (hybrid_state == HYBRID_STATE_POLLING &&
|
||||
all_hybrid_thresholds_cleared()) {
|
||||
pthread_mutex_lock(&hybrid_mutex);
|
||||
dbgmsg("Hybrid state -> interrupt");
|
||||
hybrid_state = HYBRID_STATE_MAIN_INTERRUPT;
|
||||
pthread_mutex_unlock(&hybrid_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setting->sensor->update_thresholds == NULL)
|
||||
return;
|
||||
|
||||
setting->sensor->update_thresholds(setting, threshold_type, level);
|
||||
}
|
||||
|
||||
static int pa_sensor_setup(sensor_setting_t *settings,
|
||||
sensor_t *sensor)
|
||||
{
|
||||
int fd = -1;
|
||||
int sensor_count = 0;
|
||||
do {
|
||||
/* We have nothing to do if there are no thresholds */
|
||||
if (!settings->num_thresholds) {
|
||||
dbgmsg("No thresholds for sensor %s\n", sensor->name);
|
||||
break;
|
||||
}
|
||||
|
||||
sensor_count = adc_sensors_setup(settings, sensor);
|
||||
if (sensor_count) {
|
||||
info("ADC sensor found for %s\n", sensor->name);
|
||||
sensor->shutdown = adc_sensors_shutdown;
|
||||
sensor->get_temperature = adc_sensor_get_temperature;
|
||||
break;
|
||||
}
|
||||
sensor_count = qmi_ts_setup(settings, sensor);
|
||||
if (sensor_count) {
|
||||
info("QMI TS sensor found for %s\n", sensor->name);
|
||||
sensor->update_thresholds = qmi_ts_update_thresholds;
|
||||
sensor->get_temperature = qmi_ts_get_temperature;
|
||||
sensor->interrupt_wait = qmi_ts_interrupt_wait;
|
||||
sensor->shutdown = qmi_ts_shutdown;
|
||||
sensor->interrupt_enable = 1;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
@@ -1,322 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tsens-sensor.h"
|
||||
#include "bcl-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
char *sensor_names[] =
|
||||
{
|
||||
"tsens_tz_sensor0",
|
||||
"tsens_tz_sensor1",
|
||||
"tsens_tz_sensor2",
|
||||
"tsens_tz_sensor3",
|
||||
"tsens_tz_sensor4",
|
||||
"tsens_tz_sensor5",
|
||||
"tsens_tz_sensor6",
|
||||
"tsens_tz_sensor7",
|
||||
"tsens_tz_sensor8",
|
||||
"tsens_tz_sensor9",
|
||||
"tsens_tz_sensor10",
|
||||
"bcl",
|
||||
};
|
||||
|
||||
static sensor_t g_sensors[] = {
|
||||
{
|
||||
.name = "tsens_tz_sensor0",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor1",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor2",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor3",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor4",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor5",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor6",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor7",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor8",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor9",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor10",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "bcl",
|
||||
.setup = bcl_setup,
|
||||
.shutdown = bcl_shutdown,
|
||||
.get_temperature = bcl_get_diff_imax_ibat,
|
||||
.interrupt_wait = bcl_interrupt_wait,
|
||||
.update_thresholds = bcl_update_thresholds,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
};
|
||||
|
||||
int sensors_setup(thermal_setting_t *settings)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int ret = 0;
|
||||
int sensor_count = 0;
|
||||
|
||||
if (!settings)
|
||||
return sensor_count;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
for (j = 0; j < SENSOR_IDX_MAX; j++) {
|
||||
if (!settings->sensors[j].desc ||
|
||||
strncmp(settings->sensors[j].desc, g_sensors[i].name,
|
||||
SENSOR_NAME_MAX))
|
||||
continue;
|
||||
|
||||
info("Sensor setup:[%s]\n", g_sensors[i].name);
|
||||
g_sensors[i].setting = &settings->sensors[j];
|
||||
settings->sensors[j].sensor = &g_sensors[i];
|
||||
|
||||
ret = g_sensors[i].setup(&settings->sensors[j],
|
||||
(sensor_t *)&g_sensors[i]);
|
||||
sensor_count += ret;
|
||||
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
if (!g_sensors[i].interrupt_enable)
|
||||
break;
|
||||
|
||||
/* TSENS sensor threshold setup */
|
||||
if (strncmp(settings->sensors[j].desc,
|
||||
g_sensors[i].name, strlen("tsens_tz_sensor")) == 0) {
|
||||
tsens_sensor_update_thresholds(g_sensors[i].setting,
|
||||
THRESHOLD_NOCHANGE, 0);
|
||||
}
|
||||
|
||||
/* BCL sensor threshold setup */
|
||||
if (strncmp(settings->sensors[j].desc,
|
||||
g_sensors[i].name, strlen("bcl")) == 0) {
|
||||
bcl_enable(g_sensors[i].setting, 1);
|
||||
bcl_update_thresholds(g_sensors[i].setting, 0, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void sensors_shutdown()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
|
||||
g_sensors[i].shutdown(g_sensors[i].setting);
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (sensor->id == BCL) {
|
||||
if (value <= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
if (value >= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (sensor->id == BCL) {
|
||||
if (value >= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
if (value <= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
int temp = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL ||
|
||||
setting->sensor->get_temperature == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
temp = setting->sensor->get_temperature(setting);
|
||||
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void sensor_wait(sensor_setting_t *setting)
|
||||
{
|
||||
static int is_first_poll = 1;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->sensor->interrupt_enable &&
|
||||
setting->sensor->interrupt_wait) {
|
||||
setting->sensor->interrupt_wait(setting);
|
||||
} else if (!is_first_poll) {
|
||||
usleep(setting->sampling_period_us);
|
||||
} else {
|
||||
is_first_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->sensor->interrupt_enable == 0 ||
|
||||
setting->sensor->update_thresholds == NULL)
|
||||
return;
|
||||
|
||||
setting->sensor->update_thresholds(setting, threshold_type, level);
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/msm_adc.h>
|
||||
#include "thermal.h"
|
||||
#include "sensors-hw.h"
|
||||
#include "oncrpc.h"
|
||||
#include "adc.h"
|
||||
#include "adc_rpc.h"
|
||||
|
||||
#define MSM_ADC_NODE "/dev/msm_adc"
|
||||
#define EXTN_MSM_ONCRPC_CHANNEL (23)
|
||||
#define EXTN_MSM_INVALID_TEMP (-555)
|
||||
#define EXTN_MSM_MAX_TEMP (255)
|
||||
|
||||
char *sensor_names[] =
|
||||
{
|
||||
"PMIC_THERM",
|
||||
"MSM_THERM",
|
||||
};
|
||||
|
||||
static int adc_fd = -1;
|
||||
|
||||
int sensors_setup(thermal_setting_t *settings)
|
||||
{
|
||||
struct msm_adc_lookup lookup;
|
||||
int rc, adc_value;
|
||||
uint32_t convert_value;
|
||||
|
||||
oncrpc_init();
|
||||
oncrpc_task_start();
|
||||
|
||||
/* 8x25 has two thermal mitigation solutions
|
||||
a) pmic thermistor: uses dalrpc.
|
||||
b) external thermistor: uses oncrpc.
|
||||
both solutions are mutually exclusive.
|
||||
Hence check oncrpc availability by issuing
|
||||
adc_null. If the oncrpc is available, then check whether
|
||||
msm thermistor rework is installed or not on the HW?
|
||||
*/
|
||||
if (adc_null()) {
|
||||
dbgmsg("oncrpc is available\n");
|
||||
/* look for msm thermistor rework if oncrpc is available
|
||||
and check whether value is negative or not */
|
||||
convert_value = adc_read(EXTN_MSM_ONCRPC_CHANNEL);
|
||||
if (convert_value > EXTN_MSM_MAX_TEMP) {
|
||||
convert_value |= 0xFFFF0000;
|
||||
}
|
||||
adc_value = convert_value;
|
||||
if (adc_value == EXTN_MSM_INVALID_TEMP) {
|
||||
settings->sensors[MSM_THERM].disabled = 1;
|
||||
dbgmsg("Sensor '%s' is not present\n", sensor_names[MSM_THERM]);
|
||||
oncrpc_task_stop();
|
||||
oncrpc_deinit();
|
||||
}
|
||||
else {
|
||||
dbgmsg("Sensor '%s' is present\n", sensor_names[MSM_THERM]);
|
||||
settings->sensors[MSM_THERM].disabled = 0;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
dbgmsg("oncrpc is not available\n");
|
||||
}
|
||||
|
||||
adc_fd = open(MSM_ADC_NODE, O_RDWR);
|
||||
if (adc_fd < 0) {
|
||||
msg("Error opening %s\n", MSM_ADC_NODE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
strlcpy(lookup.name, sensor_names[PMIC_THERM], MSM_ADC_MAX_CHAN_STR);
|
||||
lookup.name[MSM_ADC_MAX_CHAN_STR-1] = '\0';
|
||||
|
||||
rc = ioctl(adc_fd, MSM_ADC_LOOKUP, &lookup);
|
||||
if (rc < 0) {
|
||||
msg("Error looking up '%s', skipping\n", sensor_names[PMIC_THERM]);
|
||||
settings->sensors[PMIC_THERM].disabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
settings->sensors[PMIC_THERM].chan_idx = lookup.chan_idx;
|
||||
settings->sensors[PMIC_THERM].disabled = 0;
|
||||
|
||||
dbgmsg("Sensor '%s' -> channel '%u'\n",
|
||||
sensor_names[PMIC_THERM], lookup.chan_idx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sensors_shutdown()
|
||||
{
|
||||
if (adc_fd != -1)
|
||||
close(adc_fd);
|
||||
adc_fd = -1;
|
||||
|
||||
}
|
||||
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value >= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value <= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_get_temperature(sensor_setting_t *sensor)
|
||||
{
|
||||
int rc = 0, adc_value;
|
||||
uint32_t convert_value;
|
||||
struct adc_chan_result conv;
|
||||
|
||||
if (sensor->id == MSM_THERM) {
|
||||
convert_value = adc_read(EXTN_MSM_ONCRPC_CHANNEL);
|
||||
if (convert_value > EXTN_MSM_MAX_TEMP) {
|
||||
convert_value |= 0xFFFF0000;
|
||||
}
|
||||
adc_value = convert_value;
|
||||
/* external msm thermistor returns the temparature in degress,
|
||||
but thermal daemon expects the temparature in millie degrees.
|
||||
Hence convert from degress to miiliedegrees.*/
|
||||
dbgmsg("Sensor '%s' - %d*C (%d)\n",sensor->desc, adc_value, CONV(adc_value));
|
||||
return CONV(adc_value);
|
||||
}
|
||||
|
||||
memset(&conv, 0, sizeof(conv));
|
||||
conv.chan = sensor->chan_idx;
|
||||
|
||||
if (adc_fd <= 0) {
|
||||
msg("Error opening sensor '%s'\n", sensor->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ioctl(adc_fd, MSM_ADC_REQUEST, &conv);
|
||||
if (rc) {
|
||||
msg("Error getting sensor info '%s'\n", sensor->desc);
|
||||
} else {
|
||||
dbgmsg("Sensor '%s' - %2.1f*C (%lld)\n",
|
||||
sensor->desc, RCONV(conv.physical), conv.physical);
|
||||
}
|
||||
|
||||
return conv.physical;
|
||||
}
|
||||
|
||||
|
||||
void sensor_wait(sensor_setting_t *setting)
|
||||
{
|
||||
static int is_first_poll = 1;
|
||||
if (setting == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_first_poll) {
|
||||
usleep(setting->sampling_period_us);
|
||||
} else {
|
||||
is_first_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_triggered, int level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2011-2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#ifndef __SENSORS_HW_H__
|
||||
#define __SENSORS_HW_H__
|
||||
|
||||
#define SENSOR_NAME_MAX (20)
|
||||
#define SENSOR(x) (((x >= 0) && (x < SENSOR_IDX_MAX)) ? \
|
||||
sensor_names[x] : "unknown")
|
||||
|
||||
enum sensor_list {
|
||||
#ifdef SENSORS_7630
|
||||
PMIC_THERM,
|
||||
XO_THERM,
|
||||
XO_THERM_GPS,
|
||||
POP_MEM_TZ,
|
||||
#endif /* SENSORS_7630 */
|
||||
|
||||
#ifdef SENSORS_8660
|
||||
PMIC8058_TZ,
|
||||
TSENS_TZ_SENSOR0,
|
||||
#endif /* SENSORS_8660 */
|
||||
|
||||
#ifdef SENSORS_8960
|
||||
PM8921_TZ,
|
||||
PA_THERM0,
|
||||
PA_THERM1,
|
||||
TSENS_TZ_SENSOR0,
|
||||
TSENS_TZ_SENSOR1,
|
||||
TSENS_TZ_SENSOR2,
|
||||
TSENS_TZ_SENSOR3,
|
||||
TSENS_TZ_SENSOR4,
|
||||
TSENS_TZ_SENSOR5,
|
||||
TSENS_TZ_SENSOR6,
|
||||
TSENS_TZ_SENSOR7,
|
||||
TSENS_TZ_SENSOR8,
|
||||
TSENS_TZ_SENSOR9,
|
||||
TSENS_TZ_SENSOR10,
|
||||
BCL,
|
||||
PM8821_TZ,
|
||||
#endif /* SENSORS_8960 */
|
||||
|
||||
#ifdef SENSORS_8974
|
||||
TSENS_TZ_SENSOR0,
|
||||
TSENS_TZ_SENSOR1,
|
||||
TSENS_TZ_SENSOR2,
|
||||
TSENS_TZ_SENSOR3,
|
||||
TSENS_TZ_SENSOR4,
|
||||
TSENS_TZ_SENSOR5,
|
||||
TSENS_TZ_SENSOR6,
|
||||
TSENS_TZ_SENSOR7,
|
||||
TSENS_TZ_SENSOR8,
|
||||
TSENS_TZ_SENSOR9,
|
||||
TSENS_TZ_SENSOR10,
|
||||
BCL,
|
||||
#endif /* SENSORS_8974 */
|
||||
|
||||
#ifdef SENSORS_TEST
|
||||
TEST0,
|
||||
#endif /* SENSORS_TEST */
|
||||
#ifdef SENSORS_8625
|
||||
PMIC_THERM,
|
||||
MSM_THERM,
|
||||
#endif
|
||||
|
||||
#ifdef IPQ_806x
|
||||
TSENS_TZ_SENSOR0,
|
||||
TSENS_TZ_SENSOR1,
|
||||
TSENS_TZ_SENSOR2,
|
||||
TSENS_TZ_SENSOR3,
|
||||
TSENS_TZ_SENSOR4,
|
||||
TSENS_TZ_SENSOR5,
|
||||
TSENS_TZ_SENSOR6,
|
||||
TSENS_TZ_SENSOR7,
|
||||
TSENS_TZ_SENSOR8,
|
||||
TSENS_TZ_SENSOR9,
|
||||
TSENS_TZ_SENSOR10,
|
||||
TSENS_TZ_SENSOR11,
|
||||
TSENS_TZ_SENSOR12,
|
||||
TSENS_TZ_SENSOR13,
|
||||
TSENS_TZ_SENSOR14,
|
||||
TSENS_TZ_SENSOR15,
|
||||
#endif /*IPQ_806x */
|
||||
|
||||
SENSOR_IDX_MAX
|
||||
};
|
||||
|
||||
extern char *sensor_names[]; /* Sensor names are defined in sensors-*.c */
|
||||
|
||||
#endif /* __SENSORS_HW_H__ */
|
||||
|
||||
@@ -1,417 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2014, 2017 Qualcomm Technologies, Inc.
|
||||
All Rights Reserved.
|
||||
Confidential and Proprietary - Qualcomm Technologies, Inc.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tsens-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
char *sensor_names[] =
|
||||
{
|
||||
"tsens_tz_sensor0",
|
||||
"tsens_tz_sensor1",
|
||||
"tsens_tz_sensor2",
|
||||
"tsens_tz_sensor3",
|
||||
"tsens_tz_sensor4",
|
||||
"tsens_tz_sensor5",
|
||||
"tsens_tz_sensor6",
|
||||
"tsens_tz_sensor7",
|
||||
"tsens_tz_sensor8",
|
||||
"tsens_tz_sensor9",
|
||||
"tsens_tz_sensor10",
|
||||
"tsens_tz_sensor11",
|
||||
"tsens_tz_sensor12",
|
||||
"tsens_tz_sensor13",
|
||||
"tsens_tz_sensor14",
|
||||
"tsens_tz_sensor15",
|
||||
};
|
||||
|
||||
static sensor_t g_sensors[] = {
|
||||
{
|
||||
.name = "tsens_tz_sensor0",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor1",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor2",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor3",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor4",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor5",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor6",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor7",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor8",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor9",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor10",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor11",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor12",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor13",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor14",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
{
|
||||
.name = "tsens_tz_sensor15",
|
||||
.setup = tsens_sensors_setup,
|
||||
.shutdown = tsens_sensors_shutdown,
|
||||
.get_temperature = tsens_sensor_get_temperature,
|
||||
.interrupt_wait = tsens_sensor_interrupt_wait,
|
||||
.update_thresholds = tsens_sensor_update_thresholds,
|
||||
.enable_sensor = tsens_sensor_enable_sensor,
|
||||
.setting = NULL,
|
||||
.tzn = 0,
|
||||
.data = NULL,
|
||||
.interrupt_enable = 1,
|
||||
},
|
||||
};
|
||||
|
||||
int sensors_setup(thermal_setting_t *settings)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int ret = 0;
|
||||
int sensor_count = 0;
|
||||
#ifdef IPQ_806x
|
||||
int act_cnt;
|
||||
int thrs_cnt;
|
||||
int valid_act_cnt;
|
||||
int max_thr;
|
||||
#endif
|
||||
if (!settings)
|
||||
return sensor_count;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
for (j = 0; j < SENSOR_IDX_MAX; j++) {
|
||||
#ifdef IPQ_806x
|
||||
/*
|
||||
Some threshold actions are set to "none", so it
|
||||
is therefore required to track only the valid
|
||||
actions to avoid setting up that particular sensor.
|
||||
*/
|
||||
max_thr = settings->sensors[j].num_thresholds;
|
||||
valid_act_cnt = 0;
|
||||
for (thrs_cnt = max_thr - 1; thrs_cnt >= 0; thrs_cnt--) {
|
||||
for( act_cnt = 0 ; act_cnt < settings->sensors[j].t[thrs_cnt].num_actions;act_cnt++ ){
|
||||
if( NONE != settings->sensors[j].t[thrs_cnt].actions[act_cnt].action )
|
||||
valid_act_cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
Do not setup sensors which are not being used.
|
||||
This is required to reduce memory foot print as
|
||||
each sensor requires about 1.5MB - 2 MB for setup.
|
||||
*/
|
||||
if (!settings->sensors[j].desc ||
|
||||
valid_act_cnt == 0 ||
|
||||
settings->sensors[j].num_thresholds < 1 ||
|
||||
strncmp(settings->sensors[j].desc, g_sensors[i].name,
|
||||
SENSOR_NAME_MAX))
|
||||
continue;
|
||||
|
||||
info("Sensor setup:[%s]\n", g_sensors[i].name);
|
||||
g_sensors[i].setting = &settings->sensors[j];
|
||||
settings->sensors[j].sensor = &g_sensors[i];
|
||||
|
||||
ret = g_sensors[i].setup(&settings->sensors[j],
|
||||
(sensor_t *)&g_sensors[i]);
|
||||
sensor_count += ret;
|
||||
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
if (!g_sensors[i].interrupt_enable)
|
||||
break;
|
||||
|
||||
/* TSENS sensor threshold setup */
|
||||
if (strncmp(settings->sensors[j].desc,
|
||||
g_sensors[i].name, strlen("tsens_tz_sensor")) == 0) {
|
||||
tsens_sensor_update_thresholds(g_sensors[i].setting,
|
||||
THRESHOLD_NOCHANGE, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void sensors_shutdown()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
|
||||
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
|
||||
g_sensors[i].shutdown(g_sensors[i].setting);
|
||||
}
|
||||
}
|
||||
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value >= sensor->t[level].lvl_trig)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
|
||||
{
|
||||
if (value <= sensor->t[level].lvl_clr)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
int temp = 0;
|
||||
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL ||
|
||||
setting->sensor->get_temperature == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
temp = setting->sensor->get_temperature(setting);
|
||||
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void sensor_wait(sensor_setting_t *setting)
|
||||
{
|
||||
static int is_first_poll = 1;
|
||||
dbgmsg("Sensor_wait step in.\n");
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->sensor->interrupt_enable &&
|
||||
setting->sensor->interrupt_wait) {
|
||||
setting->sensor->interrupt_wait(setting);
|
||||
} else if (!is_first_poll) {
|
||||
dbgmsg("Sleeping for smapling period of %d us.\n" , setting->sampling_period_us );
|
||||
usleep(setting->sampling_period_us);
|
||||
} else {
|
||||
is_first_poll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
if (setting == NULL ||
|
||||
setting->sensor == NULL) {
|
||||
msg("%s: Unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dbgmsg("Interrupt Enable: %d \n" , setting->sensor->interrupt_enable );
|
||||
|
||||
if (setting->sensor->interrupt_enable == 0 ||
|
||||
setting->sensor->update_thresholds == NULL)
|
||||
{
|
||||
dbgmsg("%s: return. interrupt disabled or updatethreshold is NULL \n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
setting->sensor->update_thresholds(setting, threshold_type, level);
|
||||
}
|
||||
|
||||
void sensor_enable( sensor_setting_t *setting , int tzn , int enabled )
|
||||
{
|
||||
if ( setting && setting->sensor && setting->sensor->enable_sensor) {
|
||||
dbgmsg("%s: sensor setting found for tzn%d\n" , __func__ , tzn );
|
||||
setting->sensor->enable_sensor(tzn , enabled);
|
||||
}
|
||||
else{
|
||||
dbgmsg("%s: sensor setting not found for tzn%d. Using defaults...\n" , __func__ , tzn );
|
||||
tsens_sensor_enable_sensor(tzn , enabled);
|
||||
}
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2010-2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
#ifndef IPQ_806x
|
||||
#include "thermal_server.h"
|
||||
#endif
|
||||
|
||||
|
||||
thermal_setting_t thermal_settings;
|
||||
int num_cpus = 0;
|
||||
int num_gpus = 0;
|
||||
int exit_daemon = 0;
|
||||
int debug_output = 0;
|
||||
int enable_restore_brightness = 1;
|
||||
int minimum_mode = 0;
|
||||
int new_corelimit = 0;
|
||||
int dump_bcl_ibat_imax = 0;
|
||||
char *dump_bcl_ibat_imax_file = NULL;
|
||||
|
||||
static char *config_file = NULL;
|
||||
|
||||
void set_mitigation_level();
|
||||
|
||||
#ifdef IPQ_806x
|
||||
void terminate_signal (int sig)
|
||||
{
|
||||
|
||||
/* Do all uninitialization here */
|
||||
|
||||
/* Enabling NSS Auto scaling */
|
||||
nssfreq_request( -1 );
|
||||
|
||||
/* Resetting the powerctl */
|
||||
powerctl_restart(1);
|
||||
|
||||
/* Proceed with the termination */
|
||||
exit(sig);
|
||||
}
|
||||
#endif
|
||||
|
||||
void print_help(void)
|
||||
{
|
||||
printf("\nTemperature sensor daemon\n");
|
||||
printf("Optional arguments:\n");
|
||||
printf(" --config-file/-c <file> config file\n");
|
||||
printf(" --debug/-d debug output\n");
|
||||
#ifndef IPQ_806x
|
||||
printf(" --norestorebrightness/-r disable restore brightness functionality\n");
|
||||
printf(" --overridecorelimit/-o <degC> override core limit temperature (test only)\n");
|
||||
printf(" --dump-bcl/-i BCL ibat/imax file\n");
|
||||
#endif
|
||||
printf(" --help/-h this help screen\n");
|
||||
}
|
||||
|
||||
int parse_commandline(int argc, char *const argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"debug", 0, 0, 'd'},
|
||||
#ifndef IPQ_806x
|
||||
{"norestorebrightness", 0, 0, 'r'},
|
||||
{"overridecorelimit", 1, 0, 'o'},
|
||||
{"dump-bcl", 2, 0, 'i'},
|
||||
#endif
|
||||
{"help", 0, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, "c:i::dro:h", long_options, NULL)) != EOF) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
info("Using config file '%s'\n", optarg);
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
info("Debug output enabled\n");
|
||||
debug_output = 1;
|
||||
break;
|
||||
|
||||
#ifndef IPQ_806x
|
||||
case 'i':
|
||||
info("dump BCL ibat/imax to a file\n");
|
||||
dump_bcl_ibat_imax = 1;
|
||||
dump_bcl_ibat_imax_file = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
info("Restore brightness feature disabled\n");
|
||||
enable_restore_brightness = 0;
|
||||
break;
|
||||
case 'o':
|
||||
new_corelimit = atoi(optarg);
|
||||
/* sanity check */
|
||||
if (new_corelimit == 0) {
|
||||
printf("Invalid argument %s for core limit, value should be an "
|
||||
"integral value in degC\n", optarg);
|
||||
return 0;
|
||||
}
|
||||
else if (new_corelimit < CORELIMIT_MIN ||
|
||||
new_corelimit > CORELIMIT_MAX) {
|
||||
printf("Core limit %d out of sanity check range, "
|
||||
"should be between %d and %ddegC\n",
|
||||
new_corelimit, CORELIMIT_MIN, CORELIMIT_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
info("Core limit override to %d\n", new_corelimit);
|
||||
break;
|
||||
#endif
|
||||
case 'h':
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Too many/unrecognized argument(s) */
|
||||
if (optind < argc) {
|
||||
msg("Too many arguments\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef IPQ_806x
|
||||
if (signal (SIGTERM, terminate_signal) == SIG_IGN)
|
||||
signal (SIGTERM, SIG_IGN);
|
||||
#endif
|
||||
|
||||
info("Thermal daemon started\n");
|
||||
|
||||
setpriority(PRIO_PROCESS, getpid(), -20);
|
||||
|
||||
if (!parse_commandline(argc, argv)) {
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_settings(&thermal_settings);
|
||||
|
||||
if (!load_config(&thermal_settings, config_file)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
{
|
||||
char buf[PROPERTY_VALUE_MAX];
|
||||
/* Early stage of encrypted data partition;
|
||||
* run without modem mitigation and framework socket
|
||||
*/
|
||||
if ((property_get("vold.decrypt", buf, "0") > 0)
|
||||
&& (buf[0] == '1')) {
|
||||
minimum_mode = 1;
|
||||
info("Running in minimum mode\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
set_mitigation_level();
|
||||
cpufreq_init();
|
||||
|
||||
#ifndef IPQ_806x
|
||||
gpufreq_init();
|
||||
|
||||
if (!minimum_mode) {
|
||||
modem_communication_init();
|
||||
modem_ts_qmi_init();
|
||||
}
|
||||
|
||||
/* Initialize and setup a socket server for external
|
||||
userspace apps interested in thermal mitigation. */
|
||||
thermal_server_init();
|
||||
|
||||
#endif
|
||||
/* Disable kernel thermal module and take over */
|
||||
write_to_file("/sys/module/msm_thermal/parameters/enabled", "N" , strlen("N") + 1);
|
||||
thermal_monitor(&thermal_settings);
|
||||
|
||||
#ifndef IPQ_806x
|
||||
if (!minimum_mode) {
|
||||
modem_communication_release();
|
||||
modem_qmi_ts_comm_release();
|
||||
}
|
||||
|
||||
thermal_server_release();
|
||||
#endif
|
||||
terminate_signal(0);
|
||||
info("Thermal daemon exited\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,391 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2010-2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#ifndef __THERMAL_H__
|
||||
#define __THERMAL_H__
|
||||
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "sensors-hw.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
# include "cutils/properties.h"
|
||||
# ifdef USE_ANDROID_LOG
|
||||
# define LOG_TAG "ThermalDaemon"
|
||||
# include "cutils/log.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef IPQ_806x
|
||||
#include "common_log.h" /* define after cutils/log.h */
|
||||
#endif
|
||||
|
||||
#ifdef USE_GLIB
|
||||
#include <glib/gprintf.h>
|
||||
#define strlcat g_strlcat
|
||||
#define strlcpy g_strlcpy
|
||||
#endif /* USE_GLIB */
|
||||
|
||||
#ifndef FD_SETSIZE
|
||||
#define FD_SETSIZE 1024
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_FILE_DEFAULT
|
||||
#define CONFIG_FILE_DEFAULT "/system/etc/thermald.conf"
|
||||
#endif
|
||||
|
||||
#define MAX_CPUS (4) /* Supporting up to 4 core systems */
|
||||
|
||||
/* Abstract local socket name that report actions are sent on */
|
||||
#define UI_LOCALSOCKET_NAME "THERMALD_UI"
|
||||
|
||||
#define SAMPLING_MS_DEFAULT (5000)
|
||||
#ifdef SENSORS_8960
|
||||
#define SAMPLING_MS_MINIMUM (100)
|
||||
#else
|
||||
#define SAMPLING_MS_MINIMUM (250)
|
||||
#endif
|
||||
#define THRESHOLDS_MAX (8)
|
||||
#define ACTIONS_MAX (8)
|
||||
#define MAX_PATH (256)
|
||||
#define REPORT_MSG_MAX (60)
|
||||
#define UINT_BUF_MAX (12)
|
||||
|
||||
/* core limit temperature sanity check values in degC */
|
||||
#define CORELIMIT_MIN (50)
|
||||
#define CORELIMIT_MAX (150)
|
||||
|
||||
/* Common thermal sysfs defines */
|
||||
#define TZ_NODE "/sys/class/thermal/thermal_zone%d"
|
||||
#define TZ_MODE "/sys/devices/virtual/thermal/thermal_zone%d/mode"
|
||||
#define TZ_TEMP "/sys/devices/virtual/thermal/thermal_zone%d/temp"
|
||||
#define TZ_TYPE "/sys/devices/virtual/thermal/thermal_zone%d/type"
|
||||
|
||||
/* CPU Frequency Scaling Action */
|
||||
#define GOVERNOR_NODE "/cpufreq/scaling_governor"
|
||||
#define FMAX_INFO_NODE "/cpufreq/cpuinfo_max_freq"
|
||||
#define FMIN_INFO_NODE "/cpufreq/cpuinfo_min_freq"
|
||||
#define FREQ_MAX_NODE "/cpufreq/scaling_max_freq"
|
||||
#define FREQ_MIN_NODE "/cpufreq/scaling_min_freq"
|
||||
#define FREQ_USR_NODE "/cpufreq/scaling_setspeed"
|
||||
#define FREQ_RPT_NODE "/cpufreq/scaling_cur_freq"
|
||||
#define HOTPLUG_NODE "/online"
|
||||
#define CPU_SYSFS_DIR "/sys/devices/system/cpu"
|
||||
#define CPU_SYSFS(NODE) (CPU_SYSFS_DIR "/cpu%d" NODE)
|
||||
|
||||
/*NSS Frequency Scaling Actions */
|
||||
#define NSS_FREQ_MAX_NODE "/proc/sys/dev/nss/clock/freq_table"
|
||||
#define NSS_FREQ_AUTO_SCALE "/proc/sys/dev/nss/clock/auto_scale"
|
||||
#define NSS_CURR_FREQ "/proc/sys/dev/nss/clock/current_freq"
|
||||
|
||||
/* Fabric Frequency Scaling Actions */
|
||||
#define AFAB_CLK "/sys/kernel/debug/clk/afab_a_clk/rate"
|
||||
#define DFAB_CLK "/sys/kernel/debug/clk/dfab_a_clk/rate"
|
||||
#define SFPB_CLK "/sys/kernel/debug/clk/sfpb_a_clk/rate"
|
||||
#define CFPB_CLK "/sys/kernel/debug/clk/cfpb_a_clk/rate"
|
||||
#define NSSFAB0_CLK "/sys/kernel/debug/clk/nssfab0_a_clk/rate"
|
||||
#define NSSFAB1_CLK "/sys/kernel/debug/clk/nssfab1_a_clk/rate"
|
||||
#define EBI1_CLK "/sys/kernel/debug/clk/ebi1_a_clk/rate"
|
||||
|
||||
/* Power Control Script */
|
||||
#define POWER_CTL_PATH "/etc/init.d/powerctl"
|
||||
|
||||
/* GPU Frequency Scaling Action */
|
||||
#define GPU_FREQ_MAX_NODE "/max_gpuclk"
|
||||
#define GPU_FREQ_RPT_NODE "/gpuclk"
|
||||
#define GPU_SYSFS_DIR "/sys/class/kgsl"
|
||||
#define GPU_SYSFS(NODE) (GPU_SYSFS_DIR "/kgsl-3d%d" NODE)
|
||||
|
||||
enum therm_msm_id {
|
||||
THERM_MSM_UNKNOWN = 0,
|
||||
THERM_MSM_8X60,
|
||||
THERM_MSM_8960,
|
||||
THERM_MSM_8960AB,
|
||||
THERM_MSM_8930,
|
||||
THERM_MSM_8930AA,
|
||||
THERM_MSM_8930AB,
|
||||
THERM_MSM_8064,
|
||||
THERM_MSM_8064AB,
|
||||
THERM_MSM_8X25,
|
||||
THERM_MSM_8974,
|
||||
THERM_IPQ_8062,
|
||||
THERM_IPQ_8064,
|
||||
THERM_IPQ_8066,
|
||||
THERM_IPQ_8068,
|
||||
THERM_IPQ_8065,
|
||||
THERM_IPQ_8069,
|
||||
THERM_IPQ_8070,
|
||||
THERM_IPQ_8070A,
|
||||
THERM_IPQ_8071,
|
||||
THERM_IPQ_8071A,
|
||||
THERM_IPQ_8072,
|
||||
THERM_IPQ_8072A,
|
||||
THERM_IPQ_8074,
|
||||
THERM_IPQ_8074A,
|
||||
THERM_IPQ_8076,
|
||||
THERM_IPQ_8076A,
|
||||
THERM_IPQ_8078,
|
||||
THERM_IPQ_8078A,
|
||||
THERM_IPQ_8172,
|
||||
THERM_IPQ_8173,
|
||||
THERM_IPQ_8174,
|
||||
THERM_IPQ_6018,
|
||||
THERM_IPQ_6028,
|
||||
THERM_IPQ_6000,
|
||||
THERM_IPQ_6010
|
||||
};
|
||||
|
||||
enum therm_msm_id therm_get_msm_id(void);
|
||||
|
||||
/* Utility macros */
|
||||
#define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0]))
|
||||
|
||||
/* Convert from Celcius to hardware unit (2^-10 *C); and back */
|
||||
#define CONV(x) (int)((double)x / pow(2.0, -10))
|
||||
#define RCONV(x) ((double)x * pow(2.0, -10))
|
||||
|
||||
|
||||
enum {
|
||||
NONE,
|
||||
CPU_FREQ,
|
||||
SHUTDOWN,
|
||||
#ifdef IPQ_806x
|
||||
POWERSAVE,
|
||||
NSS_FREQ,
|
||||
#else
|
||||
REPORT,
|
||||
LCD,
|
||||
MODEM,
|
||||
FUSION,
|
||||
BATTERY,
|
||||
GPU_FREQ,
|
||||
WLAN,
|
||||
CAMERA,
|
||||
CAMCORDER,
|
||||
#endif
|
||||
ACTION_IDX_MAX
|
||||
} action_type;
|
||||
|
||||
enum {
|
||||
THRESHOLD_CLEAR = -1,
|
||||
THRESHOLD_NOCHANGE = 0,
|
||||
THRESHOLD_CROSS = 1
|
||||
} threshold_trigger;
|
||||
|
||||
|
||||
typedef struct _action_t {
|
||||
int action;
|
||||
int info;
|
||||
} action_t;
|
||||
|
||||
typedef struct _threshold_t {
|
||||
int lvl_trig;
|
||||
int lvl_clr;
|
||||
action_t actions[ACTIONS_MAX];
|
||||
int num_actions;
|
||||
} threshold_t;
|
||||
|
||||
struct _sensor_t;
|
||||
|
||||
typedef struct _sensor_setting_t {
|
||||
char *desc;
|
||||
int id;
|
||||
unsigned int chan_idx;
|
||||
int disabled;
|
||||
pthread_t monitor;
|
||||
int sampling_period_us;
|
||||
int num_thresholds;
|
||||
threshold_t t[THRESHOLDS_MAX];
|
||||
int last_lvl;
|
||||
struct _sensor_t *sensor;
|
||||
unsigned int action_mask;
|
||||
int hotplug_lvl_trig;
|
||||
int hotplug_lvl_clr;
|
||||
|
||||
/* internal counters used during config parsing */
|
||||
int _n_thresholds;
|
||||
int _n_to_clear;
|
||||
int _n_actions;
|
||||
int _n_action_info;
|
||||
} sensor_setting_t;
|
||||
|
||||
/* Common sensor struct */
|
||||
typedef struct _sensor_t {
|
||||
/* sensor name */
|
||||
char *name;
|
||||
/* setup function needs to be called before get_temperature */
|
||||
int (*setup)(sensor_setting_t *settings, struct _sensor_t* sensor);
|
||||
/* shutdown function for resource cleanup */
|
||||
void (*shutdown)(sensor_setting_t *settings);
|
||||
/* get_temperature function to query sensor reading */
|
||||
int (*get_temperature)(sensor_setting_t *setting);
|
||||
/* wait on threshold interrupt */
|
||||
void (*interrupt_wait)(sensor_setting_t *setting);
|
||||
/* update sensor thresholds */
|
||||
void (*update_thresholds)(sensor_setting_t *setting,
|
||||
int threshold_raised,
|
||||
int threshold_level);
|
||||
/* enable/disable sensor */
|
||||
void (*enable_sensor)(int tzn, int enabled);
|
||||
/* associated sensor settings */
|
||||
sensor_setting_t *setting;
|
||||
/* sysfs thermal zone number */
|
||||
int tzn;
|
||||
/* misc data */
|
||||
void *data;
|
||||
/* enable interrupt */
|
||||
int interrupt_enable;
|
||||
} sensor_t;
|
||||
|
||||
typedef struct _thermal_setting_t {
|
||||
int sample_period_ms;
|
||||
int soc_id;
|
||||
int disable_unused_tsens;
|
||||
sensor_setting_t sensors[SENSOR_IDX_MAX];
|
||||
} thermal_setting_t;
|
||||
|
||||
typedef struct _def_sensor_setting_t {
|
||||
int sensor_count;
|
||||
sensor_setting_t *sensors;
|
||||
}def_sensor_setting_t;
|
||||
|
||||
typedef struct {
|
||||
char *sensor_name;
|
||||
int cpu;
|
||||
int sensor_idx;
|
||||
} hotplug_map_t;
|
||||
|
||||
#ifdef USE_ANDROID_LOG
|
||||
#define msg(format, ...) LOGE(format, ## __VA_ARGS__)
|
||||
#define info(format, ...) LOGI(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define msg(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#define info(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define dbgmsg(format, ...) \
|
||||
do { \
|
||||
if (debug_output) \
|
||||
info(format, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
extern int exit_daemon;
|
||||
extern int debug_output;
|
||||
extern int enable_restore_brightness;
|
||||
extern int num_cpus;
|
||||
extern int num_gpus;
|
||||
extern int minimum_mode;
|
||||
extern int new_corelimit;
|
||||
extern int dump_bcl_ibat_imax;
|
||||
extern char *dump_bcl_ibat_imax_file;
|
||||
|
||||
void init_settings(thermal_setting_t *settings);
|
||||
int load_config(thermal_setting_t *settings, const char *pFName);
|
||||
|
||||
int read_line_from_file(char *path, char *buf, size_t count);
|
||||
int write_to_file(char *path, char *buf, size_t count);
|
||||
int write_to_local_file_socket(char * socket_name, char *msg, size_t count);
|
||||
int write_to_local_socket(char * socket_name, char *msg, size_t count);
|
||||
int get_tzn(char *sensor_name);
|
||||
int send_to_clients(char *buf);
|
||||
|
||||
void thermal_monitor(thermal_setting_t *settings);
|
||||
|
||||
int cpufreq_init(void);
|
||||
void cpufreq_restore(void);
|
||||
#ifndef IPQ_806x
|
||||
int gpufreq_init(void);
|
||||
int thermald_client_socket_init(void);
|
||||
void thermald_client_socket_release(void);
|
||||
#endif
|
||||
|
||||
int shutdown_action(int requester, int temperature, int delay);
|
||||
int cpufreq_request(int cpu, int requester, int temperature, int frequency);
|
||||
#ifdef IPQ_806x
|
||||
int powersave_request( int enable );
|
||||
int nssfreq_request( int frequency );
|
||||
int powerctl_restart(int reset_max);
|
||||
#else
|
||||
int report_action(int requester, int temperature, int level, int is_trigger);
|
||||
int lcd_brightness_request(int requester, int temperature, int value);
|
||||
int battery_request(int requester, int temperature, int level);
|
||||
int gpufreq_request(int gpu, int requester, int temperature, int level);
|
||||
int wlan_request(int requester, int temperature, int level);
|
||||
int camera_request(int requester, int temperature, int level);
|
||||
int camcorder_request(int requester, int temperature, int level);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef IPQ_806x
|
||||
|
||||
#ifdef ENABLE_MODEM_MITIGATION
|
||||
int modem_communication_init(void);
|
||||
int modem_communication_release(void);
|
||||
int modem_request(int requester, int temperature, int level);
|
||||
int fusion_modem_request(int requester, int temperature, int level);
|
||||
#else
|
||||
static inline int modem_communication_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int modem_communication_release(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int modem_request(int requester, int temperature, int level)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int fusion_modem_request(int requester, int temperature, int level)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MODEM_TS
|
||||
int modem_ts_qmi_init(void);
|
||||
int modem_qmi_ts_comm_release(void);
|
||||
int modem_ts_temp_request(const char *sensor_id, int send_current_temp_report,
|
||||
int high_valid, int high_thresh, int low_valid,
|
||||
int low_thresh);
|
||||
#else
|
||||
static int modem_ts_qmi_init(void)
|
||||
{
|
||||
return -(EPERM);
|
||||
}
|
||||
static int modem_qmi_ts_comm_release(void)
|
||||
{
|
||||
return -(EPERM);
|
||||
}
|
||||
|
||||
static int modem_ts_temp_request(const char *sensor_id,
|
||||
int send_current_temp_report,
|
||||
int high_valid, int high_thresh,
|
||||
int low_valid,
|
||||
int low_thresh)
|
||||
{
|
||||
return -(EPERM);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
int sensors_setup(thermal_setting_t *setting);
|
||||
void sensors_shutdown(void);
|
||||
int sensor_get_temperature(sensor_setting_t *sensor);
|
||||
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level);
|
||||
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level);
|
||||
void sensor_wait(sensor_setting_t *sensor);
|
||||
void sensor_update_thresholds(sensor_setting_t *sensor, int threshold_type, int level);
|
||||
#ifdef IPQ_806x
|
||||
void sensor_enable( sensor_setting_t *setting, int tzn ,int enabled );
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __THERMAL_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,357 +0,0 @@
|
||||
/*========================================================================================
|
||||
|
||||
thermal_client.c
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
Thermal client library for external userspace apps interested in thermal mitigation.
|
||||
|
||||
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
==========================================================================================*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/un.h>
|
||||
|
||||
#include "thermal_lib_common.h"
|
||||
#include "thermal_client.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
# include "cutils/properties.h"
|
||||
# ifdef USE_ANDROID_LOG
|
||||
# define LOG_TAG "Thermal-Lib"
|
||||
# include "cutils/log.h"
|
||||
# endif
|
||||
#endif
|
||||
#include "common_log.h" /* define after cutils/log.h */
|
||||
|
||||
#ifdef USE_ANDROID_LOG
|
||||
#define msg(format, ...) LOGE(format, ## __VA_ARGS__)
|
||||
#define info(format, ...) LOGI(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define msg(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#define info(format, ...) printf(format, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/* Utility macros */
|
||||
#define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0]))
|
||||
|
||||
static int sockfd_client_send = -1;
|
||||
static int sockfd_client_recv = -1;
|
||||
static pthread_t thermal_client_recv_thread;
|
||||
static int thermal_client_shutdown = 0;
|
||||
static int first_client = 1;
|
||||
static struct thermal_msg_data client_msg;
|
||||
struct thermal_cdata *list_head = NULL;
|
||||
|
||||
/* Supported Thermal clients */
|
||||
static char *req_client_names[] =
|
||||
{
|
||||
"spkr",
|
||||
"override",
|
||||
};
|
||||
static char *notify_client_names[] =
|
||||
{
|
||||
"camera",
|
||||
"camcorder",
|
||||
"spkr",
|
||||
};
|
||||
|
||||
/*================================================================================================
|
||||
FUNCTION do_request_to_thermal
|
||||
|
||||
Thermal client request sending thread.
|
||||
This function will run in a separate thread. This thread is intented to
|
||||
unblock parent client if connect() fails.
|
||||
|
||||
ARGUMENTS
|
||||
data - data pointer which points to message to be sent
|
||||
|
||||
RETURN VALUE
|
||||
void * - not used.
|
||||
=================================================================================================*/
|
||||
static void *do_request_to_thermal(void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
struct sockaddr_un client_addr_send;
|
||||
|
||||
while(1) {
|
||||
sockfd_client_send = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sockfd_client_send < 0) {
|
||||
msg("Thermal-Lib-Client: %s: failed setup "
|
||||
"client send sockfd", __func__);
|
||||
sleep(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&client_addr_send, 0, sizeof(struct sockaddr_un));
|
||||
snprintf(client_addr_send.sun_path, UNIX_PATH_MAX, THERMAL_RECV_CLIENT_SOCKET);
|
||||
client_addr_send.sun_family = AF_LOCAL;
|
||||
rc = connect(sockfd_client_send, (struct sockaddr *)&client_addr_send,
|
||||
sizeof(sa_family_t) + strlen(THERMAL_RECV_CLIENT_SOCKET));
|
||||
if (rc != 0) {
|
||||
close(sockfd_client_send);
|
||||
sleep(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = send(sockfd_client_send, &client_msg, sizeof(struct thermal_msg_data), 0);
|
||||
if (rc <= 0) {
|
||||
msg("Thermal-Lib-Client: "
|
||||
"Unable to send request data to fd %d", sockfd_client_send);
|
||||
break;
|
||||
}
|
||||
info("Thermal-Lib-Client: Client request sent");
|
||||
break;
|
||||
}
|
||||
close(sockfd_client_send);
|
||||
return NULL;
|
||||
}
|
||||
/*================================================================================================
|
||||
FUNCTION thermal_client_request
|
||||
|
||||
Thermal client request to thermal function.
|
||||
The client which will send/notify request to thermal.
|
||||
|
||||
ARGUMENTS
|
||||
client_name - client name
|
||||
req_data - requested data to be sent
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, negative on failure.
|
||||
=================================================================================================*/
|
||||
int thermal_client_request(char *client_name, int req_data)
|
||||
{
|
||||
int rc = 0;
|
||||
int ret = -EINVAL;
|
||||
int i;
|
||||
pthread_t thermal_client_request_thread;
|
||||
|
||||
if (NULL == client_name) {
|
||||
msg("Thermal-Lib-Client:%s: unexpected NULL", __func__);
|
||||
return ret;
|
||||
}
|
||||
/* Check for client is supported or not*/
|
||||
for (i = 0; i < ARRAY_SIZE(req_client_names); i++) {
|
||||
if (0 == strncmp(req_client_names[i], client_name, CLIENT_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(req_client_names)) {
|
||||
msg("Thermal-Lib-Client:%s is not in supported "
|
||||
"thermal client list", client_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&client_msg, 0, sizeof(struct thermal_msg_data));
|
||||
strlcpy(client_msg.client_name, client_name, CLIENT_NAME_MAX);
|
||||
client_msg.req_data = req_data;
|
||||
|
||||
rc = pthread_create(&thermal_client_request_thread, NULL, do_request_to_thermal, NULL);
|
||||
if (rc != 0) {
|
||||
msg("Thermal-Lib-Client: Unable to create pthread to "
|
||||
"send client request from %s", client_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*============================================================================================
|
||||
FUNCTION do_listen
|
||||
|
||||
Function to listen thermal socket.
|
||||
This function will run in a separate thread.
|
||||
|
||||
ARGUMENTS
|
||||
data - data pointer.
|
||||
|
||||
RETURN VALUE
|
||||
void * - not used.
|
||||
=============================================================================================*/
|
||||
static void *do_listen(void *data)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
int count;
|
||||
int (*callback)(int, void *, void *);
|
||||
struct thermal_cdata *callback_node;
|
||||
static struct sockaddr_un client_addr;
|
||||
struct thermal_msg_data thermal_msg;
|
||||
|
||||
while (thermal_client_shutdown != 1) {
|
||||
|
||||
sockfd_client_recv = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sockfd_client_recv < 0) {
|
||||
sleep(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&client_addr, 0, sizeof(struct sockaddr_un));
|
||||
snprintf(client_addr.sun_path, UNIX_PATH_MAX, THERMAL_SEND_CLIENT_SOCKET);
|
||||
client_addr.sun_family = AF_LOCAL;
|
||||
|
||||
rc = connect(sockfd_client_recv, (struct sockaddr *)&client_addr,
|
||||
sizeof(sa_family_t) + strlen(THERMAL_SEND_CLIENT_SOCKET));
|
||||
if (rc != 0) {
|
||||
close(sockfd_client_recv);
|
||||
sleep(5);
|
||||
continue;
|
||||
}
|
||||
while (thermal_client_shutdown != 1) {
|
||||
memset(&thermal_msg, 0, sizeof(struct thermal_msg_data));
|
||||
rc = recv(sockfd_client_recv, &thermal_msg, sizeof(struct thermal_msg_data), 0);
|
||||
if (rc <= 0) {
|
||||
msg("Thermal-Lib-Client:%s: recv failed", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc != sizeof(struct thermal_msg_data))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < CLIENT_NAME_MAX; i++) {
|
||||
if (thermal_msg.client_name[i] == '\0')
|
||||
break;
|
||||
}
|
||||
if (i >= CLIENT_NAME_MAX)
|
||||
thermal_msg.client_name[CLIENT_NAME_MAX - 1] = '\0';
|
||||
|
||||
info("Thermal-Lib-Client: Client received msg %s %d",
|
||||
thermal_msg.client_name, thermal_msg.req_data);
|
||||
|
||||
/* Check for client is supported or not*/
|
||||
for (i = 0; i < ARRAY_SIZE(notify_client_names); i++) {
|
||||
if (0 == strncmp(notify_client_names[i], thermal_msg.client_name, CLIENT_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(notify_client_names)) {
|
||||
msg("Thermal-Lib-Client:%s is not in supported "
|
||||
"thermal client list", thermal_msg.client_name);
|
||||
continue;
|
||||
} else if (thermal_msg.req_data < 0 || thermal_msg.req_data > LEVEL_MAX) {
|
||||
msg("Thermal-Lib-Client:%s: invalid level %d "
|
||||
"unexpected", __func__, thermal_msg.req_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
callback_node = list_head;
|
||||
count = 0;
|
||||
for (; callback_node != NULL; callback_node = callback_node->next) {
|
||||
|
||||
callback_node = get_callback_node_from_list(callback_node, thermal_msg.client_name);
|
||||
if (callback_node) {
|
||||
count++;
|
||||
callback = callback_node->callback;
|
||||
if (callback)
|
||||
callback(thermal_msg.req_data, callback_node->user_data,
|
||||
callback_node->data_reserved);
|
||||
} else {
|
||||
if (count == 0)
|
||||
msg("Thermal-Lib-Client: No clients are "
|
||||
"connected for %s", thermal_msg.client_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(sockfd_client_recv);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*================================================================================================
|
||||
FUNCTION thermal_client_register_callback
|
||||
|
||||
Thermal client registration function.
|
||||
The client is registered with name and a callback funcion and keep on connecting
|
||||
thermal local socket.Based on client name in the message from socket,corresponding
|
||||
callback will be called.
|
||||
|
||||
ARGUMENTS
|
||||
client_name - client name
|
||||
callback - callback function pointer with level, user_data pointer and
|
||||
reserved data as arguments
|
||||
data - user data
|
||||
|
||||
RETURN VALUE
|
||||
valid non zero client_cb_handle on success, zero on failure.
|
||||
=================================================================================================*/
|
||||
int thermal_client_register_callback(char *client_name, int (*callback)(int, void *, void *), void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
int ret = 0;
|
||||
int i;
|
||||
int client_cb_handle;
|
||||
|
||||
if (NULL == client_name ||
|
||||
NULL == callback) {
|
||||
msg("Thermal-Lib-Client:%s: unexpected NULL client registraion "
|
||||
"failed ", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check for client is supported or not*/
|
||||
for (i = 0; i < ARRAY_SIZE(notify_client_names); i++) {
|
||||
if (0 == strncmp(notify_client_names[i], client_name, CLIENT_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(notify_client_names)) {
|
||||
msg("Thermal-Lib-Client:%s is not in supported thermal client list", client_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
client_cb_handle = add_to_list(client_name, callback, data);
|
||||
if (client_cb_handle == 0) {
|
||||
msg("Thermal-Lib-Client: %s: Client Registration failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (first_client == 1) {
|
||||
first_client = 0;
|
||||
rc = pthread_create(&thermal_client_recv_thread, NULL, do_listen, NULL);
|
||||
if (rc != 0) {
|
||||
msg("Thermal-Lib-Client: Unable to create pthread to "
|
||||
"listen thermal events for %s", client_name);
|
||||
remove_from_list(client_cb_handle);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
info("Thermal-Lib-Client: Registraion successfully "
|
||||
"finished for %s", client_name);
|
||||
ret = client_cb_handle;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION thermal_client_unregister_callback
|
||||
|
||||
Function to unregister client req_handler.
|
||||
|
||||
ARGUMENTS
|
||||
client_cb_handle - client handle which retured on
|
||||
succesful registeration
|
||||
|
||||
RETURN VALUE
|
||||
void - return nothing.
|
||||
===========================================================================*/
|
||||
void thermal_client_unregister_callback(int client_cb_handle)
|
||||
{
|
||||
if (remove_from_list(client_cb_handle) < 0)
|
||||
msg("Thermal-Lib-Client: thermal client unregister callback error");
|
||||
|
||||
if (list_head == NULL) {
|
||||
if (thermal_client_shutdown != 1) {
|
||||
thermal_client_shutdown = 1;
|
||||
pthread_join(thermal_client_recv_thread, NULL);
|
||||
close(sockfd_client_recv);
|
||||
sockfd_client_recv = -1;
|
||||
first_client = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#ifndef __THERMAL_CLIENT_H__
|
||||
#define __THERMAL_CLIENT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int thermal_client_register_callback(char *client_name, int (*callback)(int , void *, void *), void *data);
|
||||
int thermal_client_request(char *client_name, int req_data);
|
||||
void thermal_client_unregister_callback(int client_cb_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __THERMAL_CLIENT_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,146 +0,0 @@
|
||||
/*========================================================================================
|
||||
|
||||
thermal_lib_common.c
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
Common utility functions for thermald and thermal client lib.
|
||||
|
||||
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
==========================================================================================*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "thermal_lib_common.h"
|
||||
|
||||
extern struct thermal_cdata *list_head;
|
||||
static uint32_t client_cb_handle = 0;
|
||||
|
||||
#define CLIENT_HANDLE_COND(x) (client_cb_handle & (1 << (x)))
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION get_callback_node_from_list
|
||||
|
||||
Function to get callback node from thermal client list.
|
||||
|
||||
ARGUMENTS
|
||||
list - Node of list from which loop start to iterate
|
||||
name - client name
|
||||
|
||||
RETURN VALUE
|
||||
return valid thermal_cdata node if find a callback,
|
||||
otherwise return NULL.
|
||||
===========================================================================*/
|
||||
struct thermal_cdata *get_callback_node_from_list(struct thermal_cdata *list, char *name)
|
||||
{
|
||||
for (; list != NULL; list = list->next) {
|
||||
if (0 != strncmp(list->client_name, name, CLIENT_NAME_MAX))
|
||||
continue;
|
||||
else
|
||||
return list;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION remove_from_list
|
||||
|
||||
Function to remove unregistered client and its data from thermal
|
||||
client list based on client_cb_handle.
|
||||
|
||||
ARGUMENTS
|
||||
handle - client_cb_handle,node of this to be removed
|
||||
|
||||
RETURN VALUE
|
||||
return 0 on success, -negative on failure.
|
||||
===========================================================================*/
|
||||
int remove_from_list(int handle)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct thermal_cdata *client = NULL,*prev_client = NULL;
|
||||
|
||||
if ( handle == 0 ||
|
||||
handle >= CLIENT_HANDLE_MAX ||
|
||||
0 == CLIENT_HANDLE_COND(handle))
|
||||
return ret;
|
||||
|
||||
for (client = list_head; client != NULL; client = client->next) {
|
||||
if (client->client_cb_handle != handle) {
|
||||
prev_client = client;
|
||||
continue;
|
||||
}
|
||||
if (client == list_head) {
|
||||
list_head = list_head->next;
|
||||
break;
|
||||
} else {
|
||||
prev_client->next = client->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
client_cb_handle &= ~(1 << handle);
|
||||
|
||||
if (client == NULL)
|
||||
return ret;
|
||||
free(client);
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================================
|
||||
FUNCTION add_to_list
|
||||
|
||||
Function to add new client and its data to list while registering
|
||||
with thermal.
|
||||
|
||||
ARGUMENTS
|
||||
name - client name.
|
||||
callback - callback function
|
||||
data - client specific data
|
||||
|
||||
RETURN VALUE
|
||||
return a unsigned non zero client handle on success, zero on failure.
|
||||
=============================================================================================*/
|
||||
int add_to_list(char *name, void *callback, void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
struct thermal_cdata *newclient = NULL;
|
||||
|
||||
if (NULL == name ||
|
||||
NULL == callback)
|
||||
return ret;
|
||||
|
||||
newclient = (struct thermal_cdata *) malloc(sizeof(struct thermal_cdata));
|
||||
if (NULL == newclient) {
|
||||
return ret;
|
||||
}
|
||||
memset(newclient, 0, sizeof(struct thermal_cdata));
|
||||
|
||||
for (i = 1; i < CLIENT_HANDLE_MAX; i++) {
|
||||
if (!CLIENT_HANDLE_COND(i))
|
||||
break;
|
||||
}
|
||||
if (i >= CLIENT_HANDLE_MAX)
|
||||
return ret;
|
||||
|
||||
client_cb_handle |= (1<<i);
|
||||
|
||||
newclient->client_cb_handle = i;
|
||||
newclient->client_name = name;
|
||||
newclient->callback = callback;
|
||||
newclient->user_data = data;
|
||||
newclient->data_reserved = NULL;
|
||||
newclient->next = NULL;
|
||||
|
||||
if (list_head == NULL) {
|
||||
list_head = newclient;
|
||||
} else {
|
||||
newclient->next = list_head;
|
||||
list_head = newclient;
|
||||
}
|
||||
ret = newclient->client_cb_handle;
|
||||
return ret;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#ifndef __THERMAL_LIB_COMMON_H__
|
||||
#define __THERMAL_LIB_COMMON_H__
|
||||
|
||||
#define THERMAL_SEND_CLIENT_SOCKET "/dev/socket/thermal-send-client"
|
||||
#define THERMAL_RECV_CLIENT_SOCKET "/dev/socket/thermal-recv-client"
|
||||
#define NUM_LISTEN_QUEUE (20)
|
||||
#define LEVEL_MAX (3)
|
||||
#define CLIENT_HANDLE_MAX (32)
|
||||
#define CLIENT_NAME_MAX (12)
|
||||
|
||||
/* Thermal client data */
|
||||
struct thermal_cdata {
|
||||
int client_cb_handle;
|
||||
char *client_name;
|
||||
void *callback;
|
||||
void *user_data;
|
||||
void *data_reserved;
|
||||
struct thermal_cdata *next;
|
||||
};
|
||||
|
||||
/* Thermal socket message data type */
|
||||
struct thermal_msg_data {
|
||||
int msg_type;
|
||||
char client_name[CLIENT_NAME_MAX];
|
||||
int req_data;
|
||||
};
|
||||
|
||||
int add_to_list(char *name, void *callback, void *data);
|
||||
struct thermal_cdata *get_callback_node_from_list(struct thermal_cdata *list, char *name);
|
||||
int remove_from_list(int handle);
|
||||
|
||||
#endif /* __THERMAL_LIB_COMMON_H__ */
|
||||
@@ -1,231 +0,0 @@
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
T H E R M A L _ M I T I G A T I O N _ D E V I C E _ S E R V I C E _ V 0 1 . C
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This is the file which defines the tmd service Data structures.
|
||||
|
||||
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
$Header: //source/qcom/qct/mpss/api/tmd/main/latest/src/thermal_mitigation_device_service_v01.c#1 $
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
|
||||
/* This file was generated with Tool version 2.7
|
||||
It was generated on: Thu Sep 1 2011
|
||||
From IDL File: thermal_mitigation_device_service_v01.idl */
|
||||
|
||||
#include "stdint.h"
|
||||
#include "qmi_idl_lib_internal.h"
|
||||
#include "thermal_mitigation_device_service_v01.h"
|
||||
#include "common_v01.h"
|
||||
|
||||
|
||||
/*Type Definitions*/
|
||||
static const uint8_t tmd_mitigation_dev_id_type_data_v01[] = {
|
||||
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_STRING,
|
||||
QMI_IDL_OFFSET8(tmd_mitigation_dev_id_type_v01, mitigation_dev_id),
|
||||
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01,
|
||||
|
||||
QMI_IDL_FLAG_END_VALUE
|
||||
};
|
||||
|
||||
static const uint8_t tmd_mitigation_dev_list_type_data_v01[] = {
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_mitigation_dev_list_type_v01, mitigation_dev_id),
|
||||
0, 0,
|
||||
QMI_IDL_GENERIC_1_BYTE,
|
||||
QMI_IDL_OFFSET8(tmd_mitigation_dev_list_type_v01, max_mitigation_level),
|
||||
|
||||
QMI_IDL_FLAG_END_VALUE
|
||||
};
|
||||
|
||||
/*Message Definitions*/
|
||||
/*
|
||||
* tmd_get_mitigation_device_list_req_msg is empty
|
||||
* static const uint8_t tmd_get_mitigation_device_list_req_msg_data_v01[] = {
|
||||
* };
|
||||
*/
|
||||
|
||||
static const uint8_t tmd_get_mitigation_device_list_resp_msg_data_v01[] = {
|
||||
0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, resp),
|
||||
0, 1,
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list) - QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list_valid)),
|
||||
0x10,
|
||||
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list),
|
||||
QMI_TMD_MITIGATION_DEV_LIST_MAX_V01,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list) - QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list_len),
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const uint8_t tmd_set_mitigation_level_req_msg_data_v01[] = {
|
||||
0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_set_mitigation_level_req_msg_v01, mitigation_dev_id),
|
||||
0, 0,
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
|
||||
QMI_IDL_GENERIC_1_BYTE,
|
||||
QMI_IDL_OFFSET8(tmd_set_mitigation_level_req_msg_v01, mitigation_level)
|
||||
};
|
||||
|
||||
static const uint8_t tmd_set_mitigation_level_resp_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_set_mitigation_level_resp_msg_v01, resp),
|
||||
0, 1
|
||||
};
|
||||
|
||||
static const uint8_t tmd_get_mitigation_level_req_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_level_req_msg_v01, mitigation_device),
|
||||
0, 0
|
||||
};
|
||||
|
||||
static const uint8_t tmd_get_mitigation_level_resp_msg_data_v01[] = {
|
||||
0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, resp),
|
||||
0, 1,
|
||||
|
||||
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, current_mitigation_level) - QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, current_mitigation_level_valid)),
|
||||
0x10,
|
||||
QMI_IDL_GENERIC_1_BYTE,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, current_mitigation_level),
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, requested_mitigation_level) - QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, requested_mitigation_level_valid)),
|
||||
0x11,
|
||||
QMI_IDL_GENERIC_1_BYTE,
|
||||
QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, requested_mitigation_level)
|
||||
};
|
||||
|
||||
static const uint8_t tmd_register_notification_mitigation_level_req_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_register_notification_mitigation_level_req_msg_v01, mitigation_device),
|
||||
0, 0
|
||||
};
|
||||
|
||||
static const uint8_t tmd_register_notification_mitigation_level_resp_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_register_notification_mitigation_level_resp_msg_v01, resp),
|
||||
0, 1
|
||||
};
|
||||
|
||||
static const uint8_t tmd_deregister_notification_mitigation_level_req_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_deregister_notification_mitigation_level_req_msg_v01, mitigation_device),
|
||||
0, 0
|
||||
};
|
||||
|
||||
static const uint8_t tmd_deregister_notification_mitigation_level_resp_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_deregister_notification_mitigation_level_resp_msg_v01, resp),
|
||||
0, 1
|
||||
};
|
||||
|
||||
static const uint8_t tmd_mitigation_level_report_ind_msg_data_v01[] = {
|
||||
0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(tmd_mitigation_level_report_ind_msg_v01, mitigation_device),
|
||||
0, 0,
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
|
||||
QMI_IDL_GENERIC_1_BYTE,
|
||||
QMI_IDL_OFFSET8(tmd_mitigation_level_report_ind_msg_v01, current_mitigation_level)
|
||||
};
|
||||
|
||||
/* Type Table */
|
||||
static const qmi_idl_type_table_entry tmd_type_table_v01[] = {
|
||||
{sizeof(tmd_mitigation_dev_id_type_v01), tmd_mitigation_dev_id_type_data_v01},
|
||||
{sizeof(tmd_mitigation_dev_list_type_v01), tmd_mitigation_dev_list_type_data_v01}
|
||||
};
|
||||
|
||||
/* Message Table */
|
||||
static const qmi_idl_message_table_entry tmd_message_table_v01[] = {
|
||||
{0, 0},
|
||||
{sizeof(tmd_get_mitigation_device_list_resp_msg_v01), tmd_get_mitigation_device_list_resp_msg_data_v01},
|
||||
{sizeof(tmd_set_mitigation_level_req_msg_v01), tmd_set_mitigation_level_req_msg_data_v01},
|
||||
{sizeof(tmd_set_mitigation_level_resp_msg_v01), tmd_set_mitigation_level_resp_msg_data_v01},
|
||||
{sizeof(tmd_get_mitigation_level_req_msg_v01), tmd_get_mitigation_level_req_msg_data_v01},
|
||||
{sizeof(tmd_get_mitigation_level_resp_msg_v01), tmd_get_mitigation_level_resp_msg_data_v01},
|
||||
{sizeof(tmd_register_notification_mitigation_level_req_msg_v01), tmd_register_notification_mitigation_level_req_msg_data_v01},
|
||||
{sizeof(tmd_register_notification_mitigation_level_resp_msg_v01), tmd_register_notification_mitigation_level_resp_msg_data_v01},
|
||||
{sizeof(tmd_deregister_notification_mitigation_level_req_msg_v01), tmd_deregister_notification_mitigation_level_req_msg_data_v01},
|
||||
{sizeof(tmd_deregister_notification_mitigation_level_resp_msg_v01), tmd_deregister_notification_mitigation_level_resp_msg_data_v01},
|
||||
{sizeof(tmd_mitigation_level_report_ind_msg_v01), tmd_mitigation_level_report_ind_msg_data_v01}
|
||||
};
|
||||
|
||||
/* Predefine the Type Table Object */
|
||||
static const qmi_idl_type_table_object tmd_qmi_idl_type_table_object_v01;
|
||||
|
||||
/*Referenced Tables Array*/
|
||||
static const qmi_idl_type_table_object *tmd_qmi_idl_type_table_object_referenced_tables_v01[] =
|
||||
{&tmd_qmi_idl_type_table_object_v01, &common_qmi_idl_type_table_object_v01};
|
||||
|
||||
/*Type Table Object*/
|
||||
static const qmi_idl_type_table_object tmd_qmi_idl_type_table_object_v01 = {
|
||||
sizeof(tmd_type_table_v01)/sizeof(qmi_idl_type_table_entry ),
|
||||
sizeof(tmd_message_table_v01)/sizeof(qmi_idl_message_table_entry),
|
||||
1,
|
||||
tmd_type_table_v01,
|
||||
tmd_message_table_v01,
|
||||
tmd_qmi_idl_type_table_object_referenced_tables_v01
|
||||
};
|
||||
|
||||
/*Arrays of service_message_table_entries for commands, responses and indications*/
|
||||
static const qmi_idl_service_message_table_entry tmd_service_command_messages_v01[] = {
|
||||
{QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01, TYPE16(0, 0), 0},
|
||||
{QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 2), 40},
|
||||
{QMI_TMD_GET_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 4), 36},
|
||||
{QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 6), 36},
|
||||
{QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 8), 36}
|
||||
};
|
||||
|
||||
static const qmi_idl_service_message_table_entry tmd_service_response_messages_v01[] = {
|
||||
{QMI_TMD_GET_MITIGATION_DEVICE_LIST_RESP_V01, TYPE16(0, 1), 1099},
|
||||
{QMI_TMD_SET_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 3), 7},
|
||||
{QMI_TMD_GET_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 5), 15},
|
||||
{QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 7), 7},
|
||||
{QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 9), 7}
|
||||
};
|
||||
|
||||
static const qmi_idl_service_message_table_entry tmd_service_indication_messages_v01[] = {
|
||||
{QMI_TMD_MITIGATION_LEVEL_REPORT_IND_V01, TYPE16(0, 10), 40}
|
||||
};
|
||||
|
||||
/*Service Object*/
|
||||
const struct qmi_idl_service_object tmd_qmi_idl_service_object_v01 = {
|
||||
0x02,
|
||||
0x01,
|
||||
24,
|
||||
1099,
|
||||
{ sizeof(tmd_service_command_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
|
||||
sizeof(tmd_service_response_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
|
||||
sizeof(tmd_service_indication_messages_v01)/sizeof(qmi_idl_service_message_table_entry) },
|
||||
{ tmd_service_command_messages_v01, tmd_service_response_messages_v01, tmd_service_indication_messages_v01},
|
||||
&tmd_qmi_idl_type_table_object_v01
|
||||
};
|
||||
|
||||
/* Service Object Accessor */
|
||||
qmi_idl_service_object_type tmd_get_service_object_internal_v01
|
||||
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version ){
|
||||
if ( TMD_V01_IDL_MAJOR_VERS != idl_maj_version || TMD_V01_IDL_MINOR_VERS != idl_min_version
|
||||
|| TMD_V01_IDL_TOOL_VERS != library_version)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return (qmi_idl_service_object_type)&tmd_qmi_idl_service_object_v01;
|
||||
}
|
||||
|
||||
@@ -1,338 +0,0 @@
|
||||
#ifndef TMD_SERVICE_H
|
||||
#define TMD_SERVICE_H
|
||||
/**
|
||||
@file thermal_mitigation_device_service_v01.h
|
||||
|
||||
@brief This is the public header file which defines the tmd service Data structures.
|
||||
|
||||
This header file defines the types and structures that were defined in
|
||||
tmd. It contains the constant values defined, enums, structures,
|
||||
messages, and service message IDs (in that order) Structures that were
|
||||
defined in the IDL as messages contain mandatory elements, optional
|
||||
elements, a combination of mandatory and optional elements (mandatory
|
||||
always come before optionals in the structure), or nothing (null message)
|
||||
|
||||
An optional element in a message is preceded by a uint8_t value that must be
|
||||
set to true if the element is going to be included. When decoding a received
|
||||
message, the uint8_t values will be set to true or false by the decode
|
||||
routine, and should be checked before accessing the values that they
|
||||
correspond to.
|
||||
|
||||
Variable sized arrays are defined as static sized arrays with an unsigned
|
||||
integer (32 bit) preceding it that must be set to the number of elements
|
||||
in the array that are valid. For Example:
|
||||
|
||||
uint32_t test_opaque_len;
|
||||
uint8_t test_opaque[16];
|
||||
|
||||
If only 4 elements are added to test_opaque[] then test_opaque_len must be
|
||||
set to 4 before sending the message. When decoding, the _len value is set
|
||||
by the decode routine and should be checked so that the correct number of
|
||||
elements in the array will be accessed.
|
||||
|
||||
*/
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
$Header: //source/qcom/qct/mpss/api/tmd/main/latest/thermal_mitigation_device_service_v01.h#1 $
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
|
||||
/* This file was generated with Tool version 2.7
|
||||
It was generated on: Thu Sep 1 2011
|
||||
From IDL File: thermal_mitigation_device_service_v01.idl */
|
||||
|
||||
/** @defgroup tmd_qmi_consts Constant values defined in the IDL */
|
||||
/** @defgroup tmd_qmi_msg_ids Constant values for QMI message IDs */
|
||||
/** @defgroup tmd_qmi_enums Enumerated types used in QMI messages */
|
||||
/** @defgroup tmd_qmi_messages Structures sent as QMI messages */
|
||||
/** @defgroup tmd_qmi_aggregates Aggregate types used in QMI messages */
|
||||
/** @defgroup tmd_qmi_accessor Accessor for QMI service object */
|
||||
/** @defgroup tmd_qmi_version Constant values for versioning information */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "qmi_idl_lib.h"
|
||||
#include "common_v01.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup tmd_qmi_version
|
||||
@{
|
||||
*/
|
||||
/** Major Version Number of the IDL used to generate this file */
|
||||
#define TMD_V01_IDL_MAJOR_VERS 0x01
|
||||
/** Revision Number of the IDL used to generate this file */
|
||||
#define TMD_V01_IDL_MINOR_VERS 0x00
|
||||
/** Major Version Number of the qmi_idl_compiler used to generate this file */
|
||||
#define TMD_V01_IDL_TOOL_VERS 0x02
|
||||
/** Maximum Defined Message ID */
|
||||
#define TMD_V01_MAX_MESSAGE_ID 0x0025;
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup tmd_qmi_consts
|
||||
@{
|
||||
*/
|
||||
#define QMI_TMD_MITIGATION_DEV_LIST_MAX_V01 32
|
||||
#define QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 32
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_aggregates
|
||||
@{
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
char mitigation_dev_id[QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1];
|
||||
}tmd_mitigation_dev_id_type_v01; /* Type */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_aggregates
|
||||
@{
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
tmd_mitigation_dev_id_type_v01 mitigation_dev_id;
|
||||
/**< Mitigation device ID */
|
||||
|
||||
uint8_t max_mitigation_level;
|
||||
/**< Maximum valid mitigation level; valid range from 0 - max_mitigation_level */
|
||||
}tmd_mitigation_dev_list_type_v01; /* Type */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/*
|
||||
* tmd_get_mitigation_device_list_req_msg is empty
|
||||
* typedef struct {
|
||||
* }tmd_get_mitigation_device_list_req_msg_v01;
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; This gets the list of mitigation devices from the remote endpoint. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
|
||||
/* Optional */
|
||||
uint8_t mitigation_device_list_valid; /**< Must be set to true if mitigation_device_list is being passed */
|
||||
uint32_t mitigation_device_list_len; /**< Must be set to # of elements in mitigation_device_list */
|
||||
tmd_mitigation_dev_list_type_v01 mitigation_device_list[QMI_TMD_MITIGATION_DEV_LIST_MAX_V01];
|
||||
/**< List of mitigation devices on remote endpoint */
|
||||
}tmd_get_mitigation_device_list_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Request Message; This sets thermal mitigation level for the specified mitigation
|
||||
device. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
tmd_mitigation_dev_id_type_v01 mitigation_dev_id;
|
||||
/**< Mitigation device ID */
|
||||
|
||||
/* Mandatory */
|
||||
uint8_t mitigation_level;
|
||||
/**< Thermal mitigation level to set, 0 defined as no mitigation,
|
||||
with each level increment predefined to have increasing mitigative
|
||||
effect. Per-device max valid level obtained from GET_MITIGATION_DEVICE_LIST. */
|
||||
}tmd_set_mitigation_level_req_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; This sets thermal mitigation level for the specified mitigation
|
||||
device. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
}tmd_set_mitigation_level_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Request Message; This gets the thermal mitigation level for the mitigation device. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
tmd_mitigation_dev_id_type_v01 mitigation_device;
|
||||
/**< Mitigation device */
|
||||
}tmd_get_mitigation_level_req_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; This gets the thermal mitigation level for the mitigation device. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
|
||||
/* Optional */
|
||||
uint8_t current_mitigation_level_valid; /**< Must be set to true if current_mitigation_level is being passed */
|
||||
uint8_t current_mitigation_level;
|
||||
/**< Current thermal mitigation level */
|
||||
|
||||
/* Optional */
|
||||
uint8_t requested_mitigation_level_valid; /**< Must be set to true if requested_mitigation_level is being passed */
|
||||
uint8_t requested_mitigation_level;
|
||||
/**< Requested thermal mitigation level from client, defaults to 0 if
|
||||
client has not previously set mitigation level */
|
||||
}tmd_get_mitigation_level_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Request Message; Registers for notification of mitigation device level change. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
tmd_mitigation_dev_id_type_v01 mitigation_device;
|
||||
/**< Mitigation device */
|
||||
}tmd_register_notification_mitigation_level_req_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; Registers for notification of mitigation device level change. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
}tmd_register_notification_mitigation_level_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Request Message; Deregisters notification for mitigation device level changes. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
tmd_mitigation_dev_id_type_v01 mitigation_device;
|
||||
/**< Mitigation device */
|
||||
}tmd_deregister_notification_mitigation_level_req_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; Deregisters notification for mitigation device level changes. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
}tmd_deregister_notification_mitigation_level_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup tmd_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Indication Message; Indicates that a mitigation level report has been received */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
tmd_mitigation_dev_id_type_v01 mitigation_device;
|
||||
/**< Mitigation device */
|
||||
|
||||
/* Mandatory */
|
||||
uint8_t current_mitigation_level;
|
||||
/**< Current thermal mitigation level */
|
||||
}tmd_mitigation_level_report_ind_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/*Service Message Definition*/
|
||||
/** @addtogroup tmd_qmi_msg_ids
|
||||
@{
|
||||
*/
|
||||
#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01 0x0020
|
||||
#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_RESP_V01 0x0020
|
||||
#define QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01 0x0021
|
||||
#define QMI_TMD_SET_MITIGATION_LEVEL_RESP_V01 0x0021
|
||||
#define QMI_TMD_GET_MITIGATION_LEVEL_REQ_V01 0x0022
|
||||
#define QMI_TMD_GET_MITIGATION_LEVEL_RESP_V01 0x0022
|
||||
#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0023
|
||||
#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0023
|
||||
#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0024
|
||||
#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0024
|
||||
#define QMI_TMD_MITIGATION_LEVEL_REPORT_IND_V01 0x0025
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/* Service Object Accessor */
|
||||
/** @addtogroup wms_qmi_accessor
|
||||
@{
|
||||
*/
|
||||
/** This function is used internally by the autogenerated code. Clients should use the
|
||||
macro tmd_get_service_object_v01( ) that takes in no arguments. */
|
||||
qmi_idl_service_object_type tmd_get_service_object_internal_v01
|
||||
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version );
|
||||
|
||||
/** This macro should be used to get the service object */
|
||||
#define tmd_get_service_object_v01( ) \
|
||||
tmd_get_service_object_internal_v01( \
|
||||
TMD_V01_IDL_MAJOR_VERS, TMD_V01_IDL_MINOR_VERS, \
|
||||
TMD_V01_IDL_TOOL_VERS )
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2010-2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include "thermal.h"
|
||||
|
||||
static void clear_all_alarms(sensor_setting_t *sensor, int sensor_temp)
|
||||
{
|
||||
int i, cpu;
|
||||
#ifndef IPQ_806x
|
||||
int gpu;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ACTION_IDX_MAX; i++) {
|
||||
/* check if action may have been set */
|
||||
if ((sensor->action_mask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
switch (i) {
|
||||
case CPU_FREQ:
|
||||
/* set CPU speed to highest */
|
||||
for (cpu = 0; cpu < num_cpus; cpu++) {
|
||||
cpufreq_request(cpu, sensor->id,
|
||||
sensor_temp, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef IPQ_806x
|
||||
case GPU_FREQ:
|
||||
/* set GPU speed to highest */
|
||||
for (gpu = 0; gpu < num_gpus; gpu++) {
|
||||
gpufreq_request(gpu, sensor->id,
|
||||
sensor_temp, -1);
|
||||
}
|
||||
break;
|
||||
case LCD:
|
||||
lcd_brightness_request(sensor->id, sensor_temp, -1);
|
||||
break;
|
||||
case MODEM:
|
||||
modem_request(sensor->id, sensor_temp, 0);
|
||||
break;
|
||||
case FUSION:
|
||||
fusion_modem_request(sensor->id, sensor_temp, 0);
|
||||
break;
|
||||
case BATTERY:
|
||||
battery_request(sensor->id, sensor_temp, 0);
|
||||
break;
|
||||
case WLAN:
|
||||
wlan_request(sensor->id, sensor_temp, 0);
|
||||
break;
|
||||
case CAMERA:
|
||||
camera_request(sensor->id, sensor_temp, 0);
|
||||
break;
|
||||
case CAMCORDER:
|
||||
camcorder_request(sensor->id, sensor_temp, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef IPQ_806x
|
||||
case POWERSAVE:
|
||||
powersave_request(0);
|
||||
break;
|
||||
case NSS_FREQ:
|
||||
nssfreq_request(-1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
sensor->action_mask = 0;
|
||||
}
|
||||
|
||||
void *sensor_monitor(void *vsensor)
|
||||
{
|
||||
sensor_setting_t *sensor = (sensor_setting_t *)vsensor;
|
||||
int i, j, cpu;
|
||||
#ifndef IPQ_806x
|
||||
int gpu;
|
||||
#endif
|
||||
int max_thr;
|
||||
int lvl_alarm[THRESHOLDS_MAX];
|
||||
int alarm_raised = 0, alarm_cleared = 0;
|
||||
int sensor_temp = 0;
|
||||
int lvl_max, lvl_min;
|
||||
int threshold_type = THRESHOLD_NOCHANGE;
|
||||
int threshold_level = 0;
|
||||
|
||||
if (!sensor || (sensor->num_thresholds < 1))
|
||||
return NULL;
|
||||
|
||||
max_thr = sensor->num_thresholds;
|
||||
for (i = 0; i < max_thr; i++) {
|
||||
lvl_alarm[i] = 0;
|
||||
}
|
||||
|
||||
while (exit_daemon != 1) {
|
||||
sensor_wait(sensor);
|
||||
|
||||
sensor_temp = sensor_get_temperature(sensor);
|
||||
|
||||
lvl_max = -1;
|
||||
lvl_min = INT_MAX;
|
||||
for (i = max_thr - 1; i >= 0; i--) {
|
||||
/* Scan for new alarm conditions */
|
||||
if (sensor_threshold_trigger(sensor_temp, sensor, i)) {
|
||||
if (lvl_alarm[i] == 0) {
|
||||
info("Sensor '%s' - alarm raised %d at %2.1f degC\n",
|
||||
sensor->desc, i + 1, RCONV(sensor_temp));
|
||||
lvl_alarm[i] = 1;
|
||||
alarm_raised = 1;
|
||||
}
|
||||
if (i > lvl_max)
|
||||
lvl_max = i;
|
||||
}
|
||||
/* Scan for alarm clearing conditions */
|
||||
if (sensor_threshold_clear(sensor_temp, sensor, i)) {
|
||||
if (lvl_alarm[i] == 1) {
|
||||
info("Sensor '%s' - alarm cleared %d at %2.1f degC\n",
|
||||
sensor->desc, i + 1, RCONV(sensor_temp));
|
||||
lvl_alarm[i] = 0;
|
||||
alarm_cleared = 1;
|
||||
}
|
||||
if (i < lvl_min)
|
||||
lvl_min = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update temperature thresholds */
|
||||
if (alarm_raised) {
|
||||
threshold_type = THRESHOLD_CROSS;
|
||||
threshold_level = lvl_max + 1;
|
||||
} else if (alarm_cleared) {
|
||||
threshold_type = THRESHOLD_CLEAR;
|
||||
threshold_level = lvl_min;
|
||||
} else {
|
||||
threshold_type = THRESHOLD_NOCHANGE;
|
||||
threshold_level = sensor->last_lvl;
|
||||
}
|
||||
sensor->last_lvl = threshold_level;
|
||||
|
||||
sensor_update_thresholds(sensor, threshold_type, threshold_level);
|
||||
|
||||
if (!alarm_raised && !alarm_cleared) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Perform actions on highest level alarm */
|
||||
for (i = max_thr - 1; i >= 0; i--) {
|
||||
if (lvl_alarm[i] == 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < sensor->t[i].num_actions; j++) {
|
||||
dbgmsg ("j=%d i=%d Sensor %s: action %d value %d\n",
|
||||
j, i, sensor->desc,
|
||||
sensor->t[i].actions[j].action,
|
||||
sensor->t[i].actions[j].info);
|
||||
|
||||
sensor->action_mask |= (1 << sensor->t[i].actions[j].action);
|
||||
switch(sensor->t[i].actions[j].action) {
|
||||
case NONE:
|
||||
break;
|
||||
case CPU_FREQ:
|
||||
for (cpu = 0; cpu < num_cpus; cpu++) {
|
||||
cpufreq_request(cpu, sensor->id,
|
||||
sensor_temp,
|
||||
sensor->t[i].actions[j].info);
|
||||
}
|
||||
break;
|
||||
case SHUTDOWN:
|
||||
shutdown_action(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
|
||||
#ifdef IPQ_806x
|
||||
case POWERSAVE:
|
||||
powersave_request(sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case NSS_FREQ:
|
||||
nssfreq_request(sensor->t[i].actions[j].info);
|
||||
break;
|
||||
#else
|
||||
case REPORT:
|
||||
if (alarm_raised)
|
||||
report_action(sensor->id, sensor_temp, i, 1);
|
||||
break;
|
||||
|
||||
case GPU_FREQ:
|
||||
for (gpu = 0; gpu < num_gpus; gpu++) {
|
||||
gpufreq_request(gpu, sensor->id,
|
||||
sensor_temp,
|
||||
sensor->t[i].actions[j].info);
|
||||
}
|
||||
break;
|
||||
case LCD:
|
||||
lcd_brightness_request(sensor->id,
|
||||
sensor_temp,
|
||||
sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case MODEM:
|
||||
modem_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case FUSION:
|
||||
fusion_modem_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case BATTERY:
|
||||
battery_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case WLAN:
|
||||
wlan_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case CAMERA:
|
||||
camera_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
case CAMCORDER:
|
||||
camcorder_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
msg("Unknown action %d\n", sensor->t[i].actions[j].action);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (alarm_cleared) {
|
||||
/* Handle alarm clearing cases */
|
||||
if (lvl_min == 0) {
|
||||
dbgmsg("Clearing all alarms on sensor %s\n", sensor->desc);
|
||||
clear_all_alarms(sensor, sensor_temp);
|
||||
}
|
||||
#ifndef IPQ_806x
|
||||
/* report threshold clearing */
|
||||
for (j = 0; j < sensor->t[lvl_min].num_actions; j++) {
|
||||
if (REPORT == sensor->t[lvl_min].actions[j].action) {
|
||||
report_action(sensor->id, sensor_temp, lvl_min, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
alarm_raised = 0;
|
||||
alarm_cleared = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void thermal_monitor(thermal_setting_t *settings)
|
||||
{
|
||||
int i;
|
||||
int act_cnt;
|
||||
int thrs_cnt;
|
||||
int valid_act_cnt;
|
||||
int max_thr;
|
||||
|
||||
if (!sensors_setup(settings)) {
|
||||
msg("Failed to setup at least one sensor for monitoring\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings->disable_unused_tsens) {
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++){
|
||||
dbgmsg("Disabling sensor %d\n", i);
|
||||
sensor_enable(&settings->sensors[i], i, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++){
|
||||
max_thr = settings->sensors[i].num_thresholds;
|
||||
valid_act_cnt = 0;
|
||||
for (thrs_cnt = max_thr - 1; thrs_cnt >= 0; thrs_cnt--) {
|
||||
for( act_cnt = 0 ; act_cnt < settings->sensors[i].t[thrs_cnt].num_actions;act_cnt++ ){
|
||||
if( NONE != settings->sensors[i].t[thrs_cnt].actions[act_cnt].action )
|
||||
valid_act_cnt++;
|
||||
}
|
||||
}
|
||||
dbgmsg("Sensor %d: No.of valid actions: %d\n" , i , valid_act_cnt );
|
||||
|
||||
if (valid_act_cnt) {
|
||||
dbgmsg("%s - Enabling sensor: %d tzn: %d\n" , __func__ , i, settings->sensors[i].sensor->tzn);
|
||||
sensor_enable(&settings->sensors[i], settings->sensors[i].sensor->tzn, 1 );
|
||||
} else
|
||||
continue;
|
||||
|
||||
dbgmsg("Spawn Monitor thread for sensor: %d\n" , i );
|
||||
|
||||
if (pthread_create(&settings->sensors[i].monitor,
|
||||
NULL,
|
||||
(void *)&sensor_monitor,
|
||||
(void *)&settings->sensors[i]) != 0) {
|
||||
msg("Error initializing monitor for sensor '%s'\n",
|
||||
sensor_names[i]);
|
||||
settings->sensors[i].disabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < SENSOR_IDX_MAX; i++) {
|
||||
if (!settings->sensors[i].disabled &&
|
||||
(settings->sensors[i].num_thresholds > 0)) {
|
||||
pthread_join(settings->sensors[i].monitor, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
sensors_shutdown();
|
||||
}
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
T H E R M A L _ S E N S O R _ S E R V I C E _ V 0 1 . C
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This is the file which defines the ts service Data structures.
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
|
||||
/* This file was generated with Tool version 4.2
|
||||
It was generated on: Mon Dec 5 2011
|
||||
From IDL File: thermal_sensor_service_v01.idl */
|
||||
|
||||
#include "stdint.h"
|
||||
#include "qmi_idl_lib_internal.h"
|
||||
#include "thermal_sensor_service_v01.h"
|
||||
#include "common_v01.h"
|
||||
|
||||
|
||||
/*Type Definitions*/
|
||||
static const uint8_t ts_sensor_type_data_v01[] = {
|
||||
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_STRING,
|
||||
QMI_IDL_OFFSET8(ts_sensor_type_v01, sensor_id),
|
||||
QMI_TS_SENSOR_ID_LENGTH_MAX_V01,
|
||||
|
||||
QMI_IDL_FLAG_END_VALUE
|
||||
};
|
||||
|
||||
/*Message Definitions*/
|
||||
/*
|
||||
* ts_get_sensor_list_req_msg is empty
|
||||
* static const uint8_t ts_get_sensor_list_req_msg_data_v01[] = {
|
||||
* };
|
||||
*/
|
||||
|
||||
static const uint8_t ts_get_sensor_list_resp_msg_data_v01[] = {
|
||||
0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, resp),
|
||||
0, 1,
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list) - QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list_valid)),
|
||||
0x10,
|
||||
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list),
|
||||
QMI_TS_SENSOR_LIST_MAX_V01,
|
||||
QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list) - QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list_len),
|
||||
0, 0
|
||||
};
|
||||
|
||||
static const uint8_t ts_register_notification_temp_req_msg_data_v01[] = {
|
||||
0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, sensor_id),
|
||||
0, 0,
|
||||
|
||||
0x02,
|
||||
QMI_IDL_GENERIC_1_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, send_current_temp_report),
|
||||
|
||||
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_high) - QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_high_valid)),
|
||||
0x10,
|
||||
QMI_IDL_GENERIC_4_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_high),
|
||||
|
||||
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_low) - QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_low_valid)),
|
||||
0x11,
|
||||
QMI_IDL_GENERIC_4_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_low),
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, seq_num) - QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, seq_num_valid)),
|
||||
0x12,
|
||||
QMI_IDL_GENERIC_4_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, seq_num)
|
||||
};
|
||||
|
||||
static const uint8_t ts_register_notification_temp_resp_msg_data_v01[] = {
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(ts_register_notification_temp_resp_msg_v01, resp),
|
||||
0, 1
|
||||
};
|
||||
|
||||
static const uint8_t ts_temp_report_ind_msg_data_v01[] = {
|
||||
0x01,
|
||||
QMI_IDL_AGGREGATE,
|
||||
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, sensor_id),
|
||||
0, 0,
|
||||
|
||||
0x02,
|
||||
QMI_IDL_GENERIC_4_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, report_type),
|
||||
|
||||
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, temp) - QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, temp_valid)),
|
||||
0x10,
|
||||
QMI_IDL_GENERIC_4_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, temp),
|
||||
|
||||
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, seq_num) - QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, seq_num_valid)),
|
||||
0x11,
|
||||
QMI_IDL_GENERIC_4_BYTE,
|
||||
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, seq_num)
|
||||
};
|
||||
|
||||
/* Type Table */
|
||||
static const qmi_idl_type_table_entry ts_type_table_v01[] = {
|
||||
{sizeof(ts_sensor_type_v01), ts_sensor_type_data_v01}
|
||||
};
|
||||
|
||||
/* Message Table */
|
||||
static const qmi_idl_message_table_entry ts_message_table_v01[] = {
|
||||
{0, 0},
|
||||
{sizeof(ts_get_sensor_list_resp_msg_v01), ts_get_sensor_list_resp_msg_data_v01},
|
||||
{sizeof(ts_register_notification_temp_req_msg_v01), ts_register_notification_temp_req_msg_data_v01},
|
||||
{sizeof(ts_register_notification_temp_resp_msg_v01), ts_register_notification_temp_resp_msg_data_v01},
|
||||
{sizeof(ts_temp_report_ind_msg_v01), ts_temp_report_ind_msg_data_v01}
|
||||
};
|
||||
|
||||
/* Predefine the Type Table Object */
|
||||
static const qmi_idl_type_table_object ts_qmi_idl_type_table_object_v01;
|
||||
|
||||
/*Referenced Tables Array*/
|
||||
static const qmi_idl_type_table_object *ts_qmi_idl_type_table_object_referenced_tables_v01[] =
|
||||
{&ts_qmi_idl_type_table_object_v01, &common_qmi_idl_type_table_object_v01};
|
||||
|
||||
/*Type Table Object*/
|
||||
static const qmi_idl_type_table_object ts_qmi_idl_type_table_object_v01 = {
|
||||
sizeof(ts_type_table_v01)/sizeof(qmi_idl_type_table_entry ),
|
||||
sizeof(ts_message_table_v01)/sizeof(qmi_idl_message_table_entry),
|
||||
1,
|
||||
ts_type_table_v01,
|
||||
ts_message_table_v01,
|
||||
ts_qmi_idl_type_table_object_referenced_tables_v01
|
||||
};
|
||||
|
||||
/*Arrays of service_message_table_entries for commands, responses and indications*/
|
||||
static const qmi_idl_service_message_table_entry ts_service_command_messages_v01[] = {
|
||||
{QMI_TS_GET_SENSOR_LIST_REQ_V01, TYPE16(0, 0), 0},
|
||||
{QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01, TYPE16(0, 2), 61}
|
||||
};
|
||||
|
||||
static const qmi_idl_service_message_table_entry ts_service_response_messages_v01[] = {
|
||||
{QMI_TS_GET_SENSOR_LIST_RESP_V01, TYPE16(0, 1), 1067},
|
||||
{QMI_TS_REGISTER_NOTIFICATION_TEMP_RESP_V01, TYPE16(0, 3), 7}
|
||||
};
|
||||
|
||||
static const qmi_idl_service_message_table_entry ts_service_indication_messages_v01[] = {
|
||||
{QMI_TS_TEMP_REPORT_IND_V01, TYPE16(0, 4), 57}
|
||||
};
|
||||
|
||||
/*Service Object*/
|
||||
const struct qmi_idl_service_object ts_qmi_idl_service_object_v01 = {
|
||||
0x04,
|
||||
0x01,
|
||||
23,
|
||||
1067,
|
||||
{ sizeof(ts_service_command_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
|
||||
sizeof(ts_service_response_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
|
||||
sizeof(ts_service_indication_messages_v01)/sizeof(qmi_idl_service_message_table_entry) },
|
||||
{ ts_service_command_messages_v01, ts_service_response_messages_v01, ts_service_indication_messages_v01},
|
||||
&ts_qmi_idl_type_table_object_v01
|
||||
};
|
||||
|
||||
/* Service Object Accessor */
|
||||
qmi_idl_service_object_type ts_get_service_object_internal_v01
|
||||
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version ){
|
||||
if ( TS_V01_IDL_MAJOR_VERS != idl_maj_version || TS_V01_IDL_MINOR_VERS != idl_min_version
|
||||
|| TS_V01_IDL_TOOL_VERS != library_version)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return (qmi_idl_service_object_type)&ts_qmi_idl_service_object_v01;
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
#ifndef TS_SERVICE_H
|
||||
#define TS_SERVICE_H
|
||||
/**
|
||||
@file thermal_sensor_service_v01.h
|
||||
|
||||
@brief This is the public header file which defines the ts service Data structures.
|
||||
|
||||
This header file defines the types and structures that were defined in
|
||||
ts. It contains the constant values defined, enums, structures,
|
||||
messages, and service message IDs (in that order) Structures that were
|
||||
defined in the IDL as messages contain mandatory elements, optional
|
||||
elements, a combination of mandatory and optional elements (mandatory
|
||||
always come before optionals in the structure), or nothing (null message)
|
||||
|
||||
An optional element in a message is preceded by a uint8_t value that must be
|
||||
set to true if the element is going to be included. When decoding a received
|
||||
message, the uint8_t values will be set to true or false by the decode
|
||||
routine, and should be checked before accessing the values that they
|
||||
correspond to.
|
||||
|
||||
Variable sized arrays are defined as static sized arrays with an unsigned
|
||||
integer (32 bit) preceding it that must be set to the number of elements
|
||||
in the array that are valid. For Example:
|
||||
|
||||
uint32_t test_opaque_len;
|
||||
uint8_t test_opaque[16];
|
||||
|
||||
If only 4 elements are added to test_opaque[] then test_opaque_len must be
|
||||
set to 4 before sending the message. When decoding, the _len value is set
|
||||
by the decode routine and should be checked so that the correct number of
|
||||
elements in the array will be accessed.
|
||||
|
||||
*/
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
$Header: //source/qcom/qct/interfaces/qmi/ts/main/latest/api/thermal_sensor_service_v01.h#2 $
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
|
||||
/* This file was generated with Tool version 4.2
|
||||
It was generated on: Mon Dec 5 2011
|
||||
From IDL File: thermal_sensor_service_v01.idl */
|
||||
|
||||
/** @defgroup ts_qmi_consts Constant values defined in the IDL */
|
||||
/** @defgroup ts_qmi_msg_ids Constant values for QMI message IDs */
|
||||
/** @defgroup ts_qmi_enums Enumerated types used in QMI messages */
|
||||
/** @defgroup ts_qmi_messages Structures sent as QMI messages */
|
||||
/** @defgroup ts_qmi_aggregates Aggregate types used in QMI messages */
|
||||
/** @defgroup ts_qmi_accessor Accessor for QMI service object */
|
||||
/** @defgroup ts_qmi_version Constant values for versioning information */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "qmi_idl_lib.h"
|
||||
#include "common_v01.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup ts_qmi_version
|
||||
@{
|
||||
*/
|
||||
/** Major Version Number of the IDL used to generate this file */
|
||||
#define TS_V01_IDL_MAJOR_VERS 0x01
|
||||
/** Revision Number of the IDL used to generate this file */
|
||||
#define TS_V01_IDL_MINOR_VERS 0x00
|
||||
/** Major Version Number of the qmi_idl_compiler used to generate this file */
|
||||
#define TS_V01_IDL_TOOL_VERS 0x04
|
||||
/** Maximum Defined Message ID */
|
||||
#define TS_V01_MAX_MESSAGE_ID 0x0022;
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup ts_qmi_consts
|
||||
@{
|
||||
*/
|
||||
#define QMI_TS_SENSOR_LIST_MAX_V01 32
|
||||
#define QMI_TS_SENSOR_ID_LENGTH_MAX_V01 32
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup ts_qmi_aggregates
|
||||
@{
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
char sensor_id[QMI_TS_SENSOR_ID_LENGTH_MAX_V01 + 1];
|
||||
/**< Sensor ID */
|
||||
}ts_sensor_type_v01; /* Type */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/*
|
||||
* ts_get_sensor_list_req_msg is empty
|
||||
* typedef struct {
|
||||
* }ts_get_sensor_list_req_msg_v01;
|
||||
*/
|
||||
|
||||
/** @addtogroup ts_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; Gets the list of sensors from the remote endpoint. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
|
||||
/* Optional */
|
||||
/* Sensor List */
|
||||
uint8_t sensor_list_valid; /**< Must be set to true if sensor_list is being passed */
|
||||
uint32_t sensor_list_len; /**< Must be set to # of elements in sensor_list */
|
||||
ts_sensor_type_v01 sensor_list[QMI_TS_SENSOR_LIST_MAX_V01];
|
||||
}ts_get_sensor_list_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup ts_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Request Message; Registers for notification of temperature sensor readings.
|
||||
Indicates threshold temperatures for notification. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Sensor ID */
|
||||
ts_sensor_type_v01 sensor_id;
|
||||
|
||||
/* Mandatory */
|
||||
/* Current Temperature Report */
|
||||
uint8_t send_current_temp_report;
|
||||
/**< Request for current temperature report indication.
|
||||
*/
|
||||
|
||||
/* Optional */
|
||||
/* High Threshold Temperature */
|
||||
uint8_t temp_threshold_high_valid; /**< Must be set to true if temp_threshold_high is being passed */
|
||||
float temp_threshold_high;
|
||||
/**< High threshold temperature in degrees Celsius.
|
||||
*/
|
||||
|
||||
/* Optional */
|
||||
/* Low Threshold Temperature */
|
||||
uint8_t temp_threshold_low_valid; /**< Must be set to true if temp_threshold_low is being passed */
|
||||
float temp_threshold_low;
|
||||
/**< Low threshold temperature in degrees Celsius.
|
||||
*/
|
||||
|
||||
/* Optional */
|
||||
/* Sequence Number */
|
||||
uint8_t seq_num_valid; /**< Must be set to true if seq_num is being passed */
|
||||
uint32_t seq_num;
|
||||
/**< Optional sequence cookie to match the registration with the indication.
|
||||
*/
|
||||
}ts_register_notification_temp_req_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup ts_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Response Message; Registers for notification of temperature sensor readings.
|
||||
Indicates threshold temperatures for notification. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Result Code */
|
||||
qmi_response_type_v01 resp;
|
||||
/**< Standard response type. */
|
||||
}ts_register_notification_temp_resp_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup ts_qmi_enums
|
||||
@{
|
||||
*/
|
||||
typedef enum {
|
||||
TS_TEMP_REPORT_TYPE_ENUM_MIN_ENUM_VAL_V01 = -2147483647, /**< To force a 32 bit signed enum. Do not change or use*/
|
||||
QMI_TS_TEMP_REPORT_CURRENT_TEMP_V01 = 0,
|
||||
QMI_TS_TEMP_REPORT_THRESHOLD_HIGH_V01 = 1,
|
||||
QMI_TS_TEMP_REPORT_THRESHOLD_LOW_V01 = 2,
|
||||
TS_TEMP_REPORT_TYPE_ENUM_MAX_ENUM_VAL_V01 = 2147483647 /**< To force a 32 bit signed enum. Do not change or use*/
|
||||
}ts_temp_report_type_enum_v01;
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/** @addtogroup ts_qmi_messages
|
||||
@{
|
||||
*/
|
||||
/** Indication Message; Indicates that a temperature report has been received. */
|
||||
typedef struct {
|
||||
|
||||
/* Mandatory */
|
||||
/* Sensor ID */
|
||||
ts_sensor_type_v01 sensor_id;
|
||||
|
||||
/* Mandatory */
|
||||
/* Sensor Reported */
|
||||
ts_temp_report_type_enum_v01 report_type;
|
||||
/**< Indicates temperature report type. If report_type is not recognized,
|
||||
the client ignores the report.
|
||||
*/
|
||||
|
||||
/* Optional */
|
||||
/* Temperature */
|
||||
uint8_t temp_valid; /**< Must be set to true if temp is being passed */
|
||||
float temp;
|
||||
/**< Temperature report in degrees Celsius. If this field is omitted,
|
||||
the service cannot obtain the temperature value from the sensor.
|
||||
*/
|
||||
|
||||
/* Optional */
|
||||
/* Sequence Number */
|
||||
uint8_t seq_num_valid; /**< Must be set to true if seq_num is being passed */
|
||||
uint32_t seq_num;
|
||||
/**< Optional sequence cookie to match the registration with the indication.
|
||||
*/
|
||||
}ts_temp_report_ind_msg_v01; /* Message */
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/*Service Message Definition*/
|
||||
/** @addtogroup ts_qmi_msg_ids
|
||||
@{
|
||||
*/
|
||||
#define QMI_TS_GET_SENSOR_LIST_REQ_V01 0x0020
|
||||
#define QMI_TS_GET_SENSOR_LIST_RESP_V01 0x0020
|
||||
#define QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01 0x0021
|
||||
#define QMI_TS_REGISTER_NOTIFICATION_TEMP_RESP_V01 0x0021
|
||||
#define QMI_TS_TEMP_REPORT_IND_V01 0x0022
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
/* Service Object Accessor */
|
||||
/** @addtogroup wms_qmi_accessor
|
||||
@{
|
||||
*/
|
||||
/** This function is used internally by the autogenerated code. Clients should use the
|
||||
macro ts_get_service_object_v01( ) that takes in no arguments. */
|
||||
qmi_idl_service_object_type ts_get_service_object_internal_v01
|
||||
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version );
|
||||
|
||||
/** This macro should be used to get the service object */
|
||||
#define ts_get_service_object_v01( ) \
|
||||
ts_get_service_object_internal_v01( \
|
||||
TS_V01_IDL_MAJOR_VERS, TS_V01_IDL_MINOR_VERS, \
|
||||
TS_V01_IDL_TOOL_VERS )
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,467 +0,0 @@
|
||||
/*========================================================================================
|
||||
|
||||
thermal_server.c
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
Thermal socket server related code to communicate with thermal DLL.
|
||||
|
||||
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
==========================================================================================*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/un.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
#include "thermal.h"
|
||||
#include "thermal_lib_common.h"
|
||||
#include "thermal_server.h"
|
||||
|
||||
static int sockfd_server_send = -1;
|
||||
static int sockfd_server_recv = -1;
|
||||
static pthread_t listen_client_fd_thread;
|
||||
static int server_socket_exit = 0;
|
||||
static pthread_mutex_t soc_client_mutex;
|
||||
static int thermal_send_fds[NUM_LISTEN_QUEUE];
|
||||
struct thermal_cdata *list_head = NULL;
|
||||
|
||||
static char *req_client_names[] =
|
||||
{
|
||||
"spkr",
|
||||
"override",
|
||||
};
|
||||
static char *notify_client_names[] =
|
||||
{
|
||||
"camera",
|
||||
"camcorder",
|
||||
"spkr",
|
||||
};
|
||||
|
||||
/*========================================================================================
|
||||
FUNCTION thermal_recv_data_from_client
|
||||
|
||||
Recieve requested data from client through socket and based on data
|
||||
invoke appropriate thermal callback from list which already registered.
|
||||
|
||||
ARGUMENTS
|
||||
client_fd - client fd for thermal recv socket
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, negative on failure.
|
||||
========================================================================================*/
|
||||
static int thermal_recv_data_from_client(int client_fd)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
int ret = -EINVAL;
|
||||
int count = 0;
|
||||
int (*callback)(int, void *, void *);
|
||||
struct thermal_cdata *callback_node;
|
||||
struct thermal_msg_data client_msg;
|
||||
|
||||
if (client_fd == -1)
|
||||
return ret;
|
||||
|
||||
memset(&client_msg, 0, sizeof(struct thermal_msg_data));
|
||||
rc = recv(client_fd, &client_msg, sizeof(struct thermal_msg_data), 0);
|
||||
if (rc <= 0) {
|
||||
msg("Thermal-Server: %s: recv failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rc != sizeof(struct thermal_msg_data))
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < CLIENT_NAME_MAX; i++) {
|
||||
if (client_msg.client_name[i] == '\0')
|
||||
break;
|
||||
}
|
||||
if (i >= CLIENT_NAME_MAX)
|
||||
client_msg.client_name[CLIENT_NAME_MAX - 1] = '\0';
|
||||
|
||||
info("Thermal-Server: Thermal received "
|
||||
"msg %s %d", client_msg.client_name, client_msg.req_data);
|
||||
|
||||
/* Check for client is supported or not*/
|
||||
for (i = 0; i < ARRAY_SIZE(req_client_names); i++) {
|
||||
if (0 == strncmp(req_client_names[i], client_msg.client_name, CLIENT_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(req_client_names)) {
|
||||
msg("Thermal-Server:%s is not in supported "
|
||||
"thermal client list", client_msg.client_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (callback_node = list_head; callback_node != NULL; callback_node = callback_node->next) {
|
||||
|
||||
callback_node = get_callback_node_from_list(callback_node, client_msg.client_name);
|
||||
if (callback_node) {
|
||||
count++;
|
||||
callback = callback_node->callback;
|
||||
if (callback)
|
||||
callback(client_msg.req_data, callback_node->user_data, callback_node->data_reserved);
|
||||
} else {
|
||||
if (count == 0)
|
||||
msg("Thermal-Server: No clients are "
|
||||
"connected for %s", client_msg.client_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*========================================================================================
|
||||
FUNCTION do_listen_client_fd
|
||||
|
||||
Seperate thread function for monitoring thermal usersapce clients and recieving
|
||||
client data from thermal recv socket once it is notified.
|
||||
|
||||
ARGUMENTS
|
||||
data - data, not used
|
||||
|
||||
RETURN VALUE
|
||||
void
|
||||
========================================================================================*/
|
||||
static void *do_listen_client_fd(void *data)
|
||||
{
|
||||
int fd;
|
||||
int i;
|
||||
int nread;
|
||||
int result;
|
||||
int client_len;
|
||||
int client_fd = -1;
|
||||
struct sockaddr_un client_addr;
|
||||
fd_set t_readfds,testfds;
|
||||
|
||||
FD_ZERO(&t_readfds);
|
||||
FD_SET(sockfd_server_send, &t_readfds);
|
||||
FD_SET(sockfd_server_recv, &t_readfds);
|
||||
|
||||
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
|
||||
thermal_send_fds[i] = -1;
|
||||
}
|
||||
|
||||
while(server_socket_exit != 1) {
|
||||
testfds = t_readfds;
|
||||
result = select(FD_SETSIZE, &testfds, (fd_set *)0,
|
||||
(fd_set *)0, (struct timeval *) 0);
|
||||
|
||||
if (result < 1) {
|
||||
msg("Thermal-Server: %s select error", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
for (fd = 0; fd < FD_SETSIZE; fd++) {
|
||||
if (FD_ISSET(fd,&testfds)) {
|
||||
if (fd == sockfd_server_send) {
|
||||
client_len = sizeof(struct sockaddr_un);
|
||||
client_fd = accept(sockfd_server_send,
|
||||
(struct sockaddr *)&client_addr,
|
||||
&client_len);
|
||||
if (client_fd < 0)
|
||||
continue;
|
||||
FD_SET(client_fd, &t_readfds);
|
||||
info("Thermal-Server: Adding thermal event listener on fd %d\n", client_fd);
|
||||
for (i = 0; i < NUM_LISTEN_QUEUE && thermal_send_fds[i] != -1; i++)
|
||||
continue;
|
||||
if (i < NUM_LISTEN_QUEUE)
|
||||
thermal_send_fds[i] = client_fd;
|
||||
} else if (fd == sockfd_server_recv) {
|
||||
client_len = sizeof(struct sockaddr_un);
|
||||
client_fd = accept(sockfd_server_recv,
|
||||
(struct sockaddr *)&client_addr,
|
||||
&client_len);
|
||||
if (client_fd < 0)
|
||||
continue;
|
||||
thermal_recv_data_from_client(client_fd);
|
||||
close(client_fd);
|
||||
} else {
|
||||
ioctl(fd, FIONREAD, &nread);
|
||||
if (nread == 0) {
|
||||
close(fd);
|
||||
FD_CLR(fd, &t_readfds);
|
||||
info("Thermal-Server: removing client on fd %d\n", fd);
|
||||
for (i = 0; i < NUM_LISTEN_QUEUE && thermal_send_fds[i] != fd; i++)
|
||||
continue;
|
||||
if (i < NUM_LISTEN_QUEUE) {
|
||||
thermal_send_fds[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
|
||||
if (thermal_send_fds[i] > -1)
|
||||
close(thermal_send_fds[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*========================================================================================
|
||||
FUNCTION thermal_server_init
|
||||
|
||||
Thermal socket initialization function for different clients
|
||||
This function setup a server for both thermal sending socket and
|
||||
thermal recieving socket.
|
||||
|
||||
ARGUMENTS
|
||||
none
|
||||
|
||||
RETURN VALUE
|
||||
0 on success, negative on failure.
|
||||
=========================================================================================*/
|
||||
int thermal_server_init(void)
|
||||
{
|
||||
int rc;
|
||||
int ret = -EINVAL;
|
||||
static struct sockaddr_un server_addr_send;
|
||||
static struct sockaddr_un server_addr_recv;
|
||||
|
||||
if (sockfd_server_send != -1 || sockfd_server_recv != -1) {
|
||||
sockfd_server_send = -1;
|
||||
sockfd_server_recv = -1;
|
||||
}
|
||||
|
||||
sockfd_server_send = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sockfd_server_send < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
sockfd_server_recv = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sockfd_server_recv < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(&server_addr_send, 0, sizeof(struct sockaddr_un));
|
||||
snprintf(server_addr_send.sun_path, UNIX_PATH_MAX, THERMAL_SEND_CLIENT_SOCKET);
|
||||
server_addr_send.sun_family = AF_LOCAL;
|
||||
|
||||
memset(&server_addr_recv, 0, sizeof(struct sockaddr_un));
|
||||
snprintf(server_addr_recv.sun_path, UNIX_PATH_MAX, THERMAL_RECV_CLIENT_SOCKET);
|
||||
server_addr_recv.sun_family = AF_LOCAL;
|
||||
|
||||
/* Delete existing socket file if necessary */
|
||||
unlink(server_addr_send.sun_path);
|
||||
unlink(server_addr_recv.sun_path);
|
||||
|
||||
rc = bind(sockfd_server_send,(struct sockaddr const *)&server_addr_send, sizeof(struct sockaddr_un));
|
||||
if (rc != 0) {
|
||||
msg("Thermal-Server: Send socket: bind error - %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
rc = bind(sockfd_server_recv,(struct sockaddr const *)&server_addr_recv, sizeof(struct sockaddr_un));
|
||||
if (rc != 0) {
|
||||
msg("Thermal-Server: Recv socket: bind error - %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Add Camera and media server group permission for sending
|
||||
socket to socket and add media server group for recieving
|
||||
socket untill having better security solution */
|
||||
chown(server_addr_send.sun_path, AID_ROOT, AID_CAMERA);
|
||||
chmod(server_addr_send.sun_path, 0660);
|
||||
chmod(server_addr_recv.sun_path, 0660);
|
||||
|
||||
rc = listen(sockfd_server_send, NUM_LISTEN_QUEUE);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = listen(sockfd_server_recv, NUM_LISTEN_QUEUE);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = pthread_create(&listen_client_fd_thread, NULL, do_listen_client_fd, NULL);
|
||||
if (rc != 0) {
|
||||
msg("Thermal-Server: Unable to create pthread to "
|
||||
"listen thermal clients fd");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
return ret;
|
||||
error:
|
||||
msg("Thermal-Server: Unable to create socket server for thermal clients");
|
||||
if (sockfd_server_send != -1) {
|
||||
close(sockfd_server_send);
|
||||
sockfd_server_send = -1;
|
||||
}
|
||||
if (sockfd_server_recv != -1) {
|
||||
close(sockfd_server_recv);
|
||||
sockfd_server_recv = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*=======================================================================================
|
||||
FUNCTION thermal_server_notify_clients
|
||||
|
||||
Function to send thermal event through socket to thermal clients.
|
||||
|
||||
ARGUMENTS
|
||||
client_name - client_name
|
||||
level - mitigation level
|
||||
|
||||
RETURN VALUE
|
||||
return 0 on success and -EINVAL on failure.
|
||||
========================================================================================*/
|
||||
int thermal_server_notify_clients(char *client_name, int level)
|
||||
{
|
||||
int rc;
|
||||
int i = 0;
|
||||
int ret = -EINVAL;
|
||||
int send_count = 0;
|
||||
struct thermal_msg_data thermal_msg;
|
||||
|
||||
/* Check for client is supported or not*/
|
||||
for (i = 0; i < ARRAY_SIZE(notify_client_names); i++) {
|
||||
if (0 == strncmp(notify_client_names[i], client_name, CLIENT_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(notify_client_names)) {
|
||||
msg("Thermal-Server: %s is not in supported "
|
||||
"thermal client list", client_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&thermal_msg, 0, sizeof(struct thermal_msg_data));
|
||||
strlcpy(thermal_msg.client_name, client_name, CLIENT_NAME_MAX);
|
||||
thermal_msg.req_data = level;
|
||||
|
||||
pthread_mutex_lock(&soc_client_mutex);
|
||||
|
||||
if (sockfd_server_send == -1) {
|
||||
msg("Thermal-Server: socket is not created, Trying to start server..");
|
||||
thermal_server_release();
|
||||
if ( thermal_server_init() || sockfd_server_send == -1) {
|
||||
goto handle_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send event to all connected clients */
|
||||
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
|
||||
if(thermal_send_fds[i] != -1) {
|
||||
send_count++;
|
||||
rc = send(thermal_send_fds[i], &thermal_msg,
|
||||
sizeof(struct thermal_msg_data), 0);
|
||||
if (rc <= 0) {
|
||||
msg("Thermal-Server: Unable to send "
|
||||
"event to fd %d", thermal_send_fds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (send_count == 0) {
|
||||
msg("Thermal-Server: No client connected to socket");
|
||||
goto handle_error;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
handle_error:
|
||||
pthread_mutex_unlock(&soc_client_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*================================================================================================
|
||||
FUNCTION thermal_server_register_client_req_handler
|
||||
|
||||
Thermal register function to register callback
|
||||
Whenever thermal wants to register a new callback for clients,
|
||||
invoke this API.
|
||||
|
||||
ARGUMENTS
|
||||
client_name - client name
|
||||
callback - callback function pointer with req_data, user_data pointer and
|
||||
reserved data as arguments
|
||||
data - data
|
||||
|
||||
RETURN VALUE
|
||||
valid non zero client_cb_handle on success, zero on failure.
|
||||
=================================================================================================*/
|
||||
int thermal_server_register_client_req_handler(char *client_name, int (*callback)(int, void *, void *), void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int client_cb_handle;
|
||||
|
||||
if (NULL == client_name ||
|
||||
NULL == callback) {
|
||||
msg("Thermal-Server: %s: unexpected NULL client registraion failed ", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for client is supported or not*/
|
||||
for (i = 0; i < ARRAY_SIZE(req_client_names); i++) {
|
||||
if (0 == strncmp(req_client_names[i], client_name, CLIENT_NAME_MAX))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(req_client_names)) {
|
||||
msg("Thermal-Server: %s is not in supported thermal client list", client_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
client_cb_handle = add_to_list(client_name, callback, data);
|
||||
if (client_cb_handle == 0) {
|
||||
msg("Thermal-Server: %s: Client Registration failed", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return client_cb_handle;
|
||||
}
|
||||
|
||||
/*========================================================================================
|
||||
FUNCTION thermal_server_unregister_client_req_handler
|
||||
|
||||
Function to unregister client req_handler.
|
||||
|
||||
ARGUMENTS
|
||||
client_cb_handle - client handle which retured on succesful registeration
|
||||
|
||||
RETURN VALUE
|
||||
void
|
||||
========================================================================================*/
|
||||
void thermal_server_unregister_client_req_handler(int client_cb_handle)
|
||||
{
|
||||
if (remove_from_list(client_cb_handle) < 0)
|
||||
msg("Thermal-Server: thermal client unregister callback error");
|
||||
}
|
||||
/*========================================================================================
|
||||
FUNCTION thermal_server_release
|
||||
|
||||
Function to release socket thread and fd
|
||||
|
||||
ARGUMENTS
|
||||
none
|
||||
|
||||
RETURN VALUE
|
||||
void
|
||||
========================================================================================*/
|
||||
void thermal_server_release(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
server_socket_exit = 1;
|
||||
pthread_join(listen_client_fd_thread, NULL);
|
||||
close(sockfd_server_send);
|
||||
close(sockfd_server_recv);
|
||||
sockfd_server_send = -1;
|
||||
sockfd_server_recv = -1;
|
||||
|
||||
for (i = 1; i < CLIENT_HANDLE_MAX && list_head != NULL; i++) {
|
||||
if (remove_from_list(i) < 0)
|
||||
msg("Thermal-Server: thermal client unregister callback error");
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#ifndef __THERMAL_SERVER_H__
|
||||
#define __THERMAL_SERVER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int thermal_server_init(void);
|
||||
int thermal_server_notify_clients(char *client_name, int level);
|
||||
int thermal_server_register_client_req_handler(char *, int (*callback)(int, void *, void *), void *data);
|
||||
void thermal_server_unregister_client_req_handler(int client_cb_handle);
|
||||
void thermal_server_release(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __THERMAL_SERVER_H__ */
|
||||
|
||||
@@ -1,492 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2010-2013 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/un.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include "thermal.h"
|
||||
|
||||
#define THERMAL_SYSFS "/sys/devices/virtual/thermal"
|
||||
/* Sys proc ID */
|
||||
#define SYSFS_CPU_TYPE "/proc/device-tree/cpu_type"
|
||||
#define SYSFS_PLATFORMID "/sys/devices/soc0/soc_id"
|
||||
#define SYSFS_PLATFORMID_DEP "/sys/devices/system/soc/soc0/id"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum therm_msm_id msm_id;
|
||||
int soc_id;
|
||||
} therm_msm_soc_type;
|
||||
|
||||
static therm_msm_soc_type msm_soc_table[] = {
|
||||
{THERM_MSM_8X60, 70},
|
||||
{THERM_MSM_8X60, 71},
|
||||
{THERM_MSM_8X60, 86},
|
||||
{THERM_MSM_8960, 87},
|
||||
{THERM_MSM_8960, 122},
|
||||
{THERM_MSM_8960, 123},
|
||||
{THERM_MSM_8960, 124},
|
||||
{THERM_MSM_8960AB, 138},
|
||||
{THERM_MSM_8960AB, 139},
|
||||
{THERM_MSM_8960AB, 140},
|
||||
{THERM_MSM_8960AB, 141},
|
||||
{THERM_MSM_8930, 116},
|
||||
{THERM_MSM_8930, 117},
|
||||
{THERM_MSM_8930, 118},
|
||||
{THERM_MSM_8930, 119},
|
||||
{THERM_MSM_8930, 120},
|
||||
{THERM_MSM_8930, 121},
|
||||
{THERM_MSM_8930AA, 142},
|
||||
{THERM_MSM_8930AA, 143},
|
||||
{THERM_MSM_8930AA, 144},
|
||||
{THERM_MSM_8930AA, 160},
|
||||
{THERM_MSM_8930AB, 154},
|
||||
{THERM_MSM_8930AB, 155},
|
||||
{THERM_MSM_8930AB, 156},
|
||||
{THERM_MSM_8930AB, 157},
|
||||
{THERM_MSM_8064, 109},
|
||||
{THERM_MSM_8064, 130},
|
||||
{THERM_MSM_8064AB, 153},
|
||||
{THERM_MSM_8X25, 90},
|
||||
{THERM_MSM_8X25, 91},
|
||||
{THERM_MSM_8X25, 92},
|
||||
{THERM_MSM_8X25, 97},
|
||||
{THERM_MSM_8974, 126},
|
||||
{THERM_IPQ_8062, 201},
|
||||
{THERM_IPQ_8064, 202},
|
||||
{THERM_IPQ_8066, 203},
|
||||
{THERM_IPQ_8068, 204},
|
||||
{THERM_IPQ_8065, 280},
|
||||
{THERM_IPQ_8069, 281},
|
||||
/* AC variants */
|
||||
{THERM_IPQ_8070, 375},
|
||||
{THERM_IPQ_8070A, 395},
|
||||
{THERM_IPQ_8071, 376},
|
||||
{THERM_IPQ_8071A, 396},
|
||||
/* HK variants */
|
||||
{THERM_IPQ_8072, 342},
|
||||
{THERM_IPQ_8072A, 389},
|
||||
{THERM_IPQ_8074, 323},
|
||||
{THERM_IPQ_8074A, 390},
|
||||
{THERM_IPQ_8076, 343},
|
||||
{THERM_IPQ_8076A, 391},
|
||||
{THERM_IPQ_8078, 344},
|
||||
{THERM_IPQ_8078A, 392},
|
||||
/* OAK variants */
|
||||
{THERM_IPQ_8172, 397},
|
||||
{THERM_IPQ_8173, 398},
|
||||
{THERM_IPQ_8174, 399},
|
||||
/* CP variants */
|
||||
{THERM_IPQ_6018, 402},
|
||||
{THERM_IPQ_6028, 403},
|
||||
{THERM_IPQ_6000, 421},
|
||||
{THERM_IPQ_6010, 422},
|
||||
};
|
||||
|
||||
int read_id_from_binary_file(char *path, size_t size) {
|
||||
FILE *fp;
|
||||
int ret;
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
if(!fread(&ret, size, 1, fp)) {
|
||||
ret = ferror(fp);
|
||||
}
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* returns platform id, or -errno if error */
|
||||
static int get_platform_id(void)
|
||||
{
|
||||
int ret = -1;
|
||||
char buf[UINT_BUF_MAX];
|
||||
if (!access(SYSFS_CPU_TYPE, F_OK)) {
|
||||
ret = read_id_from_binary_file(SYSFS_CPU_TYPE, sizeof(int));
|
||||
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
} else if (!access(SYSFS_PLATFORMID, F_OK)) {
|
||||
ret = read_line_from_file(SYSFS_PLATFORMID, buf, UINT_BUF_MAX);
|
||||
} else {
|
||||
ret = read_line_from_file(SYSFS_PLATFORMID_DEP, buf, UINT_BUF_MAX);
|
||||
}
|
||||
if (ret < 0) {
|
||||
msg("Error getting platform_id %d", ret);
|
||||
} else {
|
||||
ret = atoi(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum therm_msm_id therm_get_msm_id(void)
|
||||
{
|
||||
enum therm_msm_id ret_val = THERM_MSM_UNKNOWN;
|
||||
int idx;
|
||||
int soc_id = get_platform_id();
|
||||
|
||||
for (idx = 0 ; idx < ARRAY_SIZE(msm_soc_table); idx++) {
|
||||
if (soc_id == msm_soc_table[idx].soc_id) {
|
||||
ret_val = msm_soc_table[idx].msm_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION open_file
|
||||
|
||||
Utility function to open file.
|
||||
|
||||
ARGUMENTS
|
||||
path - pathname for file
|
||||
flags - file open flags
|
||||
|
||||
RETURN VALUE
|
||||
file descriptor on success,
|
||||
-1 on failure.
|
||||
===========================================================================*/
|
||||
static int open_file(char *path, int flags)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (!path) return -EINVAL;
|
||||
|
||||
rv = open(path, flags);
|
||||
if (rv < 0)
|
||||
rv = -errno;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION write_to_fd
|
||||
|
||||
Utility function to write to provided file descriptor.
|
||||
|
||||
ARGUMENTS
|
||||
fd - file descriptor
|
||||
buf - destination buffer to write to
|
||||
count - number of bytes to write to fd
|
||||
|
||||
RETURN VALUE
|
||||
number of bytes written on success, -errno on failure.
|
||||
===========================================================================*/
|
||||
static int write_to_fd(int fd, char *buf, size_t count)
|
||||
{
|
||||
ssize_t pos = 0;
|
||||
ssize_t rv = 0;
|
||||
|
||||
do {
|
||||
rv = write(fd, buf + pos, count - pos);
|
||||
if (rv < 0)
|
||||
return -errno;
|
||||
pos += rv;
|
||||
} while ((ssize_t)count > pos);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION read_line_from_file
|
||||
|
||||
Utility function to read characters from file and stores them in a string
|
||||
until (count-1) characters are read or either a newline or EOF is reached.
|
||||
|
||||
ARGUMENTS
|
||||
path - file path
|
||||
buf - destination buffer to read from
|
||||
count - max number of bytes to read from file
|
||||
|
||||
RETURN VALUE
|
||||
number of bytes read on success, -errno on failure.
|
||||
===========================================================================*/
|
||||
int read_line_from_file(char *path, char *buf, size_t count)
|
||||
{
|
||||
char * fgets_ret;
|
||||
FILE * fd;
|
||||
int rv;
|
||||
|
||||
fd = fopen(path, "r");
|
||||
if (fd == NULL)
|
||||
return -1;
|
||||
|
||||
fgets_ret = fgets(buf, count, fd);
|
||||
if (NULL != fgets_ret) {
|
||||
rv = strlen(buf);
|
||||
} else {
|
||||
rv = ferror(fd);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION write_to_file
|
||||
|
||||
Utility function to write to provided file path.
|
||||
|
||||
ARGUMENTS
|
||||
path - file path
|
||||
buf - destination buffer to write to
|
||||
count - number of bytes to write to file
|
||||
|
||||
RETURN VALUE
|
||||
number of bytes written on success, -errno on failure.
|
||||
===========================================================================*/
|
||||
int write_to_file(char *path, char *buf, size_t count)
|
||||
{
|
||||
int fd, rv;
|
||||
|
||||
fd = open_file(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
rv = write_to_fd(fd, buf, count);
|
||||
close(fd);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION connect_local_file_socket
|
||||
|
||||
Utility function to open and connect to local UNIX filesystem socket.
|
||||
|
||||
ARGUMENTS
|
||||
socket_name - name of local UNIX filesystem socket to be connected
|
||||
|
||||
RETURN VALUE
|
||||
Connected socket_fd on success,
|
||||
-1 on failure.
|
||||
===========================================================================*/
|
||||
static int connect_local_file_socket(char *socket_name)
|
||||
{
|
||||
int socket_fd = 0;
|
||||
struct sockaddr_un serv_addr;
|
||||
|
||||
socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (socket_fd < 0) {
|
||||
dbgmsg("socket error - %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
snprintf(serv_addr.sun_path, UNIX_PATH_MAX, "%s", socket_name);
|
||||
serv_addr.sun_family = AF_LOCAL;
|
||||
|
||||
if (connect(socket_fd, (struct sockaddr *) &serv_addr,
|
||||
sizeof(sa_family_t) + strlen(socket_name) ) != 0) {
|
||||
dbgmsg("connect error on %s - %s\n",
|
||||
socket_name, strerror(errno));
|
||||
close(socket_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return socket_fd;
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION connect_local_socket
|
||||
|
||||
Utility function to open and connect to abstract local UNIX socket.
|
||||
|
||||
ARGUMENTS
|
||||
socket_name - name of local UNIX socket to be connected in abstract
|
||||
socket namespace.
|
||||
|
||||
RETURN VALUE
|
||||
Connected socket_fd on success,
|
||||
-1 on failure.
|
||||
===========================================================================*/
|
||||
static int connect_local_socket(char *socket_name)
|
||||
{
|
||||
int socket_fd = 0;
|
||||
struct sockaddr_un serv_addr;
|
||||
|
||||
socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (socket_fd < 0) {
|
||||
dbgmsg("socket error - %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
snprintf(serv_addr.sun_path, UNIX_PATH_MAX, " %s", socket_name);
|
||||
serv_addr.sun_family = AF_LOCAL;
|
||||
/* abstract namespace socket starts with NULL char */
|
||||
serv_addr.sun_path[0] = '\0';
|
||||
|
||||
/* effective sockaddr_un size == sun_family + null-char + name len */
|
||||
if (connect(socket_fd, (struct sockaddr *) &serv_addr,
|
||||
sizeof(sa_family_t) + 1 + strlen(socket_name) ) != 0) {
|
||||
dbgmsg("connect error on %s - %s\n",
|
||||
socket_name, strerror(errno));
|
||||
close(socket_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return socket_fd;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION write_to_local_file_socket
|
||||
|
||||
Utility function to write to local filesystem UNIX socket.
|
||||
|
||||
ARGUMENTS
|
||||
socket_name - socket name to be written
|
||||
msg - message to be written on socket
|
||||
count - size of msg buffer to be written
|
||||
|
||||
RETURN VALUE
|
||||
Number of bytes written on success,
|
||||
-1 on failure.
|
||||
===========================================================================*/
|
||||
int write_to_local_file_socket(char *socket_name, char *msg, size_t count)
|
||||
{
|
||||
int socket_fd = 0;
|
||||
int rv;
|
||||
|
||||
if (minimum_mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_fd = connect_local_file_socket(socket_name);
|
||||
if (socket_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = write_to_fd(socket_fd, msg, count);
|
||||
close(socket_fd);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION write_to_local_socket
|
||||
|
||||
Utility function to write to abstract local UNIX socket.
|
||||
|
||||
ARGUMENTS
|
||||
socket_name - socket name to be written
|
||||
msg - message to be written on socket
|
||||
count - size of msg buffer to be written
|
||||
|
||||
RETURN VALUE
|
||||
Number of bytes written on success,
|
||||
-1 on failure.
|
||||
===========================================================================*/
|
||||
int write_to_local_socket(char *socket_name, char *msg, size_t count)
|
||||
{
|
||||
int socket_fd = 0;
|
||||
int rv;
|
||||
|
||||
if (minimum_mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_fd = connect_local_socket(socket_name);
|
||||
if (socket_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = write_to_fd(socket_fd, msg, count);
|
||||
close(socket_fd);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION get_tzn
|
||||
|
||||
Utility function to match a sensor name with thermal zone id.
|
||||
|
||||
ARGUMENTS
|
||||
sensor_name - name of sensor to match
|
||||
|
||||
RETURN VALUE
|
||||
Thermal zone id on success,
|
||||
-1 on failure.
|
||||
===========================================================================*/
|
||||
int get_tzn(char *sensor_name)
|
||||
{
|
||||
DIR *tdir = NULL;
|
||||
struct dirent *tdirent = NULL;
|
||||
int found = -1;
|
||||
int tzn = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
char cwd[MAX_PATH] = {0};
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd)))
|
||||
return found;
|
||||
|
||||
/* Change dir to read the entries. Doesnt work otherwise */
|
||||
if (chdir(THERMAL_SYSFS) != 0) {
|
||||
msg("Change directory failed: %s\n", THERMAL_SYSFS);
|
||||
return found;
|
||||
}
|
||||
|
||||
tdir = opendir(THERMAL_SYSFS);
|
||||
if (!tdir) {
|
||||
msg("Unable to open %s\n", THERMAL_SYSFS);
|
||||
return found;
|
||||
}
|
||||
|
||||
while ((tdirent = readdir(tdir))) {
|
||||
char buf[50];
|
||||
struct dirent *tzdirent;
|
||||
DIR *tzdir = NULL;
|
||||
|
||||
tzdir = opendir(tdirent->d_name);
|
||||
if (!tzdir)
|
||||
continue;
|
||||
while ((tzdirent = readdir(tzdir))) {
|
||||
if (strcmp(tzdirent->d_name, "type"))
|
||||
continue;
|
||||
snprintf(name, MAX_PATH, TZ_TYPE, tzn);
|
||||
dbgmsg("Opening %s\n", name);
|
||||
read_line_from_file(name, buf, sizeof(buf));
|
||||
buf[strlen(sensor_name)] = '\0';
|
||||
if (!strcmp(buf, sensor_name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
tzn++;
|
||||
}
|
||||
closedir(tzdir);
|
||||
if (found == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(tdir);
|
||||
|
||||
if (chdir(cwd) != 0) { /* Restore current working dir */
|
||||
msg("Restore directory failed: %s\n", cwd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (found == 1) {
|
||||
found = tzn;
|
||||
dbgmsg("Sensor %s found at tz: %d\n", sensor_name, tzn);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
sampling 1000
|
||||
|
||||
[PMIC_THERM]
|
||||
sampling 500000
|
||||
thresholds 25 30 50
|
||||
thresholds_clr 20 28 48
|
||||
actions none none none
|
||||
action_info 768000 368640 245760
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
sampling 5000
|
||||
|
||||
[pa_therm0]
|
||||
sampling 5000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 70 90 95 100 105 110 115 120
|
||||
thresholds_clr 67 85 90 95 100 105 110 115
|
||||
actions cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery shutdown
|
||||
action_info 1728000+0 1188000+0 810000+1 648000+1 540000+2 487000+2 384000+3 5000
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 70 90 95 100 105 110 115 120
|
||||
thresholds_clr 67 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1728000 1188000 810000 648000 540000 487000 384000 5000
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 70 90 95 100 105 110 115 120
|
||||
thresholds_clr 67 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1728000 1188000 810000 648000 540000 487000 384000 5000
|
||||
|
||||
[tsens_tz_sensor10]
|
||||
sampling 1000
|
||||
thresholds 70 90 95 100 105 110 115 120
|
||||
thresholds_clr 67 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1728000 1188000 810000 648000 540000 487000 384000 5000
|
||||
|
||||
[pm8821_tz]
|
||||
thresholds 107
|
||||
thresholds_clr 103
|
||||
actions cpu
|
||||
action_info 918000
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
sampling 5000
|
||||
|
||||
[pa_therm0]
|
||||
sampling 5000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 70
|
||||
thresholds_clr 67
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 70 85 90 95 100 105 110 120
|
||||
thresholds_clr 67 80 85 90 95 100 105 115
|
||||
actions cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery shutdown
|
||||
action_info 1890000+0 1674000+0 1350000+1 1026000+1 810000+2 594000+2 384000+3 5000
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 70 85 90 95 100 105 110 120
|
||||
thresholds_clr 67 80 85 90 95 100 105 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1890000 1674000 1350000 1026000 810000 594000 384000 5000
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 70 85 90 95 100 105 110 120
|
||||
thresholds_clr 67 80 85 90 95 100 105 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1890000 1674000 1350000 1026000 810000 594000 384000 5000
|
||||
|
||||
[tsens_tz_sensor10]
|
||||
sampling 1000
|
||||
thresholds 70 85 90 95 100 105 110 120
|
||||
thresholds_clr 67 80 85 90 95 100 105 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1890000 1674000 1350000 1026000 810000 594000 384000 5000
|
||||
|
||||
[pm8821_tz]
|
||||
thresholds 107
|
||||
thresholds_clr 103
|
||||
actions cpu
|
||||
action_info 918000
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
sampling 1000
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 500000
|
||||
thresholds 25 30 50
|
||||
thresholds_clr 20 28 48
|
||||
actions none none none
|
||||
action_info 768000 368640 245760
|
||||
|
||||
[pm8058_tz]
|
||||
sampling 500000
|
||||
thresholds 25 30 50
|
||||
thresholds_clr 20 28 48
|
||||
actions none none none
|
||||
action_info 768000 368640 245760
|
||||
@@ -1,79 +0,0 @@
|
||||
sampling 5000
|
||||
|
||||
[pa_therm0]
|
||||
sampling 100000
|
||||
thresholds 65 70 75 80 85 90
|
||||
thresholds_clr 60 65 70 75 80 85
|
||||
actions none none none none none none
|
||||
action_info 0 0 0 0 0 0
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1404000 1296000 1188000 918000 756000 648000 384000 5000
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
sampling 5000
|
||||
|
||||
[pa_therm0]
|
||||
sampling 100000
|
||||
thresholds 65 70 75 80 85 90
|
||||
thresholds_clr 60 65 70 75 80 85
|
||||
actions none none none none none none
|
||||
action_info 0 0 0 0 0 0
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 60
|
||||
thresholds_clr 57
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1728000 1404000 1296000 1188000 918000 756000 648000 5000
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
sampling 5000
|
||||
|
||||
[pa_therm0]
|
||||
sampling 100000
|
||||
thresholds 65 70 75 80 85 90
|
||||
thresholds_clr 60 65 70 75 80 85
|
||||
actions none none none none none none
|
||||
action_info 0 0 0 0 0 0
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 65 90 93 96 99 102 105
|
||||
thresholds_clr 62 87 90 93 96 99 102
|
||||
actions cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1296000 1188000 918000 756000 648000 5000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 75
|
||||
thresholds_clr 72
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 75
|
||||
thresholds_clr 72
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 75 78 81 84 87 90
|
||||
thresholds_clr 72 75 78 81 84 87
|
||||
actions cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1296000 1188000 918000 756000 648000 5000
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 75
|
||||
thresholds_clr 72
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
sampling 5000
|
||||
|
||||
[pa_therm0]
|
||||
sampling 100000
|
||||
thresholds 65 70 75 80 85 90
|
||||
thresholds_clr 60 65 70 75 80 85
|
||||
actions none none none none none none
|
||||
action_info 0 0 0 0 0 0
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 65 87 90 93 96 99 102 105
|
||||
thresholds_clr 62 84 87 90 93 96 99 102
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1728000 1512000 1296000 1188000 918000 756000 648000 5000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 75
|
||||
thresholds_clr 72
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 75
|
||||
thresholds_clr 72
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 75 78 81 84 87 90
|
||||
thresholds_clr 72 75 78 81 84 87
|
||||
actions cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1296000 1188000 918000 756000 648000 5000
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 75
|
||||
thresholds_clr 72
|
||||
actions none
|
||||
action_info 0
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
debug
|
||||
sampling 5000
|
||||
|
||||
[tsens_tz_sensor0]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor1]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor2]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor3]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor4]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor5]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor6]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor7]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor8]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor9]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
[tsens_tz_sensor10]
|
||||
sampling 1000
|
||||
thresholds 60 90 95 100 105 110 115 120
|
||||
thresholds_clr 57 85 90 95 100 105 110 115
|
||||
actions cpu cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
debug
|
||||
sampling 1000
|
||||
|
||||
[PMIC_THERM]
|
||||
sampling 1000
|
||||
thresholds 40 45 50 55 85
|
||||
thresholds_clr 37 42 47 52 82
|
||||
actions cpu cpu cpu cpu shutdown
|
||||
action_info 1008000 600000 480000 245760 5000
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
debug
|
||||
sampling 1000
|
||||
|
||||
[MSM_THERM]
|
||||
sampling 1000
|
||||
thresholds 30 50 53 56 59 62 70
|
||||
thresholds_clr 27 47 50 53 56 59 68
|
||||
actions cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1401600 1209600 1000800 700800 480000 320000 5
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
debug
|
||||
sampling 1000
|
||||
|
||||
[PMIC_THERM]
|
||||
sampling 1000
|
||||
thresholds 30 55 57 59 62 65 70
|
||||
thresholds_clr 27 52 55 57 59 62 65
|
||||
actions cpu cpu cpu cpu cpu cpu shutdown
|
||||
action_info 1401600 1209600 1000800 700800 480000 320000 5
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
sampling 1000
|
||||
|
||||
[PMIC_THERM]
|
||||
sampling 5000
|
||||
thresholds 40.2 45 50
|
||||
thresholds_clr 38 43 48
|
||||
actions report cpu cpu
|
||||
action_info 768000 368640 245760
|
||||
|
||||
[XO_THERM]
|
||||
sampling 5000
|
||||
thresholds 40.1 45 90
|
||||
thresholds_clr 38 43 88
|
||||
actions cpu cpu shutdown
|
||||
action_info 768000 368640 245760
|
||||
|
||||
[XO_THERM_GPS]
|
||||
sampling 5000
|
||||
thresholds 27.0 45 50
|
||||
thresholds_clr 26.5 43 48
|
||||
actions report cpu cpu
|
||||
action_info 768000 368640 245760
|
||||
@@ -1,408 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
tsens-sensor.c
|
||||
|
||||
DESCRIPTION
|
||||
TSENS sensor access functions.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
setup() function should be called before get_temperature().
|
||||
shutdown() function should be called to clean up resources.
|
||||
|
||||
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "tsens-sensor.h"
|
||||
#include "thermal.h"
|
||||
|
||||
#define LVL_BUF_MAX (12)
|
||||
|
||||
#define TSENS_TZ_TRIP_TYPE "/sys/devices/virtual/thermal/thermal_zone%d/trip_point_%d_type"
|
||||
#define TSENS_TZ_TRIP_TEMP "/sys/devices/virtual/thermal/thermal_zone%d/trip_point_%d_temp"
|
||||
|
||||
#ifdef SENSORS_8974
|
||||
#define TRIP_MAX 0 /* Trip point 0 is the high temperature */
|
||||
#define TRIP_MIN 1 /* Trip point 1 is the low temperature */
|
||||
#else
|
||||
#define TRIP_MAX 1 /* Trip point 1 is the high temperature */
|
||||
#define TRIP_MIN 2 /* Trip point 2 is the low temperature */
|
||||
#endif
|
||||
|
||||
typedef struct tsens_data {
|
||||
pthread_t tsens_thread;
|
||||
pthread_mutex_t tsens_mutex;
|
||||
pthread_cond_t tsens_condition;
|
||||
int threshold_reached;
|
||||
int hi_threshold, lo_threshold;
|
||||
int hi_idx, lo_idx;
|
||||
int sensor_shutdown;
|
||||
sensor_t *sensor;
|
||||
} tsens_data;
|
||||
|
||||
static void *tsens_uevent(void *data)
|
||||
{
|
||||
int err = 0;
|
||||
sensor_t *sensor = (sensor_t *)data;
|
||||
struct pollfd fds;
|
||||
int fd;
|
||||
char uevent[MAX_PATH] = {0};
|
||||
char buf[MAX_PATH] = {0};
|
||||
tsens_data *tsens = NULL;
|
||||
|
||||
if (NULL == sensor ||
|
||||
NULL == sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return NULL;
|
||||
}
|
||||
tsens = (tsens_data *) sensor->data;
|
||||
|
||||
/* Looking for tsens uevent */
|
||||
snprintf(uevent, MAX_PATH, TZ_TYPE, sensor->tzn);
|
||||
|
||||
fd = open(uevent, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("Unable to open %s to receive notifications.\n", uevent);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
while (!tsens->sensor_shutdown) {
|
||||
fds.fd = fd;
|
||||
fds.events = POLLERR|POLLPRI;
|
||||
fds.revents = 0;
|
||||
|
||||
err = poll(&fds, 1, -1);
|
||||
if (err == -1) {
|
||||
msg("Error in uevent poll.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (read(fd, buf, sizeof(buf)) < 0) {
|
||||
dbgmsg("TSENS uevent read failed\n");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
dbgmsg("TSENS uevent :%s", buf);
|
||||
|
||||
/* notify the waiting threads */
|
||||
pthread_mutex_lock(&(tsens->tsens_mutex));
|
||||
tsens->threshold_reached = 1;
|
||||
pthread_cond_broadcast(&(tsens->tsens_condition));
|
||||
pthread_mutex_unlock(&(tsens->tsens_mutex));
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void enable_sensor(int tzn , int enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
|
||||
snprintf( name, MAX_PATH, TZ_MODE, tzn );
|
||||
if (enabled)
|
||||
ret = write_to_file(name, "enabled", strlen("enabled"));
|
||||
else
|
||||
ret = write_to_file(name, "disabled", strlen("disabled"));
|
||||
|
||||
if (ret <= 0) {
|
||||
msg("TSENS tzn %d failed to set mode %d\n", tzn, enabled);
|
||||
} else {
|
||||
dbgmsg("TSENS tzn %d mode set to %d\n", tzn, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_threshold(tsens_data *tsens, int trip, int enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
|
||||
if (NULL == tsens ||
|
||||
NULL == tsens->sensor) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(name, MAX_PATH, TSENS_TZ_TRIP_TYPE, tsens->sensor->tzn, trip);
|
||||
if (enabled)
|
||||
ret = write_to_file(name, "enabled", strlen("enabled"));
|
||||
else
|
||||
ret = write_to_file(name, "disabled", strlen("disabled"));
|
||||
|
||||
if (ret <= 0) {
|
||||
msg("TSENS threshold at %d failed to %d\n", trip, enabled);
|
||||
} else {
|
||||
dbgmsg("TSENS threshold at %d enabled: %d\n", trip, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_thresholds(tsens_data *tsens, int lvl, int lvl_clr,
|
||||
int hi_enable, int lo_enable)
|
||||
{
|
||||
char minname[MAX_PATH]= {0};
|
||||
char maxname[MAX_PATH]= {0};
|
||||
char buf[LVL_BUF_MAX] = {0};
|
||||
int ret = 0;
|
||||
int mintemp = 0;
|
||||
|
||||
if (NULL == tsens) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(minname, MAX_PATH, TSENS_TZ_TRIP_TEMP, tsens->sensor->tzn, TRIP_MIN);
|
||||
snprintf(maxname, MAX_PATH, TSENS_TZ_TRIP_TEMP, tsens->sensor->tzn, TRIP_MAX);
|
||||
|
||||
/* Set thresholds in legal order */
|
||||
if (read_line_from_file(minname, buf, sizeof(buf)) > 0) {
|
||||
mintemp = atoi(buf);
|
||||
}
|
||||
|
||||
if (lvl >= mintemp) {
|
||||
/* set high threshold first */
|
||||
dbgmsg("Setting up TSENS thresholds high: %d\n", lvl);
|
||||
enable_threshold(tsens, TRIP_MAX, hi_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
|
||||
ret = write_to_file(maxname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("TSENS threshold high failed to set %d\n", lvl);
|
||||
|
||||
dbgmsg("Setting up TSENS thresholds low: %d\n", lvl_clr);
|
||||
enable_threshold(tsens, TRIP_MIN, lo_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
|
||||
ret = write_to_file(minname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("TSENS threshold low failed to set %d\n", lvl_clr);
|
||||
|
||||
} else {
|
||||
dbgmsg("Setting up TSENS thresholds low: %d\n", lvl_clr);
|
||||
enable_threshold(tsens, TRIP_MIN, lo_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
|
||||
ret = write_to_file(minname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("TSENS threshold low failed to set %d\n", lvl_clr);
|
||||
|
||||
dbgmsg("Setting up TSENS thresholds high: %d\n", lvl);
|
||||
enable_threshold(tsens, TRIP_MAX, hi_enable);
|
||||
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
|
||||
ret = write_to_file(maxname, buf, strlen(buf));
|
||||
if (ret <= 0)
|
||||
msg("TSENS threshold high failed to set %d\n", lvl);
|
||||
}
|
||||
|
||||
tsens->hi_threshold = lvl;
|
||||
tsens->lo_threshold = lvl_clr;
|
||||
}
|
||||
|
||||
void tsens_sensor_enable_thresholds(sensor_setting_t *setting, int hi_enabled,
|
||||
int lo_enabled)
|
||||
{
|
||||
#ifdef ENABLE_TSENS_INTERRUPT
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("tsens: unexpected NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
enable_threshold(setting->sensor->data, TRIP_MAX, hi_enabled);
|
||||
enable_threshold(setting->sensor->data, TRIP_MIN, lo_enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef IPQ_806x
|
||||
void tsens_sensor_enable_sensor(int tzn, int enabled)
|
||||
{
|
||||
if ( (0 >= tzn) && (SENSOR_IDX_MAX <= tzn) ){
|
||||
msg("%s: Invalid sensor id = %d\n" , __func__ , tzn );
|
||||
return;
|
||||
}
|
||||
|
||||
enable_sensor(tzn, enabled);
|
||||
}
|
||||
#else
|
||||
void tsens_sensor_enable_sensor(sensor_setting_t *setting, int enabled)
|
||||
{
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("tsens: unexpected NULL");
|
||||
return;
|
||||
}
|
||||
tsens_data *tsens = setting->sensor->data;
|
||||
enable_sensor( tsens->sensor->tzn, enabled);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* NOTE: tsens_sensors_setup() function does not enable the sensor
|
||||
* or set thresholds. This should be done in the target-specific setup */
|
||||
int tsens_sensors_setup(sensor_setting_t *setting, sensor_t *sensor)
|
||||
{
|
||||
int fd = -1;
|
||||
int sensor_count = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
int tzn = 0;
|
||||
tsens_data *tsens = NULL;
|
||||
|
||||
/* We have nothing to do if there are no thresholds */
|
||||
if (!setting->num_thresholds) {
|
||||
dbgmsg("No thresholds for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
tzn = get_tzn(sensor->name);
|
||||
if (tzn < 0) {
|
||||
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
|
||||
return sensor_count;
|
||||
}
|
||||
sensor->tzn = tzn;
|
||||
|
||||
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
msg("%s: Error opening %s\n", __func__, TZ_TEMP);
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
/* Allocate TSENS data */
|
||||
tsens = (tsens_data *) malloc(sizeof(tsens_data));
|
||||
if (NULL == tsens) {
|
||||
msg("%s: malloc failed", __func__);
|
||||
close(fd);
|
||||
return sensor_count;
|
||||
}
|
||||
memset(tsens, 0, sizeof(tsens_data));
|
||||
sensor->data = (void *) tsens;
|
||||
|
||||
sensor_count++;
|
||||
pthread_mutex_init(&(tsens->tsens_mutex), NULL);
|
||||
pthread_cond_init(&(tsens->tsens_condition), NULL);
|
||||
tsens->sensor_shutdown = 0;
|
||||
tsens->threshold_reached = 0;
|
||||
tsens->sensor = sensor;
|
||||
setting->disabled = 0;
|
||||
setting->chan_idx = fd;
|
||||
|
||||
if (sensor->interrupt_enable) {
|
||||
pthread_create(&(tsens->tsens_thread), NULL,
|
||||
tsens_uevent, sensor);
|
||||
}
|
||||
|
||||
return sensor_count;
|
||||
}
|
||||
|
||||
void tsens_sensors_shutdown(sensor_setting_t *setting)
|
||||
{
|
||||
tsens_data *tsens;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
tsens = (tsens_data *) setting->sensor->data;
|
||||
tsens->sensor_shutdown = 1;
|
||||
|
||||
if (setting->chan_idx > 0)
|
||||
close(setting->chan_idx);
|
||||
|
||||
if (setting->sensor->interrupt_enable)
|
||||
pthread_join(tsens->tsens_thread, NULL);
|
||||
free(tsens);
|
||||
}
|
||||
|
||||
int tsens_sensor_get_temperature(sensor_setting_t *setting)
|
||||
{
|
||||
char buf[10] = {0};
|
||||
int temp = 0;
|
||||
|
||||
if (NULL == setting) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1)
|
||||
temp = atoi(buf);
|
||||
lseek(setting->chan_idx, 0, SEEK_SET);
|
||||
|
||||
return CONV(temp);
|
||||
}
|
||||
|
||||
void tsens_sensor_interrupt_wait(sensor_setting_t *setting)
|
||||
{
|
||||
tsens_data *tsens;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if (setting->sensor->interrupt_enable) {
|
||||
tsens = (tsens_data *) setting->sensor->data;
|
||||
/* Wait for sensor threshold condition */
|
||||
pthread_mutex_lock(&(tsens->tsens_mutex));
|
||||
while (!tsens->threshold_reached) {
|
||||
pthread_cond_wait(&(tsens->tsens_condition),
|
||||
&(tsens->tsens_mutex));
|
||||
}
|
||||
tsens->threshold_reached = 0;
|
||||
pthread_mutex_unlock(&(tsens->tsens_mutex));
|
||||
}
|
||||
}
|
||||
|
||||
void tsens_sensor_update_thresholds(sensor_setting_t *setting,
|
||||
int threshold_type, int level)
|
||||
{
|
||||
int hi, lo;
|
||||
int hi_enable = 1;
|
||||
int lo_enable = 1;
|
||||
tsens_data *tsens;
|
||||
|
||||
if (NULL == setting ||
|
||||
NULL == setting->sensor ||
|
||||
NULL == setting->sensor->data) {
|
||||
msg("%s: unexpected NULL", __func__);
|
||||
return;
|
||||
}
|
||||
tsens = (tsens_data *) setting->sensor->data;
|
||||
|
||||
dbgmsg("%s: threshold_type %d, level %d", __func__,
|
||||
threshold_type, level);
|
||||
hi = RCONV(setting->t[tsens->hi_idx].lvl_trig);
|
||||
lo = RCONV(setting->t[tsens->lo_idx].lvl_clr);
|
||||
if (level >= setting->num_thresholds) {
|
||||
/* handle corner high case */
|
||||
hi = RCONV(setting->t[setting->num_thresholds - 1].lvl_trig);
|
||||
tsens->hi_idx = setting->num_thresholds - 1;
|
||||
hi_enable = 0;
|
||||
} else {
|
||||
hi = RCONV(setting->t[level].lvl_trig);
|
||||
tsens->hi_idx = level;
|
||||
}
|
||||
if (level <= 0) {
|
||||
/* handle corner low case */
|
||||
lo = RCONV(setting->t[0].lvl_clr);
|
||||
tsens->lo_idx = 0;
|
||||
lo_enable = 0;
|
||||
} else {
|
||||
lo = RCONV(setting->t[level - 1].lvl_clr);
|
||||
tsens->lo_idx = level - 1;
|
||||
}
|
||||
|
||||
set_thresholds(tsens, hi, lo, hi_enable, lo_enable);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*===========================================================================
|
||||
|
||||
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
|
||||
Qualcomm Technologies Proprietary and Confidential.
|
||||
|
||||
===========================================================================*/
|
||||
#ifndef __TSENS_SENSOR_H__
|
||||
#define __TSENS_SENSOR_H__
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
int tsens_sensors_setup(sensor_setting_t *settings, sensor_t * sensor);
|
||||
void tsens_sensors_shutdown(sensor_setting_t *setting);
|
||||
int tsens_sensor_get_temperature(sensor_setting_t *setting);
|
||||
void tsens_sensor_interrupt_wait(sensor_setting_t *setting);
|
||||
void tsens_sensor_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
|
||||
void tsens_sensor_enable_thresholds(sensor_setting_t *setting, int hi_enabled, int lo_enabled);
|
||||
|
||||
#ifndef IPQ_806x
|
||||
void tsens_sensor_enable_sensor(sensor_setting_t *setting, int enabled);
|
||||
#else
|
||||
void tsens_sensor_enable_sensor(int tzn, int enabled);
|
||||
#endif
|
||||
|
||||
#endif /* __TSENS_SENSOR_H__ */
|
||||
Reference in New Issue
Block a user