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