174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 29d2ecfb7SGuenter Roeck /* 39d2ecfb7SGuenter Roeck * Hardware monitoring driver for Maxim MAX16064 49d2ecfb7SGuenter Roeck * 59d2ecfb7SGuenter Roeck * Copyright (c) 2011 Ericsson AB. 69d2ecfb7SGuenter Roeck */ 79d2ecfb7SGuenter Roeck 89d2ecfb7SGuenter Roeck #include <linux/kernel.h> 99d2ecfb7SGuenter Roeck #include <linux/module.h> 109d2ecfb7SGuenter Roeck #include <linux/init.h> 119d2ecfb7SGuenter Roeck #include <linux/err.h> 129d2ecfb7SGuenter Roeck #include <linux/i2c.h> 139d2ecfb7SGuenter Roeck #include "pmbus.h" 149d2ecfb7SGuenter Roeck 158ebed854SGuenter Roeck #define MAX16064_MFR_VOUT_PEAK 0xd4 168ebed854SGuenter Roeck #define MAX16064_MFR_TEMPERATURE_PEAK 0xd6 178ebed854SGuenter Roeck 1843f33b6eSGuenter Roeck static int max16064_read_word_data(struct i2c_client *client, int page, 1943f33b6eSGuenter Roeck int phase, int reg) 208ebed854SGuenter Roeck { 218ebed854SGuenter Roeck int ret; 228ebed854SGuenter Roeck 238ebed854SGuenter Roeck switch (reg) { 248ebed854SGuenter Roeck case PMBUS_VIRT_READ_VOUT_MAX: 2543f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 268ebed854SGuenter Roeck MAX16064_MFR_VOUT_PEAK); 278ebed854SGuenter Roeck break; 288ebed854SGuenter Roeck case PMBUS_VIRT_READ_TEMP_MAX: 2943f33b6eSGuenter Roeck ret = pmbus_read_word_data(client, page, phase, 308ebed854SGuenter Roeck MAX16064_MFR_TEMPERATURE_PEAK); 318ebed854SGuenter Roeck break; 328ebed854SGuenter Roeck case PMBUS_VIRT_RESET_VOUT_HISTORY: 338ebed854SGuenter Roeck case PMBUS_VIRT_RESET_TEMP_HISTORY: 348ebed854SGuenter Roeck ret = 0; 358ebed854SGuenter Roeck break; 368ebed854SGuenter Roeck default: 378ebed854SGuenter Roeck ret = -ENODATA; 388ebed854SGuenter Roeck break; 398ebed854SGuenter Roeck } 408ebed854SGuenter Roeck return ret; 418ebed854SGuenter Roeck } 428ebed854SGuenter Roeck 438ebed854SGuenter Roeck static int max16064_write_word_data(struct i2c_client *client, int page, 448ebed854SGuenter Roeck int reg, u16 word) 458ebed854SGuenter Roeck { 468ebed854SGuenter Roeck int ret; 478ebed854SGuenter Roeck 488ebed854SGuenter Roeck switch (reg) { 498ebed854SGuenter Roeck case PMBUS_VIRT_RESET_VOUT_HISTORY: 508ebed854SGuenter Roeck ret = pmbus_write_word_data(client, page, 518ebed854SGuenter Roeck MAX16064_MFR_VOUT_PEAK, 0); 528ebed854SGuenter Roeck break; 538ebed854SGuenter Roeck case PMBUS_VIRT_RESET_TEMP_HISTORY: 548ebed854SGuenter Roeck ret = pmbus_write_word_data(client, page, 558ebed854SGuenter Roeck MAX16064_MFR_TEMPERATURE_PEAK, 568ebed854SGuenter Roeck 0xffff); 578ebed854SGuenter Roeck break; 588ebed854SGuenter Roeck default: 598ebed854SGuenter Roeck ret = -ENODATA; 608ebed854SGuenter Roeck break; 618ebed854SGuenter Roeck } 628ebed854SGuenter Roeck return ret; 638ebed854SGuenter Roeck } 648ebed854SGuenter Roeck 659d2ecfb7SGuenter Roeck static struct pmbus_driver_info max16064_info = { 669d2ecfb7SGuenter Roeck .pages = 4, 671061d851SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 681061d851SGuenter Roeck .format[PSC_VOLTAGE_OUT] = direct, 691061d851SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 709d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_IN] = 19995, 719d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 729d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_IN] = -1, 739d2ecfb7SGuenter Roeck .m[PSC_VOLTAGE_OUT] = 19995, 749d2ecfb7SGuenter Roeck .b[PSC_VOLTAGE_OUT] = 0, 759d2ecfb7SGuenter Roeck .R[PSC_VOLTAGE_OUT] = -1, 769d2ecfb7SGuenter Roeck .m[PSC_TEMPERATURE] = -7612, 779d2ecfb7SGuenter Roeck .b[PSC_TEMPERATURE] = 335, 789d2ecfb7SGuenter Roeck .R[PSC_TEMPERATURE] = -3, 799d2ecfb7SGuenter Roeck .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP 809d2ecfb7SGuenter Roeck | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP, 819d2ecfb7SGuenter Roeck .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 829d2ecfb7SGuenter Roeck .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 839d2ecfb7SGuenter Roeck .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT, 848ebed854SGuenter Roeck .read_word_data = max16064_read_word_data, 858ebed854SGuenter Roeck .write_word_data = max16064_write_word_data, 869d2ecfb7SGuenter Roeck }; 879d2ecfb7SGuenter Roeck 88dd431939SStephen Kitt static int max16064_probe(struct i2c_client *client) 899d2ecfb7SGuenter Roeck { 90dd431939SStephen Kitt return pmbus_do_probe(client, &max16064_info); 919d2ecfb7SGuenter Roeck } 929d2ecfb7SGuenter Roeck 939d2ecfb7SGuenter Roeck static const struct i2c_device_id max16064_id[] = { 949d2ecfb7SGuenter Roeck {"max16064", 0}, 959d2ecfb7SGuenter Roeck {} 969d2ecfb7SGuenter Roeck }; 979d2ecfb7SGuenter Roeck 989d2ecfb7SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max16064_id); 999d2ecfb7SGuenter Roeck 1009d2ecfb7SGuenter Roeck /* This is the driver that will be inserted */ 1019d2ecfb7SGuenter Roeck static struct i2c_driver max16064_driver = { 1029d2ecfb7SGuenter Roeck .driver = { 1039d2ecfb7SGuenter Roeck .name = "max16064", 1049d2ecfb7SGuenter Roeck }, 105*1975d167SUwe Kleine-König .probe = max16064_probe, 1069d2ecfb7SGuenter Roeck .id_table = max16064_id, 1079d2ecfb7SGuenter Roeck }; 1089d2ecfb7SGuenter Roeck 109f0967eeaSAxel Lin module_i2c_driver(max16064_driver); 1109d2ecfb7SGuenter Roeck 1119d2ecfb7SGuenter Roeck MODULE_AUTHOR("Guenter Roeck"); 1129d2ecfb7SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064"); 1139d2ecfb7SGuenter Roeck MODULE_LICENSE("GPL"); 114b94ca77eSGuenter Roeck MODULE_IMPORT_NS(PMBUS); 115