cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ds2780_battery.c (19923B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * 1-wire client/driver for the Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC
      4 *
      5 * Copyright (C) 2010 Indesign, LLC
      6 *
      7 * Author: Clifton Barnes <cabarnes@indesign-llc.com>
      8 *
      9 * Based on ds2760_battery and ds2782_battery drivers
     10 */
     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	1563
     25/* Charge unit measurement in uAh for a 1 milli-ohm sense resistor */
     26#define DS2780_CHARGE_UNITS		6250
     27/* 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 MSB
    163	 * and LSB registers in two's complement form
    164	 * Sign bit of the voltage value is in bit 7 of the voltage MSB register
    165	 * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the
    166	 * voltage MSB register
    167	 * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
    168	 * voltage LSB register
    169	 */
    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 class
    177	 * 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 temperature
    191	 * MSB and LSB registers in two's complement form
    192	 * Sign bit of the temperature value is in bit 7 of the temperature
    193	 * MSB register
    194	 * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the
    195	 * temperature MSB register
    196	 * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
    197	 * temperature LSB register
    198	 */
    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, the
    206	 * power_supply class measures temperature in tenths of degrees
    207	 * celsius. The temperature value is stored as a 10 bit number, plus
    208	 * 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 of
    223	 * 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	else
    240		return -EINVAL;
    241
    242	/*
    243	 * The current value is located in 16 bits across the current MSB
    244	 * and LSB registers in two's complement form
    245	 * Sign bit of the current value is in bit 7 of the current MSB register
    246	 * Bits 14 - 8 of the current value are in bits 6 - 0 of the current
    247	 * MSB register
    248	 * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
    249	 * LSB register
    250	 */
    251	ret = ds2780_read16(dev_info, &current_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 on
    268	 * 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 and
    282	 * LSB registers
    283	 * Bits 15 - 8 of the ACR value are in bits 7 - 0 of the ACR
    284	 * MSB register
    285	 * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
    286	 * LSB register
    287	 */
    288	ret = ds2780_read16(dev_info, &current_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, &current_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	else
    329		*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 and
    342	 * LSB registers
    343	 * Bits 15 - 8 of the RAAC value are in bits 7 - 0 of the RAAC
    344	 * MSB register
    345	 * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
    346	 * LSB register
    347	 */
    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 sprintf(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	else
    488		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 = sprintf(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 sprintf(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 = sprintf(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	NULL
    727};
    728
    729static struct bin_attribute *ds2780_sysfs_bin_attrs[] = {
    730	&ds2780_param_eeprom_bin_attr,
    731	&ds2780_user_eeprom_bin_attr,
    732	NULL
    733};
    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");