18ff58122SWilliam A. Kennington III #pragma once 2*0ceda043SPatrick Williams #include <cstdint> 38ff58122SWilliam A. Kennington III #include <stdexcept> 48ff58122SWilliam A. Kennington III #include <string_view> 58ff58122SWilliam A. Kennington III 68ff58122SWilliam A. Kennington III namespace gpioplus 78ff58122SWilliam A. Kennington III { 88ff58122SWilliam A. Kennington III namespace utility 98ff58122SWilliam A. Kennington III { 108ff58122SWilliam A. Kennington III namespace aspeed 118ff58122SWilliam A. Kennington III { 128ff58122SWilliam A. Kennington III 138ff58122SWilliam A. Kennington III /** @brief Converts an aspeed gpio label name into an offset usable 148ff58122SWilliam A. Kennington III * by a gpioplus line. 158ff58122SWilliam A. Kennington III * Ex. GPION3 -> nameToOffset("N3") -> 107 168ff58122SWilliam A. Kennington III * 178ff58122SWilliam A. Kennington III * NOTE: This function is constexpr, but uses exceptions for error 188ff58122SWilliam A. Kennington III * cases. If you want compile time guarantees of validity, make sure 198ff58122SWilliam A. Kennington III * you assign to a constexpr lvalue. Otherwise the error will be 208ff58122SWilliam A. Kennington III * resolved at runtime. 218ff58122SWilliam A. Kennington III * Ex. constexpr uint32_t offset = nameToOffset("A7"); 228ff58122SWilliam A. Kennington III * 238ff58122SWilliam A. Kennington III * @param[in] name - The gpio chip which provides the events 248ff58122SWilliam A. Kennington III * @throws std::logic_error when provided an invalid name. 258ff58122SWilliam A. Kennington III * @return 268ff58122SWilliam A. Kennington III */ nameToOffset(std::string_view name)278ff58122SWilliam A. Kennington IIIconstexpr uint32_t nameToOffset(std::string_view name) 288ff58122SWilliam A. Kennington III { 298ff58122SWilliam A. Kennington III // Validate the name [A-Z]+[0-9] 308ff58122SWilliam A. Kennington III if (name.length() < 2) 318ff58122SWilliam A. Kennington III { 328ff58122SWilliam A. Kennington III throw std::logic_error("GPIO name is too short"); 338ff58122SWilliam A. Kennington III } 348ff58122SWilliam A. Kennington III 358ff58122SWilliam A. Kennington III char octal = name[name.length() - 1]; 368ff58122SWilliam A. Kennington III if (octal < '0' || octal > '7') 378ff58122SWilliam A. Kennington III { 388ff58122SWilliam A. Kennington III throw std::logic_error("GPIO name must end with an octal"); 398ff58122SWilliam A. Kennington III } 408ff58122SWilliam A. Kennington III 418ff58122SWilliam A. Kennington III auto letters = name.substr(0, name.length() - 1); 428ff58122SWilliam A. Kennington III for (auto letter : letters) 438ff58122SWilliam A. Kennington III { 448ff58122SWilliam A. Kennington III if (letter < 'A' || letter > 'Z') 458ff58122SWilliam A. Kennington III { 468ff58122SWilliam A. Kennington III throw std::logic_error("GPIO name must start with letters"); 478ff58122SWilliam A. Kennington III } 488ff58122SWilliam A. Kennington III } 498ff58122SWilliam A. Kennington III 508ff58122SWilliam A. Kennington III // Limit the gpio to reasonable values 518ff58122SWilliam A. Kennington III // Current chips have no more than AB7 or 224 gpios 528ff58122SWilliam A. Kennington III if (name.length() > 3 || (name.length() == 3 && name[0] != 'A')) 538ff58122SWilliam A. Kennington III { 548ff58122SWilliam A. Kennington III throw std::logic_error("GPIO name probably not valid"); 558ff58122SWilliam A. Kennington III } 568ff58122SWilliam A. Kennington III 578ff58122SWilliam A. Kennington III uint32_t offset = 0; 588ff58122SWilliam A. Kennington III for (auto letter : letters) 598ff58122SWilliam A. Kennington III { 608ff58122SWilliam A. Kennington III offset = offset * 26 + (letter - 'A') + 1; 618ff58122SWilliam A. Kennington III } 628ff58122SWilliam A. Kennington III offset = (offset - 1) * 8 + (octal - '0'); 638ff58122SWilliam A. Kennington III return offset; 648ff58122SWilliam A. Kennington III } 658ff58122SWilliam A. Kennington III 668ff58122SWilliam A. Kennington III } // namespace aspeed 678ff58122SWilliam A. Kennington III } // namespace utility 688ff58122SWilliam A. Kennington III } // namespace gpioplus 69