summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@fuzziesquirrel.com>2017-06-14 22:32:20 -0400
committerPatrick Williams <patrick@stwcx.xyz>2017-08-02 20:18:19 +0000
commit5c5894878b09fdef8fcbee000f83283b73b8da64 (patch)
treea4d3746ab06c6334f19c795fa7171f789389c62e
parentdd62e36eabe275348bc7e74201f960197b01bd0c (diff)
downloadphosphor-fan-presence-5c5894878b09fdef8fcbee000f83283b73b8da64.tar.gz
phosphor-fan-presence-5c5894878b09fdef8fcbee000f83283b73b8da64.zip
presence: Add gpio presence sensor
Add a gpio presence implementation of the PresenceSensor interface. The gpio sensor simply maps the on off state of a gpio directly to the xyz.openbmc_project.Inventory.Item Present property. Change-Id: I071dd475bebb15372edb59506352746c20542eff Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
-rw-r--r--presence/Makefile.am1
-rw-r--r--presence/gpio.cpp98
-rw-r--r--presence/gpio.hpp107
3 files changed, 206 insertions, 0 deletions
diff --git a/presence/Makefile.am b/presence/Makefile.am
index 2ea4929..2a5976c 100644
--- a/presence/Makefile.am
+++ b/presence/Makefile.am
@@ -6,6 +6,7 @@ sbin_PROGRAMS = \
phosphor_fan_presence_tach_SOURCES = \
fan.cpp \
+ gpio.cpp \
tach.cpp \
fan_enclosure.cpp \
tach_sensor.cpp \
diff --git a/presence/gpio.cpp b/presence/gpio.cpp
new file mode 100644
index 0000000..dfd72db
--- /dev/null
+++ b/presence/gpio.cpp
@@ -0,0 +1,98 @@
+/**
+ * Copyright © 2017 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <memory>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <tuple>
+#include <xyz/openbmc_project/Common/Callout/error.hpp>
+#include "gpio.hpp"
+#include "rpolicy.hpp"
+#include "sdevent.hpp"
+
+namespace phosphor
+{
+namespace fan
+{
+namespace presence
+{
+
+Gpio::Gpio(
+ const std::string& physDevice,
+ unsigned int physPin) :
+ currentState(false),
+ evdevfd(open("/dev/input/by-path/platform-gpio-keys-event",
+ O_RDONLY | O_NONBLOCK)),
+ evdev(evdevpp::evdev::newFromFD(evdevfd())),
+ phys(physDevice),
+ pin(physPin),
+ callback(nullptr)
+{
+
+}
+
+bool Gpio::start()
+{
+ callback = std::make_unique<sdevent::event::io::IO>(
+ util::SDEvent::getEvent(),
+ evdevfd(),
+ [this](auto& s){this->ioCallback(s);});
+ currentState = present();
+ return currentState;
+}
+
+void Gpio::stop()
+{
+ callback = nullptr;
+}
+
+bool Gpio::present()
+{
+ return evdev.fetch(EV_KEY, pin) != 0;
+}
+
+void Gpio::fail()
+{
+ using namespace sdbusplus::xyz::openbmc_project::Common::Callout::Error;
+ using namespace phosphor::logging;
+ using namespace xyz::openbmc_project::Common::Callout;
+
+ report<sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>(
+ GPIO::CALLOUT_GPIO_NUM(pin),
+ GPIO::CALLOUT_ERRNO(0),
+ GPIO::CALLOUT_DEVICE_PATH(phys.c_str()));
+}
+
+void Gpio::ioCallback(sdevent::source::Source& source)
+{
+ unsigned int type, code, value;
+
+ std::tie(type, code, value) = evdev.next();
+ if (type != EV_KEY || code != pin)
+ {
+ return;
+ }
+
+ bool newState = value != 0;
+
+ if (currentState != newState)
+ {
+ getPolicy().stateChanged(newState);
+ currentState = newState;
+ }
+}
+} // namespace presence
+} // namespace fan
+} // namespace phosphor
diff --git a/presence/gpio.hpp b/presence/gpio.hpp
new file mode 100644
index 0000000..e516e0f
--- /dev/null
+++ b/presence/gpio.hpp
@@ -0,0 +1,107 @@
+#pragma once
+
+#include <memory>
+#include "evdevpp/evdev.hpp"
+#include "sdevent/io.hpp"
+#include "sdevent/source.hpp"
+#include "psensor.hpp"
+#include "utility.hpp"
+
+namespace phosphor
+{
+namespace fan
+{
+namespace presence
+{
+class RedundancyPolicy;
+
+/**
+ * @class Gpio
+ * @brief Gpio presence sensor implementation.
+ *
+ * The Gpio class uses a gpio wire to determine presence state.
+ */
+class Gpio : public PresenceSensor
+{
+ public:
+ /**
+ * @brief
+ *
+ * Cannot move or copy due to this ptr as context
+ * for sdevent callbacks.
+ */
+ Gpio() = delete;
+ Gpio(const Gpio&) = delete;
+ Gpio& operator=(const Gpio&) = delete;
+ Gpio(Gpio&&) = delete;
+ Gpio& operator=(Gpio&&) = delete;
+ ~Gpio() = default;
+
+ /**
+ * @brief Construct a gpio sensor.
+ *
+ * @param[in] physDevice - The physical gpio device path.
+ * @param[in] physPin - The physical gpio pin number.
+ */
+ Gpio(const std::string& physDevice, unsigned int physPin);
+
+ /**
+ * @brief start
+ *
+ * Register for an sdevent io callback on the gpio.
+ * Query the initial state of the gpio.
+ *
+ * @return The current sensor state.
+ */
+ bool start() override;
+
+ /**
+ * @brief stop
+ *
+ * De-register sdevent io callback.
+ */
+ void stop() override;
+
+ /**
+ * @brief fail
+ *
+ * Call the gpio out.
+ */
+ void fail() override;
+
+ /**
+ * @brief Check the sensor.
+ *
+ * Query the gpio.
+ */
+ bool present() override;
+
+ private :
+ /** @brief Get the policy associated with this sensor. */
+ virtual RedundancyPolicy& getPolicy() = 0;
+
+ /** @brief sdevent io callback. */
+ void ioCallback(sdevent::source::Source& source);
+
+ /** The current state of the sensor. */
+ bool currentState;
+
+ /** Gpio event device file descriptor. */
+ util::FileDescriptor evdevfd;
+
+ /** Gpio event device. */
+ evdevpp::evdev::EvDev evdev;
+
+ /** Physical gpio device. */
+ std::string phys;
+
+ /** Gpio pin number. */
+ unsigned int pin;
+
+ /** sdevent io callback handle. */
+ std::unique_ptr<sdevent::event::io::IO> callback;
+};
+
+} // namespace presence
+} // namespace fan
+} // namespace phosphor
OpenPOWER on IntegriCloud