1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Hardware monitoring driver for MP5920 and compatible chips. 4 */ 5 6 #include <linux/i2c.h> 7 #include <linux/minmax.h> 8 #include <linux/module.h> 9 #include <linux/of_device.h> 10 #include "pmbus.h" 11 12 static struct pmbus_driver_info mp5920_info = { 13 .pages = 1, 14 .format[PSC_VOLTAGE_IN] = direct, 15 .format[PSC_VOLTAGE_OUT] = direct, 16 .format[PSC_CURRENT_OUT] = direct, 17 .format[PSC_POWER] = direct, 18 .format[PSC_TEMPERATURE] = direct, 19 .m[PSC_VOLTAGE_IN] = 2266, 20 .b[PSC_VOLTAGE_IN] = 0, 21 .R[PSC_VOLTAGE_IN] = -1, 22 .m[PSC_VOLTAGE_OUT] = 2266, 23 .b[PSC_VOLTAGE_OUT] = 0, 24 .R[PSC_VOLTAGE_OUT] = -1, 25 .m[PSC_CURRENT_OUT] = 546, 26 .b[PSC_CURRENT_OUT] = 0, 27 .R[PSC_CURRENT_OUT] = -2, 28 .m[PSC_POWER] = 5840, 29 .b[PSC_POWER] = 0, 30 .R[PSC_POWER] = -3, 31 .m[PSC_TEMPERATURE] = 1067, 32 .b[PSC_TEMPERATURE] = 20500, 33 .R[PSC_TEMPERATURE] = -2, 34 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | 35 PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | 36 PMBUS_HAVE_TEMP, 37 }; 38 39 static int mp5920_probe(struct i2c_client *client) 40 { 41 struct device *dev = &client->dev; 42 int ret; 43 u8 buf[I2C_SMBUS_BLOCK_MAX]; 44 45 if (!i2c_check_functionality(client->adapter, 46 I2C_FUNC_SMBUS_READ_WORD_DATA)) 47 return -ENODEV; 48 49 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); 50 if (ret < 0) 51 return dev_err_probe(dev, ret, "Failed to read PMBUS_MFR_MODEL\n"); 52 53 if (ret != 6 || strncmp(buf, "MP5920", 6)) { 54 return dev_err_probe(dev, -ENODEV, "Model '%.*s' not supported\n", 55 min_t(int, ret, sizeof(buf)), buf); 56 } 57 58 return pmbus_do_probe(client, &mp5920_info); 59 } 60 61 static const struct of_device_id mp5920_of_match[] = { 62 { .compatible = "mps,mp5920" }, 63 { } 64 }; 65 66 MODULE_DEVICE_TABLE(of, mp5920_of_match); 67 68 static const struct i2c_device_id mp5920_id[] = { 69 { "mp5920" }, 70 { } 71 }; 72 73 MODULE_DEVICE_TABLE(i2c, mp5920_id); 74 75 static struct i2c_driver mp5920_driver = { 76 .driver = { 77 .name = "mp5920", 78 .of_match_table = mp5920_of_match, 79 }, 80 .probe = mp5920_probe, 81 .id_table = mp5920_id, 82 }; 83 84 module_i2c_driver(mp5920_driver); 85 86 MODULE_AUTHOR("Tony Ao <tony_ao@wiwynn.com>"); 87 MODULE_AUTHOR("Alex Vdovydchenko <xzeol@yahoo.com>"); 88 MODULE_DESCRIPTION("PMBus driver for MP5920 HSC"); 89 MODULE_LICENSE("GPL"); 90 MODULE_IMPORT_NS(PMBUS); 91