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