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