1b54357f6SMatt Spinler #pragma once
2b54357f6SMatt Spinler 
3b54357f6SMatt Spinler #include <algorithm>
4110b2841SMatt Spinler #include <experimental/filesystem>
5b54357f6SMatt Spinler #include <map>
6b54357f6SMatt Spinler #include <vector>
7b54357f6SMatt Spinler #include "device.hpp"
8d998b736SMatt Spinler #include "gpio.hpp"
9b54357f6SMatt Spinler #include "pmbus.hpp"
10b54357f6SMatt Spinler #include "types.hpp"
11b54357f6SMatt Spinler 
12b54357f6SMatt Spinler namespace witherspoon
13b54357f6SMatt Spinler {
14b54357f6SMatt Spinler namespace power
15b54357f6SMatt Spinler {
16b54357f6SMatt Spinler 
17b54357f6SMatt Spinler /**
18b54357f6SMatt Spinler  * @class UCD90160
19b54357f6SMatt Spinler  *
20b54357f6SMatt Spinler  * This class implements fault analysis for the UCD90160
21b54357f6SMatt Spinler  * power sequencer device.
22b54357f6SMatt Spinler  *
23b54357f6SMatt Spinler  */
24b54357f6SMatt Spinler class UCD90160 : public Device
25b54357f6SMatt Spinler {
26b54357f6SMatt Spinler     public:
27b54357f6SMatt Spinler 
28b54357f6SMatt Spinler         UCD90160() = delete;
29b54357f6SMatt Spinler         ~UCD90160() = default;
30b54357f6SMatt Spinler         UCD90160(const UCD90160&) = delete;
31b54357f6SMatt Spinler         UCD90160& operator=(const UCD90160&) = delete;
32b54357f6SMatt Spinler         UCD90160(UCD90160&&) = default;
33b54357f6SMatt Spinler         UCD90160& operator=(UCD90160&&) = default;
34b54357f6SMatt Spinler 
35b54357f6SMatt Spinler         /**
36b54357f6SMatt Spinler          * Constructor
37b54357f6SMatt Spinler          *
38b54357f6SMatt Spinler          * @param[in] instance - the device instance number
39b54357f6SMatt Spinler          */
40b54357f6SMatt Spinler         UCD90160(size_t instance);
41b54357f6SMatt Spinler 
42b54357f6SMatt Spinler         /**
43b54357f6SMatt Spinler          * Analyzes the device for errors when the device is
44b54357f6SMatt Spinler          * known to be in an error state.  A log will be created.
45b54357f6SMatt Spinler          */
46b54357f6SMatt Spinler         void onFailure() override;
47b54357f6SMatt Spinler 
48b54357f6SMatt Spinler         /**
49b54357f6SMatt Spinler          * Checks the device for errors and only creates a log
50b54357f6SMatt Spinler          * if one is found.
51b54357f6SMatt Spinler          */
52b54357f6SMatt Spinler         void analyze() override;
53b54357f6SMatt Spinler 
54b54357f6SMatt Spinler         /**
55b54357f6SMatt Spinler          * Clears faults in the device
56b54357f6SMatt Spinler          */
5781be00b1SMatt Spinler         void clearFaults() override
5881be00b1SMatt Spinler         {
5981be00b1SMatt Spinler         }
60b54357f6SMatt Spinler 
61b54357f6SMatt Spinler     private:
62b54357f6SMatt Spinler 
63b54357f6SMatt Spinler         /**
64*7b14db24SMatt Spinler          * Reports an error for a GPU PGOOD failure
65*7b14db24SMatt Spinler          *
66*7b14db24SMatt Spinler          * @param[in] callout - the GPU callout string
67*7b14db24SMatt Spinler          */
68*7b14db24SMatt Spinler         void gpuPGOODError(const std::string& callout);
69*7b14db24SMatt Spinler 
70*7b14db24SMatt Spinler         /**
71*7b14db24SMatt Spinler          * Reports an error for a GPU OverTemp failure
72*7b14db24SMatt Spinler          *
73*7b14db24SMatt Spinler          * @param[in] callout - the GPU callout string
74*7b14db24SMatt Spinler          */
75*7b14db24SMatt Spinler         void gpuOverTempError(const std::string& callout);
76*7b14db24SMatt Spinler 
77*7b14db24SMatt Spinler         /**
78fcd4a719SMatt Spinler          * Given the device path for a chip, find its gpiochip
79fcd4a719SMatt Spinler          * path
80fcd4a719SMatt Spinler          *
81fcd4a719SMatt Spinler          * @param[in] path - device path, like
82fcd4a719SMatt Spinler          *                   /sys/devices/.../i2c-11/11-0064
83fcd4a719SMatt Spinler          *
84fcd4a719SMatt Spinler          * @return fs::path - The gpiochip path, like
85fcd4a719SMatt Spinler          *                   /dev/gpiochip1
86110b2841SMatt Spinler          */
87fcd4a719SMatt Spinler         static std::experimental::filesystem::path findGPIODevice(
88fcd4a719SMatt Spinler                 const std::experimental::filesystem::path& path);
89110b2841SMatt Spinler 
90110b2841SMatt Spinler         /**
91b54357f6SMatt Spinler          * Checks for VOUT faults on the device.
92b54357f6SMatt Spinler          *
93b54357f6SMatt Spinler          * This device can monitor voltages of its dependent
94b54357f6SMatt Spinler          * devices, and VOUT faults are voltage faults
95b54357f6SMatt Spinler          * on these devices.
96b54357f6SMatt Spinler          *
97b54357f6SMatt Spinler          * @return bool - true if an error log was created
98b54357f6SMatt Spinler          */
99b54357f6SMatt Spinler         bool checkVOUTFaults();
100b54357f6SMatt Spinler 
101b54357f6SMatt Spinler         /**
102b54357f6SMatt Spinler          * Checks for PGOOD faults on the device.
103b54357f6SMatt Spinler          *
104b54357f6SMatt Spinler          * This device can monitor the PGOOD signals of its dependent
105b54357f6SMatt Spinler          * devices, and this check will look for faults of
106b54357f6SMatt Spinler          * those PGOODs.
107b54357f6SMatt Spinler          *
108b54357f6SMatt Spinler          * @param[in] polling - If this is running while polling for errors,
109b54357f6SMatt Spinler          *                      as opposing to analyzing a fail condition.
110b54357f6SMatt Spinler          *
111b54357f6SMatt Spinler          * @return bool - true if an error log was created
112b54357f6SMatt Spinler          */
113b54357f6SMatt Spinler          bool checkPGOODFaults(bool polling);
114b54357f6SMatt Spinler 
115b54357f6SMatt Spinler         /**
116b54357f6SMatt Spinler          * Creates an error log when the device has an error
117b54357f6SMatt Spinler          * but it isn't a PGOOD or voltage failure.
118b54357f6SMatt Spinler          */
119b54357f6SMatt Spinler         void createPowerFaultLog();
120b54357f6SMatt Spinler 
121b54357f6SMatt Spinler         /**
122e7e432b4SMatt Spinler          * Reads the status_word register
123e7e432b4SMatt Spinler          *
124e7e432b4SMatt Spinler          * @return uint16_t - the register contents
125e7e432b4SMatt Spinler          */
126e7e432b4SMatt Spinler         uint16_t readStatusWord();
127e7e432b4SMatt Spinler 
128e7e432b4SMatt Spinler         /**
129e7e432b4SMatt Spinler          * Reads the mfr_status register
130e7e432b4SMatt Spinler          *
131e7e432b4SMatt Spinler          * @return uint32_t - the register contents
132e7e432b4SMatt Spinler          */
133e7e432b4SMatt Spinler         uint32_t readMFRStatus();
134e7e432b4SMatt Spinler 
135e7e432b4SMatt Spinler         /**
136e7e432b4SMatt Spinler          * Says if we've already logged a Vout fault
137e7e432b4SMatt Spinler          *
138e7e432b4SMatt Spinler          * The policy is only 1 of the same error will
139e7e432b4SMatt Spinler          * be logged for the duration of a class instance.
140e7e432b4SMatt Spinler          *
141e7e432b4SMatt Spinler          * @param[in] page - the page to check
142e7e432b4SMatt Spinler          *
143e7e432b4SMatt Spinler          * @return bool - if we've already logged a fault against
144e7e432b4SMatt Spinler          *                this page
145e7e432b4SMatt Spinler          */
146e7e432b4SMatt Spinler         inline bool isVoutFaultLogged(uint32_t page) const
147e7e432b4SMatt Spinler         {
148e7e432b4SMatt Spinler             return std::find(voutErrors.begin(),
149e7e432b4SMatt Spinler                              voutErrors.end(),
150e7e432b4SMatt Spinler                              page) != voutErrors.end();
151e7e432b4SMatt Spinler         }
152e7e432b4SMatt Spinler 
153e7e432b4SMatt Spinler         /**
154e7e432b4SMatt Spinler          * Saves that a Vout fault has been logged
155e7e432b4SMatt Spinler          *
156e7e432b4SMatt Spinler          * @param[in] page - the page the error was logged against
157e7e432b4SMatt Spinler          */
158e7e432b4SMatt Spinler         inline void setVoutFaultLogged(uint32_t page)
159e7e432b4SMatt Spinler         {
160e7e432b4SMatt Spinler             voutErrors.push_back(page);
161e7e432b4SMatt Spinler         }
162e7e432b4SMatt Spinler 
163e7e432b4SMatt Spinler         /**
164d998b736SMatt Spinler          * Says if we've already logged a PGOOD fault
165d998b736SMatt Spinler          *
166d998b736SMatt Spinler          * The policy is only 1 of the same errors will
167d998b736SMatt Spinler          * be logged for the duration of a class instance.
168d998b736SMatt Spinler          *
169d998b736SMatt Spinler          * @param[in] input - the input to check
170d998b736SMatt Spinler          *
171d998b736SMatt Spinler          * @return bool - if we've already logged a fault against
172d998b736SMatt Spinler          *                this input
173d998b736SMatt Spinler          */
174d998b736SMatt Spinler         inline bool isPGOODFaultLogged(uint32_t input) const
175d998b736SMatt Spinler         {
176d998b736SMatt Spinler             return std::find(pgoodErrors.begin(),
177d998b736SMatt Spinler                              pgoodErrors.end(),
178d998b736SMatt Spinler                              input) != pgoodErrors.end();
179d998b736SMatt Spinler         }
180d998b736SMatt Spinler 
181d998b736SMatt Spinler         /**
182d998b736SMatt Spinler          * Saves that a PGOOD fault has been logged
183d998b736SMatt Spinler          *
184d998b736SMatt Spinler          * @param[in] input - the input the error was logged against
185d998b736SMatt Spinler          */
186d998b736SMatt Spinler         inline void setPGOODFaultLogged(uint32_t input)
187d998b736SMatt Spinler         {
188d998b736SMatt Spinler             pgoodErrors.push_back(input);
189d998b736SMatt Spinler         }
190d998b736SMatt Spinler 
191d998b736SMatt Spinler         /**
192e7e432b4SMatt Spinler          * List of pages that Vout errors have
193e7e432b4SMatt Spinler          * already been logged against
194e7e432b4SMatt Spinler          */
195e7e432b4SMatt Spinler         std::vector<uint32_t> voutErrors;
196e7e432b4SMatt Spinler 
197e7e432b4SMatt Spinler         /**
198d998b736SMatt Spinler          * List of inputs that PGOOD errors have
199d998b736SMatt Spinler          * already been logged against
200d998b736SMatt Spinler          */
201d998b736SMatt Spinler         std::vector<uint32_t> pgoodErrors;
202d998b736SMatt Spinler 
203d998b736SMatt Spinler         /**
204b54357f6SMatt Spinler          * The read/write interface to this hardware
205b54357f6SMatt Spinler          */
206b54357f6SMatt Spinler         pmbus::PMBus interface;
207b54357f6SMatt Spinler 
208b54357f6SMatt Spinler         /**
209d998b736SMatt Spinler          * A map of GPI pin IDs to the GPIO object
210d998b736SMatt Spinler          * used to access them
211d998b736SMatt Spinler          */
212d998b736SMatt Spinler         std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;
213d998b736SMatt Spinler 
214d998b736SMatt Spinler         /**
215b54357f6SMatt Spinler          * Keeps track of device access errors to avoid repeatedly
216b54357f6SMatt Spinler          * logging errors for bad hardware
217b54357f6SMatt Spinler          */
218b54357f6SMatt Spinler         bool accessError = false;
219b54357f6SMatt Spinler 
220b54357f6SMatt Spinler         /**
221110b2841SMatt Spinler          * The path to the GPIO device used to read
222110b2841SMatt Spinler          * the GPI (PGOOD) status
223110b2841SMatt Spinler          */
224110b2841SMatt Spinler         std::experimental::filesystem::path gpioDevice;
225110b2841SMatt Spinler 
226110b2841SMatt Spinler         /**
227b54357f6SMatt Spinler          * Map of device instance to the instance specific data
228b54357f6SMatt Spinler          */
229b54357f6SMatt Spinler         static const ucd90160::DeviceMap deviceMap;
230b54357f6SMatt Spinler };
231b54357f6SMatt Spinler 
232b54357f6SMatt Spinler }
233b54357f6SMatt Spinler }
234