1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "[email protected]"
18*4d7e907cSAndroid Build Coastguard Worker
19*4d7e907cSAndroid Build Coastguard Worker #include <errno.h>
20*4d7e907cSAndroid Build Coastguard Worker #include <math.h>
21*4d7e907cSAndroid Build Coastguard Worker
22*4d7e907cSAndroid Build Coastguard Worker #include <vector>
23*4d7e907cSAndroid Build Coastguard Worker
24*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h>
25*4d7e907cSAndroid Build Coastguard Worker
26*4d7e907cSAndroid Build Coastguard Worker #include <hardware/hardware.h>
27*4d7e907cSAndroid Build Coastguard Worker #include <hardware/thermal.h>
28*4d7e907cSAndroid Build Coastguard Worker
29*4d7e907cSAndroid Build Coastguard Worker #include "Thermal.h"
30*4d7e907cSAndroid Build Coastguard Worker
31*4d7e907cSAndroid Build Coastguard Worker namespace android {
32*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
33*4d7e907cSAndroid Build Coastguard Worker namespace thermal {
34*4d7e907cSAndroid Build Coastguard Worker namespace V1_0 {
35*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
36*4d7e907cSAndroid Build Coastguard Worker
37*4d7e907cSAndroid Build Coastguard Worker namespace {
38*4d7e907cSAndroid Build Coastguard Worker
finalizeTemperature(float temperature)39*4d7e907cSAndroid Build Coastguard Worker float finalizeTemperature(float temperature) {
40*4d7e907cSAndroid Build Coastguard Worker return temperature == UNKNOWN_TEMPERATURE ? NAN : temperature;
41*4d7e907cSAndroid Build Coastguard Worker }
42*4d7e907cSAndroid Build Coastguard Worker
43*4d7e907cSAndroid Build Coastguard Worker }
44*4d7e907cSAndroid Build Coastguard Worker
Thermal(thermal_module_t * module)45*4d7e907cSAndroid Build Coastguard Worker Thermal::Thermal(thermal_module_t* module) : mModule(module) {}
46*4d7e907cSAndroid Build Coastguard Worker
47*4d7e907cSAndroid Build Coastguard Worker // Methods from ::android::hardware::thermal::V1_0::IThermal follow.
getTemperatures(getTemperatures_cb _hidl_cb)48*4d7e907cSAndroid Build Coastguard Worker Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) {
49*4d7e907cSAndroid Build Coastguard Worker ThermalStatus status;
50*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::SUCCESS;
51*4d7e907cSAndroid Build Coastguard Worker hidl_vec<Temperature> temperatures;
52*4d7e907cSAndroid Build Coastguard Worker
53*4d7e907cSAndroid Build Coastguard Worker if (!mModule || !mModule->getTemperatures) {
54*4d7e907cSAndroid Build Coastguard Worker ALOGI("getTemperatures is not implemented in Thermal HAL.");
55*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, temperatures);
56*4d7e907cSAndroid Build Coastguard Worker return Void();
57*4d7e907cSAndroid Build Coastguard Worker }
58*4d7e907cSAndroid Build Coastguard Worker
59*4d7e907cSAndroid Build Coastguard Worker ssize_t size = mModule->getTemperatures(mModule, nullptr, 0);
60*4d7e907cSAndroid Build Coastguard Worker if (size >= 0) {
61*4d7e907cSAndroid Build Coastguard Worker std::vector<temperature_t> list;
62*4d7e907cSAndroid Build Coastguard Worker list.resize(size);
63*4d7e907cSAndroid Build Coastguard Worker size = mModule->getTemperatures(mModule, list.data(), list.size());
64*4d7e907cSAndroid Build Coastguard Worker if (size >= 0) {
65*4d7e907cSAndroid Build Coastguard Worker temperatures.resize(list.size());
66*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < list.size(); ++i) {
67*4d7e907cSAndroid Build Coastguard Worker switch (list[i].type) {
68*4d7e907cSAndroid Build Coastguard Worker case DEVICE_TEMPERATURE_UNKNOWN:
69*4d7e907cSAndroid Build Coastguard Worker temperatures[i].type = TemperatureType::UNKNOWN;
70*4d7e907cSAndroid Build Coastguard Worker break;
71*4d7e907cSAndroid Build Coastguard Worker case DEVICE_TEMPERATURE_CPU:
72*4d7e907cSAndroid Build Coastguard Worker temperatures[i].type = TemperatureType::CPU;
73*4d7e907cSAndroid Build Coastguard Worker break;
74*4d7e907cSAndroid Build Coastguard Worker case DEVICE_TEMPERATURE_GPU:
75*4d7e907cSAndroid Build Coastguard Worker temperatures[i].type = TemperatureType::GPU;
76*4d7e907cSAndroid Build Coastguard Worker break;
77*4d7e907cSAndroid Build Coastguard Worker case DEVICE_TEMPERATURE_BATTERY:
78*4d7e907cSAndroid Build Coastguard Worker temperatures[i].type = TemperatureType::BATTERY;
79*4d7e907cSAndroid Build Coastguard Worker break;
80*4d7e907cSAndroid Build Coastguard Worker case DEVICE_TEMPERATURE_SKIN:
81*4d7e907cSAndroid Build Coastguard Worker temperatures[i].type = TemperatureType::SKIN;
82*4d7e907cSAndroid Build Coastguard Worker break;
83*4d7e907cSAndroid Build Coastguard Worker default:
84*4d7e907cSAndroid Build Coastguard Worker ALOGE("Unknown temperature %s type", list[i].name);
85*4d7e907cSAndroid Build Coastguard Worker ;
86*4d7e907cSAndroid Build Coastguard Worker }
87*4d7e907cSAndroid Build Coastguard Worker temperatures[i].name = list[i].name;
88*4d7e907cSAndroid Build Coastguard Worker temperatures[i].currentValue = finalizeTemperature(list[i].current_value);
89*4d7e907cSAndroid Build Coastguard Worker temperatures[i].throttlingThreshold = finalizeTemperature(list[i].throttling_threshold);
90*4d7e907cSAndroid Build Coastguard Worker temperatures[i].shutdownThreshold = finalizeTemperature(list[i].shutdown_threshold);
91*4d7e907cSAndroid Build Coastguard Worker temperatures[i].vrThrottlingThreshold =
92*4d7e907cSAndroid Build Coastguard Worker finalizeTemperature(list[i].vr_throttling_threshold);
93*4d7e907cSAndroid Build Coastguard Worker }
94*4d7e907cSAndroid Build Coastguard Worker }
95*4d7e907cSAndroid Build Coastguard Worker }
96*4d7e907cSAndroid Build Coastguard Worker if (size < 0) {
97*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::FAILURE;
98*4d7e907cSAndroid Build Coastguard Worker status.debugMessage = strerror(-size);
99*4d7e907cSAndroid Build Coastguard Worker }
100*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, temperatures);
101*4d7e907cSAndroid Build Coastguard Worker return Void();
102*4d7e907cSAndroid Build Coastguard Worker }
103*4d7e907cSAndroid Build Coastguard Worker
getCpuUsages(getCpuUsages_cb _hidl_cb)104*4d7e907cSAndroid Build Coastguard Worker Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) {
105*4d7e907cSAndroid Build Coastguard Worker ThermalStatus status;
106*4d7e907cSAndroid Build Coastguard Worker hidl_vec<CpuUsage> cpuUsages;
107*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::SUCCESS;
108*4d7e907cSAndroid Build Coastguard Worker
109*4d7e907cSAndroid Build Coastguard Worker if (!mModule || !mModule->getCpuUsages) {
110*4d7e907cSAndroid Build Coastguard Worker ALOGI("getCpuUsages is not implemented in Thermal HAL");
111*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, cpuUsages);
112*4d7e907cSAndroid Build Coastguard Worker return Void();
113*4d7e907cSAndroid Build Coastguard Worker }
114*4d7e907cSAndroid Build Coastguard Worker
115*4d7e907cSAndroid Build Coastguard Worker ssize_t size = mModule->getCpuUsages(mModule, nullptr);
116*4d7e907cSAndroid Build Coastguard Worker if (size >= 0) {
117*4d7e907cSAndroid Build Coastguard Worker std::vector<cpu_usage_t> list;
118*4d7e907cSAndroid Build Coastguard Worker list.resize(size);
119*4d7e907cSAndroid Build Coastguard Worker size = mModule->getCpuUsages(mModule, list.data());
120*4d7e907cSAndroid Build Coastguard Worker if (size >= 0) {
121*4d7e907cSAndroid Build Coastguard Worker list.resize(size);
122*4d7e907cSAndroid Build Coastguard Worker cpuUsages.resize(size);
123*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < list.size(); ++i) {
124*4d7e907cSAndroid Build Coastguard Worker cpuUsages[i].name = list[i].name;
125*4d7e907cSAndroid Build Coastguard Worker cpuUsages[i].active = list[i].active;
126*4d7e907cSAndroid Build Coastguard Worker cpuUsages[i].total = list[i].total;
127*4d7e907cSAndroid Build Coastguard Worker cpuUsages[i].isOnline = list[i].is_online;
128*4d7e907cSAndroid Build Coastguard Worker }
129*4d7e907cSAndroid Build Coastguard Worker } else {
130*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::FAILURE;
131*4d7e907cSAndroid Build Coastguard Worker status.debugMessage = strerror(-size);
132*4d7e907cSAndroid Build Coastguard Worker }
133*4d7e907cSAndroid Build Coastguard Worker }
134*4d7e907cSAndroid Build Coastguard Worker if (size < 0) {
135*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::FAILURE;
136*4d7e907cSAndroid Build Coastguard Worker status.debugMessage = strerror(-size);
137*4d7e907cSAndroid Build Coastguard Worker }
138*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, cpuUsages);
139*4d7e907cSAndroid Build Coastguard Worker return Void();
140*4d7e907cSAndroid Build Coastguard Worker }
141*4d7e907cSAndroid Build Coastguard Worker
getCoolingDevices(getCoolingDevices_cb _hidl_cb)142*4d7e907cSAndroid Build Coastguard Worker Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) {
143*4d7e907cSAndroid Build Coastguard Worker ThermalStatus status;
144*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::SUCCESS;
145*4d7e907cSAndroid Build Coastguard Worker hidl_vec<CoolingDevice> coolingDevices;
146*4d7e907cSAndroid Build Coastguard Worker
147*4d7e907cSAndroid Build Coastguard Worker if (!mModule || !mModule->getCoolingDevices) {
148*4d7e907cSAndroid Build Coastguard Worker ALOGI("getCoolingDevices is not implemented in Thermal HAL.");
149*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, coolingDevices);
150*4d7e907cSAndroid Build Coastguard Worker return Void();
151*4d7e907cSAndroid Build Coastguard Worker }
152*4d7e907cSAndroid Build Coastguard Worker
153*4d7e907cSAndroid Build Coastguard Worker ssize_t size = mModule->getCoolingDevices(mModule, nullptr, 0);
154*4d7e907cSAndroid Build Coastguard Worker if (size >= 0) {
155*4d7e907cSAndroid Build Coastguard Worker std::vector<cooling_device_t> list;
156*4d7e907cSAndroid Build Coastguard Worker list.resize(size);
157*4d7e907cSAndroid Build Coastguard Worker size = mModule->getCoolingDevices(mModule, list.data(), list.size());
158*4d7e907cSAndroid Build Coastguard Worker if (size >= 0) {
159*4d7e907cSAndroid Build Coastguard Worker list.resize(size);
160*4d7e907cSAndroid Build Coastguard Worker coolingDevices.resize(list.size());
161*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < list.size(); ++i) {
162*4d7e907cSAndroid Build Coastguard Worker switch (list[i].type) {
163*4d7e907cSAndroid Build Coastguard Worker case FAN_RPM:
164*4d7e907cSAndroid Build Coastguard Worker coolingDevices[i].type = CoolingType::FAN_RPM;
165*4d7e907cSAndroid Build Coastguard Worker break;
166*4d7e907cSAndroid Build Coastguard Worker default:
167*4d7e907cSAndroid Build Coastguard Worker ALOGE("Unknown cooling device %s type", list[i].name);
168*4d7e907cSAndroid Build Coastguard Worker }
169*4d7e907cSAndroid Build Coastguard Worker coolingDevices[i].name = list[i].name;
170*4d7e907cSAndroid Build Coastguard Worker coolingDevices[i].currentValue = list[i].current_value;
171*4d7e907cSAndroid Build Coastguard Worker }
172*4d7e907cSAndroid Build Coastguard Worker }
173*4d7e907cSAndroid Build Coastguard Worker }
174*4d7e907cSAndroid Build Coastguard Worker if (size < 0) {
175*4d7e907cSAndroid Build Coastguard Worker status.code = ThermalStatusCode::FAILURE;
176*4d7e907cSAndroid Build Coastguard Worker status.debugMessage = strerror(-size);
177*4d7e907cSAndroid Build Coastguard Worker }
178*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(status, coolingDevices);
179*4d7e907cSAndroid Build Coastguard Worker return Void();
180*4d7e907cSAndroid Build Coastguard Worker }
181*4d7e907cSAndroid Build Coastguard Worker
HIDL_FETCH_IThermal(const char *)182*4d7e907cSAndroid Build Coastguard Worker IThermal* HIDL_FETCH_IThermal(const char* /* name */) {
183*4d7e907cSAndroid Build Coastguard Worker thermal_module_t* module;
184*4d7e907cSAndroid Build Coastguard Worker status_t err = hw_get_module(THERMAL_HARDWARE_MODULE_ID,
185*4d7e907cSAndroid Build Coastguard Worker const_cast<hw_module_t const**>(
186*4d7e907cSAndroid Build Coastguard Worker reinterpret_cast<hw_module_t**>(&module)));
187*4d7e907cSAndroid Build Coastguard Worker if (err || !module) {
188*4d7e907cSAndroid Build Coastguard Worker ALOGE("Couldn't load %s module (%s)", THERMAL_HARDWARE_MODULE_ID,
189*4d7e907cSAndroid Build Coastguard Worker strerror(-err));
190*4d7e907cSAndroid Build Coastguard Worker }
191*4d7e907cSAndroid Build Coastguard Worker
192*4d7e907cSAndroid Build Coastguard Worker if (err == 0 && module->common.methods->open) {
193*4d7e907cSAndroid Build Coastguard Worker struct hw_device_t* device;
194*4d7e907cSAndroid Build Coastguard Worker err = module->common.methods->open(&module->common,
195*4d7e907cSAndroid Build Coastguard Worker THERMAL_HARDWARE_MODULE_ID, &device);
196*4d7e907cSAndroid Build Coastguard Worker if (err) {
197*4d7e907cSAndroid Build Coastguard Worker ALOGE("Couldn't open %s module (%s)", THERMAL_HARDWARE_MODULE_ID,
198*4d7e907cSAndroid Build Coastguard Worker strerror(-err));
199*4d7e907cSAndroid Build Coastguard Worker } else {
200*4d7e907cSAndroid Build Coastguard Worker return new Thermal(reinterpret_cast<thermal_module_t*>(device));
201*4d7e907cSAndroid Build Coastguard Worker }
202*4d7e907cSAndroid Build Coastguard Worker }
203*4d7e907cSAndroid Build Coastguard Worker return new Thermal(module);
204*4d7e907cSAndroid Build Coastguard Worker }
205*4d7e907cSAndroid Build Coastguard Worker
206*4d7e907cSAndroid Build Coastguard Worker } // namespace implementation
207*4d7e907cSAndroid Build Coastguard Worker } // namespace V1_0
208*4d7e907cSAndroid Build Coastguard Worker } // namespace thermal
209*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware
210*4d7e907cSAndroid Build Coastguard Worker } // namespace android
211