xref: /openbmc/phosphor-power/phosphor-power-supply/util.cpp (revision f8e8bc19fa720b6b348a3dddefd8eca7650b3e26)
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     int value = -1;
45 
46     if (!line)
47     {
48         lg2::error("Failed line in GPIOInterface::read()");
49         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         }
60         catch (const std::exception& e)
61         {
62             lg2::error("Failed to get_value of GPIO line: {ERROR}", "ERROR", e);
63             line.release();
64             throw;
65         }
66 
67         line.release();
68     }
69     catch (const std::exception& e)
70     {
71         lg2::error("Failed to request GPIO line: {MSG}", "MSG", e);
72         throw;
73     }
74 
75     return value;
76 }
77 
write(int value,std::bitset<32> flags)78 void GPIOInterface::write(int value, std::bitset<32> flags)
79 {
80     if (!line)
81     {
82         lg2::error("Failed line in GPIOInterface::write");
83         throw std::runtime_error{std::string{"Failed to find line"}};
84     }
85 
86     try
87     {
88         line.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT,
89                       flags},
90                      value);
91 
92         line.release();
93     }
94     catch (std::exception& e)
95     {
96         lg2::error("Failed to set GPIO line, MSG={MSG}, VALUE={VALUE}", "MSG",
97                    e, "VALUE", value);
98         throw;
99     }
100 }
101 
toggleLowHigh(const std::chrono::milliseconds & delay)102 void 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 
createGPIO(const std::string & namedGpio)110 std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio)
111 {
112     return GPIOInterface::createGPIO(namedGpio);
113 }
114 
115 } // namespace phosphor::power::psu
116