blob: cf4baadce55c52e5b27eaddad4c3586a8d7674a1 [file] [log] [blame]
#pragma once
#include <algorithm>
#include <experimental/filesystem>
#include <map>
#include <vector>
#include "device.hpp"
#include "gpio.hpp"
#include "pmbus.hpp"
#include "types.hpp"
namespace witherspoon
{
namespace power
{
/**
* @class UCD90160
*
* This class implements fault analysis for the UCD90160
* power sequencer device.
*
*/
class UCD90160 : public Device
{
public:
UCD90160() = delete;
~UCD90160() = default;
UCD90160(const UCD90160&) = delete;
UCD90160& operator=(const UCD90160&) = delete;
UCD90160(UCD90160&&) = default;
UCD90160& operator=(UCD90160&&) = default;
/**
* Constructor
*
* @param[in] instance - the device instance number
*/
UCD90160(size_t instance);
/**
* Analyzes the device for errors when the device is
* known to be in an error state. A log will be created.
*/
void onFailure() override;
/**
* Checks the device for errors and only creates a log
* if one is found.
*/
void analyze() override;
/**
* Clears faults in the device
*/
void clearFaults() override
{
}
private:
/**
* Reports an error for a GPU PGOOD failure
*
* @param[in] callout - the GPU callout string
*/
void gpuPGOODError(const std::string& callout);
/**
* Reports an error for a GPU OverTemp failure
*
* @param[in] callout - the GPU callout string
*/
void gpuOverTempError(const std::string& callout);
/**
* Given the device path for a chip, find its gpiochip
* path
*
* @param[in] path - device path, like
* /sys/devices/.../i2c-11/11-0064
*
* @return fs::path - The gpiochip path, like
* /dev/gpiochip1
*/
static std::experimental::filesystem::path findGPIODevice(
const std::experimental::filesystem::path& path);
/**
* Checks for VOUT faults on the device.
*
* This device can monitor voltages of its dependent
* devices, and VOUT faults are voltage faults
* on these devices.
*
* @return bool - true if an error log was created
*/
bool checkVOUTFaults();
/**
* Checks for PGOOD faults on the device.
*
* This device can monitor the PGOOD signals of its dependent
* devices, and this check will look for faults of
* those PGOODs.
*
* @param[in] polling - If this is running while polling for errors,
* as opposing to analyzing a fail condition.
*
* @return bool - true if an error log was created
*/
bool checkPGOODFaults(bool polling);
/**
* Creates an error log when the device has an error
* but it isn't a PGOOD or voltage failure.
*/
void createPowerFaultLog();
/**
* Reads the status_word register
*
* @return uint16_t - the register contents
*/
uint16_t readStatusWord();
/**
* Reads the mfr_status register
*
* @return uint32_t - the register contents
*/
uint32_t readMFRStatus();
/**
* Says if we've already logged a Vout fault
*
* The policy is only 1 of the same error will
* be logged for the duration of a class instance.
*
* @param[in] page - the page to check
*
* @return bool - if we've already logged a fault against
* this page
*/
inline bool isVoutFaultLogged(uint32_t page) const
{
return std::find(voutErrors.begin(),
voutErrors.end(),
page) != voutErrors.end();
}
/**
* Saves that a Vout fault has been logged
*
* @param[in] page - the page the error was logged against
*/
inline void setVoutFaultLogged(uint32_t page)
{
voutErrors.push_back(page);
}
/**
* Says if we've already logged a PGOOD fault
*
* The policy is only 1 of the same errors will
* be logged for the duration of a class instance.
*
* @param[in] input - the input to check
*
* @return bool - if we've already logged a fault against
* this input
*/
inline bool isPGOODFaultLogged(uint32_t input) const
{
return std::find(pgoodErrors.begin(),
pgoodErrors.end(),
input) != pgoodErrors.end();
}
/**
* Saves that a PGOOD fault has been logged
*
* @param[in] input - the input the error was logged against
*/
inline void setPGOODFaultLogged(uint32_t input)
{
pgoodErrors.push_back(input);
}
/**
* List of pages that Vout errors have
* already been logged against
*/
std::vector<uint32_t> voutErrors;
/**
* List of inputs that PGOOD errors have
* already been logged against
*/
std::vector<uint32_t> pgoodErrors;
/**
* The read/write interface to this hardware
*/
pmbus::PMBus interface;
/**
* A map of GPI pin IDs to the GPIO object
* used to access them
*/
std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;
/**
* Keeps track of device access errors to avoid repeatedly
* logging errors for bad hardware
*/
bool accessError = false;
/**
* The path to the GPIO device used to read
* the GPI (PGOOD) status
*/
std::experimental::filesystem::path gpioDevice;
/**
* Map of device instance to the instance specific data
*/
static const ucd90160::DeviceMap deviceMap;
};
}
}