blob: 73c7ff5a3cf5e6a6c15a42680e727b3e23521511 [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 {
Patrick Williamsf5402192024-08-16 15:20:53 -040026 throw std::runtime_error(
27 std::string("Failed to find line: ") + e.what());
B. J. Wyman681b2a32021-04-20 22:31:22 +000028 }
29}
30
Patrick Williams92261f82025-02-01 08:22:34 -050031std::unique_ptr<GPIOInterfaceBase> GPIOInterface::createGPIO(
32 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 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000050 lg2::error("Failed line in GPIOInterface::read()");
B. J. Wyman681b2a32021-04-20 22:31:22 +000051 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 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000064 lg2::error("Failed to get_value of GPIO line: {ERROR}", "ERROR", e);
B. J. Wyman681b2a32021-04-20 22:31:22 +000065 line.release();
66 throw;
67 }
68
B. J. Wyman681b2a32021-04-20 22:31:22 +000069 line.release();
70 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050071 catch (const std::exception& e)
B. J. Wyman681b2a32021-04-20 22:31:22 +000072 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000073 lg2::error("Failed to request GPIO line: {MSG}", "MSG", e);
B. J. Wyman681b2a32021-04-20 22:31:22 +000074 throw;
75 }
76
77 return value;
78}
79
Adriana Kobylak52245b62021-09-13 15:46:21 +000080void GPIOInterface::write(int value, std::bitset<32> flags)
81{
82 using namespace phosphor::logging;
83
84 if (!line)
85 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000086 lg2::error("Failed line in GPIOInterface::write");
Adriana Kobylak52245b62021-09-13 15:46:21 +000087 throw std::runtime_error{std::string{"Failed to find line"}};
88 }
89
90 try
91 {
Patrick Williamsf5402192024-08-16 15:20:53 -040092 line.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT,
93 flags},
94 value);
Adriana Kobylak52245b62021-09-13 15:46:21 +000095
96 line.release();
97 }
98 catch (std::exception& e)
99 {
Anwaar Hadib64228d2025-05-30 23:55:26 +0000100 lg2::error("Failed to set GPIO line, MSG={MSG}, VALUE={VALUE}", "MSG",
101 e, "VALUE", value);
Adriana Kobylak52245b62021-09-13 15:46:21 +0000102 throw;
103 }
104}
105
Brandon Wyman18a24d92022-04-19 22:48:34 +0000106void GPIOInterface::toggleLowHigh(const std::chrono::milliseconds& delay)
107{
108 auto flags = gpiod::line_request::FLAG_OPEN_DRAIN;
109 write(0, flags);
110 std::this_thread::sleep_for(delay);
111 write(1, flags);
112}
113
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000114std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio)
B. J. Wyman681b2a32021-04-20 22:31:22 +0000115{
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000116 return GPIOInterface::createGPIO(namedGpio);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000117}
118
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600119} // namespace phosphor::power::psu