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