diff options
author | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-07-14 14:55:35 -0400 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-10-24 14:09:35 -0400 |
commit | 5cf231a346fb80d7945aa46e90186a068a3a001b (patch) | |
tree | 642f84017b93f745b72360b7b2d619ec2403224f /drivers/hwmon | |
parent | c5e6763667ffc94eaad4634841cb1b7ecd951fb7 (diff) |
hwmon: (pmbus/adm1275) Add support for ADM1276
ADM1276 is mostly compatible to ADM1275, with added support for input power
measurement. Add support for it to the ADM1275 driver.
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Acked-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/pmbus/Kconfig | 5 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/adm1275.c | 59 |
2 files changed, 54 insertions, 10 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index c9237b9dcff2..37575582e51a 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -26,11 +26,12 @@ config SENSORS_PMBUS | |||
26 | be called pmbus. | 26 | be called pmbus. |
27 | 27 | ||
28 | config SENSORS_ADM1275 | 28 | config SENSORS_ADM1275 |
29 | tristate "Analog Devices ADM1275" | 29 | tristate "Analog Devices ADM1275 and compatibles" |
30 | default n | 30 | default n |
31 | help | 31 | help |
32 | If you say yes here you get hardware monitoring support for Analog | 32 | If you say yes here you get hardware monitoring support for Analog |
33 | Devices ADM1275 Hot-Swap Controller and Digital Power Monitor. | 33 | Devices ADM1275 and ADM1276 Hot-Swap Controller and Digital Power |
34 | Monitor. | ||
34 | 35 | ||
35 | This driver can also be built as a module. If so, the module will | 36 | This driver can also be built as a module. If so, the module will |
36 | be called adm1275. | 37 | be called adm1275. |
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 7a9f2d9dbba4..fa1811274c27 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include "pmbus.h" | 24 | #include "pmbus.h" |
25 | 25 | ||
26 | enum chips { adm1275, adm1276 }; | ||
27 | |||
26 | #define ADM1275_PEAK_IOUT 0xd0 | 28 | #define ADM1275_PEAK_IOUT 0xd0 |
27 | #define ADM1275_PEAK_VIN 0xd1 | 29 | #define ADM1275_PEAK_VIN 0xd1 |
28 | #define ADM1275_PEAK_VOUT 0xd2 | 30 | #define ADM1275_PEAK_VOUT 0xd2 |
@@ -36,9 +38,12 @@ | |||
36 | 38 | ||
37 | #define ADM1275_IOUT_WARN2_SELECT (1 << 4) | 39 | #define ADM1275_IOUT_WARN2_SELECT (1 << 4) |
38 | 40 | ||
41 | #define ADM1276_PEAK_PIN 0xda | ||
42 | |||
39 | #define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0) | 43 | #define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0) |
40 | 44 | ||
41 | struct adm1275_data { | 45 | struct adm1275_data { |
46 | int id; | ||
42 | bool have_oc_fault; | 47 | bool have_oc_fault; |
43 | struct pmbus_driver_info info; | 48 | struct pmbus_driver_info info; |
44 | }; | 49 | }; |
@@ -49,7 +54,7 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) | |||
49 | { | 54 | { |
50 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | 55 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
51 | const struct adm1275_data *data = to_adm1275_data(info); | 56 | const struct adm1275_data *data = to_adm1275_data(info); |
52 | int ret; | 57 | int ret = 0; |
53 | 58 | ||
54 | if (page) | 59 | if (page) |
55 | return -ENXIO; | 60 | return -ENXIO; |
@@ -78,10 +83,20 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) | |||
78 | case PMBUS_VIRT_READ_VIN_MAX: | 83 | case PMBUS_VIRT_READ_VIN_MAX: |
79 | ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); | 84 | ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); |
80 | break; | 85 | break; |
86 | case PMBUS_VIRT_READ_PIN_MAX: | ||
87 | if (data->id != adm1276) { | ||
88 | ret = -ENXIO; | ||
89 | break; | ||
90 | } | ||
91 | ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN); | ||
92 | break; | ||
81 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 93 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
82 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | 94 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
83 | case PMBUS_VIRT_RESET_VIN_HISTORY: | 95 | case PMBUS_VIRT_RESET_VIN_HISTORY: |
84 | ret = 0; | 96 | break; |
97 | case PMBUS_VIRT_RESET_PIN_HISTORY: | ||
98 | if (data->id != adm1276) | ||
99 | ret = -ENXIO; | ||
85 | break; | 100 | break; |
86 | default: | 101 | default: |
87 | ret = -ENODATA; | 102 | ret = -ENODATA; |
@@ -113,6 +128,9 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, | |||
113 | case PMBUS_VIRT_RESET_VIN_HISTORY: | 128 | case PMBUS_VIRT_RESET_VIN_HISTORY: |
114 | ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0); | 129 | ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0); |
115 | break; | 130 | break; |
131 | case PMBUS_VIRT_RESET_PIN_HISTORY: | ||
132 | ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0); | ||
133 | break; | ||
116 | default: | 134 | default: |
117 | ret = -ENODATA; | 135 | ret = -ENODATA; |
118 | break; | 136 | break; |
@@ -180,6 +198,7 @@ static int adm1275_probe(struct i2c_client *client, | |||
180 | goto err_mem; | 198 | goto err_mem; |
181 | } | 199 | } |
182 | 200 | ||
201 | data->id = id->driver_data; | ||
183 | info = &data->info; | 202 | info = &data->info; |
184 | 203 | ||
185 | info->pages = 1; | 204 | info->pages = 1; |
@@ -214,10 +233,33 @@ static int adm1275_probe(struct i2c_client *client, | |||
214 | if (device_config & ADM1275_IOUT_WARN2_SELECT) | 233 | if (device_config & ADM1275_IOUT_WARN2_SELECT) |
215 | data->have_oc_fault = true; | 234 | data->have_oc_fault = true; |
216 | 235 | ||
217 | if (config & ADM1275_VIN_VOUT_SELECT) | 236 | switch (id->driver_data) { |
218 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | 237 | case adm1275: |
219 | else | 238 | if (config & ADM1275_VIN_VOUT_SELECT) |
220 | info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT; | 239 | info->func[0] |= |
240 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | ||
241 | else | ||
242 | info->func[0] |= | ||
243 | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT; | ||
244 | break; | ||
245 | case adm1276: | ||
246 | info->format[PSC_POWER] = direct; | ||
247 | info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN | ||
248 | | PMBUS_HAVE_STATUS_INPUT; | ||
249 | if (config & ADM1275_VIN_VOUT_SELECT) | ||
250 | info->func[0] |= | ||
251 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | ||
252 | if (config & ADM1275_VRANGE) { | ||
253 | info->m[PSC_POWER] = 6043; | ||
254 | info->b[PSC_POWER] = 0; | ||
255 | info->R[PSC_POWER] = -2; | ||
256 | } else { | ||
257 | info->m[PSC_POWER] = 2115; | ||
258 | info->b[PSC_POWER] = 0; | ||
259 | info->R[PSC_POWER] = -1; | ||
260 | } | ||
261 | break; | ||
262 | } | ||
221 | 263 | ||
222 | ret = pmbus_do_probe(client, id, info); | 264 | ret = pmbus_do_probe(client, id, info); |
223 | if (ret) | 265 | if (ret) |
@@ -240,7 +282,8 @@ static int adm1275_remove(struct i2c_client *client) | |||
240 | } | 282 | } |
241 | 283 | ||
242 | static const struct i2c_device_id adm1275_id[] = { | 284 | static const struct i2c_device_id adm1275_id[] = { |
243 | {"adm1275", 0}, | 285 | { "adm1275", adm1275 }, |
286 | { "adm1276", adm1276 }, | ||
244 | { } | 287 | { } |
245 | }; | 288 | }; |
246 | MODULE_DEVICE_TABLE(i2c, adm1275_id); | 289 | MODULE_DEVICE_TABLE(i2c, adm1275_id); |
@@ -265,7 +308,7 @@ static void __exit adm1275_exit(void) | |||
265 | } | 308 | } |
266 | 309 | ||
267 | MODULE_AUTHOR("Guenter Roeck"); | 310 | MODULE_AUTHOR("Guenter Roeck"); |
268 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275"); | 311 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles"); |
269 | MODULE_LICENSE("GPL"); | 312 | MODULE_LICENSE("GPL"); |
270 | module_init(adm1275_init); | 313 | module_init(adm1275_init); |
271 | module_exit(adm1275_exit); | 314 | module_exit(adm1275_exit); |