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