blob: 28db46e52949ad7e2be8ed17b57ab76d5b0fb437 [file] [log] [blame]
Brad Bishop5c589482017-06-14 22:32:20 -04001/**
2 * Copyright © 2017 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <memory>
17#include <phosphor-logging/elog-errors.hpp>
18#include <phosphor-logging/elog.hpp>
19#include <tuple>
20#include <xyz/openbmc_project/Common/Callout/error.hpp>
21#include "gpio.hpp"
22#include "rpolicy.hpp"
23#include "sdevent.hpp"
24
25namespace phosphor
26{
27namespace fan
28{
29namespace presence
30{
31
32Gpio::Gpio(
33 const std::string& physDevice,
34 unsigned int physPin) :
35 currentState(false),
36 evdevfd(open("/dev/input/by-path/platform-gpio-keys-event",
37 O_RDONLY | O_NONBLOCK)),
38 evdev(evdevpp::evdev::newFromFD(evdevfd())),
39 phys(physDevice),
40 pin(physPin),
41 callback(nullptr)
42{
43
44}
45
46bool Gpio::start()
47{
48 callback = std::make_unique<sdevent::event::io::IO>(
49 util::SDEvent::getEvent(),
50 evdevfd(),
51 [this](auto& s){this->ioCallback(s);});
52 currentState = present();
53 return currentState;
54}
55
56void Gpio::stop()
57{
58 callback = nullptr;
59}
60
61bool Gpio::present()
62{
63 return evdev.fetch(EV_KEY, pin) != 0;
64}
65
66void Gpio::fail()
67{
68 using namespace sdbusplus::xyz::openbmc_project::Common::Callout::Error;
69 using namespace phosphor::logging;
70 using namespace xyz::openbmc_project::Common::Callout;
71
72 report<sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>(
73 GPIO::CALLOUT_GPIO_NUM(pin),
74 GPIO::CALLOUT_ERRNO(0),
75 GPIO::CALLOUT_DEVICE_PATH(phys.c_str()));
76}
77
78void Gpio::ioCallback(sdevent::source::Source& source)
79{
80 unsigned int type, code, value;
81
82 std::tie(type, code, value) = evdev.next();
83 if (type != EV_KEY || code != pin)
84 {
85 return;
86 }
87
88 bool newState = value != 0;
89
90 if (currentState != newState)
91 {
Brad Bishop11083ec2017-07-25 19:08:53 -040092 getPolicy().stateChanged(newState, *this);
Brad Bishop5c589482017-06-14 22:32:20 -040093 currentState = newState;
94 }
95}
96} // namespace presence
97} // namespace fan
98} // namespace phosphor