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