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(std::string("Failed to find line: ") + 27 e.what()); 28 } 29 } 30 31 std::unique_ptr<GPIOInterfaceBase> 32 GPIOInterface::createGPIO(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 using namespace phosphor::logging; 45 46 int value = -1; 47 48 if (!line) 49 { 50 log<level::ERR>("Failed line"); 51 throw std::runtime_error{std::string{"Failed to find line"}}; 52 } 53 54 try 55 { 56 line.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT, 57 gpiod::line_request::FLAG_ACTIVE_LOW}); 58 try 59 { 60 value = line.get_value(); 61 } 62 catch (const std::exception& e) 63 { 64 log<level::ERR>( 65 fmt::format("Failed to get_value of GPIO line: {}", e.what()) 66 .c_str()); 67 line.release(); 68 throw; 69 } 70 71 line.release(); 72 } 73 catch (const std::exception& e) 74 { 75 log<level::ERR>("Failed to request GPIO line", 76 entry("MSG=%s", e.what())); 77 throw; 78 } 79 80 return value; 81 } 82 83 void GPIOInterface::write(int value, std::bitset<32> flags) 84 { 85 using namespace phosphor::logging; 86 87 if (!line) 88 { 89 log<level::ERR>("Failed line"); 90 throw std::runtime_error{std::string{"Failed to find line"}}; 91 } 92 93 try 94 { 95 line.request( 96 {__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT, flags}, 97 value); 98 99 line.release(); 100 } 101 catch (std::exception& e) 102 { 103 log<level::ERR>("Failed to set GPIO line", entry("MSG=%s", e.what()), 104 entry("VALUE=%d", value)); 105 throw; 106 } 107 } 108 109 void GPIOInterface::toggleLowHigh(const std::chrono::milliseconds& delay) 110 { 111 auto flags = gpiod::line_request::FLAG_OPEN_DRAIN; 112 write(0, flags); 113 std::this_thread::sleep_for(delay); 114 write(1, flags); 115 } 116 117 std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio) 118 { 119 return GPIOInterface::createGPIO(namedGpio); 120 } 121 122 } // namespace phosphor::power::psu 123