1cce20958SGuenter Roeck // SPDX-License-Identifier: GPL-2.0-or-later 2cce20958SGuenter Roeck /* 3cce20958SGuenter Roeck * Driver for MAX20730, MAX20734, and MAX20743 Integrated, Step-Down 4cce20958SGuenter Roeck * Switching Regulators 5cce20958SGuenter Roeck * 6cce20958SGuenter Roeck * Copyright 2019 Google LLC. 7cce20958SGuenter Roeck */ 8cce20958SGuenter Roeck 9cce20958SGuenter Roeck #include <linux/bits.h> 10cce20958SGuenter Roeck #include <linux/err.h> 11cce20958SGuenter Roeck #include <linux/i2c.h> 12cce20958SGuenter Roeck #include <linux/init.h> 13cce20958SGuenter Roeck #include <linux/kernel.h> 14cce20958SGuenter Roeck #include <linux/module.h> 15cce20958SGuenter Roeck #include <linux/mutex.h> 16cce20958SGuenter Roeck #include <linux/of_device.h> 17cce20958SGuenter Roeck #include <linux/pmbus.h> 18cce20958SGuenter Roeck #include <linux/util_macros.h> 19cce20958SGuenter Roeck #include "pmbus.h" 20cce20958SGuenter Roeck 21cce20958SGuenter Roeck enum chips { 22cce20958SGuenter Roeck max20730, 23cce20958SGuenter Roeck max20734, 24cce20958SGuenter Roeck max20743 25cce20958SGuenter Roeck }; 26cce20958SGuenter Roeck 27cce20958SGuenter Roeck struct max20730_data { 28cce20958SGuenter Roeck enum chips id; 29cce20958SGuenter Roeck struct pmbus_driver_info info; 30cce20958SGuenter Roeck struct mutex lock; /* Used to protect against parallel writes */ 31cce20958SGuenter Roeck u16 mfr_devset1; 32cce20958SGuenter Roeck }; 33cce20958SGuenter Roeck 34cce20958SGuenter Roeck #define to_max20730_data(x) container_of(x, struct max20730_data, info) 35cce20958SGuenter Roeck 36cce20958SGuenter Roeck #define MAX20730_MFR_DEVSET1 0xd2 37cce20958SGuenter Roeck 38cce20958SGuenter Roeck /* 39cce20958SGuenter Roeck * Convert discreet value to direct data format. Strictly speaking, all passed 40cce20958SGuenter Roeck * values are constants, so we could do that calculation manually. On the 41cce20958SGuenter Roeck * downside, that would make the driver more difficult to maintain, so lets 42cce20958SGuenter Roeck * use this approach. 43cce20958SGuenter Roeck */ 44cce20958SGuenter Roeck static u16 val_to_direct(int v, enum pmbus_sensor_classes class, 45cce20958SGuenter Roeck const struct pmbus_driver_info *info) 46cce20958SGuenter Roeck { 47cce20958SGuenter Roeck int R = info->R[class] - 3; /* take milli-units into account */ 48cce20958SGuenter Roeck int b = info->b[class] * 1000; 49cce20958SGuenter Roeck long d; 50cce20958SGuenter Roeck 51cce20958SGuenter Roeck d = v * info->m[class] + b; 52cce20958SGuenter Roeck /* 53cce20958SGuenter Roeck * R < 0 is true for all callers, so we don't need to bother 54cce20958SGuenter Roeck * about the R > 0 case. 55cce20958SGuenter Roeck */ 56cce20958SGuenter Roeck while (R < 0) { 57cce20958SGuenter Roeck d = DIV_ROUND_CLOSEST(d, 10); 58cce20958SGuenter Roeck R++; 59cce20958SGuenter Roeck } 60cce20958SGuenter Roeck return (u16)d; 61cce20958SGuenter Roeck } 62cce20958SGuenter Roeck 63cce20958SGuenter Roeck static long direct_to_val(u16 w, enum pmbus_sensor_classes class, 64cce20958SGuenter Roeck const struct pmbus_driver_info *info) 65cce20958SGuenter Roeck { 66cce20958SGuenter Roeck int R = info->R[class] - 3; 67cce20958SGuenter Roeck int b = info->b[class] * 1000; 68cce20958SGuenter Roeck int m = info->m[class]; 69cce20958SGuenter Roeck long d = (s16)w; 70cce20958SGuenter Roeck 71cce20958SGuenter Roeck if (m == 0) 72cce20958SGuenter Roeck return 0; 73cce20958SGuenter Roeck 74cce20958SGuenter Roeck while (R < 0) { 75cce20958SGuenter Roeck d *= 10; 76cce20958SGuenter Roeck R++; 77cce20958SGuenter Roeck } 78cce20958SGuenter Roeck d = (d - b) / m; 79cce20958SGuenter Roeck return d; 80cce20958SGuenter Roeck } 81cce20958SGuenter Roeck 82cce20958SGuenter Roeck static u32 max_current[][5] = { 83cce20958SGuenter Roeck [max20730] = { 13000, 16600, 20100, 23600 }, 84cce20958SGuenter Roeck [max20734] = { 21000, 27000, 32000, 38000 }, 85cce20958SGuenter Roeck [max20743] = { 18900, 24100, 29200, 34100 }, 86cce20958SGuenter Roeck }; 87cce20958SGuenter Roeck 88*43f33b6eSGuenter Roeck static int max20730_read_word_data(struct i2c_client *client, int page, 89*43f33b6eSGuenter Roeck int phase, int reg) 90cce20958SGuenter Roeck { 91cce20958SGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 92cce20958SGuenter Roeck const struct max20730_data *data = to_max20730_data(info); 93cce20958SGuenter Roeck int ret = 0; 94cce20958SGuenter Roeck u32 max_c; 95cce20958SGuenter Roeck 96cce20958SGuenter Roeck switch (reg) { 97cce20958SGuenter Roeck case PMBUS_OT_FAULT_LIMIT: 98cce20958SGuenter Roeck switch ((data->mfr_devset1 >> 11) & 0x3) { 99cce20958SGuenter Roeck case 0x0: 100cce20958SGuenter Roeck ret = val_to_direct(150000, PSC_TEMPERATURE, info); 101cce20958SGuenter Roeck break; 102cce20958SGuenter Roeck case 0x1: 103cce20958SGuenter Roeck ret = val_to_direct(130000, PSC_TEMPERATURE, info); 104cce20958SGuenter Roeck break; 105cce20958SGuenter Roeck default: 106cce20958SGuenter Roeck ret = -ENODATA; 107cce20958SGuenter Roeck break; 108cce20958SGuenter Roeck } 109cce20958SGuenter Roeck break; 110cce20958SGuenter Roeck case PMBUS_IOUT_OC_FAULT_LIMIT: 111cce20958SGuenter Roeck max_c = max_current[data->id][(data->mfr_devset1 >> 5) & 0x3]; 112cce20958SGuenter Roeck ret = val_to_direct(max_c, PSC_CURRENT_OUT, info); 113cce20958SGuenter Roeck break; 114cce20958SGuenter Roeck default: 115cce20958SGuenter Roeck ret = -ENODATA; 116cce20958SGuenter Roeck break; 117cce20958SGuenter Roeck } 118cce20958SGuenter Roeck return ret; 119cce20958SGuenter Roeck } 120cce20958SGuenter Roeck 121cce20958SGuenter Roeck static int max20730_write_word_data(struct i2c_client *client, int page, 122cce20958SGuenter Roeck int reg, u16 word) 123cce20958SGuenter Roeck { 124cce20958SGuenter Roeck struct pmbus_driver_info *info; 125cce20958SGuenter Roeck struct max20730_data *data; 126cce20958SGuenter Roeck u16 devset1; 127cce20958SGuenter Roeck int ret = 0; 128cce20958SGuenter Roeck int idx; 129cce20958SGuenter Roeck 130cce20958SGuenter Roeck info = (struct pmbus_driver_info *)pmbus_get_driver_info(client); 131cce20958SGuenter Roeck data = to_max20730_data(info); 132cce20958SGuenter Roeck 133cce20958SGuenter Roeck mutex_lock(&data->lock); 134cce20958SGuenter Roeck devset1 = data->mfr_devset1; 135cce20958SGuenter Roeck 136cce20958SGuenter Roeck switch (reg) { 137cce20958SGuenter Roeck case PMBUS_OT_FAULT_LIMIT: 138cce20958SGuenter Roeck devset1 &= ~(BIT(11) | BIT(12)); 139cce20958SGuenter Roeck if (direct_to_val(word, PSC_TEMPERATURE, info) < 140000) 140cce20958SGuenter Roeck devset1 |= BIT(11); 141cce20958SGuenter Roeck break; 142cce20958SGuenter Roeck case PMBUS_IOUT_OC_FAULT_LIMIT: 143cce20958SGuenter Roeck devset1 &= ~(BIT(5) | BIT(6)); 144cce20958SGuenter Roeck 145cce20958SGuenter Roeck idx = find_closest(direct_to_val(word, PSC_CURRENT_OUT, info), 146cce20958SGuenter Roeck max_current[data->id], 4); 147cce20958SGuenter Roeck devset1 |= (idx << 5); 148cce20958SGuenter Roeck break; 149cce20958SGuenter Roeck default: 150cce20958SGuenter Roeck ret = -ENODATA; 151cce20958SGuenter Roeck break; 152cce20958SGuenter Roeck } 153cce20958SGuenter Roeck 154cce20958SGuenter Roeck if (!ret && devset1 != data->mfr_devset1) { 155cce20958SGuenter Roeck ret = i2c_smbus_write_word_data(client, MAX20730_MFR_DEVSET1, 156cce20958SGuenter Roeck devset1); 157cce20958SGuenter Roeck if (!ret) { 158cce20958SGuenter Roeck data->mfr_devset1 = devset1; 159cce20958SGuenter Roeck pmbus_clear_cache(client); 160cce20958SGuenter Roeck } 161cce20958SGuenter Roeck } 162cce20958SGuenter Roeck mutex_unlock(&data->lock); 163cce20958SGuenter Roeck return ret; 164cce20958SGuenter Roeck } 165cce20958SGuenter Roeck 166cce20958SGuenter Roeck static const struct pmbus_driver_info max20730_info[] = { 167cce20958SGuenter Roeck [max20730] = { 168cce20958SGuenter Roeck .pages = 1, 169cce20958SGuenter Roeck .read_word_data = max20730_read_word_data, 170cce20958SGuenter Roeck .write_word_data = max20730_write_word_data, 171cce20958SGuenter Roeck 172cce20958SGuenter Roeck /* Source : Maxim AN6042 */ 173cce20958SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 174cce20958SGuenter Roeck .m[PSC_TEMPERATURE] = 21, 175cce20958SGuenter Roeck .b[PSC_TEMPERATURE] = 5887, 176cce20958SGuenter Roeck .R[PSC_TEMPERATURE] = -1, 177cce20958SGuenter Roeck 178cce20958SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 179cce20958SGuenter Roeck .m[PSC_VOLTAGE_IN] = 3609, 180cce20958SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 181cce20958SGuenter Roeck .R[PSC_VOLTAGE_IN] = -2, 182cce20958SGuenter Roeck 183cce20958SGuenter Roeck /* 184cce20958SGuenter Roeck * Values in the datasheet are adjusted for temperature and 185cce20958SGuenter Roeck * for the relationship between Vin and Vout. 186cce20958SGuenter Roeck * Unfortunately, the data sheet suggests that Vout measurement 187cce20958SGuenter Roeck * may be scaled with a resistor array. This is indeed the case 188cce20958SGuenter Roeck * at least on the evaulation boards. As a result, any in-driver 189cce20958SGuenter Roeck * adjustments would either be wrong or require elaborate means 190cce20958SGuenter Roeck * to configure the scaling. Instead of doing that, just report 191cce20958SGuenter Roeck * raw values and let userspace handle adjustments. 192cce20958SGuenter Roeck */ 193cce20958SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 194cce20958SGuenter Roeck .m[PSC_CURRENT_OUT] = 153, 195cce20958SGuenter Roeck .b[PSC_CURRENT_OUT] = 4976, 196cce20958SGuenter Roeck .R[PSC_CURRENT_OUT] = -1, 197cce20958SGuenter Roeck 198cce20958SGuenter Roeck .format[PSC_VOLTAGE_OUT] = linear, 199cce20958SGuenter Roeck 200cce20958SGuenter Roeck .func[0] = PMBUS_HAVE_VIN | 201cce20958SGuenter Roeck PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 202cce20958SGuenter Roeck PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 203cce20958SGuenter Roeck PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 204cce20958SGuenter Roeck }, 205cce20958SGuenter Roeck [max20734] = { 206cce20958SGuenter Roeck .pages = 1, 207cce20958SGuenter Roeck .read_word_data = max20730_read_word_data, 208cce20958SGuenter Roeck .write_word_data = max20730_write_word_data, 209cce20958SGuenter Roeck 210cce20958SGuenter Roeck /* Source : Maxim AN6209 */ 211cce20958SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 212cce20958SGuenter Roeck .m[PSC_TEMPERATURE] = 21, 213cce20958SGuenter Roeck .b[PSC_TEMPERATURE] = 5887, 214cce20958SGuenter Roeck .R[PSC_TEMPERATURE] = -1, 215cce20958SGuenter Roeck 216cce20958SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 217cce20958SGuenter Roeck .m[PSC_VOLTAGE_IN] = 3592, 218cce20958SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 219cce20958SGuenter Roeck .R[PSC_VOLTAGE_IN] = -2, 220cce20958SGuenter Roeck 221cce20958SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 222cce20958SGuenter Roeck .m[PSC_CURRENT_OUT] = 111, 223cce20958SGuenter Roeck .b[PSC_CURRENT_OUT] = 3461, 224cce20958SGuenter Roeck .R[PSC_CURRENT_OUT] = -1, 225cce20958SGuenter Roeck 226cce20958SGuenter Roeck .format[PSC_VOLTAGE_OUT] = linear, 227cce20958SGuenter Roeck 228cce20958SGuenter Roeck .func[0] = PMBUS_HAVE_VIN | 229cce20958SGuenter Roeck PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 230cce20958SGuenter Roeck PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 231cce20958SGuenter Roeck PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 232cce20958SGuenter Roeck }, 233cce20958SGuenter Roeck [max20743] = { 234cce20958SGuenter Roeck .pages = 1, 235cce20958SGuenter Roeck .read_word_data = max20730_read_word_data, 236cce20958SGuenter Roeck .write_word_data = max20730_write_word_data, 237cce20958SGuenter Roeck 238cce20958SGuenter Roeck /* Source : Maxim AN6042 */ 239cce20958SGuenter Roeck .format[PSC_TEMPERATURE] = direct, 240cce20958SGuenter Roeck .m[PSC_TEMPERATURE] = 21, 241cce20958SGuenter Roeck .b[PSC_TEMPERATURE] = 5887, 242cce20958SGuenter Roeck .R[PSC_TEMPERATURE] = -1, 243cce20958SGuenter Roeck 244cce20958SGuenter Roeck .format[PSC_VOLTAGE_IN] = direct, 245cce20958SGuenter Roeck .m[PSC_VOLTAGE_IN] = 3597, 246cce20958SGuenter Roeck .b[PSC_VOLTAGE_IN] = 0, 247cce20958SGuenter Roeck .R[PSC_VOLTAGE_IN] = -2, 248cce20958SGuenter Roeck 249cce20958SGuenter Roeck .format[PSC_CURRENT_OUT] = direct, 250cce20958SGuenter Roeck .m[PSC_CURRENT_OUT] = 95, 251cce20958SGuenter Roeck .b[PSC_CURRENT_OUT] = 5014, 252cce20958SGuenter Roeck .R[PSC_CURRENT_OUT] = -1, 253cce20958SGuenter Roeck 254cce20958SGuenter Roeck .format[PSC_VOLTAGE_OUT] = linear, 255cce20958SGuenter Roeck 256cce20958SGuenter Roeck .func[0] = PMBUS_HAVE_VIN | 257cce20958SGuenter Roeck PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 258cce20958SGuenter Roeck PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 259cce20958SGuenter Roeck PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 260cce20958SGuenter Roeck }, 261cce20958SGuenter Roeck }; 262cce20958SGuenter Roeck 263cce20958SGuenter Roeck static int max20730_probe(struct i2c_client *client, 264cce20958SGuenter Roeck const struct i2c_device_id *id) 265cce20958SGuenter Roeck { 266cce20958SGuenter Roeck struct device *dev = &client->dev; 267cce20958SGuenter Roeck u8 buf[I2C_SMBUS_BLOCK_MAX + 1]; 268cce20958SGuenter Roeck struct max20730_data *data; 269cce20958SGuenter Roeck enum chips chip_id; 270cce20958SGuenter Roeck int ret; 271cce20958SGuenter Roeck 272cce20958SGuenter Roeck if (!i2c_check_functionality(client->adapter, 273cce20958SGuenter Roeck I2C_FUNC_SMBUS_READ_BYTE_DATA | 274cce20958SGuenter Roeck I2C_FUNC_SMBUS_READ_WORD_DATA | 275cce20958SGuenter Roeck I2C_FUNC_SMBUS_BLOCK_DATA)) 276cce20958SGuenter Roeck return -ENODEV; 277cce20958SGuenter Roeck 278cce20958SGuenter Roeck ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); 279cce20958SGuenter Roeck if (ret < 0) { 280cce20958SGuenter Roeck dev_err(&client->dev, "Failed to read Manufacturer ID\n"); 281cce20958SGuenter Roeck return ret; 282cce20958SGuenter Roeck } 283cce20958SGuenter Roeck if (ret != 5 || strncmp(buf, "MAXIM", 5)) { 284cce20958SGuenter Roeck buf[ret] = '\0'; 285cce20958SGuenter Roeck dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf); 286cce20958SGuenter Roeck return -ENODEV; 287cce20958SGuenter Roeck } 288cce20958SGuenter Roeck 289cce20958SGuenter Roeck /* 290cce20958SGuenter Roeck * The chips support reading PMBUS_MFR_MODEL. On both MAX20730 291cce20958SGuenter Roeck * and MAX20734, reading it returns M20743. Presumably that is 292cce20958SGuenter Roeck * the reason why the command is not documented. Unfortunately, 293cce20958SGuenter Roeck * that means that there is no reliable means to detect the chip. 294cce20958SGuenter Roeck * However, we can at least detect the chip series. Compare 295cce20958SGuenter Roeck * the returned value against 'M20743' and bail out if there is 296cce20958SGuenter Roeck * a mismatch. If that doesn't work for all chips, we may have 297cce20958SGuenter Roeck * to remove this check. 298cce20958SGuenter Roeck */ 299cce20958SGuenter Roeck ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); 300cce20958SGuenter Roeck if (ret < 0) { 301cce20958SGuenter Roeck dev_err(dev, "Failed to read Manufacturer Model\n"); 302cce20958SGuenter Roeck return ret; 303cce20958SGuenter Roeck } 304cce20958SGuenter Roeck if (ret != 6 || strncmp(buf, "M20743", 6)) { 305cce20958SGuenter Roeck buf[ret] = '\0'; 306cce20958SGuenter Roeck dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf); 307cce20958SGuenter Roeck return -ENODEV; 308cce20958SGuenter Roeck } 309cce20958SGuenter Roeck 310cce20958SGuenter Roeck ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf); 311cce20958SGuenter Roeck if (ret < 0) { 312cce20958SGuenter Roeck dev_err(dev, "Failed to read Manufacturer Revision\n"); 313cce20958SGuenter Roeck return ret; 314cce20958SGuenter Roeck } 315cce20958SGuenter Roeck if (ret != 1 || buf[0] != 'F') { 316cce20958SGuenter Roeck buf[ret] = '\0'; 317cce20958SGuenter Roeck dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf); 318cce20958SGuenter Roeck return -ENODEV; 319cce20958SGuenter Roeck } 320cce20958SGuenter Roeck 321cce20958SGuenter Roeck if (client->dev.of_node) 322cce20958SGuenter Roeck chip_id = (enum chips)of_device_get_match_data(dev); 323cce20958SGuenter Roeck else 324cce20958SGuenter Roeck chip_id = id->driver_data; 325cce20958SGuenter Roeck 326cce20958SGuenter Roeck data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 327cce20958SGuenter Roeck if (!data) 328cce20958SGuenter Roeck return -ENOMEM; 329cce20958SGuenter Roeck data->id = chip_id; 330cce20958SGuenter Roeck mutex_init(&data->lock); 331cce20958SGuenter Roeck memcpy(&data->info, &max20730_info[chip_id], sizeof(data->info)); 332cce20958SGuenter Roeck 333cce20958SGuenter Roeck ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET1); 334cce20958SGuenter Roeck if (ret < 0) 335cce20958SGuenter Roeck return ret; 336cce20958SGuenter Roeck data->mfr_devset1 = ret; 337cce20958SGuenter Roeck 338cce20958SGuenter Roeck return pmbus_do_probe(client, id, &data->info); 339cce20958SGuenter Roeck } 340cce20958SGuenter Roeck 341cce20958SGuenter Roeck static const struct i2c_device_id max20730_id[] = { 342cce20958SGuenter Roeck { "max20730", max20730 }, 343cce20958SGuenter Roeck { "max20734", max20734 }, 344cce20958SGuenter Roeck { "max20743", max20743 }, 345cce20958SGuenter Roeck { }, 346cce20958SGuenter Roeck }; 347cce20958SGuenter Roeck 348cce20958SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max20730_id); 349cce20958SGuenter Roeck 350cce20958SGuenter Roeck static const struct of_device_id max20730_of_match[] = { 351cce20958SGuenter Roeck { .compatible = "maxim,max20730", .data = (void *)max20730 }, 352cce20958SGuenter Roeck { .compatible = "maxim,max20734", .data = (void *)max20734 }, 353cce20958SGuenter Roeck { .compatible = "maxim,max20743", .data = (void *)max20743 }, 354cce20958SGuenter Roeck { }, 355cce20958SGuenter Roeck }; 356cce20958SGuenter Roeck 357cce20958SGuenter Roeck MODULE_DEVICE_TABLE(of, max20730_of_match); 358cce20958SGuenter Roeck 359cce20958SGuenter Roeck static struct i2c_driver max20730_driver = { 360cce20958SGuenter Roeck .driver = { 361cce20958SGuenter Roeck .name = "max20730", 362cce20958SGuenter Roeck .of_match_table = max20730_of_match, 363cce20958SGuenter Roeck }, 364cce20958SGuenter Roeck .probe = max20730_probe, 365cce20958SGuenter Roeck .remove = pmbus_do_remove, 366cce20958SGuenter Roeck .id_table = max20730_id, 367cce20958SGuenter Roeck }; 368cce20958SGuenter Roeck 369cce20958SGuenter Roeck module_i2c_driver(max20730_driver); 370cce20958SGuenter Roeck 371cce20958SGuenter Roeck MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 372cce20958SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX20730 / MAX20734 / MAX20743"); 373cce20958SGuenter Roeck MODULE_LICENSE("GPL"); 374