103e9bd8dSGuenter Roeck /* 203e9bd8dSGuenter Roeck * Hardware monitoring driver for LM25066 / LM5064 / LM5066 303e9bd8dSGuenter Roeck * 403e9bd8dSGuenter Roeck * Copyright (c) 2011 Ericsson AB. 5a7c69118SGuenter Roeck * Copyright (c) 2013 Guenter Roeck 603e9bd8dSGuenter Roeck * 703e9bd8dSGuenter Roeck * This program is free software; you can redistribute it and/or modify 803e9bd8dSGuenter Roeck * it under the terms of the GNU General Public License as published by 903e9bd8dSGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 1003e9bd8dSGuenter Roeck * (at your option) any later version. 1103e9bd8dSGuenter Roeck * 1203e9bd8dSGuenter Roeck * This program is distributed in the hope that it will be useful, 1303e9bd8dSGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 1403e9bd8dSGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1503e9bd8dSGuenter Roeck * GNU General Public License for more details. 1603e9bd8dSGuenter Roeck * 1703e9bd8dSGuenter Roeck * You should have received a copy of the GNU General Public License 1803e9bd8dSGuenter Roeck * along with this program; if not, write to the Free Software 1903e9bd8dSGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 2003e9bd8dSGuenter Roeck */ 2103e9bd8dSGuenter Roeck 2203e9bd8dSGuenter Roeck #include <linux/kernel.h> 2303e9bd8dSGuenter Roeck #include <linux/module.h> 2403e9bd8dSGuenter Roeck #include <linux/init.h> 2503e9bd8dSGuenter Roeck #include <linux/err.h> 2603e9bd8dSGuenter Roeck #include <linux/slab.h> 2703e9bd8dSGuenter Roeck #include <linux/i2c.h> 2803e9bd8dSGuenter Roeck #include "pmbus.h" 2903e9bd8dSGuenter Roeck 3003e9bd8dSGuenter Roeck enum chips { lm25066, lm5064, lm5066 }; 3103e9bd8dSGuenter Roeck 3203e9bd8dSGuenter Roeck #define LM25066_READ_VAUX 0xd0 3303e9bd8dSGuenter Roeck #define LM25066_MFR_READ_IIN 0xd1 3403e9bd8dSGuenter Roeck #define LM25066_MFR_READ_PIN 0xd2 3503e9bd8dSGuenter Roeck #define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3 3603e9bd8dSGuenter Roeck #define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4 3703e9bd8dSGuenter Roeck #define LM25066_READ_PIN_PEAK 0xd5 3803e9bd8dSGuenter Roeck #define LM25066_CLEAR_PIN_PEAK 0xd6 3903e9bd8dSGuenter Roeck #define LM25066_DEVICE_SETUP 0xd9 4003e9bd8dSGuenter Roeck #define LM25066_READ_AVG_VIN 0xdc 4103e9bd8dSGuenter Roeck #define LM25066_READ_AVG_VOUT 0xdd 4203e9bd8dSGuenter Roeck #define LM25066_READ_AVG_IIN 0xde 4303e9bd8dSGuenter Roeck #define LM25066_READ_AVG_PIN 0xdf 4403e9bd8dSGuenter Roeck 4503e9bd8dSGuenter Roeck #define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ 4603e9bd8dSGuenter Roeck 47*e53e6497SGuenter Roeck struct __coeff { 48*e53e6497SGuenter Roeck short m, b, R; 49*e53e6497SGuenter Roeck }; 50*e53e6497SGuenter Roeck 51*e53e6497SGuenter Roeck #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) 52*e53e6497SGuenter Roeck #define PSC_POWER_L (PSC_NUM_CLASSES + 1) 53*e53e6497SGuenter Roeck 54*e53e6497SGuenter Roeck static struct __coeff lm25066_coeff[3][PSC_NUM_CLASSES + 2] = { 55*e53e6497SGuenter Roeck [lm25066] = { 56*e53e6497SGuenter Roeck [PSC_VOLTAGE_IN] = { 57*e53e6497SGuenter Roeck .m = 22070, 58*e53e6497SGuenter Roeck .R = -2, 59*e53e6497SGuenter Roeck }, 60*e53e6497SGuenter Roeck [PSC_VOLTAGE_OUT] = { 61*e53e6497SGuenter Roeck .m = 22070, 62*e53e6497SGuenter Roeck .R = -2, 63*e53e6497SGuenter Roeck }, 64*e53e6497SGuenter Roeck [PSC_CURRENT_IN] = { 65*e53e6497SGuenter Roeck .m = 13661, 66*e53e6497SGuenter Roeck .R = -2, 67*e53e6497SGuenter Roeck }, 68*e53e6497SGuenter Roeck [PSC_CURRENT_IN_L] = { 69*e53e6497SGuenter Roeck .m = 6852, 70*e53e6497SGuenter Roeck .R = -2, 71*e53e6497SGuenter Roeck }, 72*e53e6497SGuenter Roeck [PSC_POWER] = { 73*e53e6497SGuenter Roeck .m = 736, 74*e53e6497SGuenter Roeck .R = -2, 75*e53e6497SGuenter Roeck }, 76*e53e6497SGuenter Roeck [PSC_POWER_L] = { 77*e53e6497SGuenter Roeck .m = 369, 78*e53e6497SGuenter Roeck .R = -2, 79*e53e6497SGuenter Roeck }, 80*e53e6497SGuenter Roeck [PSC_TEMPERATURE] = { 81*e53e6497SGuenter Roeck .m = 16, 82*e53e6497SGuenter Roeck }, 83*e53e6497SGuenter Roeck }, 84*e53e6497SGuenter Roeck [lm5064] = { 85*e53e6497SGuenter Roeck [PSC_VOLTAGE_IN] = { 86*e53e6497SGuenter Roeck .m = 4611, 87*e53e6497SGuenter Roeck .R = -2, 88*e53e6497SGuenter Roeck }, 89*e53e6497SGuenter Roeck [PSC_VOLTAGE_OUT] = { 90*e53e6497SGuenter Roeck .m = 4621, 91*e53e6497SGuenter Roeck .R = -2, 92*e53e6497SGuenter Roeck }, 93*e53e6497SGuenter Roeck [PSC_CURRENT_IN] = { 94*e53e6497SGuenter Roeck .m = 10742, 95*e53e6497SGuenter Roeck .R = -2, 96*e53e6497SGuenter Roeck }, 97*e53e6497SGuenter Roeck [PSC_CURRENT_IN_L] = { 98*e53e6497SGuenter Roeck .m = 5456, 99*e53e6497SGuenter Roeck .R = -2, 100*e53e6497SGuenter Roeck }, 101*e53e6497SGuenter Roeck [PSC_POWER] = { 102*e53e6497SGuenter Roeck .m = 1204, 103*e53e6497SGuenter Roeck .R = -3, 104*e53e6497SGuenter Roeck }, 105*e53e6497SGuenter Roeck [PSC_POWER_L] = { 106*e53e6497SGuenter Roeck .m = 612, 107*e53e6497SGuenter Roeck .R = -3, 108*e53e6497SGuenter Roeck }, 109*e53e6497SGuenter Roeck [PSC_TEMPERATURE] = { 110*e53e6497SGuenter Roeck .m = 16, 111*e53e6497SGuenter Roeck }, 112*e53e6497SGuenter Roeck }, 113*e53e6497SGuenter Roeck [lm5066] = { 114*e53e6497SGuenter Roeck [PSC_VOLTAGE_IN] = { 115*e53e6497SGuenter Roeck .m = 4587, 116*e53e6497SGuenter Roeck .R = -2, 117*e53e6497SGuenter Roeck }, 118*e53e6497SGuenter Roeck [PSC_VOLTAGE_OUT] = { 119*e53e6497SGuenter Roeck .m = 4587, 120*e53e6497SGuenter Roeck .R = -2, 121*e53e6497SGuenter Roeck }, 122*e53e6497SGuenter Roeck [PSC_CURRENT_IN] = { 123*e53e6497SGuenter Roeck .m = 10753, 124*e53e6497SGuenter Roeck .R = -2, 125*e53e6497SGuenter Roeck }, 126*e53e6497SGuenter Roeck [PSC_CURRENT_IN_L] = { 127*e53e6497SGuenter Roeck .m = 5405, 128*e53e6497SGuenter Roeck .R = -2, 129*e53e6497SGuenter Roeck }, 130*e53e6497SGuenter Roeck [PSC_POWER] = { 131*e53e6497SGuenter Roeck .m = 1204, 132*e53e6497SGuenter Roeck .R = -3, 133*e53e6497SGuenter Roeck }, 134*e53e6497SGuenter Roeck [PSC_POWER_L] = { 135*e53e6497SGuenter Roeck .m = 605, 136*e53e6497SGuenter Roeck .R = -3, 137*e53e6497SGuenter Roeck }, 138*e53e6497SGuenter Roeck [PSC_TEMPERATURE] = { 139*e53e6497SGuenter Roeck .m = 16, 140*e53e6497SGuenter Roeck }, 141*e53e6497SGuenter Roeck }, 142*e53e6497SGuenter Roeck }; 143*e53e6497SGuenter Roeck 14403e9bd8dSGuenter Roeck struct lm25066_data { 14503e9bd8dSGuenter Roeck int id; 14603e9bd8dSGuenter Roeck struct pmbus_driver_info info; 14703e9bd8dSGuenter Roeck }; 14803e9bd8dSGuenter Roeck 14903e9bd8dSGuenter Roeck #define to_lm25066_data(x) container_of(x, struct lm25066_data, info) 15003e9bd8dSGuenter Roeck 15103e9bd8dSGuenter Roeck static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) 15203e9bd8dSGuenter Roeck { 15303e9bd8dSGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 15403e9bd8dSGuenter Roeck const struct lm25066_data *data = to_lm25066_data(info); 15503e9bd8dSGuenter Roeck int ret; 15603e9bd8dSGuenter Roeck 15703e9bd8dSGuenter Roeck switch (reg) { 158a7c69118SGuenter Roeck case PMBUS_VIRT_READ_VMON: 159a7c69118SGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX); 16003e9bd8dSGuenter Roeck if (ret < 0) 16103e9bd8dSGuenter Roeck break; 162a7c69118SGuenter Roeck /* Adjust returned value to match VIN coefficients */ 16303e9bd8dSGuenter Roeck switch (data->id) { 16403e9bd8dSGuenter Roeck case lm25066: 165a7c69118SGuenter Roeck /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ 16603e9bd8dSGuenter Roeck ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); 16703e9bd8dSGuenter Roeck break; 16803e9bd8dSGuenter Roeck case lm5064: 169a7c69118SGuenter Roeck /* VIN: 4.53 mV VAUX: 700 uV LSB */ 17003e9bd8dSGuenter Roeck ret = DIV_ROUND_CLOSEST(ret * 70, 453); 17103e9bd8dSGuenter Roeck break; 17203e9bd8dSGuenter Roeck case lm5066: 173a7c69118SGuenter Roeck /* VIN: 2.18 mV VAUX: 725 uV LSB */ 17403e9bd8dSGuenter Roeck ret = DIV_ROUND_CLOSEST(ret * 725, 2180); 17503e9bd8dSGuenter Roeck break; 17603e9bd8dSGuenter Roeck } 17703e9bd8dSGuenter Roeck break; 17803e9bd8dSGuenter Roeck case PMBUS_READ_IIN: 17903e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); 18003e9bd8dSGuenter Roeck break; 18103e9bd8dSGuenter Roeck case PMBUS_READ_PIN: 18203e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN); 18303e9bd8dSGuenter Roeck break; 18403e9bd8dSGuenter Roeck case PMBUS_IIN_OC_WARN_LIMIT: 18503e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, 18603e9bd8dSGuenter Roeck LM25066_MFR_IIN_OC_WARN_LIMIT); 18703e9bd8dSGuenter Roeck break; 18803e9bd8dSGuenter Roeck case PMBUS_PIN_OP_WARN_LIMIT: 18903e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, 19003e9bd8dSGuenter Roeck LM25066_MFR_PIN_OP_WARN_LIMIT); 19103e9bd8dSGuenter Roeck break; 19203e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_VIN_AVG: 19303e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN); 19403e9bd8dSGuenter Roeck break; 19503e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_VOUT_AVG: 19603e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT); 19703e9bd8dSGuenter Roeck break; 19803e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_IIN_AVG: 19903e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN); 20003e9bd8dSGuenter Roeck break; 20103e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_PIN_AVG: 20203e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN); 20303e9bd8dSGuenter Roeck break; 20403e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_PIN_MAX: 20503e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK); 20603e9bd8dSGuenter Roeck break; 20703e9bd8dSGuenter Roeck case PMBUS_VIRT_RESET_PIN_HISTORY: 20803e9bd8dSGuenter Roeck ret = 0; 20903e9bd8dSGuenter Roeck break; 21003e9bd8dSGuenter Roeck default: 21103e9bd8dSGuenter Roeck ret = -ENODATA; 21203e9bd8dSGuenter Roeck break; 21303e9bd8dSGuenter Roeck } 21403e9bd8dSGuenter Roeck return ret; 21503e9bd8dSGuenter Roeck } 21603e9bd8dSGuenter Roeck 21703e9bd8dSGuenter Roeck static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, 21803e9bd8dSGuenter Roeck u16 word) 21903e9bd8dSGuenter Roeck { 22003e9bd8dSGuenter Roeck int ret; 22103e9bd8dSGuenter Roeck 22203e9bd8dSGuenter Roeck switch (reg) { 2232507abb3SGuenter Roeck case PMBUS_VOUT_UV_WARN_LIMIT: 2242507abb3SGuenter Roeck case PMBUS_OT_FAULT_LIMIT: 2252507abb3SGuenter Roeck case PMBUS_OT_WARN_LIMIT: 2262507abb3SGuenter Roeck case PMBUS_VIN_UV_WARN_LIMIT: 2272507abb3SGuenter Roeck case PMBUS_VIN_OV_WARN_LIMIT: 2282507abb3SGuenter Roeck word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); 2292507abb3SGuenter Roeck ret = pmbus_write_word_data(client, 0, reg, word); 2302507abb3SGuenter Roeck pmbus_clear_cache(client); 2312507abb3SGuenter Roeck break; 23203e9bd8dSGuenter Roeck case PMBUS_IIN_OC_WARN_LIMIT: 2332507abb3SGuenter Roeck word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); 23403e9bd8dSGuenter Roeck ret = pmbus_write_word_data(client, 0, 23503e9bd8dSGuenter Roeck LM25066_MFR_IIN_OC_WARN_LIMIT, 23603e9bd8dSGuenter Roeck word); 2372507abb3SGuenter Roeck pmbus_clear_cache(client); 23803e9bd8dSGuenter Roeck break; 23903e9bd8dSGuenter Roeck case PMBUS_PIN_OP_WARN_LIMIT: 2402507abb3SGuenter Roeck word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); 24103e9bd8dSGuenter Roeck ret = pmbus_write_word_data(client, 0, 24203e9bd8dSGuenter Roeck LM25066_MFR_PIN_OP_WARN_LIMIT, 24303e9bd8dSGuenter Roeck word); 2442507abb3SGuenter Roeck pmbus_clear_cache(client); 24503e9bd8dSGuenter Roeck break; 24603e9bd8dSGuenter Roeck case PMBUS_VIRT_RESET_PIN_HISTORY: 24703e9bd8dSGuenter Roeck ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); 24803e9bd8dSGuenter Roeck break; 24903e9bd8dSGuenter Roeck default: 25003e9bd8dSGuenter Roeck ret = -ENODATA; 25103e9bd8dSGuenter Roeck break; 25203e9bd8dSGuenter Roeck } 25303e9bd8dSGuenter Roeck return ret; 25403e9bd8dSGuenter Roeck } 25503e9bd8dSGuenter Roeck 25603e9bd8dSGuenter Roeck static int lm25066_probe(struct i2c_client *client, 25703e9bd8dSGuenter Roeck const struct i2c_device_id *id) 25803e9bd8dSGuenter Roeck { 25903e9bd8dSGuenter Roeck int config; 26003e9bd8dSGuenter Roeck struct lm25066_data *data; 26103e9bd8dSGuenter Roeck struct pmbus_driver_info *info; 262*e53e6497SGuenter Roeck struct __coeff *coeff; 26303e9bd8dSGuenter Roeck 26403e9bd8dSGuenter Roeck if (!i2c_check_functionality(client->adapter, 26503e9bd8dSGuenter Roeck I2C_FUNC_SMBUS_READ_BYTE_DATA)) 26603e9bd8dSGuenter Roeck return -ENODEV; 26703e9bd8dSGuenter Roeck 2688b313ca7SGuenter Roeck data = devm_kzalloc(&client->dev, sizeof(struct lm25066_data), 2698b313ca7SGuenter Roeck GFP_KERNEL); 27003e9bd8dSGuenter Roeck if (!data) 27103e9bd8dSGuenter Roeck return -ENOMEM; 27203e9bd8dSGuenter Roeck 27303e9bd8dSGuenter Roeck config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP); 2748b313ca7SGuenter Roeck if (config < 0) 2758b313ca7SGuenter Roeck return config; 27603e9bd8dSGuenter Roeck 27703e9bd8dSGuenter Roeck data->id = id->driver_data; 27803e9bd8dSGuenter Roeck info = &data->info; 27903e9bd8dSGuenter Roeck 280a7c69118SGuenter Roeck info->pages = 1; 28103e9bd8dSGuenter Roeck info->format[PSC_VOLTAGE_IN] = direct; 28203e9bd8dSGuenter Roeck info->format[PSC_VOLTAGE_OUT] = direct; 28303e9bd8dSGuenter Roeck info->format[PSC_CURRENT_IN] = direct; 28403e9bd8dSGuenter Roeck info->format[PSC_TEMPERATURE] = direct; 28503e9bd8dSGuenter Roeck info->format[PSC_POWER] = direct; 28603e9bd8dSGuenter Roeck 28703e9bd8dSGuenter Roeck 288a7c69118SGuenter Roeck info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON | PMBUS_HAVE_VOUT 28903e9bd8dSGuenter Roeck | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN 29003e9bd8dSGuenter Roeck | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 29103e9bd8dSGuenter Roeck 29203e9bd8dSGuenter Roeck info->read_word_data = lm25066_read_word_data; 29303e9bd8dSGuenter Roeck info->write_word_data = lm25066_write_word_data; 29403e9bd8dSGuenter Roeck 295*e53e6497SGuenter Roeck coeff = &lm25066_coeff[data->id][0]; 296*e53e6497SGuenter Roeck info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m; 297*e53e6497SGuenter Roeck info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b; 298*e53e6497SGuenter Roeck info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R; 299*e53e6497SGuenter Roeck info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m; 300*e53e6497SGuenter Roeck info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b; 301*e53e6497SGuenter Roeck info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R; 302*e53e6497SGuenter Roeck info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m; 303*e53e6497SGuenter Roeck info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b; 304*e53e6497SGuenter Roeck info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R; 305*e53e6497SGuenter Roeck info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b; 306*e53e6497SGuenter Roeck info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R; 307*e53e6497SGuenter Roeck info->b[PSC_POWER] = coeff[PSC_POWER].b; 308*e53e6497SGuenter Roeck info->R[PSC_POWER] = coeff[PSC_POWER].R; 30903e9bd8dSGuenter Roeck if (config & LM25066_DEV_SETUP_CL) { 310*e53e6497SGuenter Roeck info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m; 311*e53e6497SGuenter Roeck info->m[PSC_POWER] = coeff[PSC_POWER_L].m; 31203e9bd8dSGuenter Roeck } else { 313*e53e6497SGuenter Roeck info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m; 314*e53e6497SGuenter Roeck info->m[PSC_POWER] = coeff[PSC_POWER].m; 31503e9bd8dSGuenter Roeck } 31603e9bd8dSGuenter Roeck 3178b313ca7SGuenter Roeck return pmbus_do_probe(client, id, info); 31803e9bd8dSGuenter Roeck } 31903e9bd8dSGuenter Roeck 32003e9bd8dSGuenter Roeck static const struct i2c_device_id lm25066_id[] = { 32103e9bd8dSGuenter Roeck {"lm25066", lm25066}, 32203e9bd8dSGuenter Roeck {"lm5064", lm5064}, 32303e9bd8dSGuenter Roeck {"lm5066", lm5066}, 32403e9bd8dSGuenter Roeck { } 32503e9bd8dSGuenter Roeck }; 32603e9bd8dSGuenter Roeck 32703e9bd8dSGuenter Roeck MODULE_DEVICE_TABLE(i2c, lm25066_id); 32803e9bd8dSGuenter Roeck 32903e9bd8dSGuenter Roeck /* This is the driver that will be inserted */ 33003e9bd8dSGuenter Roeck static struct i2c_driver lm25066_driver = { 33103e9bd8dSGuenter Roeck .driver = { 33203e9bd8dSGuenter Roeck .name = "lm25066", 33303e9bd8dSGuenter Roeck }, 33403e9bd8dSGuenter Roeck .probe = lm25066_probe, 335dd285ad7SGuenter Roeck .remove = pmbus_do_remove, 33603e9bd8dSGuenter Roeck .id_table = lm25066_id, 33703e9bd8dSGuenter Roeck }; 33803e9bd8dSGuenter Roeck 339f0967eeaSAxel Lin module_i2c_driver(lm25066_driver); 34003e9bd8dSGuenter Roeck 34103e9bd8dSGuenter Roeck MODULE_AUTHOR("Guenter Roeck"); 34203e9bd8dSGuenter Roeck MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); 34303e9bd8dSGuenter Roeck MODULE_LICENSE("GPL"); 344