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, &current_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, &current_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, &current_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