Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hwmon: (pmbus/mp5990) add support for MP5998

Add support for the MPS MP5998 hot-swap controller. Like MP5990, MP5998
uses EFUSE_CFG (0xC4) bit 9 to indicate linear/direct data format.

Signed-off-by: Cosmo Chou <chou.cosmo@gmail.com>
Link: https://lore.kernel.org/r/20250916095026.800164-2-chou.cosmo@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Cosmo Chou and committed by
Guenter Roeck
bef3c793 bca9b663

+85 -12
+26 -4
Documentation/hwmon/mp5990.rst
··· 9 9 10 10 Prefix: 'mp5990' 11 11 12 - * Datasheet 12 + Datasheet: Publicly available at the MPS website: https://www.monolithicpower.com/en/mp5990.html 13 13 14 - Publicly available at the MPS website : https://www.monolithicpower.com/en/mp5990.html 14 + * MPS MP5998 15 + 16 + Prefix: 'mp5998' 17 + 18 + Datasheet: Not publicly available 15 19 16 20 Author: 17 21 ··· 25 21 ----------- 26 22 27 23 This driver implements support for Monolithic Power Systems, Inc. (MPS) 28 - MP5990 Hot-Swap Controller. 24 + MP5990 and MP5998 Hot-Swap Controller. 29 25 30 26 Device compliant with: 31 27 ··· 57 53 58 54 **in2_alarm** 59 55 60 - The driver provides the following attributes for output current: 56 + The driver provides the following attributes for current: 61 57 62 58 **curr1_input** 63 59 ··· 67 63 68 64 **curr1_max** 69 65 66 + **curr2_input** 67 + 68 + **curr2_label** 69 + 70 + **curr2_max** 71 + 72 + **curr2_max_alarm** 73 + 70 74 The driver provides the following attributes for input power: 71 75 72 76 **power1_input** ··· 82 70 **power1_label** 83 71 84 72 **power1_alarm** 73 + 74 + The driver provides the following attributes for output power: 75 + 76 + **power2_input** 77 + 78 + **power2_label** 79 + 80 + **power2_max** 81 + 82 + **power2_max_alarm** 85 83 86 84 The driver provides the following attributes for temperature: 87 85
+59 -8
drivers/hwmon/pmbus/mp5990.c
··· 8 8 #include <linux/of_device.h> 9 9 #include "pmbus.h" 10 10 11 + enum chips { mp5990, mp5998 }; 12 + 11 13 #define MP5990_EFUSE_CFG (0xC4) 12 14 #define MP5990_VOUT_FORMAT BIT(9) 13 15 ··· 112 110 .read_word_data = mp5990_read_word_data, 113 111 }; 114 112 113 + static struct pmbus_driver_info mp5998_info = { 114 + .pages = 1, 115 + .format[PSC_VOLTAGE_IN] = direct, 116 + .format[PSC_VOLTAGE_OUT] = direct, 117 + .format[PSC_CURRENT_IN] = direct, 118 + .format[PSC_CURRENT_OUT] = direct, 119 + .format[PSC_POWER] = direct, 120 + .format[PSC_TEMPERATURE] = direct, 121 + .m[PSC_VOLTAGE_IN] = 64, 122 + .b[PSC_VOLTAGE_IN] = 0, 123 + .R[PSC_VOLTAGE_IN] = 0, 124 + .m[PSC_VOLTAGE_OUT] = 64, 125 + .b[PSC_VOLTAGE_OUT] = 0, 126 + .R[PSC_VOLTAGE_OUT] = 0, 127 + .m[PSC_CURRENT_IN] = 16, 128 + .b[PSC_CURRENT_IN] = 0, 129 + .R[PSC_CURRENT_IN] = 0, 130 + .m[PSC_CURRENT_OUT] = 16, 131 + .b[PSC_CURRENT_OUT] = 0, 132 + .R[PSC_CURRENT_OUT] = 0, 133 + .m[PSC_POWER] = 2, 134 + .b[PSC_POWER] = 0, 135 + .R[PSC_POWER] = 0, 136 + .m[PSC_TEMPERATURE] = 1, 137 + .b[PSC_TEMPERATURE] = 0, 138 + .R[PSC_TEMPERATURE] = 0, 139 + .func[0] = 140 + PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | 141 + PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | 142 + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_IOUT | 143 + PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP, 144 + .read_byte_data = mp5990_read_byte_data, 145 + .read_word_data = mp5990_read_word_data, 146 + }; 147 + 148 + static const struct i2c_device_id mp5990_id[] = { 149 + {"mp5990", mp5990}, 150 + {"mp5998", mp5998}, 151 + { } 152 + }; 153 + MODULE_DEVICE_TABLE(i2c, mp5990_id); 154 + 115 155 static int mp5990_probe(struct i2c_client *client) 116 156 { 117 157 struct pmbus_driver_info *info; 118 158 struct mp5990_data *data; 159 + enum chips chip; 119 160 int ret; 120 161 121 162 data = devm_kzalloc(&client->dev, sizeof(struct mp5990_data), ··· 166 121 if (!data) 167 122 return -ENOMEM; 168 123 169 - memcpy(&data->info, &mp5990_info, sizeof(*info)); 124 + if (client->dev.of_node) 125 + chip = (uintptr_t)of_device_get_match_data(&client->dev); 126 + else 127 + chip = i2c_match_id(mp5990_id, client)->driver_data; 128 + 129 + if (chip == mp5990) 130 + memcpy(&data->info, &mp5990_info, sizeof(*info)); 131 + else 132 + memcpy(&data->info, &mp5998_info, sizeof(*info)); 170 133 info = &data->info; 171 134 172 135 /* Read Vout Config */ ··· 193 140 data->info.format[PSC_VOLTAGE_OUT] = linear; 194 141 data->info.format[PSC_CURRENT_OUT] = linear; 195 142 data->info.format[PSC_POWER] = linear; 143 + if (chip == mp5998) 144 + data->info.format[PSC_CURRENT_IN] = linear; 145 + 196 146 ret = i2c_smbus_read_word_data(client, PMBUS_READ_VOUT); 197 147 if (ret < 0) { 198 148 dev_err(&client->dev, "Can't get vout exponent."); ··· 209 153 } 210 154 211 155 static const struct of_device_id mp5990_of_match[] = { 212 - { .compatible = "mps,mp5990" }, 156 + { .compatible = "mps,mp5990", .data = (void *)mp5990 }, 157 + { .compatible = "mps,mp5998", .data = (void *)mp5998 }, 213 158 {} 214 159 }; 215 - 216 - static const struct i2c_device_id mp5990_id[] = { 217 - {"mp5990"}, 218 - { } 219 - }; 220 - MODULE_DEVICE_TABLE(i2c, mp5990_id); 221 160 222 161 static struct i2c_driver mp5990_driver = { 223 162 .driver = {