1 #include "util.hpp" 2 3 #include <gpiod.hpp> 4 5 namespace phosphor::power::psu 6 { 7 8 const UtilBase& getUtils() 9 { 10 static Util util; 11 return util; 12 } 13 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 31 std::unique_ptr<GPIOInterfaceBase> GPIOInterface::createGPIO( 32 const std::string& namedGpio) 33 { 34 return std::make_unique<GPIOInterface>(namedGpio); 35 } 36 37 std::string GPIOInterface::getName() const 38 { 39 return line.name(); 40 } 41 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 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 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 110 std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio) 111 { 112 return GPIOInterface::createGPIO(namedGpio); 113 } 114 115 } // namespace phosphor::power::psu 116