xref: /openbmc/gpioplus/src/gpioplus/utility/aspeed.hpp (revision 0ceda043fa13a077e940ad15e6865e26e5e16e88)
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 III constexpr 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