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*fcd4a719SMatt Spinler          * Given the device path for a chip, find its gpiochip
65*fcd4a719SMatt Spinler          * path
66*fcd4a719SMatt Spinler          *
67*fcd4a719SMatt Spinler          * @param[in] path - device path, like
68*fcd4a719SMatt Spinler          *                   /sys/devices/.../i2c-11/11-0064
69*fcd4a719SMatt Spinler          *
70*fcd4a719SMatt Spinler          * @return fs::path - The gpiochip path, like
71*fcd4a719SMatt Spinler          *                   /dev/gpiochip1
72110b2841SMatt Spinler          */
73*fcd4a719SMatt Spinler         static std::experimental::filesystem::path findGPIODevice(
74*fcd4a719SMatt Spinler                 const std::experimental::filesystem::path& path);
75110b2841SMatt Spinler 
76110b2841SMatt Spinler         /**
77b54357f6SMatt Spinler          * Checks for VOUT faults on the device.
78b54357f6SMatt Spinler          *
79b54357f6SMatt Spinler          * This device can monitor voltages of its dependent
80b54357f6SMatt Spinler          * devices, and VOUT faults are voltage faults
81b54357f6SMatt Spinler          * on these devices.
82b54357f6SMatt Spinler          *
83b54357f6SMatt Spinler          * @return bool - true if an error log was created
84b54357f6SMatt Spinler          */
85b54357f6SMatt Spinler         bool checkVOUTFaults();
86b54357f6SMatt Spinler 
87b54357f6SMatt Spinler         /**
88b54357f6SMatt Spinler          * Checks for PGOOD faults on the device.
89b54357f6SMatt Spinler          *
90b54357f6SMatt Spinler          * This device can monitor the PGOOD signals of its dependent
91b54357f6SMatt Spinler          * devices, and this check will look for faults of
92b54357f6SMatt Spinler          * those PGOODs.
93b54357f6SMatt Spinler          *
94b54357f6SMatt Spinler          * @param[in] polling - If this is running while polling for errors,
95b54357f6SMatt Spinler          *                      as opposing to analyzing a fail condition.
96b54357f6SMatt Spinler          *
97b54357f6SMatt Spinler          * @return bool - true if an error log was created
98b54357f6SMatt Spinler          */
99b54357f6SMatt Spinler          bool checkPGOODFaults(bool polling);
100b54357f6SMatt Spinler 
101b54357f6SMatt Spinler         /**
102b54357f6SMatt Spinler          * Creates an error log when the device has an error
103b54357f6SMatt Spinler          * but it isn't a PGOOD or voltage failure.
104b54357f6SMatt Spinler          */
105b54357f6SMatt Spinler         void createPowerFaultLog();
106b54357f6SMatt Spinler 
107b54357f6SMatt Spinler         /**
108e7e432b4SMatt Spinler          * Reads the status_word register
109e7e432b4SMatt Spinler          *
110e7e432b4SMatt Spinler          * @return uint16_t - the register contents
111e7e432b4SMatt Spinler          */
112e7e432b4SMatt Spinler         uint16_t readStatusWord();
113e7e432b4SMatt Spinler 
114e7e432b4SMatt Spinler         /**
115e7e432b4SMatt Spinler          * Reads the mfr_status register
116e7e432b4SMatt Spinler          *
117e7e432b4SMatt Spinler          * @return uint32_t - the register contents
118e7e432b4SMatt Spinler          */
119e7e432b4SMatt Spinler         uint32_t readMFRStatus();
120e7e432b4SMatt Spinler 
121e7e432b4SMatt Spinler         /**
122e7e432b4SMatt Spinler          * Says if we've already logged a Vout fault
123e7e432b4SMatt Spinler          *
124e7e432b4SMatt Spinler          * The policy is only 1 of the same error will
125e7e432b4SMatt Spinler          * be logged for the duration of a class instance.
126e7e432b4SMatt Spinler          *
127e7e432b4SMatt Spinler          * @param[in] page - the page to check
128e7e432b4SMatt Spinler          *
129e7e432b4SMatt Spinler          * @return bool - if we've already logged a fault against
130e7e432b4SMatt Spinler          *                this page
131e7e432b4SMatt Spinler          */
132e7e432b4SMatt Spinler         inline bool isVoutFaultLogged(uint32_t page) const
133e7e432b4SMatt Spinler         {
134e7e432b4SMatt Spinler             return std::find(voutErrors.begin(),
135e7e432b4SMatt Spinler                              voutErrors.end(),
136e7e432b4SMatt Spinler                              page) != voutErrors.end();
137e7e432b4SMatt Spinler         }
138e7e432b4SMatt Spinler 
139e7e432b4SMatt Spinler         /**
140e7e432b4SMatt Spinler          * Saves that a Vout fault has been logged
141e7e432b4SMatt Spinler          *
142e7e432b4SMatt Spinler          * @param[in] page - the page the error was logged against
143e7e432b4SMatt Spinler          */
144e7e432b4SMatt Spinler         inline void setVoutFaultLogged(uint32_t page)
145e7e432b4SMatt Spinler         {
146e7e432b4SMatt Spinler             voutErrors.push_back(page);
147e7e432b4SMatt Spinler         }
148e7e432b4SMatt Spinler 
149e7e432b4SMatt Spinler         /**
150d998b736SMatt Spinler          * Says if we've already logged a PGOOD fault
151d998b736SMatt Spinler          *
152d998b736SMatt Spinler          * The policy is only 1 of the same errors will
153d998b736SMatt Spinler          * be logged for the duration of a class instance.
154d998b736SMatt Spinler          *
155d998b736SMatt Spinler          * @param[in] input - the input to check
156d998b736SMatt Spinler          *
157d998b736SMatt Spinler          * @return bool - if we've already logged a fault against
158d998b736SMatt Spinler          *                this input
159d998b736SMatt Spinler          */
160d998b736SMatt Spinler         inline bool isPGOODFaultLogged(uint32_t input) const
161d998b736SMatt Spinler         {
162d998b736SMatt Spinler             return std::find(pgoodErrors.begin(),
163d998b736SMatt Spinler                              pgoodErrors.end(),
164d998b736SMatt Spinler                              input) != pgoodErrors.end();
165d998b736SMatt Spinler         }
166d998b736SMatt Spinler 
167d998b736SMatt Spinler         /**
168d998b736SMatt Spinler          * Saves that a PGOOD fault has been logged
169d998b736SMatt Spinler          *
170d998b736SMatt Spinler          * @param[in] input - the input the error was logged against
171d998b736SMatt Spinler          */
172d998b736SMatt Spinler         inline void setPGOODFaultLogged(uint32_t input)
173d998b736SMatt Spinler         {
174d998b736SMatt Spinler             pgoodErrors.push_back(input);
175d998b736SMatt Spinler         }
176d998b736SMatt Spinler 
177d998b736SMatt Spinler         /**
178e7e432b4SMatt Spinler          * List of pages that Vout errors have
179e7e432b4SMatt Spinler          * already been logged against
180e7e432b4SMatt Spinler          */
181e7e432b4SMatt Spinler         std::vector<uint32_t> voutErrors;
182e7e432b4SMatt Spinler 
183e7e432b4SMatt Spinler         /**
184d998b736SMatt Spinler          * List of inputs that PGOOD errors have
185d998b736SMatt Spinler          * already been logged against
186d998b736SMatt Spinler          */
187d998b736SMatt Spinler         std::vector<uint32_t> pgoodErrors;
188d998b736SMatt Spinler 
189d998b736SMatt Spinler         /**
190b54357f6SMatt Spinler          * The read/write interface to this hardware
191b54357f6SMatt Spinler          */
192b54357f6SMatt Spinler         pmbus::PMBus interface;
193b54357f6SMatt Spinler 
194b54357f6SMatt Spinler         /**
195d998b736SMatt Spinler          * A map of GPI pin IDs to the GPIO object
196d998b736SMatt Spinler          * used to access them
197d998b736SMatt Spinler          */
198d998b736SMatt Spinler         std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;
199d998b736SMatt Spinler 
200d998b736SMatt Spinler         /**
201b54357f6SMatt Spinler          * Keeps track of device access errors to avoid repeatedly
202b54357f6SMatt Spinler          * logging errors for bad hardware
203b54357f6SMatt Spinler          */
204b54357f6SMatt Spinler         bool accessError = false;
205b54357f6SMatt Spinler 
206b54357f6SMatt Spinler         /**
207110b2841SMatt Spinler          * The path to the GPIO device used to read
208110b2841SMatt Spinler          * the GPI (PGOOD) status
209110b2841SMatt Spinler          */
210110b2841SMatt Spinler         std::experimental::filesystem::path gpioDevice;
211110b2841SMatt Spinler 
212110b2841SMatt Spinler         /**
213b54357f6SMatt Spinler          * Map of device instance to the instance specific data
214b54357f6SMatt Spinler          */
215b54357f6SMatt Spinler         static const ucd90160::DeviceMap deviceMap;
216b54357f6SMatt Spinler };
217b54357f6SMatt Spinler 
218b54357f6SMatt Spinler }
219b54357f6SMatt Spinler }
220