Skip to content

Commit ccfcbc1

Browse files
committed
hwmon: (adm1275) Add support for ADM1075
Signed-off-by: Guenter Roeck <[email protected]>
1 parent 0560c04 commit ccfcbc1

File tree

2 files changed

+94
-10
lines changed

2 files changed

+94
-10
lines changed

Documentation/adm1275

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ Kernel driver adm1275
22
=====================
33

44
Supported chips:
5+
* Analog Devices ADM1075
6+
Prefix: 'adm1075'
7+
Addresses scanned: -
8+
Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1075.pdf
59
* Analog Devices ADM1275
610
Prefix: 'adm1275'
711
Addresses scanned: -
@@ -17,13 +21,13 @@ Author: Guenter Roeck <[email protected]>
1721
Description
1822
-----------
1923

20-
This driver supports hardware montoring for Analog Devices ADM1275 and ADM1276
21-
Hot-Swap Controller and Digital Power Monitor.
24+
This driver supports hardware montoring for Analog Devices ADM1075, ADM1275,
25+
and ADM1276 Hot-Swap Controller and Digital Power Monitor.
2226

23-
ADM1275 and ADM1276 are hot-swap controllers that allow a circuit board to be
24-
removed from or inserted into a live backplane. They also feature current and
25-
voltage readback via an integrated 12-bit analog-to-digital converter (ADC),
26-
accessed using a PMBus interface.
27+
ADM1075, ADM1275, and ADM1276 are hot-swap controllers that allow a circuit
28+
board to be removed from or inserted into a live backplane. They also feature
29+
current and voltage readback via an integrated 12-bit analog-to-digital
30+
converter (ADC), accessed using a PMBus interface.
2731

2832
The driver is a client driver to the core PMBus driver. Please see
2933
Documentation/hwmon/pmbus for details on PMBus client drivers.

adm1275.c

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <linux/i2c.h>
2424
#include "pmbus.h"
2525

26-
enum chips { adm1275, adm1276 };
26+
enum chips { adm1075, adm1275, adm1276 };
2727

2828
#define ADM1275_PEAK_IOUT 0xd0
2929
#define ADM1275_PEAK_VIN 0xd1
@@ -32,6 +32,9 @@ enum chips { adm1275, adm1276 };
3232

3333
#define ADM1275_VIN_VOUT_SELECT (1 << 6)
3434
#define ADM1275_VRANGE (1 << 5)
35+
#define ADM1075_IRANGE_50 (1 << 4)
36+
#define ADM1075_IRANGE_25 (1 << 3)
37+
#define ADM1075_IRANGE_MASK ((1 << 3) | (1 << 4))
3538

3639
#define ADM1275_ALERT1_CONFIG 0xd5
3740
#define ADM1275_ALERT2_CONFIG 0xd6
@@ -53,6 +56,14 @@ enum chips { adm1275, adm1276 };
5356

5457
#define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0)
5558

59+
#define ADM1075_READ_VAUX 0xdd
60+
#define ADM1075_VAUX_OV_WARN_LIMIT 0xde
61+
#define ADM1075_VAUX_UV_WARN_LIMIT 0xdf
62+
#define ADM1075_VAUX_STATUS 0xf6
63+
64+
#define ADM1075_VAUX_OV_WARN (1<<7)
65+
#define ADM1075_VAUX_UV_WARN (1<<6)
66+
5667
struct adm1275_data {
5768
int id;
5869
bool have_oc_fault;
@@ -87,6 +98,29 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
8798
}
8899
ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
89100
break;
101+
case PMBUS_VOUT_OV_WARN_LIMIT:
102+
if (data->id != adm1075) {
103+
ret = -ENODATA;
104+
break;
105+
}
106+
ret = pmbus_read_word_data(client, 0,
107+
ADM1075_VAUX_OV_WARN_LIMIT);
108+
break;
109+
case PMBUS_VOUT_UV_WARN_LIMIT:
110+
if (data->id != adm1075) {
111+
ret = -ENODATA;
112+
break;
113+
}
114+
ret = pmbus_read_word_data(client, 0,
115+
ADM1075_VAUX_UV_WARN_LIMIT);
116+
break;
117+
case PMBUS_READ_VOUT:
118+
if (data->id != adm1075) {
119+
ret = -ENODATA;
120+
break;
121+
}
122+
ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX);
123+
break;
90124
case PMBUS_VIRT_READ_IOUT_MAX:
91125
ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT);
92126
break;
@@ -97,7 +131,7 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
97131
ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN);
98132
break;
99133
case PMBUS_VIRT_READ_PIN_MAX:
100-
if (data->id != adm1276) {
134+
if (data->id == adm1275) {
101135
ret = -ENXIO;
102136
break;
103137
}
@@ -108,7 +142,7 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
108142
case PMBUS_VIRT_RESET_VIN_HISTORY:
109143
break;
110144
case PMBUS_VIRT_RESET_PIN_HISTORY:
111-
if (data->id != adm1276)
145+
if (data->id == adm1275)
112146
ret = -ENXIO;
113147
break;
114148
default:
@@ -176,6 +210,19 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg)
176210
PB_IOUT_OC_FAULT : PB_IOUT_UC_FAULT;
177211
}
178212
break;
213+
case PMBUS_STATUS_VOUT:
214+
if (data->id != adm1075) {
215+
ret = -ENODATA;
216+
break;
217+
}
218+
ret = 0;
219+
mfr_status = pmbus_read_byte_data(client, 0,
220+
ADM1075_VAUX_STATUS);
221+
if (mfr_status & ADM1075_VAUX_OV_WARN)
222+
ret |= PB_VOLTAGE_OV_WARNING;
223+
if (mfr_status & ADM1075_VAUX_UV_WARN)
224+
ret |= PB_VOLTAGE_UV_WARNING;
225+
break;
179226
default:
180227
ret = -ENODATA;
181228
break;
@@ -243,6 +290,7 @@ static void adm1275_alert_handler(struct i2c_client *client, bool alarm)
243290
}
244291

245292
static const struct i2c_device_id adm1275_id[] = {
293+
{ "adm1075", adm1075 },
246294
{ "adm1275", adm1275 },
247295
{ "adm1276", adm1276 },
248296
{ }
@@ -337,7 +385,14 @@ static int adm1275_probe(struct i2c_client *client,
337385
info->write_word_data = adm1275_write_word_data;
338386
info->alert_handler = adm1275_alert_handler;
339387

340-
if (config & ADM1275_VRANGE) {
388+
if (data->id == adm1075) {
389+
info->m[PSC_VOLTAGE_IN] = 27169;
390+
info->b[PSC_VOLTAGE_IN] = 0;
391+
info->R[PSC_VOLTAGE_IN] = -1;
392+
info->m[PSC_VOLTAGE_OUT] = 27169;
393+
info->b[PSC_VOLTAGE_OUT] = 0;
394+
info->R[PSC_VOLTAGE_OUT] = -1;
395+
} else if (config & ADM1275_VRANGE) {
341396
info->m[PSC_VOLTAGE_IN] = 19199;
342397
info->b[PSC_VOLTAGE_IN] = 0;
343398
info->R[PSC_VOLTAGE_IN] = -2;
@@ -357,6 +412,31 @@ static int adm1275_probe(struct i2c_client *client,
357412
data->have_oc_fault = true;
358413

359414
switch (data->id) {
415+
case adm1075:
416+
info->format[PSC_POWER] = direct;
417+
info->b[PSC_POWER] = 0;
418+
info->R[PSC_POWER] = -1;
419+
switch (config & ADM1075_IRANGE_MASK) {
420+
case ADM1075_IRANGE_25:
421+
info->m[PSC_POWER] = 8549;
422+
info->m[PSC_CURRENT_OUT] = 806;
423+
break;
424+
case ADM1075_IRANGE_50:
425+
info->m[PSC_POWER] = 4279;
426+
info->m[PSC_CURRENT_OUT] = 404;
427+
break;
428+
default:
429+
dev_err(&client->dev, "Invalid input current range");
430+
info->m[PSC_POWER] = 0;
431+
info->m[PSC_CURRENT_OUT] = 0;
432+
break;
433+
}
434+
info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
435+
| PMBUS_HAVE_STATUS_INPUT;
436+
if (config & ADM1275_VIN_VOUT_SELECT)
437+
info->func[0] |=
438+
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
439+
break;
360440
case adm1275:
361441
if (config & ADM1275_VIN_VOUT_SELECT)
362442
info->func[0] |=

0 commit comments

Comments
 (0)