blob: cb32125bcf94e8dfa026a1b3bcccbb985e9c3c0e [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
Kuiying Wanga9d39e32018-08-14 13:47:32 +080018#include "common.hpp"
19#include "gpio.hpp"
Patrick Venture0d9377d2018-11-01 19:34:59 -070020#include "xyz/openbmc_project/Chassis/Buttons/ID/server.hpp"
21#include "xyz/openbmc_project/Chassis/Common/error.hpp"
Kuiying Wanga9d39e32018-08-14 13:47:32 +080022
Patrick Venture0d9377d2018-11-01 19:34:59 -070023#include <unistd.h>
24
25#include <phosphor-logging/elog-errors.hpp>
26
27const static constexpr char* ID_BUTTON = "ID_BTN";
Kuiying Wanga9d39e32018-08-14 13:47:32 +080028
29struct IDButton
30 : sdbusplus::server::object::object<
Patrick Venture0d9377d2018-11-01 19:34:59 -070031 sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::ID>
Kuiying Wanga9d39e32018-08-14 13:47:32 +080032{
33
Patrick Venture0d9377d2018-11-01 19:34:59 -070034 IDButton(sdbusplus::bus::bus& bus, const char* path, EventPtr& event,
Naveen Mosesdd5495c2021-12-03 22:40:46 +053035 buttonConfig& buttonCfg,
Kuiying Wanga9d39e32018-08-14 13:47:32 +080036 sd_event_io_handler_t handler = IDButton::EventHandler) :
37 sdbusplus::server::object::object<
38 sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::ID>(
39 bus, path),
Naveen Mosesdd5495c2021-12-03 22:40:46 +053040 fd(-1), buttonIFConfig(buttonCfg), bus(bus), event(event),
41 callbackHandler(handler)
Kuiying Wanga9d39e32018-08-14 13:47:32 +080042 {
43
44 int ret = -1;
45
Naveen Mosesdd5495c2021-12-03 22:40:46 +053046 // config group gpio based on the gpio defs read from the json file
47 ret = configGroupGpio(bus, buttonIFConfig);
48
Kuiying Wanga9d39e32018-08-14 13:47:32 +080049 if (ret < 0)
50 {
51 phosphor::logging::log<phosphor::logging::level::ERR>(
52 "ID_BUTTON: failed to config GPIO");
Patrick Venture0d9377d2018-11-01 19:34:59 -070053 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
54 IOError();
Kuiying Wanga9d39e32018-08-14 13:47:32 +080055 }
Naveen Mosesdd5495c2021-12-03 22:40:46 +053056 // initialize the button io fd from the buttonConfig
57 // which has fd stored when configGroupGpio is called
58 fd = buttonIFConfig.gpios[0].fd;
Kuiying Wanga9d39e32018-08-14 13:47:32 +080059
Matt Spinlerb3d86c92018-11-15 16:13:19 -060060 char buf;
61 ::read(fd, &buf, sizeof(buf));
62
Kuiying Wanga9d39e32018-08-14 13:47:32 +080063 ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
64 callbackHandler, this);
65 if (ret < 0)
66 {
67 phosphor::logging::log<phosphor::logging::level::ERR>(
68 "ID_BUTTON: failed to add to event loop");
69 ::closeGpio(fd);
Patrick Venture0d9377d2018-11-01 19:34:59 -070070 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
71 IOError();
Kuiying Wanga9d39e32018-08-14 13:47:32 +080072 }
73 }
74
75 ~IDButton()
76 {
77 ::closeGpio(fd);
78 }
79
80 void simPress() override;
81
Naveen Mosesdd5495c2021-12-03 22:40:46 +053082 static const std::string getGpioName()
Matt Spinler8605bdf2018-11-05 14:55:46 -060083 {
84 return ID_BUTTON;
85 }
86
Patrick Venture0d9377d2018-11-01 19:34:59 -070087 static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
88 void* userdata)
Kuiying Wanga9d39e32018-08-14 13:47:32 +080089 {
90
91 int n = -1;
92 char buf = '0';
93
94 if (!userdata)
95 {
96 phosphor::logging::log<phosphor::logging::level::ERR>(
97 "ID_BUTTON: userdata null!");
Patrick Venture0d9377d2018-11-01 19:34:59 -070098 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
99 IOError();
Kuiying Wanga9d39e32018-08-14 13:47:32 +0800100 }
101
102 IDButton* idButton = static_cast<IDButton*>(userdata);
103
104 if (!idButton)
105 {
106 phosphor::logging::log<phosphor::logging::level::ERR>(
107 "ID_BUTTON: null pointer!");
Patrick Venture0d9377d2018-11-01 19:34:59 -0700108 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
109 IOError();
Kuiying Wanga9d39e32018-08-14 13:47:32 +0800110 }
111
112 n = ::lseek(fd, 0, SEEK_SET);
113
114 if (n < 0)
115 {
116 phosphor::logging::log<phosphor::logging::level::ERR>(
117 "ID_BUTTON: lseek error!");
Patrick Venture0d9377d2018-11-01 19:34:59 -0700118 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
119 IOError();
Kuiying Wanga9d39e32018-08-14 13:47:32 +0800120 }
121
122 n = ::read(fd, &buf, sizeof(buf));
123 if (n < 0)
124 {
125 phosphor::logging::log<phosphor::logging::level::ERR>(
126 "ID_BUTTON: read error!");
Patrick Venture0d9377d2018-11-01 19:34:59 -0700127 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
128 IOError();
Kuiying Wanga9d39e32018-08-14 13:47:32 +0800129 }
130
131 if (buf == '0')
132 {
133 phosphor::logging::log<phosphor::logging::level::DEBUG>(
134 "ID_BUTTON: pressed");
135 // emit pressed signal
136 idButton->pressed();
137 }
138 else
139 {
140 phosphor::logging::log<phosphor::logging::level::DEBUG>(
141 "ID_BUTTON: released");
142 // released
143 idButton->released();
144 }
145
146 return 0;
147 }
148
149 private:
150 int fd;
Naveen Mosesdd5495c2021-12-03 22:40:46 +0530151 buttonConfig buttonIFConfig;
Kuiying Wanga9d39e32018-08-14 13:47:32 +0800152 sdbusplus::bus::bus& bus;
153 EventPtr& event;
154 sd_event_io_handler_t callbackHandler;
155};