1a9d39e30SKuiying Wang /* 2a9d39e30SKuiying Wang // Copyright (c) 2018 Intel Corporation 3a9d39e30SKuiying Wang // 4a9d39e30SKuiying Wang // Licensed under the Apache License, Version 2.0 (the "License"); 5a9d39e30SKuiying Wang // you may not use this file except in compliance with the License. 6a9d39e30SKuiying Wang // You may obtain a copy of the License at 7a9d39e30SKuiying Wang // 8a9d39e30SKuiying Wang // http://www.apache.org/licenses/LICENSE-2.0 9a9d39e30SKuiying Wang // 10a9d39e30SKuiying Wang // Unless required by applicable law or agreed to in writing, software 11a9d39e30SKuiying Wang // distributed under the License is distributed on an "AS IS" BASIS, 12a9d39e30SKuiying Wang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9d39e30SKuiying Wang // See the License for the specific language governing permissions and 14a9d39e30SKuiying Wang // limitations under the License. 15a9d39e30SKuiying Wang */ 16a9d39e30SKuiying Wang 17a9d39e30SKuiying Wang #pragma once 18a9d39e30SKuiying Wang #include "common.hpp" 19a9d39e30SKuiying Wang #include "gpio.hpp" 200d9377d2SPatrick Venture #include "xyz/openbmc_project/Chassis/Buttons/Reset/server.hpp" 210d9377d2SPatrick Venture #include "xyz/openbmc_project/Chassis/Common/error.hpp" 220d9377d2SPatrick Venture 230d9377d2SPatrick Venture #include <unistd.h> 240d9377d2SPatrick Venture 250d9377d2SPatrick Venture #include <phosphor-logging/elog-errors.hpp> 26a9d39e30SKuiying Wang 27a9d39e30SKuiying Wang const static constexpr char* RESET_BUTTON = "RESET_BUTTON"; 28a9d39e30SKuiying Wang 29a9d39e30SKuiying Wang struct ResetButton 30a9d39e30SKuiying Wang : sdbusplus::server::object::object< 31a9d39e30SKuiying Wang sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset> 32a9d39e30SKuiying Wang { 33a9d39e30SKuiying Wang 340d9377d2SPatrick Venture ResetButton(sdbusplus::bus::bus& bus, const char* path, EventPtr& event, 35a9d39e30SKuiying Wang sd_event_io_handler_t handler = ResetButton::EventHandler) : 36a9d39e30SKuiying Wang sdbusplus::server::object::object< 37a9d39e30SKuiying Wang sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset>( 38a9d39e30SKuiying Wang bus, path), 39a9d39e30SKuiying Wang fd(-1), bus(bus), event(event), callbackHandler(handler) 40a9d39e30SKuiying Wang { 41a9d39e30SKuiying Wang 42a9d39e30SKuiying Wang int ret = -1; 43a9d39e30SKuiying Wang 44a9d39e30SKuiying Wang // config gpio 45a9d39e30SKuiying Wang ret = ::configGpio(RESET_BUTTON, &fd, bus); 46a9d39e30SKuiying Wang if (ret < 0) 47a9d39e30SKuiying Wang { 48a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 49a9d39e30SKuiying Wang "RESET_BUTTON: failed to config GPIO"); 500d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 510d9377d2SPatrick Venture IOError(); 52a9d39e30SKuiying Wang } 53a9d39e30SKuiying Wang 54a9d39e30SKuiying Wang ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI, 55a9d39e30SKuiying Wang callbackHandler, this); 56a9d39e30SKuiying Wang if (ret < 0) 57a9d39e30SKuiying Wang { 58a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 59a9d39e30SKuiying Wang "RESET_BUTTON: failed to add to event loop"); 60a9d39e30SKuiying Wang ::closeGpio(fd); 610d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 620d9377d2SPatrick Venture IOError(); 63a9d39e30SKuiying Wang } 64a9d39e30SKuiying Wang } 65a9d39e30SKuiying Wang 66a9d39e30SKuiying Wang ~ResetButton() 67a9d39e30SKuiying Wang { 68a9d39e30SKuiying Wang ::closeGpio(fd); 69a9d39e30SKuiying Wang } 70a9d39e30SKuiying Wang 71a9d39e30SKuiying Wang void simPress() override; 72a9d39e30SKuiying Wang 73*8605bdffSMatt Spinler static const char* getGpioName() 74*8605bdffSMatt Spinler { 75*8605bdffSMatt Spinler return RESET_BUTTON; 76*8605bdffSMatt Spinler } 77*8605bdffSMatt Spinler 780d9377d2SPatrick Venture static int EventHandler(sd_event_source* es, int fd, uint32_t revents, 790d9377d2SPatrick Venture void* userdata) 80a9d39e30SKuiying Wang { 81a9d39e30SKuiying Wang 82a9d39e30SKuiying Wang int n = -1; 83a9d39e30SKuiying Wang char buf = '0'; 84a9d39e30SKuiying Wang 85a9d39e30SKuiying Wang if (!userdata) 86a9d39e30SKuiying Wang { 87a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 88a9d39e30SKuiying Wang "RESET_BUTTON: userdata null!"); 890d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 900d9377d2SPatrick Venture IOError(); 91a9d39e30SKuiying Wang } 92a9d39e30SKuiying Wang 93a9d39e30SKuiying Wang ResetButton* resetButton = static_cast<ResetButton*>(userdata); 94a9d39e30SKuiying Wang 95a9d39e30SKuiying Wang if (!resetButton) 96a9d39e30SKuiying Wang { 97a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 98a9d39e30SKuiying Wang "RESET_BUTTON: null pointer!"); 990d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 1000d9377d2SPatrick Venture IOError(); 101a9d39e30SKuiying Wang } 102a9d39e30SKuiying Wang 103a9d39e30SKuiying Wang n = ::lseek(fd, 0, SEEK_SET); 104a9d39e30SKuiying Wang 105a9d39e30SKuiying Wang if (n < 0) 106a9d39e30SKuiying Wang { 107a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 108a9d39e30SKuiying Wang "RESET_BUTTON: lseek error!"); 1090d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 1100d9377d2SPatrick Venture IOError(); 111a9d39e30SKuiying Wang } 112a9d39e30SKuiying Wang 113a9d39e30SKuiying Wang n = ::read(fd, &buf, sizeof(buf)); 114a9d39e30SKuiying Wang if (n < 0) 115a9d39e30SKuiying Wang { 116a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 117a9d39e30SKuiying Wang "RESET_BUTTON: read error!"); 1180d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 1190d9377d2SPatrick Venture IOError(); 120a9d39e30SKuiying Wang } 121a9d39e30SKuiying Wang 122a9d39e30SKuiying Wang if (buf == '0') 123a9d39e30SKuiying Wang { 124a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::DEBUG>( 125a9d39e30SKuiying Wang "RESET_BUTTON: pressed"); 126a9d39e30SKuiying Wang // emit pressed signal 127a9d39e30SKuiying Wang resetButton->pressed(); 128a9d39e30SKuiying Wang } 129a9d39e30SKuiying Wang else 130a9d39e30SKuiying Wang { 131a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::DEBUG>( 132a9d39e30SKuiying Wang "RESET_BUTTON: released"); 133a9d39e30SKuiying Wang // released 134a9d39e30SKuiying Wang resetButton->released(); 135a9d39e30SKuiying Wang } 136a9d39e30SKuiying Wang 137a9d39e30SKuiying Wang return 0; 138a9d39e30SKuiying Wang } 139a9d39e30SKuiying Wang 140a9d39e30SKuiying Wang private: 141a9d39e30SKuiying Wang int fd; 142a9d39e30SKuiying Wang sdbusplus::bus::bus& bus; 143a9d39e30SKuiying Wang EventPtr& event; 144a9d39e30SKuiying Wang sd_event_io_handler_t callbackHandler; 145a9d39e30SKuiying Wang }; 146