summaryrefslogtreecommitdiffstats
path: root/sensor.cpp
diff options
context:
space:
mode:
authorPatrick Venture <venture@google.com>2018-09-14 10:19:14 -0700
committerPatrick Venture <venture@google.com>2018-09-21 10:26:14 -0700
commitb28f432a3fdb96c634e93ea27807daec59a941e7 (patch)
tree7c3619d61d1f662bd29389fe34d3e3ba984af0e6 /sensor.cpp
parent86e58fffbb3a889beb2e306464929819dbf97986 (diff)
downloadphosphor-hwmon-b28f432a3fdb96c634e93ea27807daec59a941e7.tar.gz
phosphor-hwmon-b28f432a3fdb96c634e93ea27807daec59a941e7.zip
Use gpioplus for specifying gpio gating
A GPIO can control whether a hwmon sensor is readable. This module allows one to specify whether a sensor is gated and by what GPIO. This is often the case for battery voltages, such that the battery isn't drained constantly by being left open. For each sensor where you need GPIO locking: GPIOCHIP_in1=0 GPIO_in1=53 such that GPIOCHIP is the gpiochip: /sys/bus/gpio/devices/gpiochip{id} such that GPIO is the line offset. the value used to unlock the sensor via gpio is 1 after 1 is written to the gpio, it pauses for 500ms Tested: Verified the failure case for invalid gpio fields. Verified correct behavior on two platforms. Change-Id: I2fa12848972075cad0e0f69c0bfa6382e15d4f50 Signed-off-by: Patrick Venture <venture@google.com>
Diffstat (limited to 'sensor.cpp')
-rw-r--r--sensor.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/sensor.cpp b/sensor.cpp
index bc5f34d..e68f7a7 100644
--- a/sensor.cpp
+++ b/sensor.cpp
@@ -3,6 +3,7 @@
#include "sensor.hpp"
#include "env.hpp"
+#include "gpio_handle.hpp"
#include "hwmon.hpp"
#include "sensorset.hpp"
#include "sysfs.hpp"
@@ -10,18 +11,34 @@
#include <cstring>
#include <experimental/filesystem>
#include <phosphor-logging/elog-errors.hpp>
+#include <thread>
+#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>
namespace sensor
{
using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Sensor::Sensor(const SensorSet::key_type& sensor,
const hwmonio::HwmonIO& ioAccess, const std::string& devPath) :
sensor(sensor),
ioAccess(ioAccess), devPath(devPath)
{
+ auto chip = env::getEnv("GPIOCHIP", sensor);
+ auto access = env::getEnv("GPIO", sensor);
+ if (!access.empty() && !chip.empty())
+ {
+ handle = gpio::BuildGpioHandle(chip, access);
+
+ if (!handle)
+ {
+ log<level::ERR>("Unable to set up gpio locking");
+ elog<InternalFailure>();
+ }
+ }
+
auto gain = env::getEnv("GAIN", sensor);
if (!gain.empty())
{
@@ -110,11 +127,15 @@ std::shared_ptr<ValueObject> Sensor::addValue(const RetryIO& retryIO,
// its status is functional, read the input value.
if (!statusIface || (statusIface && statusIface->functional()))
{
+ unlockGpio();
+
// Retry for up to a second if device is busy
// or has a transient error.
val = ioAccess.read(sensor.first, sensor.second, hwmon::entry::cinput,
std::get<size_t>(retryIO),
std::get<std::chrono::milliseconds>(retryIO));
+
+ lockGpio();
val = adjustValue(val);
}
@@ -199,4 +220,21 @@ std::shared_ptr<StatusObject> Sensor::addStatus(ObjectInfo& info)
return iface;
}
+void Sensor::unlockGpio()
+{
+ if (handle)
+ {
+ handle->setValues({1});
+ std::this_thread::sleep_for(pause);
+ }
+}
+
+void Sensor::lockGpio()
+{
+ if (handle)
+ {
+ handle->setValues({0});
+ }
+}
+
} // namespace sensor
OpenPOWER on IntegriCloud