xref: /openbmc/phosphor-fan-presence/presence/gpio.cpp (revision 1cfc2f11b13412a15f8478cebc35e50e6feb13a2)
15c589487SBrad Bishop /**
25c589487SBrad Bishop  * Copyright © 2017 IBM Corporation
35c589487SBrad Bishop  *
45c589487SBrad Bishop  * Licensed under the Apache License, Version 2.0 (the "License");
55c589487SBrad Bishop  * you may not use this file except in compliance with the License.
65c589487SBrad Bishop  * You may obtain a copy of the License at
75c589487SBrad Bishop  *
85c589487SBrad Bishop  *     http://www.apache.org/licenses/LICENSE-2.0
95c589487SBrad Bishop  *
105c589487SBrad Bishop  * Unless required by applicable law or agreed to in writing, software
115c589487SBrad Bishop  * distributed under the License is distributed on an "AS IS" BASIS,
125c589487SBrad Bishop  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135c589487SBrad Bishop  * See the License for the specific language governing permissions and
145c589487SBrad Bishop  * limitations under the License.
155c589487SBrad Bishop  */
16*1cfc2f11SWilliam A. Kennington III #include <functional>
175c589487SBrad Bishop #include <phosphor-logging/elog-errors.hpp>
185c589487SBrad Bishop #include <phosphor-logging/elog.hpp>
19*1cfc2f11SWilliam A. Kennington III #include <sdeventplus/event.hpp>
205c589487SBrad Bishop #include <tuple>
215c589487SBrad Bishop #include <xyz/openbmc_project/Common/Callout/error.hpp>
225c589487SBrad Bishop #include "gpio.hpp"
235c589487SBrad Bishop #include "rpolicy.hpp"
245c589487SBrad Bishop 
255c589487SBrad Bishop namespace phosphor
265c589487SBrad Bishop {
275c589487SBrad Bishop namespace fan
285c589487SBrad Bishop {
295c589487SBrad Bishop namespace presence
305c589487SBrad Bishop {
315c589487SBrad Bishop 
325c589487SBrad Bishop Gpio::Gpio(
335c589487SBrad Bishop         const std::string& physDevice,
342e9788d7SBrad Bishop         const std::string& device,
355c589487SBrad Bishop         unsigned int physPin) :
365c589487SBrad Bishop     currentState(false),
372e9788d7SBrad Bishop     evdevfd(open(device.c_str(), O_RDONLY | O_NONBLOCK)),
385c589487SBrad Bishop     evdev(evdevpp::evdev::newFromFD(evdevfd())),
395c589487SBrad Bishop     phys(physDevice),
40*1cfc2f11SWilliam A. Kennington III     pin(physPin)
415c589487SBrad Bishop {
425c589487SBrad Bishop 
435c589487SBrad Bishop }
445c589487SBrad Bishop 
455c589487SBrad Bishop bool Gpio::start()
465c589487SBrad Bishop {
47*1cfc2f11SWilliam A. Kennington III     source.emplace(sdeventplus::Event::get_default(),
48*1cfc2f11SWilliam A. Kennington III             evdevfd(), EPOLLIN,
49*1cfc2f11SWilliam A. Kennington III             std::bind(&Gpio::ioCallback, this));
505c589487SBrad Bishop     currentState = present();
515c589487SBrad Bishop     return currentState;
525c589487SBrad Bishop }
535c589487SBrad Bishop 
545c589487SBrad Bishop void Gpio::stop()
555c589487SBrad Bishop {
56*1cfc2f11SWilliam A. Kennington III     source.reset();
575c589487SBrad Bishop }
585c589487SBrad Bishop 
595c589487SBrad Bishop bool Gpio::present()
605c589487SBrad Bishop {
615c589487SBrad Bishop     return evdev.fetch(EV_KEY, pin) != 0;
625c589487SBrad Bishop }
635c589487SBrad Bishop 
645c589487SBrad Bishop void Gpio::fail()
655c589487SBrad Bishop {
665c589487SBrad Bishop     using namespace sdbusplus::xyz::openbmc_project::Common::Callout::Error;
675c589487SBrad Bishop     using namespace phosphor::logging;
685c589487SBrad Bishop     using namespace xyz::openbmc_project::Common::Callout;
695c589487SBrad Bishop 
705c589487SBrad Bishop     report<sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>(
715c589487SBrad Bishop             GPIO::CALLOUT_GPIO_NUM(pin),
725c589487SBrad Bishop             GPIO::CALLOUT_ERRNO(0),
735c589487SBrad Bishop             GPIO::CALLOUT_DEVICE_PATH(phys.c_str()));
745c589487SBrad Bishop }
755c589487SBrad Bishop 
76*1cfc2f11SWilliam A. Kennington III void Gpio::ioCallback()
775c589487SBrad Bishop {
785c589487SBrad Bishop     unsigned int type, code, value;
795c589487SBrad Bishop 
805c589487SBrad Bishop     std::tie(type, code, value) = evdev.next();
815c589487SBrad Bishop     if (type != EV_KEY || code != pin)
825c589487SBrad Bishop     {
835c589487SBrad Bishop         return;
845c589487SBrad Bishop     }
855c589487SBrad Bishop 
865c589487SBrad Bishop     bool newState = value != 0;
875c589487SBrad Bishop 
885c589487SBrad Bishop     if (currentState != newState)
895c589487SBrad Bishop     {
9011083ecaSBrad Bishop         getPolicy().stateChanged(newState, *this);
915c589487SBrad Bishop         currentState = newState;
925c589487SBrad Bishop     }
935c589487SBrad Bishop }
945c589487SBrad Bishop } // namespace presence
955c589487SBrad Bishop } // namespace fan
965c589487SBrad Bishop } // namespace phosphor
97