2 * Fuel gauge driver for Maxim 17042 / 8966 / 8997
3 * Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
5 * Copyright (C) 2011 Samsung Electronics
6 * MyungJoo Ham <myungjoo.ham@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * This driver is based on max17040_battery.c
25 #include <linux/init.h>
26 #include <linux/slab.h>
27 #include <linux/i2c.h>
28 #include <linux/mod_devicetable.h>
29 #include <linux/power_supply.h>
30 #include <linux/power/max17042_battery.h>
32 enum max17042_register
{
33 MAX17042_STATUS
= 0x00,
34 MAX17042_VALRT_Th
= 0x01,
35 MAX17042_TALRT_Th
= 0x02,
36 MAX17042_SALRT_Th
= 0x03,
37 MAX17042_AtRate
= 0x04,
38 MAX17042_RepCap
= 0x05,
39 MAX17042_RepSOC
= 0x06,
42 MAX17042_VCELL
= 0x09,
43 MAX17042_Current
= 0x0A,
44 MAX17042_AvgCurrent
= 0x0B,
45 MAX17042_Qresidual
= 0x0C,
47 MAX17042_AvSOC
= 0x0E,
48 MAX17042_RemCap
= 0x0F,
49 MAX17402_FullCAP
= 0x10,
51 MAX17042_V_empty
= 0x12,
53 MAX17042_RSLOW
= 0x14,
55 MAX17042_AvgTA
= 0x16,
56 MAX17042_Cycles
= 0x17,
57 MAX17042_DesignCap
= 0x18,
58 MAX17042_AvgVCELL
= 0x19,
59 MAX17042_MinMaxTemp
= 0x1A,
60 MAX17042_MinMaxVolt
= 0x1B,
61 MAX17042_MinMaxCurr
= 0x1C,
62 MAX17042_CONFIG
= 0x1D,
63 MAX17042_ICHGTerm
= 0x1E,
64 MAX17042_AvCap
= 0x1F,
65 MAX17042_ManName
= 0x20,
66 MAX17042_DevName
= 0x21,
67 MAX17042_DevChem
= 0x22,
69 MAX17042_TempNom
= 0x24,
70 MAX17042_TempCold
= 0x25,
71 MAX17042_TempHot
= 0x26,
73 MAX17042_LearnCFG
= 0x28,
74 MAX17042_SHFTCFG
= 0x29,
75 MAX17042_RelaxCFG
= 0x2A,
76 MAX17042_MiscCFG
= 0x2B,
77 MAX17042_TGAIN
= 0x2C,
79 MAX17042_CGAIN
= 0x2E,
82 MAX17042_Q_empty
= 0x33,
83 MAX17042_T_empty
= 0x34,
85 MAX17042_RCOMP0
= 0x38,
86 MAX17042_TempCo
= 0x39,
88 MAX17042_T_empty0
= 0x3B,
89 MAX17042_TaskPeriod
= 0x3C,
90 MAX17042_FSTAT
= 0x3D,
92 MAX17042_SHDNTIMER
= 0x3F,
94 MAX17042_VFRemCap
= 0x4A,
100 struct max17042_chip
{
101 struct i2c_client
*client
;
102 struct power_supply battery
;
103 struct max17042_platform_data
*pdata
;
106 static int max17042_write_reg(struct i2c_client
*client
, u8 reg
, u16 value
)
108 int ret
= i2c_smbus_write_word_data(client
, reg
, value
);
111 dev_err(&client
->dev
, "%s: err %d\n", __func__
, ret
);
116 static int max17042_read_reg(struct i2c_client
*client
, u8 reg
)
118 int ret
= i2c_smbus_read_word_data(client
, reg
);
121 dev_err(&client
->dev
, "%s: err %d\n", __func__
, ret
);
126 static enum power_supply_property max17042_battery_props
[] = {
127 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
128 POWER_SUPPLY_PROP_VOLTAGE_AVG
,
129 POWER_SUPPLY_PROP_CAPACITY
,
132 static int max17042_get_property(struct power_supply
*psy
,
133 enum power_supply_property psp
,
134 union power_supply_propval
*val
)
136 struct max17042_chip
*chip
= container_of(psy
,
137 struct max17042_chip
, battery
);
140 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
141 val
->intval
= max17042_read_reg(chip
->client
,
142 MAX17042_VCELL
) * 83; /* 1000 / 12 = 83 */
144 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
145 val
->intval
= max17042_read_reg(chip
->client
,
146 MAX17042_AvgVCELL
) * 83;
148 case POWER_SUPPLY_PROP_CAPACITY
:
149 val
->intval
= max17042_read_reg(chip
->client
,
158 static int __devinit
max17042_probe(struct i2c_client
*client
,
159 const struct i2c_device_id
*id
)
161 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
162 struct max17042_chip
*chip
;
165 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_WORD_DATA
))
168 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
172 chip
->client
= client
;
173 chip
->pdata
= client
->dev
.platform_data
;
175 i2c_set_clientdata(client
, chip
);
177 chip
->battery
.name
= "max17042_battery";
178 chip
->battery
.type
= POWER_SUPPLY_TYPE_BATTERY
;
179 chip
->battery
.get_property
= max17042_get_property
;
180 chip
->battery
.properties
= max17042_battery_props
;
181 chip
->battery
.num_properties
= ARRAY_SIZE(max17042_battery_props
);
183 ret
= power_supply_register(&client
->dev
, &chip
->battery
);
185 dev_err(&client
->dev
, "failed: power supply register\n");
186 i2c_set_clientdata(client
, NULL
);
191 if (!chip
->pdata
->enable_current_sense
) {
192 max17042_write_reg(client
, MAX17042_CGAIN
, 0x0000);
193 max17042_write_reg(client
, MAX17042_MiscCFG
, 0x0003);
194 max17042_write_reg(client
, MAX17042_LearnCFG
, 0x0007);
200 static int __devexit
max17042_remove(struct i2c_client
*client
)
202 struct max17042_chip
*chip
= i2c_get_clientdata(client
);
204 power_supply_unregister(&chip
->battery
);
205 i2c_set_clientdata(client
, NULL
);
210 static const struct i2c_device_id max17042_id
[] = {
214 MODULE_DEVICE_TABLE(i2c
, max17042_id
);
216 static struct i2c_driver max17042_i2c_driver
= {
220 .probe
= max17042_probe
,
221 .remove
= __devexit_p(max17042_remove
),
222 .id_table
= max17042_id
,
225 static int __init
max17042_init(void)
227 return i2c_add_driver(&max17042_i2c_driver
);
229 module_init(max17042_init
);
231 static void __exit
max17042_exit(void)
233 i2c_del_driver(&max17042_i2c_driver
);
235 module_exit(max17042_exit
);
237 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
238 MODULE_DESCRIPTION("MAX17042 Fuel Gauge");
239 MODULE_LICENSE("GPL");