1b89395b1SShawn McCarney /** 2b89395b1SShawn McCarney * Copyright © 2024 IBM Corporation 3b89395b1SShawn McCarney * 4b89395b1SShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License"); 5b89395b1SShawn McCarney * you may not use this file except in compliance with the License. 6b89395b1SShawn McCarney * You may obtain a copy of the License at 7b89395b1SShawn McCarney * 8b89395b1SShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0 9b89395b1SShawn McCarney * 10b89395b1SShawn McCarney * Unless required by applicable law or agreed to in writing, software 11b89395b1SShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS, 12b89395b1SShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b89395b1SShawn McCarney * See the License for the specific language governing permissions and 14b89395b1SShawn McCarney * limitations under the License. 15b89395b1SShawn McCarney */ 16b89395b1SShawn McCarney #pragma once 17b89395b1SShawn McCarney 18b89395b1SShawn McCarney #include "pmbus.hpp" 19b89395b1SShawn McCarney #include "rail.hpp" 20b89395b1SShawn McCarney #include "services.hpp" 21b89395b1SShawn McCarney #include "standard_device.hpp" 22b89395b1SShawn McCarney 23b89395b1SShawn McCarney #include <stddef.h> // for size_t 24b89395b1SShawn McCarney 25b89395b1SShawn McCarney #include <cstdint> 26b89395b1SShawn McCarney #include <map> 27b89395b1SShawn McCarney #include <memory> 28b89395b1SShawn McCarney #include <optional> 29b89395b1SShawn McCarney #include <string> 30b89395b1SShawn McCarney #include <utility> 31b89395b1SShawn McCarney #include <vector> 32b89395b1SShawn McCarney 33b89395b1SShawn McCarney namespace phosphor::power::sequencer 34b89395b1SShawn McCarney { 35b89395b1SShawn McCarney 36b89395b1SShawn McCarney /** 37b89395b1SShawn McCarney * @class PMBusDriverDevice 38b89395b1SShawn McCarney * 39b89395b1SShawn McCarney * StandardDevice sub-class for power sequencer devices that are bound to a 40b89395b1SShawn McCarney * PMBus device driver. 41b89395b1SShawn McCarney */ 42b89395b1SShawn McCarney class PMBusDriverDevice : public StandardDevice 43b89395b1SShawn McCarney { 44b89395b1SShawn McCarney public: 45b89395b1SShawn McCarney // Specify which compiler-generated methods we want 46b89395b1SShawn McCarney PMBusDriverDevice() = delete; 47b89395b1SShawn McCarney PMBusDriverDevice(const PMBusDriverDevice&) = delete; 48b89395b1SShawn McCarney PMBusDriverDevice(PMBusDriverDevice&&) = delete; 49b89395b1SShawn McCarney PMBusDriverDevice& operator=(const PMBusDriverDevice&) = delete; 50b89395b1SShawn McCarney PMBusDriverDevice& operator=(PMBusDriverDevice&&) = delete; 51b89395b1SShawn McCarney virtual ~PMBusDriverDevice() = default; 52b89395b1SShawn McCarney 53b89395b1SShawn McCarney /** 54b89395b1SShawn McCarney * Constructor. 55b89395b1SShawn McCarney * 56b89395b1SShawn McCarney * @param name Device name 57b89395b1SShawn McCarney * @param rails Voltage rails that are enabled and monitored by this device 58b89395b1SShawn McCarney * @param services System services like hardware presence and the journal 59b89395b1SShawn McCarney * @param bus I2C bus for the device 60b89395b1SShawn McCarney * @param address I2C address for the device 61b89395b1SShawn McCarney * @param driverName Device driver name 62b89395b1SShawn McCarney * @param instance Chip instance number 63b89395b1SShawn McCarney */ PMBusDriverDevice(const std::string & name,std::vector<std::unique_ptr<Rail>> rails,Services & services,uint8_t bus,uint16_t address,const std::string & driverName="",size_t instance=0)64f5402197SPatrick Williams explicit PMBusDriverDevice( 65f5402197SPatrick Williams const std::string& name, std::vector<std::unique_ptr<Rail>> rails, 66f5402197SPatrick Williams Services& services, uint8_t bus, uint16_t address, 67f5402197SPatrick Williams const std::string& driverName = "", size_t instance = 0) : 68f5402197SPatrick Williams StandardDevice(name, std::move(rails)), bus{bus}, address{address}, 69f5402197SPatrick Williams driverName{driverName}, instance{instance} 70b89395b1SShawn McCarney { 71f5402197SPatrick Williams pmbusInterface = 72f5402197SPatrick Williams services.createPMBus(bus, address, driverName, instance); 73b89395b1SShawn McCarney } 74b89395b1SShawn McCarney 75b89395b1SShawn McCarney /** 76b89395b1SShawn McCarney * Returns the I2C bus for the device. 77b89395b1SShawn McCarney * 78b89395b1SShawn McCarney * @return I2C bus 79b89395b1SShawn McCarney */ getBus() const80b89395b1SShawn McCarney uint8_t getBus() const 81b89395b1SShawn McCarney { 82b89395b1SShawn McCarney return bus; 83b89395b1SShawn McCarney } 84b89395b1SShawn McCarney 85b89395b1SShawn McCarney /** 86b89395b1SShawn McCarney * Returns the I2C address for the device. 87b89395b1SShawn McCarney * 88b89395b1SShawn McCarney * @return I2C address 89b89395b1SShawn McCarney */ getAddress() const90b89395b1SShawn McCarney uint16_t getAddress() const 91b89395b1SShawn McCarney { 92b89395b1SShawn McCarney return address; 93b89395b1SShawn McCarney } 94b89395b1SShawn McCarney 95b89395b1SShawn McCarney /** 96b89395b1SShawn McCarney * Returns the device driver name. 97b89395b1SShawn McCarney * 98b89395b1SShawn McCarney * @return driver name 99b89395b1SShawn McCarney */ getDriverName() const100b89395b1SShawn McCarney const std::string& getDriverName() const 101b89395b1SShawn McCarney { 102b89395b1SShawn McCarney return driverName; 103b89395b1SShawn McCarney } 104b89395b1SShawn McCarney 105b89395b1SShawn McCarney /** 106b89395b1SShawn McCarney * Returns the chip instance number. 107b89395b1SShawn McCarney * 108b89395b1SShawn McCarney * @return chip instance 109b89395b1SShawn McCarney */ getInstance() const110b89395b1SShawn McCarney size_t getInstance() const 111b89395b1SShawn McCarney { 112b89395b1SShawn McCarney return instance; 113b89395b1SShawn McCarney } 114b89395b1SShawn McCarney 115b89395b1SShawn McCarney /** 116b89395b1SShawn McCarney * Returns interface to the PMBus information that is provided by the device 117b89395b1SShawn McCarney * driver in sysfs. 118b89395b1SShawn McCarney * 119b89395b1SShawn McCarney * @return PMBus interface object 120b89395b1SShawn McCarney */ getPMBusInterface()121b89395b1SShawn McCarney pmbus::PMBusBase& getPMBusInterface() 122b89395b1SShawn McCarney { 123b89395b1SShawn McCarney return *pmbusInterface; 124b89395b1SShawn McCarney } 125b89395b1SShawn McCarney 126b89395b1SShawn McCarney /** @copydoc PowerSequencerDevice::getGPIOValues() */ 127b89395b1SShawn McCarney virtual std::vector<int> getGPIOValues(Services& services) override; 128b89395b1SShawn McCarney 129b89395b1SShawn McCarney /** @copydoc PowerSequencerDevice::getStatusWord() */ 130b89395b1SShawn McCarney virtual uint16_t getStatusWord(uint8_t page) override; 131b89395b1SShawn McCarney 132b89395b1SShawn McCarney /** @copydoc PowerSequencerDevice::getStatusVout() */ 133b89395b1SShawn McCarney virtual uint8_t getStatusVout(uint8_t page) override; 134b89395b1SShawn McCarney 135b89395b1SShawn McCarney /** @copydoc PowerSequencerDevice::getReadVout() */ 136b89395b1SShawn McCarney virtual double getReadVout(uint8_t page) override; 137b89395b1SShawn McCarney 138b89395b1SShawn McCarney /** @copydoc PowerSequencerDevice::getVoutUVFaultLimit() */ 139b89395b1SShawn McCarney virtual double getVoutUVFaultLimit(uint8_t page) override; 140b89395b1SShawn McCarney 141b89395b1SShawn McCarney /** 142b89395b1SShawn McCarney * Returns map from PMBus PAGE numbers to sysfs hwmon file numbers. 143b89395b1SShawn McCarney * 144b89395b1SShawn McCarney * Throws an exception if an error occurs trying to build the map. 145b89395b1SShawn McCarney * 146b89395b1SShawn McCarney * @return page to file number map 147b89395b1SShawn McCarney */ getPageToFileNumberMap()148b89395b1SShawn McCarney const std::map<uint8_t, unsigned int>& getPageToFileNumberMap() 149b89395b1SShawn McCarney { 150b89395b1SShawn McCarney if (pageToFileNumber.empty()) 151b89395b1SShawn McCarney { 152b89395b1SShawn McCarney buildPageToFileNumberMap(); 153b89395b1SShawn McCarney } 154b89395b1SShawn McCarney return pageToFileNumber; 155b89395b1SShawn McCarney } 156b89395b1SShawn McCarney 157b89395b1SShawn McCarney /** 158b89395b1SShawn McCarney * Returns the hwmon file number that corresponds to the specified PMBus 159b89395b1SShawn McCarney * PAGE number. 160b89395b1SShawn McCarney * 161b89395b1SShawn McCarney * Throws an exception if a file number was not found for the specified PAGE 162b89395b1SShawn McCarney * number. 163b89395b1SShawn McCarney * 164b89395b1SShawn McCarney * @param page PMBus PAGE number 165b89395b1SShawn McCarney * @return hwmon file number 166b89395b1SShawn McCarney */ 167b89395b1SShawn McCarney unsigned int getFileNumber(uint8_t page); 168b89395b1SShawn McCarney 169b89395b1SShawn McCarney protected: 170b89395b1SShawn McCarney /** @copydoc StandardDevice::prepareForPgoodFaultDetection() */ prepareForPgoodFaultDetection(Services & services)171b89395b1SShawn McCarney virtual void prepareForPgoodFaultDetection(Services& services) override 172b89395b1SShawn McCarney { 173b89395b1SShawn McCarney // Rebuild PMBus PAGE to hwmon file number map 174b89395b1SShawn McCarney buildPageToFileNumberMap(); 175b89395b1SShawn McCarney 176b89395b1SShawn McCarney // Call parent class method to do any actions defined there 177b89395b1SShawn McCarney StandardDevice::prepareForPgoodFaultDetection(services); 178b89395b1SShawn McCarney } 179b89395b1SShawn McCarney 180b89395b1SShawn McCarney /** 181b89395b1SShawn McCarney * Build mapping from PMBus PAGE numbers to the hwmon file numbers in 182b89395b1SShawn McCarney * sysfs. 183b89395b1SShawn McCarney * 184b89395b1SShawn McCarney * hwmon file names have the format: 185b89395b1SShawn McCarney * <type><number>_<item> 186b89395b1SShawn McCarney * 187b89395b1SShawn McCarney * The <number> is not the PMBus PAGE number. The PMBus PAGE is determined 188b89395b1SShawn McCarney * by reading the contents of the <type><number>_label file. 189b89395b1SShawn McCarney * 190b89395b1SShawn McCarney * If the map is not empty, it is cleared and rebuilt. This is necessary 191b89395b1SShawn McCarney * over time because power devices may have been added or removed. 192b89395b1SShawn McCarney * 193b89395b1SShawn McCarney * Throws an exception if an error occurs trying to build the map. 194b89395b1SShawn McCarney */ 195b89395b1SShawn McCarney virtual void buildPageToFileNumberMap(); 196b89395b1SShawn McCarney 197b89395b1SShawn McCarney /** 198b89395b1SShawn McCarney * Returns whether the specified sysfs hwmon file is a voltage label file. 199b89395b1SShawn McCarney * 200b89395b1SShawn McCarney * If it is a label file, the hwmon file number is obtained from the file 201b89395b1SShawn McCarney * name and returned. 202b89395b1SShawn McCarney * 203b89395b1SShawn McCarney * @param fileName file within the sysfs hwmon directory 204b89395b1SShawn McCarney * @param fileNumber the hwmon file number is stored in this output 205b89395b1SShawn McCarney * parameter if this is a label file 206b89395b1SShawn McCarney * @return true if specified file is a voltage label file, false otherwise 207b89395b1SShawn McCarney */ 208b89395b1SShawn McCarney virtual bool isLabelFile(const std::string& fileName, 209b89395b1SShawn McCarney unsigned int& fileNumber); 210b89395b1SShawn McCarney 211b89395b1SShawn McCarney /** 212b89395b1SShawn McCarney * Reads the specified voltage label file to obtain the associated PMBus 213b89395b1SShawn McCarney * PAGE number. 214b89395b1SShawn McCarney * 215b89395b1SShawn McCarney * The returned optional variable will have no value if the PMBus PAGE 216b89395b1SShawn McCarney * number could not be obtained due to an error. 217b89395b1SShawn McCarney * 218b89395b1SShawn McCarney * @param fileName voltage label file within the sysfs hwmon directory 219b89395b1SShawn McCarney * @return PMBus page number 220b89395b1SShawn McCarney */ 221*92261f88SPatrick Williams virtual std::optional<uint8_t> readPageFromLabelFile( 222*92261f88SPatrick Williams const std::string& fileName); 223b89395b1SShawn McCarney 224b89395b1SShawn McCarney /** 225b89395b1SShawn McCarney * I2C bus for the device. 226b89395b1SShawn McCarney */ 227b89395b1SShawn McCarney uint8_t bus; 228b89395b1SShawn McCarney 229b89395b1SShawn McCarney /** 230b89395b1SShawn McCarney * I2C address for the device. 231b89395b1SShawn McCarney */ 232b89395b1SShawn McCarney uint16_t address; 233b89395b1SShawn McCarney 234b89395b1SShawn McCarney /** 235b89395b1SShawn McCarney * Device driver name. 236b89395b1SShawn McCarney */ 237b89395b1SShawn McCarney std::string driverName; 238b89395b1SShawn McCarney 239b89395b1SShawn McCarney /** 240b89395b1SShawn McCarney * Chip instance number. 241b89395b1SShawn McCarney */ 242b89395b1SShawn McCarney size_t instance; 243b89395b1SShawn McCarney 244b89395b1SShawn McCarney /** 245b89395b1SShawn McCarney * Interface to the PMBus information that is provided by the device driver 246b89395b1SShawn McCarney * in sysfs. 247b89395b1SShawn McCarney */ 248b89395b1SShawn McCarney std::unique_ptr<pmbus::PMBusBase> pmbusInterface; 249b89395b1SShawn McCarney 250b89395b1SShawn McCarney /** 251b89395b1SShawn McCarney * Map from PMBus PAGE numbers to sysfs hwmon file numbers. 252b89395b1SShawn McCarney */ 253b89395b1SShawn McCarney std::map<uint8_t, unsigned int> pageToFileNumber; 254b89395b1SShawn McCarney }; 255b89395b1SShawn McCarney 256b89395b1SShawn McCarney } // namespace phosphor::power::sequencer 257