1 /**
2  * Copyright © 2024 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "ucd90160_device.hpp"
18 
19 #include "format_utils.hpp"
20 #include "standard_device.hpp"
21 
22 #include <algorithm>
23 #include <array>
24 #include <format>
25 #include <span>
26 
27 namespace phosphor::power::sequencer
28 {
29 
30 /**
31  * UCD90160 GPIO names.
32  *
33  * The array indices correspond to the Pin IDs defined in the UCD90160 PMBus
34  * interface documentation.  These Pin IDs are the same as the libgpiod line
35  * offsets used to obtain the GPIO values.
36  */
37 static constexpr std::array<const char*, 26> gpioNames = {
38     "FPWM1_GPIO5", "FPWM2_GPIO6",  "FPWM3_GPIO7",  "FPWM4_GPIO8",
39     "FPWM5_GPIO9", "FPWM6_GPIO10", "FPWM7_GPIO11", "FPWM8_GPIO12",
40     "GPI1_PWM1",   "GPI2_PWM2",    "GPI3_PWM3",    "GPI4_PWM4",
41     "GPIO14",      "GPIO15",       "TDO_GPIO20",   "TCK_GPIO19",
42     "TMS_GPIO22",  "TDI_GPIO21",   "GPIO1",        "GPIO2",
43     "GPIO3",       "GPIO4",        "GPIO13",       "GPIO16",
44     "GPIO17",      "GPIO18"};
45 
46 void UCD90160Device::storeGPIOValues(
47     Services& services, const std::vector<int>& values,
48     std::map<std::string, std::string>& additionalData)
49 {
50     // Verify the expected number of GPIO values were passed in
51     if (values.size() != gpioNames.size())
52     {
53         // Unexpected number of values; store as a plain list of integers
54         StandardDevice::storeGPIOValues(services, values, additionalData);
55         return;
56     }
57 
58     // Store GPIO names and values in additional data and journal.
59     // Use groups of GPIOs in journal to minimize number of entries.
60     services.logInfoMsg(std::format("Device {} GPIO values:", name));
61     unsigned int groupSize{4};
62     auto namesSpan = std::span{gpioNames};
63     auto valuesSpan = std::span{values};
64     std::string namesStr, valuesStr;
65     for (unsigned int i = 0; i < gpioNames.size(); ++i)
66     {
67         additionalData.emplace(gpioNames[i], std::format("{}", values[i]));
68         if ((i % groupSize) == 0)
69         {
70             unsigned int gpiosLeft = gpioNames.size() - i;
71             unsigned int count = std::min(groupSize, gpiosLeft);
72             namesStr = format_utils::toString(namesSpan.subspan(i, count));
73             valuesStr = format_utils::toString(valuesSpan.subspan(i, count));
74             services.logInfoMsg(std::format("{}: {}", namesStr, valuesStr));
75         }
76     }
77 }
78 
79 } // namespace phosphor::power::sequencer
80