1*03e9bd8dSGuenter Roeck /* 2*03e9bd8dSGuenter Roeck * Hardware monitoring driver for LM25066 / LM5064 / LM5066 3*03e9bd8dSGuenter Roeck * 4*03e9bd8dSGuenter Roeck * Copyright (c) 2011 Ericsson AB. 5*03e9bd8dSGuenter Roeck * 6*03e9bd8dSGuenter Roeck * This program is free software; you can redistribute it and/or modify 7*03e9bd8dSGuenter Roeck * it under the terms of the GNU General Public License as published by 8*03e9bd8dSGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 9*03e9bd8dSGuenter Roeck * (at your option) any later version. 10*03e9bd8dSGuenter Roeck * 11*03e9bd8dSGuenter Roeck * This program is distributed in the hope that it will be useful, 12*03e9bd8dSGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*03e9bd8dSGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*03e9bd8dSGuenter Roeck * GNU General Public License for more details. 15*03e9bd8dSGuenter Roeck * 16*03e9bd8dSGuenter Roeck * You should have received a copy of the GNU General Public License 17*03e9bd8dSGuenter Roeck * along with this program; if not, write to the Free Software 18*03e9bd8dSGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*03e9bd8dSGuenter Roeck */ 20*03e9bd8dSGuenter Roeck 21*03e9bd8dSGuenter Roeck #include <linux/kernel.h> 22*03e9bd8dSGuenter Roeck #include <linux/module.h> 23*03e9bd8dSGuenter Roeck #include <linux/init.h> 24*03e9bd8dSGuenter Roeck #include <linux/err.h> 25*03e9bd8dSGuenter Roeck #include <linux/slab.h> 26*03e9bd8dSGuenter Roeck #include <linux/i2c.h> 27*03e9bd8dSGuenter Roeck #include "pmbus.h" 28*03e9bd8dSGuenter Roeck 29*03e9bd8dSGuenter Roeck enum chips { lm25066, lm5064, lm5066 }; 30*03e9bd8dSGuenter Roeck 31*03e9bd8dSGuenter Roeck #define LM25066_READ_VAUX 0xd0 32*03e9bd8dSGuenter Roeck #define LM25066_MFR_READ_IIN 0xd1 33*03e9bd8dSGuenter Roeck #define LM25066_MFR_READ_PIN 0xd2 34*03e9bd8dSGuenter Roeck #define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3 35*03e9bd8dSGuenter Roeck #define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4 36*03e9bd8dSGuenter Roeck #define LM25066_READ_PIN_PEAK 0xd5 37*03e9bd8dSGuenter Roeck #define LM25066_CLEAR_PIN_PEAK 0xd6 38*03e9bd8dSGuenter Roeck #define LM25066_DEVICE_SETUP 0xd9 39*03e9bd8dSGuenter Roeck #define LM25066_READ_AVG_VIN 0xdc 40*03e9bd8dSGuenter Roeck #define LM25066_READ_AVG_VOUT 0xdd 41*03e9bd8dSGuenter Roeck #define LM25066_READ_AVG_IIN 0xde 42*03e9bd8dSGuenter Roeck #define LM25066_READ_AVG_PIN 0xdf 43*03e9bd8dSGuenter Roeck 44*03e9bd8dSGuenter Roeck #define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */ 45*03e9bd8dSGuenter Roeck 46*03e9bd8dSGuenter Roeck struct lm25066_data { 47*03e9bd8dSGuenter Roeck int id; 48*03e9bd8dSGuenter Roeck struct pmbus_driver_info info; 49*03e9bd8dSGuenter Roeck }; 50*03e9bd8dSGuenter Roeck 51*03e9bd8dSGuenter Roeck #define to_lm25066_data(x) container_of(x, struct lm25066_data, info) 52*03e9bd8dSGuenter Roeck 53*03e9bd8dSGuenter Roeck static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) 54*03e9bd8dSGuenter Roeck { 55*03e9bd8dSGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 56*03e9bd8dSGuenter Roeck const struct lm25066_data *data = to_lm25066_data(info); 57*03e9bd8dSGuenter Roeck int ret; 58*03e9bd8dSGuenter Roeck 59*03e9bd8dSGuenter Roeck if (page > 1) 60*03e9bd8dSGuenter Roeck return -EINVAL; 61*03e9bd8dSGuenter Roeck 62*03e9bd8dSGuenter Roeck /* Map READ_VAUX into READ_VOUT register on page 1 */ 63*03e9bd8dSGuenter Roeck if (page == 1) { 64*03e9bd8dSGuenter Roeck switch (reg) { 65*03e9bd8dSGuenter Roeck case PMBUS_READ_VOUT: 66*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, 67*03e9bd8dSGuenter Roeck LM25066_READ_VAUX); 68*03e9bd8dSGuenter Roeck if (ret < 0) 69*03e9bd8dSGuenter Roeck break; 70*03e9bd8dSGuenter Roeck /* Adjust returned value to match VOUT coefficients */ 71*03e9bd8dSGuenter Roeck switch (data->id) { 72*03e9bd8dSGuenter Roeck case lm25066: 73*03e9bd8dSGuenter Roeck /* VOUT: 4.54 mV VAUX: 283.2 uV LSB */ 74*03e9bd8dSGuenter Roeck ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); 75*03e9bd8dSGuenter Roeck break; 76*03e9bd8dSGuenter Roeck case lm5064: 77*03e9bd8dSGuenter Roeck /* VOUT: 4.53 mV VAUX: 700 uV LSB */ 78*03e9bd8dSGuenter Roeck ret = DIV_ROUND_CLOSEST(ret * 70, 453); 79*03e9bd8dSGuenter Roeck break; 80*03e9bd8dSGuenter Roeck case lm5066: 81*03e9bd8dSGuenter Roeck /* VOUT: 2.18 mV VAUX: 725 uV LSB */ 82*03e9bd8dSGuenter Roeck ret = DIV_ROUND_CLOSEST(ret * 725, 2180); 83*03e9bd8dSGuenter Roeck break; 84*03e9bd8dSGuenter Roeck } 85*03e9bd8dSGuenter Roeck break; 86*03e9bd8dSGuenter Roeck default: 87*03e9bd8dSGuenter Roeck /* No other valid registers on page 1 */ 88*03e9bd8dSGuenter Roeck ret = -EINVAL; 89*03e9bd8dSGuenter Roeck break; 90*03e9bd8dSGuenter Roeck } 91*03e9bd8dSGuenter Roeck goto done; 92*03e9bd8dSGuenter Roeck } 93*03e9bd8dSGuenter Roeck 94*03e9bd8dSGuenter Roeck switch (reg) { 95*03e9bd8dSGuenter Roeck case PMBUS_READ_IIN: 96*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); 97*03e9bd8dSGuenter Roeck break; 98*03e9bd8dSGuenter Roeck case PMBUS_READ_PIN: 99*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN); 100*03e9bd8dSGuenter Roeck break; 101*03e9bd8dSGuenter Roeck case PMBUS_IIN_OC_WARN_LIMIT: 102*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, 103*03e9bd8dSGuenter Roeck LM25066_MFR_IIN_OC_WARN_LIMIT); 104*03e9bd8dSGuenter Roeck break; 105*03e9bd8dSGuenter Roeck case PMBUS_PIN_OP_WARN_LIMIT: 106*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, 107*03e9bd8dSGuenter Roeck LM25066_MFR_PIN_OP_WARN_LIMIT); 108*03e9bd8dSGuenter Roeck break; 109*03e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_VIN_AVG: 110*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN); 111*03e9bd8dSGuenter Roeck break; 112*03e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_VOUT_AVG: 113*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT); 114*03e9bd8dSGuenter Roeck break; 115*03e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_IIN_AVG: 116*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN); 117*03e9bd8dSGuenter Roeck break; 118*03e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_PIN_AVG: 119*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN); 120*03e9bd8dSGuenter Roeck break; 121*03e9bd8dSGuenter Roeck case PMBUS_VIRT_READ_PIN_MAX: 122*03e9bd8dSGuenter Roeck ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK); 123*03e9bd8dSGuenter Roeck break; 124*03e9bd8dSGuenter Roeck case PMBUS_VIRT_RESET_PIN_HISTORY: 125*03e9bd8dSGuenter Roeck ret = 0; 126*03e9bd8dSGuenter Roeck break; 127*03e9bd8dSGuenter Roeck default: 128*03e9bd8dSGuenter Roeck ret = -ENODATA; 129*03e9bd8dSGuenter Roeck break; 130*03e9bd8dSGuenter Roeck } 131*03e9bd8dSGuenter Roeck done: 132*03e9bd8dSGuenter Roeck return ret; 133*03e9bd8dSGuenter Roeck } 134*03e9bd8dSGuenter Roeck 135*03e9bd8dSGuenter Roeck static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, 136*03e9bd8dSGuenter Roeck u16 word) 137*03e9bd8dSGuenter Roeck { 138*03e9bd8dSGuenter Roeck int ret; 139*03e9bd8dSGuenter Roeck 140*03e9bd8dSGuenter Roeck if (page > 1) 141*03e9bd8dSGuenter Roeck return -EINVAL; 142*03e9bd8dSGuenter Roeck 143*03e9bd8dSGuenter Roeck switch (reg) { 144*03e9bd8dSGuenter Roeck case PMBUS_IIN_OC_WARN_LIMIT: 145*03e9bd8dSGuenter Roeck ret = pmbus_write_word_data(client, 0, 146*03e9bd8dSGuenter Roeck LM25066_MFR_IIN_OC_WARN_LIMIT, 147*03e9bd8dSGuenter Roeck word); 148*03e9bd8dSGuenter Roeck break; 149*03e9bd8dSGuenter Roeck case PMBUS_PIN_OP_WARN_LIMIT: 150*03e9bd8dSGuenter Roeck ret = pmbus_write_word_data(client, 0, 151*03e9bd8dSGuenter Roeck LM25066_MFR_PIN_OP_WARN_LIMIT, 152*03e9bd8dSGuenter Roeck word); 153*03e9bd8dSGuenter Roeck break; 154*03e9bd8dSGuenter Roeck case PMBUS_VIRT_RESET_PIN_HISTORY: 155*03e9bd8dSGuenter Roeck ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK); 156*03e9bd8dSGuenter Roeck break; 157*03e9bd8dSGuenter Roeck default: 158*03e9bd8dSGuenter Roeck ret = -ENODATA; 159*03e9bd8dSGuenter Roeck break; 160*03e9bd8dSGuenter Roeck } 161*03e9bd8dSGuenter Roeck return ret; 162*03e9bd8dSGuenter Roeck } 163*03e9bd8dSGuenter Roeck 164*03e9bd8dSGuenter Roeck static int lm25066_probe(struct i2c_client *client, 165*03e9bd8dSGuenter Roeck const struct i2c_device_id *id) 166*03e9bd8dSGuenter Roeck { 167*03e9bd8dSGuenter Roeck int config; 168*03e9bd8dSGuenter Roeck int ret; 169*03e9bd8dSGuenter Roeck struct lm25066_data *data; 170*03e9bd8dSGuenter Roeck struct pmbus_driver_info *info; 171*03e9bd8dSGuenter Roeck 172*03e9bd8dSGuenter Roeck if (!i2c_check_functionality(client->adapter, 173*03e9bd8dSGuenter Roeck I2C_FUNC_SMBUS_READ_BYTE_DATA)) 174*03e9bd8dSGuenter Roeck return -ENODEV; 175*03e9bd8dSGuenter Roeck 176*03e9bd8dSGuenter Roeck data = kzalloc(sizeof(struct lm25066_data), GFP_KERNEL); 177*03e9bd8dSGuenter Roeck if (!data) 178*03e9bd8dSGuenter Roeck return -ENOMEM; 179*03e9bd8dSGuenter Roeck 180*03e9bd8dSGuenter Roeck config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP); 181*03e9bd8dSGuenter Roeck if (config < 0) { 182*03e9bd8dSGuenter Roeck ret = config; 183*03e9bd8dSGuenter Roeck goto err_mem; 184*03e9bd8dSGuenter Roeck } 185*03e9bd8dSGuenter Roeck 186*03e9bd8dSGuenter Roeck data->id = id->driver_data; 187*03e9bd8dSGuenter Roeck info = &data->info; 188*03e9bd8dSGuenter Roeck 189*03e9bd8dSGuenter Roeck info->pages = 2; 190*03e9bd8dSGuenter Roeck info->format[PSC_VOLTAGE_IN] = direct; 191*03e9bd8dSGuenter Roeck info->format[PSC_VOLTAGE_OUT] = direct; 192*03e9bd8dSGuenter Roeck info->format[PSC_CURRENT_IN] = direct; 193*03e9bd8dSGuenter Roeck info->format[PSC_TEMPERATURE] = direct; 194*03e9bd8dSGuenter Roeck info->format[PSC_POWER] = direct; 195*03e9bd8dSGuenter Roeck 196*03e9bd8dSGuenter Roeck info->m[PSC_TEMPERATURE] = 16; 197*03e9bd8dSGuenter Roeck info->b[PSC_TEMPERATURE] = 0; 198*03e9bd8dSGuenter Roeck info->R[PSC_TEMPERATURE] = 0; 199*03e9bd8dSGuenter Roeck 200*03e9bd8dSGuenter Roeck info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT 201*03e9bd8dSGuenter Roeck | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN 202*03e9bd8dSGuenter Roeck | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 203*03e9bd8dSGuenter Roeck info->func[1] = PMBUS_HAVE_VOUT; 204*03e9bd8dSGuenter Roeck 205*03e9bd8dSGuenter Roeck info->read_word_data = lm25066_read_word_data; 206*03e9bd8dSGuenter Roeck info->write_word_data = lm25066_write_word_data; 207*03e9bd8dSGuenter Roeck 208*03e9bd8dSGuenter Roeck switch (id->driver_data) { 209*03e9bd8dSGuenter Roeck case lm25066: 210*03e9bd8dSGuenter Roeck info->m[PSC_VOLTAGE_IN] = 22070; 211*03e9bd8dSGuenter Roeck info->b[PSC_VOLTAGE_IN] = 0; 212*03e9bd8dSGuenter Roeck info->R[PSC_VOLTAGE_IN] = -2; 213*03e9bd8dSGuenter Roeck info->m[PSC_VOLTAGE_OUT] = 22070; 214*03e9bd8dSGuenter Roeck info->b[PSC_VOLTAGE_OUT] = 0; 215*03e9bd8dSGuenter Roeck info->R[PSC_VOLTAGE_OUT] = -2; 216*03e9bd8dSGuenter Roeck 217*03e9bd8dSGuenter Roeck if (config & LM25066_DEV_SETUP_CL) { 218*03e9bd8dSGuenter Roeck info->m[PSC_CURRENT_IN] = 6852; 219*03e9bd8dSGuenter Roeck info->b[PSC_CURRENT_IN] = 0; 220*03e9bd8dSGuenter Roeck info->R[PSC_CURRENT_IN] = -2; 221*03e9bd8dSGuenter Roeck info->m[PSC_POWER] = 369; 222*03e9bd8dSGuenter Roeck info->b[PSC_POWER] = 0; 223*03e9bd8dSGuenter Roeck info->R[PSC_POWER] = -2; 224*03e9bd8dSGuenter Roeck } else { 225*03e9bd8dSGuenter Roeck info->m[PSC_CURRENT_IN] = 13661; 226*03e9bd8dSGuenter Roeck info->b[PSC_CURRENT_IN] = 0; 227*03e9bd8dSGuenter Roeck info->R[PSC_CURRENT_IN] = -2; 228*03e9bd8dSGuenter Roeck info->m[PSC_POWER] = 736; 229*03e9bd8dSGuenter Roeck info->b[PSC_POWER] = 0; 230*03e9bd8dSGuenter Roeck info->R[PSC_POWER] = -2; 231*03e9bd8dSGuenter Roeck } 232*03e9bd8dSGuenter Roeck break; 233*03e9bd8dSGuenter Roeck case lm5064: 234*03e9bd8dSGuenter Roeck info->m[PSC_VOLTAGE_IN] = 22075; 235*03e9bd8dSGuenter Roeck info->b[PSC_VOLTAGE_IN] = 0; 236*03e9bd8dSGuenter Roeck info->R[PSC_VOLTAGE_IN] = -2; 237*03e9bd8dSGuenter Roeck info->m[PSC_VOLTAGE_OUT] = 22075; 238*03e9bd8dSGuenter Roeck info->b[PSC_VOLTAGE_OUT] = 0; 239*03e9bd8dSGuenter Roeck info->R[PSC_VOLTAGE_OUT] = -2; 240*03e9bd8dSGuenter Roeck 241*03e9bd8dSGuenter Roeck if (config & LM25066_DEV_SETUP_CL) { 242*03e9bd8dSGuenter Roeck info->m[PSC_CURRENT_IN] = 6713; 243*03e9bd8dSGuenter Roeck info->b[PSC_CURRENT_IN] = 0; 244*03e9bd8dSGuenter Roeck info->R[PSC_CURRENT_IN] = -2; 245*03e9bd8dSGuenter Roeck info->m[PSC_POWER] = 3619; 246*03e9bd8dSGuenter Roeck info->b[PSC_POWER] = 0; 247*03e9bd8dSGuenter Roeck info->R[PSC_POWER] = -3; 248*03e9bd8dSGuenter Roeck } else { 249*03e9bd8dSGuenter Roeck info->m[PSC_CURRENT_IN] = 13426; 250*03e9bd8dSGuenter Roeck info->b[PSC_CURRENT_IN] = 0; 251*03e9bd8dSGuenter Roeck info->R[PSC_CURRENT_IN] = -2; 252*03e9bd8dSGuenter Roeck info->m[PSC_POWER] = 7238; 253*03e9bd8dSGuenter Roeck info->b[PSC_POWER] = 0; 254*03e9bd8dSGuenter Roeck info->R[PSC_POWER] = -3; 255*03e9bd8dSGuenter Roeck } 256*03e9bd8dSGuenter Roeck break; 257*03e9bd8dSGuenter Roeck case lm5066: 258*03e9bd8dSGuenter Roeck info->m[PSC_VOLTAGE_IN] = 4587; 259*03e9bd8dSGuenter Roeck info->b[PSC_VOLTAGE_IN] = 0; 260*03e9bd8dSGuenter Roeck info->R[PSC_VOLTAGE_IN] = -2; 261*03e9bd8dSGuenter Roeck info->m[PSC_VOLTAGE_OUT] = 4587; 262*03e9bd8dSGuenter Roeck info->b[PSC_VOLTAGE_OUT] = 0; 263*03e9bd8dSGuenter Roeck info->R[PSC_VOLTAGE_OUT] = -2; 264*03e9bd8dSGuenter Roeck 265*03e9bd8dSGuenter Roeck if (config & LM25066_DEV_SETUP_CL) { 266*03e9bd8dSGuenter Roeck info->m[PSC_CURRENT_IN] = 10753; 267*03e9bd8dSGuenter Roeck info->b[PSC_CURRENT_IN] = 0; 268*03e9bd8dSGuenter Roeck info->R[PSC_CURRENT_IN] = -2; 269*03e9bd8dSGuenter Roeck info->m[PSC_POWER] = 1204; 270*03e9bd8dSGuenter Roeck info->b[PSC_POWER] = 0; 271*03e9bd8dSGuenter Roeck info->R[PSC_POWER] = -3; 272*03e9bd8dSGuenter Roeck } else { 273*03e9bd8dSGuenter Roeck info->m[PSC_CURRENT_IN] = 5405; 274*03e9bd8dSGuenter Roeck info->b[PSC_CURRENT_IN] = 0; 275*03e9bd8dSGuenter Roeck info->R[PSC_CURRENT_IN] = -2; 276*03e9bd8dSGuenter Roeck info->m[PSC_POWER] = 605; 277*03e9bd8dSGuenter Roeck info->b[PSC_POWER] = 0; 278*03e9bd8dSGuenter Roeck info->R[PSC_POWER] = -3; 279*03e9bd8dSGuenter Roeck } 280*03e9bd8dSGuenter Roeck break; 281*03e9bd8dSGuenter Roeck default: 282*03e9bd8dSGuenter Roeck ret = -ENODEV; 283*03e9bd8dSGuenter Roeck goto err_mem; 284*03e9bd8dSGuenter Roeck } 285*03e9bd8dSGuenter Roeck 286*03e9bd8dSGuenter Roeck ret = pmbus_do_probe(client, id, info); 287*03e9bd8dSGuenter Roeck if (ret) 288*03e9bd8dSGuenter Roeck goto err_mem; 289*03e9bd8dSGuenter Roeck return 0; 290*03e9bd8dSGuenter Roeck 291*03e9bd8dSGuenter Roeck err_mem: 292*03e9bd8dSGuenter Roeck kfree(data); 293*03e9bd8dSGuenter Roeck return ret; 294*03e9bd8dSGuenter Roeck } 295*03e9bd8dSGuenter Roeck 296*03e9bd8dSGuenter Roeck static int lm25066_remove(struct i2c_client *client) 297*03e9bd8dSGuenter Roeck { 298*03e9bd8dSGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 299*03e9bd8dSGuenter Roeck const struct lm25066_data *data = to_lm25066_data(info); 300*03e9bd8dSGuenter Roeck int ret; 301*03e9bd8dSGuenter Roeck 302*03e9bd8dSGuenter Roeck ret = pmbus_do_remove(client); 303*03e9bd8dSGuenter Roeck kfree(data); 304*03e9bd8dSGuenter Roeck return ret; 305*03e9bd8dSGuenter Roeck } 306*03e9bd8dSGuenter Roeck 307*03e9bd8dSGuenter Roeck static const struct i2c_device_id lm25066_id[] = { 308*03e9bd8dSGuenter Roeck {"lm25066", lm25066}, 309*03e9bd8dSGuenter Roeck {"lm5064", lm5064}, 310*03e9bd8dSGuenter Roeck {"lm5066", lm5066}, 311*03e9bd8dSGuenter Roeck { } 312*03e9bd8dSGuenter Roeck }; 313*03e9bd8dSGuenter Roeck 314*03e9bd8dSGuenter Roeck MODULE_DEVICE_TABLE(i2c, lm25066_id); 315*03e9bd8dSGuenter Roeck 316*03e9bd8dSGuenter Roeck /* This is the driver that will be inserted */ 317*03e9bd8dSGuenter Roeck static struct i2c_driver lm25066_driver = { 318*03e9bd8dSGuenter Roeck .driver = { 319*03e9bd8dSGuenter Roeck .name = "lm25066", 320*03e9bd8dSGuenter Roeck }, 321*03e9bd8dSGuenter Roeck .probe = lm25066_probe, 322*03e9bd8dSGuenter Roeck .remove = lm25066_remove, 323*03e9bd8dSGuenter Roeck .id_table = lm25066_id, 324*03e9bd8dSGuenter Roeck }; 325*03e9bd8dSGuenter Roeck 326*03e9bd8dSGuenter Roeck static int __init lm25066_init(void) 327*03e9bd8dSGuenter Roeck { 328*03e9bd8dSGuenter Roeck return i2c_add_driver(&lm25066_driver); 329*03e9bd8dSGuenter Roeck } 330*03e9bd8dSGuenter Roeck 331*03e9bd8dSGuenter Roeck static void __exit lm25066_exit(void) 332*03e9bd8dSGuenter Roeck { 333*03e9bd8dSGuenter Roeck i2c_del_driver(&lm25066_driver); 334*03e9bd8dSGuenter Roeck } 335*03e9bd8dSGuenter Roeck 336*03e9bd8dSGuenter Roeck MODULE_AUTHOR("Guenter Roeck"); 337*03e9bd8dSGuenter Roeck MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); 338*03e9bd8dSGuenter Roeck MODULE_LICENSE("GPL"); 339*03e9bd8dSGuenter Roeck module_init(lm25066_init); 340*03e9bd8dSGuenter Roeck module_exit(lm25066_exit); 341