| // Copyright 2015 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "thermald/ath10k_temperature_sensor.h" |
| |
| #include <string> |
| |
| #include "base/check.h" |
| #include "base/files/file_enumerator.h" |
| #include "base/files/file_path.h" |
| #include "base/logging.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/stringprintf.h" |
| |
| #include "thermald/ath10k_interface.h" |
| #include "thermald/hwmon_temperature_sensor.h" |
| #include "thermald/network_interface.h" |
| |
| using std::string; |
| |
| namespace thermald { |
| |
| static bool GetHwmonChipId(const string &interface_name, int *chip_id) { |
| base::FilePath phy_hwmon_dir(base::StringPrintf( |
| "/sys/class/net/%s/phy80211/device/hwmon", interface_name.c_str())); |
| |
| base::FileEnumerator hwmon_enum(phy_hwmon_dir, false, |
| base::FileEnumerator::DIRECTORIES, |
| FILE_PATH_LITERAL("hwmon*")); |
| |
| base::FilePath hwmon_dev = hwmon_enum.Next(); |
| if (hwmon_dev.empty()) { |
| LOG(ERROR) << "ath10k interface '" << interface_name |
| << "' has no thermal sensor"; |
| return false; |
| } |
| |
| if (!hwmon_enum.Next().empty()) { |
| LOG(ERROR) << "failed to determine thermal sensor of ath10k device '" |
| << interface_name << "': more than one hwmon device"; |
| return false; |
| } |
| |
| return base::StringToInt(hwmon_dev.BaseName().value().substr(5), chip_id); |
| } |
| |
| Ath10kTemperatureSensor::Ath10kTemperatureSensor( |
| const string &interface_name, const string &sensor_name) |
| : TemperatureSensorCommon(sensor_name), |
| interface_name_(interface_name), |
| no_thermal_support_(false) { |
| } |
| |
| Ath10kTemperatureSensor::Ath10kTemperatureSensor( |
| const string &interface_name) |
| : Ath10kTemperatureSensor(interface_name, interface_name) { |
| } |
| |
| bool Ath10kTemperatureSensor::ReadTemperature(int *value) { |
| DCHECK(value); |
| |
| if (no_thermal_support_) { |
| return false; |
| } |
| |
| if (!ath10k_interface_.get()) { |
| if (!Initialize()) { |
| return false; |
| } |
| } |
| |
| return hwmon_sensor_->ReadTemperature(value); |
| } |
| |
| bool Ath10kTemperatureSensor::IsOperational() { |
| if (no_thermal_support_) { |
| return false; |
| } |
| |
| if (!ath10k_interface_.get()) { |
| // First check if the network interface exists at all before |
| // checking for ath10k specifics in Initialize(). This helps |
| // to reduce log clutter. |
| if (!NetworkInterface::Exists(interface_name_)) { |
| return false; |
| } |
| |
| if (!Initialize()) { |
| return false; |
| } |
| } |
| |
| // The sensor of ath10k interfaces can only be read when the interface is |
| // activated. |
| return ath10k_interface_->IsUp(); |
| } |
| |
| bool Ath10kTemperatureSensor::Initialize() { |
| if (!Ath10kInterface::IsAth10kInterface(interface_name_)) { |
| return false; |
| } |
| |
| if (!Ath10kInterface::HasThermalSupport(interface_name_)) { |
| no_thermal_support_ = true; |
| return false; |
| } |
| |
| int chip_id; |
| if (!GetHwmonChipId(interface_name_, &chip_id)) { |
| return false; |
| } |
| |
| hwmon_sensor_.reset( |
| new HwmonTemperatureSensor(chip_id, 1, name())); |
| |
| ath10k_interface_.reset(new Ath10kInterface(interface_name_)); |
| |
| return true; |
| } |
| |
| } // namespace thermald |