1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Hardware monitoring driver for Analog Devices ADP1050 4 * 5 * Copyright (C) 2024 Analog Devices, Inc. 6 */ 7 #include <linux/bits.h> 8 #include <linux/i2c.h> 9 #include <linux/mod_devicetable.h> 10 #include <linux/module.h> 11 12 #include "pmbus.h" 13 14 #if IS_ENABLED(CONFIG_SENSORS_ADP1050_REGULATOR) 15 static const struct regulator_desc adp1050_reg_desc[] = { 16 PMBUS_REGULATOR_ONE("vout"), 17 }; 18 #endif /* CONFIG_SENSORS_ADP1050_REGULATOR */ 19 20 static struct pmbus_driver_info adp1050_info = { 21 .pages = 1, 22 .format[PSC_VOLTAGE_IN] = linear, 23 .format[PSC_VOLTAGE_OUT] = linear, 24 .format[PSC_CURRENT_IN] = linear, 25 .format[PSC_TEMPERATURE] = linear, 26 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 27 | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT 28 | PMBUS_HAVE_IIN | PMBUS_HAVE_TEMP 29 | PMBUS_HAVE_STATUS_TEMP, 30 }; 31 32 static struct pmbus_driver_info adp1051_info = { 33 .pages = 1, 34 .format[PSC_VOLTAGE_IN] = linear, 35 .format[PSC_VOLTAGE_OUT] = linear, 36 .format[PSC_CURRENT_IN] = linear, 37 .format[PSC_TEMPERATURE] = linear, 38 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN 39 | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT 40 | PMBUS_HAVE_TEMP 41 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT 42 | PMBUS_HAVE_STATUS_INPUT 43 | PMBUS_HAVE_STATUS_TEMP, 44 }; 45 46 static struct pmbus_driver_info adp1055_info = { 47 .pages = 1, 48 .format[PSC_VOLTAGE_IN] = linear, 49 .format[PSC_VOLTAGE_OUT] = linear, 50 .format[PSC_CURRENT_IN] = linear, 51 .format[PSC_TEMPERATURE] = linear, 52 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN 53 | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT 54 | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 55 | PMBUS_HAVE_POUT 56 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT 57 | PMBUS_HAVE_STATUS_INPUT 58 | PMBUS_HAVE_STATUS_TEMP, 59 }; 60 61 static struct pmbus_driver_info ltp8800_info = { 62 .pages = 1, 63 .format[PSC_VOLTAGE_IN] = linear, 64 .format[PSC_VOLTAGE_OUT] = linear, 65 .format[PSC_CURRENT_IN] = linear, 66 .format[PSC_TEMPERATURE] = linear, 67 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN 68 | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT 69 | PMBUS_HAVE_TEMP 70 | PMBUS_HAVE_POUT 71 | PMBUS_HAVE_STATUS_VOUT 72 | PMBUS_HAVE_STATUS_INPUT 73 | PMBUS_HAVE_STATUS_TEMP, 74 #if IS_ENABLED(CONFIG_SENSORS_ADP1050_REGULATOR) 75 .num_regulators = 1, 76 .reg_desc = adp1050_reg_desc, 77 #endif 78 }; 79 80 static int adp1050_probe(struct i2c_client *client) 81 { 82 struct pmbus_driver_info *info; 83 84 info = (struct pmbus_driver_info *)i2c_get_match_data(client); 85 if (!info) 86 return -ENODEV; 87 88 return pmbus_do_probe(client, info); 89 } 90 91 static const struct i2c_device_id adp1050_id[] = { 92 { .name = "adp1050", .driver_data = (kernel_ulong_t)&adp1050_info }, 93 { .name = "adp1051", .driver_data = (kernel_ulong_t)&adp1051_info }, 94 { .name = "adp1055", .driver_data = (kernel_ulong_t)&adp1055_info }, 95 { .name = "ltp8800", .driver_data = (kernel_ulong_t)<p8800_info }, 96 {} 97 }; 98 MODULE_DEVICE_TABLE(i2c, adp1050_id); 99 100 static const struct of_device_id adp1050_of_match[] = { 101 { .compatible = "adi,adp1050", .data = &adp1050_info }, 102 { .compatible = "adi,adp1051", .data = &adp1051_info }, 103 { .compatible = "adi,adp1055", .data = &adp1055_info }, 104 { .compatible = "adi,ltp8800", .data = <p8800_info }, 105 {} 106 }; 107 MODULE_DEVICE_TABLE(of, adp1050_of_match); 108 109 static struct i2c_driver adp1050_driver = { 110 .driver = { 111 .name = "adp1050", 112 .of_match_table = adp1050_of_match, 113 }, 114 .probe = adp1050_probe, 115 .id_table = adp1050_id, 116 }; 117 module_i2c_driver(adp1050_driver); 118 119 MODULE_AUTHOR("Radu Sabau <radu.sabau@analog.com>"); 120 MODULE_DESCRIPTION("Analog Devices ADP1050 HWMON PMBus Driver"); 121 MODULE_LICENSE("GPL"); 122 MODULE_IMPORT_NS("PMBUS"); 123