Skip to content

Commit e2ecf16

Browse files
ADM1273 support (#2250)
This change is largely a renaming of ADM1272 to ADM127x since the ADM1273 is a drop-in replacement and has the same behavior. The only thing of substance that was modified was how we Validate this device. The current behavior is the read the MFG_MODEL register and expect it to be `ADM1272-2A`. I think this is a bit fragile as the die revision is tacked on there (`-2A`) and could change without us knowing (the orderable PN here is actually still `ADM1272-1A` even though `ADM1272-2A` is being delivered). Then there is the additional complication that with the ADM1273 we would see something like `ADM1273-$A`. Thus, I've changed the behavior of the `adm127x::validate` no longer use the common `pmbus_validate` but to use its own version which will look at the first 7 bytes of the MFG_MODEL and make sure it is either `ADM1272` or `ADM1273`. fixes #2247
1 parent 9c40dcc commit e2ecf16

File tree

16 files changed

+92
-84
lines changed

16 files changed

+92
-84
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/cosmo/base.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ refdes = "U73"
12231223
[[config.i2c.devices]]
12241224
bus = "rear"
12251225
address = 0x14
1226-
device = "adm1272"
1226+
device = "adm127x"
12271227
description = "Sled hot swap controller"
12281228
power = { rails = [ "V54P5_IBC_A3" ] }
12291229
sensors = { temperature = 1, voltage = 1, current = 1 }

app/gemini-bu/app.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ refdes = "U501"
263263
# a development or evaluation vehicle
264264
#
265265
[[config.i2c.devices]]
266-
device = "adm1272"
266+
device = "adm127x"
267267
controller = 4
268268
port = "F"
269269
mux = 1

app/gimlet/base.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ refdes = "U352"
994994
[[config.i2c.devices]]
995995
bus = "rear"
996996
address = 0x10
997-
device = "adm1272"
997+
device = "adm127x"
998998
description = "Fan hot swap controller"
999999
power = { rails = [ "V54_FAN" ] }
10001000
sensors = { temperature = 1, voltage = 1, current = 1 }
@@ -1003,7 +1003,7 @@ refdes = "U419"
10031003
[[config.i2c.devices]]
10041004
bus = "rear"
10051005
address = 0x14
1006-
device = "adm1272"
1006+
device = "adm127x"
10071007
description = "Sled hot swap controller"
10081008
power = { rails = [ "V54_HS_OUTPUT" ] }
10091009
sensors = { temperature = 1, voltage = 1, current = 1 }

app/minibar/app.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ refdes = "U12"
248248
[[config.i2c.devices]]
249249
bus = "power"
250250
address = 0b0010_001
251-
device = "adm1272"
251+
device = "adm127x"
252252
description = "VBUS_SLED hot swap controller"
253253
power = { rails = [ "VBUS_SLED" ] }
254254
sensors = { temperature = 1, voltage = 1, current = 1 }
@@ -257,7 +257,7 @@ refdes = "U1"
257257
[[config.i2c.devices]]
258258
bus = "power"
259259
address = 0b0010_000
260-
device = "adm1272"
260+
device = "adm127x"
261261
description = "VBUS_SYS hot swap controller"
262262
power = { rails = [ "VBUS_SYS" ] }
263263
sensors = { temperature = 1, voltage = 1, current = 1 }

app/sidecar/base.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ af = 4
483483
[[config.i2c.devices]]
484484
bus = "northeast0"
485485
address = 0b0010_000
486-
device = "adm1272"
486+
device = "adm127x"
487487
description = "Fan 1 hot swap controller"
488488
power = { rails = [ "V54_FAN1" ] }
489489
sensors = { temperature = 1, voltage = 1, current = 1 }
@@ -531,7 +531,7 @@ refdes = "U92"
531531
[[config.i2c.devices]]
532532
bus = "northeast1"
533533
address = 0b0010_011
534-
device = "adm1272"
534+
device = "adm127x"
535535
description = "Fan 0 hot swap controller"
536536
power = { rails = [ "V54_FAN0" ] }
537537
sensors = { temperature = 1, voltage = 1, current = 1 }
@@ -559,7 +559,7 @@ removable = true
559559
[[config.i2c.devices]]
560560
bus = "northwest0"
561561
address = 0b0010_110
562-
device = "adm1272"
562+
device = "adm127x"
563563
description = "54V hot swap controller"
564564
power = { rails = [ "V54_HSC" ] }
565565
sensors = { temperature = 1, voltage = 1, current = 1 }
@@ -616,7 +616,7 @@ refdes = "U12"
616616
[[config.i2c.devices]]
617617
bus = "northwest1"
618618
address = 0b0010_011
619-
device = "adm1272"
619+
device = "adm127x"
620620
description = "Fan 2 hot swap controller"
621621
power = { rails = [ "V54_FAN2" ] }
622622
sensors = { temperature = 1, voltage = 1, current = 1 }
@@ -625,7 +625,7 @@ refdes = "U8"
625625
[[config.i2c.devices]]
626626
bus = "northwest1"
627627
address = 0b0010_000
628-
device = "adm1272"
628+
device = "adm127x"
629629
description = "Fan 3 hot swap controller"
630630
power = { rails = [ "V54_FAN3" ] }
631631
sensors = { temperature = 1, voltage = 1, current = 1 }

drv/i2c-devices/src/adm1272.rs renamed to drv/i2c-devices/src/adm127x.rs

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

5-
//! Driver for the ADM1272 hot-swap controller
5+
//! Driver for the ADM1272 and ADM1273 hot-swap controller
66
77
use core::cell::Cell;
88

99
use crate::{
10-
pmbus_validate, BadValidation, CurrentSensor, TempSensor, Validate,
11-
VoltageSensor,
10+
BadValidation, CurrentSensor, TempSensor, Validate, VoltageSensor,
1211
};
1312
use drv_i2c_api::*;
1413
use num_traits::float::FloatCore;
@@ -62,34 +61,34 @@ struct Coefficients {
6261
power: pmbus::Coefficients,
6362
}
6463

65-
pub struct Adm1272 {
64+
pub struct Adm127X {
6665
/// Underlying I2C device
6766
device: I2cDevice,
6867
/// Value of the rsense resistor, in milliohms
6968
rsense: i32,
7069
/// Our (cached) coefficients
7170
coefficients: Cell<Option<Coefficients>>,
7271
/// Our (cached) configuration
73-
config: Cell<Option<adm1272::PMON_CONFIG::CommandData>>,
72+
config: Cell<Option<adm127x::PMON_CONFIG::CommandData>>,
7473
}
7574

76-
impl core::fmt::Display for Adm1272 {
75+
impl core::fmt::Display for Adm127X {
7776
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
78-
write!(f, "adm1272: {}", &self.device)
77+
write!(f, "adm127x: {}", &self.device)
7978
}
8079
}
8180

8281
#[derive(Copy, Clone, PartialEq)]
8382
enum Trace {
8483
None,
8584
Coefficients(pmbus::Coefficients),
86-
Config(adm1272::PMON_CONFIG::CommandData),
87-
WriteConfig(adm1272::PMON_CONFIG::CommandData),
85+
Config(adm127x::PMON_CONFIG::CommandData),
86+
WriteConfig(adm127x::PMON_CONFIG::CommandData),
8887
}
8988

9089
ringbuf!(Trace, 8, Trace::None);
9190

92-
impl Adm1272 {
91+
impl Adm127X {
9392
pub fn new(device: &I2cDevice, rsense: Ohms) -> Self {
9493
Self {
9594
device: *device,
@@ -99,12 +98,12 @@ impl Adm1272 {
9998
}
10099
}
101100

102-
fn read_config(&self) -> Result<adm1272::PMON_CONFIG::CommandData, Error> {
101+
fn read_config(&self) -> Result<adm127x::PMON_CONFIG::CommandData, Error> {
103102
if let Some(ref config) = self.config.get() {
104103
return Ok(*config);
105104
}
106105

107-
let config = pmbus_read!(self.device, adm1272::PMON_CONFIG)?;
106+
let config = pmbus_read!(self.device, adm127x::PMON_CONFIG)?;
108107
ringbuf_entry!(Trace::Config(config));
109108
self.config.set(Some(config));
110109

@@ -113,10 +112,10 @@ impl Adm1272 {
113112

114113
fn write_config(
115114
&self,
116-
config: adm1272::PMON_CONFIG::CommandData,
115+
config: adm127x::PMON_CONFIG::CommandData,
117116
) -> Result<(), Error> {
118117
ringbuf_entry!(Trace::WriteConfig(config));
119-
let out = pmbus_write!(self.device, adm1272::PMON_CONFIG, config);
118+
let out = pmbus_write!(self.device, adm127x::PMON_CONFIG, config);
120119
if out.is_err() {
121120
// If the write fails, invalidate the cache, since we don't
122121
// know exactly what state the remote system ended up in.
@@ -127,11 +126,11 @@ impl Adm1272 {
127126

128127
//
129128
// Unlike many/most PMBus devices that have one set of coefficients, the
130-
// coefficients for the ADM1272 depends on the mode of the device. We
129+
// coefficients for the ADM127x depends on the mode of the device. We
131130
// therefore determine these dynamically -- but cache the results.
132131
//
133132
fn load_coefficients(&self) -> Result<Coefficients, Error> {
134-
use adm1272::PMON_CONFIG::*;
133+
use adm127x::PMON_CONFIG::*;
135134

136135
if let Some(coefficients) = self.coefficients.get() {
137136
return Ok(coefficients);
@@ -143,7 +142,7 @@ impl Adm1272 {
143142
let irange = config.get_i_range().ok_or(Error::InvalidConfig)?;
144143

145144
//
146-
// From Table 10 (columns 1 and 2) of the ADM1272 datasheet.
145+
// From Table 10 (columns 1 and 2) of the ADM1272 and ADM1273 datasheets.
147146
//
148147
let voltage = match vrange {
149148
VRange::Range100V => pmbus::Coefficients {
@@ -161,7 +160,7 @@ impl Adm1272 {
161160
ringbuf_entry!(Trace::Coefficients(voltage));
162161

163162
//
164-
// From Table 10 (columns 3 and 4) of the ADM1272 datasheet.
163+
// From Table 10 (columns 3 and 4) of the ADM1272 and ADM1273 datasheets.
165164
//
166165
let current = match irange {
167166
IRange::Range30mV => pmbus::Coefficients {
@@ -179,7 +178,7 @@ impl Adm1272 {
179178
ringbuf_entry!(Trace::Coefficients(current));
180179

181180
//
182-
// From Table 10 (columns 5 through 8) of the ADM1272 datasheet.
181+
// From Table 10 (columns 5 through 8) of the ADM1272 and ADM1273 datasheet.
183182
//
184183
let power = match (irange, vrange) {
185184
(IRange::Range15mV, VRange::Range60V) => pmbus::Coefficients {
@@ -215,7 +214,7 @@ impl Adm1272 {
215214
}
216215

217216
fn enable_vin_sampling(&self) -> Result<(), Error> {
218-
use adm1272::PMON_CONFIG::*;
217+
use adm127x::PMON_CONFIG::*;
219218
let mut config = self.read_config()?;
220219

221220
match config.get_v_in_enable() {
@@ -229,7 +228,7 @@ impl Adm1272 {
229228
}
230229

231230
fn enable_vout_sampling(&self) -> Result<(), Error> {
232-
use adm1272::PMON_CONFIG::*;
231+
use adm127x::PMON_CONFIG::*;
233232
let mut config = self.read_config()?;
234233

235234
match config.get_v_out_enable() {
@@ -243,7 +242,7 @@ impl Adm1272 {
243242
}
244243

245244
fn enable_temp1_sampling(&self) -> Result<(), Error> {
246-
use adm1272::PMON_CONFIG::*;
245+
use adm127x::PMON_CONFIG::*;
247246
let mut config = self.read_config()?;
248247

249248
match config.get_temp_1_enable() {
@@ -258,12 +257,12 @@ impl Adm1272 {
258257

259258
pub fn read_vin(&self) -> Result<Volts, Error> {
260259
self.enable_vin_sampling()?;
261-
let vin = pmbus_read!(self.device, adm1272::READ_VIN)?;
260+
let vin = pmbus_read!(self.device, adm127x::READ_VIN)?;
262261
Ok(Volts(vin.get(&self.load_coefficients()?.voltage)?.0))
263262
}
264263

265264
pub fn peak_iout(&self) -> Result<Amperes, Error> {
266-
let iout = pmbus_read!(self.device, adm1272::PEAK_IOUT)?;
265+
let iout = pmbus_read!(self.device, adm127x::PEAK_IOUT)?;
267266
Ok(Amperes(iout.get(&self.load_coefficients()?.current)?.0))
268267
}
269268

@@ -272,33 +271,42 @@ impl Adm1272 {
272271
}
273272
}
274273

275-
impl Validate<Error> for Adm1272 {
274+
impl Validate<Error> for Adm127X {
276275
fn validate(device: &I2cDevice) -> Result<bool, Error> {
277-
let expected = b"ADM1272-2A";
278-
pmbus_validate(device, CommandCode::MFR_MODEL, expected)
279-
.map_err(Into::into)
276+
// We don't use the usual `pmbus_validate` here as the ADM127x case is special in that
277+
// multiple device models and die revisions may be supported. We read 10 bytes but only
278+
// look at the first 7 since the final three are a dash byte and two bytes of die rev.
279+
// E.g., ADM1272-2A or ADM1273-1A
280+
let cmd = CommandCode::MFR_MODEL as u8;
281+
let mut model = [0u8; 10];
282+
let allowed = [b"ADM1272", b"ADM1273"];
283+
match device.read_block(cmd, &mut model) {
284+
Ok(size) => Ok(size == model.len()
285+
&& allowed.iter().any(|&m| model.starts_with(m))),
286+
Err(code) => Err(Error::from(BadValidation { cmd, code })),
287+
}
280288
}
281289
}
282290

283-
impl TempSensor<Error> for Adm1272 {
291+
impl TempSensor<Error> for Adm127X {
284292
fn read_temperature(&self) -> Result<Celsius, Error> {
285293
self.enable_temp1_sampling()?;
286-
let temp = pmbus_read!(self.device, adm1272::READ_TEMPERATURE_1)?;
294+
let temp = pmbus_read!(self.device, adm127x::READ_TEMPERATURE_1)?;
287295
Ok(Celsius(temp.get()?.0))
288296
}
289297
}
290298

291-
impl CurrentSensor<Error> for Adm1272 {
299+
impl CurrentSensor<Error> for Adm127X {
292300
fn read_iout(&self) -> Result<Amperes, Error> {
293-
let iout = pmbus_read!(self.device, adm1272::READ_IOUT)?;
301+
let iout = pmbus_read!(self.device, adm127x::READ_IOUT)?;
294302
Ok(Amperes(iout.get(&self.load_coefficients()?.current)?.0))
295303
}
296304
}
297305

298-
impl VoltageSensor<Error> for Adm1272 {
306+
impl VoltageSensor<Error> for Adm127X {
299307
fn read_vout(&self) -> Result<Volts, Error> {
300308
self.enable_vout_sampling()?;
301-
let vout = pmbus_read!(self.device, adm1272::READ_VOUT)?;
309+
let vout = pmbus_read!(self.device, adm127x::READ_VOUT)?;
302310
Ok(Volts(vout.get(&self.load_coefficients()?.voltage)?.0))
303311
}
304312
}

drv/i2c-devices/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//!
77
//! This crate contains (generally) all I2C device drivers, including:
88
//!
9-
//! - [`adm1272`]: ADM1272 hot swap controller
9+
//! - [`adm127x`]: ADM1272 or ADM1273 hot swap controller
1010
//! - [`adt7420`]: ADT7420 temperature sensor
1111
//! - [`at24csw080`]: AT24CSW080 serial EEPROM
1212
//! - [`ds2482`]: DS2482-100 1-wire initiator
@@ -233,7 +233,7 @@ pub trait Validate<T: core::convert::Into<drv_i2c_api::ResponseCode>> {
233233
}
234234
}
235235

236-
pub mod adm1272;
236+
pub mod adm127x;
237237
pub mod adt7420;
238238
pub mod at24csw080;
239239
pub mod bmr491;

lib/host-sp-messages/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ pub enum InventoryData {
414414
fans: [Identity; 3],
415415
},
416416

417-
Adm1272 {
417+
Adm127x {
418418
/// MFR_ID (PMBus operation 0x99)
419419
mfr_id: [u8; 3],
420420
/// MFR_MODEL (PMBus operation 0x9A)
@@ -1192,7 +1192,7 @@ mod tests {
11921192
b = &b[106..];
11931193
}
11941194

1195-
let d = InventoryData::Adm1272 {
1195+
let d = InventoryData::Adm127x {
11961196
mfr_id: [1, 2, 3],
11971197
mfr_model: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
11981198
mfr_revision: [0, 10],

task/host-sp-comms/src/bsp/cosmo_a.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,9 @@ impl ServerImpl {
345345
})
346346
}
347347
33 => {
348-
let (dev, sensors) = by_refdes!(U79, adm1272);
348+
let (dev, sensors) = by_refdes!(U79, adm127x);
349349
let name = dev.component_id().as_bytes();
350-
*self.scratch = InventoryData::Adm1272 {
350+
*self.scratch = InventoryData::Adm127x {
351351
mfr_id: [0u8; 3],
352352
mfr_model: [0u8; 10],
353353
mfr_revision: [0u8; 2],
@@ -359,7 +359,7 @@ impl ServerImpl {
359359
};
360360
self.tx_buf.try_encode_inventory(sequence, name, || {
361361
use pmbus::commands::tps546b24a::CommandCode;
362-
let InventoryData::Adm1272 {
362+
let InventoryData::Adm127x {
363363
mfr_id,
364364
mfr_model,
365365
mfr_revision,

0 commit comments

Comments
 (0)