blob: 1affa62e5f74f71bce6eff0b1e25e2f266d80120 [file] [log] [blame]
Alpana Kumarib17dd3b2020-10-01 00:18:10 -05001#include "gpioMonitor.hpp"
2
3#include "common_utility.hpp"
4#include "ibm_vpd_utils.hpp"
5
Sunny Srivastava523af2e2022-02-14 07:30:10 -06006#include <boost/asio.hpp>
7#include <boost/bind/bind.hpp>
Alpana Kumarib17dd3b2020-10-01 00:18:10 -05008#include <gpiod.hpp>
Alpana Kumarib17dd3b2020-10-01 00:18:10 -05009
10using namespace std;
11using namespace openpower::vpd::constants;
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050012
13namespace openpower
14{
15namespace vpd
16{
17namespace manager
18{
19
20bool GpioEventHandler::getPresencePinValue()
21{
22 Byte gpioData = 1;
23 gpiod::line presenceLine = gpiod::find_line(presencePin);
24 if (!presenceLine)
25 {
26 cerr << "Error getPresencePinValue: couldn't find presence line:"
27 << presencePin << " on GPIO \n";
28 // return previous state as we couldn't read current state
29 return prevPresPinValue;
30 }
31
32 presenceLine.request(
33 {"Op-panel presence line", gpiod::line_request::DIRECTION_INPUT, 0});
34
35 gpioData = presenceLine.get_value();
36
37 return gpioData;
38}
39
Sunny Srivastava523af2e2022-02-14 07:30:10 -060040void GpioMonitor::initGpioInfos(
41 std::shared_ptr<boost::asio::io_context>& ioContext)
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050042{
43 Byte outputValue = 0;
44 Byte presenceValue = 0;
45 string presencePinName{}, outputPinName{};
46 string devNameAddr{}, driverType{}, busType{}, objectPath{};
47
48 for (const auto& eachFRU : jsonFile["frus"].items())
49 {
50 for (const auto& eachInventory : eachFRU.value())
51 {
52 objectPath = eachInventory["inventoryPath"];
53
54 if ((eachInventory.find("presence") != eachInventory.end()) &&
55 (eachInventory.find("preAction") != eachInventory.end()))
56 {
Alpana Kumari187bc272022-02-10 23:18:09 -060057 if (!eachInventory["presence"].value("pollingRequired", false))
58 {
59 // Polling not required for this FRU , skip.
60 continue;
61 }
62
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050063 for (const auto& presStatus : eachInventory["presence"].items())
64 {
65 if (presStatus.key() == "pin")
66 {
67 presencePinName = presStatus.value();
68 }
69 else if (presStatus.key() == "value")
70 {
71 presenceValue = presStatus.value();
72 }
73 }
74
75 // Based on presence pin value, preAction pin will be set/reset
76 // This action will be taken before vpd collection.
77 for (const auto& preAction : eachInventory["preAction"].items())
78 {
79 if (preAction.key() == "pin")
80 {
81 outputPinName = preAction.value();
82 }
83 else if (preAction.key() == "value")
84 {
85 outputValue = preAction.value();
86 }
87 }
88
Alpana Kumari64b9f5f2022-02-19 13:25:58 -060089 if ((eachInventory.find("devAddress") != eachInventory.end()) &&
90 (eachInventory.find("driverType") != eachInventory.end()) &&
91 (eachInventory.find("busType") != eachInventory.end()))
92 {
93 devNameAddr = eachInventory["devAddress"];
94 driverType = eachInventory["driverType"];
95 busType = eachInventory["busType"];
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050096
Alpana Kumari64b9f5f2022-02-19 13:25:58 -060097 // Init all Gpio info variables
98 std::shared_ptr<GpioEventHandler> gpioObj =
99 make_shared<GpioEventHandler>(
100 presencePinName, presenceValue, outputPinName,
101 outputValue, devNameAddr, driverType, busType,
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600102 objectPath, ioContext);
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500103
Alpana Kumari64b9f5f2022-02-19 13:25:58 -0600104 gpioObjects.push_back(gpioObj);
105 }
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500106 }
107 }
108 }
109}
110
111void GpioEventHandler::toggleGpio()
112{
113 bool presPinVal = getPresencePinValue();
114 bool isPresent = false;
115
116 // preserve the new value
117 prevPresPinValue = presPinVal;
118
119 if (presPinVal == presenceValue)
120 {
121 isPresent = true;
122 }
123
124 // if FRU went away set the present property to false
125 if (!isPresent)
126 {
127 inventory::ObjectMap objects;
128 inventory::InterfaceMap interfaces;
129 inventory::PropertyMap presProp;
130
131 presProp.emplace("Present", false);
132 interfaces.emplace("xyz.openbmc_project.Inventory.Item", presProp);
133 objects.emplace(objectPath, move(interfaces));
134
135 common::utility::callPIM(move(objects));
136 }
137
138 gpiod::line outputLine = gpiod::find_line(outputPin);
139 if (!outputLine)
140 {
141 cerr << "Error: toggleGpio: couldn't find output line:" << outputPin
142 << ". Skipping update\n";
143
144 return;
145 }
146
147 outputLine.request({"FRU presence: update the output GPIO pin",
148 gpiod::line_request::DIRECTION_OUTPUT, 0},
149 isPresent ? outputValue : (!outputValue));
150
151 string cmnd = createBindUnbindDriverCmnd(devNameAddr, busType, driverType,
152 isPresent ? "bind" : "unbind");
153
154 cout << cmnd << endl;
155 executeCmd(cmnd);
156}
157
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600158void GpioEventHandler::handleTimerExpiry(
159 const boost::system::error_code& ec,
160 std::shared_ptr<boost::asio::steady_timer>& timer)
161{
162 if (ec == boost::asio::error::operation_aborted)
163 {
164 return;
165 }
166
167 if (ec)
168 {
169 std::cerr << "Timer wait failed for gpio pin" << ec.message();
170 return;
171 }
172
173 if (hasEventOccurred())
174 {
175 toggleGpio();
176 }
177 timer->expires_at(std::chrono::steady_clock::now() +
178 std::chrono::seconds(5));
179 timer->async_wait(boost::bind(&GpioEventHandler::handleTimerExpiry, this,
180 boost::asio::placeholders::error, timer));
181}
182
183void GpioEventHandler::doEventAndTimerSetup(
184 std::shared_ptr<boost::asio::io_context>& ioContext)
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500185{
186 prevPresPinValue = getPresencePinValue();
187
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600188 static vector<std::shared_ptr<boost::asio::steady_timer>> timers;
189
190 auto timer = make_shared<boost::asio::steady_timer>(
191 *ioContext, std::chrono::seconds(5));
192
193 timer->async_wait(boost::bind(&GpioEventHandler::handleTimerExpiry, this,
194 boost::asio::placeholders::error, timer));
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500195
196 timers.push_back(timer);
197}
198
199} // namespace manager
200} // namespace vpd
201} // namespace openpower