Skip to content

Commit

Permalink
hwmon: (adm1275) Add support for ADM1278
Browse files Browse the repository at this point in the history
ADM1278 is mostly compatible to other chips of the same series.
Besides the usual difference in coefficients, it supports
a temperature sensor, and it can measure both input and output
voltage at the same time.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
(cherry picked from commit 709066a)
Signed-off-by: Joel Stanley <joel@jms.id.au>
  • Loading branch information
groeck authored and shenki committed Mar 21, 2016
1 parent 271462b commit 1500e26
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 9 deletions.
29 changes: 23 additions & 6 deletions Documentation/hwmon/adm1275
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Supported chips:
Prefix: 'adm1276'
Addresses scanned: -
Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1276.pdf
* Analog Devices ADM1278
Prefix: 'adm1278'
Addresses scanned: -
Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1278.pdf
* Analog Devices ADM1293/ADM1294
Prefix: 'adm1293', 'adm1294'
Addresses scanned: -
Expand All @@ -25,13 +29,15 @@ Author: Guenter Roeck <linux@roeck-us.net>
Description
-----------

This driver supports hardware montoring for Analog Devices ADM1075, ADM1275,
ADM1276, ADM1293, and ADM1294 Hot-Swap Controller and Digital Power Monitors.
This driver supports hardware monitoring for Analog Devices ADM1075, ADM1275,
ADM1276, ADM1278, ADM1293, and ADM1294 Hot-Swap Controller and Digital
Power Monitors.

ADM1075, ADM1275, ADM1276, ADM1293, and ADM1294 are hot-swap controllers that
allow a circuit board to be removed from or inserted into a live backplane.
They also feature current and voltage readback via an integrated 12
bit analog-to-digital converter (ADC), accessed using a PMBus interface.
ADM1075, ADM1275, ADM1276, ADM1278, ADM1293, and ADM1294 are hot-swap
controllers that allow a circuit board to be removed from or inserted into
a live backplane. They also feature current and voltage readback via an
integrated 12 bit analog-to-digital converter (ADC), accessed using a
PMBus interface.

The driver is a client driver to the core PMBus driver. Please see
Documentation/hwmon/pmbus for details on PMBus client drivers.
Expand Down Expand Up @@ -96,3 +102,14 @@ power1_reset_history Write any value to reset history.

Power attributes are supported on ADM1075, ADM1276,
ADM1293, and ADM1294.

temp1_input Chip temperature.
Temperature attributes are only available on ADM1278.
temp1_max Maximum chip temperature.
temp1_max_alarm Temperature alarm.
temp1_crit Critical chip temperature.
temp1_crit_alarm Critical temperature high alarm.
temp1_highest Highest observed temperature.
temp1_reset_history Write any value to reset history.

Temperature attributes are supported on ADM1278.
4 changes: 2 additions & 2 deletions drivers/hwmon/pmbus/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ config SENSORS_ADM1275
default n
help
If you say yes here you get hardware monitoring support for Analog
Devices ADM1075, ADM1275, ADM1276, ADM1293, and ADM1294 Hot-Swap
Controller and Digital Power Monitors.
Devices ADM1075, ADM1275, ADM1276, ADM1278, ADM1293, and ADM1294
Hot-Swap Controller and Digital Power Monitors.

This driver can also be built as a module. If so, the module will
be called adm1275.
Expand Down
56 changes: 55 additions & 1 deletion drivers/hwmon/pmbus/adm1275.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <linux/bitops.h>
#include "pmbus.h"

enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 };
enum chips { adm1075, adm1275, adm1276, adm1278, adm1293, adm1294 };

#define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0)
#define ADM1293_MFR_STATUS_VAUX_UV_WARN BIT(5)
Expand All @@ -41,6 +41,10 @@ enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 };
#define ADM1075_IRANGE_25 BIT(3)
#define ADM1075_IRANGE_MASK (BIT(3) | BIT(4))

#define ADM1278_TEMP1_EN BIT(3)
#define ADM1278_VIN_EN BIT(2)
#define ADM1278_VOUT_EN BIT(1)

#define ADM1293_IRANGE_25 0
#define ADM1293_IRANGE_50 BIT(6)
#define ADM1293_IRANGE_100 BIT(7)
Expand All @@ -54,6 +58,7 @@ enum chips { adm1075, adm1275, adm1276, adm1293, adm1294 };

#define ADM1293_VAUX_EN BIT(1)

#define ADM1278_PEAK_TEMP 0xd7
#define ADM1275_IOUT_WARN2_LIMIT 0xd7
#define ADM1275_DEVICE_CONFIG 0xd8

Expand All @@ -80,6 +85,7 @@ struct adm1275_data {
bool have_iout_min;
bool have_pin_min;
bool have_pin_max;
bool have_temp_max;
struct pmbus_driver_info info;
};

Expand Down Expand Up @@ -113,6 +119,13 @@ static const struct coefficients adm1276_coefficients[] = {
[4] = { 2115, 0, -1 }, /* power, vrange not set */
};

static const struct coefficients adm1278_coefficients[] = {
[0] = { 19599, 0, -2 }, /* voltage */
[1] = { 800, 20475, -1 }, /* current */
[2] = { 6123, 0, -2 }, /* power */
[3] = { 42, 31880, -1 }, /* temperature */
};

static const struct coefficients adm1293_coefficients[] = {
[0] = { 3333, -1, 0 }, /* voltage, vrange 1.2V */
[1] = { 5552, -5, -1 }, /* voltage, vrange 7.4V */
Expand Down Expand Up @@ -196,6 +209,11 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN);
break;
case PMBUS_VIRT_READ_TEMP_MAX:
if (!data->have_temp_max)
return -ENXIO;
ret = pmbus_read_word_data(client, 0, ADM1278_PEAK_TEMP);
break;
case PMBUS_VIRT_RESET_IOUT_HISTORY:
case PMBUS_VIRT_RESET_VOUT_HISTORY:
case PMBUS_VIRT_RESET_VIN_HISTORY:
Expand All @@ -204,6 +222,10 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
if (!data->have_pin_max)
return -ENXIO;
break;
case PMBUS_VIRT_RESET_TEMP_HISTORY:
if (!data->have_temp_max)
return -ENXIO;
break;
default:
ret = -ENODATA;
break;
Expand Down Expand Up @@ -245,6 +267,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
ret = pmbus_write_word_data(client, 0,
ADM1293_PIN_MIN, 0);
break;
case PMBUS_VIRT_RESET_TEMP_HISTORY:
ret = pmbus_write_word_data(client, 0, ADM1278_PEAK_TEMP, 0);
break;
default:
ret = -ENODATA;
break;
Expand Down Expand Up @@ -312,6 +337,7 @@ static const struct i2c_device_id adm1275_id[] = {
{ "adm1075", adm1075 },
{ "adm1275", adm1275 },
{ "adm1276", adm1276 },
{ "adm1278", adm1278 },
{ "adm1293", adm1293 },
{ "adm1294", adm1294 },
{ }
Expand All @@ -329,6 +355,7 @@ static int adm1275_probe(struct i2c_client *client,
const struct i2c_device_id *mid;
const struct coefficients *coefficients;
int vindex = -1, voindex = -1, cindex = -1, pindex = -1;
int tindex = -1;

if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA
Expand Down Expand Up @@ -386,6 +413,7 @@ static int adm1275_probe(struct i2c_client *client,
info->format[PSC_VOLTAGE_OUT] = direct;
info->format[PSC_CURRENT_OUT] = direct;
info->format[PSC_POWER] = direct;
info->format[PSC_TEMPERATURE] = direct;
info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;

info->read_word_data = adm1275_read_word_data;
Expand Down Expand Up @@ -460,6 +488,27 @@ static int adm1275_probe(struct i2c_client *client,
info->func[0] |=
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
break;
case adm1278:
data->have_vout = true;
data->have_pin_max = true;
data->have_temp_max = true;

coefficients = adm1278_coefficients;
vindex = 0;
cindex = 1;
pindex = 2;
tindex = 3;

info->func[0] |= PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT;
if (config & ADM1278_TEMP1_EN)
info->func[0] |=
PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
if (config & ADM1278_VIN_EN)
info->func[0] |= PMBUS_HAVE_VIN;
if (config & ADM1278_VOUT_EN)
info->func[0] |=
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
break;
case adm1293:
case adm1294:
data->have_iout_min = true;
Expand Down Expand Up @@ -537,6 +586,11 @@ static int adm1275_probe(struct i2c_client *client,
info->b[PSC_POWER] = coefficients[pindex].b;
info->R[PSC_POWER] = coefficients[pindex].R;
}
if (tindex >= 0) {
info->m[PSC_TEMPERATURE] = coefficients[tindex].m;
info->b[PSC_TEMPERATURE] = coefficients[tindex].b;
info->R[PSC_TEMPERATURE] = coefficients[tindex].R;
}

return pmbus_do_probe(client, id, info);
}
Expand Down

0 comments on commit 1500e26

Please sign in to comment.