aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/pmbus
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-02-24 06:40:22 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2012-03-18 21:27:52 -0400
commit590defe59ef9596dcd892d2d8395d730c510323d (patch)
treed186bfff6b0eb41d8dec801eaad8869c06ef6dbe /drivers/hwmon/pmbus
parent60b873e3329891cd86cf5a2629157dc0022f8beb (diff)
hwmon: (max34440) Add support for MAX34446
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/pmbus')
-rw-r--r--drivers/hwmon/pmbus/Kconfig4
-rw-r--r--drivers/hwmon/pmbus/max34440.c112
2 files changed, 111 insertions, 5 deletions
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index d1aa2dbd5b75..1f0d0110b6b8 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -68,11 +68,11 @@ config SENSORS_MAX16064
68 be called max16064. 68 be called max16064.
69 69
70config SENSORS_MAX34440 70config SENSORS_MAX34440
71 tristate "Maxim MAX34440/MAX34441" 71 tristate "Maxim MAX34440 and compatibles"
72 default n 72 default n
73 help 73 help
74 If you say yes here you get hardware monitoring support for Maxim 74 If you say yes here you get hardware monitoring support for Maxim
75 MAX34440 and MAX34441. 75 MAX34440, MAX34441, and MAX34446.
76 76
77 This driver can also be built as a module. If so, the module will 77 This driver can also be built as a module. If so, the module will
78 be called max34440. 78 be called max34440.
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
index 95ee9e195cb6..2ada7b021fbe 100644
--- a/drivers/hwmon/pmbus/max34440.c
+++ b/drivers/hwmon/pmbus/max34440.c
@@ -25,21 +25,35 @@
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include "pmbus.h" 26#include "pmbus.h"
27 27
28enum chips { max34440, max34441 }; 28enum chips { max34440, max34441, max34446 };
29 29
30#define MAX34440_MFR_VOUT_PEAK 0xd4 30#define MAX34440_MFR_VOUT_PEAK 0xd4
31#define MAX34440_MFR_IOUT_PEAK 0xd5 31#define MAX34440_MFR_IOUT_PEAK 0xd5
32#define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 32#define MAX34440_MFR_TEMPERATURE_PEAK 0xd6
33#define MAX34440_MFR_VOUT_MIN 0xd7 33#define MAX34440_MFR_VOUT_MIN 0xd7
34 34
35#define MAX34446_MFR_POUT_PEAK 0xe0
36#define MAX34446_MFR_POUT_AVG 0xe1
37#define MAX34446_MFR_IOUT_AVG 0xe2
38#define MAX34446_MFR_TEMPERATURE_AVG 0xe3
39
35#define MAX34440_STATUS_OC_WARN (1 << 0) 40#define MAX34440_STATUS_OC_WARN (1 << 0)
36#define MAX34440_STATUS_OC_FAULT (1 << 1) 41#define MAX34440_STATUS_OC_FAULT (1 << 1)
37#define MAX34440_STATUS_OT_FAULT (1 << 5) 42#define MAX34440_STATUS_OT_FAULT (1 << 5)
38#define MAX34440_STATUS_OT_WARN (1 << 6) 43#define MAX34440_STATUS_OT_WARN (1 << 6)
39 44
45struct max34440_data {
46 int id;
47 struct pmbus_driver_info info;
48};
49
50#define to_max34440_data(x) container_of(x, struct max34440_data, info)
51
40static int max34440_read_word_data(struct i2c_client *client, int page, int reg) 52static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
41{ 53{
42 int ret; 54 int ret;
55 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
56 const struct max34440_data *data = to_max34440_data(info);
43 57
44 switch (reg) { 58 switch (reg) {
45 case PMBUS_VIRT_READ_VOUT_MIN: 59 case PMBUS_VIRT_READ_VOUT_MIN:
@@ -50,14 +64,43 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
50 ret = pmbus_read_word_data(client, page, 64 ret = pmbus_read_word_data(client, page,
51 MAX34440_MFR_VOUT_PEAK); 65 MAX34440_MFR_VOUT_PEAK);
52 break; 66 break;
67 case PMBUS_VIRT_READ_IOUT_AVG:
68 if (data->id != max34446)
69 return -ENXIO;
70 ret = pmbus_read_word_data(client, page,
71 MAX34446_MFR_IOUT_AVG);
72 break;
53 case PMBUS_VIRT_READ_IOUT_MAX: 73 case PMBUS_VIRT_READ_IOUT_MAX:
54 ret = pmbus_read_word_data(client, page, 74 ret = pmbus_read_word_data(client, page,
55 MAX34440_MFR_IOUT_PEAK); 75 MAX34440_MFR_IOUT_PEAK);
56 break; 76 break;
77 case PMBUS_VIRT_READ_POUT_AVG:
78 if (data->id != max34446)
79 return -ENXIO;
80 ret = pmbus_read_word_data(client, page,
81 MAX34446_MFR_POUT_AVG);
82 break;
83 case PMBUS_VIRT_READ_POUT_MAX:
84 if (data->id != max34446)
85 return -ENXIO;
86 ret = pmbus_read_word_data(client, page,
87 MAX34446_MFR_POUT_PEAK);
88 break;
89 case PMBUS_VIRT_READ_TEMP_AVG:
90 if (data->id != max34446)
91 return -ENXIO;
92 ret = pmbus_read_word_data(client, page,
93 MAX34446_MFR_TEMPERATURE_AVG);
94 break;
57 case PMBUS_VIRT_READ_TEMP_MAX: 95 case PMBUS_VIRT_READ_TEMP_MAX:
58 ret = pmbus_read_word_data(client, page, 96 ret = pmbus_read_word_data(client, page,
59 MAX34440_MFR_TEMPERATURE_PEAK); 97 MAX34440_MFR_TEMPERATURE_PEAK);
60 break; 98 break;
99 case PMBUS_VIRT_RESET_POUT_HISTORY:
100 if (data->id != max34446)
101 return -ENXIO;
102 ret = 0;
103 break;
61 case PMBUS_VIRT_RESET_VOUT_HISTORY: 104 case PMBUS_VIRT_RESET_VOUT_HISTORY:
62 case PMBUS_VIRT_RESET_IOUT_HISTORY: 105 case PMBUS_VIRT_RESET_IOUT_HISTORY:
63 case PMBUS_VIRT_RESET_TEMP_HISTORY: 106 case PMBUS_VIRT_RESET_TEMP_HISTORY:
@@ -73,9 +116,19 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
73static int max34440_write_word_data(struct i2c_client *client, int page, 116static int max34440_write_word_data(struct i2c_client *client, int page,
74 int reg, u16 word) 117 int reg, u16 word)
75{ 118{
119 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
120 const struct max34440_data *data = to_max34440_data(info);
76 int ret; 121 int ret;
77 122
78 switch (reg) { 123 switch (reg) {
124 case PMBUS_VIRT_RESET_POUT_HISTORY:
125 ret = pmbus_write_word_data(client, page,
126 MAX34446_MFR_POUT_PEAK, 0);
127 if (ret)
128 break;
129 ret = pmbus_write_word_data(client, page,
130 MAX34446_MFR_POUT_AVG, 0);
131 break;
79 case PMBUS_VIRT_RESET_VOUT_HISTORY: 132 case PMBUS_VIRT_RESET_VOUT_HISTORY:
80 ret = pmbus_write_word_data(client, page, 133 ret = pmbus_write_word_data(client, page,
81 MAX34440_MFR_VOUT_MIN, 0x7fff); 134 MAX34440_MFR_VOUT_MIN, 0x7fff);
@@ -87,11 +140,18 @@ static int max34440_write_word_data(struct i2c_client *client, int page,
87 case PMBUS_VIRT_RESET_IOUT_HISTORY: 140 case PMBUS_VIRT_RESET_IOUT_HISTORY:
88 ret = pmbus_write_word_data(client, page, 141 ret = pmbus_write_word_data(client, page,
89 MAX34440_MFR_IOUT_PEAK, 0); 142 MAX34440_MFR_IOUT_PEAK, 0);
143 if (!ret && data->id == max34446)
144 ret = pmbus_write_word_data(client, page,
145 MAX34446_MFR_IOUT_AVG, 0);
146
90 break; 147 break;
91 case PMBUS_VIRT_RESET_TEMP_HISTORY: 148 case PMBUS_VIRT_RESET_TEMP_HISTORY:
92 ret = pmbus_write_word_data(client, page, 149 ret = pmbus_write_word_data(client, page,
93 MAX34440_MFR_TEMPERATURE_PEAK, 150 MAX34440_MFR_TEMPERATURE_PEAK,
94 0x8000); 151 0x8000);
152 if (!ret && data->id == max34446)
153 ret = pmbus_write_word_data(client, page,
154 MAX34446_MFR_TEMPERATURE_AVG, 0);
95 break; 155 break;
96 default: 156 default:
97 ret = -ENODATA; 157 ret = -ENODATA;
@@ -225,20 +285,66 @@ static struct pmbus_driver_info max34440_info[] = {
225 .read_word_data = max34440_read_word_data, 285 .read_word_data = max34440_read_word_data,
226 .write_word_data = max34440_write_word_data, 286 .write_word_data = max34440_write_word_data,
227 }, 287 },
288 [max34446] = {
289 .pages = 7,
290 .format[PSC_VOLTAGE_IN] = direct,
291 .format[PSC_VOLTAGE_OUT] = direct,
292 .format[PSC_TEMPERATURE] = direct,
293 .format[PSC_CURRENT_OUT] = direct,
294 .format[PSC_POWER] = direct,
295 .m[PSC_VOLTAGE_IN] = 1,
296 .b[PSC_VOLTAGE_IN] = 0,
297 .R[PSC_VOLTAGE_IN] = 3,
298 .m[PSC_VOLTAGE_OUT] = 1,
299 .b[PSC_VOLTAGE_OUT] = 0,
300 .R[PSC_VOLTAGE_OUT] = 3,
301 .m[PSC_CURRENT_OUT] = 1,
302 .b[PSC_CURRENT_OUT] = 0,
303 .R[PSC_CURRENT_OUT] = 3,
304 .m[PSC_POWER] = 1,
305 .b[PSC_POWER] = 0,
306 .R[PSC_POWER] = 3,
307 .m[PSC_TEMPERATURE] = 1,
308 .b[PSC_TEMPERATURE] = 0,
309 .R[PSC_TEMPERATURE] = 2,
310 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
311 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
312 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
313 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
314 .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
315 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
316 .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
317 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
318 .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
319 .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
320 .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
321 .read_byte_data = max34440_read_byte_data,
322 .read_word_data = max34440_read_word_data,
323 .write_word_data = max34440_write_word_data,
324 },
228}; 325};
229 326
230static int max34440_probe(struct i2c_client *client, 327static int max34440_probe(struct i2c_client *client,
231 const struct i2c_device_id *id) 328 const struct i2c_device_id *id)
232{ 329{
233 return pmbus_do_probe(client, id, &max34440_info[id->driver_data]); 330 struct max34440_data *data;
331
332 data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
333 GFP_KERNEL);
334 if (!data)
335 return -ENOMEM;
336 data->id = id->driver_data;
337 data->info = max34440_info[id->driver_data];
338
339 return pmbus_do_probe(client, id, &data->info);
234} 340}
235 341
236static const struct i2c_device_id max34440_id[] = { 342static const struct i2c_device_id max34440_id[] = {
237 {"max34440", max34440}, 343 {"max34440", max34440},
238 {"max34441", max34441}, 344 {"max34441", max34441},
345 {"max34446", max34446},
239 {} 346 {}
240}; 347};
241
242MODULE_DEVICE_TABLE(i2c, max34440_id); 348MODULE_DEVICE_TABLE(i2c, max34440_id);
243 349
244/* This is the driver that will be inserted */ 350/* This is the driver that will be inserted */