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>
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