2 * Hardware monitoring driver for Maxim MAX34440/MAX34441
4 * Copyright (c) 2011 Ericsson AB.
5 * Copyright (c) 2012 Guenter Roeck
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/bitops.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/err.h>
27 #include <linux/i2c.h>
30 enum chips
{ max34440
, max34441
, max34446
, max34460
, max34461
};
32 #define MAX34440_MFR_VOUT_PEAK 0xd4
33 #define MAX34440_MFR_IOUT_PEAK 0xd5
34 #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6
35 #define MAX34440_MFR_VOUT_MIN 0xd7
37 #define MAX34446_MFR_POUT_PEAK 0xe0
38 #define MAX34446_MFR_POUT_AVG 0xe1
39 #define MAX34446_MFR_IOUT_AVG 0xe2
40 #define MAX34446_MFR_TEMPERATURE_AVG 0xe3
42 #define MAX34440_STATUS_OC_WARN BIT(0)
43 #define MAX34440_STATUS_OC_FAULT BIT(1)
44 #define MAX34440_STATUS_OT_FAULT BIT(5)
45 #define MAX34440_STATUS_OT_WARN BIT(6)
47 struct max34440_data
{
49 struct pmbus_driver_info info
;
52 #define to_max34440_data(x) container_of(x, struct max34440_data, info)
54 static int max34440_read_word_data(struct i2c_client
*client
, int page
, int reg
)
57 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
58 const struct max34440_data
*data
= to_max34440_data(info
);
61 case PMBUS_VIRT_READ_VOUT_MIN
:
62 ret
= pmbus_read_word_data(client
, page
,
63 MAX34440_MFR_VOUT_MIN
);
65 case PMBUS_VIRT_READ_VOUT_MAX
:
66 ret
= pmbus_read_word_data(client
, page
,
67 MAX34440_MFR_VOUT_PEAK
);
69 case PMBUS_VIRT_READ_IOUT_AVG
:
70 if (data
->id
!= max34446
)
72 ret
= pmbus_read_word_data(client
, page
,
73 MAX34446_MFR_IOUT_AVG
);
75 case PMBUS_VIRT_READ_IOUT_MAX
:
76 ret
= pmbus_read_word_data(client
, page
,
77 MAX34440_MFR_IOUT_PEAK
);
79 case PMBUS_VIRT_READ_POUT_AVG
:
80 if (data
->id
!= max34446
)
82 ret
= pmbus_read_word_data(client
, page
,
83 MAX34446_MFR_POUT_AVG
);
85 case PMBUS_VIRT_READ_POUT_MAX
:
86 if (data
->id
!= max34446
)
88 ret
= pmbus_read_word_data(client
, page
,
89 MAX34446_MFR_POUT_PEAK
);
91 case PMBUS_VIRT_READ_TEMP_AVG
:
92 if (data
->id
!= max34446
&& data
->id
!= max34460
&&
95 ret
= pmbus_read_word_data(client
, page
,
96 MAX34446_MFR_TEMPERATURE_AVG
);
98 case PMBUS_VIRT_READ_TEMP_MAX
:
99 ret
= pmbus_read_word_data(client
, page
,
100 MAX34440_MFR_TEMPERATURE_PEAK
);
102 case PMBUS_VIRT_RESET_POUT_HISTORY
:
103 if (data
->id
!= max34446
)
107 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
108 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
109 case PMBUS_VIRT_RESET_TEMP_HISTORY
:
119 static int max34440_write_word_data(struct i2c_client
*client
, int page
,
122 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
123 const struct max34440_data
*data
= to_max34440_data(info
);
127 case PMBUS_VIRT_RESET_POUT_HISTORY
:
128 ret
= pmbus_write_word_data(client
, page
,
129 MAX34446_MFR_POUT_PEAK
, 0);
132 ret
= pmbus_write_word_data(client
, page
,
133 MAX34446_MFR_POUT_AVG
, 0);
135 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
136 ret
= pmbus_write_word_data(client
, page
,
137 MAX34440_MFR_VOUT_MIN
, 0x7fff);
140 ret
= pmbus_write_word_data(client
, page
,
141 MAX34440_MFR_VOUT_PEAK
, 0);
143 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
144 ret
= pmbus_write_word_data(client
, page
,
145 MAX34440_MFR_IOUT_PEAK
, 0);
146 if (!ret
&& data
->id
== max34446
)
147 ret
= pmbus_write_word_data(client
, page
,
148 MAX34446_MFR_IOUT_AVG
, 0);
151 case PMBUS_VIRT_RESET_TEMP_HISTORY
:
152 ret
= pmbus_write_word_data(client
, page
,
153 MAX34440_MFR_TEMPERATURE_PEAK
,
155 if (!ret
&& data
->id
== max34446
)
156 ret
= pmbus_write_word_data(client
, page
,
157 MAX34446_MFR_TEMPERATURE_AVG
, 0);
166 static int max34440_read_byte_data(struct i2c_client
*client
, int page
, int reg
)
172 ret
= pmbus_set_page(client
, page
);
178 case PMBUS_STATUS_IOUT
:
179 mfg_status
= pmbus_read_word_data(client
, 0,
180 PMBUS_STATUS_MFR_SPECIFIC
);
183 if (mfg_status
& MAX34440_STATUS_OC_WARN
)
184 ret
|= PB_IOUT_OC_WARNING
;
185 if (mfg_status
& MAX34440_STATUS_OC_FAULT
)
186 ret
|= PB_IOUT_OC_FAULT
;
188 case PMBUS_STATUS_TEMPERATURE
:
189 mfg_status
= pmbus_read_word_data(client
, 0,
190 PMBUS_STATUS_MFR_SPECIFIC
);
193 if (mfg_status
& MAX34440_STATUS_OT_WARN
)
194 ret
|= PB_TEMP_OT_WARNING
;
195 if (mfg_status
& MAX34440_STATUS_OT_FAULT
)
196 ret
|= PB_TEMP_OT_FAULT
;
205 static struct pmbus_driver_info max34440_info
[] = {
208 .format
[PSC_VOLTAGE_IN
] = direct
,
209 .format
[PSC_VOLTAGE_OUT
] = direct
,
210 .format
[PSC_TEMPERATURE
] = direct
,
211 .format
[PSC_CURRENT_OUT
] = direct
,
212 .m
[PSC_VOLTAGE_IN
] = 1,
213 .b
[PSC_VOLTAGE_IN
] = 0,
214 .R
[PSC_VOLTAGE_IN
] = 3, /* R = 0 in datasheet reflects mV */
215 .m
[PSC_VOLTAGE_OUT
] = 1,
216 .b
[PSC_VOLTAGE_OUT
] = 0,
217 .R
[PSC_VOLTAGE_OUT
] = 3, /* R = 0 in datasheet reflects mV */
218 .m
[PSC_CURRENT_OUT
] = 1,
219 .b
[PSC_CURRENT_OUT
] = 0,
220 .R
[PSC_CURRENT_OUT
] = 3, /* R = 0 in datasheet reflects mA */
221 .m
[PSC_TEMPERATURE
] = 1,
222 .b
[PSC_TEMPERATURE
] = 0,
223 .R
[PSC_TEMPERATURE
] = 2,
224 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
225 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
226 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
227 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
228 .func
[2] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
229 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
230 .func
[3] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
231 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
232 .func
[4] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
233 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
234 .func
[5] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
235 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
236 .func
[6] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
237 .func
[7] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
238 .func
[8] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
239 .func
[9] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
240 .func
[10] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
241 .func
[11] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
242 .func
[12] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
243 .func
[13] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
244 .read_byte_data
= max34440_read_byte_data
,
245 .read_word_data
= max34440_read_word_data
,
246 .write_word_data
= max34440_write_word_data
,
250 .format
[PSC_VOLTAGE_IN
] = direct
,
251 .format
[PSC_VOLTAGE_OUT
] = direct
,
252 .format
[PSC_TEMPERATURE
] = direct
,
253 .format
[PSC_CURRENT_OUT
] = direct
,
254 .format
[PSC_FAN
] = direct
,
255 .m
[PSC_VOLTAGE_IN
] = 1,
256 .b
[PSC_VOLTAGE_IN
] = 0,
257 .R
[PSC_VOLTAGE_IN
] = 3,
258 .m
[PSC_VOLTAGE_OUT
] = 1,
259 .b
[PSC_VOLTAGE_OUT
] = 0,
260 .R
[PSC_VOLTAGE_OUT
] = 3,
261 .m
[PSC_CURRENT_OUT
] = 1,
262 .b
[PSC_CURRENT_OUT
] = 0,
263 .R
[PSC_CURRENT_OUT
] = 3,
264 .m
[PSC_TEMPERATURE
] = 1,
265 .b
[PSC_TEMPERATURE
] = 0,
266 .R
[PSC_TEMPERATURE
] = 2,
270 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
271 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
272 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
273 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
274 .func
[2] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
275 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
276 .func
[3] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
277 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
278 .func
[4] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
279 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
280 .func
[5] = PMBUS_HAVE_FAN12
| PMBUS_HAVE_STATUS_FAN12
,
281 .func
[6] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
282 .func
[7] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
283 .func
[8] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
284 .func
[9] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
285 .func
[10] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
286 .func
[11] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
287 .read_byte_data
= max34440_read_byte_data
,
288 .read_word_data
= max34440_read_word_data
,
289 .write_word_data
= max34440_write_word_data
,
293 .format
[PSC_VOLTAGE_IN
] = direct
,
294 .format
[PSC_VOLTAGE_OUT
] = direct
,
295 .format
[PSC_TEMPERATURE
] = direct
,
296 .format
[PSC_CURRENT_OUT
] = direct
,
297 .format
[PSC_POWER
] = direct
,
298 .m
[PSC_VOLTAGE_IN
] = 1,
299 .b
[PSC_VOLTAGE_IN
] = 0,
300 .R
[PSC_VOLTAGE_IN
] = 3,
301 .m
[PSC_VOLTAGE_OUT
] = 1,
302 .b
[PSC_VOLTAGE_OUT
] = 0,
303 .R
[PSC_VOLTAGE_OUT
] = 3,
304 .m
[PSC_CURRENT_OUT
] = 1,
305 .b
[PSC_CURRENT_OUT
] = 0,
306 .R
[PSC_CURRENT_OUT
] = 3,
310 .m
[PSC_TEMPERATURE
] = 1,
311 .b
[PSC_TEMPERATURE
] = 0,
312 .R
[PSC_TEMPERATURE
] = 2,
313 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
314 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_POUT
,
315 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
316 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
317 .func
[2] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
318 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_POUT
,
319 .func
[3] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
320 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
,
321 .func
[4] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
322 .func
[5] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
323 .func
[6] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
324 .read_byte_data
= max34440_read_byte_data
,
325 .read_word_data
= max34440_read_word_data
,
326 .write_word_data
= max34440_write_word_data
,
330 .format
[PSC_VOLTAGE_OUT
] = direct
,
331 .format
[PSC_TEMPERATURE
] = direct
,
332 .m
[PSC_VOLTAGE_OUT
] = 1,
333 .b
[PSC_VOLTAGE_OUT
] = 0,
334 .R
[PSC_VOLTAGE_OUT
] = 3,
335 .m
[PSC_TEMPERATURE
] = 1,
336 .b
[PSC_TEMPERATURE
] = 0,
337 .R
[PSC_TEMPERATURE
] = 2,
338 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
339 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
340 .func
[2] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
341 .func
[3] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
342 .func
[4] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
343 .func
[5] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
344 .func
[6] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
345 .func
[7] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
346 .func
[8] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
347 .func
[9] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
348 .func
[10] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
349 .func
[11] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
350 .func
[13] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
351 .func
[14] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
352 .func
[15] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
353 .func
[16] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
354 .func
[17] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
355 .read_byte_data
= max34440_read_byte_data
,
356 .read_word_data
= max34440_read_word_data
,
357 .write_word_data
= max34440_write_word_data
,
361 .format
[PSC_VOLTAGE_OUT
] = direct
,
362 .format
[PSC_TEMPERATURE
] = direct
,
363 .m
[PSC_VOLTAGE_OUT
] = 1,
364 .b
[PSC_VOLTAGE_OUT
] = 0,
365 .R
[PSC_VOLTAGE_OUT
] = 3,
366 .m
[PSC_TEMPERATURE
] = 1,
367 .b
[PSC_TEMPERATURE
] = 0,
368 .R
[PSC_TEMPERATURE
] = 2,
369 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
370 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
371 .func
[2] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
372 .func
[3] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
373 .func
[4] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
374 .func
[5] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
375 .func
[6] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
376 .func
[7] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
377 .func
[8] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
378 .func
[9] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
379 .func
[10] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
380 .func
[11] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
381 .func
[12] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
382 .func
[13] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
383 .func
[14] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
384 .func
[15] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
,
385 /* page 16 is reserved */
386 .func
[17] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
387 .func
[18] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
388 .func
[19] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
389 .func
[20] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
390 .func
[21] = PMBUS_HAVE_TEMP
| PMBUS_HAVE_STATUS_TEMP
,
391 .read_byte_data
= max34440_read_byte_data
,
392 .read_word_data
= max34440_read_word_data
,
393 .write_word_data
= max34440_write_word_data
,
397 static int max34440_probe(struct i2c_client
*client
,
398 const struct i2c_device_id
*id
)
400 struct max34440_data
*data
;
402 data
= devm_kzalloc(&client
->dev
, sizeof(struct max34440_data
),
406 data
->id
= id
->driver_data
;
407 data
->info
= max34440_info
[id
->driver_data
];
409 return pmbus_do_probe(client
, id
, &data
->info
);
412 static const struct i2c_device_id max34440_id
[] = {
413 {"max34440", max34440
},
414 {"max34441", max34441
},
415 {"max34446", max34446
},
416 {"max34460", max34460
},
417 {"max34461", max34461
},
420 MODULE_DEVICE_TABLE(i2c
, max34440_id
);
422 /* This is the driver that will be inserted */
423 static struct i2c_driver max34440_driver
= {
427 .probe
= max34440_probe
,
428 .remove
= pmbus_do_remove
,
429 .id_table
= max34440_id
,
432 module_i2c_driver(max34440_driver
);
434 MODULE_AUTHOR("Guenter Roeck");
435 MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
436 MODULE_LICENSE("GPL");