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