xref: /openbmc/phosphor-power/phosphor-power-sequencer/src/pmbus_driver_device.hpp (revision 92261f88729b618b1c31d20f28328a8aff73b83b)
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