xref: /openbmc/phosphor-power/phosphor-power-supply/util.cpp (revision f54021972b91be5058b50e9046bb0dd5a3b22a80)
13f1242f3SBrandon Wyman #include "util.hpp"
23f1242f3SBrandon Wyman 
3681b2a36SB. J. Wyman #include <gpiod.hpp>
4681b2a36SB. J. Wyman 
53f1242f3SBrandon Wyman namespace phosphor::power::psu
63f1242f3SBrandon Wyman {
73f1242f3SBrandon Wyman 
getUtils()83f1242f3SBrandon Wyman const UtilBase& getUtils()
93f1242f3SBrandon Wyman {
103f1242f3SBrandon Wyman     static Util util;
113f1242f3SBrandon Wyman     return util;
123f1242f3SBrandon Wyman }
133f1242f3SBrandon Wyman 
GPIOInterface(const std::string & namedGpio)143ca062aeSAdriana Kobylak GPIOInterface::GPIOInterface(const std::string& namedGpio)
15681b2a36SB. J. Wyman {
16681b2a36SB. J. Wyman     try
17681b2a36SB. J. Wyman     {
18681b2a36SB. J. Wyman         line = gpiod::find_line(namedGpio);
19a588eafeSAdriana Kobylak         if (!line)
20a588eafeSAdriana Kobylak         {
21a588eafeSAdriana Kobylak             throw std::runtime_error("Line does not exist: " + namedGpio);
22a588eafeSAdriana Kobylak         }
23681b2a36SB. J. Wyman     }
24c1d4de5eSPatrick Williams     catch (const std::exception& e)
25681b2a36SB. J. Wyman     {
26*f5402197SPatrick Williams         throw std::runtime_error(
27*f5402197SPatrick Williams             std::string("Failed to find line: ") + e.what());
28681b2a36SB. J. Wyman     }
29681b2a36SB. J. Wyman }
30681b2a36SB. J. Wyman 
313ca062aeSAdriana Kobylak std::unique_ptr<GPIOInterfaceBase>
createGPIO(const std::string & namedGpio)323ca062aeSAdriana Kobylak     GPIOInterface::createGPIO(const std::string& namedGpio)
33681b2a36SB. J. Wyman {
343ca062aeSAdriana Kobylak     return std::make_unique<GPIOInterface>(namedGpio);
35681b2a36SB. J. Wyman }
36681b2a36SB. J. Wyman 
getName() const373ca062aeSAdriana Kobylak std::string GPIOInterface::getName() const
38d8b8cb15SB. J. Wyman {
39d8b8cb15SB. J. Wyman     return line.name();
40d8b8cb15SB. J. Wyman }
41d8b8cb15SB. J. Wyman 
read()423ca062aeSAdriana Kobylak int GPIOInterface::read()
43681b2a36SB. J. Wyman {
44681b2a36SB. J. Wyman     using namespace phosphor::logging;
45681b2a36SB. J. Wyman 
46681b2a36SB. J. Wyman     int value = -1;
47681b2a36SB. J. Wyman 
48681b2a36SB. J. Wyman     if (!line)
49681b2a36SB. J. Wyman     {
50681b2a36SB. J. Wyman         log<level::ERR>("Failed line");
51681b2a36SB. J. Wyman         throw std::runtime_error{std::string{"Failed to find line"}};
52681b2a36SB. J. Wyman     }
53681b2a36SB. J. Wyman 
54681b2a36SB. J. Wyman     try
55681b2a36SB. J. Wyman     {
56681b2a36SB. J. Wyman         line.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT,
57681b2a36SB. J. Wyman                       gpiod::line_request::FLAG_ACTIVE_LOW});
58681b2a36SB. J. Wyman         try
59681b2a36SB. J. Wyman         {
60681b2a36SB. J. Wyman             value = line.get_value();
61681b2a36SB. J. Wyman         }
62c1d4de5eSPatrick Williams         catch (const std::exception& e)
63681b2a36SB. J. Wyman         {
64681b2a36SB. J. Wyman             log<level::ERR>(
65768d2269SShawn McCarney                 std::format("Failed to get_value of GPIO line: {}", e.what())
66681b2a36SB. J. Wyman                     .c_str());
67681b2a36SB. J. Wyman             line.release();
68681b2a36SB. J. Wyman             throw;
69681b2a36SB. J. Wyman         }
70681b2a36SB. J. Wyman 
71681b2a36SB. J. Wyman         line.release();
72681b2a36SB. J. Wyman     }
73c1d4de5eSPatrick Williams     catch (const std::exception& e)
74681b2a36SB. J. Wyman     {
75681b2a36SB. J. Wyman         log<level::ERR>("Failed to request GPIO line",
76681b2a36SB. J. Wyman                         entry("MSG=%s", e.what()));
77681b2a36SB. J. Wyman         throw;
78681b2a36SB. J. Wyman     }
79681b2a36SB. J. Wyman 
80681b2a36SB. J. Wyman     return value;
81681b2a36SB. J. Wyman }
82681b2a36SB. J. Wyman 
write(int value,std::bitset<32> flags)8352245b69SAdriana Kobylak void GPIOInterface::write(int value, std::bitset<32> flags)
8452245b69SAdriana Kobylak {
8552245b69SAdriana Kobylak     using namespace phosphor::logging;
8652245b69SAdriana Kobylak 
8752245b69SAdriana Kobylak     if (!line)
8852245b69SAdriana Kobylak     {
8952245b69SAdriana Kobylak         log<level::ERR>("Failed line");
9052245b69SAdriana Kobylak         throw std::runtime_error{std::string{"Failed to find line"}};
9152245b69SAdriana Kobylak     }
9252245b69SAdriana Kobylak 
9352245b69SAdriana Kobylak     try
9452245b69SAdriana Kobylak     {
95*f5402197SPatrick Williams         line.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT,
96*f5402197SPatrick Williams                       flags},
9752245b69SAdriana Kobylak                      value);
9852245b69SAdriana Kobylak 
9952245b69SAdriana Kobylak         line.release();
10052245b69SAdriana Kobylak     }
10152245b69SAdriana Kobylak     catch (std::exception& e)
10252245b69SAdriana Kobylak     {
10352245b69SAdriana Kobylak         log<level::ERR>("Failed to set GPIO line", entry("MSG=%s", e.what()),
10452245b69SAdriana Kobylak                         entry("VALUE=%d", value));
10552245b69SAdriana Kobylak         throw;
10652245b69SAdriana Kobylak     }
10752245b69SAdriana Kobylak }
10852245b69SAdriana Kobylak 
toggleLowHigh(const std::chrono::milliseconds & delay)10918a24d92SBrandon Wyman void GPIOInterface::toggleLowHigh(const std::chrono::milliseconds& delay)
11018a24d92SBrandon Wyman {
11118a24d92SBrandon Wyman     auto flags = gpiod::line_request::FLAG_OPEN_DRAIN;
11218a24d92SBrandon Wyman     write(0, flags);
11318a24d92SBrandon Wyman     std::this_thread::sleep_for(delay);
11418a24d92SBrandon Wyman     write(1, flags);
11518a24d92SBrandon Wyman }
11618a24d92SBrandon Wyman 
createGPIO(const std::string & namedGpio)1173ca062aeSAdriana Kobylak std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio)
118681b2a36SB. J. Wyman {
1193ca062aeSAdriana Kobylak     return GPIOInterface::createGPIO(namedGpio);
120681b2a36SB. J. Wyman }
121681b2a36SB. J. Wyman 
1223f1242f3SBrandon Wyman } // namespace phosphor::power::psu
123