blob: 94d15c670242e6569ffdeba8e3fc2b304a276d5c [file] [log] [blame]
Kuiying Wanga9d39e32018-08-14 13:47:32 +08001/*
2// Copyright (c) 2018 Intel 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
17#pragma once
18#include <phosphor-logging/elog-errors.hpp>
19#include <unistd.h>
20#include "xyz/openbmc_project/Chassis/Common/error.hpp"
21#include "xyz/openbmc_project/Chassis/Buttons/Power/server.hpp"
22#include "common.hpp"
23#include "gpio.hpp"
24
25const static constexpr char* POWER_BUTTON = "POWER_BUTTON";
26
27struct PowerButton
28 : sdbusplus::server::object::object<
29 sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>
30{
31
32 PowerButton(sdbusplus::bus::bus& bus, const char* path,
33 EventPtr& event,
34 sd_event_io_handler_t handler = PowerButton::EventHandler) :
35 sdbusplus::server::object::object<
36 sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>(
37 bus, path),
38 fd(-1), bus(bus), event(event), callbackHandler(handler)
39 {
40
41 int ret = -1;
42
43 // config gpio
44 ret = ::configGpio(POWER_BUTTON, &fd, bus);
45 if (ret < 0)
46 {
47 phosphor::logging::log<phosphor::logging::level::ERR>(
48 "POWER_BUTTON: failed to config GPIO");
49 throw sdbusplus::xyz::openbmc_project::Chassis::Common::
50 Error::IOError();
51 }
52
53 ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
54 callbackHandler, this);
55 if (ret < 0)
56 {
57 phosphor::logging::log<phosphor::logging::level::ERR>(
58 "POWER_BUTTON: failed to add to event loop");
59 ::closeGpio(fd);
60 throw sdbusplus::xyz::openbmc_project::Chassis::Common::
61 Error::IOError();
62 }
63 }
64
65 ~PowerButton()
66 {
67 ::closeGpio(fd);
68 }
69
70 void simPress() override;
71 void simLongPress() override;
72
73 static int EventHandler(sd_event_source* es, int fd,
74 uint32_t revents, void* userdata)
75 {
76
77 int n = -1;
78 char buf = '0';
79
80 if (!userdata)
81 {
82 phosphor::logging::log<phosphor::logging::level::ERR>(
83 "POWER_BUTTON: userdata null!");
84 throw sdbusplus::xyz::openbmc_project::Chassis::Common::
85 Error::IOError();
86 }
87
88 PowerButton* powerButton = static_cast<PowerButton*>(userdata);
89
90 if (!powerButton)
91 {
92 phosphor::logging::log<phosphor::logging::level::ERR>(
93 "POWER_BUTTON: null pointer!");
94 throw sdbusplus::xyz::openbmc_project::Chassis::Common::
95 Error::IOError();
96 }
97
98 n = ::lseek(fd, 0, SEEK_SET);
99
100 if (n < 0)
101 {
102 phosphor::logging::log<phosphor::logging::level::ERR>(
103 "POWER_BUTTON: lseek error!");
104 throw sdbusplus::xyz::openbmc_project::Chassis::Common::
105 Error::IOError();
106 }
107
108 n = ::read(fd, &buf, sizeof(buf));
109 if (n < 0)
110 {
111 phosphor::logging::log<phosphor::logging::level::ERR>(
112 "POWER_BUTTON: read error!");
113 throw sdbusplus::xyz::openbmc_project::Chassis::Common::
114 Error::IOError();
115 }
116
117 if (buf == '0')
118 {
119 phosphor::logging::log<phosphor::logging::level::DEBUG>(
120 "POWER_BUTTON: pressed");
121 // emit pressed signal
122 powerButton->pressed();
123 }
124 else
125 {
126 phosphor::logging::log<phosphor::logging::level::DEBUG>(
127 "POWER_BUTTON: released");
128 // released
129 powerButton->released();
130 }
131
132 return 0;
133 }
134
135 private:
136 int fd;
137 sdbusplus::bus::bus& bus;
138 EventPtr& event;
139 sd_event_io_handler_t callbackHandler;
140};