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