blob: 23e436a0ea49913cc3d796b8edb9fd3dc7955667 [file] [log] [blame]
// 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