aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/pmbus/max34440.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/pmbus/max34440.c')
-rw-r--r--drivers/hwmon/pmbus/max34440.c112
1 files changed, 109 insertions, 3 deletions
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 */