diff options
author | Daniel Mack <daniel@caiaq.de> | 2009-04-28 04:55:02 -0400 |
---|---|---|
committer | Anton Vorontsov <cbouatmailru@gmail.com> | 2009-06-08 15:25:17 -0400 |
commit | cef437e3a9b6d229d4ed3730cde047007267df6d (patch) | |
tree | 6a01e75b651988c82d231bc4f6bedb49ea12173a | |
parent | 0b47b5703b1cc6c3aa89663ac70e28dadedf6ccc (diff) |
w1: ds2760_battery: add support for sleep mode feature
This adds support for ds2760's sleep mode feature. With this feature
enabled, the chip enters a deep sleep mode and disconnects from the
battery when the w1 line is held down for more than 2 seconds.
This new behaviour can be switched on and off using a new module
parameter.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
Acked-by: Matt Reimer <mreimer@vpop.net>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
-rw-r--r-- | drivers/power/ds2760_battery.c | 26 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2760.h | 5 |
2 files changed, 31 insertions, 0 deletions
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index 9331009090f1..520b5c49ff30 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c | |||
@@ -62,6 +62,10 @@ static unsigned int cache_time = 1000; | |||
62 | module_param(cache_time, uint, 0644); | 62 | module_param(cache_time, uint, 0644); |
63 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 63 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
64 | 64 | ||
65 | static unsigned int pmod_enabled; | ||
66 | module_param(pmod_enabled, bool, 0644); | ||
67 | MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit"); | ||
68 | |||
65 | /* Some batteries have their rated capacity stored a N * 10 mAh, while | 69 | /* Some batteries have their rated capacity stored a N * 10 mAh, while |
66 | * others use an index into this table. */ | 70 | * others use an index into this table. */ |
67 | static int rated_capacities[] = { | 71 | static int rated_capacities[] = { |
@@ -259,6 +263,17 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di) | |||
259 | power_supply_changed(&di->bat); | 263 | power_supply_changed(&di->bat); |
260 | } | 264 | } |
261 | 265 | ||
266 | static void ds2760_battery_write_status(struct ds2760_device_info *di, | ||
267 | char status) | ||
268 | { | ||
269 | if (status == di->raw[DS2760_STATUS_REG]) | ||
270 | return; | ||
271 | |||
272 | w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1); | ||
273 | w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); | ||
274 | w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); | ||
275 | } | ||
276 | |||
262 | static void ds2760_battery_work(struct work_struct *work) | 277 | static void ds2760_battery_work(struct work_struct *work) |
263 | { | 278 | { |
264 | struct ds2760_device_info *di = container_of(work, | 279 | struct ds2760_device_info *di = container_of(work, |
@@ -342,6 +357,7 @@ static enum power_supply_property ds2760_battery_props[] = { | |||
342 | 357 | ||
343 | static int ds2760_battery_probe(struct platform_device *pdev) | 358 | static int ds2760_battery_probe(struct platform_device *pdev) |
344 | { | 359 | { |
360 | char status; | ||
345 | int retval = 0; | 361 | int retval = 0; |
346 | struct ds2760_device_info *di; | 362 | struct ds2760_device_info *di; |
347 | 363 | ||
@@ -371,6 +387,16 @@ static int ds2760_battery_probe(struct platform_device *pdev) | |||
371 | goto batt_failed; | 387 | goto batt_failed; |
372 | } | 388 | } |
373 | 389 | ||
390 | /* enable sleep mode feature */ | ||
391 | ds2760_battery_read_status(di); | ||
392 | status = di->raw[DS2760_STATUS_REG]; | ||
393 | if (pmod_enabled) | ||
394 | status |= DS2760_STATUS_PMOD; | ||
395 | else | ||
396 | status &= ~DS2760_STATUS_PMOD; | ||
397 | |||
398 | ds2760_battery_write_status(di, status); | ||
399 | |||
374 | INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); | 400 | INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); |
375 | di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); | 401 | di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); |
376 | if (!di->monitor_wqueue) { | 402 | if (!di->monitor_wqueue) { |
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h index ea39419172a6..58e774141568 100644 --- a/drivers/w1/slaves/w1_ds2760.h +++ b/drivers/w1/slaves/w1_ds2760.h | |||
@@ -25,6 +25,10 @@ | |||
25 | 25 | ||
26 | #define DS2760_PROTECTION_REG 0x00 | 26 | #define DS2760_PROTECTION_REG 0x00 |
27 | #define DS2760_STATUS_REG 0x01 | 27 | #define DS2760_STATUS_REG 0x01 |
28 | #define DS2760_STATUS_IE (1 << 2) | ||
29 | #define DS2760_STATUS_SWEN (1 << 3) | ||
30 | #define DS2760_STATUS_RNAOP (1 << 4) | ||
31 | #define DS2760_STATUS_PMOD (1 << 5) | ||
28 | #define DS2760_EEPROM_REG 0x07 | 32 | #define DS2760_EEPROM_REG 0x07 |
29 | #define DS2760_SPECIAL_FEATURE_REG 0x08 | 33 | #define DS2760_SPECIAL_FEATURE_REG 0x08 |
30 | #define DS2760_VOLTAGE_MSB 0x0c | 34 | #define DS2760_VOLTAGE_MSB 0x0c |
@@ -38,6 +42,7 @@ | |||
38 | #define DS2760_EEPROM_BLOCK0 0x20 | 42 | #define DS2760_EEPROM_BLOCK0 0x20 |
39 | #define DS2760_ACTIVE_FULL 0x20 | 43 | #define DS2760_ACTIVE_FULL 0x20 |
40 | #define DS2760_EEPROM_BLOCK1 0x30 | 44 | #define DS2760_EEPROM_BLOCK1 0x30 |
45 | #define DS2760_STATUS_WRITE_REG 0x31 | ||
41 | #define DS2760_RATED_CAPACITY 0x32 | 46 | #define DS2760_RATED_CAPACITY 0x32 |
42 | #define DS2760_CURRENT_OFFSET_BIAS 0x33 | 47 | #define DS2760_CURRENT_OFFSET_BIAS 0x33 |
43 | #define DS2760_ACTIVE_EMPTY 0x3b | 48 | #define DS2760_ACTIVE_EMPTY 0x3b |