aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-11 21:53:05 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-11 21:53:05 -0500
commitb24ca57e7625bc304e77bc429693ad32a691eb16 (patch)
tree770aa389c6e763cf37776a35e85ff1e41958b1e9 /drivers/power
parent6296e5d3c067df41980a5fd09ad4cc6765f79bb9 (diff)
parent913272b3864d6da89c70d9fc2c30ccb57794b369 (diff)
Merge git://git.infradead.org/battery-2.6
* git://git.infradead.org/battery-2.6: (68 commits) power_supply: Mark da9052 driver as broken power_supply: Drop usage of nowarn variant of sysfs_create_link() s3c_adc_battery: Average over more than one adc sample power_supply: Add DA9052 battery driver isp1704_charger: Fix missing check jz4740-battery: Fix signedness bug power_supply: Assume mains power by default sbs-battery: Fix devicetree match table ARM: rx51: Add bq27200 i2c board info sbs-battery: Change power supply name devicetree-bindings: Propagate bq20z75->sbs rename to dt bindings devicetree-bindings: Add vendor entry for Smart Battery Systems sbs-battery: Rename internals to new name bq20z75: Rename to sbs-battery wm97xx_battery: Use DEFINE_MUTEX() for work_lock max8997_charger: Remove duplicate module.h lp8727_charger: Some minor fixes for the header lp8727_charger: Add header file power_supply: Convert drivers/power/* to use module_platform_driver() power_supply: Add "unknown" in power supply type ...
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/Kconfig32
-rw-r--r--drivers/power/Makefile5
-rw-r--r--drivers/power/bq27x00_battery.c210
-rw-r--r--drivers/power/charger-manager.c1072
-rw-r--r--drivers/power/collie_battery.c55
-rw-r--r--drivers/power/da9030_battery.c13
-rw-r--r--drivers/power/da9052-battery.c664
-rw-r--r--drivers/power/ds2760_battery.c19
-rw-r--r--drivers/power/ds2780_battery.c18
-rw-r--r--drivers/power/gpio-charger.c12
-rw-r--r--drivers/power/intel_mid_battery.c13
-rw-r--r--drivers/power/isp1704_charger.c14
-rw-r--r--drivers/power/jz4740-battery.c14
-rw-r--r--drivers/power/lp8727_charger.c494
-rw-r--r--drivers/power/max17042_battery.c94
-rw-r--r--drivers/power/max8903_charger.c14
-rw-r--r--drivers/power/max8925_power.c75
-rw-r--r--drivers/power/max8997_charger.c4
-rw-r--r--drivers/power/max8998_charger.c14
-rw-r--r--drivers/power/olpc_battery.c75
-rw-r--r--drivers/power/pcf50633-charger.c12
-rw-r--r--drivers/power/pda_power.c89
-rw-r--r--drivers/power/power_supply_core.c19
-rw-r--r--drivers/power/power_supply_sysfs.c12
-rw-r--r--drivers/power/s3c_adc_battery.c37
-rw-r--r--drivers/power/sbs-battery.c (renamed from drivers/power/bq20z75.c)481
-rw-r--r--drivers/power/tosa_battery.c79
-rw-r--r--drivers/power/wm831x_backup.c12
-rw-r--r--drivers/power/wm831x_power.c56
-rw-r--r--drivers/power/wm8350_power.c12
-rw-r--r--drivers/power/wm97xx_battery.c20
-rw-r--r--drivers/power/z2_battery.c4
32 files changed, 3034 insertions, 710 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 9f88641e67f9..3a8daf858742 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -116,12 +116,12 @@ config BATTERY_WM97XX
116 help 116 help
117 Say Y to enable support for battery measured by WM97xx aux port. 117 Say Y to enable support for battery measured by WM97xx aux port.
118 118
119config BATTERY_BQ20Z75 119config BATTERY_SBS
120 tristate "TI BQ20z75 gas gauge" 120 tristate "SBS Compliant gas gauge"
121 depends on I2C 121 depends on I2C
122 help 122 help
123 Say Y to include support for TI BQ20z75 SBS-compliant 123 Say Y to include support for SBS battery driver for SBS-compliant
124 gas gauge and protection IC. 124 gas gauges.
125 125
126config BATTERY_BQ27x00 126config BATTERY_BQ27x00
127 tristate "BQ27x00 battery driver" 127 tristate "BQ27x00 battery driver"
@@ -150,6 +150,14 @@ config BATTERY_DA9030
150 Say Y here to enable support for batteries charger integrated into 150 Say Y here to enable support for batteries charger integrated into
151 DA9030 PMIC. 151 DA9030 PMIC.
152 152
153config BATTERY_DA9052
154 tristate "Dialog DA9052 Battery"
155 depends on PMIC_DA9052
156 depends on BROKEN
157 help
158 Say Y here to enable support for batteries charger integrated into
159 DA9052 PMIC.
160
153config BATTERY_MAX17040 161config BATTERY_MAX17040
154 tristate "Maxim MAX17040 Fuel Gauge" 162 tristate "Maxim MAX17040 Fuel Gauge"
155 depends on I2C 163 depends on I2C
@@ -226,6 +234,12 @@ config CHARGER_TWL4030
226 help 234 help
227 Say Y here to enable support for TWL4030 Battery Charge Interface. 235 Say Y here to enable support for TWL4030 Battery Charge Interface.
228 236
237config CHARGER_LP8727
238 tristate "National Semiconductor LP8727 charger driver"
239 depends on I2C
240 help
241 Say Y here to enable support for LP8727 Charger Driver.
242
229config CHARGER_GPIO 243config CHARGER_GPIO
230 tristate "GPIO charger" 244 tristate "GPIO charger"
231 depends on GPIOLIB 245 depends on GPIOLIB
@@ -236,6 +250,16 @@ config CHARGER_GPIO
236 This driver can be build as a module. If so, the module will be 250 This driver can be build as a module. If so, the module will be
237 called gpio-charger. 251 called gpio-charger.
238 252
253config CHARGER_MANAGER
254 bool "Battery charger manager for multiple chargers"
255 depends on REGULATOR && RTC_CLASS
256 help
257 Say Y to enable charger-manager support, which allows multiple
258 chargers attached to a battery and multiple batteries attached to a
259 system. The charger-manager also can monitor charging status in
260 runtime and in suspend-to-RAM by waking up the system periodically
261 with help of suspend_again support.
262
239config CHARGER_MAX8997 263config CHARGER_MAX8997
240 tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver" 264 tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
241 depends on MFD_MAX8997 && REGULATOR_MAX8997 265 depends on MFD_MAX8997 && REGULATOR_MAX8997
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b4af13dd8b66..e429008eaf10 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -22,9 +22,10 @@ obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
22obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o 22obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
23obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o 23obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
24obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o 24obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
25obj-$(CONFIG_BATTERY_BQ20Z75) += bq20z75.o 25obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
26obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o 26obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
27obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o 27obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
28obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
28obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o 29obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
29obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o 30obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
30obj-$(CONFIG_BATTERY_Z2) += z2_battery.o 31obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
@@ -35,6 +36,8 @@ obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
35obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o 36obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
36obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o 37obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
37obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o 38obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
39obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
38obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o 40obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
41obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
39obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o 42obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
40obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o 43obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index bb16f5b7e167..98bf5676318d 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -54,13 +54,19 @@
54 54
55#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ 55#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
56#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */ 56#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */
57#define BQ27000_FLAG_CHGS BIT(7) 57#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */
58#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */
59#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */
58#define BQ27000_FLAG_FC BIT(5) 60#define BQ27000_FLAG_FC BIT(5)
61#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
59 62
60#define BQ27500_REG_SOC 0x2C 63#define BQ27500_REG_SOC 0x2C
61#define BQ27500_REG_DCAP 0x3C /* Design capacity */ 64#define BQ27500_REG_DCAP 0x3C /* Design capacity */
62#define BQ27500_FLAG_DSC BIT(0) 65#define BQ27500_FLAG_DSG BIT(0) /* Discharging */
63#define BQ27500_FLAG_FC BIT(9) 66#define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */
67#define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */
68#define BQ27500_FLAG_CHG BIT(8) /* Charging */
69#define BQ27500_FLAG_FC BIT(9) /* Fully charged */
64 70
65#define BQ27000_RS 20 /* Resistor sense */ 71#define BQ27000_RS 20 /* Resistor sense */
66 72
@@ -79,9 +85,8 @@ struct bq27x00_reg_cache {
79 int charge_full; 85 int charge_full;
80 int cycle_count; 86 int cycle_count;
81 int capacity; 87 int capacity;
88 int energy;
82 int flags; 89 int flags;
83
84 int current_now;
85}; 90};
86 91
87struct bq27x00_device_info { 92struct bq27x00_device_info {
@@ -108,6 +113,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
108 POWER_SUPPLY_PROP_VOLTAGE_NOW, 113 POWER_SUPPLY_PROP_VOLTAGE_NOW,
109 POWER_SUPPLY_PROP_CURRENT_NOW, 114 POWER_SUPPLY_PROP_CURRENT_NOW,
110 POWER_SUPPLY_PROP_CAPACITY, 115 POWER_SUPPLY_PROP_CAPACITY,
116 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
111 POWER_SUPPLY_PROP_TEMP, 117 POWER_SUPPLY_PROP_TEMP,
112 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, 118 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
113 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 119 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
@@ -149,7 +155,7 @@ static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
149 rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true); 155 rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);
150 156
151 if (rsoc < 0) 157 if (rsoc < 0)
152 dev_err(di->dev, "error reading relative State-of-Charge\n"); 158 dev_dbg(di->dev, "error reading relative State-of-Charge\n");
153 159
154 return rsoc; 160 return rsoc;
155} 161}
@@ -164,7 +170,8 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
164 170
165 charge = bq27x00_read(di, reg, false); 171 charge = bq27x00_read(di, reg, false);
166 if (charge < 0) { 172 if (charge < 0) {
167 dev_err(di->dev, "error reading nominal available capacity\n"); 173 dev_dbg(di->dev, "error reading charge register %02x: %d\n",
174 reg, charge);
168 return charge; 175 return charge;
169 } 176 }
170 177
@@ -208,7 +215,7 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
208 ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true); 215 ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
209 216
210 if (ilmd < 0) { 217 if (ilmd < 0) {
211 dev_err(di->dev, "error reading initial last measured discharge\n"); 218 dev_dbg(di->dev, "error reading initial last measured discharge\n");
212 return ilmd; 219 return ilmd;
213 } 220 }
214 221
@@ -221,6 +228,50 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
221} 228}
222 229
223/* 230/*
231 * Return the battery Available energy in µWh
232 * Or < 0 if something fails.
233 */
234static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
235{
236 int ae;
237
238 ae = bq27x00_read(di, BQ27x00_REG_AE, false);
239 if (ae < 0) {
240 dev_dbg(di->dev, "error reading available energy\n");
241 return ae;
242 }
243
244 if (di->chip == BQ27500)
245 ae *= 1000;
246 else
247 ae = ae * 29200 / BQ27000_RS;
248
249 return ae;
250}
251
252/*
253 * Return the battery temperature in tenths of degree Celsius
254 * Or < 0 if something fails.
255 */
256static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
257{
258 int temp;
259
260 temp = bq27x00_read(di, BQ27x00_REG_TEMP, false);
261 if (temp < 0) {
262 dev_err(di->dev, "error reading temperature\n");
263 return temp;
264 }
265
266 if (di->chip == BQ27500)
267 temp -= 2731;
268 else
269 temp = ((temp * 5) - 5463) / 2;
270
271 return temp;
272}
273
274/*
224 * Return the battery Cycle count total 275 * Return the battery Cycle count total
225 * Or < 0 if something fails. 276 * Or < 0 if something fails.
226 */ 277 */
@@ -245,7 +296,8 @@ static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg)
245 296
246 tval = bq27x00_read(di, reg, false); 297 tval = bq27x00_read(di, reg, false);
247 if (tval < 0) { 298 if (tval < 0) {
248 dev_err(di->dev, "error reading register %02x: %d\n", reg, tval); 299 dev_dbg(di->dev, "error reading time register %02x: %d\n",
300 reg, tval);
249 return tval; 301 return tval;
250 } 302 }
251 303
@@ -262,25 +314,31 @@ static void bq27x00_update(struct bq27x00_device_info *di)
262 314
263 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500); 315 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500);
264 if (cache.flags >= 0) { 316 if (cache.flags >= 0) {
265 cache.capacity = bq27x00_battery_read_rsoc(di); 317 if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) {
266 cache.temperature = bq27x00_read(di, BQ27x00_REG_TEMP, false); 318 dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
267 cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE); 319 cache.capacity = -ENODATA;
268 cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP); 320 cache.energy = -ENODATA;
269 cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF); 321 cache.time_to_empty = -ENODATA;
270 cache.charge_full = bq27x00_battery_read_lmd(di); 322 cache.time_to_empty_avg = -ENODATA;
323 cache.time_to_full = -ENODATA;
324 cache.charge_full = -ENODATA;
325 } else {
326 cache.capacity = bq27x00_battery_read_rsoc(di);
327 cache.energy = bq27x00_battery_read_energy(di);
328 cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE);
329 cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);
330 cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);
331 cache.charge_full = bq27x00_battery_read_lmd(di);
332 }
333 cache.temperature = bq27x00_battery_read_temperature(di);
271 cache.cycle_count = bq27x00_battery_read_cyct(di); 334 cache.cycle_count = bq27x00_battery_read_cyct(di);
272 335
273 if (!is_bq27500)
274 cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false);
275
276 /* We only have to read charge design full once */ 336 /* We only have to read charge design full once */
277 if (di->charge_design_full <= 0) 337 if (di->charge_design_full <= 0)
278 di->charge_design_full = bq27x00_battery_read_ilmd(di); 338 di->charge_design_full = bq27x00_battery_read_ilmd(di);
279 } 339 }
280 340
281 /* Ignore current_now which is a snapshot of the current battery state 341 if (memcmp(&di->cache, &cache, sizeof(cache)) != 0) {
282 * and is likely to be different even between two consecutive reads */
283 if (memcmp(&di->cache, &cache, sizeof(cache) - sizeof(int)) != 0) {
284 di->cache = cache; 342 di->cache = cache;
285 power_supply_changed(&di->bat); 343 power_supply_changed(&di->bat);
286 } 344 }
@@ -302,25 +360,6 @@ static void bq27x00_battery_poll(struct work_struct *work)
302 } 360 }
303} 361}
304 362
305
306/*
307 * Return the battery temperature in tenths of degree Celsius
308 * Or < 0 if something fails.
309 */
310static int bq27x00_battery_temperature(struct bq27x00_device_info *di,
311 union power_supply_propval *val)
312{
313 if (di->cache.temperature < 0)
314 return di->cache.temperature;
315
316 if (di->chip == BQ27500)
317 val->intval = di->cache.temperature - 2731;
318 else
319 val->intval = ((di->cache.temperature * 5) - 5463) / 2;
320
321 return 0;
322}
323
324/* 363/*
325 * Return the battery average current in µA 364 * Return the battery average current in µA
326 * Note that current can be negative signed as well 365 * Note that current can be negative signed as well
@@ -330,20 +369,20 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di,
330 union power_supply_propval *val) 369 union power_supply_propval *val)
331{ 370{
332 int curr; 371 int curr;
372 int flags;
333 373
334 if (di->chip == BQ27500) 374 curr = bq27x00_read(di, BQ27x00_REG_AI, false);
335 curr = bq27x00_read(di, BQ27x00_REG_AI, false); 375 if (curr < 0) {
336 else 376 dev_err(di->dev, "error reading current\n");
337 curr = di->cache.current_now;
338
339 if (curr < 0)
340 return curr; 377 return curr;
378 }
341 379
342 if (di->chip == BQ27500) { 380 if (di->chip == BQ27500) {
343 /* bq27500 returns signed value */ 381 /* bq27500 returns signed value */
344 val->intval = (int)((s16)curr) * 1000; 382 val->intval = (int)((s16)curr) * 1000;
345 } else { 383 } else {
346 if (di->cache.flags & BQ27000_FLAG_CHGS) { 384 flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
385 if (flags & BQ27000_FLAG_CHGS) {
347 dev_dbg(di->dev, "negative current!\n"); 386 dev_dbg(di->dev, "negative current!\n");
348 curr = -curr; 387 curr = -curr;
349 } 388 }
@@ -362,10 +401,14 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
362 if (di->chip == BQ27500) { 401 if (di->chip == BQ27500) {
363 if (di->cache.flags & BQ27500_FLAG_FC) 402 if (di->cache.flags & BQ27500_FLAG_FC)
364 status = POWER_SUPPLY_STATUS_FULL; 403 status = POWER_SUPPLY_STATUS_FULL;
365 else if (di->cache.flags & BQ27500_FLAG_DSC) 404 else if (di->cache.flags & BQ27500_FLAG_DSG)
366 status = POWER_SUPPLY_STATUS_DISCHARGING; 405 status = POWER_SUPPLY_STATUS_DISCHARGING;
367 else 406 else if (di->cache.flags & BQ27500_FLAG_CHG)
368 status = POWER_SUPPLY_STATUS_CHARGING; 407 status = POWER_SUPPLY_STATUS_CHARGING;
408 else if (power_supply_am_i_supplied(&di->bat))
409 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
410 else
411 status = POWER_SUPPLY_STATUS_UNKNOWN;
369 } else { 412 } else {
370 if (di->cache.flags & BQ27000_FLAG_FC) 413 if (di->cache.flags & BQ27000_FLAG_FC)
371 status = POWER_SUPPLY_STATUS_FULL; 414 status = POWER_SUPPLY_STATUS_FULL;
@@ -382,50 +425,56 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
382 return 0; 425 return 0;
383} 426}
384 427
385/* 428static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
386 * Return the battery Voltage in milivolts
387 * Or < 0 if something fails.
388 */
389static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
390 union power_supply_propval *val) 429 union power_supply_propval *val)
391{ 430{
392 int volt; 431 int level;
393 432
394 volt = bq27x00_read(di, BQ27x00_REG_VOLT, false); 433 if (di->chip == BQ27500) {
395 if (volt < 0) 434 if (di->cache.flags & BQ27500_FLAG_FC)
396 return volt; 435 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
436 else if (di->cache.flags & BQ27500_FLAG_SOC1)
437 level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
438 else if (di->cache.flags & BQ27500_FLAG_SOCF)
439 level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
440 else
441 level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
442 } else {
443 if (di->cache.flags & BQ27000_FLAG_FC)
444 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
445 else if (di->cache.flags & BQ27000_FLAG_EDV1)
446 level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
447 else if (di->cache.flags & BQ27000_FLAG_EDVF)
448 level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
449 else
450 level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
451 }
397 452
398 val->intval = volt * 1000; 453 val->intval = level;
399 454
400 return 0; 455 return 0;
401} 456}
402 457
403/* 458/*
404 * Return the battery Available energy in µWh 459 * Return the battery Voltage in milivolts
405 * Or < 0 if something fails. 460 * Or < 0 if something fails.
406 */ 461 */
407static int bq27x00_battery_energy(struct bq27x00_device_info *di, 462static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
408 union power_supply_propval *val) 463 union power_supply_propval *val)
409{ 464{
410 int ae; 465 int volt;
411 466
412 ae = bq27x00_read(di, BQ27x00_REG_AE, false); 467 volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);
413 if (ae < 0) { 468 if (volt < 0) {
414 dev_err(di->dev, "error reading available energy\n"); 469 dev_err(di->dev, "error reading voltage\n");
415 return ae; 470 return volt;
416 } 471 }
417 472
418 if (di->chip == BQ27500) 473 val->intval = volt * 1000;
419 ae *= 1000;
420 else
421 ae = ae * 29200 / BQ27000_RS;
422
423 val->intval = ae;
424 474
425 return 0; 475 return 0;
426} 476}
427 477
428
429static int bq27x00_simple_value(int value, 478static int bq27x00_simple_value(int value,
430 union power_supply_propval *val) 479 union power_supply_propval *val)
431{ 480{
@@ -473,8 +522,11 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
473 case POWER_SUPPLY_PROP_CAPACITY: 522 case POWER_SUPPLY_PROP_CAPACITY:
474 ret = bq27x00_simple_value(di->cache.capacity, val); 523 ret = bq27x00_simple_value(di->cache.capacity, val);
475 break; 524 break;
525 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
526 ret = bq27x00_battery_capacity_level(di, val);
527 break;
476 case POWER_SUPPLY_PROP_TEMP: 528 case POWER_SUPPLY_PROP_TEMP:
477 ret = bq27x00_battery_temperature(di, val); 529 ret = bq27x00_simple_value(di->cache.temperature, val);
478 break; 530 break;
479 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 531 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
480 ret = bq27x00_simple_value(di->cache.time_to_empty, val); 532 ret = bq27x00_simple_value(di->cache.time_to_empty, val);
@@ -501,7 +553,7 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
501 ret = bq27x00_simple_value(di->cache.cycle_count, val); 553 ret = bq27x00_simple_value(di->cache.cycle_count, val);
502 break; 554 break;
503 case POWER_SUPPLY_PROP_ENERGY_NOW: 555 case POWER_SUPPLY_PROP_ENERGY_NOW:
504 ret = bq27x00_battery_energy(di, val); 556 ret = bq27x00_simple_value(di->cache.energy, val);
505 break; 557 break;
506 default: 558 default:
507 return -EINVAL; 559 return -EINVAL;
@@ -546,6 +598,14 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di)
546 598
547static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di) 599static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
548{ 600{
601 /*
602 * power_supply_unregister call bq27x00_battery_get_property which
603 * call bq27x00_battery_poll.
604 * Make sure that bq27x00_battery_poll will not call
605 * schedule_delayed_work again after unregister (which cause OOPS).
606 */
607 poll_interval = 0;
608
549 cancel_delayed_work_sync(&di->work); 609 cancel_delayed_work_sync(&di->work);
550 610
551 power_supply_unregister(&di->bat); 611 power_supply_unregister(&di->bat);
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
new file mode 100644
index 000000000000..0378d019efae
--- /dev/null
+++ b/drivers/power/charger-manager.c
@@ -0,0 +1,1072 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
3 * MyungJoo Ham <myungjoo.ham@samsung.com>
4 *
5 * This driver enables to monitor battery health and control charger
6 * during suspend-to-mem.
7 * Charger manager depends on other devices. register this later than
8 * the depending devices.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13**/
14
15#include <linux/io.h>
16#include <linux/module.h>
17#include <linux/irq.h>
18#include <linux/interrupt.h>
19#include <linux/rtc.h>
20#include <linux/slab.h>
21#include <linux/workqueue.h>
22#include <linux/platform_device.h>
23#include <linux/power/charger-manager.h>
24#include <linux/regulator/consumer.h>
25
26/*
27 * Regard CM_JIFFIES_SMALL jiffies is small enough to ignore for
28 * delayed works so that we can run delayed works with CM_JIFFIES_SMALL
29 * without any delays.
30 */
31#define CM_JIFFIES_SMALL (2)
32
33/* If y is valid (> 0) and smaller than x, do x = y */
34#define CM_MIN_VALID(x, y) x = (((y > 0) && ((x) > (y))) ? (y) : (x))
35
36/*
37 * Regard CM_RTC_SMALL (sec) is small enough to ignore error in invoking
38 * rtc alarm. It should be 2 or larger
39 */
40#define CM_RTC_SMALL (2)
41
42#define UEVENT_BUF_SIZE 32
43
44static LIST_HEAD(cm_list);
45static DEFINE_MUTEX(cm_list_mtx);
46
47/* About in-suspend (suspend-again) monitoring */
48static struct rtc_device *rtc_dev;
49/*
50 * Backup RTC alarm
51 * Save the wakeup alarm before entering suspend-to-RAM
52 */
53static struct rtc_wkalrm rtc_wkalarm_save;
54/* Backup RTC alarm time in terms of seconds since 01-01-1970 00:00:00 */
55static unsigned long rtc_wkalarm_save_time;
56static bool cm_suspended;
57static bool cm_rtc_set;
58static unsigned long cm_suspend_duration_ms;
59
60/* Global charger-manager description */
61static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
62
63/**
64 * is_batt_present - See if the battery presents in place.
65 * @cm: the Charger Manager representing the battery.
66 */
67static bool is_batt_present(struct charger_manager *cm)
68{
69 union power_supply_propval val;
70 bool present = false;
71 int i, ret;
72
73 switch (cm->desc->battery_present) {
74 case CM_FUEL_GAUGE:
75 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
76 POWER_SUPPLY_PROP_PRESENT, &val);
77 if (ret == 0 && val.intval)
78 present = true;
79 break;
80 case CM_CHARGER_STAT:
81 for (i = 0; cm->charger_stat[i]; i++) {
82 ret = cm->charger_stat[i]->get_property(
83 cm->charger_stat[i],
84 POWER_SUPPLY_PROP_PRESENT, &val);
85 if (ret == 0 && val.intval) {
86 present = true;
87 break;
88 }
89 }
90 break;
91 }
92
93 return present;
94}
95
96/**
97 * is_ext_pwr_online - See if an external power source is attached to charge
98 * @cm: the Charger Manager representing the battery.
99 *
100 * Returns true if at least one of the chargers of the battery has an external
101 * power source attached to charge the battery regardless of whether it is
102 * actually charging or not.
103 */
104static bool is_ext_pwr_online(struct charger_manager *cm)
105{
106 union power_supply_propval val;
107 bool online = false;
108 int i, ret;
109
110 /* If at least one of them has one, it's yes. */
111 for (i = 0; cm->charger_stat[i]; i++) {
112 ret = cm->charger_stat[i]->get_property(
113 cm->charger_stat[i],
114 POWER_SUPPLY_PROP_ONLINE, &val);
115 if (ret == 0 && val.intval) {
116 online = true;
117 break;
118 }
119 }
120
121 return online;
122}
123
124/**
125 * get_batt_uV - Get the voltage level of the battery
126 * @cm: the Charger Manager representing the battery.
127 * @uV: the voltage level returned.
128 *
129 * Returns 0 if there is no error.
130 * Returns a negative value on error.
131 */
132static int get_batt_uV(struct charger_manager *cm, int *uV)
133{
134 union power_supply_propval val;
135 int ret;
136
137 if (cm->fuel_gauge)
138 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
139 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
140 else
141 return -ENODEV;
142
143 if (ret)
144 return ret;
145
146 *uV = val.intval;
147 return 0;
148}
149
150/**
151 * is_charging - Returns true if the battery is being charged.
152 * @cm: the Charger Manager representing the battery.
153 */
154static bool is_charging(struct charger_manager *cm)
155{
156 int i, ret;
157 bool charging = false;
158 union power_supply_propval val;
159
160 /* If there is no battery, it cannot be charged */
161 if (!is_batt_present(cm))
162 return false;
163
164 /* If at least one of the charger is charging, return yes */
165 for (i = 0; cm->charger_stat[i]; i++) {
166 /* 1. The charger sholuld not be DISABLED */
167 if (cm->emergency_stop)
168 continue;
169 if (!cm->charger_enabled)
170 continue;
171
172 /* 2. The charger should be online (ext-power) */
173 ret = cm->charger_stat[i]->get_property(
174 cm->charger_stat[i],
175 POWER_SUPPLY_PROP_ONLINE, &val);
176 if (ret) {
177 dev_warn(cm->dev, "Cannot read ONLINE value from %s.\n",
178 cm->desc->psy_charger_stat[i]);
179 continue;
180 }
181 if (val.intval == 0)
182 continue;
183
184 /*
185 * 3. The charger should not be FULL, DISCHARGING,
186 * or NOT_CHARGING.
187 */
188 ret = cm->charger_stat[i]->get_property(
189 cm->charger_stat[i],
190 POWER_SUPPLY_PROP_STATUS, &val);
191 if (ret) {
192 dev_warn(cm->dev, "Cannot read STATUS value from %s.\n",
193 cm->desc->psy_charger_stat[i]);
194 continue;
195 }
196 if (val.intval == POWER_SUPPLY_STATUS_FULL ||
197 val.intval == POWER_SUPPLY_STATUS_DISCHARGING ||
198 val.intval == POWER_SUPPLY_STATUS_NOT_CHARGING)
199 continue;
200
201 /* Then, this is charging. */
202 charging = true;
203 break;
204 }
205
206 return charging;
207}
208
209/**
210 * is_polling_required - Return true if need to continue polling for this CM.
211 * @cm: the Charger Manager representing the battery.
212 */
213static bool is_polling_required(struct charger_manager *cm)
214{
215 switch (cm->desc->polling_mode) {
216 case CM_POLL_DISABLE:
217 return false;
218 case CM_POLL_ALWAYS:
219 return true;
220 case CM_POLL_EXTERNAL_POWER_ONLY:
221 return is_ext_pwr_online(cm);
222 case CM_POLL_CHARGING_ONLY:
223 return is_charging(cm);
224 default:
225 dev_warn(cm->dev, "Incorrect polling_mode (%d)\n",
226 cm->desc->polling_mode);
227 }
228
229 return false;
230}
231
232/**
233 * try_charger_enable - Enable/Disable chargers altogether
234 * @cm: the Charger Manager representing the battery.
235 * @enable: true: enable / false: disable
236 *
237 * Note that Charger Manager keeps the charger enabled regardless whether
238 * the charger is charging or not (because battery is full or no external
239 * power source exists) except when CM needs to disable chargers forcibly
240 * bacause of emergency causes; when the battery is overheated or too cold.
241 */
242static int try_charger_enable(struct charger_manager *cm, bool enable)
243{
244 int err = 0, i;
245 struct charger_desc *desc = cm->desc;
246
247 /* Ignore if it's redundent command */
248 if (enable && cm->charger_enabled)
249 return 0;
250 if (!enable && !cm->charger_enabled)
251 return 0;
252
253 if (enable) {
254 if (cm->emergency_stop)
255 return -EAGAIN;
256 err = regulator_bulk_enable(desc->num_charger_regulators,
257 desc->charger_regulators);
258 } else {
259 /*
260 * Abnormal battery state - Stop charging forcibly,
261 * even if charger was enabled at the other places
262 */
263 err = regulator_bulk_disable(desc->num_charger_regulators,
264 desc->charger_regulators);
265
266 for (i = 0; i < desc->num_charger_regulators; i++) {
267 if (regulator_is_enabled(
268 desc->charger_regulators[i].consumer)) {
269 regulator_force_disable(
270 desc->charger_regulators[i].consumer);
271 dev_warn(cm->dev,
272 "Disable regulator(%s) forcibly.\n",
273 desc->charger_regulators[i].supply);
274 }
275 }
276 }
277
278 if (!err)
279 cm->charger_enabled = enable;
280
281 return err;
282}
283
284/**
285 * uevent_notify - Let users know something has changed.
286 * @cm: the Charger Manager representing the battery.
287 * @event: the event string.
288 *
289 * If @event is null, it implies that uevent_notify is called
290 * by resume function. When called in the resume function, cm_suspended
291 * should be already reset to false in order to let uevent_notify
292 * notify the recent event during the suspend to users. While
293 * suspended, uevent_notify does not notify users, but tracks
294 * events so that uevent_notify can notify users later after resumed.
295 */
296static void uevent_notify(struct charger_manager *cm, const char *event)
297{
298 static char env_str[UEVENT_BUF_SIZE + 1] = "";
299 static char env_str_save[UEVENT_BUF_SIZE + 1] = "";
300
301 if (cm_suspended) {
302 /* Nothing in suspended-event buffer */
303 if (env_str_save[0] == 0) {
304 if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
305 return; /* status not changed */
306 strncpy(env_str_save, event, UEVENT_BUF_SIZE);
307 return;
308 }
309
310 if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE))
311 return; /* Duplicated. */
312 else
313 strncpy(env_str_save, event, UEVENT_BUF_SIZE);
314
315 return;
316 }
317
318 if (event == NULL) {
319 /* No messages pending */
320 if (!env_str_save[0])
321 return;
322
323 strncpy(env_str, env_str_save, UEVENT_BUF_SIZE);
324 kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
325 env_str_save[0] = 0;
326
327 return;
328 }
329
330 /* status not changed */
331 if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
332 return;
333
334 /* save the status and notify the update */
335 strncpy(env_str, event, UEVENT_BUF_SIZE);
336 kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
337
338 dev_info(cm->dev, event);
339}
340
341/**
342 * _cm_monitor - Monitor the temperature and return true for exceptions.
343 * @cm: the Charger Manager representing the battery.
344 *
345 * Returns true if there is an event to notify for the battery.
346 * (True if the status of "emergency_stop" changes)
347 */
348static bool _cm_monitor(struct charger_manager *cm)
349{
350 struct charger_desc *desc = cm->desc;
351 int temp = desc->temperature_out_of_range(&cm->last_temp_mC);
352
353 dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
354 cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
355
356 /* It has been stopped or charging already */
357 if (!!temp == !!cm->emergency_stop)
358 return false;
359
360 if (temp) {
361 cm->emergency_stop = temp;
362 if (!try_charger_enable(cm, false)) {
363 if (temp > 0)
364 uevent_notify(cm, "OVERHEAT");
365 else
366 uevent_notify(cm, "COLD");
367 }
368 } else {
369 cm->emergency_stop = 0;
370 if (!try_charger_enable(cm, true))
371 uevent_notify(cm, "CHARGING");
372 }
373
374 return true;
375}
376
377/**
378 * cm_monitor - Monitor every battery.
379 *
380 * Returns true if there is an event to notify from any of the batteries.
381 * (True if the status of "emergency_stop" changes)
382 */
383static bool cm_monitor(void)
384{
385 bool stop = false;
386 struct charger_manager *cm;
387
388 mutex_lock(&cm_list_mtx);
389
390 list_for_each_entry(cm, &cm_list, entry)
391 stop = stop || _cm_monitor(cm);
392
393 mutex_unlock(&cm_list_mtx);
394
395 return stop;
396}
397
398static int charger_get_property(struct power_supply *psy,
399 enum power_supply_property psp,
400 union power_supply_propval *val)
401{
402 struct charger_manager *cm = container_of(psy,
403 struct charger_manager, charger_psy);
404 struct charger_desc *desc = cm->desc;
405 int i, ret = 0, uV;
406
407 switch (psp) {
408 case POWER_SUPPLY_PROP_STATUS:
409 if (is_charging(cm))
410 val->intval = POWER_SUPPLY_STATUS_CHARGING;
411 else if (is_ext_pwr_online(cm))
412 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
413 else
414 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
415 break;
416 case POWER_SUPPLY_PROP_HEALTH:
417 if (cm->emergency_stop > 0)
418 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
419 else if (cm->emergency_stop < 0)
420 val->intval = POWER_SUPPLY_HEALTH_COLD;
421 else
422 val->intval = POWER_SUPPLY_HEALTH_GOOD;
423 break;
424 case POWER_SUPPLY_PROP_PRESENT:
425 if (is_batt_present(cm))
426 val->intval = 1;
427 else
428 val->intval = 0;
429 break;
430 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
431 ret = get_batt_uV(cm, &i);
432 val->intval = i;
433 break;
434 case POWER_SUPPLY_PROP_CURRENT_NOW:
435 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
436 POWER_SUPPLY_PROP_CURRENT_NOW, val);
437 break;
438 case POWER_SUPPLY_PROP_TEMP:
439 /* in thenth of centigrade */
440 if (cm->last_temp_mC == INT_MIN)
441 desc->temperature_out_of_range(&cm->last_temp_mC);
442 val->intval = cm->last_temp_mC / 100;
443 if (!desc->measure_battery_temp)
444 ret = -ENODEV;
445 break;
446 case POWER_SUPPLY_PROP_TEMP_AMBIENT:
447 /* in thenth of centigrade */
448 if (cm->last_temp_mC == INT_MIN)
449 desc->temperature_out_of_range(&cm->last_temp_mC);
450 val->intval = cm->last_temp_mC / 100;
451 if (desc->measure_battery_temp)
452 ret = -ENODEV;
453 break;
454 case POWER_SUPPLY_PROP_CAPACITY:
455 if (!cm->fuel_gauge) {
456 ret = -ENODEV;
457 break;
458 }
459
460 if (!is_batt_present(cm)) {
461 /* There is no battery. Assume 100% */
462 val->intval = 100;
463 break;
464 }
465
466 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
467 POWER_SUPPLY_PROP_CAPACITY, val);
468 if (ret)
469 break;
470
471 if (val->intval > 100) {
472 val->intval = 100;
473 break;
474 }
475 if (val->intval < 0)
476 val->intval = 0;
477
478 /* Do not adjust SOC when charging: voltage is overrated */
479 if (is_charging(cm))
480 break;
481
482 /*
483 * If the capacity value is inconsistent, calibrate it base on
484 * the battery voltage values and the thresholds given as desc
485 */
486 ret = get_batt_uV(cm, &uV);
487 if (ret) {
488 /* Voltage information not available. No calibration */
489 ret = 0;
490 break;
491 }
492
493 if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
494 !is_charging(cm)) {
495 val->intval = 100;
496 break;
497 }
498
499 break;
500 case POWER_SUPPLY_PROP_ONLINE:
501 if (is_ext_pwr_online(cm))
502 val->intval = 1;
503 else
504 val->intval = 0;
505 break;
506 case POWER_SUPPLY_PROP_CHARGE_FULL:
507 if (cm->fuel_gauge) {
508 if (cm->fuel_gauge->get_property(cm->fuel_gauge,
509 POWER_SUPPLY_PROP_CHARGE_FULL, val) == 0)
510 break;
511 }
512
513 if (is_ext_pwr_online(cm)) {
514 /* Not full if it's charging. */
515 if (is_charging(cm)) {
516 val->intval = 0;
517 break;
518 }
519 /*
520 * Full if it's powered but not charging andi
521 * not forced stop by emergency
522 */
523 if (!cm->emergency_stop) {
524 val->intval = 1;
525 break;
526 }
527 }
528
529 /* Full if it's over the fullbatt voltage */
530 ret = get_batt_uV(cm, &uV);
531 if (!ret && desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
532 !is_charging(cm)) {
533 val->intval = 1;
534 break;
535 }
536
537 /* Full if the cap is 100 */
538 if (cm->fuel_gauge) {
539 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
540 POWER_SUPPLY_PROP_CAPACITY, val);
541 if (!ret && val->intval >= 100 && !is_charging(cm)) {
542 val->intval = 1;
543 break;
544 }
545 }
546
547 val->intval = 0;
548 ret = 0;
549 break;
550 case POWER_SUPPLY_PROP_CHARGE_NOW:
551 if (is_charging(cm)) {
552 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
553 POWER_SUPPLY_PROP_CHARGE_NOW,
554 val);
555 if (ret) {
556 val->intval = 1;
557 ret = 0;
558 } else {
559 /* If CHARGE_NOW is supplied, use it */
560 val->intval = (val->intval > 0) ?
561 val->intval : 1;
562 }
563 } else {
564 val->intval = 0;
565 }
566 break;
567 default:
568 return -EINVAL;
569 }
570 return ret;
571}
572
573#define NUM_CHARGER_PSY_OPTIONAL (4)
574static enum power_supply_property default_charger_props[] = {
575 /* Guaranteed to provide */
576 POWER_SUPPLY_PROP_STATUS,
577 POWER_SUPPLY_PROP_HEALTH,
578 POWER_SUPPLY_PROP_PRESENT,
579 POWER_SUPPLY_PROP_VOLTAGE_NOW,
580 POWER_SUPPLY_PROP_CAPACITY,
581 POWER_SUPPLY_PROP_ONLINE,
582 POWER_SUPPLY_PROP_CHARGE_FULL,
583 /*
584 * Optional properties are:
585 * POWER_SUPPLY_PROP_CHARGE_NOW,
586 * POWER_SUPPLY_PROP_CURRENT_NOW,
587 * POWER_SUPPLY_PROP_TEMP, and
588 * POWER_SUPPLY_PROP_TEMP_AMBIENT,
589 */
590};
591
592static struct power_supply psy_default = {
593 .name = "battery",
594 .type = POWER_SUPPLY_TYPE_BATTERY,
595 .properties = default_charger_props,
596 .num_properties = ARRAY_SIZE(default_charger_props),
597 .get_property = charger_get_property,
598};
599
600/**
601 * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
602 * for suspend_again.
603 *
604 * Returns true if the alarm is set for Charger Manager to use.
605 * Returns false if
606 * cm_setup_timer fails to set an alarm,
607 * cm_setup_timer does not need to set an alarm for Charger Manager,
608 * or an alarm previously configured is to be used.
609 */
610static bool cm_setup_timer(void)
611{
612 struct charger_manager *cm;
613 unsigned int wakeup_ms = UINT_MAX;
614 bool ret = false;
615
616 mutex_lock(&cm_list_mtx);
617
618 list_for_each_entry(cm, &cm_list, entry) {
619 /* Skip if polling is not required for this CM */
620 if (!is_polling_required(cm) && !cm->emergency_stop)
621 continue;
622 if (cm->desc->polling_interval_ms == 0)
623 continue;
624 CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms);
625 }
626
627 mutex_unlock(&cm_list_mtx);
628
629 if (wakeup_ms < UINT_MAX && wakeup_ms > 0) {
630 pr_info("Charger Manager wakeup timer: %u ms.\n", wakeup_ms);
631 if (rtc_dev) {
632 struct rtc_wkalrm tmp;
633 unsigned long time, now;
634 unsigned long add = DIV_ROUND_UP(wakeup_ms, 1000);
635
636 /*
637 * Set alarm with the polling interval (wakeup_ms)
638 * except when rtc_wkalarm_save comes first.
639 * However, the alarm time should be NOW +
640 * CM_RTC_SMALL or later.
641 */
642 tmp.enabled = 1;
643 rtc_read_time(rtc_dev, &tmp.time);
644 rtc_tm_to_time(&tmp.time, &now);
645 if (add < CM_RTC_SMALL)
646 add = CM_RTC_SMALL;
647 time = now + add;
648
649 ret = true;
650
651 if (rtc_wkalarm_save.enabled &&
652 rtc_wkalarm_save_time &&
653 rtc_wkalarm_save_time < time) {
654 if (rtc_wkalarm_save_time < now + CM_RTC_SMALL)
655 time = now + CM_RTC_SMALL;
656 else
657 time = rtc_wkalarm_save_time;
658
659 /* The timer is not appointed by CM */
660 ret = false;
661 }
662
663 pr_info("Waking up after %lu secs.\n",
664 time - now);
665
666 rtc_time_to_tm(time, &tmp.time);
667 rtc_set_alarm(rtc_dev, &tmp);
668 cm_suspend_duration_ms += wakeup_ms;
669 return ret;
670 }
671 }
672
673 if (rtc_dev)
674 rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
675 return false;
676}
677
678/**
679 * cm_suspend_again - Determine whether suspend again or not
680 *
681 * Returns true if the system should be suspended again
682 * Returns false if the system should be woken up
683 */
684bool cm_suspend_again(void)
685{
686 struct charger_manager *cm;
687 bool ret = false;
688
689 if (!g_desc || !g_desc->rtc_only_wakeup || !g_desc->rtc_only_wakeup() ||
690 !cm_rtc_set)
691 return false;
692
693 if (cm_monitor())
694 goto out;
695
696 ret = true;
697 mutex_lock(&cm_list_mtx);
698 list_for_each_entry(cm, &cm_list, entry) {
699 if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) ||
700 cm->status_save_batt != is_batt_present(cm))
701 ret = false;
702 }
703 mutex_unlock(&cm_list_mtx);
704
705 cm_rtc_set = cm_setup_timer();
706out:
707 /* It's about the time when the non-CM appointed timer goes off */
708 if (rtc_wkalarm_save.enabled) {
709 unsigned long now;
710 struct rtc_time tmp;
711
712 rtc_read_time(rtc_dev, &tmp);
713 rtc_tm_to_time(&tmp, &now);
714
715 if (rtc_wkalarm_save_time &&
716 now + CM_RTC_SMALL >= rtc_wkalarm_save_time)
717 return false;
718 }
719 return ret;
720}
721EXPORT_SYMBOL_GPL(cm_suspend_again);
722
723/**
724 * setup_charger_manager - initialize charger_global_desc data
725 * @gd: pointer to instance of charger_global_desc
726 */
727int setup_charger_manager(struct charger_global_desc *gd)
728{
729 if (!gd)
730 return -EINVAL;
731
732 if (rtc_dev)
733 rtc_class_close(rtc_dev);
734 rtc_dev = NULL;
735 g_desc = NULL;
736
737 if (!gd->rtc_only_wakeup) {
738 pr_err("The callback rtc_only_wakeup is not given.\n");
739 return -EINVAL;
740 }
741
742 if (gd->rtc_name) {
743 rtc_dev = rtc_class_open(gd->rtc_name);
744 if (IS_ERR_OR_NULL(rtc_dev)) {
745 rtc_dev = NULL;
746 /* Retry at probe. RTC may be not registered yet */
747 }
748 } else {
749 pr_warn("No wakeup timer is given for charger manager."
750 "In-suspend monitoring won't work.\n");
751 }
752
753 g_desc = gd;
754 return 0;
755}
756EXPORT_SYMBOL_GPL(setup_charger_manager);
757
758static int charger_manager_probe(struct platform_device *pdev)
759{
760 struct charger_desc *desc = dev_get_platdata(&pdev->dev);
761 struct charger_manager *cm;
762 int ret = 0, i = 0;
763 union power_supply_propval val;
764
765 if (g_desc && !rtc_dev && g_desc->rtc_name) {
766 rtc_dev = rtc_class_open(g_desc->rtc_name);
767 if (IS_ERR_OR_NULL(rtc_dev)) {
768 rtc_dev = NULL;
769 dev_err(&pdev->dev, "Cannot get RTC %s.\n",
770 g_desc->rtc_name);
771 ret = -ENODEV;
772 goto err_alloc;
773 }
774 }
775
776 if (!desc) {
777 dev_err(&pdev->dev, "No platform data (desc) found.\n");
778 ret = -ENODEV;
779 goto err_alloc;
780 }
781
782 cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL);
783 if (!cm) {
784 dev_err(&pdev->dev, "Cannot allocate memory.\n");
785 ret = -ENOMEM;
786 goto err_alloc;
787 }
788
789 /* Basic Values. Unspecified are Null or 0 */
790 cm->dev = &pdev->dev;
791 cm->desc = kzalloc(sizeof(struct charger_desc), GFP_KERNEL);
792 if (!cm->desc) {
793 dev_err(&pdev->dev, "Cannot allocate memory.\n");
794 ret = -ENOMEM;
795 goto err_alloc_desc;
796 }
797 memcpy(cm->desc, desc, sizeof(struct charger_desc));
798 cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
799
800 if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
801 ret = -EINVAL;
802 dev_err(&pdev->dev, "charger_regulators undefined.\n");
803 goto err_no_charger;
804 }
805
806 if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
807 dev_err(&pdev->dev, "No power supply defined.\n");
808 ret = -EINVAL;
809 goto err_no_charger_stat;
810 }
811
812 /* Counting index only */
813 while (desc->psy_charger_stat[i])
814 i++;
815
816 cm->charger_stat = kzalloc(sizeof(struct power_supply *) * (i + 1),
817 GFP_KERNEL);
818 if (!cm->charger_stat) {
819 ret = -ENOMEM;
820 goto err_no_charger_stat;
821 }
822
823 for (i = 0; desc->psy_charger_stat[i]; i++) {
824 cm->charger_stat[i] = power_supply_get_by_name(
825 desc->psy_charger_stat[i]);
826 if (!cm->charger_stat[i]) {
827 dev_err(&pdev->dev, "Cannot find power supply "
828 "\"%s\"\n",
829 desc->psy_charger_stat[i]);
830 ret = -ENODEV;
831 goto err_chg_stat;
832 }
833 }
834
835 cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
836 if (!cm->fuel_gauge) {
837 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
838 desc->psy_fuel_gauge);
839 ret = -ENODEV;
840 goto err_chg_stat;
841 }
842
843 if (desc->polling_interval_ms == 0 ||
844 msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) {
845 dev_err(&pdev->dev, "polling_interval_ms is too small\n");
846 ret = -EINVAL;
847 goto err_chg_stat;
848 }
849
850 if (!desc->temperature_out_of_range) {
851 dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
852 ret = -EINVAL;
853 goto err_chg_stat;
854 }
855
856 platform_set_drvdata(pdev, cm);
857
858 memcpy(&cm->charger_psy, &psy_default,
859 sizeof(psy_default));
860 if (!desc->psy_name) {
861 strncpy(cm->psy_name_buf, psy_default.name,
862 PSY_NAME_MAX);
863 } else {
864 strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
865 }
866 cm->charger_psy.name = cm->psy_name_buf;
867
868 /* Allocate for psy properties because they may vary */
869 cm->charger_psy.properties = kzalloc(sizeof(enum power_supply_property)
870 * (ARRAY_SIZE(default_charger_props) +
871 NUM_CHARGER_PSY_OPTIONAL),
872 GFP_KERNEL);
873 if (!cm->charger_psy.properties) {
874 dev_err(&pdev->dev, "Cannot allocate for psy properties.\n");
875 ret = -ENOMEM;
876 goto err_chg_stat;
877 }
878 memcpy(cm->charger_psy.properties, default_charger_props,
879 sizeof(enum power_supply_property) *
880 ARRAY_SIZE(default_charger_props));
881 cm->charger_psy.num_properties = psy_default.num_properties;
882
883 /* Find which optional psy-properties are available */
884 if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
885 POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
886 cm->charger_psy.properties[cm->charger_psy.num_properties] =
887 POWER_SUPPLY_PROP_CHARGE_NOW;
888 cm->charger_psy.num_properties++;
889 }
890 if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
891 POWER_SUPPLY_PROP_CURRENT_NOW,
892 &val)) {
893 cm->charger_psy.properties[cm->charger_psy.num_properties] =
894 POWER_SUPPLY_PROP_CURRENT_NOW;
895 cm->charger_psy.num_properties++;
896 }
897 if (!desc->measure_battery_temp) {
898 cm->charger_psy.properties[cm->charger_psy.num_properties] =
899 POWER_SUPPLY_PROP_TEMP_AMBIENT;
900 cm->charger_psy.num_properties++;
901 }
902 if (desc->measure_battery_temp) {
903 cm->charger_psy.properties[cm->charger_psy.num_properties] =
904 POWER_SUPPLY_PROP_TEMP;
905 cm->charger_psy.num_properties++;
906 }
907
908 ret = power_supply_register(NULL, &cm->charger_psy);
909 if (ret) {
910 dev_err(&pdev->dev, "Cannot register charger-manager with"
911 " name \"%s\".\n", cm->charger_psy.name);
912 goto err_register;
913 }
914
915 ret = regulator_bulk_get(&pdev->dev, desc->num_charger_regulators,
916 desc->charger_regulators);
917 if (ret) {
918 dev_err(&pdev->dev, "Cannot get charger regulators.\n");
919 goto err_bulk_get;
920 }
921
922 ret = try_charger_enable(cm, true);
923 if (ret) {
924 dev_err(&pdev->dev, "Cannot enable charger regulators\n");
925 goto err_chg_enable;
926 }
927
928 /* Add to the list */
929 mutex_lock(&cm_list_mtx);
930 list_add(&cm->entry, &cm_list);
931 mutex_unlock(&cm_list_mtx);
932
933 return 0;
934
935err_chg_enable:
936 if (desc->charger_regulators)
937 regulator_bulk_free(desc->num_charger_regulators,
938 desc->charger_regulators);
939err_bulk_get:
940 power_supply_unregister(&cm->charger_psy);
941err_register:
942 kfree(cm->charger_psy.properties);
943err_chg_stat:
944 kfree(cm->charger_stat);
945err_no_charger_stat:
946err_no_charger:
947 kfree(cm->desc);
948err_alloc_desc:
949 kfree(cm);
950err_alloc:
951 return ret;
952}
953
954static int __devexit charger_manager_remove(struct platform_device *pdev)
955{
956 struct charger_manager *cm = platform_get_drvdata(pdev);
957 struct charger_desc *desc = cm->desc;
958
959 /* Remove from the list */
960 mutex_lock(&cm_list_mtx);
961 list_del(&cm->entry);
962 mutex_unlock(&cm_list_mtx);
963
964 if (desc->charger_regulators)
965 regulator_bulk_free(desc->num_charger_regulators,
966 desc->charger_regulators);
967
968 power_supply_unregister(&cm->charger_psy);
969 kfree(cm->charger_psy.properties);
970 kfree(cm->charger_stat);
971 kfree(cm->desc);
972 kfree(cm);
973
974 return 0;
975}
976
977const struct platform_device_id charger_manager_id[] = {
978 { "charger-manager", 0 },
979 { },
980};
981
982static int cm_suspend_prepare(struct device *dev)
983{
984 struct platform_device *pdev = container_of(dev, struct platform_device,
985 dev);
986 struct charger_manager *cm = platform_get_drvdata(pdev);
987
988 if (!cm_suspended) {
989 if (rtc_dev) {
990 struct rtc_time tmp;
991 unsigned long now;
992
993 rtc_read_alarm(rtc_dev, &rtc_wkalarm_save);
994 rtc_read_time(rtc_dev, &tmp);
995
996 if (rtc_wkalarm_save.enabled) {
997 rtc_tm_to_time(&rtc_wkalarm_save.time,
998 &rtc_wkalarm_save_time);
999 rtc_tm_to_time(&tmp, &now);
1000 if (now > rtc_wkalarm_save_time)
1001 rtc_wkalarm_save_time = 0;
1002 } else {
1003 rtc_wkalarm_save_time = 0;
1004 }
1005 }
1006 cm_suspended = true;
1007 }
1008
1009 cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm);
1010 cm->status_save_batt = is_batt_present(cm);
1011
1012 if (!cm_rtc_set) {
1013 cm_suspend_duration_ms = 0;
1014 cm_rtc_set = cm_setup_timer();
1015 }
1016
1017 return 0;
1018}
1019
1020static void cm_suspend_complete(struct device *dev)
1021{
1022 struct platform_device *pdev = container_of(dev, struct platform_device,
1023 dev);
1024 struct charger_manager *cm = platform_get_drvdata(pdev);
1025
1026 if (cm_suspended) {
1027 if (rtc_dev) {
1028 struct rtc_wkalrm tmp;
1029
1030 rtc_read_alarm(rtc_dev, &tmp);
1031 rtc_wkalarm_save.pending = tmp.pending;
1032 rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
1033 }
1034 cm_suspended = false;
1035 cm_rtc_set = false;
1036 }
1037
1038 uevent_notify(cm, NULL);
1039}
1040
1041static const struct dev_pm_ops charger_manager_pm = {
1042 .prepare = cm_suspend_prepare,
1043 .complete = cm_suspend_complete,
1044};
1045
1046static struct platform_driver charger_manager_driver = {
1047 .driver = {
1048 .name = "charger-manager",
1049 .owner = THIS_MODULE,
1050 .pm = &charger_manager_pm,
1051 },
1052 .probe = charger_manager_probe,
1053 .remove = __devexit_p(charger_manager_remove),
1054 .id_table = charger_manager_id,
1055};
1056
1057static int __init charger_manager_init(void)
1058{
1059 return platform_driver_register(&charger_manager_driver);
1060}
1061late_initcall(charger_manager_init);
1062
1063static void __exit charger_manager_cleanup(void)
1064{
1065 platform_driver_unregister(&charger_manager_driver);
1066}
1067module_exit(charger_manager_cleanup);
1068
1069MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
1070MODULE_DESCRIPTION("Charger Manager");
1071MODULE_LICENSE("GPL");
1072MODULE_ALIAS("charger-manager");
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c
index 548d263b1ad0..74c6b23aeabf 100644
--- a/drivers/power/collie_battery.c
+++ b/drivers/power/collie_battery.c
@@ -146,7 +146,7 @@ static void collie_bat_external_power_changed(struct power_supply *psy)
146 146
147static irqreturn_t collie_bat_gpio_isr(int irq, void *data) 147static irqreturn_t collie_bat_gpio_isr(int irq, void *data)
148{ 148{
149 pr_info("collie_bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq))); 149 pr_info("collie_bat_gpio irq\n");
150 schedule_work(&bat_work); 150 schedule_work(&bat_work);
151 return IRQ_HANDLED; 151 return IRQ_HANDLED;
152} 152}
@@ -277,18 +277,13 @@ static struct collie_bat collie_bat_bu = {
277 .adc_temp_divider = -1, 277 .adc_temp_divider = -1,
278}; 278};
279 279
280static struct { 280static struct gpio collie_batt_gpios[] = {
281 int gpio; 281 { COLLIE_GPIO_CO, GPIOF_IN, "main battery full" },
282 char *name; 282 { COLLIE_GPIO_MAIN_BAT_LOW, GPIOF_IN, "main battery low" },
283 bool output; 283 { COLLIE_GPIO_CHARGE_ON, GPIOF_OUT_INIT_LOW, "main charge on" },
284 int value; 284 { COLLIE_GPIO_MBAT_ON, GPIOF_OUT_INIT_LOW, "main battery" },
285} gpios[] = { 285 { COLLIE_GPIO_TMP_ON, GPIOF_OUT_INIT_LOW, "main battery temp" },
286 { COLLIE_GPIO_CO, "main battery full", 0, 0 }, 286 { COLLIE_GPIO_BBAT_ON, GPIOF_OUT_INIT_LOW, "backup battery" },
287 { COLLIE_GPIO_MAIN_BAT_LOW, "main battery low", 0, 0 },
288 { COLLIE_GPIO_CHARGE_ON, "main charge on", 1, 0 },
289 { COLLIE_GPIO_MBAT_ON, "main battery", 1, 0 },
290 { COLLIE_GPIO_TMP_ON, "main battery temp", 1, 0 },
291 { COLLIE_GPIO_BBAT_ON, "backup battery", 1, 0 },
292}; 287};
293 288
294#ifdef CONFIG_PM 289#ifdef CONFIG_PM
@@ -313,29 +308,16 @@ static int collie_bat_resume(struct ucb1x00_dev *dev)
313static int __devinit collie_bat_probe(struct ucb1x00_dev *dev) 308static int __devinit collie_bat_probe(struct ucb1x00_dev *dev)
314{ 309{
315 int ret; 310 int ret;
316 int i;
317 311
318 if (!machine_is_collie()) 312 if (!machine_is_collie())
319 return -ENODEV; 313 return -ENODEV;
320 314
321 ucb = dev->ucb; 315 ucb = dev->ucb;
322 316
323 for (i = 0; i < ARRAY_SIZE(gpios); i++) { 317 ret = gpio_request_array(collie_batt_gpios,
324 ret = gpio_request(gpios[i].gpio, gpios[i].name); 318 ARRAY_SIZE(collie_batt_gpios));
325 if (ret) { 319 if (ret)
326 i--; 320 return ret;
327 goto err_gpio;
328 }
329
330 if (gpios[i].output)
331 ret = gpio_direction_output(gpios[i].gpio,
332 gpios[i].value);
333 else
334 ret = gpio_direction_input(gpios[i].gpio);
335
336 if (ret)
337 goto err_gpio;
338 }
339 321
340 mutex_init(&collie_bat_main.work_lock); 322 mutex_init(&collie_bat_main.work_lock);
341 323
@@ -363,19 +345,12 @@ err_psy_reg_main:
363 345
364 /* see comment in collie_bat_remove */ 346 /* see comment in collie_bat_remove */
365 cancel_work_sync(&bat_work); 347 cancel_work_sync(&bat_work);
366 348 gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios));
367 i--;
368err_gpio:
369 for (; i >= 0; i--)
370 gpio_free(gpios[i].gpio);
371
372 return ret; 349 return ret;
373} 350}
374 351
375static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) 352static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
376{ 353{
377 int i;
378
379 free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main); 354 free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main);
380 355
381 power_supply_unregister(&collie_bat_bu.psy); 356 power_supply_unregister(&collie_bat_bu.psy);
@@ -387,9 +362,7 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
387 * unregistered now. 362 * unregistered now.
388 */ 363 */
389 cancel_work_sync(&bat_work); 364 cancel_work_sync(&bat_work);
390 365 gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios));
391 for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
392 gpio_free(gpios[i].gpio);
393} 366}
394 367
395static struct ucb1x00_driver collie_bat_driver = { 368static struct ucb1x00_driver collie_bat_driver = {
diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
index d2c793cf6765..3fd3e95d2b85 100644
--- a/drivers/power/da9030_battery.c
+++ b/drivers/power/da9030_battery.c
@@ -588,18 +588,7 @@ static struct platform_driver da903x_battery_driver = {
588 .remove = da9030_battery_remove, 588 .remove = da9030_battery_remove,
589}; 589};
590 590
591static int da903x_battery_init(void) 591module_platform_driver(da903x_battery_driver);
592{
593 return platform_driver_register(&da903x_battery_driver);
594}
595
596static void da903x_battery_exit(void)
597{
598 platform_driver_unregister(&da903x_battery_driver);
599}
600
601module_init(da903x_battery_init);
602module_exit(da903x_battery_exit);
603 592
604MODULE_DESCRIPTION("DA9030 battery charger driver"); 593MODULE_DESCRIPTION("DA9030 battery charger driver");
605MODULE_AUTHOR("Mike Rapoport, CompuLab"); 594MODULE_AUTHOR("Mike Rapoport, CompuLab");
diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c
new file mode 100644
index 000000000000..e8ea47a53dee
--- /dev/null
+++ b/drivers/power/da9052-battery.c
@@ -0,0 +1,664 @@
1/*
2 * Batttery Driver for Dialog DA9052 PMICs
3 *
4 * Copyright(c) 2011 Dialog Semiconductor Ltd.
5 *
6 * Author: David Dajun Chen <dchen@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/delay.h>
15#include <linux/freezer.h>
16#include <linux/fs.h>
17#include <linux/jiffies.h>
18#include <linux/module.h>
19#include <linux/timer.h>
20#include <linux/uaccess.h>
21#include <linux/platform_device.h>
22#include <linux/power_supply.h>
23
24#include <linux/mfd/da9052/da9052.h>
25#include <linux/mfd/da9052/pdata.h>
26#include <linux/mfd/da9052/reg.h>
27
28/* STATIC CONFIGURATION */
29#define DA9052_BAT_CUTOFF_VOLT 2800
30#define DA9052_BAT_TSH 62000
31#define DA9052_BAT_LOW_CAP 4
32#define DA9052_AVG_SZ 4
33#define DA9052_VC_TBL_SZ 68
34#define DA9052_VC_TBL_REF_SZ 3
35
36#define DA9052_ISET_USB_MASK 0x0F
37#define DA9052_CHG_USB_ILIM_MASK 0x40
38#define DA9052_CHG_LIM_COLS 16
39
40#define DA9052_MEAN(x, y) ((x + y) / 2)
41
42enum charger_type_enum {
43 DA9052_NOCHARGER = 1,
44 DA9052_CHARGER,
45};
46
47static const u16 da9052_chg_current_lim[2][DA9052_CHG_LIM_COLS] = {
48 {70, 80, 90, 100, 110, 120, 400, 450,
49 500, 550, 600, 650, 700, 900, 1100, 1300},
50 {80, 90, 100, 110, 120, 400, 450, 500,
51 550, 600, 800, 1000, 1200, 1400, 1600, 1800},
52};
53
54static const u16 vc_tbl_ref[3] = {10, 25, 40};
55/* Lookup table for voltage vs capacity */
56static u32 const vc_tbl[3][68][2] = {
57 /* For temperature 10 degree Celsius */
58 {
59 {4082, 100}, {4036, 98},
60 {4020, 96}, {4008, 95},
61 {3997, 93}, {3983, 91},
62 {3964, 90}, {3943, 88},
63 {3926, 87}, {3912, 85},
64 {3900, 84}, {3890, 82},
65 {3881, 80}, {3873, 79},
66 {3865, 77}, {3857, 76},
67 {3848, 74}, {3839, 73},
68 {3829, 71}, {3820, 70},
69 {3811, 68}, {3802, 67},
70 {3794, 65}, {3785, 64},
71 {3778, 62}, {3770, 61},
72 {3763, 59}, {3756, 58},
73 {3750, 56}, {3744, 55},
74 {3738, 53}, {3732, 52},
75 {3727, 50}, {3722, 49},
76 {3717, 47}, {3712, 46},
77 {3708, 44}, {3703, 43},
78 {3700, 41}, {3696, 40},
79 {3693, 38}, {3691, 37},
80 {3688, 35}, {3686, 34},
81 {3683, 32}, {3681, 31},
82 {3678, 29}, {3675, 28},
83 {3672, 26}, {3669, 25},
84 {3665, 23}, {3661, 22},
85 {3656, 21}, {3651, 19},
86 {3645, 18}, {3639, 16},
87 {3631, 15}, {3622, 13},
88 {3611, 12}, {3600, 10},
89 {3587, 9}, {3572, 7},
90 {3548, 6}, {3503, 5},
91 {3420, 3}, {3268, 2},
92 {2992, 1}, {2746, 0}
93 },
94 /* For temperature 25 degree Celsius */
95 {
96 {4102, 100}, {4065, 98},
97 {4048, 96}, {4034, 95},
98 {4021, 93}, {4011, 92},
99 {4001, 90}, {3986, 88},
100 {3968, 87}, {3952, 85},
101 {3938, 84}, {3926, 82},
102 {3916, 81}, {3908, 79},
103 {3900, 77}, {3892, 76},
104 {3883, 74}, {3874, 73},
105 {3864, 71}, {3855, 70},
106 {3846, 68}, {3836, 67},
107 {3827, 65}, {3819, 64},
108 {3810, 62}, {3801, 61},
109 {3793, 59}, {3786, 58},
110 {3778, 56}, {3772, 55},
111 {3765, 53}, {3759, 52},
112 {3754, 50}, {3748, 49},
113 {3743, 47}, {3738, 46},
114 {3733, 44}, {3728, 43},
115 {3724, 41}, {3720, 40},
116 {3716, 38}, {3712, 37},
117 {3709, 35}, {3706, 34},
118 {3703, 33}, {3701, 31},
119 {3698, 30}, {3696, 28},
120 {3693, 27}, {3690, 25},
121 {3687, 24}, {3683, 22},
122 {3680, 21}, {3675, 19},
123 {3671, 18}, {3666, 17},
124 {3660, 15}, {3654, 14},
125 {3647, 12}, {3639, 11},
126 {3630, 9}, {3621, 8},
127 {3613, 6}, {3606, 5},
128 {3597, 4}, {3582, 2},
129 {3546, 1}, {2747, 0}
130 },
131 /* For temperature 40 degree Celsius */
132 {
133 {4114, 100}, {4081, 98},
134 {4065, 96}, {4050, 95},
135 {4036, 93}, {4024, 92},
136 {4013, 90}, {4002, 88},
137 {3990, 87}, {3976, 85},
138 {3962, 84}, {3950, 82},
139 {3939, 81}, {3930, 79},
140 {3921, 77}, {3912, 76},
141 {3902, 74}, {3893, 73},
142 {3883, 71}, {3874, 70},
143 {3865, 68}, {3856, 67},
144 {3847, 65}, {3838, 64},
145 {3829, 62}, {3820, 61},
146 {3812, 59}, {3803, 58},
147 {3795, 56}, {3787, 55},
148 {3780, 53}, {3773, 52},
149 {3767, 50}, {3761, 49},
150 {3756, 47}, {3751, 46},
151 {3746, 44}, {3741, 43},
152 {3736, 41}, {3732, 40},
153 {3728, 38}, {3724, 37},
154 {3720, 35}, {3716, 34},
155 {3713, 33}, {3710, 31},
156 {3707, 30}, {3704, 28},
157 {3701, 27}, {3698, 25},
158 {3695, 24}, {3691, 22},
159 {3686, 21}, {3681, 19},
160 {3676, 18}, {3671, 17},
161 {3666, 15}, {3661, 14},
162 {3655, 12}, {3648, 11},
163 {3640, 9}, {3632, 8},
164 {3622, 6}, {3616, 5},
165 {3611, 4}, {3604, 2},
166 {3594, 1}, {2747, 0}
167 }
168};
169
170struct da9052_battery {
171 struct da9052 *da9052;
172 struct power_supply psy;
173 struct notifier_block nb;
174 int charger_type;
175 int status;
176 int health;
177};
178
179static inline int volt_reg_to_mV(int value)
180{
181 return ((value * 1000) / 512) + 2500;
182}
183
184static inline int ichg_reg_to_mA(int value)
185{
186 return (value * 3900) / 1000;
187}
188
189static int da9052_read_chgend_current(struct da9052_battery *bat,
190 int *current_mA)
191{
192 int ret;
193
194 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
195 return -EINVAL;
196
197 ret = da9052_reg_read(bat->da9052, DA9052_ICHG_END_REG);
198 if (ret < 0)
199 return ret;
200
201 *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGEND_ICHGEND);
202
203 return 0;
204}
205
206static int da9052_read_chg_current(struct da9052_battery *bat, int *current_mA)
207{
208 int ret;
209
210 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
211 return -EINVAL;
212
213 ret = da9052_reg_read(bat->da9052, DA9052_ICHG_AV_REG);
214 if (ret < 0)
215 return ret;
216
217 *current_mA = ichg_reg_to_mA(ret & DA9052_ICHGAV_ICHGAV);
218
219 return 0;
220}
221
222static int da9052_bat_check_status(struct da9052_battery *bat, int *status)
223{
224 u8 v[2] = {0, 0};
225 u8 bat_status;
226 u8 chg_end;
227 int ret;
228 int chg_current;
229 int chg_end_current;
230 bool dcinsel;
231 bool dcindet;
232 bool vbussel;
233 bool vbusdet;
234 bool dc;
235 bool vbus;
236
237 ret = da9052_group_read(bat->da9052, DA9052_STATUS_A_REG, 2, v);
238 if (ret < 0)
239 return ret;
240
241 bat_status = v[0];
242 chg_end = v[1];
243
244 dcinsel = bat_status & DA9052_STATUSA_DCINSEL;
245 dcindet = bat_status & DA9052_STATUSA_DCINDET;
246 vbussel = bat_status & DA9052_STATUSA_VBUSSEL;
247 vbusdet = bat_status & DA9052_STATUSA_VBUSDET;
248 dc = dcinsel && dcindet;
249 vbus = vbussel && vbusdet;
250
251 /* Preference to WALL(DCIN) charger unit */
252 if (dc || vbus) {
253 bat->charger_type = DA9052_CHARGER;
254
255 /* If charging end flag is set and Charging current is greater
256 * than charging end limit then battery is charging
257 */
258 if ((chg_end & DA9052_STATUSB_CHGEND) != 0) {
259 ret = da9052_read_chg_current(bat, &chg_current);
260 if (ret < 0)
261 return ret;
262 ret = da9052_read_chgend_current(bat, &chg_end_current);
263 if (ret < 0)
264 return ret;
265
266 if (chg_current >= chg_end_current)
267 bat->status = POWER_SUPPLY_STATUS_CHARGING;
268 else
269 bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
270 } else {
271 /* If Charging end flag is cleared then battery is
272 * charging
273 */
274 bat->status = POWER_SUPPLY_STATUS_CHARGING;
275 }
276 } else if (dcindet || vbusdet) {
277 bat->charger_type = DA9052_CHARGER;
278 bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
279 } else {
280 bat->charger_type = DA9052_NOCHARGER;
281 bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
282 }
283
284 if (status != NULL)
285 *status = bat->status;
286 return 0;
287}
288
289static int da9052_bat_read_volt(struct da9052_battery *bat, int *volt_mV)
290{
291 int volt;
292
293 volt = da9052_adc_manual_read(bat->da9052, DA9052_ADC_MAN_MUXSEL_VBAT);
294 if (volt < 0)
295 return volt;
296
297 *volt_mV = volt_reg_to_mV(volt);
298
299 return 0;
300}
301
302static int da9052_bat_check_presence(struct da9052_battery *bat, int *illegal)
303{
304 int bat_temp;
305
306 bat_temp = da9052_adc_read_temp(bat->da9052);
307 if (bat_temp < 0)
308 return bat_temp;
309
310 if (bat_temp > DA9052_BAT_TSH)
311 *illegal = 1;
312 else
313 *illegal = 0;
314
315 return 0;
316}
317
318static int da9052_bat_interpolate(int vbat_lower, int vbat_upper,
319 int level_lower, int level_upper,
320 int bat_voltage)
321{
322 int tmp;
323
324 tmp = ((level_upper - level_lower) * 1000) / (vbat_upper - vbat_lower);
325 tmp = level_lower + (((bat_voltage - vbat_lower) * tmp) / 1000);
326
327 return tmp;
328}
329
330unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
331{
332 int i;
333
334 if (adc_temp <= vc_tbl_ref[0])
335 return 0;
336
337 if (adc_temp > vc_tbl_ref[DA9052_VC_TBL_REF_SZ - 1])
338 return DA9052_VC_TBL_REF_SZ - 1;
339
340 for (i = 0; i < DA9052_VC_TBL_REF_SZ; i++) {
341 if ((adc_temp > vc_tbl_ref[i]) &&
342 (adc_temp <= DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1])))
343 return i;
344 if ((adc_temp > DA9052_MEAN(vc_tbl_ref[i], vc_tbl_ref[i + 1]))
345 && (adc_temp <= vc_tbl_ref[i]))
346 return i + 1;
347 }
348}
349
350static int da9052_bat_read_capacity(struct da9052_battery *bat, int *capacity)
351{
352 int adc_temp;
353 int bat_voltage;
354 int vbat_lower;
355 int vbat_upper;
356 int level_upper;
357 int level_lower;
358 int ret;
359 int flag;
360 int i = 0;
361 int j;
362
363 ret = da9052_bat_read_volt(bat, &bat_voltage);
364 if (ret < 0)
365 return ret;
366
367 adc_temp = da9052_adc_read_temp(bat->da9052);
368 if (adc_temp < 0)
369 return adc_temp;
370
371 i = da9052_determine_vc_tbl_index(adc_temp);
372
373 if (bat_voltage >= vc_tbl[i][0][0]) {
374 *capacity = 100;
375 return 0;
376 }
377 if (bat_voltage <= vc_tbl[i][DA9052_VC_TBL_SZ - 1][0]) {
378 *capacity = 0;
379 return 0;
380 }
381 flag = 0;
382
383 for (j = 0; j < (DA9052_VC_TBL_SZ-1); j++) {
384 if ((bat_voltage <= vc_tbl[i][j][0]) &&
385 (bat_voltage >= vc_tbl[i][j + 1][0])) {
386 vbat_upper = vc_tbl[i][j][0];
387 vbat_lower = vc_tbl[i][j + 1][0];
388 level_upper = vc_tbl[i][j][1];
389 level_lower = vc_tbl[i][j + 1][1];
390 flag = 1;
391 break;
392 }
393 }
394 if (!flag)
395 return -EIO;
396
397 *capacity = da9052_bat_interpolate(vbat_lower, vbat_upper, level_lower,
398 level_upper, bat_voltage);
399
400 return 0;
401}
402
403static int da9052_bat_check_health(struct da9052_battery *bat, int *health)
404{
405 int ret;
406 int bat_illegal;
407 int capacity;
408
409 ret = da9052_bat_check_presence(bat, &bat_illegal);
410 if (ret < 0)
411 return ret;
412
413 if (bat_illegal) {
414 bat->health = POWER_SUPPLY_HEALTH_UNKNOWN;
415 return 0;
416 }
417
418 if (bat->health != POWER_SUPPLY_HEALTH_OVERHEAT) {
419 ret = da9052_bat_read_capacity(bat, &capacity);
420 if (ret < 0)
421 return ret;
422 if (capacity < DA9052_BAT_LOW_CAP)
423 bat->health = POWER_SUPPLY_HEALTH_DEAD;
424 else
425 bat->health = POWER_SUPPLY_HEALTH_GOOD;
426 }
427
428 *health = bat->health;
429
430 return 0;
431}
432
433static irqreturn_t da9052_bat_irq(int irq, void *data)
434{
435 struct da9052_battery *bat = data;
436
437 irq -= bat->da9052->irq_base;
438
439 if (irq == DA9052_IRQ_CHGEND)
440 bat->status = POWER_SUPPLY_STATUS_FULL;
441 else
442 da9052_bat_check_status(bat, NULL);
443
444 if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN ||
445 irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) {
446 power_supply_changed(&bat->psy);
447 }
448
449 return IRQ_HANDLED;
450}
451
452static int da9052_USB_current_notifier(struct notifier_block *nb,
453 unsigned long events, void *data)
454{
455 u8 row;
456 u8 col;
457 int *current_mA = data;
458 int ret;
459 struct da9052_battery *bat = container_of(nb, struct da9052_battery,
460 nb);
461
462 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
463 return -EPERM;
464
465 ret = da9052_reg_read(bat->da9052, DA9052_CHGBUCK_REG);
466 if (ret & DA9052_CHG_USB_ILIM_MASK)
467 return -EPERM;
468
469 if (bat->da9052->chip_id == DA9052)
470 row = 0;
471 else
472 row = 1;
473
474 if (*current_mA < da9052_chg_current_lim[row][0] ||
475 *current_mA > da9052_chg_current_lim[row][DA9052_CHG_LIM_COLS - 1])
476 return -EINVAL;
477
478 for (col = 0; col <= DA9052_CHG_LIM_COLS - 1 ; col++) {
479 if (*current_mA <= da9052_chg_current_lim[row][col])
480 break;
481 }
482
483 return da9052_reg_update(bat->da9052, DA9052_ISET_REG,
484 DA9052_ISET_USB_MASK, col);
485}
486
487static int da9052_bat_get_property(struct power_supply *psy,
488 enum power_supply_property psp,
489 union power_supply_propval *val)
490{
491 int ret;
492 int illegal;
493 struct da9052_battery *bat = container_of(psy, struct da9052_battery,
494 psy);
495
496 ret = da9052_bat_check_presence(bat, &illegal);
497 if (ret < 0)
498 return ret;
499
500 if (illegal && psp != POWER_SUPPLY_PROP_PRESENT)
501 return -ENODEV;
502
503 switch (psp) {
504 case POWER_SUPPLY_PROP_STATUS:
505 ret = da9052_bat_check_status(bat, &val->intval);
506 break;
507 case POWER_SUPPLY_PROP_ONLINE:
508 val->intval =
509 (bat->charger_type == DA9052_NOCHARGER) ? 0 : 1;
510 break;
511 case POWER_SUPPLY_PROP_PRESENT:
512 ret = da9052_bat_check_presence(bat, &val->intval);
513 break;
514 case POWER_SUPPLY_PROP_HEALTH:
515 ret = da9052_bat_check_health(bat, &val->intval);
516 break;
517 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
518 val->intval = DA9052_BAT_CUTOFF_VOLT * 1000;
519 break;
520 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
521 ret = da9052_bat_read_volt(bat, &val->intval);
522 break;
523 case POWER_SUPPLY_PROP_CURRENT_AVG:
524 ret = da9052_read_chg_current(bat, &val->intval);
525 break;
526 case POWER_SUPPLY_PROP_CAPACITY:
527 ret = da9052_bat_read_capacity(bat, &val->intval);
528 break;
529 case POWER_SUPPLY_PROP_TEMP:
530 val->intval = da9052_adc_read_temp(bat->da9052);
531 ret = val->intval;
532 break;
533 case POWER_SUPPLY_PROP_TECHNOLOGY:
534 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
535 break;
536 default:
537 return -EINVAL;
538 }
539 return ret;
540}
541
542static enum power_supply_property da9052_bat_props[] = {
543 POWER_SUPPLY_PROP_STATUS,
544 POWER_SUPPLY_PROP_ONLINE,
545 POWER_SUPPLY_PROP_PRESENT,
546 POWER_SUPPLY_PROP_HEALTH,
547 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
548 POWER_SUPPLY_PROP_VOLTAGE_AVG,
549 POWER_SUPPLY_PROP_CURRENT_AVG,
550 POWER_SUPPLY_PROP_CAPACITY,
551 POWER_SUPPLY_PROP_TEMP,
552 POWER_SUPPLY_PROP_TECHNOLOGY,
553};
554
555static struct power_supply template_battery = {
556 .name = "da9052-bat",
557 .type = POWER_SUPPLY_TYPE_BATTERY,
558 .properties = da9052_bat_props,
559 .num_properties = ARRAY_SIZE(da9052_bat_props),
560 .get_property = da9052_bat_get_property,
561};
562
563static const char *const da9052_bat_irqs[] = {
564 "BATT TEMP",
565 "DCIN DET",
566 "DCIN REM",
567 "VBUS DET",
568 "VBUS REM",
569 "CHG END",
570};
571
572static s32 __devinit da9052_bat_probe(struct platform_device *pdev)
573{
574 struct da9052_pdata *pdata;
575 struct da9052_battery *bat;
576 int ret;
577 int irq;
578 int i;
579
580 bat = kzalloc(sizeof(struct da9052_battery), GFP_KERNEL);
581 if (!bat)
582 return -ENOMEM;
583
584 bat->da9052 = dev_get_drvdata(pdev->dev.parent);
585 bat->psy = template_battery;
586 bat->charger_type = DA9052_NOCHARGER;
587 bat->status = POWER_SUPPLY_STATUS_UNKNOWN;
588 bat->health = POWER_SUPPLY_HEALTH_UNKNOWN;
589 bat->nb.notifier_call = da9052_USB_current_notifier;
590
591 pdata = bat->da9052->dev->platform_data;
592 if (pdata != NULL && pdata->use_for_apm)
593 bat->psy.use_for_apm = pdata->use_for_apm;
594 else
595 bat->psy.use_for_apm = 1;
596
597 for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
598 irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
599 ret = request_threaded_irq(bat->da9052->irq_base + irq,
600 NULL, da9052_bat_irq,
601 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
602 da9052_bat_irqs[i], bat);
603 if (ret != 0) {
604 dev_err(bat->da9052->dev,
605 "DA9052 failed to request %s IRQ %d: %d\n",
606 da9052_bat_irqs[i], irq, ret);
607 goto err;
608 }
609 }
610
611 ret = power_supply_register(&pdev->dev, &bat->psy);
612 if (ret)
613 goto err;
614
615 return 0;
616
617err:
618 for (; i >= 0; i--) {
619 irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
620 free_irq(bat->da9052->irq_base + irq, bat);
621 }
622 kfree(bat);
623 return ret;
624}
625static int __devexit da9052_bat_remove(struct platform_device *pdev)
626{
627 int i;
628 int irq;
629 struct da9052_battery *bat = platform_get_drvdata(pdev);
630
631 for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
632 irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
633 free_irq(bat->da9052->irq_base + irq, bat);
634 }
635 power_supply_unregister(&bat->psy);
636
637 return 0;
638}
639
640static struct platform_driver da9052_bat_driver = {
641 .probe = da9052_bat_probe,
642 .remove = __devexit_p(da9052_bat_remove),
643 .driver = {
644 .name = "da9052-bat",
645 .owner = THIS_MODULE,
646 },
647};
648
649static int __init da9052_bat_init(void)
650{
651 return platform_driver_register(&da9052_bat_driver);
652}
653module_init(da9052_bat_init);
654
655static void __exit da9052_bat_exit(void)
656{
657 platform_driver_unregister(&da9052_bat_driver);
658}
659module_exit(da9052_bat_exit);
660
661MODULE_DESCRIPTION("DA9052 BAT Device Driver");
662MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
663MODULE_LICENSE("GPL");
664MODULE_ALIAS("platform:da9052-bat");
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index f2c9cc33c0f9..545874b1df9e 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -95,7 +95,11 @@ static int rated_capacities[] = {
95 2880, /* Samsung */ 95 2880, /* Samsung */
96 2880, /* BYD */ 96 2880, /* BYD */
97 2880, /* Lishen */ 97 2880, /* Lishen */
98 2880 /* NEC */ 98 2880, /* NEC */
99#ifdef CONFIG_MACH_H4700
100 0,
101 3600, /* HP iPAQ hx4700 3.7V 3600mAh (359114-001) */
102#endif
99}; 103};
100 104
101/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C 105/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C
@@ -637,18 +641,7 @@ static struct platform_driver ds2760_battery_driver = {
637 .resume = ds2760_battery_resume, 641 .resume = ds2760_battery_resume,
638}; 642};
639 643
640static int __init ds2760_battery_init(void) 644module_platform_driver(ds2760_battery_driver);
641{
642 return platform_driver_register(&ds2760_battery_driver);
643}
644
645static void __exit ds2760_battery_exit(void)
646{
647 platform_driver_unregister(&ds2760_battery_driver);
648}
649
650module_init(ds2760_battery_init);
651module_exit(ds2760_battery_exit);
652 645
653MODULE_LICENSE("GPL"); 646MODULE_LICENSE("GPL");
654MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, " 647MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c
index 91a783d72360..de31cae1ba53 100644
--- a/drivers/power/ds2780_battery.c
+++ b/drivers/power/ds2780_battery.c
@@ -841,29 +841,17 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev)
841 return 0; 841 return 0;
842} 842}
843 843
844MODULE_ALIAS("platform:ds2780-battery");
845
846static struct platform_driver ds2780_battery_driver = { 844static struct platform_driver ds2780_battery_driver = {
847 .driver = { 845 .driver = {
848 .name = "ds2780-battery", 846 .name = "ds2780-battery",
849 }, 847 },
850 .probe = ds2780_battery_probe, 848 .probe = ds2780_battery_probe,
851 .remove = ds2780_battery_remove, 849 .remove = __devexit_p(ds2780_battery_remove),
852}; 850};
853 851
854static int __init ds2780_battery_init(void) 852module_platform_driver(ds2780_battery_driver);
855{
856 return platform_driver_register(&ds2780_battery_driver);
857}
858
859static void __exit ds2780_battery_exit(void)
860{
861 platform_driver_unregister(&ds2780_battery_driver);
862}
863
864module_init(ds2780_battery_init);
865module_exit(ds2780_battery_exit);
866 853
867MODULE_LICENSE("GPL"); 854MODULE_LICENSE("GPL");
868MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>"); 855MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>");
869MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver"); 856MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver");
857MODULE_ALIAS("platform:ds2780-battery");
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c
index a64b8854cfd5..8672c9177dd7 100644
--- a/drivers/power/gpio-charger.c
+++ b/drivers/power/gpio-charger.c
@@ -185,17 +185,7 @@ static struct platform_driver gpio_charger_driver = {
185 }, 185 },
186}; 186};
187 187
188static int __init gpio_charger_init(void) 188module_platform_driver(gpio_charger_driver);
189{
190 return platform_driver_register(&gpio_charger_driver);
191}
192module_init(gpio_charger_init);
193
194static void __exit gpio_charger_exit(void)
195{
196 platform_driver_unregister(&gpio_charger_driver);
197}
198module_exit(gpio_charger_exit);
199 189
200MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 190MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
201MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO"); 191MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO");
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c
index 01fa671ec97f..d09649706bd3 100644
--- a/drivers/power/intel_mid_battery.c
+++ b/drivers/power/intel_mid_battery.c
@@ -779,18 +779,7 @@ static struct platform_driver platform_pmic_battery_driver = {
779 .remove = __devexit_p(platform_pmic_battery_remove), 779 .remove = __devexit_p(platform_pmic_battery_remove),
780}; 780};
781 781
782static int __init platform_pmic_battery_module_init(void) 782module_platform_driver(platform_pmic_battery_driver);
783{
784 return platform_driver_register(&platform_pmic_battery_driver);
785}
786
787static void __exit platform_pmic_battery_module_exit(void)
788{
789 platform_driver_unregister(&platform_pmic_battery_driver);
790}
791
792module_init(platform_pmic_battery_module_init);
793module_exit(platform_pmic_battery_module_exit);
794 783
795MODULE_AUTHOR("Nithish Mahalingam <nithish.mahalingam@intel.com>"); 784MODULE_AUTHOR("Nithish Mahalingam <nithish.mahalingam@intel.com>");
796MODULE_DESCRIPTION("Intel Moorestown PMIC Battery Driver"); 785MODULE_DESCRIPTION("Intel Moorestown PMIC Battery Driver");
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index f6d72b402a8e..b806667b59ae 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -79,7 +79,7 @@ static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on)
79{ 79{
80 struct isp1704_charger_data *board = isp->dev->platform_data; 80 struct isp1704_charger_data *board = isp->dev->platform_data;
81 81
82 if (board->set_power) 82 if (board && board->set_power)
83 board->set_power(on); 83 board->set_power(on);
84} 84}
85 85
@@ -494,17 +494,7 @@ static struct platform_driver isp1704_charger_driver = {
494 .remove = __devexit_p(isp1704_charger_remove), 494 .remove = __devexit_p(isp1704_charger_remove),
495}; 495};
496 496
497static int __init isp1704_charger_init(void) 497module_platform_driver(isp1704_charger_driver);
498{
499 return platform_driver_register(&isp1704_charger_driver);
500}
501module_init(isp1704_charger_init);
502
503static void __exit isp1704_charger_exit(void)
504{
505 platform_driver_unregister(&isp1704_charger_driver);
506}
507module_exit(isp1704_charger_exit);
508 498
509MODULE_ALIAS("platform:isp1704_charger"); 499MODULE_ALIAS("platform:isp1704_charger");
510MODULE_AUTHOR("Nokia Corporation"); 500MODULE_AUTHOR("Nokia Corporation");
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index 763f894ed188..8dbc7bfaab14 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -67,7 +67,7 @@ static irqreturn_t jz_battery_irq_handler(int irq, void *devid)
67 67
68static long jz_battery_read_voltage(struct jz_battery *battery) 68static long jz_battery_read_voltage(struct jz_battery *battery)
69{ 69{
70 unsigned long t; 70 long t;
71 unsigned long val; 71 unsigned long val;
72 long voltage; 72 long voltage;
73 73
@@ -441,17 +441,7 @@ static struct platform_driver jz_battery_driver = {
441 }, 441 },
442}; 442};
443 443
444static int __init jz_battery_init(void) 444module_platform_driver(jz_battery_driver);
445{
446 return platform_driver_register(&jz_battery_driver);
447}
448module_init(jz_battery_init);
449
450static void __exit jz_battery_exit(void)
451{
452 platform_driver_unregister(&jz_battery_driver);
453}
454module_exit(jz_battery_exit);
455 445
456MODULE_ALIAS("platform:jz4740-battery"); 446MODULE_ALIAS("platform:jz4740-battery");
457MODULE_LICENSE("GPL"); 447MODULE_LICENSE("GPL");
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c
new file mode 100644
index 000000000000..b15b575c070c
--- /dev/null
+++ b/drivers/power/lp8727_charger.c
@@ -0,0 +1,494 @@
1/*
2 * Driver for LP8727 Micro/Mini USB IC with intergrated charger
3 *
4 * Copyright (C) 2011 National Semiconductor
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/interrupt.h>
15#include <linux/i2c.h>
16#include <linux/power_supply.h>
17#include <linux/lp8727.h>
18
19#define DEBOUNCE_MSEC 270
20
21/* Registers */
22#define CTRL1 0x1
23#define CTRL2 0x2
24#define SWCTRL 0x3
25#define INT1 0x4
26#define INT2 0x5
27#define STATUS1 0x6
28#define STATUS2 0x7
29#define CHGCTRL2 0x9
30
31/* CTRL1 register */
32#define CP_EN (1 << 0)
33#define ADC_EN (1 << 1)
34#define ID200_EN (1 << 4)
35
36/* CTRL2 register */
37#define CHGDET_EN (1 << 1)
38#define INT_EN (1 << 6)
39
40/* SWCTRL register */
41#define SW_DM1_DM (0x0 << 0)
42#define SW_DM1_U1 (0x1 << 0)
43#define SW_DM1_HiZ (0x7 << 0)
44#define SW_DP2_DP (0x0 << 3)
45#define SW_DP2_U2 (0x1 << 3)
46#define SW_DP2_HiZ (0x7 << 3)
47
48/* INT1 register */
49#define IDNO (0xF << 0)
50#define VBUS (1 << 4)
51
52/* STATUS1 register */
53#define CHGSTAT (3 << 4)
54#define CHPORT (1 << 6)
55#define DCPORT (1 << 7)
56
57/* STATUS2 register */
58#define TEMP_STAT (3 << 5)
59
60enum lp8727_dev_id {
61 ID_NONE,
62 ID_TA,
63 ID_DEDICATED_CHG,
64 ID_USB_CHG,
65 ID_USB_DS,
66 ID_MAX,
67};
68
69enum lp8727_chg_stat {
70 PRECHG,
71 CC,
72 CV,
73 EOC,
74};
75
76struct lp8727_psy {
77 struct power_supply ac;
78 struct power_supply usb;
79 struct power_supply batt;
80};
81
82struct lp8727_chg {
83 struct device *dev;
84 struct i2c_client *client;
85 struct mutex xfer_lock;
86 struct delayed_work work;
87 struct workqueue_struct *irqthread;
88 struct lp8727_platform_data *pdata;
89 struct lp8727_psy *psy;
90 struct lp8727_chg_param *chg_parm;
91 enum lp8727_dev_id devid;
92};
93
94static int lp8727_i2c_read(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
95{
96 s32 ret;
97
98 mutex_lock(&pchg->xfer_lock);
99 ret = i2c_smbus_read_i2c_block_data(pchg->client, reg, len, data);
100 mutex_unlock(&pchg->xfer_lock);
101
102 return (ret != len) ? -EIO : 0;
103}
104
105static int lp8727_i2c_write(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
106{
107 s32 ret;
108
109 mutex_lock(&pchg->xfer_lock);
110 ret = i2c_smbus_write_i2c_block_data(pchg->client, reg, len, data);
111 mutex_unlock(&pchg->xfer_lock);
112
113 return ret;
114}
115
116static inline int lp8727_i2c_read_byte(struct lp8727_chg *pchg, u8 reg,
117 u8 *data)
118{
119 return lp8727_i2c_read(pchg, reg, data, 1);
120}
121
122static inline int lp8727_i2c_write_byte(struct lp8727_chg *pchg, u8 reg,
123 u8 *data)
124{
125 return lp8727_i2c_write(pchg, reg, data, 1);
126}
127
128static int lp8727_is_charger_attached(const char *name, int id)
129{
130 if (name) {
131 if (!strcmp(name, "ac"))
132 return (id == ID_TA || id == ID_DEDICATED_CHG) ? 1 : 0;
133 else if (!strcmp(name, "usb"))
134 return (id == ID_USB_CHG) ? 1 : 0;
135 }
136
137 return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0;
138}
139
140static void lp8727_init_device(struct lp8727_chg *pchg)
141{
142 u8 val;
143
144 val = ID200_EN | ADC_EN | CP_EN;
145 if (lp8727_i2c_write_byte(pchg, CTRL1, &val))
146 dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL1);
147
148 val = INT_EN | CHGDET_EN;
149 if (lp8727_i2c_write_byte(pchg, CTRL2, &val))
150 dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL2);
151}
152
153static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg)
154{
155 u8 val;
156 lp8727_i2c_read_byte(pchg, STATUS1, &val);
157 return (val & DCPORT);
158}
159
160static int lp8727_is_usb_charger(struct lp8727_chg *pchg)
161{
162 u8 val;
163 lp8727_i2c_read_byte(pchg, STATUS1, &val);
164 return (val & CHPORT);
165}
166
167static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
168{
169 u8 val = sw;
170 lp8727_i2c_write_byte(pchg, SWCTRL, &val);
171}
172
173static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin)
174{
175 u8 devid = ID_NONE;
176 u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ;
177
178 switch (id) {
179 case 0x5:
180 devid = ID_TA;
181 pchg->chg_parm = &pchg->pdata->ac;
182 break;
183 case 0xB:
184 if (lp8727_is_dedicated_charger(pchg)) {
185 pchg->chg_parm = &pchg->pdata->ac;
186 devid = ID_DEDICATED_CHG;
187 } else if (lp8727_is_usb_charger(pchg)) {
188 pchg->chg_parm = &pchg->pdata->usb;
189 devid = ID_USB_CHG;
190 swctrl = SW_DM1_DM | SW_DP2_DP;
191 } else if (vbusin) {
192 devid = ID_USB_DS;
193 swctrl = SW_DM1_DM | SW_DP2_DP;
194 }
195 break;
196 default:
197 devid = ID_NONE;
198 pchg->chg_parm = NULL;
199 break;
200 }
201
202 pchg->devid = devid;
203 lp8727_ctrl_switch(pchg, swctrl);
204}
205
206static void lp8727_enable_chgdet(struct lp8727_chg *pchg)
207{
208 u8 val;
209
210 lp8727_i2c_read_byte(pchg, CTRL2, &val);
211 val |= CHGDET_EN;
212 lp8727_i2c_write_byte(pchg, CTRL2, &val);
213}
214
215static void lp8727_delayed_func(struct work_struct *_work)
216{
217 u8 intstat[2], idno, vbus;
218 struct lp8727_chg *pchg =
219 container_of(_work, struct lp8727_chg, work.work);
220
221 if (lp8727_i2c_read(pchg, INT1, intstat, 2)) {
222 dev_err(pchg->dev, "can not read INT registers\n");
223 return;
224 }
225
226 idno = intstat[0] & IDNO;
227 vbus = intstat[0] & VBUS;
228
229 lp8727_id_detection(pchg, idno, vbus);
230 lp8727_enable_chgdet(pchg);
231
232 power_supply_changed(&pchg->psy->ac);
233 power_supply_changed(&pchg->psy->usb);
234 power_supply_changed(&pchg->psy->batt);
235}
236
237static irqreturn_t lp8727_isr_func(int irq, void *ptr)
238{
239 struct lp8727_chg *pchg = ptr;
240 unsigned long delay = msecs_to_jiffies(DEBOUNCE_MSEC);
241
242 queue_delayed_work(pchg->irqthread, &pchg->work, delay);
243
244 return IRQ_HANDLED;
245}
246
247static void lp8727_intr_config(struct lp8727_chg *pchg)
248{
249 INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func);
250
251 pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd");
252 if (!pchg->irqthread)
253 dev_err(pchg->dev, "can not create thread for lp8727\n");
254
255 if (request_threaded_irq(pchg->client->irq,
256 NULL,
257 lp8727_isr_func,
258 IRQF_TRIGGER_FALLING, "lp8727_irq", pchg)) {
259 dev_err(pchg->dev, "lp8727 irq can not be registered\n");
260 }
261}
262
263static enum power_supply_property lp8727_charger_prop[] = {
264 POWER_SUPPLY_PROP_ONLINE,
265};
266
267static enum power_supply_property lp8727_battery_prop[] = {
268 POWER_SUPPLY_PROP_STATUS,
269 POWER_SUPPLY_PROP_HEALTH,
270 POWER_SUPPLY_PROP_PRESENT,
271 POWER_SUPPLY_PROP_VOLTAGE_NOW,
272 POWER_SUPPLY_PROP_CAPACITY,
273 POWER_SUPPLY_PROP_TEMP,
274};
275
276static char *battery_supplied_to[] = {
277 "main_batt",
278};
279
280static int lp8727_charger_get_property(struct power_supply *psy,
281 enum power_supply_property psp,
282 union power_supply_propval *val)
283{
284 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
285
286 if (psp == POWER_SUPPLY_PROP_ONLINE)
287 val->intval = lp8727_is_charger_attached(psy->name,
288 pchg->devid);
289
290 return 0;
291}
292
293static int lp8727_battery_get_property(struct power_supply *psy,
294 enum power_supply_property psp,
295 union power_supply_propval *val)
296{
297 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
298 u8 read;
299
300 switch (psp) {
301 case POWER_SUPPLY_PROP_STATUS:
302 if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
303 lp8727_i2c_read_byte(pchg, STATUS1, &read);
304 if (((read & CHGSTAT) >> 4) == EOC)
305 val->intval = POWER_SUPPLY_STATUS_FULL;
306 else
307 val->intval = POWER_SUPPLY_STATUS_CHARGING;
308 } else {
309 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
310 }
311 break;
312 case POWER_SUPPLY_PROP_HEALTH:
313 lp8727_i2c_read_byte(pchg, STATUS2, &read);
314 read = (read & TEMP_STAT) >> 5;
315 if (read >= 0x1 && read <= 0x3)
316 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
317 else
318 val->intval = POWER_SUPPLY_HEALTH_GOOD;
319 break;
320 case POWER_SUPPLY_PROP_PRESENT:
321 if (pchg->pdata->get_batt_present)
322 val->intval = pchg->pdata->get_batt_present();
323 break;
324 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
325 if (pchg->pdata->get_batt_level)
326 val->intval = pchg->pdata->get_batt_level();
327 break;
328 case POWER_SUPPLY_PROP_CAPACITY:
329 if (pchg->pdata->get_batt_capacity)
330 val->intval = pchg->pdata->get_batt_capacity();
331 break;
332 case POWER_SUPPLY_PROP_TEMP:
333 if (pchg->pdata->get_batt_temp)
334 val->intval = pchg->pdata->get_batt_temp();
335 break;
336 default:
337 break;
338 }
339
340 return 0;
341}
342
343static void lp8727_charger_changed(struct power_supply *psy)
344{
345 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
346 u8 val;
347 u8 eoc_level, ichg;
348
349 if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
350 if (pchg->chg_parm) {
351 eoc_level = pchg->chg_parm->eoc_level;
352 ichg = pchg->chg_parm->ichg;
353 val = (ichg << 4) | eoc_level;
354 lp8727_i2c_write_byte(pchg, CHGCTRL2, &val);
355 }
356 }
357}
358
359static int lp8727_register_psy(struct lp8727_chg *pchg)
360{
361 struct lp8727_psy *psy;
362
363 psy = kzalloc(sizeof(*psy), GFP_KERNEL);
364 if (!psy)
365 goto err_mem;
366
367 pchg->psy = psy;
368
369 psy->ac.name = "ac";
370 psy->ac.type = POWER_SUPPLY_TYPE_MAINS;
371 psy->ac.properties = lp8727_charger_prop;
372 psy->ac.num_properties = ARRAY_SIZE(lp8727_charger_prop);
373 psy->ac.get_property = lp8727_charger_get_property;
374 psy->ac.supplied_to = battery_supplied_to;
375 psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to);
376
377 if (power_supply_register(pchg->dev, &psy->ac))
378 goto err_psy;
379
380 psy->usb.name = "usb";
381 psy->usb.type = POWER_SUPPLY_TYPE_USB;
382 psy->usb.properties = lp8727_charger_prop;
383 psy->usb.num_properties = ARRAY_SIZE(lp8727_charger_prop);
384 psy->usb.get_property = lp8727_charger_get_property;
385 psy->usb.supplied_to = battery_supplied_to;
386 psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to);
387
388 if (power_supply_register(pchg->dev, &psy->usb))
389 goto err_psy;
390
391 psy->batt.name = "main_batt";
392 psy->batt.type = POWER_SUPPLY_TYPE_BATTERY;
393 psy->batt.properties = lp8727_battery_prop;
394 psy->batt.num_properties = ARRAY_SIZE(lp8727_battery_prop);
395 psy->batt.get_property = lp8727_battery_get_property;
396 psy->batt.external_power_changed = lp8727_charger_changed;
397
398 if (power_supply_register(pchg->dev, &psy->batt))
399 goto err_psy;
400
401 return 0;
402
403err_mem:
404 return -ENOMEM;
405err_psy:
406 kfree(psy);
407 return -EPERM;
408}
409
410static void lp8727_unregister_psy(struct lp8727_chg *pchg)
411{
412 struct lp8727_psy *psy = pchg->psy;
413
414 if (!psy)
415 return;
416
417 power_supply_unregister(&psy->ac);
418 power_supply_unregister(&psy->usb);
419 power_supply_unregister(&psy->batt);
420 kfree(psy);
421}
422
423static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
424{
425 struct lp8727_chg *pchg;
426 int ret;
427
428 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
429 return -EIO;
430
431 pchg = kzalloc(sizeof(*pchg), GFP_KERNEL);
432 if (!pchg)
433 return -ENOMEM;
434
435 pchg->client = cl;
436 pchg->dev = &cl->dev;
437 pchg->pdata = cl->dev.platform_data;
438 i2c_set_clientdata(cl, pchg);
439
440 mutex_init(&pchg->xfer_lock);
441
442 lp8727_init_device(pchg);
443 lp8727_intr_config(pchg);
444
445 ret = lp8727_register_psy(pchg);
446 if (ret)
447 dev_err(pchg->dev,
448 "can not register power supplies. err=%d", ret);
449
450 return 0;
451}
452
453static int __devexit lp8727_remove(struct i2c_client *cl)
454{
455 struct lp8727_chg *pchg = i2c_get_clientdata(cl);
456
457 lp8727_unregister_psy(pchg);
458 free_irq(pchg->client->irq, pchg);
459 flush_workqueue(pchg->irqthread);
460 destroy_workqueue(pchg->irqthread);
461 kfree(pchg);
462 return 0;
463}
464
465static const struct i2c_device_id lp8727_ids[] = {
466 {"lp8727", 0},
467};
468
469static struct i2c_driver lp8727_driver = {
470 .driver = {
471 .name = "lp8727",
472 },
473 .probe = lp8727_probe,
474 .remove = __devexit_p(lp8727_remove),
475 .id_table = lp8727_ids,
476};
477
478static int __init lp8727_init(void)
479{
480 return i2c_add_driver(&lp8727_driver);
481}
482
483static void __exit lp8727_exit(void)
484{
485 i2c_del_driver(&lp8727_driver);
486}
487
488module_init(lp8727_init);
489module_exit(lp8727_exit);
490
491MODULE_DESCRIPTION("National Semiconductor LP8727 charger driver");
492MODULE_AUTHOR
493 ("Woogyom Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>");
494MODULE_LICENSE("GPL");
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
index 9f0183c73076..86acee2f9889 100644
--- a/drivers/power/max17042_battery.c
+++ b/drivers/power/max17042_battery.c
@@ -85,55 +85,79 @@ static int max17042_get_property(struct power_supply *psy,
85{ 85{
86 struct max17042_chip *chip = container_of(psy, 86 struct max17042_chip *chip = container_of(psy,
87 struct max17042_chip, battery); 87 struct max17042_chip, battery);
88 int ret;
88 89
89 switch (psp) { 90 switch (psp) {
90 case POWER_SUPPLY_PROP_PRESENT: 91 case POWER_SUPPLY_PROP_PRESENT:
91 val->intval = max17042_read_reg(chip->client, 92 ret = max17042_read_reg(chip->client, MAX17042_STATUS);
92 MAX17042_STATUS); 93 if (ret < 0)
93 if (val->intval & MAX17042_STATUS_BattAbsent) 94 return ret;
95
96 if (ret & MAX17042_STATUS_BattAbsent)
94 val->intval = 0; 97 val->intval = 0;
95 else 98 else
96 val->intval = 1; 99 val->intval = 1;
97 break; 100 break;
98 case POWER_SUPPLY_PROP_CYCLE_COUNT: 101 case POWER_SUPPLY_PROP_CYCLE_COUNT:
99 val->intval = max17042_read_reg(chip->client, 102 ret = max17042_read_reg(chip->client, MAX17042_Cycles);
100 MAX17042_Cycles); 103 if (ret < 0)
104 return ret;
105
106 val->intval = ret;
101 break; 107 break;
102 case POWER_SUPPLY_PROP_VOLTAGE_MAX: 108 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
103 val->intval = max17042_read_reg(chip->client, 109 ret = max17042_read_reg(chip->client, MAX17042_MinMaxVolt);
104 MAX17042_MinMaxVolt); 110 if (ret < 0)
105 val->intval >>= 8; 111 return ret;
112
113 val->intval = ret >> 8;
106 val->intval *= 20000; /* Units of LSB = 20mV */ 114 val->intval *= 20000; /* Units of LSB = 20mV */
107 break; 115 break;
108 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 116 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
109 val->intval = max17042_read_reg(chip->client, 117 ret = max17042_read_reg(chip->client, MAX17042_V_empty);
110 MAX17042_V_empty); 118 if (ret < 0)
111 val->intval >>= 7; 119 return ret;
120
121 val->intval = ret >> 7;
112 val->intval *= 10000; /* Units of LSB = 10mV */ 122 val->intval *= 10000; /* Units of LSB = 10mV */
113 break; 123 break;
114 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 124 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
115 val->intval = max17042_read_reg(chip->client, 125 ret = max17042_read_reg(chip->client, MAX17042_VCELL);
116 MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */ 126 if (ret < 0)
127 return ret;
128
129 val->intval = ret * 625 / 8;
117 break; 130 break;
118 case POWER_SUPPLY_PROP_VOLTAGE_AVG: 131 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
119 val->intval = max17042_read_reg(chip->client, 132 ret = max17042_read_reg(chip->client, MAX17042_AvgVCELL);
120 MAX17042_AvgVCELL) * 83; 133 if (ret < 0)
134 return ret;
135
136 val->intval = ret * 625 / 8;
121 break; 137 break;
122 case POWER_SUPPLY_PROP_CAPACITY: 138 case POWER_SUPPLY_PROP_CAPACITY:
123 val->intval = max17042_read_reg(chip->client, 139 ret = max17042_read_reg(chip->client, MAX17042_SOC);
124 MAX17042_SOC) / 256; 140 if (ret < 0)
141 return ret;
142
143 val->intval = ret >> 8;
125 break; 144 break;
126 case POWER_SUPPLY_PROP_CHARGE_FULL: 145 case POWER_SUPPLY_PROP_CHARGE_FULL:
127 val->intval = max17042_read_reg(chip->client, 146 ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
128 MAX17042_RepSOC); 147 if (ret < 0)
129 if ((val->intval / 256) >= MAX17042_BATTERY_FULL) 148 return ret;
149
150 if ((ret >> 8) >= MAX17042_BATTERY_FULL)
130 val->intval = 1; 151 val->intval = 1;
131 else if (val->intval >= 0) 152 else if (ret >= 0)
132 val->intval = 0; 153 val->intval = 0;
133 break; 154 break;
134 case POWER_SUPPLY_PROP_TEMP: 155 case POWER_SUPPLY_PROP_TEMP:
135 val->intval = max17042_read_reg(chip->client, 156 ret = max17042_read_reg(chip->client, MAX17042_TEMP);
136 MAX17042_TEMP); 157 if (ret < 0)
158 return ret;
159
160 val->intval = ret;
137 /* The value is signed. */ 161 /* The value is signed. */
138 if (val->intval & 0x8000) { 162 if (val->intval & 0x8000) {
139 val->intval = (0x7fff & ~val->intval) + 1; 163 val->intval = (0x7fff & ~val->intval) + 1;
@@ -145,24 +169,30 @@ static int max17042_get_property(struct power_supply *psy,
145 break; 169 break;
146 case POWER_SUPPLY_PROP_CURRENT_NOW: 170 case POWER_SUPPLY_PROP_CURRENT_NOW:
147 if (chip->pdata->enable_current_sense) { 171 if (chip->pdata->enable_current_sense) {
148 val->intval = max17042_read_reg(chip->client, 172 ret = max17042_read_reg(chip->client, MAX17042_Current);
149 MAX17042_Current); 173 if (ret < 0)
174 return ret;
175
176 val->intval = ret;
150 if (val->intval & 0x8000) { 177 if (val->intval & 0x8000) {
151 /* Negative */ 178 /* Negative */
152 val->intval = ~val->intval & 0x7fff; 179 val->intval = ~val->intval & 0x7fff;
153 val->intval++; 180 val->intval++;
154 val->intval *= -1; 181 val->intval *= -1;
155 } 182 }
156 val->intval >>= 4; 183 val->intval *= 1562500 / chip->pdata->r_sns;
157 val->intval *= 1000000 * 25 / chip->pdata->r_sns;
158 } else { 184 } else {
159 return -EINVAL; 185 return -EINVAL;
160 } 186 }
161 break; 187 break;
162 case POWER_SUPPLY_PROP_CURRENT_AVG: 188 case POWER_SUPPLY_PROP_CURRENT_AVG:
163 if (chip->pdata->enable_current_sense) { 189 if (chip->pdata->enable_current_sense) {
164 val->intval = max17042_read_reg(chip->client, 190 ret = max17042_read_reg(chip->client,
165 MAX17042_AvgCurrent); 191 MAX17042_AvgCurrent);
192 if (ret < 0)
193 return ret;
194
195 val->intval = ret;
166 if (val->intval & 0x8000) { 196 if (val->intval & 0x8000) {
167 /* Negative */ 197 /* Negative */
168 val->intval = ~val->intval & 0x7fff; 198 val->intval = ~val->intval & 0x7fff;
@@ -210,6 +240,9 @@ static int __devinit max17042_probe(struct i2c_client *client,
210 if (!chip->pdata->enable_current_sense) 240 if (!chip->pdata->enable_current_sense)
211 chip->battery.num_properties -= 2; 241 chip->battery.num_properties -= 2;
212 242
243 if (chip->pdata->r_sns == 0)
244 chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
245
213 ret = power_supply_register(&client->dev, &chip->battery); 246 ret = power_supply_register(&client->dev, &chip->battery);
214 if (ret) { 247 if (ret) {
215 dev_err(&client->dev, "failed: power supply register\n"); 248 dev_err(&client->dev, "failed: power supply register\n");
@@ -226,9 +259,6 @@ static int __devinit max17042_probe(struct i2c_client *client,
226 max17042_write_reg(client, MAX17042_CGAIN, 0x0000); 259 max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
227 max17042_write_reg(client, MAX17042_MiscCFG, 0x0003); 260 max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
228 max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); 261 max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
229 } else {
230 if (chip->pdata->r_sns == 0)
231 chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
232 } 262 }
233 263
234 return 0; 264 return 0;
diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c
index 2595145f3bff..3e23f43e98af 100644
--- a/drivers/power/max8903_charger.c
+++ b/drivers/power/max8903_charger.c
@@ -374,19 +374,9 @@ static struct platform_driver max8903_driver = {
374 }, 374 },
375}; 375};
376 376
377static int __init max8903_init(void) 377module_platform_driver(max8903_driver);
378{
379 return platform_driver_register(&max8903_driver);
380}
381module_init(max8903_init);
382
383static void __exit max8903_exit(void)
384{
385 platform_driver_unregister(&max8903_driver);
386}
387module_exit(max8903_exit);
388 378
389MODULE_LICENSE("GPL"); 379MODULE_LICENSE("GPL");
390MODULE_DESCRIPTION("MAX8903 Charger Driver"); 380MODULE_DESCRIPTION("MAX8903 Charger Driver");
391MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 381MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
392MODULE_ALIAS("max8903-charger"); 382MODULE_ALIAS("platform:max8903-charger");
diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c
index a70e16d3a3dc..daa333bd7ebb 100644
--- a/drivers/power/max8925_power.c
+++ b/drivers/power/max8925_power.c
@@ -78,6 +78,8 @@ struct max8925_power_info {
78 unsigned batt_detect:1; /* detecing MB by ID pin */ 78 unsigned batt_detect:1; /* detecing MB by ID pin */
79 unsigned topoff_threshold:2; 79 unsigned topoff_threshold:2;
80 unsigned fast_charge:3; 80 unsigned fast_charge:3;
81 unsigned no_temp_support:1;
82 unsigned no_insert_detect:1;
81 83
82 int (*set_charger) (int); 84 int (*set_charger) (int);
83}; 85};
@@ -116,17 +118,7 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
116 case MAX8925_IRQ_VCHG_DC_F: 118 case MAX8925_IRQ_VCHG_DC_F:
117 info->ac_online = 0; 119 info->ac_online = 0;
118 __set_charger(info, 0); 120 __set_charger(info, 0);
119 dev_dbg(chip->dev, "Adapter is removal\n"); 121 dev_dbg(chip->dev, "Adapter removed\n");
120 break;
121 case MAX8925_IRQ_VCHG_USB_R:
122 info->usb_online = 1;
123 __set_charger(info, 1);
124 dev_dbg(chip->dev, "USB inserted\n");
125 break;
126 case MAX8925_IRQ_VCHG_USB_F:
127 info->usb_online = 0;
128 __set_charger(info, 0);
129 dev_dbg(chip->dev, "USB is removal\n");
130 break; 122 break;
131 case MAX8925_IRQ_VCHG_THM_OK_F: 123 case MAX8925_IRQ_VCHG_THM_OK_F:
132 /* Battery is not ready yet */ 124 /* Battery is not ready yet */
@@ -168,27 +160,33 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
168static int start_measure(struct max8925_power_info *info, int type) 160static int start_measure(struct max8925_power_info *info, int type)
169{ 161{
170 unsigned char buf[2] = {0, 0}; 162 unsigned char buf[2] = {0, 0};
163 int meas_cmd;
171 int meas_reg = 0, ret; 164 int meas_reg = 0, ret;
172 165
173 switch (type) { 166 switch (type) {
174 case MEASURE_VCHG: 167 case MEASURE_VCHG:
168 meas_cmd = MAX8925_CMD_VCHG;
175 meas_reg = MAX8925_ADC_VCHG; 169 meas_reg = MAX8925_ADC_VCHG;
176 break; 170 break;
177 case MEASURE_VBBATT: 171 case MEASURE_VBBATT:
172 meas_cmd = MAX8925_CMD_VBBATT;
178 meas_reg = MAX8925_ADC_VBBATT; 173 meas_reg = MAX8925_ADC_VBBATT;
179 break; 174 break;
180 case MEASURE_VMBATT: 175 case MEASURE_VMBATT:
176 meas_cmd = MAX8925_CMD_VMBATT;
181 meas_reg = MAX8925_ADC_VMBATT; 177 meas_reg = MAX8925_ADC_VMBATT;
182 break; 178 break;
183 case MEASURE_ISNS: 179 case MEASURE_ISNS:
180 meas_cmd = MAX8925_CMD_ISNS;
184 meas_reg = MAX8925_ADC_ISNS; 181 meas_reg = MAX8925_ADC_ISNS;
185 break; 182 break;
186 default: 183 default:
187 return -EINVAL; 184 return -EINVAL;
188 } 185 }
189 186
187 max8925_reg_write(info->adc, meas_cmd, 0);
190 max8925_bulk_read(info->adc, meas_reg, 2, buf); 188 max8925_bulk_read(info->adc, meas_reg, 2, buf);
191 ret = (buf[0] << 4) | (buf[1] >> 4); 189 ret = ((buf[0]<<8) | buf[1]) >> 4;
192 190
193 return ret; 191 return ret;
194} 192}
@@ -208,7 +206,7 @@ static int max8925_ac_get_prop(struct power_supply *psy,
208 if (info->ac_online) { 206 if (info->ac_online) {
209 ret = start_measure(info, MEASURE_VCHG); 207 ret = start_measure(info, MEASURE_VCHG);
210 if (ret >= 0) { 208 if (ret >= 0) {
211 val->intval = ret << 1; /* unit is mV */ 209 val->intval = ret * 2000; /* unit is uV */
212 goto out; 210 goto out;
213 } 211 }
214 } 212 }
@@ -242,7 +240,7 @@ static int max8925_usb_get_prop(struct power_supply *psy,
242 if (info->usb_online) { 240 if (info->usb_online) {
243 ret = start_measure(info, MEASURE_VCHG); 241 ret = start_measure(info, MEASURE_VCHG);
244 if (ret >= 0) { 242 if (ret >= 0) {
245 val->intval = ret << 1; /* unit is mV */ 243 val->intval = ret * 2000; /* unit is uV */
246 goto out; 244 goto out;
247 } 245 }
248 } 246 }
@@ -266,7 +264,6 @@ static int max8925_bat_get_prop(struct power_supply *psy,
266 union power_supply_propval *val) 264 union power_supply_propval *val)
267{ 265{
268 struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); 266 struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
269 long long int tmp = 0;
270 int ret = 0; 267 int ret = 0;
271 268
272 switch (psp) { 269 switch (psp) {
@@ -277,7 +274,7 @@ static int max8925_bat_get_prop(struct power_supply *psy,
277 if (info->bat_online) { 274 if (info->bat_online) {
278 ret = start_measure(info, MEASURE_VMBATT); 275 ret = start_measure(info, MEASURE_VMBATT);
279 if (ret >= 0) { 276 if (ret >= 0) {
280 val->intval = ret << 1; /* unit is mV */ 277 val->intval = ret * 2000; /* unit is uV */
281 ret = 0; 278 ret = 0;
282 break; 279 break;
283 } 280 }
@@ -288,8 +285,8 @@ static int max8925_bat_get_prop(struct power_supply *psy,
288 if (info->bat_online) { 285 if (info->bat_online) {
289 ret = start_measure(info, MEASURE_ISNS); 286 ret = start_measure(info, MEASURE_ISNS);
290 if (ret >= 0) { 287 if (ret >= 0) {
291 tmp = (long long int)ret * 6250 / 4096 - 3125; 288 /* assume r_sns is 0.02 */
292 ret = (int)tmp; 289 ret = ((ret * 6250) - 3125) /* uA */;
293 val->intval = 0; 290 val->intval = 0;
294 if (ret > 0) 291 if (ret > 0)
295 val->intval = ret; /* unit is mA */ 292 val->intval = ret; /* unit is mA */
@@ -365,13 +362,14 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
365 int ret; 362 int ret;
366 363
367 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp"); 364 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
368 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove"); 365 if (!info->no_insert_detect) {
369 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert"); 366 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
370 REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp"); 367 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
371 REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove"); 368 }
372 REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert"); 369 if (!info->no_temp_support) {
373 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range"); 370 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
374 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range"); 371 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
372 }
375 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high"); 373 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
376 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low"); 374 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
377 REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset"); 375 REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
@@ -379,9 +377,15 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
379 REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff"); 377 REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
380 REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire"); 378 REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
381 379
382 info->ac_online = 0;
383 info->usb_online = 0; 380 info->usb_online = 0;
384 info->bat_online = 0; 381 info->bat_online = 0;
382
383 /* check for power - can miss interrupt at boot time */
384 if (start_measure(info, MEASURE_VCHG) * 2000 > 500000)
385 info->ac_online = 1;
386 else
387 info->ac_online = 0;
388
385 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS); 389 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
386 if (ret >= 0) { 390 if (ret >= 0) {
387 /* 391 /*
@@ -449,6 +453,8 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
449 info->ac.properties = max8925_ac_props; 453 info->ac.properties = max8925_ac_props;
450 info->ac.num_properties = ARRAY_SIZE(max8925_ac_props); 454 info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
451 info->ac.get_property = max8925_ac_get_prop; 455 info->ac.get_property = max8925_ac_get_prop;
456 info->ac.supplied_to = pdata->supplied_to;
457 info->ac.num_supplicants = pdata->num_supplicants;
452 ret = power_supply_register(&pdev->dev, &info->ac); 458 ret = power_supply_register(&pdev->dev, &info->ac);
453 if (ret) 459 if (ret)
454 goto out; 460 goto out;
@@ -459,6 +465,9 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
459 info->usb.properties = max8925_usb_props; 465 info->usb.properties = max8925_usb_props;
460 info->usb.num_properties = ARRAY_SIZE(max8925_usb_props); 466 info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
461 info->usb.get_property = max8925_usb_get_prop; 467 info->usb.get_property = max8925_usb_get_prop;
468 info->usb.supplied_to = pdata->supplied_to;
469 info->usb.num_supplicants = pdata->num_supplicants;
470
462 ret = power_supply_register(&pdev->dev, &info->usb); 471 ret = power_supply_register(&pdev->dev, &info->usb);
463 if (ret) 472 if (ret)
464 goto out_usb; 473 goto out_usb;
@@ -478,6 +487,8 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
478 info->topoff_threshold = pdata->topoff_threshold; 487 info->topoff_threshold = pdata->topoff_threshold;
479 info->fast_charge = pdata->fast_charge; 488 info->fast_charge = pdata->fast_charge;
480 info->set_charger = pdata->set_charger; 489 info->set_charger = pdata->set_charger;
490 info->no_temp_support = pdata->no_temp_support;
491 info->no_insert_detect = pdata->no_insert_detect;
481 492
482 max8925_init_charger(chip, info); 493 max8925_init_charger(chip, info);
483 return 0; 494 return 0;
@@ -512,17 +523,7 @@ static struct platform_driver max8925_power_driver = {
512 }, 523 },
513}; 524};
514 525
515static int __init max8925_power_init(void) 526module_platform_driver(max8925_power_driver);
516{
517 return platform_driver_register(&max8925_power_driver);
518}
519module_init(max8925_power_init);
520
521static void __exit max8925_power_exit(void)
522{
523 platform_driver_unregister(&max8925_power_driver);
524}
525module_exit(max8925_power_exit);
526 527
527MODULE_LICENSE("GPL"); 528MODULE_LICENSE("GPL");
528MODULE_DESCRIPTION("Power supply driver for MAX8925"); 529MODULE_DESCRIPTION("Power supply driver for MAX8925");
diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c
index a23317d75c5a..6e88c5d026b9 100644
--- a/drivers/power/max8997_charger.c
+++ b/drivers/power/max8997_charger.c
@@ -19,7 +19,6 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/module.h>
23#include <linux/err.h> 22#include <linux/err.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
@@ -98,7 +97,7 @@ static __devinit int max8997_battery_probe(struct platform_device *pdev)
98 return -EINVAL; 97 return -EINVAL;
99 98
100 if (pdata->eoc_mA) { 99 if (pdata->eoc_mA) {
101 u8 val = (pdata->eoc_mA - 50) / 10; 100 int val = (pdata->eoc_mA - 50) / 10;
102 if (val < 0) 101 if (val < 0)
103 val = 0; 102 val = 0;
104 if (val > 0xf) 103 if (val > 0xf)
@@ -179,6 +178,7 @@ static int __devexit max8997_battery_remove(struct platform_device *pdev)
179 178
180static const struct platform_device_id max8997_battery_id[] = { 179static const struct platform_device_id max8997_battery_id[] = {
181 { "max8997-battery", 0 }, 180 { "max8997-battery", 0 },
181 { }
182}; 182};
183 183
184static struct platform_driver max8997_battery_driver = { 184static struct platform_driver max8997_battery_driver = {
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c
index 93e3bb47a3a8..9b3f2bf56e70 100644
--- a/drivers/power/max8998_charger.c
+++ b/drivers/power/max8998_charger.c
@@ -154,6 +154,7 @@ static __devinit int max8998_battery_probe(struct platform_device *pdev)
154 case 0: 154 case 0:
155 dev_dbg(max8998->dev, 155 dev_dbg(max8998->dev,
156 "Full Timeout not set: leave it unchanged.\n"); 156 "Full Timeout not set: leave it unchanged.\n");
157 break;
157 default: 158 default:
158 dev_err(max8998->dev, "Invalid Full Timeout value\n"); 159 dev_err(max8998->dev, "Invalid Full Timeout value\n");
159 ret = -EINVAL; 160 ret = -EINVAL;
@@ -190,6 +191,7 @@ static int __devexit max8998_battery_remove(struct platform_device *pdev)
190 191
191static const struct platform_device_id max8998_battery_id[] = { 192static const struct platform_device_id max8998_battery_id[] = {
192 { "max8998-battery", TYPE_MAX8998 }, 193 { "max8998-battery", TYPE_MAX8998 },
194 { }
193}; 195};
194 196
195static struct platform_driver max8998_battery_driver = { 197static struct platform_driver max8998_battery_driver = {
@@ -202,17 +204,7 @@ static struct platform_driver max8998_battery_driver = {
202 .id_table = max8998_battery_id, 204 .id_table = max8998_battery_id,
203}; 205};
204 206
205static int __init max8998_battery_init(void) 207module_platform_driver(max8998_battery_driver);
206{
207 return platform_driver_register(&max8998_battery_driver);
208}
209module_init(max8998_battery_init);
210
211static void __exit max8998_battery_cleanup(void)
212{
213 platform_driver_unregister(&max8998_battery_driver);
214}
215module_exit(max8998_battery_cleanup);
216 208
217MODULE_DESCRIPTION("MAXIM 8998 battery control driver"); 209MODULE_DESCRIPTION("MAXIM 8998 battery control driver");
218MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 210MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index 0b0ff3a936a6..7385092f9bc8 100644
--- a/drivers/power/olpc_battery.c
+++ b/drivers/power/olpc_battery.c
@@ -519,29 +519,35 @@ static struct device_attribute olpc_bat_error = {
519 * Initialisation 519 * Initialisation
520 *********************************************************************/ 520 *********************************************************************/
521 521
522static struct platform_device *bat_pdev;
523
524static struct power_supply olpc_bat = { 522static struct power_supply olpc_bat = {
523 .name = "olpc-battery",
525 .get_property = olpc_bat_get_property, 524 .get_property = olpc_bat_get_property,
526 .use_for_apm = 1, 525 .use_for_apm = 1,
527}; 526};
528 527
529void olpc_battery_trigger_uevent(unsigned long cause) 528static int olpc_battery_suspend(struct platform_device *pdev,
529 pm_message_t state)
530{ 530{
531 if (cause & EC_SCI_SRC_ACPWR) 531 if (device_may_wakeup(olpc_ac.dev))
532 kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE); 532 olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR);
533 if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY)) 533 else
534 kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE); 534 olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR);
535
536 if (device_may_wakeup(olpc_bat.dev))
537 olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
538 | EC_SCI_SRC_BATERR);
539 else
540 olpc_ec_wakeup_clear(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
541 | EC_SCI_SRC_BATERR);
542
543 return 0;
535} 544}
536 545
537static int __init olpc_bat_init(void) 546static int __devinit olpc_battery_probe(struct platform_device *pdev)
538{ 547{
539 int ret = 0; 548 int ret;
540 uint8_t status; 549 uint8_t status;
541 550
542 if (!olpc_platform_info.ecver)
543 return -ENXIO;
544
545 /* 551 /*
546 * We've seen a number of EC protocol changes; this driver requires 552 * We've seen a number of EC protocol changes; this driver requires
547 * the latest EC protocol, supported by 0x44 and above. 553 * the latest EC protocol, supported by 0x44 and above.
@@ -558,15 +564,10 @@ static int __init olpc_bat_init(void)
558 564
559 /* Ignore the status. It doesn't actually matter */ 565 /* Ignore the status. It doesn't actually matter */
560 566
561 bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0); 567 ret = power_supply_register(&pdev->dev, &olpc_ac);
562 if (IS_ERR(bat_pdev))
563 return PTR_ERR(bat_pdev);
564
565 ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
566 if (ret) 568 if (ret)
567 goto ac_failed; 569 return ret;
568 570
569 olpc_bat.name = bat_pdev->name;
570 if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ 571 if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */
571 olpc_bat.properties = olpc_xo15_bat_props; 572 olpc_bat.properties = olpc_xo15_bat_props;
572 olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); 573 olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props);
@@ -575,7 +576,7 @@ static int __init olpc_bat_init(void)
575 olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); 576 olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props);
576 } 577 }
577 578
578 ret = power_supply_register(&bat_pdev->dev, &olpc_bat); 579 ret = power_supply_register(&pdev->dev, &olpc_bat);
579 if (ret) 580 if (ret)
580 goto battery_failed; 581 goto battery_failed;
581 582
@@ -587,7 +588,12 @@ static int __init olpc_bat_init(void)
587 if (ret) 588 if (ret)
588 goto error_failed; 589 goto error_failed;
589 590
590 goto success; 591 if (olpc_ec_wakeup_available()) {
592 device_set_wakeup_capable(olpc_ac.dev, true);
593 device_set_wakeup_capable(olpc_bat.dev, true);
594 }
595
596 return 0;
591 597
592error_failed: 598error_failed:
593 device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); 599 device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
@@ -595,23 +601,36 @@ eeprom_failed:
595 power_supply_unregister(&olpc_bat); 601 power_supply_unregister(&olpc_bat);
596battery_failed: 602battery_failed:
597 power_supply_unregister(&olpc_ac); 603 power_supply_unregister(&olpc_ac);
598ac_failed:
599 platform_device_unregister(bat_pdev);
600success:
601 return ret; 604 return ret;
602} 605}
603 606
604static void __exit olpc_bat_exit(void) 607static int __devexit olpc_battery_remove(struct platform_device *pdev)
605{ 608{
606 device_remove_file(olpc_bat.dev, &olpc_bat_error); 609 device_remove_file(olpc_bat.dev, &olpc_bat_error);
607 device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); 610 device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
608 power_supply_unregister(&olpc_bat); 611 power_supply_unregister(&olpc_bat);
609 power_supply_unregister(&olpc_ac); 612 power_supply_unregister(&olpc_ac);
610 platform_device_unregister(bat_pdev); 613 return 0;
611} 614}
612 615
613module_init(olpc_bat_init); 616static const struct of_device_id olpc_battery_ids[] __devinitconst = {
614module_exit(olpc_bat_exit); 617 { .compatible = "olpc,xo1-battery" },
618 {}
619};
620MODULE_DEVICE_TABLE(of, olpc_battery_ids);
621
622static struct platform_driver olpc_battery_driver = {
623 .driver = {
624 .name = "olpc-battery",
625 .owner = THIS_MODULE,
626 .of_match_table = olpc_battery_ids,
627 },
628 .probe = olpc_battery_probe,
629 .remove = __devexit_p(olpc_battery_remove),
630 .suspend = olpc_battery_suspend,
631};
632
633module_platform_driver(olpc_battery_driver);
615 634
616MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 635MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
617MODULE_LICENSE("GPL"); 636MODULE_LICENSE("GPL");
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index 4fa52e1781a2..3d1e9efb6f53 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -474,17 +474,7 @@ static struct platform_driver pcf50633_mbc_driver = {
474 .remove = __devexit_p(pcf50633_mbc_remove), 474 .remove = __devexit_p(pcf50633_mbc_remove),
475}; 475};
476 476
477static int __init pcf50633_mbc_init(void) 477module_platform_driver(pcf50633_mbc_driver);
478{
479 return platform_driver_register(&pcf50633_mbc_driver);
480}
481module_init(pcf50633_mbc_init);
482
483static void __exit pcf50633_mbc_exit(void)
484{
485 platform_driver_unregister(&pcf50633_mbc_driver);
486}
487module_exit(pcf50633_mbc_exit);
488 478
489MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); 479MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
490MODULE_DESCRIPTION("PCF50633 mbc driver"); 480MODULE_DESCRIPTION("PCF50633 mbc driver");
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index 69f8aa3a6a4b..fd49689738af 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/notifier.h>
17#include <linux/power_supply.h> 18#include <linux/power_supply.h>
18#include <linux/pda_power.h> 19#include <linux/pda_power.h>
19#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
@@ -40,7 +41,9 @@ static int polling;
40 41
41#ifdef CONFIG_USB_OTG_UTILS 42#ifdef CONFIG_USB_OTG_UTILS
42static struct otg_transceiver *transceiver; 43static struct otg_transceiver *transceiver;
44static struct notifier_block otg_nb;
43#endif 45#endif
46
44static struct regulator *ac_draw; 47static struct regulator *ac_draw;
45 48
46enum { 49enum {
@@ -222,7 +225,42 @@ static void polling_timer_func(unsigned long unused)
222#ifdef CONFIG_USB_OTG_UTILS 225#ifdef CONFIG_USB_OTG_UTILS
223static int otg_is_usb_online(void) 226static int otg_is_usb_online(void)
224{ 227{
225 return (transceiver->state == OTG_STATE_B_PERIPHERAL); 228 return (transceiver->last_event == USB_EVENT_VBUS ||
229 transceiver->last_event == USB_EVENT_ENUMERATED);
230}
231
232static int otg_is_ac_online(void)
233{
234 return (transceiver->last_event == USB_EVENT_CHARGER);
235}
236
237static int otg_handle_notification(struct notifier_block *nb,
238 unsigned long event, void *unused)
239{
240 switch (event) {
241 case USB_EVENT_CHARGER:
242 ac_status = PDA_PSY_TO_CHANGE;
243 break;
244 case USB_EVENT_VBUS:
245 case USB_EVENT_ENUMERATED:
246 usb_status = PDA_PSY_TO_CHANGE;
247 break;
248 case USB_EVENT_NONE:
249 ac_status = PDA_PSY_TO_CHANGE;
250 usb_status = PDA_PSY_TO_CHANGE;
251 break;
252 default:
253 return NOTIFY_OK;
254 }
255
256 /*
257 * Wait a bit before reading ac/usb line status and setting charger,
258 * because ac/usb status readings may lag from irq.
259 */
260 mod_timer(&charger_timer,
261 jiffies + msecs_to_jiffies(pdata->wait_for_status));
262
263 return NOTIFY_OK;
226} 264}
227#endif 265#endif
228 266
@@ -282,6 +320,16 @@ static int pda_power_probe(struct platform_device *pdev)
282 ret = PTR_ERR(ac_draw); 320 ret = PTR_ERR(ac_draw);
283 } 321 }
284 322
323#ifdef CONFIG_USB_OTG_UTILS
324 transceiver = otg_get_transceiver();
325 if (transceiver && !pdata->is_usb_online) {
326 pdata->is_usb_online = otg_is_usb_online;
327 }
328 if (transceiver && !pdata->is_ac_online) {
329 pdata->is_ac_online = otg_is_ac_online;
330 }
331#endif
332
285 if (pdata->is_ac_online) { 333 if (pdata->is_ac_online) {
286 ret = power_supply_register(&pdev->dev, &pda_psy_ac); 334 ret = power_supply_register(&pdev->dev, &pda_psy_ac);
287 if (ret) { 335 if (ret) {
@@ -303,13 +351,6 @@ static int pda_power_probe(struct platform_device *pdev)
303 } 351 }
304 } 352 }
305 353
306#ifdef CONFIG_USB_OTG_UTILS
307 transceiver = otg_get_transceiver();
308 if (transceiver && !pdata->is_usb_online) {
309 pdata->is_usb_online = otg_is_usb_online;
310 }
311#endif
312
313 if (pdata->is_usb_online) { 354 if (pdata->is_usb_online) {
314 ret = power_supply_register(&pdev->dev, &pda_psy_usb); 355 ret = power_supply_register(&pdev->dev, &pda_psy_usb);
315 if (ret) { 356 if (ret) {
@@ -331,6 +372,18 @@ static int pda_power_probe(struct platform_device *pdev)
331 } 372 }
332 } 373 }
333 374
375#ifdef CONFIG_USB_OTG_UTILS
376 if (transceiver && pdata->use_otg_notifier) {
377 otg_nb.notifier_call = otg_handle_notification;
378 ret = otg_register_notifier(transceiver, &otg_nb);
379 if (ret) {
380 dev_err(dev, "failure to register otg notifier\n");
381 goto otg_reg_notifier_failed;
382 }
383 polling = 0;
384 }
385#endif
386
334 if (polling) { 387 if (polling) {
335 dev_dbg(dev, "will poll for status\n"); 388 dev_dbg(dev, "will poll for status\n");
336 setup_timer(&polling_timer, polling_timer_func, 0); 389 setup_timer(&polling_timer, polling_timer_func, 0);
@@ -343,6 +396,11 @@ static int pda_power_probe(struct platform_device *pdev)
343 396
344 return 0; 397 return 0;
345 398
399#ifdef CONFIG_USB_OTG_UTILS
400otg_reg_notifier_failed:
401 if (pdata->is_usb_online && usb_irq)
402 free_irq(usb_irq->start, &pda_psy_usb);
403#endif
346usb_irq_failed: 404usb_irq_failed:
347 if (pdata->is_usb_online) 405 if (pdata->is_usb_online)
348 power_supply_unregister(&pda_psy_usb); 406 power_supply_unregister(&pda_psy_usb);
@@ -440,8 +498,6 @@ static int pda_power_resume(struct platform_device *pdev)
440#define pda_power_resume NULL 498#define pda_power_resume NULL
441#endif /* CONFIG_PM */ 499#endif /* CONFIG_PM */
442 500
443MODULE_ALIAS("platform:pda-power");
444
445static struct platform_driver pda_power_pdrv = { 501static struct platform_driver pda_power_pdrv = {
446 .driver = { 502 .driver = {
447 .name = "pda-power", 503 .name = "pda-power",
@@ -452,17 +508,8 @@ static struct platform_driver pda_power_pdrv = {
452 .resume = pda_power_resume, 508 .resume = pda_power_resume,
453}; 509};
454 510
455static int __init pda_power_init(void) 511module_platform_driver(pda_power_pdrv);
456{
457 return platform_driver_register(&pda_power_pdrv);
458}
459 512
460static void __exit pda_power_exit(void)
461{
462 platform_driver_unregister(&pda_power_pdrv);
463}
464
465module_init(pda_power_init);
466module_exit(pda_power_exit);
467MODULE_LICENSE("GPL"); 513MODULE_LICENSE("GPL");
468MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>"); 514MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
515MODULE_ALIAS("platform:pda-power");
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 329b46b2327d..6ad612726785 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -98,7 +98,9 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
98{ 98{
99 union power_supply_propval ret = {0,}; 99 union power_supply_propval ret = {0,};
100 struct power_supply *psy = dev_get_drvdata(dev); 100 struct power_supply *psy = dev_get_drvdata(dev);
101 unsigned int *count = data;
101 102
103 (*count)++;
102 if (psy->type != POWER_SUPPLY_TYPE_BATTERY) { 104 if (psy->type != POWER_SUPPLY_TYPE_BATTERY) {
103 if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret)) 105 if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret))
104 return 0; 106 return 0;
@@ -111,10 +113,18 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
111int power_supply_is_system_supplied(void) 113int power_supply_is_system_supplied(void)
112{ 114{
113 int error; 115 int error;
116 unsigned int count = 0;
114 117
115 error = class_for_each_device(power_supply_class, NULL, NULL, 118 error = class_for_each_device(power_supply_class, NULL, &count,
116 __power_supply_is_system_supplied); 119 __power_supply_is_system_supplied);
117 120
121 /*
122 * If no power class device was found at all, most probably we are
123 * running on a desktop system, so assume we are on mains power.
124 */
125 if (count == 0)
126 return 1;
127
118 return error; 128 return error;
119} 129}
120EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); 130EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
@@ -147,6 +157,12 @@ struct power_supply *power_supply_get_by_name(char *name)
147} 157}
148EXPORT_SYMBOL_GPL(power_supply_get_by_name); 158EXPORT_SYMBOL_GPL(power_supply_get_by_name);
149 159
160int power_supply_powers(struct power_supply *psy, struct device *dev)
161{
162 return sysfs_create_link(&psy->dev->kobj, &dev->kobj, "powers");
163}
164EXPORT_SYMBOL_GPL(power_supply_powers);
165
150static void power_supply_dev_release(struct device *dev) 166static void power_supply_dev_release(struct device *dev)
151{ 167{
152 pr_debug("device: '%s': %s\n", dev_name(dev), __func__); 168 pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -202,6 +218,7 @@ EXPORT_SYMBOL_GPL(power_supply_register);
202void power_supply_unregister(struct power_supply *psy) 218void power_supply_unregister(struct power_supply *psy)
203{ 219{
204 cancel_work_sync(&psy->changed_work); 220 cancel_work_sync(&psy->changed_work);
221 sysfs_remove_link(&psy->dev->kobj, "powers");
205 power_supply_remove_triggers(psy); 222 power_supply_remove_triggers(psy);
206 device_unregister(psy->dev); 223 device_unregister(psy->dev);
207} 224}
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index e95cd657dac2..b52b57ca3084 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -43,7 +43,7 @@ static ssize_t power_supply_show_property(struct device *dev,
43 struct device_attribute *attr, 43 struct device_attribute *attr,
44 char *buf) { 44 char *buf) {
45 static char *type_text[] = { 45 static char *type_text[] = {
46 "Battery", "UPS", "Mains", "USB", 46 "Unknown", "Battery", "UPS", "Mains", "USB",
47 "USB_DCP", "USB_CDP", "USB_ACA" 47 "USB_DCP", "USB_CDP", "USB_ACA"
48 }; 48 };
49 static char *status_text[] = { 49 static char *status_text[] = {
@@ -63,6 +63,9 @@ static ssize_t power_supply_show_property(struct device *dev,
63 static char *capacity_level_text[] = { 63 static char *capacity_level_text[] = {
64 "Unknown", "Critical", "Low", "Normal", "High", "Full" 64 "Unknown", "Critical", "Low", "Normal", "High", "Full"
65 }; 65 };
66 static char *scope_text[] = {
67 "Unknown", "System", "Device"
68 };
66 ssize_t ret = 0; 69 ssize_t ret = 0;
67 struct power_supply *psy = dev_get_drvdata(dev); 70 struct power_supply *psy = dev_get_drvdata(dev);
68 const ptrdiff_t off = attr - power_supply_attrs; 71 const ptrdiff_t off = attr - power_supply_attrs;
@@ -78,8 +81,8 @@ static ssize_t power_supply_show_property(struct device *dev,
78 dev_dbg(dev, "driver has no data for `%s' property\n", 81 dev_dbg(dev, "driver has no data for `%s' property\n",
79 attr->attr.name); 82 attr->attr.name);
80 else if (ret != -ENODEV) 83 else if (ret != -ENODEV)
81 dev_err(dev, "driver failed to report `%s' property\n", 84 dev_err(dev, "driver failed to report `%s' property: %zd\n",
82 attr->attr.name); 85 attr->attr.name, ret);
83 return ret; 86 return ret;
84 } 87 }
85 88
@@ -95,6 +98,8 @@ static ssize_t power_supply_show_property(struct device *dev,
95 return sprintf(buf, "%s\n", capacity_level_text[value.intval]); 98 return sprintf(buf, "%s\n", capacity_level_text[value.intval]);
96 else if (off == POWER_SUPPLY_PROP_TYPE) 99 else if (off == POWER_SUPPLY_PROP_TYPE)
97 return sprintf(buf, "%s\n", type_text[value.intval]); 100 return sprintf(buf, "%s\n", type_text[value.intval]);
101 else if (off == POWER_SUPPLY_PROP_SCOPE)
102 return sprintf(buf, "%s\n", scope_text[value.intval]);
98 else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) 103 else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
99 return sprintf(buf, "%s\n", value.strval); 104 return sprintf(buf, "%s\n", value.strval);
100 105
@@ -167,6 +172,7 @@ static struct device_attribute power_supply_attrs[] = {
167 POWER_SUPPLY_ATTR(time_to_full_now), 172 POWER_SUPPLY_ATTR(time_to_full_now),
168 POWER_SUPPLY_ATTR(time_to_full_avg), 173 POWER_SUPPLY_ATTR(time_to_full_avg),
169 POWER_SUPPLY_ATTR(type), 174 POWER_SUPPLY_ATTR(type),
175 POWER_SUPPLY_ATTR(scope),
170 /* Properties of type `const char *' */ 176 /* Properties of type `const char *' */
171 POWER_SUPPLY_ATTR(model_name), 177 POWER_SUPPLY_ATTR(model_name),
172 POWER_SUPPLY_ATTR(manufacturer), 178 POWER_SUPPLY_ATTR(manufacturer),
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c
index d32d0d70f9ba..8b804a566756 100644
--- a/drivers/power/s3c_adc_battery.c
+++ b/drivers/power/s3c_adc_battery.c
@@ -47,6 +47,22 @@ static void s3c_adc_bat_ext_power_changed(struct power_supply *psy)
47 msecs_to_jiffies(JITTER_DELAY)); 47 msecs_to_jiffies(JITTER_DELAY));
48} 48}
49 49
50static int gather_samples(struct s3c_adc_client *client, int num, int channel)
51{
52 int value, i;
53
54 /* default to 1 if nothing is set */
55 if (num < 1)
56 num = 1;
57
58 value = 0;
59 for (i = 0; i < num; i++)
60 value += s3c_adc_read(client, channel);
61 value /= num;
62
63 return value;
64}
65
50static enum power_supply_property s3c_adc_backup_bat_props[] = { 66static enum power_supply_property s3c_adc_backup_bat_props[] = {
51 POWER_SUPPLY_PROP_VOLTAGE_NOW, 67 POWER_SUPPLY_PROP_VOLTAGE_NOW,
52 POWER_SUPPLY_PROP_VOLTAGE_MIN, 68 POWER_SUPPLY_PROP_VOLTAGE_MIN,
@@ -67,7 +83,8 @@ static int s3c_adc_backup_bat_get_property(struct power_supply *psy,
67 if (bat->volt_value < 0 || 83 if (bat->volt_value < 0 ||
68 jiffies_to_msecs(jiffies - bat->timestamp) > 84 jiffies_to_msecs(jiffies - bat->timestamp) >
69 BAT_POLL_INTERVAL) { 85 BAT_POLL_INTERVAL) {
70 bat->volt_value = s3c_adc_read(bat->client, 86 bat->volt_value = gather_samples(bat->client,
87 bat->pdata->backup_volt_samples,
71 bat->pdata->backup_volt_channel); 88 bat->pdata->backup_volt_channel);
72 bat->volt_value *= bat->pdata->backup_volt_mult; 89 bat->volt_value *= bat->pdata->backup_volt_mult;
73 bat->timestamp = jiffies; 90 bat->timestamp = jiffies;
@@ -139,9 +156,11 @@ static int s3c_adc_bat_get_property(struct power_supply *psy,
139 if (bat->volt_value < 0 || bat->cur_value < 0 || 156 if (bat->volt_value < 0 || bat->cur_value < 0 ||
140 jiffies_to_msecs(jiffies - bat->timestamp) > 157 jiffies_to_msecs(jiffies - bat->timestamp) >
141 BAT_POLL_INTERVAL) { 158 BAT_POLL_INTERVAL) {
142 bat->volt_value = s3c_adc_read(bat->client, 159 bat->volt_value = gather_samples(bat->client,
160 bat->pdata->volt_samples,
143 bat->pdata->volt_channel) * bat->pdata->volt_mult; 161 bat->pdata->volt_channel) * bat->pdata->volt_mult;
144 bat->cur_value = s3c_adc_read(bat->client, 162 bat->cur_value = gather_samples(bat->client,
163 bat->pdata->current_samples,
145 bat->pdata->current_channel) * bat->pdata->current_mult; 164 bat->pdata->current_channel) * bat->pdata->current_mult;
146 bat->timestamp = jiffies; 165 bat->timestamp = jiffies;
147 } 166 }
@@ -421,17 +440,7 @@ static struct platform_driver s3c_adc_bat_driver = {
421 .resume = s3c_adc_bat_resume, 440 .resume = s3c_adc_bat_resume,
422}; 441};
423 442
424static int __init s3c_adc_bat_init(void) 443module_platform_driver(s3c_adc_bat_driver);
425{
426 return platform_driver_register(&s3c_adc_bat_driver);
427}
428module_init(s3c_adc_bat_init);
429
430static void __exit s3c_adc_bat_exit(void)
431{
432 platform_driver_unregister(&s3c_adc_bat_driver);
433}
434module_exit(s3c_adc_bat_exit);
435 444
436MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>"); 445MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>");
437MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver"); 446MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver");
diff --git a/drivers/power/bq20z75.c b/drivers/power/sbs-battery.c
index 9c5e5beda3a8..9ff8af069da6 100644
--- a/drivers/power/bq20z75.c
+++ b/drivers/power/sbs-battery.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Gas Gauge driver for TI's BQ20Z75 2 * Gas Gauge driver for SBS Compliant Batteries
3 * 3 *
4 * Copyright (c) 2010, NVIDIA Corporation. 4 * Copyright (c) 2010, NVIDIA Corporation.
5 * 5 *
@@ -28,7 +28,7 @@
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/gpio.h> 29#include <linux/gpio.h>
30 30
31#include <linux/power/bq20z75.h> 31#include <linux/power/sbs-battery.h>
32 32
33enum { 33enum {
34 REG_MANUFACTURER_DATA, 34 REG_MANUFACTURER_DATA,
@@ -53,7 +53,7 @@ enum {
53/* Battery Mode defines */ 53/* Battery Mode defines */
54#define BATTERY_MODE_OFFSET 0x03 54#define BATTERY_MODE_OFFSET 0x03
55#define BATTERY_MODE_MASK 0x8000 55#define BATTERY_MODE_MASK 0x8000
56enum bq20z75_battery_mode { 56enum sbs_battery_mode {
57 BATTERY_MODE_AMPS, 57 BATTERY_MODE_AMPS,
58 BATTERY_MODE_WATTS 58 BATTERY_MODE_WATTS
59}; 59};
@@ -67,62 +67,56 @@ enum bq20z75_battery_mode {
67#define BATTERY_FULL_CHARGED 0x20 67#define BATTERY_FULL_CHARGED 0x20
68#define BATTERY_FULL_DISCHARGED 0x10 68#define BATTERY_FULL_DISCHARGED 0x10
69 69
70#define BQ20Z75_DATA(_psp, _addr, _min_value, _max_value) { \ 70#define SBS_DATA(_psp, _addr, _min_value, _max_value) { \
71 .psp = _psp, \ 71 .psp = _psp, \
72 .addr = _addr, \ 72 .addr = _addr, \
73 .min_value = _min_value, \ 73 .min_value = _min_value, \
74 .max_value = _max_value, \ 74 .max_value = _max_value, \
75} 75}
76 76
77static const struct bq20z75_device_data { 77static const struct chip_data {
78 enum power_supply_property psp; 78 enum power_supply_property psp;
79 u8 addr; 79 u8 addr;
80 int min_value; 80 int min_value;
81 int max_value; 81 int max_value;
82} bq20z75_data[] = { 82} sbs_data[] = {
83 [REG_MANUFACTURER_DATA] = 83 [REG_MANUFACTURER_DATA] =
84 BQ20Z75_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535), 84 SBS_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
85 [REG_TEMPERATURE] = 85 [REG_TEMPERATURE] =
86 BQ20Z75_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535), 86 SBS_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
87 [REG_VOLTAGE] = 87 [REG_VOLTAGE] =
88 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000), 88 SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
89 [REG_CURRENT] = 89 [REG_CURRENT] =
90 BQ20Z75_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 90 SBS_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 32767),
91 32767),
92 [REG_CAPACITY] = 91 [REG_CAPACITY] =
93 BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100), 92 SBS_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
94 [REG_REMAINING_CAPACITY] = 93 [REG_REMAINING_CAPACITY] =
95 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535), 94 SBS_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
96 [REG_REMAINING_CAPACITY_CHARGE] = 95 [REG_REMAINING_CAPACITY_CHARGE] =
97 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535), 96 SBS_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
98 [REG_FULL_CHARGE_CAPACITY] = 97 [REG_FULL_CHARGE_CAPACITY] =
99 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535), 98 SBS_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
100 [REG_FULL_CHARGE_CAPACITY_CHARGE] = 99 [REG_FULL_CHARGE_CAPACITY_CHARGE] =
101 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535), 100 SBS_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
102 [REG_TIME_TO_EMPTY] = 101 [REG_TIME_TO_EMPTY] =
103 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 102 SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 65535),
104 65535),
105 [REG_TIME_TO_FULL] = 103 [REG_TIME_TO_FULL] =
106 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 104 SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 65535),
107 65535),
108 [REG_STATUS] = 105 [REG_STATUS] =
109 BQ20Z75_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535), 106 SBS_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
110 [REG_CYCLE_COUNT] = 107 [REG_CYCLE_COUNT] =
111 BQ20Z75_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535), 108 SBS_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
112 [REG_DESIGN_CAPACITY] = 109 [REG_DESIGN_CAPACITY] =
113 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0, 110 SBS_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0, 65535),
114 65535),
115 [REG_DESIGN_CAPACITY_CHARGE] = 111 [REG_DESIGN_CAPACITY_CHARGE] =
116 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0, 112 SBS_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0, 65535),
117 65535),
118 [REG_DESIGN_VOLTAGE] = 113 [REG_DESIGN_VOLTAGE] =
119 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0, 114 SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0, 65535),
120 65535),
121 [REG_SERIAL_NUMBER] = 115 [REG_SERIAL_NUMBER] =
122 BQ20Z75_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535), 116 SBS_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
123}; 117};
124 118
125static enum power_supply_property bq20z75_properties[] = { 119static enum power_supply_property sbs_properties[] = {
126 POWER_SUPPLY_PROP_STATUS, 120 POWER_SUPPLY_PROP_STATUS,
127 POWER_SUPPLY_PROP_HEALTH, 121 POWER_SUPPLY_PROP_HEALTH,
128 POWER_SUPPLY_PROP_PRESENT, 122 POWER_SUPPLY_PROP_PRESENT,
@@ -144,10 +138,10 @@ static enum power_supply_property bq20z75_properties[] = {
144 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 138 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
145}; 139};
146 140
147struct bq20z75_info { 141struct sbs_info {
148 struct i2c_client *client; 142 struct i2c_client *client;
149 struct power_supply power_supply; 143 struct power_supply power_supply;
150 struct bq20z75_platform_data *pdata; 144 struct sbs_platform_data *pdata;
151 bool is_present; 145 bool is_present;
152 bool gpio_detect; 146 bool gpio_detect;
153 bool enable_detection; 147 bool enable_detection;
@@ -158,14 +152,14 @@ struct bq20z75_info {
158 int ignore_changes; 152 int ignore_changes;
159}; 153};
160 154
161static int bq20z75_read_word_data(struct i2c_client *client, u8 address) 155static int sbs_read_word_data(struct i2c_client *client, u8 address)
162{ 156{
163 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 157 struct sbs_info *chip = i2c_get_clientdata(client);
164 s32 ret = 0; 158 s32 ret = 0;
165 int retries = 1; 159 int retries = 1;
166 160
167 if (bq20z75_device->pdata) 161 if (chip->pdata)
168 retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1); 162 retries = max(chip->pdata->i2c_retry_count + 1, 1);
169 163
170 while (retries > 0) { 164 while (retries > 0) {
171 ret = i2c_smbus_read_word_data(client, address); 165 ret = i2c_smbus_read_word_data(client, address);
@@ -184,15 +178,15 @@ static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
184 return le16_to_cpu(ret); 178 return le16_to_cpu(ret);
185} 179}
186 180
187static int bq20z75_write_word_data(struct i2c_client *client, u8 address, 181static int sbs_write_word_data(struct i2c_client *client, u8 address,
188 u16 value) 182 u16 value)
189{ 183{
190 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 184 struct sbs_info *chip = i2c_get_clientdata(client);
191 s32 ret = 0; 185 s32 ret = 0;
192 int retries = 1; 186 int retries = 1;
193 187
194 if (bq20z75_device->pdata) 188 if (chip->pdata)
195 retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1); 189 retries = max(chip->pdata->i2c_retry_count + 1, 1);
196 190
197 while (retries > 0) { 191 while (retries > 0) {
198 ret = i2c_smbus_write_word_data(client, address, 192 ret = i2c_smbus_write_word_data(client, address,
@@ -212,44 +206,41 @@ static int bq20z75_write_word_data(struct i2c_client *client, u8 address,
212 return 0; 206 return 0;
213} 207}
214 208
215static int bq20z75_get_battery_presence_and_health( 209static int sbs_get_battery_presence_and_health(
216 struct i2c_client *client, enum power_supply_property psp, 210 struct i2c_client *client, enum power_supply_property psp,
217 union power_supply_propval *val) 211 union power_supply_propval *val)
218{ 212{
219 s32 ret; 213 s32 ret;
220 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 214 struct sbs_info *chip = i2c_get_clientdata(client);
221 215
222 if (psp == POWER_SUPPLY_PROP_PRESENT && 216 if (psp == POWER_SUPPLY_PROP_PRESENT &&
223 bq20z75_device->gpio_detect) { 217 chip->gpio_detect) {
224 ret = gpio_get_value( 218 ret = gpio_get_value(chip->pdata->battery_detect);
225 bq20z75_device->pdata->battery_detect); 219 if (ret == chip->pdata->battery_detect_present)
226 if (ret == bq20z75_device->pdata->battery_detect_present)
227 val->intval = 1; 220 val->intval = 1;
228 else 221 else
229 val->intval = 0; 222 val->intval = 0;
230 bq20z75_device->is_present = val->intval; 223 chip->is_present = val->intval;
231 return ret; 224 return ret;
232 } 225 }
233 226
234 /* Write to ManufacturerAccess with 227 /* Write to ManufacturerAccess with
235 * ManufacturerAccess command and then 228 * ManufacturerAccess command and then
236 * read the status */ 229 * read the status */
237 ret = bq20z75_write_word_data(client, 230 ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
238 bq20z75_data[REG_MANUFACTURER_DATA].addr, 231 MANUFACTURER_ACCESS_STATUS);
239 MANUFACTURER_ACCESS_STATUS);
240 if (ret < 0) { 232 if (ret < 0) {
241 if (psp == POWER_SUPPLY_PROP_PRESENT) 233 if (psp == POWER_SUPPLY_PROP_PRESENT)
242 val->intval = 0; /* battery removed */ 234 val->intval = 0; /* battery removed */
243 return ret; 235 return ret;
244 } 236 }
245 237
246 ret = bq20z75_read_word_data(client, 238 ret = sbs_read_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr);
247 bq20z75_data[REG_MANUFACTURER_DATA].addr);
248 if (ret < 0) 239 if (ret < 0)
249 return ret; 240 return ret;
250 241
251 if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value || 242 if (ret < sbs_data[REG_MANUFACTURER_DATA].min_value ||
252 ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) { 243 ret > sbs_data[REG_MANUFACTURER_DATA].max_value) {
253 val->intval = 0; 244 val->intval = 0;
254 return 0; 245 return 0;
255 } 246 }
@@ -279,24 +270,23 @@ static int bq20z75_get_battery_presence_and_health(
279 return 0; 270 return 0;
280} 271}
281 272
282static int bq20z75_get_battery_property(struct i2c_client *client, 273static int sbs_get_battery_property(struct i2c_client *client,
283 int reg_offset, enum power_supply_property psp, 274 int reg_offset, enum power_supply_property psp,
284 union power_supply_propval *val) 275 union power_supply_propval *val)
285{ 276{
286 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 277 struct sbs_info *chip = i2c_get_clientdata(client);
287 s32 ret; 278 s32 ret;
288 279
289 ret = bq20z75_read_word_data(client, 280 ret = sbs_read_word_data(client, sbs_data[reg_offset].addr);
290 bq20z75_data[reg_offset].addr);
291 if (ret < 0) 281 if (ret < 0)
292 return ret; 282 return ret;
293 283
294 /* returned values are 16 bit */ 284 /* returned values are 16 bit */
295 if (bq20z75_data[reg_offset].min_value < 0) 285 if (sbs_data[reg_offset].min_value < 0)
296 ret = (s16)ret; 286 ret = (s16)ret;
297 287
298 if (ret >= bq20z75_data[reg_offset].min_value && 288 if (ret >= sbs_data[reg_offset].min_value &&
299 ret <= bq20z75_data[reg_offset].max_value) { 289 ret <= sbs_data[reg_offset].max_value) {
300 val->intval = ret; 290 val->intval = ret;
301 if (psp != POWER_SUPPLY_PROP_STATUS) 291 if (psp != POWER_SUPPLY_PROP_STATUS)
302 return 0; 292 return 0;
@@ -310,12 +300,12 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
310 else 300 else
311 val->intval = POWER_SUPPLY_STATUS_CHARGING; 301 val->intval = POWER_SUPPLY_STATUS_CHARGING;
312 302
313 if (bq20z75_device->poll_time == 0) 303 if (chip->poll_time == 0)
314 bq20z75_device->last_state = val->intval; 304 chip->last_state = val->intval;
315 else if (bq20z75_device->last_state != val->intval) { 305 else if (chip->last_state != val->intval) {
316 cancel_delayed_work_sync(&bq20z75_device->work); 306 cancel_delayed_work_sync(&chip->work);
317 power_supply_changed(&bq20z75_device->power_supply); 307 power_supply_changed(&chip->power_supply);
318 bq20z75_device->poll_time = 0; 308 chip->poll_time = 0;
319 } 309 }
320 } else { 310 } else {
321 if (psp == POWER_SUPPLY_PROP_STATUS) 311 if (psp == POWER_SUPPLY_PROP_STATUS)
@@ -327,7 +317,7 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
327 return 0; 317 return 0;
328} 318}
329 319
330static void bq20z75_unit_adjustment(struct i2c_client *client, 320static void sbs_unit_adjustment(struct i2c_client *client,
331 enum power_supply_property psp, union power_supply_propval *val) 321 enum power_supply_property psp, union power_supply_propval *val)
332{ 322{
333#define BASE_UNIT_CONVERSION 1000 323#define BASE_UNIT_CONVERSION 1000
@@ -338,7 +328,7 @@ static void bq20z75_unit_adjustment(struct i2c_client *client,
338 case POWER_SUPPLY_PROP_ENERGY_NOW: 328 case POWER_SUPPLY_PROP_ENERGY_NOW:
339 case POWER_SUPPLY_PROP_ENERGY_FULL: 329 case POWER_SUPPLY_PROP_ENERGY_FULL:
340 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 330 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
341 /* bq20z75 provides energy in units of 10mWh. 331 /* sbs provides energy in units of 10mWh.
342 * Convert to µWh 332 * Convert to µWh
343 */ 333 */
344 val->intval *= BATTERY_MODE_CAP_MULT_WATT; 334 val->intval *= BATTERY_MODE_CAP_MULT_WATT;
@@ -354,7 +344,7 @@ static void bq20z75_unit_adjustment(struct i2c_client *client,
354 break; 344 break;
355 345
356 case POWER_SUPPLY_PROP_TEMP: 346 case POWER_SUPPLY_PROP_TEMP:
357 /* bq20z75 provides battery temperature in 0.1K 347 /* sbs provides battery temperature in 0.1K
358 * so convert it to 0.1°C 348 * so convert it to 0.1°C
359 */ 349 */
360 val->intval -= TEMP_KELVIN_TO_CELSIUS; 350 val->intval -= TEMP_KELVIN_TO_CELSIUS;
@@ -362,7 +352,7 @@ static void bq20z75_unit_adjustment(struct i2c_client *client,
362 352
363 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 353 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
364 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 354 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
365 /* bq20z75 provides time to empty and time to full in minutes. 355 /* sbs provides time to empty and time to full in minutes.
366 * Convert to seconds 356 * Convert to seconds
367 */ 357 */
368 val->intval *= TIME_UNIT_CONVERSION; 358 val->intval *= TIME_UNIT_CONVERSION;
@@ -374,13 +364,12 @@ static void bq20z75_unit_adjustment(struct i2c_client *client,
374 } 364 }
375} 365}
376 366
377static enum bq20z75_battery_mode 367static enum sbs_battery_mode sbs_set_battery_mode(struct i2c_client *client,
378bq20z75_set_battery_mode(struct i2c_client *client, 368 enum sbs_battery_mode mode)
379 enum bq20z75_battery_mode mode)
380{ 369{
381 int ret, original_val; 370 int ret, original_val;
382 371
383 original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET); 372 original_val = sbs_read_word_data(client, BATTERY_MODE_OFFSET);
384 if (original_val < 0) 373 if (original_val < 0)
385 return original_val; 374 return original_val;
386 375
@@ -392,68 +381,67 @@ bq20z75_set_battery_mode(struct i2c_client *client,
392 else 381 else
393 ret = original_val | BATTERY_MODE_MASK; 382 ret = original_val | BATTERY_MODE_MASK;
394 383
395 ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret); 384 ret = sbs_write_word_data(client, BATTERY_MODE_OFFSET, ret);
396 if (ret < 0) 385 if (ret < 0)
397 return ret; 386 return ret;
398 387
399 return original_val & BATTERY_MODE_MASK; 388 return original_val & BATTERY_MODE_MASK;
400} 389}
401 390
402static int bq20z75_get_battery_capacity(struct i2c_client *client, 391static int sbs_get_battery_capacity(struct i2c_client *client,
403 int reg_offset, enum power_supply_property psp, 392 int reg_offset, enum power_supply_property psp,
404 union power_supply_propval *val) 393 union power_supply_propval *val)
405{ 394{
406 s32 ret; 395 s32 ret;
407 enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS; 396 enum sbs_battery_mode mode = BATTERY_MODE_WATTS;
408 397
409 if (power_supply_is_amp_property(psp)) 398 if (power_supply_is_amp_property(psp))
410 mode = BATTERY_MODE_AMPS; 399 mode = BATTERY_MODE_AMPS;
411 400
412 mode = bq20z75_set_battery_mode(client, mode); 401 mode = sbs_set_battery_mode(client, mode);
413 if (mode < 0) 402 if (mode < 0)
414 return mode; 403 return mode;
415 404
416 ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr); 405 ret = sbs_read_word_data(client, sbs_data[reg_offset].addr);
417 if (ret < 0) 406 if (ret < 0)
418 return ret; 407 return ret;
419 408
420 if (psp == POWER_SUPPLY_PROP_CAPACITY) { 409 if (psp == POWER_SUPPLY_PROP_CAPACITY) {
421 /* bq20z75 spec says that this can be >100 % 410 /* sbs spec says that this can be >100 %
422 * even if max value is 100 % */ 411 * even if max value is 100 % */
423 val->intval = min(ret, 100); 412 val->intval = min(ret, 100);
424 } else 413 } else
425 val->intval = ret; 414 val->intval = ret;
426 415
427 ret = bq20z75_set_battery_mode(client, mode); 416 ret = sbs_set_battery_mode(client, mode);
428 if (ret < 0) 417 if (ret < 0)
429 return ret; 418 return ret;
430 419
431 return 0; 420 return 0;
432} 421}
433 422
434static char bq20z75_serial[5]; 423static char sbs_serial[5];
435static int bq20z75_get_battery_serial_number(struct i2c_client *client, 424static int sbs_get_battery_serial_number(struct i2c_client *client,
436 union power_supply_propval *val) 425 union power_supply_propval *val)
437{ 426{
438 int ret; 427 int ret;
439 428
440 ret = bq20z75_read_word_data(client, 429 ret = sbs_read_word_data(client, sbs_data[REG_SERIAL_NUMBER].addr);
441 bq20z75_data[REG_SERIAL_NUMBER].addr);
442 if (ret < 0) 430 if (ret < 0)
443 return ret; 431 return ret;
444 432
445 ret = sprintf(bq20z75_serial, "%04x", ret); 433 ret = sprintf(sbs_serial, "%04x", ret);
446 val->strval = bq20z75_serial; 434 val->strval = sbs_serial;
447 435
448 return 0; 436 return 0;
449} 437}
450 438
451static int bq20z75_get_property_index(struct i2c_client *client, 439static int sbs_get_property_index(struct i2c_client *client,
452 enum power_supply_property psp) 440 enum power_supply_property psp)
453{ 441{
454 int count; 442 int count;
455 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++) 443 for (count = 0; count < ARRAY_SIZE(sbs_data); count++)
456 if (psp == bq20z75_data[count].psp) 444 if (psp == sbs_data[count].psp)
457 return count; 445 return count;
458 446
459 dev_warn(&client->dev, 447 dev_warn(&client->dev,
@@ -462,19 +450,19 @@ static int bq20z75_get_property_index(struct i2c_client *client,
462 return -EINVAL; 450 return -EINVAL;
463} 451}
464 452
465static int bq20z75_get_property(struct power_supply *psy, 453static int sbs_get_property(struct power_supply *psy,
466 enum power_supply_property psp, 454 enum power_supply_property psp,
467 union power_supply_propval *val) 455 union power_supply_propval *val)
468{ 456{
469 int ret = 0; 457 int ret = 0;
470 struct bq20z75_info *bq20z75_device = container_of(psy, 458 struct sbs_info *chip = container_of(psy,
471 struct bq20z75_info, power_supply); 459 struct sbs_info, power_supply);
472 struct i2c_client *client = bq20z75_device->client; 460 struct i2c_client *client = chip->client;
473 461
474 switch (psp) { 462 switch (psp) {
475 case POWER_SUPPLY_PROP_PRESENT: 463 case POWER_SUPPLY_PROP_PRESENT:
476 case POWER_SUPPLY_PROP_HEALTH: 464 case POWER_SUPPLY_PROP_HEALTH:
477 ret = bq20z75_get_battery_presence_and_health(client, psp, val); 465 ret = sbs_get_battery_presence_and_health(client, psp, val);
478 if (psp == POWER_SUPPLY_PROP_PRESENT) 466 if (psp == POWER_SUPPLY_PROP_PRESENT)
479 return 0; 467 return 0;
480 break; 468 break;
@@ -490,15 +478,15 @@ static int bq20z75_get_property(struct power_supply *psy,
490 case POWER_SUPPLY_PROP_CHARGE_FULL: 478 case POWER_SUPPLY_PROP_CHARGE_FULL:
491 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 479 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
492 case POWER_SUPPLY_PROP_CAPACITY: 480 case POWER_SUPPLY_PROP_CAPACITY:
493 ret = bq20z75_get_property_index(client, psp); 481 ret = sbs_get_property_index(client, psp);
494 if (ret < 0) 482 if (ret < 0)
495 break; 483 break;
496 484
497 ret = bq20z75_get_battery_capacity(client, ret, psp, val); 485 ret = sbs_get_battery_capacity(client, ret, psp, val);
498 break; 486 break;
499 487
500 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 488 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
501 ret = bq20z75_get_battery_serial_number(client, val); 489 ret = sbs_get_battery_serial_number(client, val);
502 break; 490 break;
503 491
504 case POWER_SUPPLY_PROP_STATUS: 492 case POWER_SUPPLY_PROP_STATUS:
@@ -509,11 +497,11 @@ static int bq20z75_get_property(struct power_supply *psy,
509 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 497 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
510 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 498 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
511 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 499 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
512 ret = bq20z75_get_property_index(client, psp); 500 ret = sbs_get_property_index(client, psp);
513 if (ret < 0) 501 if (ret < 0)
514 break; 502 break;
515 503
516 ret = bq20z75_get_battery_property(client, ret, psp, val); 504 ret = sbs_get_battery_property(client, ret, psp, val);
517 break; 505 break;
518 506
519 default: 507 default:
@@ -522,25 +510,25 @@ static int bq20z75_get_property(struct power_supply *psy,
522 return -EINVAL; 510 return -EINVAL;
523 } 511 }
524 512
525 if (!bq20z75_device->enable_detection) 513 if (!chip->enable_detection)
526 goto done; 514 goto done;
527 515
528 if (!bq20z75_device->gpio_detect && 516 if (!chip->gpio_detect &&
529 bq20z75_device->is_present != (ret >= 0)) { 517 chip->is_present != (ret >= 0)) {
530 bq20z75_device->is_present = (ret >= 0); 518 chip->is_present = (ret >= 0);
531 power_supply_changed(&bq20z75_device->power_supply); 519 power_supply_changed(&chip->power_supply);
532 } 520 }
533 521
534done: 522done:
535 if (!ret) { 523 if (!ret) {
536 /* Convert units to match requirements for power supply class */ 524 /* Convert units to match requirements for power supply class */
537 bq20z75_unit_adjustment(client, psp, val); 525 sbs_unit_adjustment(client, psp, val);
538 } 526 }
539 527
540 dev_dbg(&client->dev, 528 dev_dbg(&client->dev,
541 "%s: property = %d, value = %x\n", __func__, psp, val->intval); 529 "%s: property = %d, value = %x\n", __func__, psp, val->intval);
542 530
543 if (ret && bq20z75_device->is_present) 531 if (ret && chip->is_present)
544 return ret; 532 return ret;
545 533
546 /* battery not present, so return NODATA for properties */ 534 /* battery not present, so return NODATA for properties */
@@ -550,7 +538,7 @@ done:
550 return 0; 538 return 0;
551} 539}
552 540
553static irqreturn_t bq20z75_irq(int irq, void *devid) 541static irqreturn_t sbs_irq(int irq, void *devid)
554{ 542{
555 struct power_supply *battery = devid; 543 struct power_supply *battery = devid;
556 544
@@ -559,36 +547,35 @@ static irqreturn_t bq20z75_irq(int irq, void *devid)
559 return IRQ_HANDLED; 547 return IRQ_HANDLED;
560} 548}
561 549
562static void bq20z75_external_power_changed(struct power_supply *psy) 550static void sbs_external_power_changed(struct power_supply *psy)
563{ 551{
564 struct bq20z75_info *bq20z75_device; 552 struct sbs_info *chip;
565 553
566 bq20z75_device = container_of(psy, struct bq20z75_info, power_supply); 554 chip = container_of(psy, struct sbs_info, power_supply);
567 555
568 if (bq20z75_device->ignore_changes > 0) { 556 if (chip->ignore_changes > 0) {
569 bq20z75_device->ignore_changes--; 557 chip->ignore_changes--;
570 return; 558 return;
571 } 559 }
572 560
573 /* cancel outstanding work */ 561 /* cancel outstanding work */
574 cancel_delayed_work_sync(&bq20z75_device->work); 562 cancel_delayed_work_sync(&chip->work);
575 563
576 schedule_delayed_work(&bq20z75_device->work, HZ); 564 schedule_delayed_work(&chip->work, HZ);
577 bq20z75_device->poll_time = bq20z75_device->pdata->poll_retry_count; 565 chip->poll_time = chip->pdata->poll_retry_count;
578} 566}
579 567
580static void bq20z75_delayed_work(struct work_struct *work) 568static void sbs_delayed_work(struct work_struct *work)
581{ 569{
582 struct bq20z75_info *bq20z75_device; 570 struct sbs_info *chip;
583 s32 ret; 571 s32 ret;
584 572
585 bq20z75_device = container_of(work, struct bq20z75_info, work.work); 573 chip = container_of(work, struct sbs_info, work.work);
586 574
587 ret = bq20z75_read_word_data(bq20z75_device->client, 575 ret = sbs_read_word_data(chip->client, sbs_data[REG_STATUS].addr);
588 bq20z75_data[REG_STATUS].addr);
589 /* if the read failed, give up on this work */ 576 /* if the read failed, give up on this work */
590 if (ret < 0) { 577 if (ret < 0) {
591 bq20z75_device->poll_time = 0; 578 chip->poll_time = 0;
592 return; 579 return;
593 } 580 }
594 581
@@ -601,62 +588,145 @@ static void bq20z75_delayed_work(struct work_struct *work)
601 else 588 else
602 ret = POWER_SUPPLY_STATUS_CHARGING; 589 ret = POWER_SUPPLY_STATUS_CHARGING;
603 590
604 if (bq20z75_device->last_state != ret) { 591 if (chip->last_state != ret) {
605 bq20z75_device->poll_time = 0; 592 chip->poll_time = 0;
606 power_supply_changed(&bq20z75_device->power_supply); 593 power_supply_changed(&chip->power_supply);
607 return; 594 return;
608 } 595 }
609 if (bq20z75_device->poll_time > 0) { 596 if (chip->poll_time > 0) {
610 schedule_delayed_work(&bq20z75_device->work, HZ); 597 schedule_delayed_work(&chip->work, HZ);
611 bq20z75_device->poll_time--; 598 chip->poll_time--;
612 return; 599 return;
613 } 600 }
614} 601}
615 602
616static int __devinit bq20z75_probe(struct i2c_client *client, 603#if defined(CONFIG_OF)
604
605#include <linux/of_device.h>
606#include <linux/of_gpio.h>
607
608static const struct of_device_id sbs_dt_ids[] = {
609 { .compatible = "sbs,sbs-battery" },
610 { .compatible = "ti,bq20z75" },
611 { }
612};
613MODULE_DEVICE_TABLE(of, sbs_dt_ids);
614
615static struct sbs_platform_data *sbs_of_populate_pdata(
616 struct i2c_client *client)
617{
618 struct device_node *of_node = client->dev.of_node;
619 struct sbs_platform_data *pdata = client->dev.platform_data;
620 enum of_gpio_flags gpio_flags;
621 int rc;
622 u32 prop;
623
624 /* verify this driver matches this device */
625 if (!of_node)
626 return NULL;
627
628 /* if platform data is set, honor it */
629 if (pdata)
630 return pdata;
631
632 /* first make sure at least one property is set, otherwise
633 * it won't change behavior from running without pdata.
634 */
635 if (!of_get_property(of_node, "sbs,i2c-retry-count", NULL) &&
636 !of_get_property(of_node, "sbs,poll-retry-count", NULL) &&
637 !of_get_property(of_node, "sbs,battery-detect-gpios", NULL))
638 goto of_out;
639
640 pdata = devm_kzalloc(&client->dev, sizeof(struct sbs_platform_data),
641 GFP_KERNEL);
642 if (!pdata)
643 goto of_out;
644
645 rc = of_property_read_u32(of_node, "sbs,i2c-retry-count", &prop);
646 if (!rc)
647 pdata->i2c_retry_count = prop;
648
649 rc = of_property_read_u32(of_node, "sbs,poll-retry-count", &prop);
650 if (!rc)
651 pdata->poll_retry_count = prop;
652
653 if (!of_get_property(of_node, "sbs,battery-detect-gpios", NULL)) {
654 pdata->battery_detect = -1;
655 goto of_out;
656 }
657
658 pdata->battery_detect = of_get_named_gpio_flags(of_node,
659 "sbs,battery-detect-gpios", 0, &gpio_flags);
660
661 if (gpio_flags & OF_GPIO_ACTIVE_LOW)
662 pdata->battery_detect_present = 0;
663 else
664 pdata->battery_detect_present = 1;
665
666of_out:
667 return pdata;
668}
669#else
670#define sbs_dt_ids NULL
671static struct sbs_platform_data *sbs_of_populate_pdata(
672 struct i2c_client *client)
673{
674 return client->dev.platform_data;
675}
676#endif
677
678static int __devinit sbs_probe(struct i2c_client *client,
617 const struct i2c_device_id *id) 679 const struct i2c_device_id *id)
618{ 680{
619 struct bq20z75_info *bq20z75_device; 681 struct sbs_info *chip;
620 struct bq20z75_platform_data *pdata = client->dev.platform_data; 682 struct sbs_platform_data *pdata = client->dev.platform_data;
621 int rc; 683 int rc;
622 int irq; 684 int irq;
685 char *name;
623 686
624 bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL); 687 name = kasprintf(GFP_KERNEL, "sbs-%s", dev_name(&client->dev));
625 if (!bq20z75_device) 688 if (!name) {
689 dev_err(&client->dev, "Failed to allocate device name\n");
626 return -ENOMEM; 690 return -ENOMEM;
691 }
692
693 chip = kzalloc(sizeof(struct sbs_info), GFP_KERNEL);
694 if (!chip) {
695 rc = -ENOMEM;
696 goto exit_free_name;
697 }
627 698
628 bq20z75_device->client = client; 699 chip->client = client;
629 bq20z75_device->enable_detection = false; 700 chip->enable_detection = false;
630 bq20z75_device->gpio_detect = false; 701 chip->gpio_detect = false;
631 bq20z75_device->power_supply.name = "battery"; 702 chip->power_supply.name = name;
632 bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY; 703 chip->power_supply.type = POWER_SUPPLY_TYPE_BATTERY;
633 bq20z75_device->power_supply.properties = bq20z75_properties; 704 chip->power_supply.properties = sbs_properties;
634 bq20z75_device->power_supply.num_properties = 705 chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties);
635 ARRAY_SIZE(bq20z75_properties); 706 chip->power_supply.get_property = sbs_get_property;
636 bq20z75_device->power_supply.get_property = bq20z75_get_property;
637 /* ignore first notification of external change, it is generated 707 /* ignore first notification of external change, it is generated
638 * from the power_supply_register call back 708 * from the power_supply_register call back
639 */ 709 */
640 bq20z75_device->ignore_changes = 1; 710 chip->ignore_changes = 1;
641 bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN; 711 chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
642 bq20z75_device->power_supply.external_power_changed = 712 chip->power_supply.external_power_changed = sbs_external_power_changed;
643 bq20z75_external_power_changed; 713
714 pdata = sbs_of_populate_pdata(client);
644 715
645 if (pdata) { 716 if (pdata) {
646 bq20z75_device->gpio_detect = 717 chip->gpio_detect = gpio_is_valid(pdata->battery_detect);
647 gpio_is_valid(pdata->battery_detect); 718 chip->pdata = pdata;
648 bq20z75_device->pdata = pdata;
649 } 719 }
650 720
651 i2c_set_clientdata(client, bq20z75_device); 721 i2c_set_clientdata(client, chip);
652 722
653 if (!bq20z75_device->gpio_detect) 723 if (!chip->gpio_detect)
654 goto skip_gpio; 724 goto skip_gpio;
655 725
656 rc = gpio_request(pdata->battery_detect, dev_name(&client->dev)); 726 rc = gpio_request(pdata->battery_detect, dev_name(&client->dev));
657 if (rc) { 727 if (rc) {
658 dev_warn(&client->dev, "Failed to request gpio: %d\n", rc); 728 dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
659 bq20z75_device->gpio_detect = false; 729 chip->gpio_detect = false;
660 goto skip_gpio; 730 goto skip_gpio;
661 } 731 }
662 732
@@ -664,7 +734,7 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
664 if (rc) { 734 if (rc) {
665 dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc); 735 dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
666 gpio_free(pdata->battery_detect); 736 gpio_free(pdata->battery_detect);
667 bq20z75_device->gpio_detect = false; 737 chip->gpio_detect = false;
668 goto skip_gpio; 738 goto skip_gpio;
669 } 739 }
670 740
@@ -672,25 +742,25 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
672 if (irq <= 0) { 742 if (irq <= 0) {
673 dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); 743 dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
674 gpio_free(pdata->battery_detect); 744 gpio_free(pdata->battery_detect);
675 bq20z75_device->gpio_detect = false; 745 chip->gpio_detect = false;
676 goto skip_gpio; 746 goto skip_gpio;
677 } 747 }
678 748
679 rc = request_irq(irq, bq20z75_irq, 749 rc = request_irq(irq, sbs_irq,
680 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 750 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
681 dev_name(&client->dev), &bq20z75_device->power_supply); 751 dev_name(&client->dev), &chip->power_supply);
682 if (rc) { 752 if (rc) {
683 dev_warn(&client->dev, "Failed to request irq: %d\n", rc); 753 dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
684 gpio_free(pdata->battery_detect); 754 gpio_free(pdata->battery_detect);
685 bq20z75_device->gpio_detect = false; 755 chip->gpio_detect = false;
686 goto skip_gpio; 756 goto skip_gpio;
687 } 757 }
688 758
689 bq20z75_device->irq = irq; 759 chip->irq = irq;
690 760
691skip_gpio: 761skip_gpio:
692 762
693 rc = power_supply_register(&client->dev, &bq20z75_device->power_supply); 763 rc = power_supply_register(&client->dev, &chip->power_supply);
694 if (rc) { 764 if (rc) {
695 dev_err(&client->dev, 765 dev_err(&client->dev,
696 "%s: Failed to register power supply\n", __func__); 766 "%s: Failed to register power supply\n", __func__);
@@ -700,95 +770,100 @@ skip_gpio:
700 dev_info(&client->dev, 770 dev_info(&client->dev,
701 "%s: battery gas gauge device registered\n", client->name); 771 "%s: battery gas gauge device registered\n", client->name);
702 772
703 INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work); 773 INIT_DELAYED_WORK(&chip->work, sbs_delayed_work);
704 774
705 bq20z75_device->enable_detection = true; 775 chip->enable_detection = true;
706 776
707 return 0; 777 return 0;
708 778
709exit_psupply: 779exit_psupply:
710 if (bq20z75_device->irq) 780 if (chip->irq)
711 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply); 781 free_irq(chip->irq, &chip->power_supply);
712 if (bq20z75_device->gpio_detect) 782 if (chip->gpio_detect)
713 gpio_free(pdata->battery_detect); 783 gpio_free(pdata->battery_detect);
714 784
715 kfree(bq20z75_device); 785 kfree(chip);
786
787exit_free_name:
788 kfree(name);
716 789
717 return rc; 790 return rc;
718} 791}
719 792
720static int __devexit bq20z75_remove(struct i2c_client *client) 793static int __devexit sbs_remove(struct i2c_client *client)
721{ 794{
722 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 795 struct sbs_info *chip = i2c_get_clientdata(client);
723 796
724 if (bq20z75_device->irq) 797 if (chip->irq)
725 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply); 798 free_irq(chip->irq, &chip->power_supply);
726 if (bq20z75_device->gpio_detect) 799 if (chip->gpio_detect)
727 gpio_free(bq20z75_device->pdata->battery_detect); 800 gpio_free(chip->pdata->battery_detect);
728 801
729 power_supply_unregister(&bq20z75_device->power_supply); 802 power_supply_unregister(&chip->power_supply);
730 803
731 cancel_delayed_work_sync(&bq20z75_device->work); 804 cancel_delayed_work_sync(&chip->work);
732 805
733 kfree(bq20z75_device); 806 kfree(chip->power_supply.name);
734 bq20z75_device = NULL; 807 kfree(chip);
808 chip = NULL;
735 809
736 return 0; 810 return 0;
737} 811}
738 812
739#if defined CONFIG_PM 813#if defined CONFIG_PM
740static int bq20z75_suspend(struct i2c_client *client, 814static int sbs_suspend(struct i2c_client *client,
741 pm_message_t state) 815 pm_message_t state)
742{ 816{
743 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); 817 struct sbs_info *chip = i2c_get_clientdata(client);
744 s32 ret; 818 s32 ret;
745 819
746 if (bq20z75_device->poll_time > 0) 820 if (chip->poll_time > 0)
747 cancel_delayed_work_sync(&bq20z75_device->work); 821 cancel_delayed_work_sync(&chip->work);
748 822
749 /* write to manufacturer access with sleep command */ 823 /* write to manufacturer access with sleep command */
750 ret = bq20z75_write_word_data(client, 824 ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
751 bq20z75_data[REG_MANUFACTURER_DATA].addr,
752 MANUFACTURER_ACCESS_SLEEP); 825 MANUFACTURER_ACCESS_SLEEP);
753 if (bq20z75_device->is_present && ret < 0) 826 if (chip->is_present && ret < 0)
754 return ret; 827 return ret;
755 828
756 return 0; 829 return 0;
757} 830}
758#else 831#else
759#define bq20z75_suspend NULL 832#define sbs_suspend NULL
760#endif 833#endif
761/* any smbus transaction will wake up bq20z75 */ 834/* any smbus transaction will wake up sbs */
762#define bq20z75_resume NULL 835#define sbs_resume NULL
763 836
764static const struct i2c_device_id bq20z75_id[] = { 837static const struct i2c_device_id sbs_id[] = {
765 { "bq20z75", 0 }, 838 { "bq20z75", 0 },
839 { "sbs-battery", 1 },
766 {} 840 {}
767}; 841};
768MODULE_DEVICE_TABLE(i2c, bq20z75_id); 842MODULE_DEVICE_TABLE(i2c, sbs_id);
769 843
770static struct i2c_driver bq20z75_battery_driver = { 844static struct i2c_driver sbs_battery_driver = {
771 .probe = bq20z75_probe, 845 .probe = sbs_probe,
772 .remove = __devexit_p(bq20z75_remove), 846 .remove = __devexit_p(sbs_remove),
773 .suspend = bq20z75_suspend, 847 .suspend = sbs_suspend,
774 .resume = bq20z75_resume, 848 .resume = sbs_resume,
775 .id_table = bq20z75_id, 849 .id_table = sbs_id,
776 .driver = { 850 .driver = {
777 .name = "bq20z75-battery", 851 .name = "sbs-battery",
852 .of_match_table = sbs_dt_ids,
778 }, 853 },
779}; 854};
780 855
781static int __init bq20z75_battery_init(void) 856static int __init sbs_battery_init(void)
782{ 857{
783 return i2c_add_driver(&bq20z75_battery_driver); 858 return i2c_add_driver(&sbs_battery_driver);
784} 859}
785module_init(bq20z75_battery_init); 860module_init(sbs_battery_init);
786 861
787static void __exit bq20z75_battery_exit(void) 862static void __exit sbs_battery_exit(void)
788{ 863{
789 i2c_del_driver(&bq20z75_battery_driver); 864 i2c_del_driver(&sbs_battery_driver);
790} 865}
791module_exit(bq20z75_battery_exit); 866module_exit(sbs_battery_exit);
792 867
793MODULE_DESCRIPTION("BQ20z75 battery monitor driver"); 868MODULE_DESCRIPTION("SBS battery monitor driver");
794MODULE_LICENSE("GPL"); 869MODULE_LICENSE("GPL");
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
index 53f0d3524fcd..28bbe7e094e3 100644
--- a/drivers/power/tosa_battery.c
+++ b/drivers/power/tosa_battery.c
@@ -307,25 +307,20 @@ static struct tosa_bat tosa_bat_bu = {
307 .adc_temp_divider = -1, 307 .adc_temp_divider = -1,
308}; 308};
309 309
310static struct { 310static struct gpio tosa_bat_gpios[] = {
311 int gpio; 311 { TOSA_GPIO_CHARGE_OFF, GPIOF_OUT_INIT_HIGH, "main charge off" },
312 char *name; 312 { TOSA_GPIO_CHARGE_OFF_JC, GPIOF_OUT_INIT_HIGH, "jacket charge off" },
313 bool output; 313 { TOSA_GPIO_BAT_SW_ON, GPIOF_OUT_INIT_LOW, "battery switch" },
314 int value; 314 { TOSA_GPIO_BAT0_V_ON, GPIOF_OUT_INIT_LOW, "main battery" },
315} gpios[] = { 315 { TOSA_GPIO_BAT1_V_ON, GPIOF_OUT_INIT_LOW, "jacket battery" },
316 { TOSA_GPIO_CHARGE_OFF, "main charge off", 1, 1 }, 316 { TOSA_GPIO_BAT1_TH_ON, GPIOF_OUT_INIT_LOW, "main battery temp" },
317 { TOSA_GPIO_CHARGE_OFF_JC, "jacket charge off", 1, 1 }, 317 { TOSA_GPIO_BAT0_TH_ON, GPIOF_OUT_INIT_LOW, "jacket battery temp" },
318 { TOSA_GPIO_BAT_SW_ON, "battery switch", 1, 0 }, 318 { TOSA_GPIO_BU_CHRG_ON, GPIOF_OUT_INIT_LOW, "backup battery" },
319 { TOSA_GPIO_BAT0_V_ON, "main battery", 1, 0 }, 319 { TOSA_GPIO_BAT0_CRG, GPIOF_IN, "main battery full" },
320 { TOSA_GPIO_BAT1_V_ON, "jacket battery", 1, 0 }, 320 { TOSA_GPIO_BAT1_CRG, GPIOF_IN, "jacket battery full" },
321 { TOSA_GPIO_BAT1_TH_ON, "main battery temp", 1, 0 }, 321 { TOSA_GPIO_BAT0_LOW, GPIOF_IN, "main battery low" },
322 { TOSA_GPIO_BAT0_TH_ON, "jacket battery temp", 1, 0 }, 322 { TOSA_GPIO_BAT1_LOW, GPIOF_IN, "jacket battery low" },
323 { TOSA_GPIO_BU_CHRG_ON, "backup battery", 1, 0 }, 323 { TOSA_GPIO_JACKET_DETECT, GPIOF_IN, "jacket detect" },
324 { TOSA_GPIO_BAT0_CRG, "main battery full", 0, 0 },
325 { TOSA_GPIO_BAT1_CRG, "jacket battery full", 0, 0 },
326 { TOSA_GPIO_BAT0_LOW, "main battery low", 0, 0 },
327 { TOSA_GPIO_BAT1_LOW, "jacket battery low", 0, 0 },
328 { TOSA_GPIO_JACKET_DETECT, "jacket detect", 0, 0 },
329}; 324};
330 325
331#ifdef CONFIG_PM 326#ifdef CONFIG_PM
@@ -350,27 +345,13 @@ static int tosa_bat_resume(struct platform_device *dev)
350static int __devinit tosa_bat_probe(struct platform_device *dev) 345static int __devinit tosa_bat_probe(struct platform_device *dev)
351{ 346{
352 int ret; 347 int ret;
353 int i;
354 348
355 if (!machine_is_tosa()) 349 if (!machine_is_tosa())
356 return -ENODEV; 350 return -ENODEV;
357 351
358 for (i = 0; i < ARRAY_SIZE(gpios); i++) { 352 ret = gpio_request_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
359 ret = gpio_request(gpios[i].gpio, gpios[i].name); 353 if (ret)
360 if (ret) { 354 return ret;
361 i--;
362 goto err_gpio;
363 }
364
365 if (gpios[i].output)
366 ret = gpio_direction_output(gpios[i].gpio,
367 gpios[i].value);
368 else
369 ret = gpio_direction_input(gpios[i].gpio);
370
371 if (ret)
372 goto err_gpio;
373 }
374 355
375 mutex_init(&tosa_bat_main.work_lock); 356 mutex_init(&tosa_bat_main.work_lock);
376 mutex_init(&tosa_bat_jacket.work_lock); 357 mutex_init(&tosa_bat_jacket.work_lock);
@@ -424,18 +405,12 @@ err_psy_reg_main:
424 /* see comment in tosa_bat_remove */ 405 /* see comment in tosa_bat_remove */
425 cancel_work_sync(&bat_work); 406 cancel_work_sync(&bat_work);
426 407
427 i--; 408 gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
428err_gpio:
429 for (; i >= 0; i--)
430 gpio_free(gpios[i].gpio);
431
432 return ret; 409 return ret;
433} 410}
434 411
435static int __devexit tosa_bat_remove(struct platform_device *dev) 412static int __devexit tosa_bat_remove(struct platform_device *dev)
436{ 413{
437 int i;
438
439 free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket); 414 free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket);
440 free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); 415 free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
441 free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); 416 free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
@@ -450,10 +425,7 @@ static int __devexit tosa_bat_remove(struct platform_device *dev)
450 * unregistered now. 425 * unregistered now.
451 */ 426 */
452 cancel_work_sync(&bat_work); 427 cancel_work_sync(&bat_work);
453 428 gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
454 for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
455 gpio_free(gpios[i].gpio);
456
457 return 0; 429 return 0;
458} 430}
459 431
@@ -466,18 +438,7 @@ static struct platform_driver tosa_bat_driver = {
466 .resume = tosa_bat_resume, 438 .resume = tosa_bat_resume,
467}; 439};
468 440
469static int __init tosa_bat_init(void) 441module_platform_driver(tosa_bat_driver);
470{
471 return platform_driver_register(&tosa_bat_driver);
472}
473
474static void __exit tosa_bat_exit(void)
475{
476 platform_driver_unregister(&tosa_bat_driver);
477}
478
479module_init(tosa_bat_init);
480module_exit(tosa_bat_exit);
481 442
482MODULE_LICENSE("GPL"); 443MODULE_LICENSE("GPL");
483MODULE_AUTHOR("Dmitry Baryshkov"); 444MODULE_AUTHOR("Dmitry Baryshkov");
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c
index e648cbea1e6a..6243e6975126 100644
--- a/drivers/power/wm831x_backup.c
+++ b/drivers/power/wm831x_backup.c
@@ -226,17 +226,7 @@ static struct platform_driver wm831x_backup_driver = {
226 }, 226 },
227}; 227};
228 228
229static int __init wm831x_backup_init(void) 229module_platform_driver(wm831x_backup_driver);
230{
231 return platform_driver_register(&wm831x_backup_driver);
232}
233module_init(wm831x_backup_init);
234
235static void __exit wm831x_backup_exit(void)
236{
237 platform_driver_unregister(&wm831x_backup_driver);
238}
239module_exit(wm831x_backup_exit);
240 230
241MODULE_DESCRIPTION("Backup battery charger driver for WM831x PMICs"); 231MODULE_DESCRIPTION("Backup battery charger driver for WM831x PMICs");
242MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 232MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index 6cc2ca6427f3..987332b71d8d 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -27,6 +27,7 @@ struct wm831x_power {
27 char wall_name[20]; 27 char wall_name[20];
28 char usb_name[20]; 28 char usb_name[20];
29 char battery_name[20]; 29 char battery_name[20];
30 bool have_battery;
30}; 31};
31 32
32static int wm831x_power_check_online(struct wm831x *wm831x, int supply, 33static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -449,7 +450,8 @@ static irqreturn_t wm831x_bat_irq(int irq, void *data)
449 450
450 /* The battery charger is autonomous so we don't need to do 451 /* The battery charger is autonomous so we don't need to do
451 * anything except kick user space */ 452 * anything except kick user space */
452 power_supply_changed(&wm831x_power->battery); 453 if (wm831x_power->have_battery)
454 power_supply_changed(&wm831x_power->battery);
453 455
454 return IRQ_HANDLED; 456 return IRQ_HANDLED;
455} 457}
@@ -479,7 +481,8 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
479 dev_dbg(wm831x->dev, "Power source changed\n"); 481 dev_dbg(wm831x->dev, "Power source changed\n");
480 482
481 /* Just notify for everything - little harm in overnotifying. */ 483 /* Just notify for everything - little harm in overnotifying. */
482 power_supply_changed(&wm831x_power->battery); 484 if (wm831x_power->have_battery)
485 power_supply_changed(&wm831x_power->battery);
483 power_supply_changed(&wm831x_power->usb); 486 power_supply_changed(&wm831x_power->usb);
484 power_supply_changed(&wm831x_power->wall); 487 power_supply_changed(&wm831x_power->wall);
485 488
@@ -537,15 +540,6 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
537 if (ret) 540 if (ret)
538 goto err_kmalloc; 541 goto err_kmalloc;
539 542
540 battery->name = power->battery_name;
541 battery->properties = wm831x_bat_props;
542 battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
543 battery->get_property = wm831x_bat_get_prop;
544 battery->use_for_apm = 1;
545 ret = power_supply_register(&pdev->dev, battery);
546 if (ret)
547 goto err_wall;
548
549 usb->name = power->usb_name, 543 usb->name = power->usb_name,
550 usb->type = POWER_SUPPLY_TYPE_USB; 544 usb->type = POWER_SUPPLY_TYPE_USB;
551 usb->properties = wm831x_usb_props; 545 usb->properties = wm831x_usb_props;
@@ -553,7 +547,23 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
553 usb->get_property = wm831x_usb_get_prop; 547 usb->get_property = wm831x_usb_get_prop;
554 ret = power_supply_register(&pdev->dev, usb); 548 ret = power_supply_register(&pdev->dev, usb);
555 if (ret) 549 if (ret)
556 goto err_battery; 550 goto err_wall;
551
552 ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1);
553 if (ret < 0)
554 goto err_wall;
555 power->have_battery = ret & WM831X_CHG_ENA;
556
557 if (power->have_battery) {
558 battery->name = power->battery_name;
559 battery->properties = wm831x_bat_props;
560 battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
561 battery->get_property = wm831x_bat_get_prop;
562 battery->use_for_apm = 1;
563 ret = power_supply_register(&pdev->dev, battery);
564 if (ret)
565 goto err_usb;
566 }
557 567
558 irq = platform_get_irq_byname(pdev, "SYSLO"); 568 irq = platform_get_irq_byname(pdev, "SYSLO");
559 ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq, 569 ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
@@ -562,7 +572,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
562 if (ret != 0) { 572 if (ret != 0) {
563 dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n", 573 dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
564 irq, ret); 574 irq, ret);
565 goto err_usb; 575 goto err_battery;
566 } 576 }
567 577
568 irq = platform_get_irq_byname(pdev, "PWR SRC"); 578 irq = platform_get_irq_byname(pdev, "PWR SRC");
@@ -601,10 +611,11 @@ err_bat_irq:
601err_syslo: 611err_syslo:
602 irq = platform_get_irq_byname(pdev, "SYSLO"); 612 irq = platform_get_irq_byname(pdev, "SYSLO");
603 free_irq(irq, power); 613 free_irq(irq, power);
614err_battery:
615 if (power->have_battery)
616 power_supply_unregister(battery);
604err_usb: 617err_usb:
605 power_supply_unregister(usb); 618 power_supply_unregister(usb);
606err_battery:
607 power_supply_unregister(battery);
608err_wall: 619err_wall:
609 power_supply_unregister(wall); 620 power_supply_unregister(wall);
610err_kmalloc: 621err_kmalloc:
@@ -628,7 +639,8 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev)
628 irq = platform_get_irq_byname(pdev, "SYSLO"); 639 irq = platform_get_irq_byname(pdev, "SYSLO");
629 free_irq(irq, wm831x_power); 640 free_irq(irq, wm831x_power);
630 641
631 power_supply_unregister(&wm831x_power->battery); 642 if (wm831x_power->have_battery)
643 power_supply_unregister(&wm831x_power->battery);
632 power_supply_unregister(&wm831x_power->wall); 644 power_supply_unregister(&wm831x_power->wall);
633 power_supply_unregister(&wm831x_power->usb); 645 power_supply_unregister(&wm831x_power->usb);
634 kfree(wm831x_power); 646 kfree(wm831x_power);
@@ -643,17 +655,7 @@ static struct platform_driver wm831x_power_driver = {
643 }, 655 },
644}; 656};
645 657
646static int __init wm831x_power_init(void) 658module_platform_driver(wm831x_power_driver);
647{
648 return platform_driver_register(&wm831x_power_driver);
649}
650module_init(wm831x_power_init);
651
652static void __exit wm831x_power_exit(void)
653{
654 platform_driver_unregister(&wm831x_power_driver);
655}
656module_exit(wm831x_power_exit);
657 659
658MODULE_DESCRIPTION("Power supply driver for WM831x PMICs"); 660MODULE_DESCRIPTION("Power supply driver for WM831x PMICs");
659MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 661MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c
index 0693902d6151..fae04d384657 100644
--- a/drivers/power/wm8350_power.c
+++ b/drivers/power/wm8350_power.c
@@ -522,17 +522,7 @@ static struct platform_driver wm8350_power_driver = {
522 }, 522 },
523}; 523};
524 524
525static int __init wm8350_power_init(void) 525module_platform_driver(wm8350_power_driver);
526{
527 return platform_driver_register(&wm8350_power_driver);
528}
529module_init(wm8350_power_init);
530
531static void __exit wm8350_power_exit(void)
532{
533 platform_driver_unregister(&wm8350_power_driver);
534}
535module_exit(wm8350_power_exit);
536 526
537MODULE_LICENSE("GPL"); 527MODULE_LICENSE("GPL");
538MODULE_DESCRIPTION("Power supply driver for WM8350"); 528MODULE_DESCRIPTION("Power supply driver for WM8350");
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
index 156559e56fa5..d2d4c08c681c 100644
--- a/drivers/power/wm97xx_battery.c
+++ b/drivers/power/wm97xx_battery.c
@@ -25,9 +25,8 @@
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27 27
28static DEFINE_MUTEX(bat_lock);
29static struct work_struct bat_work; 28static struct work_struct bat_work;
30static struct mutex work_lock; 29static DEFINE_MUTEX(work_lock);
31static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN; 30static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
32static enum power_supply_property *prop; 31static enum power_supply_property *prop;
33 32
@@ -181,8 +180,6 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev)
181 if (dev->id != -1) 180 if (dev->id != -1)
182 return -EINVAL; 181 return -EINVAL;
183 182
184 mutex_init(&work_lock);
185
186 if (!pdata) { 183 if (!pdata) {
187 dev_err(&dev->dev, "No platform_data supplied\n"); 184 dev_err(&dev->dev, "No platform_data supplied\n");
188 return -EINVAL; 185 return -EINVAL;
@@ -196,7 +193,7 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev)
196 if (ret) 193 if (ret)
197 goto err2; 194 goto err2;
198 ret = request_irq(gpio_to_irq(pdata->charge_gpio), 195 ret = request_irq(gpio_to_irq(pdata->charge_gpio),
199 wm97xx_chrg_irq, IRQF_DISABLED, 196 wm97xx_chrg_irq, 0,
200 "AC Detect", dev); 197 "AC Detect", dev);
201 if (ret) 198 if (ret)
202 goto err2; 199 goto err2;
@@ -291,18 +288,7 @@ static struct platform_driver wm97xx_bat_driver = {
291 .remove = __devexit_p(wm97xx_bat_remove), 288 .remove = __devexit_p(wm97xx_bat_remove),
292}; 289};
293 290
294static int __init wm97xx_bat_init(void) 291module_platform_driver(wm97xx_bat_driver);
295{
296 return platform_driver_register(&wm97xx_bat_driver);
297}
298
299static void __exit wm97xx_bat_exit(void)
300{
301 platform_driver_unregister(&wm97xx_bat_driver);
302}
303
304module_init(wm97xx_bat_init);
305module_exit(wm97xx_bat_exit);
306 292
307MODULE_LICENSE("GPL"); 293MODULE_LICENSE("GPL");
308MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); 294MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c
index d119c38b3ff6..636ebb2a0e80 100644
--- a/drivers/power/z2_battery.c
+++ b/drivers/power/z2_battery.c
@@ -218,7 +218,7 @@ static int __devinit z2_batt_probe(struct i2c_client *client,
218 irq_set_irq_type(gpio_to_irq(info->charge_gpio), 218 irq_set_irq_type(gpio_to_irq(info->charge_gpio),
219 IRQ_TYPE_EDGE_BOTH); 219 IRQ_TYPE_EDGE_BOTH);
220 ret = request_irq(gpio_to_irq(info->charge_gpio), 220 ret = request_irq(gpio_to_irq(info->charge_gpio),
221 z2_charge_switch_irq, IRQF_DISABLED, 221 z2_charge_switch_irq, 0,
222 "AC Detect", charger); 222 "AC Detect", charger);
223 if (ret) 223 if (ret)
224 goto err3; 224 goto err3;
@@ -313,7 +313,7 @@ static struct i2c_driver z2_batt_driver = {
313 .pm = Z2_BATTERY_PM_OPS 313 .pm = Z2_BATTERY_PM_OPS
314 }, 314 },
315 .probe = z2_batt_probe, 315 .probe = z2_batt_probe,
316 .remove = z2_batt_remove, 316 .remove = __devexit_p(z2_batt_remove),
317 .id_table = z2_batt_id, 317 .id_table = z2_batt_id,
318}; 318};
319 319