linux/drivers/power/ds2780_battery.c
<<
>>
Prefs
   1/*
   2 * 1-wire client/driver for the Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC
   3 *
   4 * Copyright (C) 2010 Indesign, LLC
   5 *
   6 * Author: Clifton Barnes <cabarnes@indesign-llc.com>
   7 *
   8 * Based on ds2760_battery and ds2782_battery drivers
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/slab.h>
  18#include <linux/param.h>
  19#include <linux/pm.h>
  20#include <linux/platform_device.h>
  21#include <linux/power_supply.h>
  22#include <linux/idr.h>
  23
  24#include "../w1/w1.h"
  25#include "../w1/slaves/w1_ds2780.h"
  26
  27/* Current unit measurement in uA for a 1 milli-ohm sense resistor */
  28#define DS2780_CURRENT_UNITS    1563
  29/* Charge unit measurement in uAh for a 1 milli-ohm sense resistor */
  30#define DS2780_CHARGE_UNITS             6250
  31/* Number of bytes in user EEPROM space */
  32#define DS2780_USER_EEPROM_SIZE         (DS2780_EEPROM_BLOCK0_END - \
  33                                        DS2780_EEPROM_BLOCK0_START + 1)
  34/* Number of bytes in parameter EEPROM space */
  35#define DS2780_PARAM_EEPROM_SIZE        (DS2780_EEPROM_BLOCK1_END - \
  36                                        DS2780_EEPROM_BLOCK1_START + 1)
  37
  38struct ds2780_device_info {
  39        struct device *dev;
  40        struct power_supply bat;
  41        struct device *w1_dev;
  42};
  43
  44enum current_types {
  45        CURRENT_NOW,
  46        CURRENT_AVG,
  47};
  48
  49static const char model[] = "DS2780";
  50static const char manufacturer[] = "Maxim/Dallas";
  51
  52static inline struct ds2780_device_info *
  53to_ds2780_device_info(struct power_supply *psy)
  54{
  55        return container_of(psy, struct ds2780_device_info, bat);
  56}
  57
  58static inline struct power_supply *to_power_supply(struct device *dev)
  59{
  60        return dev_get_drvdata(dev);
  61}
  62
  63static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
  64        char *buf, int addr, size_t count, int io)
  65{
  66        return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
  67}
  68
  69static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val,
  70        int addr)
  71{
  72        return ds2780_battery_io(dev_info, val, addr, sizeof(u8), 0);
  73}
  74
  75static int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val,
  76        int addr)
  77{
  78        int ret;
  79        u8 raw[2];
  80
  81        ret = ds2780_battery_io(dev_info, raw, addr, sizeof(raw), 0);
  82        if (ret < 0)
  83                return ret;
  84
  85        *val = (raw[0] << 8) | raw[1];
  86
  87        return 0;
  88}
  89
  90static inline int ds2780_read_block(struct ds2780_device_info *dev_info,
  91        u8 *val, int addr, size_t count)
  92{
  93        return ds2780_battery_io(dev_info, val, addr, count, 0);
  94}
  95
  96static inline int ds2780_write(struct ds2780_device_info *dev_info, u8 *val,
  97        int addr, size_t count)
  98{
  99        return ds2780_battery_io(dev_info, val, addr, count, 1);
 100}
 101
 102static inline int ds2780_store_eeprom(struct device *dev, int addr)
 103{
 104        return w1_ds2780_eeprom_cmd(dev, addr, W1_DS2780_COPY_DATA);
 105}
 106
 107static inline int ds2780_recall_eeprom(struct device *dev, int addr)
 108{
 109        return w1_ds2780_eeprom_cmd(dev, addr, W1_DS2780_RECALL_DATA);
 110}
 111
 112static int ds2780_save_eeprom(struct ds2780_device_info *dev_info, int reg)
 113{
 114        int ret;
 115
 116        ret = ds2780_store_eeprom(dev_info->w1_dev, reg);
 117        if (ret < 0)
 118                return ret;
 119
 120        ret = ds2780_recall_eeprom(dev_info->w1_dev, reg);
 121        if (ret < 0)
 122                return ret;
 123
 124        return 0;
 125}
 126
 127/* Set sense resistor value in mhos */
 128static int ds2780_set_sense_register(struct ds2780_device_info *dev_info,
 129        u8 conductance)
 130{
 131        int ret;
 132
 133        ret = ds2780_write(dev_info, &conductance,
 134                                DS2780_RSNSP_REG, sizeof(u8));
 135        if (ret < 0)
 136                return ret;
 137
 138        return ds2780_save_eeprom(dev_info, DS2780_RSNSP_REG);
 139}
 140
 141/* Get RSGAIN value from 0 to 1.999 in steps of 0.001 */
 142static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info,
 143        u16 *rsgain)
 144{
 145        return ds2780_read16(dev_info, rsgain, DS2780_RSGAIN_MSB_REG);
 146}
 147
 148/* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */
 149static int ds2780_set_rsgain_register(struct ds2780_device_info *dev_info,
 150        u16 rsgain)
 151{
 152        int ret;
 153        u8 raw[] = {rsgain >> 8, rsgain & 0xFF};
 154
 155        ret = ds2780_write(dev_info, raw,
 156                                DS2780_RSGAIN_MSB_REG, sizeof(raw));
 157        if (ret < 0)
 158                return ret;
 159
 160        return ds2780_save_eeprom(dev_info, DS2780_RSGAIN_MSB_REG);
 161}
 162
 163static int ds2780_get_voltage(struct ds2780_device_info *dev_info,
 164        int *voltage_uV)
 165{
 166        int ret;
 167        s16 voltage_raw;
 168
 169        /*
 170         * The voltage value is located in 10 bits across the voltage MSB
 171         * and LSB registers in two's compliment form
 172         * Sign bit of the voltage value is in bit 7 of the voltage MSB register
 173         * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the
 174         * voltage MSB register
 175         * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
 176         * voltage LSB register
 177         */
 178        ret = ds2780_read16(dev_info, &voltage_raw,
 179                                DS2780_VOLT_MSB_REG);
 180        if (ret < 0)
 181                return ret;
 182
 183        /*
 184         * DS2780 reports voltage in units of 4.88mV, but the battery class
 185         * reports in units of uV, so convert by multiplying by 4880.
 186         */
 187        *voltage_uV = (voltage_raw / 32) * 4880;
 188        return 0;
 189}
 190
 191static int ds2780_get_temperature(struct ds2780_device_info *dev_info,
 192        int *temperature)
 193{
 194        int ret;
 195        s16 temperature_raw;
 196
 197        /*
 198         * The temperature value is located in 10 bits across the temperature
 199         * MSB and LSB registers in two's compliment form
 200         * Sign bit of the temperature value is in bit 7 of the temperature
 201         * MSB register
 202         * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the
 203         * temperature MSB register
 204         * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
 205         * temperature LSB register
 206         */
 207        ret = ds2780_read16(dev_info, &temperature_raw,
 208                                DS2780_TEMP_MSB_REG);
 209        if (ret < 0)
 210                return ret;
 211
 212        /*
 213         * Temperature is measured in units of 0.125 degrees celcius, the
 214         * power_supply class measures temperature in tenths of degrees
 215         * celsius. The temperature value is stored as a 10 bit number, plus
 216         * sign in the upper bits of a 16 bit register.
 217         */
 218        *temperature = ((temperature_raw / 32) * 125) / 100;
 219        return 0;
 220}
 221
 222static int ds2780_get_current(struct ds2780_device_info *dev_info,
 223        enum current_types type, int *current_uA)
 224{
 225        int ret, sense_res;
 226        s16 current_raw;
 227        u8 sense_res_raw, reg_msb;
 228
 229        /*
 230         * The units of measurement for current are dependent on the value of
 231         * the sense resistor.
 232         */
 233        ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
 234        if (ret < 0)
 235                return ret;
 236
 237        if (sense_res_raw == 0) {
 238                dev_err(dev_info->dev, "sense resistor value is 0\n");
 239                return -EINVAL;
 240        }
 241        sense_res = 1000 / sense_res_raw;
 242
 243        if (type == CURRENT_NOW)
 244                reg_msb = DS2780_CURRENT_MSB_REG;
 245        else if (type == CURRENT_AVG)
 246                reg_msb = DS2780_IAVG_MSB_REG;
 247        else
 248                return -EINVAL;
 249
 250        /*
 251         * The current value is located in 16 bits across the current MSB
 252         * and LSB registers in two's compliment form
 253         * Sign bit of the current value is in bit 7 of the current MSB register
 254         * Bits 14 - 8 of the current value are in bits 6 - 0 of the current
 255         * MSB register
 256         * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
 257         * LSB register
 258         */
 259        ret = ds2780_read16(dev_info, &current_raw, reg_msb);
 260        if (ret < 0)
 261                return ret;
 262
 263        *current_uA = current_raw * (DS2780_CURRENT_UNITS / sense_res);
 264        return 0;
 265}
 266
 267static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info,
 268        int *accumulated_current)
 269{
 270        int ret, sense_res;
 271        s16 current_raw;
 272        u8 sense_res_raw;
 273
 274        /*
 275         * The units of measurement for accumulated current are dependent on
 276         * the value of the sense resistor.
 277         */
 278        ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
 279        if (ret < 0)
 280                return ret;
 281
 282        if (sense_res_raw == 0) {
 283                dev_err(dev_info->dev, "sense resistor value is 0\n");
 284                return -ENXIO;
 285        }
 286        sense_res = 1000 / sense_res_raw;
 287
 288        /*
 289         * The ACR value is located in 16 bits across the ACR MSB and
 290         * LSB registers
 291         * Bits 15 - 8 of the ACR value are in bits 7 - 0 of the ACR
 292         * MSB register
 293         * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
 294         * LSB register
 295         */
 296        ret = ds2780_read16(dev_info, &current_raw, DS2780_ACR_MSB_REG);
 297        if (ret < 0)
 298                return ret;
 299
 300        *accumulated_current = current_raw * (DS2780_CHARGE_UNITS / sense_res);
 301        return 0;
 302}
 303
 304static int ds2780_get_capacity(struct ds2780_device_info *dev_info,
 305        int *capacity)
 306{
 307        int ret;
 308        u8 raw;
 309
 310        ret = ds2780_read8(dev_info, &raw, DS2780_RARC_REG);
 311        if (ret < 0)
 312                return ret;
 313
 314        *capacity = raw;
 315        return raw;
 316}
 317
 318static int ds2780_get_status(struct ds2780_device_info *dev_info, int *status)
 319{
 320        int ret, current_uA, capacity;
 321
 322        ret = ds2780_get_current(dev_info, CURRENT_NOW, &current_uA);
 323        if (ret < 0)
 324                return ret;
 325
 326        ret = ds2780_get_capacity(dev_info, &capacity);
 327        if (ret < 0)
 328                return ret;
 329
 330        if (capacity == 100)
 331                *status = POWER_SUPPLY_STATUS_FULL;
 332        else if (current_uA == 0)
 333                *status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 334        else if (current_uA < 0)
 335                *status = POWER_SUPPLY_STATUS_DISCHARGING;
 336        else
 337                *status = POWER_SUPPLY_STATUS_CHARGING;
 338
 339        return 0;
 340}
 341
 342static int ds2780_get_charge_now(struct ds2780_device_info *dev_info,
 343        int *charge_now)
 344{
 345        int ret;
 346        u16 charge_raw;
 347
 348        /*
 349         * The RAAC value is located in 16 bits across the RAAC MSB and
 350         * LSB registers
 351         * Bits 15 - 8 of the RAAC value are in bits 7 - 0 of the RAAC
 352         * MSB register
 353         * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
 354         * LSB register
 355         */
 356        ret = ds2780_read16(dev_info, &charge_raw, DS2780_RAAC_MSB_REG);
 357        if (ret < 0)
 358                return ret;
 359
 360        *charge_now = charge_raw * 1600;
 361        return 0;
 362}
 363
 364static int ds2780_get_control_register(struct ds2780_device_info *dev_info,
 365        u8 *control_reg)
 366{
 367        return ds2780_read8(dev_info, control_reg, DS2780_CONTROL_REG);
 368}
 369
 370static int ds2780_set_control_register(struct ds2780_device_info *dev_info,
 371        u8 control_reg)
 372{
 373        int ret;
 374
 375        ret = ds2780_write(dev_info, &control_reg,
 376                                DS2780_CONTROL_REG, sizeof(u8));
 377        if (ret < 0)
 378                return ret;
 379
 380        return ds2780_save_eeprom(dev_info, DS2780_CONTROL_REG);
 381}
 382
 383static int ds2780_battery_get_property(struct power_supply *psy,
 384        enum power_supply_property psp,
 385        union power_supply_propval *val)
 386{
 387        int ret = 0;
 388        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 389
 390        switch (psp) {
 391        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 392                ret = ds2780_get_voltage(dev_info, &val->intval);
 393                break;
 394
 395        case POWER_SUPPLY_PROP_TEMP:
 396                ret = ds2780_get_temperature(dev_info, &val->intval);
 397                break;
 398
 399        case POWER_SUPPLY_PROP_MODEL_NAME:
 400                val->strval = model;
 401                break;
 402
 403        case POWER_SUPPLY_PROP_MANUFACTURER:
 404                val->strval = manufacturer;
 405                break;
 406
 407        case POWER_SUPPLY_PROP_CURRENT_NOW:
 408                ret = ds2780_get_current(dev_info, CURRENT_NOW, &val->intval);
 409                break;
 410
 411        case POWER_SUPPLY_PROP_CURRENT_AVG:
 412                ret = ds2780_get_current(dev_info, CURRENT_AVG, &val->intval);
 413                break;
 414
 415        case POWER_SUPPLY_PROP_STATUS:
 416                ret = ds2780_get_status(dev_info, &val->intval);
 417                break;
 418
 419        case POWER_SUPPLY_PROP_CAPACITY:
 420                ret = ds2780_get_capacity(dev_info, &val->intval);
 421                break;
 422
 423        case POWER_SUPPLY_PROP_CHARGE_COUNTER:
 424                ret = ds2780_get_accumulated_current(dev_info, &val->intval);
 425                break;
 426
 427        case POWER_SUPPLY_PROP_CHARGE_NOW:
 428                ret = ds2780_get_charge_now(dev_info, &val->intval);
 429                break;
 430
 431        default:
 432                ret = -EINVAL;
 433        }
 434
 435        return ret;
 436}
 437
 438static enum power_supply_property ds2780_battery_props[] = {
 439        POWER_SUPPLY_PROP_STATUS,
 440        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 441        POWER_SUPPLY_PROP_TEMP,
 442        POWER_SUPPLY_PROP_MODEL_NAME,
 443        POWER_SUPPLY_PROP_MANUFACTURER,
 444        POWER_SUPPLY_PROP_CURRENT_NOW,
 445        POWER_SUPPLY_PROP_CURRENT_AVG,
 446        POWER_SUPPLY_PROP_CAPACITY,
 447        POWER_SUPPLY_PROP_CHARGE_COUNTER,
 448        POWER_SUPPLY_PROP_CHARGE_NOW,
 449};
 450
 451static ssize_t ds2780_get_pmod_enabled(struct device *dev,
 452        struct device_attribute *attr,
 453        char *buf)
 454{
 455        int ret;
 456        u8 control_reg;
 457        struct power_supply *psy = to_power_supply(dev);
 458        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 459
 460        /* Get power mode */
 461        ret = ds2780_get_control_register(dev_info, &control_reg);
 462        if (ret < 0)
 463                return ret;
 464
 465        return sprintf(buf, "%d\n",
 466                 !!(control_reg & DS2780_CONTROL_REG_PMOD));
 467}
 468
 469static ssize_t ds2780_set_pmod_enabled(struct device *dev,
 470        struct device_attribute *attr,
 471        const char *buf,
 472        size_t count)
 473{
 474        int ret;
 475        u8 control_reg, new_setting;
 476        struct power_supply *psy = to_power_supply(dev);
 477        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 478
 479        /* Set power mode */
 480        ret = ds2780_get_control_register(dev_info, &control_reg);
 481        if (ret < 0)
 482                return ret;
 483
 484        ret = kstrtou8(buf, 0, &new_setting);
 485        if (ret < 0)
 486                return ret;
 487
 488        if ((new_setting != 0) && (new_setting != 1)) {
 489                dev_err(dev_info->dev, "Invalid pmod setting (0 or 1)\n");
 490                return -EINVAL;
 491        }
 492
 493        if (new_setting)
 494                control_reg |= DS2780_CONTROL_REG_PMOD;
 495        else
 496                control_reg &= ~DS2780_CONTROL_REG_PMOD;
 497
 498        ret = ds2780_set_control_register(dev_info, control_reg);
 499        if (ret < 0)
 500                return ret;
 501
 502        return count;
 503}
 504
 505static ssize_t ds2780_get_sense_resistor_value(struct device *dev,
 506        struct device_attribute *attr,
 507        char *buf)
 508{
 509        int ret;
 510        u8 sense_resistor;
 511        struct power_supply *psy = to_power_supply(dev);
 512        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 513
 514        ret = ds2780_read8(dev_info, &sense_resistor, DS2780_RSNSP_REG);
 515        if (ret < 0)
 516                return ret;
 517
 518        ret = sprintf(buf, "%d\n", sense_resistor);
 519        return ret;
 520}
 521
 522static ssize_t ds2780_set_sense_resistor_value(struct device *dev,
 523        struct device_attribute *attr,
 524        const char *buf,
 525        size_t count)
 526{
 527        int ret;
 528        u8 new_setting;
 529        struct power_supply *psy = to_power_supply(dev);
 530        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 531
 532        ret = kstrtou8(buf, 0, &new_setting);
 533        if (ret < 0)
 534                return ret;
 535
 536        ret = ds2780_set_sense_register(dev_info, new_setting);
 537        if (ret < 0)
 538                return ret;
 539
 540        return count;
 541}
 542
 543static ssize_t ds2780_get_rsgain_setting(struct device *dev,
 544        struct device_attribute *attr,
 545        char *buf)
 546{
 547        int ret;
 548        u16 rsgain;
 549        struct power_supply *psy = to_power_supply(dev);
 550        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 551
 552        ret = ds2780_get_rsgain_register(dev_info, &rsgain);
 553        if (ret < 0)
 554                return ret;
 555
 556        return sprintf(buf, "%d\n", rsgain);
 557}
 558
 559static ssize_t ds2780_set_rsgain_setting(struct device *dev,
 560        struct device_attribute *attr,
 561        const char *buf,
 562        size_t count)
 563{
 564        int ret;
 565        u16 new_setting;
 566        struct power_supply *psy = to_power_supply(dev);
 567        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 568
 569        ret = kstrtou16(buf, 0, &new_setting);
 570        if (ret < 0)
 571                return ret;
 572
 573        /* Gain can only be from 0 to 1.999 in steps of .001 */
 574        if (new_setting > 1999) {
 575                dev_err(dev_info->dev, "Invalid rsgain setting (0 - 1999)\n");
 576                return -EINVAL;
 577        }
 578
 579        ret = ds2780_set_rsgain_register(dev_info, new_setting);
 580        if (ret < 0)
 581                return ret;
 582
 583        return count;
 584}
 585
 586static ssize_t ds2780_get_pio_pin(struct device *dev,
 587        struct device_attribute *attr,
 588        char *buf)
 589{
 590        int ret;
 591        u8 sfr;
 592        struct power_supply *psy = to_power_supply(dev);
 593        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 594
 595        ret = ds2780_read8(dev_info, &sfr, DS2780_SFR_REG);
 596        if (ret < 0)
 597                return ret;
 598
 599        ret = sprintf(buf, "%d\n", sfr & DS2780_SFR_REG_PIOSC);
 600        return ret;
 601}
 602
 603static ssize_t ds2780_set_pio_pin(struct device *dev,
 604        struct device_attribute *attr,
 605        const char *buf,
 606        size_t count)
 607{
 608        int ret;
 609        u8 new_setting;
 610        struct power_supply *psy = to_power_supply(dev);
 611        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 612
 613        ret = kstrtou8(buf, 0, &new_setting);
 614        if (ret < 0)
 615                return ret;
 616
 617        if ((new_setting != 0) && (new_setting != 1)) {
 618                dev_err(dev_info->dev, "Invalid pio_pin setting (0 or 1)\n");
 619                return -EINVAL;
 620        }
 621
 622        ret = ds2780_write(dev_info, &new_setting,
 623                                DS2780_SFR_REG, sizeof(u8));
 624        if (ret < 0)
 625                return ret;
 626
 627        return count;
 628}
 629
 630static ssize_t ds2780_read_param_eeprom_bin(struct file *filp,
 631                                struct kobject *kobj,
 632                                struct bin_attribute *bin_attr,
 633                                char *buf, loff_t off, size_t count)
 634{
 635        struct device *dev = container_of(kobj, struct device, kobj);
 636        struct power_supply *psy = to_power_supply(dev);
 637        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 638
 639        count = min_t(loff_t, count,
 640                DS2780_EEPROM_BLOCK1_END -
 641                DS2780_EEPROM_BLOCK1_START + 1 - off);
 642
 643        return ds2780_read_block(dev_info, buf,
 644                                DS2780_EEPROM_BLOCK1_START + off, count);
 645}
 646
 647static ssize_t ds2780_write_param_eeprom_bin(struct file *filp,
 648                                struct kobject *kobj,
 649                                struct bin_attribute *bin_attr,
 650                                char *buf, loff_t off, size_t count)
 651{
 652        struct device *dev = container_of(kobj, struct device, kobj);
 653        struct power_supply *psy = to_power_supply(dev);
 654        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 655        int ret;
 656
 657        count = min_t(loff_t, count,
 658                DS2780_EEPROM_BLOCK1_END -
 659                DS2780_EEPROM_BLOCK1_START + 1 - off);
 660
 661        ret = ds2780_write(dev_info, buf,
 662                                DS2780_EEPROM_BLOCK1_START + off, count);
 663        if (ret < 0)
 664                return ret;
 665
 666        ret = ds2780_save_eeprom(dev_info, DS2780_EEPROM_BLOCK1_START);
 667        if (ret < 0)
 668                return ret;
 669
 670        return count;
 671}
 672
 673static struct bin_attribute ds2780_param_eeprom_bin_attr = {
 674        .attr = {
 675                .name = "param_eeprom",
 676                .mode = S_IRUGO | S_IWUSR,
 677        },
 678        .size = DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1,
 679        .read = ds2780_read_param_eeprom_bin,
 680        .write = ds2780_write_param_eeprom_bin,
 681};
 682
 683static ssize_t ds2780_read_user_eeprom_bin(struct file *filp,
 684                                struct kobject *kobj,
 685                                struct bin_attribute *bin_attr,
 686                                char *buf, loff_t off, size_t count)
 687{
 688        struct device *dev = container_of(kobj, struct device, kobj);
 689        struct power_supply *psy = to_power_supply(dev);
 690        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 691
 692        count = min_t(loff_t, count,
 693                DS2780_EEPROM_BLOCK0_END -
 694                DS2780_EEPROM_BLOCK0_START + 1 - off);
 695
 696        return ds2780_read_block(dev_info, buf,
 697                                DS2780_EEPROM_BLOCK0_START + off, count);
 698}
 699
 700static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
 701                                struct kobject *kobj,
 702                                struct bin_attribute *bin_attr,
 703                                char *buf, loff_t off, size_t count)
 704{
 705        struct device *dev = container_of(kobj, struct device, kobj);
 706        struct power_supply *psy = to_power_supply(dev);
 707        struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
 708        int ret;
 709
 710        count = min_t(loff_t, count,
 711                DS2780_EEPROM_BLOCK0_END -
 712                DS2780_EEPROM_BLOCK0_START + 1 - off);
 713
 714        ret = ds2780_write(dev_info, buf,
 715                                DS2780_EEPROM_BLOCK0_START + off, count);
 716        if (ret < 0)
 717                return ret;
 718
 719        ret = ds2780_save_eeprom(dev_info, DS2780_EEPROM_BLOCK0_START);
 720        if (ret < 0)
 721                return ret;
 722
 723        return count;
 724}
 725
 726static struct bin_attribute ds2780_user_eeprom_bin_attr = {
 727        .attr = {
 728                .name = "user_eeprom",
 729                .mode = S_IRUGO | S_IWUSR,
 730        },
 731        .size = DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1,
 732        .read = ds2780_read_user_eeprom_bin,
 733        .write = ds2780_write_user_eeprom_bin,
 734};
 735
 736static DEVICE_ATTR(pmod_enabled, S_IRUGO | S_IWUSR, ds2780_get_pmod_enabled,
 737        ds2780_set_pmod_enabled);
 738static DEVICE_ATTR(sense_resistor_value, S_IRUGO | S_IWUSR,
 739        ds2780_get_sense_resistor_value, ds2780_set_sense_resistor_value);
 740static DEVICE_ATTR(rsgain_setting, S_IRUGO | S_IWUSR, ds2780_get_rsgain_setting,
 741        ds2780_set_rsgain_setting);
 742static DEVICE_ATTR(pio_pin, S_IRUGO | S_IWUSR, ds2780_get_pio_pin,
 743        ds2780_set_pio_pin);
 744
 745
 746static struct attribute *ds2780_attributes[] = {
 747        &dev_attr_pmod_enabled.attr,
 748        &dev_attr_sense_resistor_value.attr,
 749        &dev_attr_rsgain_setting.attr,
 750        &dev_attr_pio_pin.attr,
 751        NULL
 752};
 753
 754static const struct attribute_group ds2780_attr_group = {
 755        .attrs = ds2780_attributes,
 756};
 757
 758static int __devinit ds2780_battery_probe(struct platform_device *pdev)
 759{
 760        int ret = 0;
 761        struct ds2780_device_info *dev_info;
 762
 763        dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
 764        if (!dev_info) {
 765                ret = -ENOMEM;
 766                goto fail;
 767        }
 768
 769        platform_set_drvdata(pdev, dev_info);
 770
 771        dev_info->dev                   = &pdev->dev;
 772        dev_info->w1_dev                = pdev->dev.parent;
 773        dev_info->bat.name              = dev_name(&pdev->dev);
 774        dev_info->bat.type              = POWER_SUPPLY_TYPE_BATTERY;
 775        dev_info->bat.properties        = ds2780_battery_props;
 776        dev_info->bat.num_properties    = ARRAY_SIZE(ds2780_battery_props);
 777        dev_info->bat.get_property      = ds2780_battery_get_property;
 778
 779        ret = power_supply_register(&pdev->dev, &dev_info->bat);
 780        if (ret) {
 781                dev_err(dev_info->dev, "failed to register battery\n");
 782                goto fail_free_info;
 783        }
 784
 785        ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
 786        if (ret) {
 787                dev_err(dev_info->dev, "failed to create sysfs group\n");
 788                goto fail_unregister;
 789        }
 790
 791        ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj,
 792                                        &ds2780_param_eeprom_bin_attr);
 793        if (ret) {
 794                dev_err(dev_info->dev,
 795                                "failed to create param eeprom bin file");
 796                goto fail_remove_group;
 797        }
 798
 799        ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj,
 800                                        &ds2780_user_eeprom_bin_attr);
 801        if (ret) {
 802                dev_err(dev_info->dev,
 803                                "failed to create user eeprom bin file");
 804                goto fail_remove_bin_file;
 805        }
 806
 807        return 0;
 808
 809fail_remove_bin_file:
 810        sysfs_remove_bin_file(&dev_info->bat.dev->kobj,
 811                                &ds2780_param_eeprom_bin_attr);
 812fail_remove_group:
 813        sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
 814fail_unregister:
 815        power_supply_unregister(&dev_info->bat);
 816fail_free_info:
 817        kfree(dev_info);
 818fail:
 819        return ret;
 820}
 821
 822static int __devexit ds2780_battery_remove(struct platform_device *pdev)
 823{
 824        struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
 825
 826        /* remove attributes */
 827        sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
 828
 829        power_supply_unregister(&dev_info->bat);
 830
 831        kfree(dev_info);
 832        return 0;
 833}
 834
 835static struct platform_driver ds2780_battery_driver = {
 836        .driver = {
 837                .name = "ds2780-battery",
 838        },
 839        .probe    = ds2780_battery_probe,
 840        .remove   = __devexit_p(ds2780_battery_remove),
 841};
 842
 843module_platform_driver(ds2780_battery_driver);
 844
 845MODULE_LICENSE("GPL");
 846MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>");
 847MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver");
 848MODULE_ALIAS("platform:ds2780-battery");
 849
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.