1 /* 2 * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943 3 * and LTC2944 Battery Gas Gauge IC 4 * 5 * Copyright (C) 2014 Topic Embedded Systems 6 * 7 * Author: Auryn Verwegen 8 * Author: Mike Looijmans 9 */ 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <linux/types.h> 14 #include <linux/errno.h> 15 #include <linux/swab.h> 16 #include <linux/i2c.h> 17 #include <linux/delay.h> 18 #include <linux/power_supply.h> 19 #include <linux/slab.h> 20 21 #define I16_MSB(x) ((x >> 8) & 0xFF) 22 #define I16_LSB(x) (x & 0xFF) 23 24 #define LTC294X_WORK_DELAY 10 /* Update delay in seconds */ 25 26 #define LTC294X_MAX_VALUE 0xFFFF 27 #define LTC294X_MID_SUPPLY 0x7FFF 28 29 #define LTC2941_MAX_PRESCALER_EXP 7 30 #define LTC2943_MAX_PRESCALER_EXP 6 31 32 enum ltc294x_reg { 33 LTC294X_REG_STATUS = 0x00, 34 LTC294X_REG_CONTROL = 0x01, 35 LTC294X_REG_ACC_CHARGE_MSB = 0x02, 36 LTC294X_REG_ACC_CHARGE_LSB = 0x03, 37 LTC294X_REG_CHARGE_THR_HIGH_MSB = 0x04, 38 LTC294X_REG_CHARGE_THR_HIGH_LSB = 0x05, 39 LTC294X_REG_CHARGE_THR_LOW_MSB = 0x06, 40 LTC294X_REG_CHARGE_THR_LOW_LSB = 0x07, 41 LTC294X_REG_VOLTAGE_MSB = 0x08, 42 LTC294X_REG_VOLTAGE_LSB = 0x09, 43 LTC2942_REG_TEMPERATURE_MSB = 0x0C, 44 LTC2942_REG_TEMPERATURE_LSB = 0x0D, 45 LTC2943_REG_CURRENT_MSB = 0x0E, 46 LTC2943_REG_CURRENT_LSB = 0x0F, 47 LTC2943_REG_TEMPERATURE_MSB = 0x14, 48 LTC2943_REG_TEMPERATURE_LSB = 0x15, 49 }; 50 51 enum ltc294x_id { 52 LTC2941_ID, 53 LTC2942_ID, 54 LTC2943_ID, 55 LTC2944_ID, 56 }; 57 58 #define LTC2941_REG_STATUS_CHIP_ID BIT(7) 59 60 #define LTC2942_REG_CONTROL_MODE_SCAN (BIT(7) | BIT(6)) 61 #define LTC2943_REG_CONTROL_MODE_SCAN BIT(7) 62 #define LTC294X_REG_CONTROL_PRESCALER_MASK (BIT(5) | BIT(4) | BIT(3)) 63 #define LTC294X_REG_CONTROL_SHUTDOWN_MASK (BIT(0)) 64 #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \ 65 ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK) 66 #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0 67 #define LTC294X_REG_CONTROL_ADC_DISABLE(x) ((x) & ~(BIT(7) | BIT(6))) 68 69 struct ltc294x_info { 70 struct i2c_client *client; /* I2C Client pointer */ 71 struct power_supply *supply; /* Supply pointer */ 72 struct power_supply_desc supply_desc; /* Supply description */ 73 struct delayed_work work; /* Work scheduler */ 74 enum ltc294x_id id; /* Chip type */ 75 int charge; /* Last charge register content */ 76 int r_sense; /* mOhm */ 77 int Qlsb; /* nAh */ 78 }; 79 80 static inline int convert_bin_to_uAh( 81 const struct ltc294x_info *info, int Q) 82 { 83 return ((Q * (info->Qlsb / 10))) / 100; 84 } 85 86 static inline int convert_uAh_to_bin( 87 const struct ltc294x_info *info, int uAh) 88 { 89 int Q; 90 91 Q = (uAh * 100) / (info->Qlsb/10); 92 return (Q < LTC294X_MAX_VALUE) ? Q : LTC294X_MAX_VALUE; 93 } 94 95 static int ltc294x_read_regs(struct i2c_client *client, 96 enum ltc294x_reg reg, u8 *buf, int num_regs) 97 { 98 int ret; 99 struct i2c_msg msgs[2] = { }; 100 u8 reg_start = reg; 101 102 msgs[0].addr = client->addr; 103 msgs[0].len = 1; 104 msgs[0].buf = ®_start; 105 106 msgs[1].addr = client->addr; 107 msgs[1].len = num_regs; 108 msgs[1].buf = buf; 109 msgs[1].flags = I2C_M_RD; 110 111 ret = i2c_transfer(client->adapter, &msgs[0], 2); 112 if (ret < 0) { 113 dev_err(&client->dev, "ltc2941 read_reg failed!\n"); 114 return ret; 115 } 116 117 dev_dbg(&client->dev, "%s (%#x, %d) -> %#x\n", 118 __func__, reg, num_regs, *buf); 119 120 return 0; 121 } 122 123 static int ltc294x_write_regs(struct i2c_client *client, 124 enum ltc294x_reg reg, const u8 *buf, int num_regs) 125 { 126 int ret; 127 u8 reg_start = reg; 128 129 ret = i2c_smbus_write_i2c_block_data(client, reg_start, num_regs, buf); 130 if (ret < 0) { 131 dev_err(&client->dev, "ltc2941 write_reg failed!\n"); 132 return ret; 133 } 134 135 dev_dbg(&client->dev, "%s (%#x, %d) -> %#x\n", 136 __func__, reg, num_regs, *buf); 137 138 return 0; 139 } 140 141 static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp) 142 { 143 int ret; 144 u8 value; 145 u8 control; 146 147 /* Read status and control registers */ 148 ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1); 149 if (ret < 0) { 150 dev_err(&info->client->dev, 151 "Could not read registers from device\n"); 152 goto error_exit; 153 } 154 155 control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) | 156 LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED; 157 /* Put device into "monitor" mode */ 158 switch (info->id) { 159 case LTC2942_ID: /* 2942 measures every 2 sec */ 160 control |= LTC2942_REG_CONTROL_MODE_SCAN; 161 break; 162 case LTC2943_ID: 163 case LTC2944_ID: /* 2943 and 2944 measure every 10 sec */ 164 control |= LTC2943_REG_CONTROL_MODE_SCAN; 165 break; 166 default: 167 break; 168 } 169 170 if (value != control) { 171 ret = ltc294x_write_regs(info->client, 172 LTC294X_REG_CONTROL, &control, 1); 173 if (ret < 0) { 174 dev_err(&info->client->dev, 175 "Could not write register\n"); 176 goto error_exit; 177 } 178 } 179 180 return 0; 181 182 error_exit: 183 return ret; 184 } 185 186 static int ltc294x_read_charge_register(const struct ltc294x_info *info, 187 enum ltc294x_reg reg) 188 { 189 int ret; 190 u8 datar[2]; 191 192 ret = ltc294x_read_regs(info->client, reg, &datar[0], 2); 193 if (ret < 0) 194 return ret; 195 return (datar[0] << 8) + datar[1]; 196 } 197 198 static int ltc294x_get_charge(const struct ltc294x_info *info, 199 enum ltc294x_reg reg, int *val) 200 { 201 int value = ltc294x_read_charge_register(info, reg); 202 203 if (value < 0) 204 return value; 205 /* When r_sense < 0, this counts up when the battery discharges */ 206 if (info->Qlsb < 0) 207 value -= 0xFFFF; 208 *val = convert_bin_to_uAh(info, value); 209 return 0; 210 } 211 212 static int ltc294x_set_charge_now(const struct ltc294x_info *info, int val) 213 { 214 int ret; 215 u8 dataw[2]; 216 u8 ctrl_reg; 217 s32 value; 218 219 value = convert_uAh_to_bin(info, val); 220 /* Direction depends on how sense+/- were connected */ 221 if (info->Qlsb < 0) 222 value += 0xFFFF; 223 if ((value < 0) || (value > 0xFFFF)) /* input validation */ 224 return -EINVAL; 225 226 /* Read control register */ 227 ret = ltc294x_read_regs(info->client, 228 LTC294X_REG_CONTROL, &ctrl_reg, 1); 229 if (ret < 0) 230 return ret; 231 /* Disable analog section */ 232 ctrl_reg |= LTC294X_REG_CONTROL_SHUTDOWN_MASK; 233 ret = ltc294x_write_regs(info->client, 234 LTC294X_REG_CONTROL, &ctrl_reg, 1); 235 if (ret < 0) 236 return ret; 237 /* Set new charge value */ 238 dataw[0] = I16_MSB(value); 239 dataw[1] = I16_LSB(value); 240 ret = ltc294x_write_regs(info->client, 241 LTC294X_REG_ACC_CHARGE_MSB, &dataw[0], 2); 242 if (ret < 0) 243 goto error_exit; 244 /* Enable analog section */ 245 error_exit: 246 ctrl_reg &= ~LTC294X_REG_CONTROL_SHUTDOWN_MASK; 247 ret = ltc294x_write_regs(info->client, 248 LTC294X_REG_CONTROL, &ctrl_reg, 1); 249 250 return ret < 0 ? ret : 0; 251 } 252 253 static int ltc294x_set_charge_thr(const struct ltc294x_info *info, 254 enum ltc294x_reg reg, int val) 255 { 256 u8 dataw[2]; 257 s32 value; 258 259 value = convert_uAh_to_bin(info, val); 260 /* Direction depends on how sense+/- were connected */ 261 if (info->Qlsb < 0) 262 value += 0xFFFF; 263 if ((value < 0) || (value > 0xFFFF)) /* input validation */ 264 return -EINVAL; 265 266 /* Set new charge value */ 267 dataw[0] = I16_MSB(value); 268 dataw[1] = I16_LSB(value); 269 return ltc294x_write_regs(info->client, reg, &dataw[0], 2); 270 } 271 272 static int ltc294x_get_charge_counter( 273 const struct ltc294x_info *info, int *val) 274 { 275 int value = ltc294x_read_charge_register(info, LTC294X_REG_ACC_CHARGE_MSB); 276 277 if (value < 0) 278 return value; 279 value -= LTC294X_MID_SUPPLY; 280 *val = convert_bin_to_uAh(info, value); 281 return 0; 282 } 283 284 static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val) 285 { 286 int ret; 287 u8 datar[2]; 288 u32 value; 289 290 ret = ltc294x_read_regs(info->client, 291 LTC294X_REG_VOLTAGE_MSB, &datar[0], 2); 292 value = (datar[0] << 8) | datar[1]; 293 switch (info->id) { 294 case LTC2943_ID: 295 value *= 23600 * 2; 296 value /= 0xFFFF; 297 value *= 1000 / 2; 298 break; 299 case LTC2944_ID: 300 value *= 70800 / 5*4; 301 value /= 0xFFFF; 302 value *= 1000 * 5/4; 303 break; 304 default: 305 value *= 6000 * 10; 306 value /= 0xFFFF; 307 value *= 1000 / 10; 308 break; 309 } 310 *val = value; 311 return ret; 312 } 313 314 static int ltc294x_get_current(const struct ltc294x_info *info, int *val) 315 { 316 int ret; 317 u8 datar[2]; 318 s32 value; 319 320 ret = ltc294x_read_regs(info->client, 321 LTC2943_REG_CURRENT_MSB, &datar[0], 2); 322 value = (datar[0] << 8) | datar[1]; 323 value -= 0x7FFF; 324 if (info->id == LTC2944_ID) 325 value *= 64000; 326 else 327 value *= 60000; 328 /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm, 329 * the formula below keeps everything in s32 range while preserving 330 * enough digits */ 331 *val = 1000 * (value / (info->r_sense * 0x7FFF)); /* in uA */ 332 return ret; 333 } 334 335 static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val) 336 { 337 enum ltc294x_reg reg; 338 int ret; 339 u8 datar[2]; 340 u32 value; 341 342 if (info->id == LTC2942_ID) { 343 reg = LTC2942_REG_TEMPERATURE_MSB; 344 value = 6000; /* Full-scale is 600 Kelvin */ 345 } else { 346 reg = LTC2943_REG_TEMPERATURE_MSB; 347 value = 5100; /* Full-scale is 510 Kelvin */ 348 } 349 ret = ltc294x_read_regs(info->client, reg, &datar[0], 2); 350 value *= (datar[0] << 8) | datar[1]; 351 /* Convert to tenths of degree Celsius */ 352 *val = value / 0xFFFF - 2722; 353 return ret; 354 } 355 356 static int ltc294x_get_property(struct power_supply *psy, 357 enum power_supply_property prop, 358 union power_supply_propval *val) 359 { 360 struct ltc294x_info *info = power_supply_get_drvdata(psy); 361 362 switch (prop) { 363 case POWER_SUPPLY_PROP_CHARGE_FULL: 364 return ltc294x_get_charge(info, LTC294X_REG_CHARGE_THR_HIGH_MSB, 365 &val->intval); 366 case POWER_SUPPLY_PROP_CHARGE_EMPTY: 367 return ltc294x_get_charge(info, LTC294X_REG_CHARGE_THR_LOW_MSB, 368 &val->intval); 369 case POWER_SUPPLY_PROP_CHARGE_NOW: 370 return ltc294x_get_charge(info, LTC294X_REG_ACC_CHARGE_MSB, 371 &val->intval); 372 case POWER_SUPPLY_PROP_CHARGE_COUNTER: 373 return ltc294x_get_charge_counter(info, &val->intval); 374 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 375 return ltc294x_get_voltage(info, &val->intval); 376 case POWER_SUPPLY_PROP_CURRENT_NOW: 377 return ltc294x_get_current(info, &val->intval); 378 case POWER_SUPPLY_PROP_TEMP: 379 return ltc294x_get_temperature(info, &val->intval); 380 default: 381 return -EINVAL; 382 } 383 } 384 385 static int ltc294x_set_property(struct power_supply *psy, 386 enum power_supply_property psp, 387 const union power_supply_propval *val) 388 { 389 struct ltc294x_info *info = power_supply_get_drvdata(psy); 390 391 switch (psp) { 392 case POWER_SUPPLY_PROP_CHARGE_FULL: 393 return ltc294x_set_charge_thr(info, 394 LTC294X_REG_CHARGE_THR_HIGH_MSB, val->intval); 395 case POWER_SUPPLY_PROP_CHARGE_EMPTY: 396 return ltc294x_set_charge_thr(info, 397 LTC294X_REG_CHARGE_THR_LOW_MSB, val->intval); 398 case POWER_SUPPLY_PROP_CHARGE_NOW: 399 return ltc294x_set_charge_now(info, val->intval); 400 default: 401 return -EPERM; 402 } 403 } 404 405 static int ltc294x_property_is_writeable( 406 struct power_supply *psy, enum power_supply_property psp) 407 { 408 switch (psp) { 409 case POWER_SUPPLY_PROP_CHARGE_FULL: 410 case POWER_SUPPLY_PROP_CHARGE_EMPTY: 411 case POWER_SUPPLY_PROP_CHARGE_NOW: 412 return 1; 413 default: 414 return 0; 415 } 416 } 417 418 static void ltc294x_update(struct ltc294x_info *info) 419 { 420 int charge = ltc294x_read_charge_register(info, LTC294X_REG_ACC_CHARGE_MSB); 421 422 if (charge != info->charge) { 423 info->charge = charge; 424 power_supply_changed(info->supply); 425 } 426 } 427 428 static void ltc294x_work(struct work_struct *work) 429 { 430 struct ltc294x_info *info; 431 432 info = container_of(work, struct ltc294x_info, work.work); 433 ltc294x_update(info); 434 schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); 435 } 436 437 static enum power_supply_property ltc294x_properties[] = { 438 POWER_SUPPLY_PROP_CHARGE_COUNTER, 439 POWER_SUPPLY_PROP_CHARGE_FULL, 440 POWER_SUPPLY_PROP_CHARGE_EMPTY, 441 POWER_SUPPLY_PROP_CHARGE_NOW, 442 POWER_SUPPLY_PROP_VOLTAGE_NOW, 443 POWER_SUPPLY_PROP_TEMP, 444 POWER_SUPPLY_PROP_CURRENT_NOW, 445 }; 446 447 static int ltc294x_i2c_remove(struct i2c_client *client) 448 { 449 struct ltc294x_info *info = i2c_get_clientdata(client); 450 451 cancel_delayed_work(&info->work); 452 power_supply_unregister(info->supply); 453 return 0; 454 } 455 456 static int ltc294x_i2c_probe(struct i2c_client *client, 457 const struct i2c_device_id *id) 458 { 459 struct power_supply_config psy_cfg = {}; 460 struct ltc294x_info *info; 461 struct device_node *np; 462 int ret; 463 u32 prescaler_exp; 464 s32 r_sense; 465 u8 status; 466 467 info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); 468 if (info == NULL) 469 return -ENOMEM; 470 471 i2c_set_clientdata(client, info); 472 473 np = of_node_get(client->dev.of_node); 474 475 info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev); 476 info->supply_desc.name = np->name; 477 478 /* r_sense can be negative, when sense+ is connected to the battery 479 * instead of the sense-. This results in reversed measurements. */ 480 ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense); 481 if (ret < 0) { 482 dev_err(&client->dev, 483 "Could not find lltc,resistor-sense in devicetree\n"); 484 return ret; 485 } 486 info->r_sense = r_sense; 487 488 ret = of_property_read_u32(np, "lltc,prescaler-exponent", 489 &prescaler_exp); 490 if (ret < 0) { 491 dev_warn(&client->dev, 492 "lltc,prescaler-exponent not in devicetree\n"); 493 prescaler_exp = LTC2941_MAX_PRESCALER_EXP; 494 } 495 496 if (info->id == LTC2943_ID) { 497 if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP) 498 prescaler_exp = LTC2943_MAX_PRESCALER_EXP; 499 info->Qlsb = ((340 * 50000) / r_sense) / 500 (4096 / (1 << (2*prescaler_exp))); 501 } else { 502 if (prescaler_exp > LTC2941_MAX_PRESCALER_EXP) 503 prescaler_exp = LTC2941_MAX_PRESCALER_EXP; 504 info->Qlsb = ((85 * 50000) / r_sense) / 505 (128 / (1 << prescaler_exp)); 506 } 507 508 /* Read status register to check for LTC2942 */ 509 if (info->id == LTC2941_ID || info->id == LTC2942_ID) { 510 ret = ltc294x_read_regs(client, LTC294X_REG_STATUS, &status, 1); 511 if (ret < 0) { 512 dev_err(&client->dev, 513 "Could not read status register\n"); 514 return ret; 515 } 516 if (status & LTC2941_REG_STATUS_CHIP_ID) 517 info->id = LTC2941_ID; 518 else 519 info->id = LTC2942_ID; 520 } 521 522 info->client = client; 523 info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; 524 info->supply_desc.properties = ltc294x_properties; 525 switch (info->id) { 526 case LTC2944_ID: 527 case LTC2943_ID: 528 info->supply_desc.num_properties = 529 ARRAY_SIZE(ltc294x_properties); 530 break; 531 case LTC2942_ID: 532 info->supply_desc.num_properties = 533 ARRAY_SIZE(ltc294x_properties) - 1; 534 break; 535 case LTC2941_ID: 536 default: 537 info->supply_desc.num_properties = 538 ARRAY_SIZE(ltc294x_properties) - 3; 539 break; 540 } 541 info->supply_desc.get_property = ltc294x_get_property; 542 info->supply_desc.set_property = ltc294x_set_property; 543 info->supply_desc.property_is_writeable = ltc294x_property_is_writeable; 544 info->supply_desc.external_power_changed = NULL; 545 546 psy_cfg.drv_data = info; 547 548 INIT_DELAYED_WORK(&info->work, ltc294x_work); 549 550 ret = ltc294x_reset(info, prescaler_exp); 551 if (ret < 0) { 552 dev_err(&client->dev, "Communication with chip failed\n"); 553 return ret; 554 } 555 556 info->supply = power_supply_register(&client->dev, &info->supply_desc, 557 &psy_cfg); 558 if (IS_ERR(info->supply)) { 559 dev_err(&client->dev, "failed to register ltc2941\n"); 560 return PTR_ERR(info->supply); 561 } else { 562 schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); 563 } 564 565 return 0; 566 } 567 568 static void ltc294x_i2c_shutdown(struct i2c_client *client) 569 { 570 struct ltc294x_info *info = i2c_get_clientdata(client); 571 int ret; 572 u8 value; 573 u8 control; 574 575 /* The LTC2941 does not need any special handling */ 576 if (info->id == LTC2941_ID) 577 return; 578 579 /* Read control register */ 580 ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1); 581 if (ret < 0) 582 return; 583 584 /* Disable continuous ADC conversion as this drains the battery */ 585 control = LTC294X_REG_CONTROL_ADC_DISABLE(value); 586 if (control != value) 587 ltc294x_write_regs(info->client, LTC294X_REG_CONTROL, 588 &control, 1); 589 } 590 591 #ifdef CONFIG_PM_SLEEP 592 593 static int ltc294x_suspend(struct device *dev) 594 { 595 struct i2c_client *client = to_i2c_client(dev); 596 struct ltc294x_info *info = i2c_get_clientdata(client); 597 598 cancel_delayed_work(&info->work); 599 return 0; 600 } 601 602 static int ltc294x_resume(struct device *dev) 603 { 604 struct i2c_client *client = to_i2c_client(dev); 605 struct ltc294x_info *info = i2c_get_clientdata(client); 606 607 schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); 608 return 0; 609 } 610 611 static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume); 612 #define LTC294X_PM_OPS (<c294x_pm_ops) 613 614 #else 615 #define LTC294X_PM_OPS NULL 616 #endif /* CONFIG_PM_SLEEP */ 617 618 619 static const struct i2c_device_id ltc294x_i2c_id[] = { 620 { "ltc2941", LTC2941_ID, }, 621 { "ltc2942", LTC2942_ID, }, 622 { "ltc2943", LTC2943_ID, }, 623 { "ltc2944", LTC2944_ID, }, 624 { }, 625 }; 626 MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id); 627 628 static const struct of_device_id ltc294x_i2c_of_match[] = { 629 { 630 .compatible = "lltc,ltc2941", 631 .data = (void *)LTC2941_ID, 632 }, 633 { 634 .compatible = "lltc,ltc2942", 635 .data = (void *)LTC2942_ID, 636 }, 637 { 638 .compatible = "lltc,ltc2943", 639 .data = (void *)LTC2943_ID, 640 }, 641 { 642 .compatible = "lltc,ltc2944", 643 .data = (void *)LTC2944_ID, 644 }, 645 { }, 646 }; 647 MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match); 648 649 static struct i2c_driver ltc294x_driver = { 650 .driver = { 651 .name = "LTC2941", 652 .of_match_table = ltc294x_i2c_of_match, 653 .pm = LTC294X_PM_OPS, 654 }, 655 .probe = ltc294x_i2c_probe, 656 .remove = ltc294x_i2c_remove, 657 .shutdown = ltc294x_i2c_shutdown, 658 .id_table = ltc294x_i2c_id, 659 }; 660 module_i2c_driver(ltc294x_driver); 661 662 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems"); 663 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products"); 664 MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver"); 665 MODULE_LICENSE("GPL"); 666