1 #include "util.hpp"
2
3 #include <gpiod.hpp>
4
5 namespace phosphor::power::psu
6 {
7
getUtils()8 const UtilBase& getUtils()
9 {
10 static Util util;
11 return util;
12 }
13
GPIOInterface(const std::string & namedGpio)14 GPIOInterface::GPIOInterface(const std::string& namedGpio)
15 {
16 try
17 {
18 line = gpiod::find_line(namedGpio);
19 if (!line)
20 {
21 throw std::runtime_error("Line does not exist: " + namedGpio);
22 }
23 }
24 catch (const std::exception& e)
25 {
26 throw std::runtime_error(
27 std::string("Failed to find line: ") + e.what());
28 }
29 }
30
createGPIO(const std::string & namedGpio)31 std::unique_ptr<GPIOInterfaceBase> GPIOInterface::createGPIO(
32 const std::string& namedGpio)
33 {
34 return std::make_unique<GPIOInterface>(namedGpio);
35 }
36
getName() const37 std::string GPIOInterface::getName() const
38 {
39 return line.name();
40 }
41
read()42 int GPIOInterface::read()
43 {
44 using namespace phosphor::logging;
45
46 int value = -1;
47
48 if (!line)
49 {
50 log<level::ERR>("Failed line");
51 throw std::runtime_error{std::string{"Failed to find line"}};
52 }
53
54 try
55 {
56 line.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT,
57 gpiod::line_request::FLAG_ACTIVE_LOW});
58 try
59 {
60 value = line.get_value();
61 }
62 catch (const std::exception& e)
63 {
64 log<level::ERR>(
65 std::format("Failed to get_value of GPIO line: {}", e.what())
66 .c_str());
67 line.release();
68 throw;
69 }
70
71 line.release();
72 }
73 catch (const std::exception& e)
74 {
75 log<level::ERR>("Failed to request GPIO line",
76 entry("MSG=%s", e.what()));
77 throw;
78 }
79
80 return value;
81 }
82
write(int value,std::bitset<32> flags)83 void GPIOInterface::write(int value, std::bitset<32> flags)
84 {
85 using namespace phosphor::logging;
86
87 if (!line)
88 {
89 log<level::ERR>("Failed line");
90 throw std::runtime_error{std::string{"Failed to find line"}};
91 }
92
93 try
94 {
95 line.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT,
96 flags},
97 value);
98
99 line.release();
100 }
101 catch (std::exception& e)
102 {
103 log<level::ERR>("Failed to set GPIO line", entry("MSG=%s", e.what()),
104 entry("VALUE=%d", value));
105 throw;
106 }
107 }
108
toggleLowHigh(const std::chrono::milliseconds & delay)109 void GPIOInterface::toggleLowHigh(const std::chrono::milliseconds& delay)
110 {
111 auto flags = gpiod::line_request::FLAG_OPEN_DRAIN;
112 write(0, flags);
113 std::this_thread::sleep_for(delay);
114 write(1, flags);
115 }
116
createGPIO(const std::string & namedGpio)117 std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio)
118 {
119 return GPIOInterface::createGPIO(namedGpio);
120 }
121
122 } // namespace phosphor::power::psu
123