aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/adxl34x.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-07-01 12:07:33 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-07-03 16:13:21 -0400
commitaf6e1d99ea525161f70f68ecb83d0d0f54f1bf62 (patch)
tree5d805e4e6da3f252bd9b4d8a958b25723970837f /drivers/input/misc/adxl34x.c
parent963ce8ae6dbc7c8dffb1b117ba14673d40b22dda (diff)
Input: adxl34 - make enable/disable separate from suspend/resume
Suspending and resuming the device should be separate from enabling and disabling it through sysfs attribute and thus should not alter ac->disabled flag. [michael.hennerich@analog.com: various fixups] Tested-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/misc/adxl34x.c')
-rw-r--r--drivers/input/misc/adxl34x.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
index 77fb40987059..bb9c10f9dfd3 100644
--- a/drivers/input/misc/adxl34x.c
+++ b/drivers/input/misc/adxl34x.c
@@ -200,6 +200,7 @@ struct adxl34x {
200 unsigned orient3d_saved; 200 unsigned orient3d_saved;
201 bool disabled; /* P: mutex */ 201 bool disabled; /* P: mutex */
202 bool opened; /* P: mutex */ 202 bool opened; /* P: mutex */
203 bool suspended; /* P: mutex */
203 bool fifo_delay; 204 bool fifo_delay;
204 int irq; 205 int irq;
205 unsigned model; 206 unsigned model;
@@ -399,41 +400,44 @@ static irqreturn_t adxl34x_irq(int irq, void *handle)
399 400
400static void __adxl34x_disable(struct adxl34x *ac) 401static void __adxl34x_disable(struct adxl34x *ac)
401{ 402{
402 if (!ac->disabled && ac->opened) { 403 /*
403 /* 404 * A '0' places the ADXL34x into standby mode
404 * A '0' places the ADXL34x into standby mode 405 * with minimum power consumption.
405 * with minimum power consumption. 406 */
406 */ 407 AC_WRITE(ac, POWER_CTL, 0);
407 AC_WRITE(ac, POWER_CTL, 0);
408
409 ac->disabled = true;
410 }
411} 408}
412 409
413static void __adxl34x_enable(struct adxl34x *ac) 410static void __adxl34x_enable(struct adxl34x *ac)
414{ 411{
415 if (ac->disabled && ac->opened) { 412 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
416 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
417 ac->disabled = false;
418 }
419} 413}
420 414
421void adxl34x_disable(struct adxl34x *ac) 415void adxl34x_suspend(struct adxl34x *ac)
422{ 416{
423 mutex_lock(&ac->mutex); 417 mutex_lock(&ac->mutex);
424 __adxl34x_disable(ac); 418
419 if (!ac->suspended && !ac->disabled && ac->opened)
420 __adxl34x_disable(ac);
421
422 ac->suspended = true;
423
425 mutex_unlock(&ac->mutex); 424 mutex_unlock(&ac->mutex);
426} 425}
427EXPORT_SYMBOL_GPL(adxl34x_disable); 426EXPORT_SYMBOL_GPL(adxl34x_suspend);
428 427
429void adxl34x_enable(struct adxl34x *ac) 428void adxl34x_resume(struct adxl34x *ac)
430{ 429{
431 mutex_lock(&ac->mutex); 430 mutex_lock(&ac->mutex);
432 __adxl34x_enable(ac); 431
432 if (ac->suspended && !ac->disabled && ac->opened)
433 __adxl34x_enable(ac);
434
435 ac->suspended= false;
436
433 mutex_unlock(&ac->mutex); 437 mutex_unlock(&ac->mutex);
434} 438}
435 439
436EXPORT_SYMBOL_GPL(adxl34x_enable); 440EXPORT_SYMBOL_GPL(adxl34x_resume);
437 441
438static ssize_t adxl34x_disable_show(struct device *dev, 442static ssize_t adxl34x_disable_show(struct device *dev,
439 struct device_attribute *attr, char *buf) 443 struct device_attribute *attr, char *buf)
@@ -455,10 +459,21 @@ static ssize_t adxl34x_disable_store(struct device *dev,
455 if (error) 459 if (error)
456 return error; 460 return error;
457 461
458 if (val) 462 mutex_lock(&ac->mutex);
459 adxl34x_disable(ac); 463
460 else 464 if (!ac->suspended && ac->opened) {
461 adxl34x_enable(ac); 465 if (val) {
466 if (!ac->disabled)
467 __adxl34x_disable(ac);
468 } else {
469 if (ac->disabled)
470 __adxl34x_enable(ac);
471 }
472 }
473
474 ac->disabled = !!val;
475
476 mutex_unlock(&ac->mutex);
462 477
463 return count; 478 return count;
464} 479}
@@ -575,7 +590,7 @@ static ssize_t adxl34x_autosleep_store(struct device *dev,
575 else 590 else
576 ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK); 591 ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK);
577 592
578 if (!ac->disabled && ac->opened) 593 if (!ac->disabled && !ac->suspended && ac->opened)
579 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); 594 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
580 595
581 mutex_unlock(&ac->mutex); 596 mutex_unlock(&ac->mutex);
@@ -649,8 +664,12 @@ static int adxl34x_input_open(struct input_dev *input)
649 struct adxl34x *ac = input_get_drvdata(input); 664 struct adxl34x *ac = input_get_drvdata(input);
650 665
651 mutex_lock(&ac->mutex); 666 mutex_lock(&ac->mutex);
667
668 if (!ac->suspended && !ac->disabled)
669 __adxl34x_enable(ac);
670
652 ac->opened = true; 671 ac->opened = true;
653 __adxl34x_enable(ac); 672
654 mutex_unlock(&ac->mutex); 673 mutex_unlock(&ac->mutex);
655 674
656 return 0; 675 return 0;
@@ -661,8 +680,12 @@ static void adxl34x_input_close(struct input_dev *input)
661 struct adxl34x *ac = input_get_drvdata(input); 680 struct adxl34x *ac = input_get_drvdata(input);
662 681
663 mutex_lock(&ac->mutex); 682 mutex_lock(&ac->mutex);
664 __adxl34x_disable(ac); 683
684 if (!ac->suspended && !ac->disabled)
685 __adxl34x_disable(ac);
686
665 ac->opened = false; 687 ac->opened = false;
688
666 mutex_unlock(&ac->mutex); 689 mutex_unlock(&ac->mutex);
667} 690}
668 691
@@ -878,7 +901,6 @@ EXPORT_SYMBOL_GPL(adxl34x_probe);
878 901
879int adxl34x_remove(struct adxl34x *ac) 902int adxl34x_remove(struct adxl34x *ac)
880{ 903{
881 adxl34x_disable(ac);
882 sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group); 904 sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
883 free_irq(ac->irq, ac); 905 free_irq(ac->irq, ac);
884 input_unregister_device(ac->input); 906 input_unregister_device(ac->input);