root/drivers/power/supply/da9150-fg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. da9150_fg_read_attr
  2. da9150_fg_write_attr
  3. da9150_fg_read_sync_start
  4. da9150_fg_read_sync_end
  5. da9150_fg_read_attr_sync
  6. da9150_fg_write_attr_sync
  7. da9150_fg_capacity
  8. da9150_fg_current_avg
  9. da9150_fg_voltage_avg
  10. da9150_fg_charge_full
  11. da9150_fg_temp
  12. da9150_fg_get_prop
  13. da9150_fg_soc_changed
  14. da9150_fg_work
  15. da9150_fg_soc_event_config
  16. da9150_fg_irq
  17. da9150_fg_dt_pdata
  18. da9150_fg_probe
  19. da9150_fg_remove
  20. da9150_fg_resume

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

/* [<][>][^][v][top][bottom][index][help] */