[PDDF] Add IIO, SMBus, scaling and threshold support to voltage sensor base class#25875
[PDDF] Add IIO, SMBus, scaling and threshold support to voltage sensor base class#25875pbdspec wants to merge 1 commit intosonic-net:masterfrom
Conversation
…r base class
#### Why I did it
The existing PDDF PddfVoltageSensor base class only supports hwmon sysfs
reads. This forces any vendor with non-hwmon voltage sensors (IIO ADCs,
raw PMBus chips without hwmon drivers) to write their own custom
platform-specific Python code, duplicating effort across vendors.
Many switch platforms use:
- IIO ADC chips (max1139, max11613, ads7828, lt2488) that expose
voltage via iio:deviceX/in_voltageN_raw — not hwmon
- PMBus VRM chips behind I2C MUXes that lack a hwmon driver, requiring
raw SMBus reads of VOUT_MODE (0x20) + READ_VOUT (0x8B) registers
- Voltage dividers or millivolt-scale outputs needing scaling factors
- Per-sensor operational thresholds (high/low/crit) from JSON config
Without this change, each vendor must independently implement IIO reads,
PMBus Linear16/VID decoding, scaling arithmetic, and threshold lookups —
all of which are generic and belong in the common base class.
#### How I did it
**pddf_voltage_sensor.py:**
1. Three-way sensor dispatch in get_value() based on sensor_type in
JSON dev_attr:
- sensor_type absent or default → existing hwmon sysfs path (unchanged)
- sensor_type = "iio" → new _read_iio() method
- sensor_type = "smbus" → new _read_smbus() / _read_smbus_via_parent()
2. IIO read path (_read_iio):
- Discovers iio:deviceX/in_voltageN_raw from bus/addr/channel_id
- Caches the resolved sysfs path for subsequent reads
- Reads raw ADC count, applies multi_factor/decimate_factor scaling
- Auto-creates I2C device via new_device if not yet bound
3. SMBus read path (_read_smbus / _read_smbus_via_parent):
- Reads VOUT_MODE register to determine output format
- Reads READ_VOUT register for raw voltage data
- Decodes PMBus Linear16 format (mode=0): mantissa × 2^exponent
- Decodes PMBus VID format (mode=1): VR12/VR12.5/VR13 lookup tables
- Supports cascaded MUX topologies via _read_smbus_via_parent()
which manually selects MUX channel, reads, then deselects
4. Scaling support:
- multi_factor: multiplication after raw read (e.g., 4 for 4:1 divider)
- decimate_factor: division after raw read (e.g., 10 for mV→V scaling)
- Applied uniformly to all three read paths
5. Threshold support:
- get_high_threshold(), get_low_threshold(),
get_high_critical_threshold(), get_low_critical_threshold()
- Priority: sysfs hwmon limits first (chip hardware limits),
JSON dev_attr fallback (high_threshold, low_threshold,
high_crit_threshold, low_crit_threshold)
- Returns float millivolts or None
6. Named PMBus constants replacing all magic numbers:
- PMBUS_VOUT_MODE (0x20), PMBUS_READ_VOUT (0x8B)
- PMBUS_VOUT_MODE_LINEAR (0), PMBUS_VOUT_MODE_VID (1)
- PMBUS_VOUT_MODE_SHIFT (5), PMBUS_VOUT_MODE_MASK (0x07)
- PMBUS_VOUT_EXP_MASK, PMBUS_VOUT_EXP_SIGN_BIT, PMBUS_VOUT_EXP_OFFSET
- VID_VR12_BASE_MV, VID_VR12_STEP_MV, VID_VR13_BASE_MV, VID_VR13_STEP_MV
- MV_PER_VOLT (1000), MUX_DESELECT (0x00)
7. Robust error handling:
- try/except on all JSON float/int parsing (ValueError, TypeError)
- try/except on all I/O operations with None return on failure
- Guarded smbus2 import (HAS_SMBUS2 flag)
**pddfapi.py:**
1. show_attr_voltage_sensor_device(): checks sensor_type in dev_attr,
routes "iio" → show_attr_iio_device(), else → show_attr_hwmon_device()
2. New show_attr_iio_device(): resolves IIO sysfs path from
bus/addr/channel_id, reads in_voltageN_raw, supports virt_parent
for parent device hwmon resolution
**Backward compatibility:**
- Platforms without sensor_type in JSON continue to use the existing
hwmon path — behavior is identical to the original base class
- No changes to existing pddf-device.json files required
- No new dependencies (smbus2 is optional, gracefully degrades)
**Sample JSON configuration for each sensor type:**
hwmon (existing, unchanged — uses DCDC parent + virt_parent):
"VOLTAGE12": {
"dev_info": {"device_type": "VOLTAGE_SENSOR"},
"i2c": {
"virt_parent": "VRM1",
"attr_list": [{"attr_name": "volt1_input",
"drv_attr_name": "in2_input"}],
"dev_attr": {"display_name": "MB_TRVDD1_0V9",
"high_threshold": "927",
"low_threshold": "873"}
}
}
IIO ADC (new — sensor_type + channel_id + scaling):
"VOLTAGE1": {
"dev_info": {"device_type": "VOLTAGE_SENSOR"},
"i2c": {
"topo_info": {"parent_bus": "0x9",
"dev_addr": "0x34",
"dev_type": "max1139"},
"dev_attr": {"sensor_type": "iio",
"channel_id": "0",
"multi_factor": "4",
"display_name": "BXX_VCC5P0",
"high_threshold": "5250",
"low_threshold": "4750"}
}
}
SMBus raw PMBus (new — sensor_type + optional parent MUX):
"VOLTAGE28": {
"dev_info": {"device_type": "VOLTAGE_SENSOR"},
"i2c": {
"topo_info": {"parent_bus": "0x3f",
"dev_addr": "0x20",
"dev_type": "max20796"},
"dev_attr": {"sensor_type": "smbus",
"display_name": "FPC_VDD_0V85",
"high_threshold": "875",
"low_threshold": "825",
"parent_mux_bus": "0x3d",
"parent_mux_addr": "0x70",
"parent_mux_ch": "0x08"}
}
}
#### How to verify it
1. For hwmon sensors (backward compatible):
- No changes to existing JSON needed
- 'show platform voltage' should show same values as before
2. For IIO sensors:
- Add VOLTAGE_SENSOR entries with sensor_type="iio" in pddf-device.json
- Ensure IIO ADC driver is loaded (e.g., max1363 for max1139)
- 'show platform voltage' should show IIO sensor values with scaling
3. For SMBus sensors:
- Add VOLTAGE_SENSOR entries with sensor_type="smbus" in pddf-device.json
- Ensure smbus2 Python package is available in pmon container
- 'show platform voltage' should show PMBus voltage decoded values
4. For thresholds:
- Add high_threshold/low_threshold in JSON dev_attr (millivolts)
- 'show platform voltage' should display Warning=True when
sensor value exceeds configured thresholds
5. Tested on Juniper platform with:
- 15 hwmon sensors (tps53659, max16602, max16545 via DCDC+virt_parent)
- 16 IIO sensors (max1139, max11613 ADCs with multi_factor scaling)
- 8 SMBus sensors (max20796 behind PCA9548 MUX)
- All 39 sensors reading correctly with thresholds
#### Which release branch to backport
N/A
#### Tested branch
master
Verified on Juniper platform hardware with SONiC master
#### Description for the changelog
Enhance PDDF voltage sensor base class to support IIO subsystem reads,
raw SMBus/PMBus register reads (Linear16 and VID decode), multi_factor/
decimate_factor scaling, and per-sensor threshold configuration from JSON.
This allows vendors with IIO ADCs or raw PMBus chips to leverage the PDDF
common infrastructure without writing custom platform-specific Python code.
Fully backward compatible — existing hwmon-only platforms are unaffected.
#### Link to config_db schema for YANG module changes
N/A — no config_db or YANG changes. Only pddf-device.json dev_attr
fields are extended (sensor_type, channel_id, multi_factor,
decimate_factor, high_threshold, low_threshold, high_crit_threshold,
low_crit_threshold, parent_mux_bus, parent_mux_addr, parent_mux_ch).
Signed-off-by: Satish Gopalakrishnan <satishg@juniper.net>
|
|
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
azpw/ run |
|
=== Voltage Sensor Readings (39 sensors) — Juniper Platform === Sensor Name Value(mV) HighThresh LowThresh Status--- IIO sensors (max1139 ADC, channel 0-10) --- --- hwmon sensors (tps53659, max16602, max16545 via DCDC+virt_parent) --- --- SMBus sensors (max20796 via raw PMBus reads behind PCA9548 MUX) --- |
Why I did it
The existing PDDF PddfVoltageSensor base class only supports hwmon sysfs reads. This forces any vendor with non-hwmon voltage sensors (IIO ADCs, raw PMBus chips without hwmon drivers) to write their own custom platform-specific Python code, duplicating effort across vendors.
Many switch platforms use:
Without this change, each vendor must independently implement IIO reads, PMBus Linear16/VID decoding, scaling arithmetic, and threshold lookups — all of which are generic and belong in the common base class.
How I did it
pddf_voltage_sensor.py:
Three-way sensor dispatch in get_value() based on sensor_type in JSON dev_attr:
IIO read path (_read_iio):
SMBus read path (_read_smbus / _read_smbus_via_parent):
Scaling support:
Threshold support:
Named PMBus constants replacing all magic numbers:
Robust error handling:
pddfapi.py:
show_attr_voltage_sensor_device(): checks sensor_type in dev_attr, routes "iio" → show_attr_iio_device(), else → show_attr_hwmon_device()
New show_attr_iio_device(): resolves IIO sysfs path from bus/addr/channel_id, reads in_voltageN_raw, supports virt_parent for parent device hwmon resolution
Backward compatibility:
Sample JSON configuration for each sensor type:
hwmon (existing, unchanged — uses DCDC parent + virt_parent):
"VOLTAGE12": {
"dev_info": {"device_type": "VOLTAGE_SENSOR"},
"i2c": {
"virt_parent": "VRM1",
"attr_list": [{"attr_name": "volt1_input",
"drv_attr_name": "in2_input"}],
"dev_attr": {"display_name": "MB_TRVDD1_0V9",
"high_threshold": "927",
"low_threshold": "873"}
}
}
IIO ADC (new — sensor_type + channel_id + scaling):
"VOLTAGE1": {
"dev_info": {"device_type": "VOLTAGE_SENSOR"},
"i2c": {
"topo_info": {"parent_bus": "0x9",
"dev_addr": "0x34",
"dev_type": "max1139"},
"dev_attr": {"sensor_type": "iio",
"channel_id": "0",
"multi_factor": "4",
"display_name": "BXX_VCC5P0",
"high_threshold": "5250",
"low_threshold": "4750"}
}
}
SMBus raw PMBus (new — sensor_type + optional parent MUX):
"VOLTAGE28": {
"dev_info": {"device_type": "VOLTAGE_SENSOR"},
"i2c": {
"topo_info": {"parent_bus": "0x3f",
"dev_addr": "0x20",
"dev_type": "max20796"},
"dev_attr": {"sensor_type": "smbus",
"display_name": "FPC_VDD_0V85",
"high_threshold": "875",
"low_threshold": "825",
"parent_mux_bus": "0x3d",
"parent_mux_addr": "0x70",
"parent_mux_ch": "0x08"}
}
}
How to verify it
For hwmon sensors (backward compatible):
For IIO sensors:
For SMBus sensors:
For thresholds:
Tested on Juniper platform with:
Which release branch to backport
N/A
Tested branch
master
Verified on Juniper platform hardware with SONiC master
Description for the changelog
Add IIO, SMBus, scaling and threshold support to PDDF voltage sensor
Link to config_db schema for YANG module changes
N/A
Signed-off-by: Satish Gopalakrishnan satishg@juniper.net