blob: 282b9354aaae6f6bfb93fe15df1c5adaa59793a1 [file] [view]
# PSU Sensor Module
<!--*
# Document freshness: For more information, see go/fresh-source.
freshness: { owner: 'tlbmc-dev' reviewed: '2026-07-28' }
*-->
The PSU Sensor Module in tlBMC is responsible for reading multi-channel power
telemetries (including voltage, current, power, and temperature) from hardware
power controllers, voltage regulators, and PMBus chips via the Hwmon and I3C
sysfs Hardware Abstraction Layers (HALs).
## Purpose & Overview
PSU Sensors interface with hardware power controllers, PMBus chips, power
bricks, and hotswap controllers to collect critical runtime physical telemetry.
When enabled as part of the sensor collection subsystem, this module discovers
and monitors multi-channel power and thermal attributes, exposing them as
standard Redfish `Sensor` resources within the
`/redfish/v1/Chassis/{id}/Sensors` collection and integrating them directly into
the underlying Redfish thermal and power subsystems.
## Central Configuration (central_config.proto)
PSU Sensor telemetry collection is managed under the central
`SensorCollectorModule` configuration within `central_config.proto`. Enabling
the central sensor collector activates the discovery and lifecycle management of
all configured PSU sensors.
Field Name | Type | Default Value | Description
:------------------------------------ | :-------------------------------- | :------------ | :----------
`enabled` | `bool` | `false` | Controls whether the sensor collector module is active.
`allow_sensor_creation_failure` | `bool` | `false` | If true, non-fatal hardware sysfs probe failures do not abort central sensor collection.
`enable_threshold_monitoring` | `bool` | `false` | If true, creates a background monitoring task to track thresholds and log SEL events upon crossing.
`sensor_collection_append_sub_module` | `SensorCollectionAppendSubmodule` | `none` | Controls appending tlBMC-discovered sensors to external Redfish sensor collections.
`thermal_control_sub_module` | `ThermalControlSubmodule` | `none` | Submodule for orchestrating Redfish thermal and power subsystem integrations.
## Entity Manager Configuration Reference
Platform hardware developers configure and activate PSU sensors by defining JSON
configuration blocks within Entity Manager configuration files. When an Entity
Manager block declares `Type` matching a supported PSU sensor and specifies
`"TlbmcOwned": true`, tlBMC parses the block and instantiates the underlying
channels via sysfs.
| Attribute Name | Expected Type | Description |
| :------------------------- | :------------------- | :----------------------- |
| `Type` | `string` | The specific hardware |
: : : chip or driver type :
: : : (e.g., `"ADM1266"`, :
: : : `"PMBUS"`). :
| `Name` | `string` | Base entity name for the |
: : : sensor group and :
: : : configuration block. :
| `Bus` | `integer` / `string` | Logical I2C or I3C bus |
: : : number (or expression :
: : : like `"$bus"`). :
| `Address` | `string` | Hexadecimal device |
: : : address on the bus :
: : : (e.g., `"0x40"`). :
| `Labels` | `array` of `string` | List of sysfs Hwmon |
: : : channel labels to expose :
: : : (e.g., `["vout1", :
: : : "curr1", :
: : : "highestpin"]`). :
| `<Label>_Name` / | `string` (optional) | Custom Redfish resource |
: `Name<Index>` : : name for a specific :
: : : label channel. :
| `<Label>_Max` / | `number` (optional) | Custom maximum and |
: `<Label>_Min` : : minimum reading range :
: : : overrides. :
| `<Label>_Scale` / | `number` (optional) | Custom scaling factor |
: `<Label>_Offset` : : (`reading / scale + :
: : : offset`) override. :
| `Thresholds` | `array` of `object` | List of threshold |
: : : definitions (`Name`, :
: : : `Value`, `Direction`, :
: : : `Severity`, optional :
: : : `Label`). :
| `RelatedItem` | `object` (optional) | Relates the sensor |
: : : entity to a target :
: : : parent resource (`Id`, :
: : : `Type`). :
| `RedfishHidden` | `boolean` / `array` | Hides specific sensor |
: : : instances or all (`*` or :
: : : `true`) from Redfish :
: : : collections. :
| `AppendToSensorCollection` | `boolean` / `array` | Appends specific sensor |
: : : routes or all (`*` or :
: : : `true`) to Redfish :
: : : `SensorCollection`. :
| `SensorGroup` | `string` (optional) | Identifier for the |
: : : sensor group / root bus :
: : : topology association. :
| `TlbmcOwned` | `boolean` | Must be `true` for tlBMC |
: : : to discover and manage :
: : : this sensor entity. :
## Supported Chips & Drivers
tlBMC registers a comprehensive hardware chip mapping table
(`kSupportedPsuSensorTypes`) that automatically associates Entity Manager `Type`
strings with Linux kernel sysfs driver names:
| Entity Manager `Type` | Kernel Driver Name | Interface & Notes |
| :-------------------- | :----------------- | :-------------------------- |
| `ADM1266` | `"adm1266"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `ADM1272` | `"adm1272"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `ADM1273` | `"adm1275"` | Uses `adm1275` kernel |
: : : driver. :
| `BMR490` | `"bmr490"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `DPS800` | `"dps800"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `GOOGLE_TPU` | `"google_tpu"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `INA226` | `"ina226"` | Voltage and current |
: : : monitoring driver. :
| `LTC2991` | `"ltc2991"` | Octal I2C |
: : : voltage/current/temperature :
: : : monitor. :
| `LTC4287` | `"ltc4286"` | Uses `ltc4286` kernel |
: : : driver. :
| `LX6301` | `"lx6301"` | Standard I2C Hwmon driver. |
| `MAX20826` | `"max20826"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `MAX20830C` | `"max20830c"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `MAX20840C` | `"max20840c"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `MAX34451` | `"max34451"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `MP2925` | `"mp2925"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `MP2929` | `"mp2929"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `MP5998` | `"mp5998"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `PMBUS` | `"pmbus"` | Generic PMBus monitoring |
: : : interface. :
| `Q50SN12072` | `"q50sn12072"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `Q54SN120A4` | `"q54sn120a4"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `RAA228228` | `"raa228228"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `RAA229141` | `"raa229141"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `RAA229621` | `"raa229621"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `RAA229639` | `"raa229639"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `SBRMI_I3C` | `"sbrmi_i3c"` | **I3C Required Chip:** |
: : : Requires I3C Sysfs HAL :
: : : interaction :
: : : (`IsI3cPsuSensor`). :
| `SBTSI_I3C` | `"sbtsi_i3c"` | **I3C Required Chip:** |
: : : Requires I3C Sysfs HAL :
: : : interaction :
: : : (`IsI3cPsuSensor`). :
| `TDA38640` | `"tda38640"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `TDA38725` | `"tda38725"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `TDA38740` | `"tda38740"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `TPS25990` | `"tps25990"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `TPS546E25` | `"tps546e25"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `XDPE19284C` | `"xdpe19284c"` | Standard I2C/PMBus Hwmon |
: : : driver. :
| `XDPE1A2G5B` | `"xdpe1a2g5b"` | Standard I2C/PMBus Hwmon |
: : : driver. :
> [!NOTE] Chips designated as **I3C Required Chips** (`SBTSI_I3C` and
> `SBRMI_I3C`) are verified via `PsuSensor::IsI3cPsuSensor` and utilize the
> `I3cSysfs` HAL for device detection and sysfs HWMon path resolution.
## Default Reading Properties & Scale Factors (kDefaultPsuSensorProperties)
tlBMC automatically maps non-digit base labels (e.g., `vout1` stripped of
numbers -> `vout`) to standardized default physical reading properties
(`ReadingProperties`). This mapping assigns correct physical quantities, units
(`SensorUnit`), scale divisor powers (`pow(10, scale)`), and defaults:
| Base Label | Physical | Default Unit | Scale | Default |
: : Quantity : : Divisor : Range :
: : : : (`pow(10, : (Min / :
: : : : scale)`) : Max) :
| :------------ | :---------- | :-------------------- | :---------- | :------- |
| `curr` / | Output | `UNIT_AMPERE` | `1000` | `0.0` / |
: `iout` : Current : : (`pow(10, : `255.0` :
: : : : 3)`) : A :
| `iin` | Input | `UNIT_AMPERE` | `1000` | `0.0` / |
: : Current : : (`pow(10, : `20.0` A :
: : : : 3)`) : :
| `isysin` / | System | `UNIT_AMPERE` | `1000` | `0.0` / |
: `isysout` : Current : : (`pow(10, : `255.0` :
: : : : 3)`) : A :
| `highestiout` | Peak Output | `UNIT_AMPERE` | `1000` | `0.0` / |
: / `peakiout` : Current : : (`pow(10, : `255.0` :
: : : : 3)`) : A :
| `vin` | Input | `UNIT_VOLT` | `1000` | `0.0` / |
: : Voltage : : (`pow(10, : `300.0` :
: : : : 3)`) : V :
| `in` / `vout` | Output | `UNIT_VOLT` | `1000` | `0.0` / |
: / `voltage` : Voltage : : (`pow(10, : `255.0` :
: : : : 3)`) : V :
| `vmon` | Auxiliary | `UNIT_VOLT` | `1000` | `0.0` / |
: : Input : : (`pow(10, : `255.0` :
: : Voltage : : 3)`) : V :
| `highestvin` | Peak Input | `UNIT_VOLT` | `1000` | `0.0` / |
: : Voltage : : (`pow(10, : `300.0` :
: : : : 3)`) : V :
| `highestvout` | Peak Output | `UNIT_VOLT` | `1000` | `0.0` / |
: : Voltage : : (`pow(10, : `255.0` :
: : : : 3)`) : V :
| `peakvin` | Peak Input | `UNIT_VOLT` | `1000` | `0.0` / |
: : Voltage : : (`pow(10, : `300.0` :
: : : : 3)`) : V :
| `peakvout` | Peak Output | `UNIT_VOLT` | `1000` | `0.0` / |
: : Voltage : : (`pow(10, : `255.0` :
: : : : 3)`) : V :
| `pin` | Input Power | `UNIT_WATT` | `1,000,000` | `0.0` / |
: : : : (`pow(10, : `3000.0` :
: : : : 6)`) : W :
| `pout` / | Output | `UNIT_WATT` | `1,000,000` | `0.0` / |
: `power` : Power : : (`pow(10, : `3000.0` :
: : : : 6)`) : W :
| `highestpin` | Peak Input | `UNIT_WATT` | `1,000,000` | `0.0` / |
: / `peakpin` : Power : : (`pow(10, : `3000.0` :
: : : : 6)`) : W :
| `temp` | Temperature | `UNIT_DEGREE_CELSIUS` | `1000` | `-128.0` |
: : : : (`pow(10, : / :
: : : : 3)`) : `127.0` :
: : : : : °C :
| `highesttemp` | Peak | `UNIT_DEGREE_CELSIUS` | `1000` | `-128.0` |
: / `peaktemp` : Temperature : : (`pow(10, : / :
: : : : 3)`) : `127.0` :
: : : : : °C :
> [!TIP] When sysfs returns integer raw readings (e.g. millivolts, milliamps,
> microwatts), `PsuSensor::HandleRefreshResult` applies the final conversion:
> `reading = (raw_value / scale) + offset`.
## Special File Type Handling (PsuSensorFileType)
To handle distinct historical sysfs file naming conventions across power
controller drivers, `PsuSensor::GetPsuSensorFileInfo` inspects sysfs file
suffixes and associates them with appropriate label modification prefixes:
* **`kDefault` (`_input` suffix):** Standard telemetry input reading file
(e.g., `in1_input`, `temp1_input`). Applies an empty (`""`) label modifier
prefix.
* **`kHighestPower` (`_input_highest` suffix):** Special sysfs file generated
for peak power telemetries (e.g., `power1_input_highest`). Applies the
`"highest"` label modifier prefix.
* **`kHighestDefault` (`_highest` suffix):** Special sysfs file generated for
peak temperature or voltage defaults (e.g., `temp1_highest`). Applies the
`"highest"` label modifier prefix.
**Label Normalization:** To maintain cross-platform compatibility where
integrators interchange `"highest"` and `"peak"` modifiers (e.g. `"highestpin"`
vs `"peakpin"`), tlBMC automatically maps both prefixes to the same underlying
sysfs input file.
## Sensor Key Generation (GetPsuSensorKey)
Every instantiated PSU Sensor receives a fully qualified unique identifier
(`name`) within Redfish:
1. **Custom Name Check:** If the Entity Manager configuration explicitly
provides `<Label>_Name` or `Name<Index>`, that string is used directly.
2. **Fallback Derivation:** Otherwise, combines the parent configuration block
name and the label's descriptive type name (e.g., `ADM1266_Input_Voltage`).
3. **Unit Prefix Assignment:** Regardless of origin, `GetPsuSensorKey` prefixes
the final Redfish identifier based on its physical unit:
* `UNIT_AMPERE` $\rightarrow$ `current_{name}`
* `UNIT_VOLT` $\rightarrow$ `voltage_{name}`
* `UNIT_WATT` $\rightarrow$ `power_{name}`
* `UNIT_DEGREE_CELSIUS` $\rightarrow$ `temperature_{name}`
## Protobuf Configuration
The following underlying protobuf schemas define the runtime data structures,
properties, and configuration parsing models for PSU Sensors:
* [psu_sensor_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/psu_sensor_config.proto):
Defines `PsuSensorType` enums and the primary `PsuSensorConfig` message
mapping labels to instance properties.
* [hal_common_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/hal_common_config.proto):
Defines logical bus numbers and hardware addresses (`HalCommonConfig`).
* [sensor_instance_properties.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/sensor_instance_properties.proto):
Defines instance-specific units, thresholds, transforms, ranges, and
visibility flags (`SensorInstanceProperties`).
* [entity_common_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/entity_common_config.proto):
Defines entity-level refresh intervals, queue sizes, sensor groups, and
power state dependencies (`EntityCommonConfig`).
* [central_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/central_config/central_config.proto):
Defines top-level collection orchestration options
(`SensorCollectorModule`).
* [reading_range_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/reading_range_config.proto):
Defines min/max operational reading ranges (`ReadingRangeConfigs`).
* [reading_transform_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/reading_transform_config.proto):
Defines scaling divisors and offsets (`ReadingTransformConfig`).
* [threshold_config.proto](http://google3/third_party/milotic/external/cc/tlbmc/configs/threshold_config.proto):
Defines critical and non-critical thresholds (`ThresholdConfigs`).
## Usage & Configuration Examples
Below is a concrete, fully qualified Entity Manager configuration block defining
an `ADM1266` power supply controller on Bus 20 at Address `0x40`. It exposes
specific voltage channels and configures an upper critical threshold:
```json
{
"Address": "0x40",
"Bus": 20,
"Labels": [
"vout1",
"vout5",
"vout6"
],
"Name": "ADM1266",
"Thresholds": [
{
"Direction": "greater than",
"Label": "vout1",
"Name": "upper critical",
"Severity": 1,
"Value": 13.56
}
],
"TlbmcOwned": true
}
```
## Code References
* [psu_sensor.h](http://google3/third_party/milotic/external/cc/tlbmc/sensors/psu_sensor.h):
Main header defining `PsuSensor`, `PsuSensorFileType`, and scale mappings.
* [psu_sensor.cc](http://google3/third_party/milotic/external/cc/tlbmc/sensors/psu_sensor.cc):
Implementation file containing registered chip models, default properties,
and sysfs reading parsers.
* [entity_config_json_impl.cc](http://google3/third_party/milotic/external/cc/tlbmc/configs/entity_config_json_impl.cc):
Entity Manager JSON configuration parser implementing
`ParsePsuSensorConfig`.