xref: /openbmc/gpioplus/src/gpioplus/utility/aspeed.hpp (revision 8ff581220aaf38edda428d37ed1fe3151c0542d9)
1 #pragma once
2 #include <stdexcept>
3 #include <string_view>
4 
5 namespace gpioplus
6 {
7 namespace utility
8 {
9 namespace aspeed
10 {
11 
12 /** @brief Converts an aspeed gpio label name into an offset usable
13  *         by a gpioplus line.
14  *         Ex. GPION3 -> nameToOffset("N3") -> 107
15  *
16  *         NOTE: This function is constexpr, but uses exceptions for error
17  *         cases. If you want compile time guarantees of validity, make sure
18  *         you assign to a constexpr lvalue. Otherwise the error will be
19  *         resolved at runtime.
20  *         Ex. constexpr uint32_t offset = nameToOffset("A7");
21  *
22  *  @param[in] name - The gpio chip which provides the events
23  *  @throws std::logic_error when provided an invalid name.
24  *  @return
25  */
26 constexpr uint32_t nameToOffset(std::string_view name)
27 {
28     // Validate the name [A-Z]+[0-9]
29     if (name.length() < 2)
30     {
31         throw std::logic_error("GPIO name is too short");
32     }
33 
34     char octal = name[name.length() - 1];
35     if (octal < '0' || octal > '7')
36     {
37         throw std::logic_error("GPIO name must end with an octal");
38     }
39 
40     auto letters = name.substr(0, name.length() - 1);
41     for (auto letter : letters)
42     {
43         if (letter < 'A' || letter > 'Z')
44         {
45             throw std::logic_error("GPIO name must start with letters");
46         }
47     }
48 
49     // Limit the gpio to reasonable values
50     // Current chips have no more than AB7 or 224 gpios
51     if (name.length() > 3 || (name.length() == 3 && name[0] != 'A'))
52     {
53         throw std::logic_error("GPIO name probably not valid");
54     }
55 
56     uint32_t offset = 0;
57     for (auto letter : letters)
58     {
59         offset = offset * 26 + (letter - 'A') + 1;
60     }
61     offset = (offset - 1) * 8 + (octal - '0');
62     return offset;
63 }
64 
65 } // namespace aspeed
66 } // namespace utility
67 } // namespace gpioplus
68