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>

authored by Daniel Mack and committed by Anton Vorontsov cef437e3 0b47b570

+31
+26
drivers/power/ds2760_battery.c
··· 62 module_param(cache_time, uint, 0644); 63 MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 64 65 /* Some batteries have their rated capacity stored a N * 10 mAh, while 66 * others use an index into this table. */ 67 static int rated_capacities[] = { ··· 263 power_supply_changed(&di->bat); 264 } 265 266 static void ds2760_battery_work(struct work_struct *work) 267 { 268 struct ds2760_device_info *di = container_of(work, ··· 357 358 static int ds2760_battery_probe(struct platform_device *pdev) 359 { 360 int retval = 0; 361 struct ds2760_device_info *di; 362 ··· 386 dev_err(di->dev, "failed to register battery\n"); 387 goto batt_failed; 388 } 389 390 INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); 391 di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev));
··· 62 module_param(cache_time, uint, 0644); 63 MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 64 65 + static unsigned int pmod_enabled; 66 + module_param(pmod_enabled, bool, 0644); 67 + MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit"); 68 + 69 /* Some batteries have their rated capacity stored a N * 10 mAh, while 70 * others use an index into this table. */ 71 static int rated_capacities[] = { ··· 259 power_supply_changed(&di->bat); 260 } 261 262 + static void ds2760_battery_write_status(struct ds2760_device_info *di, 263 + char status) 264 + { 265 + if (status == di->raw[DS2760_STATUS_REG]) 266 + return; 267 + 268 + w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1); 269 + w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 270 + w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 271 + } 272 + 273 static void ds2760_battery_work(struct work_struct *work) 274 { 275 struct ds2760_device_info *di = container_of(work, ··· 342 343 static int ds2760_battery_probe(struct platform_device *pdev) 344 { 345 + char status; 346 int retval = 0; 347 struct ds2760_device_info *di; 348 ··· 370 dev_err(di->dev, "failed to register battery\n"); 371 goto batt_failed; 372 } 373 + 374 + /* enable sleep mode feature */ 375 + ds2760_battery_read_status(di); 376 + status = di->raw[DS2760_STATUS_REG]; 377 + if (pmod_enabled) 378 + status |= DS2760_STATUS_PMOD; 379 + else 380 + status &= ~DS2760_STATUS_PMOD; 381 + 382 + ds2760_battery_write_status(di, status); 383 384 INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); 385 di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev));
+5
drivers/w1/slaves/w1_ds2760.h
··· 25 26 #define DS2760_PROTECTION_REG 0x00 27 #define DS2760_STATUS_REG 0x01 28 #define DS2760_EEPROM_REG 0x07 29 #define DS2760_SPECIAL_FEATURE_REG 0x08 30 #define DS2760_VOLTAGE_MSB 0x0c ··· 42 #define DS2760_EEPROM_BLOCK0 0x20 43 #define DS2760_ACTIVE_FULL 0x20 44 #define DS2760_EEPROM_BLOCK1 0x30 45 #define DS2760_RATED_CAPACITY 0x32 46 #define DS2760_CURRENT_OFFSET_BIAS 0x33 47 #define DS2760_ACTIVE_EMPTY 0x3b
··· 25 26 #define DS2760_PROTECTION_REG 0x00 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) 32 #define DS2760_EEPROM_REG 0x07 33 #define DS2760_SPECIAL_FEATURE_REG 0x08 34 #define DS2760_VOLTAGE_MSB 0x0c ··· 38 #define DS2760_EEPROM_BLOCK0 0x20 39 #define DS2760_ACTIVE_FULL 0x20 40 #define DS2760_EEPROM_BLOCK1 0x30 41 + #define DS2760_STATUS_WRITE_REG 0x31 42 #define DS2760_RATED_CAPACITY 0x32 43 #define DS2760_CURRENT_OFFSET_BIAS 0x33 44 #define DS2760_ACTIVE_EMPTY 0x3b