1275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* 2275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * 1-wire client/driver for the Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC 3275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * 4275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Copyright (C) 2010 Indesign, LLC 5275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * 6275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Author: Clifton Barnes <cabarnes@indesign-llc.com> 7275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * 8275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Based on ds2760_battery and ds2782_battery drivers 9275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * 10275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * This program is free software; you can redistribute it and/or modify 11275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * it under the terms of the GNU General Public License version 2 as 12275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * published by the Free Software Foundation. 13275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * 14275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 15275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 16275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/module.h> 17275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/slab.h> 18275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/param.h> 19275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/pm.h> 20275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/platform_device.h> 21275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/power_supply.h> 22275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include <linux/idr.h> 23275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 24275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include "../w1/w1.h" 25275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#include "../w1/slaves/w1_ds2780.h" 26275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 27275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Current unit measurement in uA for a 1 milli-ohm sense resistor */ 28275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#define DS2780_CURRENT_UNITS 1563 29275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Charge unit measurement in uAh for a 1 milli-ohm sense resistor */ 30275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#define DS2780_CHARGE_UNITS 6250 31275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Number of bytes in user EEPROM space */ 32275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#define DS2780_USER_EEPROM_SIZE (DS2780_EEPROM_BLOCK0_END - \ 33275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_START + 1) 34275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Number of bytes in parameter EEPROM space */ 35275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes#define DS2780_PARAM_EEPROM_SIZE (DS2780_EEPROM_BLOCK1_END - \ 36275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_START + 1) 37275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 38275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstruct ds2780_device_info { 39275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device *dev; 40275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply bat; 41275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device *w1_dev; 420e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes struct task_struct *mutex_holder; 43275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 44275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 45275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesenum current_types { 46275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes CURRENT_NOW, 47275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes CURRENT_AVG, 48275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 49275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 50275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic const char model[] = "DS2780"; 51275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic const char manufacturer[] = "Maxim/Dallas"; 52275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 53853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesstatic inline struct ds2780_device_info * 54853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesto_ds2780_device_info(struct power_supply *psy) 55275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 56275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return container_of(psy, struct ds2780_device_info, bat); 57275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 58275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 59275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic inline struct power_supply *to_power_supply(struct device *dev) 60275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 61275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return dev_get_drvdata(dev); 62275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 63275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 64853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesstatic inline int ds2780_battery_io(struct ds2780_device_info *dev_info, 65853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes char *buf, int addr, size_t count, int io) 66275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 670e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes if (dev_info->mutex_holder == current) 680e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io); 690e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes else 70853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); 71275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 72275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 73853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesstatic inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val, 74853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes int addr) 75853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes{ 76853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_battery_io(dev_info, val, addr, sizeof(u8), 0); 77275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 78275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 79853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesstatic int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val, 80853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes int addr) 81275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 82275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 83275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 raw[2]; 84275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 85853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_battery_io(dev_info, raw, addr, sizeof(raw), 0); 86275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 87275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 88275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 89275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *val = (raw[0] << 8) | raw[1]; 90275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 91275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 92275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 93275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 94853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesstatic inline int ds2780_read_block(struct ds2780_device_info *dev_info, 95853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes u8 *val, int addr, size_t count) 96275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 97853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_battery_io(dev_info, val, addr, count, 0); 98275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 99275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 100853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnesstatic inline int ds2780_write(struct ds2780_device_info *dev_info, u8 *val, 101853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes int addr, size_t count) 102275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 103853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_battery_io(dev_info, val, addr, count, 1); 104275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 105275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 106275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic inline int ds2780_store_eeprom(struct device *dev, int addr) 107275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 108275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return w1_ds2780_eeprom_cmd(dev, addr, W1_DS2780_COPY_DATA); 109275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 110275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 111275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic inline int ds2780_recall_eeprom(struct device *dev, int addr) 112275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 113275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return w1_ds2780_eeprom_cmd(dev, addr, W1_DS2780_RECALL_DATA); 114275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 115275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 116275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_save_eeprom(struct ds2780_device_info *dev_info, int reg) 117275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 118275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 119275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 120275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_store_eeprom(dev_info->w1_dev, reg); 121275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 122275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 123275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 124275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_recall_eeprom(dev_info->w1_dev, reg); 125275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 126275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 127275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 128275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 129275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 130275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 131275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Set sense resistor value in mhos */ 132275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_set_sense_register(struct ds2780_device_info *dev_info, 133275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 conductance) 134275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 135275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 136275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 137853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_write(dev_info, &conductance, 138275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_RSNSP_REG, sizeof(u8)); 139275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 140275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 141275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 142275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ds2780_save_eeprom(dev_info, DS2780_RSNSP_REG); 143275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 144275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 145275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Get RSGAIN value from 0 to 1.999 in steps of 0.001 */ 146275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info, 147275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u16 *rsgain) 148275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 149853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_read16(dev_info, rsgain, DS2780_RSGAIN_MSB_REG); 150275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 151275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 152275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes/* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */ 153275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_set_rsgain_register(struct ds2780_device_info *dev_info, 154275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u16 rsgain) 155275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 156275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 157275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 raw[] = {rsgain >> 8, rsgain & 0xFF}; 158275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 159853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_write(dev_info, raw, 160853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes DS2780_RSGAIN_MSB_REG, sizeof(raw)); 161275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 162275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 163275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 164275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ds2780_save_eeprom(dev_info, DS2780_RSGAIN_MSB_REG); 165275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 166275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 167275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_voltage(struct ds2780_device_info *dev_info, 168275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int *voltage_uV) 169275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 170275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 171275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes s16 voltage_raw; 172275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 173275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 174275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The voltage value is located in 10 bits across the voltage MSB 175275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * and LSB registers in two's compliment form 176275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Sign bit of the voltage value is in bit 7 of the voltage MSB register 177275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the 178275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * voltage MSB register 179275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the 180275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * voltage LSB register 181275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 182853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read16(dev_info, &voltage_raw, 183275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_VOLT_MSB_REG); 184275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 185275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 186275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 187275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 188275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * DS2780 reports voltage in units of 4.88mV, but the battery class 189275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * reports in units of uV, so convert by multiplying by 4880. 190275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 191275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *voltage_uV = (voltage_raw / 32) * 4880; 192275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 193275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 194275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 195275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_temperature(struct ds2780_device_info *dev_info, 196275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int *temperature) 197275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 198275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 199275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes s16 temperature_raw; 200275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 201275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 202275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The temperature value is located in 10 bits across the temperature 203275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * MSB and LSB registers in two's compliment form 204275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Sign bit of the temperature value is in bit 7 of the temperature 205275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * MSB register 206275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the 207275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * temperature MSB register 208275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the 209275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * temperature LSB register 210275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 211853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read16(dev_info, &temperature_raw, 212275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_TEMP_MSB_REG); 213275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 214275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 215275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 216275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 217275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Temperature is measured in units of 0.125 degrees celcius, the 218275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * power_supply class measures temperature in tenths of degrees 219275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * celsius. The temperature value is stored as a 10 bit number, plus 220275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * sign in the upper bits of a 16 bit register. 221275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 222275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *temperature = ((temperature_raw / 32) * 125) / 100; 223275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 224275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 225275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 226275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_current(struct ds2780_device_info *dev_info, 227275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes enum current_types type, int *current_uA) 228275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 229275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret, sense_res; 230275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes s16 current_raw; 231275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 sense_res_raw, reg_msb; 232275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 233275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 234275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The units of measurement for current are dependent on the value of 235275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * the sense resistor. 236275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 237853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG); 238275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 239275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 240275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 241275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (sense_res_raw == 0) { 242275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "sense resistor value is 0\n"); 243853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return -EINVAL; 244275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 245275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes sense_res = 1000 / sense_res_raw; 246275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 247275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (type == CURRENT_NOW) 248275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes reg_msb = DS2780_CURRENT_MSB_REG; 249275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes else if (type == CURRENT_AVG) 250275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes reg_msb = DS2780_IAVG_MSB_REG; 251275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes else 252275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return -EINVAL; 253275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 254275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 255275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The current value is located in 16 bits across the current MSB 256275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * and LSB registers in two's compliment form 257275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Sign bit of the current value is in bit 7 of the current MSB register 258275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 14 - 8 of the current value are in bits 6 - 0 of the current 259275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * MSB register 260275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 7 - 0 of the current value are in bits 7 - 0 of the current 261275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * LSB register 262275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 263853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read16(dev_info, ¤t_raw, reg_msb); 264275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 265275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 266275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 267275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *current_uA = current_raw * (DS2780_CURRENT_UNITS / sense_res); 268275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 269275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 270275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 271275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info, 272275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int *accumulated_current) 273275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 274275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret, sense_res; 275275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes s16 current_raw; 276275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 sense_res_raw; 277275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 278275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 279275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The units of measurement for accumulated current are dependent on 280275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * the value of the sense resistor. 281275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 282853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG); 283275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 284275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 285275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 286275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (sense_res_raw == 0) { 287275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "sense resistor value is 0\n"); 288275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return -ENXIO; 289275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 290275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes sense_res = 1000 / sense_res_raw; 291275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 292275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 293275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The ACR value is located in 16 bits across the ACR MSB and 294275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * LSB registers 295275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 15 - 8 of the ACR value are in bits 7 - 0 of the ACR 296275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * MSB register 297275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR 298275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * LSB register 299275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 300853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read16(dev_info, ¤t_raw, DS2780_ACR_MSB_REG); 301275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 302275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 303275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 304275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *accumulated_current = current_raw * (DS2780_CHARGE_UNITS / sense_res); 305275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 306275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 307275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 308275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_capacity(struct ds2780_device_info *dev_info, 309275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int *capacity) 310275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 311275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 312275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 raw; 313275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 314853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read8(dev_info, &raw, DS2780_RARC_REG); 315275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 316275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 317275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 318275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *capacity = raw; 319275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return raw; 320275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 321275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 322275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_status(struct ds2780_device_info *dev_info, int *status) 323275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 324275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret, current_uA, capacity; 325275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 326275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_current(dev_info, CURRENT_NOW, ¤t_uA); 327275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 328275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 329275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 330275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_capacity(dev_info, &capacity); 331275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 332275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 333275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 334275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (capacity == 100) 335275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *status = POWER_SUPPLY_STATUS_FULL; 336275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes else if (current_uA == 0) 337275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *status = POWER_SUPPLY_STATUS_NOT_CHARGING; 338275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes else if (current_uA < 0) 339275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *status = POWER_SUPPLY_STATUS_DISCHARGING; 340275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes else 341275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *status = POWER_SUPPLY_STATUS_CHARGING; 342275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 343275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 344275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 345275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 346275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_charge_now(struct ds2780_device_info *dev_info, 347275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int *charge_now) 348275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 349275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 350275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u16 charge_raw; 351275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 352275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* 353275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * The RAAC value is located in 16 bits across the RAAC MSB and 354275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * LSB registers 355275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 15 - 8 of the RAAC value are in bits 7 - 0 of the RAAC 356275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * MSB register 357275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC 358275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes * LSB register 359275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes */ 360853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read16(dev_info, &charge_raw, DS2780_RAAC_MSB_REG); 361275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 362275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 363275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 364275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes *charge_now = charge_raw * 1600; 365275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 366275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 367275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 368275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_get_control_register(struct ds2780_device_info *dev_info, 369275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 *control_reg) 370275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 371853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_read8(dev_info, control_reg, DS2780_CONTROL_REG); 372275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 373275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 374275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_set_control_register(struct ds2780_device_info *dev_info, 375275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 control_reg) 376275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 377275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 378275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 379853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_write(dev_info, &control_reg, 380275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_CONTROL_REG, sizeof(u8)); 381275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 382275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 383275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 384275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ds2780_save_eeprom(dev_info, DS2780_CONTROL_REG); 385275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 386275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 387275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int ds2780_battery_get_property(struct power_supply *psy, 388275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes enum power_supply_property psp, 389275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes union power_supply_propval *val) 390275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 391275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret = 0; 392275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 393275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 394275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes switch (psp) { 395275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_VOLTAGE_NOW: 396275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_voltage(dev_info, &val->intval); 397275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 398275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 399275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_TEMP: 400275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_temperature(dev_info, &val->intval); 401275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 402275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 403275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_MODEL_NAME: 404275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes val->strval = model; 405275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 406275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 407275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_MANUFACTURER: 408275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes val->strval = manufacturer; 409275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 410275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 411275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_CURRENT_NOW: 412275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_current(dev_info, CURRENT_NOW, &val->intval); 413275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 414275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 415275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_CURRENT_AVG: 416275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_current(dev_info, CURRENT_AVG, &val->intval); 417275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 418275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 419275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_STATUS: 420275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_status(dev_info, &val->intval); 421275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 422275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 423275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_CAPACITY: 424275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_capacity(dev_info, &val->intval); 425275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 426275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 427275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_CHARGE_COUNTER: 428275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_accumulated_current(dev_info, &val->intval); 429275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 430275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 431275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes case POWER_SUPPLY_PROP_CHARGE_NOW: 432275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_charge_now(dev_info, &val->intval); 433275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes break; 434275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 435275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes default: 436275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = -EINVAL; 437275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 438275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 439275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 440275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 441275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 442275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic enum power_supply_property ds2780_battery_props[] = { 443275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_STATUS, 444275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_VOLTAGE_NOW, 445275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_TEMP, 446275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_MODEL_NAME, 447275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_MANUFACTURER, 448275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_CURRENT_NOW, 449275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_CURRENT_AVG, 450275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_CAPACITY, 451275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_CHARGE_COUNTER, 452275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes POWER_SUPPLY_PROP_CHARGE_NOW, 453275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 454275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 455275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_get_pmod_enabled(struct device *dev, 456275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 457275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf) 458275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 459275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 460275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 control_reg; 461275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 462275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 463275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 464275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* Get power mode */ 465275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_control_register(dev_info, &control_reg); 466275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 467275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 468275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 469275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return sprintf(buf, "%d\n", 470275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes !!(control_reg & DS2780_CONTROL_REG_PMOD)); 471275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 472275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 473275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_set_pmod_enabled(struct device *dev, 474275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 475275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes const char *buf, 476275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes size_t count) 477275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 478275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 479275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 control_reg, new_setting; 480275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 481275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 482275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 483275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* Set power mode */ 484275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_control_register(dev_info, &control_reg); 485275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 486275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 487275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 488275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = kstrtou8(buf, 0, &new_setting); 489275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 490275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 491275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 492275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if ((new_setting != 0) && (new_setting != 1)) { 493275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "Invalid pmod setting (0 or 1)\n"); 494275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return -EINVAL; 495275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 496275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 497275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (new_setting) 498275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes control_reg |= DS2780_CONTROL_REG_PMOD; 499275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes else 500275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes control_reg &= ~DS2780_CONTROL_REG_PMOD; 501275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 502275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_set_control_register(dev_info, control_reg); 503275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 504275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 505275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 506275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return count; 507275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 508275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 509275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_get_sense_resistor_value(struct device *dev, 510275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 511275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf) 512275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 513275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 514275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 sense_resistor; 515275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 516275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 517275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 518853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read8(dev_info, &sense_resistor, DS2780_RSNSP_REG); 519275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 520275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 521275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 522275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = sprintf(buf, "%d\n", sense_resistor); 523275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 524275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 525275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 526275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_set_sense_resistor_value(struct device *dev, 527275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 528275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes const char *buf, 529275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes size_t count) 530275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 531275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 532275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 new_setting; 533275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 534275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 535275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 536275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = kstrtou8(buf, 0, &new_setting); 537275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 538275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 539275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 540275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_set_sense_register(dev_info, new_setting); 541275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 542275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 543275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 544275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return count; 545275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 546275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 547275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_get_rsgain_setting(struct device *dev, 548275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 549275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf) 550275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 551275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 552275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u16 rsgain; 553275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 554275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 555275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 556275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_get_rsgain_register(dev_info, &rsgain); 557275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 558275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 559275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 560275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return sprintf(buf, "%d\n", rsgain); 561275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 562275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 563275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_set_rsgain_setting(struct device *dev, 564275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 565275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes const char *buf, 566275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes size_t count) 567275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 568275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 569275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u16 new_setting; 570275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 571275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 572275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 573275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = kstrtou16(buf, 0, &new_setting); 574275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 575275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 576275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 577275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* Gain can only be from 0 to 1.999 in steps of .001 */ 578275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (new_setting > 1999) { 579275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "Invalid rsgain setting (0 - 1999)\n"); 580275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return -EINVAL; 581275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 582275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 583275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_set_rsgain_register(dev_info, new_setting); 584275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 585275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 586275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 587275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return count; 588275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 589275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 590275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_get_pio_pin(struct device *dev, 591275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 592275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf) 593275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 594275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 595275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 sfr; 596275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 597275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 598275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 599853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_read8(dev_info, &sfr, DS2780_SFR_REG); 600275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 601275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 602275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 603275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = sprintf(buf, "%d\n", sfr & DS2780_SFR_REG_PIOSC); 604275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 605275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 606275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 607275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_set_pio_pin(struct device *dev, 608275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device_attribute *attr, 609275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes const char *buf, 610275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes size_t count) 611275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 612275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 613275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes u8 new_setting; 614275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 615275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 616275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 617275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = kstrtou8(buf, 0, &new_setting); 618275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 619275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 620275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 621275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if ((new_setting != 0) && (new_setting != 1)) { 622275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "Invalid pio_pin setting (0 or 1)\n"); 623275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return -EINVAL; 624275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 625275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 626853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_write(dev_info, &new_setting, 627275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_SFR_REG, sizeof(u8)); 628275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 629275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 630275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 631275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return count; 632275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 633275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 634275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_read_param_eeprom_bin(struct file *filp, 635275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct kobject *kobj, 636275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct bin_attribute *bin_attr, 637275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf, loff_t off, size_t count) 638275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 639275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device *dev = container_of(kobj, struct device, kobj); 640275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 641275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 642275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 643275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes count = min_t(loff_t, count, 644275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_END - 645275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_START + 1 - off); 646275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 647853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_read_block(dev_info, buf, 648275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_START + off, count); 649275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 650275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 651275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_write_param_eeprom_bin(struct file *filp, 652275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct kobject *kobj, 653275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct bin_attribute *bin_attr, 654275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf, loff_t off, size_t count) 655275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 656275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device *dev = container_of(kobj, struct device, kobj); 657275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 658275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 659275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 660275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 661275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes count = min_t(loff_t, count, 662275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_END - 663275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_START + 1 - off); 664275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 665853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_write(dev_info, buf, 666275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK1_START + off, count); 667275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 668275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 669275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 670275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_save_eeprom(dev_info, DS2780_EEPROM_BLOCK1_START); 671275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 672275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 673275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 674275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return count; 675275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 676275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 677275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic struct bin_attribute ds2780_param_eeprom_bin_attr = { 678275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .attr = { 679275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .name = "param_eeprom", 680275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .mode = S_IRUGO | S_IWUSR, 681275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes }, 682275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .size = DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1, 683275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .read = ds2780_read_param_eeprom_bin, 684275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .write = ds2780_write_param_eeprom_bin, 685275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 686275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 687275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_read_user_eeprom_bin(struct file *filp, 688275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct kobject *kobj, 689275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct bin_attribute *bin_attr, 690275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf, loff_t off, size_t count) 691275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 692275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device *dev = container_of(kobj, struct device, kobj); 693275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 694275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 695275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 696275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes count = min_t(loff_t, count, 697275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_END - 698275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_START + 1 - off); 699275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 700853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes return ds2780_read_block(dev_info, buf, 701275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_START + off, count); 702275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 703275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 704275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic ssize_t ds2780_write_user_eeprom_bin(struct file *filp, 705275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct kobject *kobj, 706275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct bin_attribute *bin_attr, 707275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes char *buf, loff_t off, size_t count) 708275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 709275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct device *dev = container_of(kobj, struct device, kobj); 710275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct power_supply *psy = to_power_supply(dev); 711275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); 712275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret; 713275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 714275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes count = min_t(loff_t, count, 715275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_END - 716275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_START + 1 - off); 717275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 718853eee72f74f449797f0500ea19fc1bf497428d8Clifton Barnes ret = ds2780_write(dev_info, buf, 719275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes DS2780_EEPROM_BLOCK0_START + off, count); 720275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 721275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 722275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 723275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = ds2780_save_eeprom(dev_info, DS2780_EEPROM_BLOCK0_START); 724275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret < 0) 725275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 726275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 727275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return count; 728275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 729275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 730275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic struct bin_attribute ds2780_user_eeprom_bin_attr = { 731275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .attr = { 732275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .name = "user_eeprom", 733275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .mode = S_IRUGO | S_IWUSR, 734275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes }, 735275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .size = DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1, 736275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .read = ds2780_read_user_eeprom_bin, 737275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .write = ds2780_write_user_eeprom_bin, 738275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 739275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 740275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic DEVICE_ATTR(pmod_enabled, S_IRUGO | S_IWUSR, ds2780_get_pmod_enabled, 741275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ds2780_set_pmod_enabled); 742275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic DEVICE_ATTR(sense_resistor_value, S_IRUGO | S_IWUSR, 743275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ds2780_get_sense_resistor_value, ds2780_set_sense_resistor_value); 744275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic DEVICE_ATTR(rsgain_setting, S_IRUGO | S_IWUSR, ds2780_get_rsgain_setting, 745275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ds2780_set_rsgain_setting); 746275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic DEVICE_ATTR(pio_pin, S_IRUGO | S_IWUSR, ds2780_get_pio_pin, 747275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ds2780_set_pio_pin); 748275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 749275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 750275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic struct attribute *ds2780_attributes[] = { 751275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &dev_attr_pmod_enabled.attr, 752275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &dev_attr_sense_resistor_value.attr, 753275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &dev_attr_rsgain_setting.attr, 754275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &dev_attr_pio_pin.attr, 755275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes NULL 756275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 757275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 758275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic const struct attribute_group ds2780_attr_group = { 759275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .attrs = ds2780_attributes, 760275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 761275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 762275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int __devinit ds2780_battery_probe(struct platform_device *pdev) 763275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 764275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes int ret = 0; 765275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info; 766275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 767275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); 768275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (!dev_info) { 769275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = -ENOMEM; 770275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes goto fail; 771275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 772275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 773275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes platform_set_drvdata(pdev, dev_info); 774275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 775275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->dev = &pdev->dev; 776275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->w1_dev = pdev->dev.parent; 777275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->bat.name = dev_name(&pdev->dev); 778275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->bat.type = POWER_SUPPLY_TYPE_BATTERY; 779275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->bat.properties = ds2780_battery_props; 780275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); 781275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_info->bat.get_property = ds2780_battery_get_property; 7820e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes dev_info->mutex_holder = current; 783275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 784275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = power_supply_register(&pdev->dev, &dev_info->bat); 785275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret) { 786275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "failed to register battery\n"); 787275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes goto fail_free_info; 788275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 789275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 790275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); 791275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret) { 792275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, "failed to create sysfs group\n"); 793275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes goto fail_unregister; 794275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 795275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 796275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj, 797275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &ds2780_param_eeprom_bin_attr); 798275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret) { 799275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, 800275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes "failed to create param eeprom bin file"); 801275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes goto fail_remove_group; 802275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 803275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 804275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj, 805275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &ds2780_user_eeprom_bin_attr); 806275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes if (ret) { 807275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes dev_err(dev_info->dev, 808275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes "failed to create user eeprom bin file"); 809275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes goto fail_remove_bin_file; 810275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes } 811275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 8120e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes dev_info->mutex_holder = NULL; 8130e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes 814275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 815275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 816275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesfail_remove_bin_file: 817275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes sysfs_remove_bin_file(&dev_info->bat.dev->kobj, 818275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes &ds2780_param_eeprom_bin_attr); 819275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesfail_remove_group: 820275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); 821275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesfail_unregister: 822275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes power_supply_unregister(&dev_info->bat); 823275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesfail_free_info: 824275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes kfree(dev_info); 825275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesfail: 826275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return ret; 827275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 828275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 829275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic int __devexit ds2780_battery_remove(struct platform_device *pdev) 830275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes{ 831275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); 832275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 8330e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes dev_info->mutex_holder = current; 8340e053fcbbbc4d945247cb32cad2767b483cb65f8Clifton Barnes 835275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes /* remove attributes */ 836275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); 837275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 838275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes power_supply_unregister(&dev_info->bat); 839275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 840275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes kfree(dev_info); 841275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes return 0; 842275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes} 843275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 844275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnesstatic struct platform_driver ds2780_battery_driver = { 845275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .driver = { 846275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .name = "ds2780-battery", 847275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes }, 848275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes .probe = ds2780_battery_probe, 8490bea4b866448af09051e357b139f598aa70b8614Axel Lin .remove = __devexit_p(ds2780_battery_remove), 850275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes}; 851275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 852300bac7fb85a20b2704dc3645419057992f78565Axel Linmodule_platform_driver(ds2780_battery_driver); 853275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton Barnes 854275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton BarnesMODULE_LICENSE("GPL"); 855275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton BarnesMODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>"); 856275ac74629c4d8ec430d7edecb16d936f46a47c5Clifton BarnesMODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver"); 857300bac7fb85a20b2704dc3645419057992f78565Axel LinMODULE_ALIAS("platform:ds2780-battery"); 858