blob: 35c35cad79e087eb083ca02ee0c2444e5b118ab4 [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{
B. J. Wyman681b2a32021-04-20 22:31:22 +000044 int value = -1;
45
46 if (!line)
47 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000048 lg2::error("Failed line in GPIOInterface::read()");
B. J. Wyman681b2a32021-04-20 22:31:22 +000049 throw std::runtime_error{std::string{"Failed to find line"}};
50 }
51
52 try
53 {
54 line.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT,
55 gpiod::line_request::FLAG_ACTIVE_LOW});
56 try
57 {
58 value = line.get_value();
59 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050060 catch (const std::exception& e)
B. J. Wyman681b2a32021-04-20 22:31:22 +000061 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000062 lg2::error("Failed to get_value of GPIO line: {ERROR}", "ERROR", e);
B. J. Wyman681b2a32021-04-20 22:31:22 +000063 line.release();
64 throw;
65 }
66
B. J. Wyman681b2a32021-04-20 22:31:22 +000067 line.release();
68 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050069 catch (const std::exception& e)
B. J. Wyman681b2a32021-04-20 22:31:22 +000070 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000071 lg2::error("Failed to request GPIO line: {MSG}", "MSG", e);
B. J. Wyman681b2a32021-04-20 22:31:22 +000072 throw;
73 }
74
75 return value;
76}
77
Adriana Kobylak52245b62021-09-13 15:46:21 +000078void GPIOInterface::write(int value, std::bitset<32> flags)
79{
Adriana Kobylak52245b62021-09-13 15:46:21 +000080 if (!line)
81 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000082 lg2::error("Failed line in GPIOInterface::write");
Adriana Kobylak52245b62021-09-13 15:46:21 +000083 throw std::runtime_error{std::string{"Failed to find line"}};
84 }
85
86 try
87 {
Patrick Williamsf5402192024-08-16 15:20:53 -040088 line.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT,
89 flags},
90 value);
Adriana Kobylak52245b62021-09-13 15:46:21 +000091
92 line.release();
93 }
94 catch (std::exception& e)
95 {
Anwaar Hadib64228d2025-05-30 23:55:26 +000096 lg2::error("Failed to set GPIO line, MSG={MSG}, VALUE={VALUE}", "MSG",
97 e, "VALUE", value);
Adriana Kobylak52245b62021-09-13 15:46:21 +000098 throw;
99 }
100}
101
Brandon Wyman18a24d92022-04-19 22:48:34 +0000102void GPIOInterface::toggleLowHigh(const std::chrono::milliseconds& delay)
103{
104 auto flags = gpiod::line_request::FLAG_OPEN_DRAIN;
105 write(0, flags);
106 std::this_thread::sleep_for(delay);
107 write(1, flags);
108}
109
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000110std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio)
B. J. Wyman681b2a32021-04-20 22:31:22 +0000111{
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000112 return GPIOInterface::createGPIO(namedGpio);
B. J. Wyman681b2a32021-04-20 22:31:22 +0000113}
114
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600115} // namespace phosphor::power::psu