blob: 503e1c3b8e8c0dbbea24fd08fa3cc40ba2258a2a [file] [log] [blame]
Brandon Wyman3f1242f2020-01-28 13:11:25 -06001#include "util.hpp"
2
B. J. Wyman681b2a32021-04-20 22:31:22 +00003#include <gpiod.hpp>
4
Brandon Wyman3f1242f2020-01-28 13:11:25 -06005namespace phosphor::power::psu
6{
7
8const UtilBase& getUtils()
9{
10 static Util util;
11 return util;
12}
13
Adriana Kobylak3ca062a2021-10-20 15:27:23 +000014GPIOInterface::GPIOInterface(const std::string& namedGpio)
B. J. Wyman681b2a32021-04-20 22:31:22 +000015{
16 try
17 {
18 line = gpiod::find_line(namedGpio);
Adriana Kobylaka588eaf2021-09-20 20:05:25 +000019 if (!line)
20 {
21 throw std::runtime_error("Line does not exist: " + namedGpio);
22 }
B. J. Wyman681b2a32021-04-20 22:31:22 +000023 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050024 catch (const std::exception& e)
B. J. Wyman681b2a32021-04-20 22:31:22 +000025 {
Adriana Kobylakc0a07582021-10-13 15:52:25 +000026 throw std::runtime_error(std::string("Failed to find line: ") +
27 e.what());
B. J. Wyman681b2a32021-04-20 22:31:22 +000028 }
29}
30
Adriana Kobylak3ca062a2021-10-20 15:27:23 +000031std::unique_ptr<GPIOInterfaceBase>
32 GPIOInterface::createGPIO(const std::string& namedGpio)
B. J. Wyman681b2a32021-04-20 22:31:22 +000033{
Adriana Kobylak3ca062a2021-10-20 15:27:23 +000034 return std::make_unique<GPIOInterface>(namedGpio);
B. J. Wyman681b2a32021-04-20 22:31:22 +000035}
36
Adriana Kobylak3ca062a2021-10-20 15:27:23 +000037std::string GPIOInterface::getName() const
B. J. Wymand8b8cb12021-07-15 22:03:34 +000038{
39 return line.name();
40}
41
Adriana Kobylak3ca062a2021-10-20 15:27:23 +000042int GPIOInterface::read()
B. J. Wyman681b2a32021-04-20 22:31:22 +000043{
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 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050062 catch (const std::exception& e)
B. J. Wyman681b2a32021-04-20 22:31:22 +000063 {
64 log<level::ERR>(
65 fmt::format("Failed to get_value of GPIO line: {}", e.what())
66 .c_str());
67 line.release();
68 throw;
69 }
70
B. J. Wyman681b2a32021-04-20 22:31:22 +000071 line.release();
72 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050073 catch (const std::exception& e)
B. J. Wyman681b2a32021-04-20 22:31:22 +000074 {
75 log<level::ERR>("Failed to request GPIO line",
76 entry("MSG=%s", e.what()));
77 throw;
78 }
79
80 return value;
81}
82
Adriana Kobylak52245b62021-09-13 15:46:21 +000083void 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(
96 {__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT, 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
Brandon Wyman18a24d92022-04-19 22:48:34 +0000109void 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
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000117std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio)
B. J. Wyman681b2a32021-04-20 22:31:22 +0000118{
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000119 return GPIOInterface::createGPIO(namedGpio);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000120}
121
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600122} // namespace phosphor::power::psu