1/* 2 * DA9150 Fuel-Gauge Driver 3 * 4 * Copyright (c) 2015 Dialog Semiconductor 5 * 6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/platform_device.h> 17#include <linux/of.h> 18#include <linux/of_platform.h> 19#include <linux/slab.h> 20#include <linux/interrupt.h> 21#include <linux/delay.h> 22#include <linux/power_supply.h> 23#include <linux/list.h> 24#include <asm/div64.h> 25#include <linux/mfd/da9150/core.h> 26#include <linux/mfd/da9150/registers.h> 27 28/* Core2Wire */ 29#define DA9150_QIF_READ (0x0 << 7) 30#define DA9150_QIF_WRITE (0x1 << 7) 31#define DA9150_QIF_CODE_MASK 0x7F 32 33#define DA9150_QIF_BYTE_SIZE 8 34#define DA9150_QIF_BYTE_MASK 0xFF 35#define DA9150_QIF_SHORT_SIZE 2 36#define DA9150_QIF_LONG_SIZE 4 37 38/* QIF Codes */ 39#define DA9150_QIF_UAVG 6 40#define DA9150_QIF_UAVG_SIZE DA9150_QIF_LONG_SIZE 41#define DA9150_QIF_IAVG 8 42#define DA9150_QIF_IAVG_SIZE DA9150_QIF_LONG_SIZE 43#define DA9150_QIF_NTCAVG 12 44#define DA9150_QIF_NTCAVG_SIZE DA9150_QIF_LONG_SIZE 45#define DA9150_QIF_SHUNT_VAL 36 46#define DA9150_QIF_SHUNT_VAL_SIZE DA9150_QIF_SHORT_SIZE 47#define DA9150_QIF_SD_GAIN 38 48#define DA9150_QIF_SD_GAIN_SIZE DA9150_QIF_LONG_SIZE 49#define DA9150_QIF_FCC_MAH 40 50#define DA9150_QIF_FCC_MAH_SIZE DA9150_QIF_SHORT_SIZE 51#define DA9150_QIF_SOC_PCT 43 52#define DA9150_QIF_SOC_PCT_SIZE DA9150_QIF_SHORT_SIZE 53#define DA9150_QIF_CHARGE_LIMIT 44 54#define DA9150_QIF_CHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE 55#define DA9150_QIF_DISCHARGE_LIMIT 45 56#define DA9150_QIF_DISCHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE 57#define DA9150_QIF_FW_MAIN_VER 118 58#define DA9150_QIF_FW_MAIN_VER_SIZE DA9150_QIF_SHORT_SIZE 59#define DA9150_QIF_E_FG_STATUS 126 60#define DA9150_QIF_E_FG_STATUS_SIZE DA9150_QIF_SHORT_SIZE 61#define DA9150_QIF_SYNC 127 62#define DA9150_QIF_SYNC_SIZE DA9150_QIF_SHORT_SIZE 63#define DA9150_QIF_MAX_CODES 128 64 65/* QIF Sync Timeout */ 66#define DA9150_QIF_SYNC_TIMEOUT 1000 67#define DA9150_QIF_SYNC_RETRIES 10 68 69/* QIF E_FG_STATUS */ 70#define DA9150_FG_IRQ_LOW_SOC_MASK (1 << 0) 71#define DA9150_FG_IRQ_HIGH_SOC_MASK (1 << 1) 72#define DA9150_FG_IRQ_SOC_MASK \ 73 (DA9150_FG_IRQ_LOW_SOC_MASK | DA9150_FG_IRQ_HIGH_SOC_MASK) 74 75/* Private data */ 76struct da9150_fg { 77 struct da9150 *da9150; 78 struct device *dev; 79 80 struct mutex io_lock; 81 82 struct power_supply *battery; 83 struct delayed_work work; 84 u32 interval; 85 86 int warn_soc; 87 int crit_soc; 88 int soc; 89}; 90 91/* Battery Properties */ 92static u32 da9150_fg_read_attr(struct da9150_fg *fg, u8 code, u8 size) 93 94{ 95 u8 buf[size]; 96 u8 read_addr; 97 u32 res = 0; 98 int i; 99 100 /* Set QIF code (READ mode) */ 101 read_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_READ; 102 103 da9150_read_qif(fg->da9150, read_addr, size, buf); 104 for (i = 0; i < size; ++i) 105 res |= (buf[i] << (i * DA9150_QIF_BYTE_SIZE)); 106 107 return res; 108} 109 110static void da9150_fg_write_attr(struct da9150_fg *fg, u8 code, u8 size, 111 u32 val) 112 113{ 114 u8 buf[size]; 115 u8 write_addr; 116 int i; 117 118 /* Set QIF code (WRITE mode) */ 119 write_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_WRITE; 120 121 for (i = 0; i < size; ++i) { 122 buf[i] = (val >> (i * DA9150_QIF_BYTE_SIZE)) & 123 DA9150_QIF_BYTE_MASK; 124 } 125 da9150_write_qif(fg->da9150, write_addr, size, buf); 126} 127 128/* Trigger QIF Sync to update QIF readable data */ 129static void da9150_fg_read_sync_start(struct da9150_fg *fg) 130{ 131 int i = 0; 132 u32 res = 0; 133 134 mutex_lock(&fg->io_lock); 135 136 /* Check if QIF sync already requested, and write to sync if not */ 137 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, 138 DA9150_QIF_SYNC_SIZE); 139 if (res > 0) 140 da9150_fg_write_attr(fg, DA9150_QIF_SYNC, 141 DA9150_QIF_SYNC_SIZE, 0); 142 143 /* Wait for sync to complete */ 144 res = 0; 145 while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) { 146 usleep_range(DA9150_QIF_SYNC_TIMEOUT, 147 DA9150_QIF_SYNC_TIMEOUT * 2); 148 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, 149 DA9150_QIF_SYNC_SIZE); 150 } 151 152 /* Check if sync completed */ 153 if (res == 0) 154 dev_err(fg->dev, "Failed to perform QIF read sync!\n"); 155} 156 157/* 158 * Should always be called after QIF sync read has been performed, and all 159 * attributes required have been accessed. 160 */ 161static inline void da9150_fg_read_sync_end(struct da9150_fg *fg) 162{ 163 mutex_unlock(&fg->io_lock); 164} 165 166/* Sync read of single QIF attribute */ 167static u32 da9150_fg_read_attr_sync(struct da9150_fg *fg, u8 code, u8 size) 168{ 169 u32 val; 170 171 da9150_fg_read_sync_start(fg); 172 val = da9150_fg_read_attr(fg, code, size); 173 da9150_fg_read_sync_end(fg); 174 175 return val; 176} 177 178/* Wait for QIF Sync, write QIF data and wait for ack */ 179static void da9150_fg_write_attr_sync(struct da9150_fg *fg, u8 code, u8 size, 180 u32 val) 181{ 182 int i = 0; 183 u32 res = 0, sync_val; 184 185 mutex_lock(&fg->io_lock); 186 187 /* Check if QIF sync already requested */ 188 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, 189 DA9150_QIF_SYNC_SIZE); 190 191 /* Wait for an existing sync to complete */ 192 while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) { 193 usleep_range(DA9150_QIF_SYNC_TIMEOUT, 194 DA9150_QIF_SYNC_TIMEOUT * 2); 195 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, 196 DA9150_QIF_SYNC_SIZE); 197 } 198 199 if (res == 0) { 200 dev_err(fg->dev, "Timeout waiting for existing QIF sync!\n"); 201 mutex_unlock(&fg->io_lock); 202 return; 203 } 204 205 /* Write value for QIF code */ 206 da9150_fg_write_attr(fg, code, size, val); 207 208 /* Wait for write acknowledgment */ 209 i = 0; 210 sync_val = res; 211 while ((res == sync_val) && (i++ < DA9150_QIF_SYNC_RETRIES)) { 212 usleep_range(DA9150_QIF_SYNC_TIMEOUT, 213 DA9150_QIF_SYNC_TIMEOUT * 2); 214 res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, 215 DA9150_QIF_SYNC_SIZE); 216 } 217 218 mutex_unlock(&fg->io_lock); 219 220 /* Check write was actually successful */ 221 if (res != (sync_val + 1)) 222 dev_err(fg->dev, "Error performing QIF sync write for code %d\n", 223 code); 224} 225 226/* Power Supply attributes */ 227static int da9150_fg_capacity(struct da9150_fg *fg, 228 union power_supply_propval *val) 229{ 230 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT, 231 DA9150_QIF_SOC_PCT_SIZE); 232 233 if (val->intval > 100) 234 val->intval = 100; 235 236 return 0; 237} 238 239static int da9150_fg_current_avg(struct da9150_fg *fg, 240 union power_supply_propval *val) 241{ 242 u32 iavg, sd_gain, shunt_val; 243 u64 div, res; 244 245 da9150_fg_read_sync_start(fg); 246 iavg = da9150_fg_read_attr(fg, DA9150_QIF_IAVG, 247 DA9150_QIF_IAVG_SIZE); 248 shunt_val = da9150_fg_read_attr(fg, DA9150_QIF_SHUNT_VAL, 249 DA9150_QIF_SHUNT_VAL_SIZE); 250 sd_gain = da9150_fg_read_attr(fg, DA9150_QIF_SD_GAIN, 251 DA9150_QIF_SD_GAIN_SIZE); 252 da9150_fg_read_sync_end(fg); 253 254 div = (u64) (sd_gain * shunt_val * 65536ULL); 255 do_div(div, 1000000); 256 res = (u64) (iavg * 1000000ULL); 257 do_div(res, div); 258 259 val->intval = (int) res; 260 261 return 0; 262} 263 264static int da9150_fg_voltage_avg(struct da9150_fg *fg, 265 union power_supply_propval *val) 266{ 267 u64 res; 268 269 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_UAVG, 270 DA9150_QIF_UAVG_SIZE); 271 272 res = (u64) (val->intval * 186ULL); 273 do_div(res, 10000); 274 val->intval = (int) res; 275 276 return 0; 277} 278 279static int da9150_fg_charge_full(struct da9150_fg *fg, 280 union power_supply_propval *val) 281{ 282 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_FCC_MAH, 283 DA9150_QIF_FCC_MAH_SIZE); 284 285 val->intval = val->intval * 1000; 286 287 return 0; 288} 289 290/* 291 * Temperature reading from device is only valid if battery/system provides 292 * valid NTC to associated pin of DA9150 chip. 293 */ 294static int da9150_fg_temp(struct da9150_fg *fg, 295 union power_supply_propval *val) 296{ 297 val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_NTCAVG, 298 DA9150_QIF_NTCAVG_SIZE); 299 300 val->intval = (val->intval * 10) / 1048576; 301 302 return 0; 303} 304 305static enum power_supply_property da9150_fg_props[] = { 306 POWER_SUPPLY_PROP_CAPACITY, 307 POWER_SUPPLY_PROP_CURRENT_AVG, 308 POWER_SUPPLY_PROP_VOLTAGE_AVG, 309 POWER_SUPPLY_PROP_CHARGE_FULL, 310 POWER_SUPPLY_PROP_TEMP, 311}; 312 313static int da9150_fg_get_prop(struct power_supply *psy, 314 enum power_supply_property psp, 315 union power_supply_propval *val) 316{ 317 struct da9150_fg *fg = dev_get_drvdata(psy->dev.parent); 318 int ret; 319 320 switch (psp) { 321 case POWER_SUPPLY_PROP_CAPACITY: 322 ret = da9150_fg_capacity(fg, val); 323 break; 324 case POWER_SUPPLY_PROP_CURRENT_AVG: 325 ret = da9150_fg_current_avg(fg, val); 326 break; 327 case POWER_SUPPLY_PROP_VOLTAGE_AVG: 328 ret = da9150_fg_voltage_avg(fg, val); 329 break; 330 case POWER_SUPPLY_PROP_CHARGE_FULL: 331 ret = da9150_fg_charge_full(fg, val); 332 break; 333 case POWER_SUPPLY_PROP_TEMP: 334 ret = da9150_fg_temp(fg, val); 335 break; 336 default: 337 ret = -EINVAL; 338 break; 339 } 340 341 return ret; 342} 343 344/* Repeated SOC check */ 345static bool da9150_fg_soc_changed(struct da9150_fg *fg) 346{ 347 union power_supply_propval val; 348 349 da9150_fg_capacity(fg, &val); 350 if (val.intval != fg->soc) { 351 fg->soc = val.intval; 352 return true; 353 } 354 355 return false; 356} 357 358static void da9150_fg_work(struct work_struct *work) 359{ 360 struct da9150_fg *fg = container_of(work, struct da9150_fg, work.work); 361 362 /* Report if SOC has changed */ 363 if (da9150_fg_soc_changed(fg)) 364 power_supply_changed(fg->battery); 365 366 schedule_delayed_work(&fg->work, msecs_to_jiffies(fg->interval)); 367} 368 369/* SOC level event configuration */ 370static void da9150_fg_soc_event_config(struct da9150_fg *fg) 371{ 372 int soc; 373 374 soc = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT, 375 DA9150_QIF_SOC_PCT_SIZE); 376 377 if (soc > fg->warn_soc) { 378 /* If SOC > warn level, set discharge warn level event */ 379 da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT, 380 DA9150_QIF_DISCHARGE_LIMIT_SIZE, 381 fg->warn_soc + 1); 382 } else if ((soc <= fg->warn_soc) && (soc > fg->crit_soc)) { 383 /* 384 * If SOC <= warn level, set discharge crit level event, 385 * and set charge warn level event. 386 */ 387 da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT, 388 DA9150_QIF_DISCHARGE_LIMIT_SIZE, 389 fg->crit_soc + 1); 390 391 da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT, 392 DA9150_QIF_CHARGE_LIMIT_SIZE, 393 fg->warn_soc); 394 } else if (soc <= fg->crit_soc) { 395 /* If SOC <= crit level, set charge crit level event */ 396 da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT, 397 DA9150_QIF_CHARGE_LIMIT_SIZE, 398 fg->crit_soc); 399 } 400} 401 402static irqreturn_t da9150_fg_irq(int irq, void *data) 403{ 404 struct da9150_fg *fg = data; 405 u32 e_fg_status; 406 407 /* Read FG IRQ status info */ 408 e_fg_status = da9150_fg_read_attr(fg, DA9150_QIF_E_FG_STATUS, 409 DA9150_QIF_E_FG_STATUS_SIZE); 410 411 /* Handle warning/critical threhold events */ 412 if (e_fg_status & DA9150_FG_IRQ_SOC_MASK) 413 da9150_fg_soc_event_config(fg); 414 415 /* Clear any FG IRQs */ 416 da9150_fg_write_attr(fg, DA9150_QIF_E_FG_STATUS, 417 DA9150_QIF_E_FG_STATUS_SIZE, e_fg_status); 418 419 return IRQ_HANDLED; 420} 421 422static struct da9150_fg_pdata *da9150_fg_dt_pdata(struct device *dev) 423{ 424 struct device_node *fg_node = dev->of_node; 425 struct da9150_fg_pdata *pdata; 426 427 pdata = devm_kzalloc(dev, sizeof(struct da9150_fg_pdata), GFP_KERNEL); 428 if (!pdata) 429 return NULL; 430 431 of_property_read_u32(fg_node, "dlg,update-interval", 432 &pdata->update_interval); 433 of_property_read_u8(fg_node, "dlg,warn-soc-level", 434 &pdata->warn_soc_lvl); 435 of_property_read_u8(fg_node, "dlg,crit-soc-level", 436 &pdata->crit_soc_lvl); 437 438 return pdata; 439} 440 441static const struct power_supply_desc fg_desc = { 442 .name = "da9150-fg", 443 .type = POWER_SUPPLY_TYPE_BATTERY, 444 .properties = da9150_fg_props, 445 .num_properties = ARRAY_SIZE(da9150_fg_props), 446 .get_property = da9150_fg_get_prop, 447}; 448 449static int da9150_fg_probe(struct platform_device *pdev) 450{ 451 struct device *dev = &pdev->dev; 452 struct da9150 *da9150 = dev_get_drvdata(dev->parent); 453 struct da9150_fg_pdata *fg_pdata = dev_get_platdata(dev); 454 struct da9150_fg *fg; 455 int ver, irq, ret = 0; 456 457 fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL); 458 if (fg == NULL) 459 return -ENOMEM; 460 461 platform_set_drvdata(pdev, fg); 462 fg->da9150 = da9150; 463 fg->dev = dev; 464 465 mutex_init(&fg->io_lock); 466 467 /* Enable QIF */ 468 da9150_set_bits(da9150, DA9150_CORE2WIRE_CTRL_A, DA9150_FG_QIF_EN_MASK, 469 DA9150_FG_QIF_EN_MASK); 470 471 fg->battery = devm_power_supply_register(dev, &fg_desc, NULL); 472 if (IS_ERR(fg->battery)) { 473 ret = PTR_ERR(fg->battery); 474 return ret; 475 } 476 477 ver = da9150_fg_read_attr(fg, DA9150_QIF_FW_MAIN_VER, 478 DA9150_QIF_FW_MAIN_VER_SIZE); 479 dev_info(dev, "Version: 0x%x\n", ver); 480 481 /* Handle DT data if provided */ 482 if (dev->of_node) { 483 fg_pdata = da9150_fg_dt_pdata(dev); 484 dev->platform_data = fg_pdata; 485 } 486 487 /* Handle any pdata provided */ 488 if (fg_pdata) { 489 fg->interval = fg_pdata->update_interval; 490 491 if (fg_pdata->warn_soc_lvl > 100) 492 dev_warn(dev, "Invalid SOC warning level provided, Ignoring"); 493 else 494 fg->warn_soc = fg_pdata->warn_soc_lvl; 495 496 if ((fg_pdata->crit_soc_lvl > 100) || 497 (fg_pdata->crit_soc_lvl >= fg_pdata->warn_soc_lvl)) 498 dev_warn(dev, "Invalid SOC critical level provided, Ignoring"); 499 else 500 fg->crit_soc = fg_pdata->crit_soc_lvl; 501 502 503 } 504 505 /* Configure initial SOC level events */ 506 da9150_fg_soc_event_config(fg); 507 508 /* 509 * If an interval period has been provided then setup repeating 510 * work for reporting data updates. 511 */ 512 if (fg->interval) { 513 INIT_DELAYED_WORK(&fg->work, da9150_fg_work); 514 schedule_delayed_work(&fg->work, 515 msecs_to_jiffies(fg->interval)); 516 } 517 518 /* Register IRQ */ 519 irq = platform_get_irq_byname(pdev, "FG"); 520 if (irq < 0) { 521 dev_err(dev, "Failed to get IRQ FG: %d\n", irq); 522 ret = irq; 523 goto irq_fail; 524 } 525 526 ret = devm_request_threaded_irq(dev, irq, NULL, da9150_fg_irq, 527 IRQF_ONESHOT, "FG", fg); 528 if (ret) { 529 dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret); 530 goto irq_fail; 531 } 532 533 return 0; 534 535irq_fail: 536 if (fg->interval) 537 cancel_delayed_work(&fg->work); 538 539 return ret; 540} 541 542static int da9150_fg_remove(struct platform_device *pdev) 543{ 544 struct da9150_fg *fg = platform_get_drvdata(pdev); 545 546 if (fg->interval) 547 cancel_delayed_work(&fg->work); 548 549 return 0; 550} 551 552static int da9150_fg_resume(struct platform_device *pdev) 553{ 554 struct da9150_fg *fg = platform_get_drvdata(pdev); 555 556 /* 557 * Trigger SOC check to happen now so as to indicate any value change 558 * since last check before suspend. 559 */ 560 if (fg->interval) 561 flush_delayed_work(&fg->work); 562 563 return 0; 564} 565 566static struct platform_driver da9150_fg_driver = { 567 .driver = { 568 .name = "da9150-fuel-gauge", 569 }, 570 .probe = da9150_fg_probe, 571 .remove = da9150_fg_remove, 572 .resume = da9150_fg_resume, 573}; 574 575module_platform_driver(da9150_fg_driver); 576 577MODULE_DESCRIPTION("Fuel-Gauge Driver for DA9150"); 578MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>"); 579MODULE_LICENSE("GPL"); 580