aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/input/misc/adxl34x-i2c.c22
-rw-r--r--drivers/input/misc/adxl34x-spi.c16
-rw-r--r--drivers/input/misc/adxl34x.c76
-rw-r--r--drivers/input/misc/adxl34x.h4
4 files changed, 70 insertions, 48 deletions
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
index 76194b58bd0..0779724af7e 100644
--- a/drivers/input/misc/adxl34x-i2c.c
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -58,14 +58,14 @@ static int adxl34x_i2c_read_block(struct device *dev,
58 return 0; 58 return 0;
59} 59}
60 60
61static const struct adxl34x_bus_ops adx134x_smbus_bops = { 61static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
62 .bustype = BUS_I2C, 62 .bustype = BUS_I2C,
63 .write = adxl34x_smbus_write, 63 .write = adxl34x_smbus_write,
64 .read = adxl34x_smbus_read, 64 .read = adxl34x_smbus_read,
65 .read_block = adxl34x_smbus_read_block, 65 .read_block = adxl34x_smbus_read_block,
66}; 66};
67 67
68static const struct adxl34x_bus_ops adx134x_i2c_bops = { 68static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
69 .bustype = BUS_I2C, 69 .bustype = BUS_I2C,
70 .write = adxl34x_smbus_write, 70 .write = adxl34x_smbus_write,
71 .read = adxl34x_smbus_read, 71 .read = adxl34x_smbus_read,
@@ -88,7 +88,7 @@ static int __devinit adxl34x_i2c_probe(struct i2c_client *client,
88 ac = adxl34x_probe(&client->dev, client->irq, false, 88 ac = adxl34x_probe(&client->dev, client->irq, false,
89 i2c_check_functionality(client->adapter, 89 i2c_check_functionality(client->adapter,
90 I2C_FUNC_SMBUS_READ_I2C_BLOCK) ? 90 I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
91 &adx134x_smbus_bops : &adx134x_i2c_bops); 91 &adxl34x_smbus_bops : &adxl34x_i2c_bops);
92 if (IS_ERR(ac)) 92 if (IS_ERR(ac))
93 return PTR_ERR(ac); 93 return PTR_ERR(ac);
94 94
@@ -105,26 +105,26 @@ static int __devexit adxl34x_i2c_remove(struct i2c_client *client)
105} 105}
106 106
107#ifdef CONFIG_PM 107#ifdef CONFIG_PM
108static int adxl34x_suspend(struct i2c_client *client, pm_message_t message) 108static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message)
109{ 109{
110 struct adxl34x *ac = i2c_get_clientdata(client); 110 struct adxl34x *ac = i2c_get_clientdata(client);
111 111
112 adxl34x_disable(ac); 112 adxl34x_suspend(ac);
113 113
114 return 0; 114 return 0;
115} 115}
116 116
117static int adxl34x_resume(struct i2c_client *client) 117static int adxl34x_i2c_resume(struct i2c_client *client)
118{ 118{
119 struct adxl34x *ac = i2c_get_clientdata(client); 119 struct adxl34x *ac = i2c_get_clientdata(client);
120 120
121 adxl34x_enable(ac); 121 adxl34x_resume(ac);
122 122
123 return 0; 123 return 0;
124} 124}
125#else 125#else
126# define adxl34x_suspend NULL 126# define adxl34x_i2c_suspend NULL
127# define adxl34x_resume NULL 127# define adxl34x_i2c_resume NULL
128#endif 128#endif
129 129
130static const struct i2c_device_id adxl34x_id[] = { 130static const struct i2c_device_id adxl34x_id[] = {
@@ -141,8 +141,8 @@ static struct i2c_driver adxl34x_driver = {
141 }, 141 },
142 .probe = adxl34x_i2c_probe, 142 .probe = adxl34x_i2c_probe,
143 .remove = __devexit_p(adxl34x_i2c_remove), 143 .remove = __devexit_p(adxl34x_i2c_remove),
144 .suspend = adxl34x_suspend, 144 .suspend = adxl34x_i2c_suspend,
145 .resume = adxl34x_resume, 145 .resume = adxl34x_i2c_resume,
146 .id_table = adxl34x_id, 146 .id_table = adxl34x_id,
147}; 147};
148 148
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c
index 7f992353ffd..782de9e8982 100644
--- a/drivers/input/misc/adxl34x-spi.c
+++ b/drivers/input/misc/adxl34x-spi.c
@@ -94,26 +94,26 @@ static int __devexit adxl34x_spi_remove(struct spi_device *spi)
94} 94}
95 95
96#ifdef CONFIG_PM 96#ifdef CONFIG_PM
97static int adxl34x_suspend(struct spi_device *spi, pm_message_t message) 97static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message)
98{ 98{
99 struct adxl34x *ac = dev_get_drvdata(&spi->dev); 99 struct adxl34x *ac = dev_get_drvdata(&spi->dev);
100 100
101 adxl34x_disable(ac); 101 adxl34x_suspend(ac);
102 102
103 return 0; 103 return 0;
104} 104}
105 105
106static int adxl34x_resume(struct spi_device *spi) 106static int adxl34x_spi_resume(struct spi_device *spi)
107{ 107{
108 struct adxl34x *ac = dev_get_drvdata(&spi->dev); 108 struct adxl34x *ac = dev_get_drvdata(&spi->dev);
109 109
110 adxl34x_enable(ac); 110 adxl34x_resume(ac);
111 111
112 return 0; 112 return 0;
113} 113}
114#else 114#else
115# define adxl34x_suspend NULL 115# define adxl34x_spi_suspend NULL
116# define adxl34x_resume NULL 116# define adxl34x_spi_resume NULL
117#endif 117#endif
118 118
119static struct spi_driver adxl34x_driver = { 119static struct spi_driver adxl34x_driver = {
@@ -124,8 +124,8 @@ static struct spi_driver adxl34x_driver = {
124 }, 124 },
125 .probe = adxl34x_spi_probe, 125 .probe = adxl34x_spi_probe,
126 .remove = __devexit_p(adxl34x_spi_remove), 126 .remove = __devexit_p(adxl34x_spi_remove),
127 .suspend = adxl34x_suspend, 127 .suspend = adxl34x_spi_suspend,
128 .resume = adxl34x_resume, 128 .resume = adxl34x_spi_resume,
129}; 129};
130 130
131static int __init adxl34x_spi_init(void) 131static int __init adxl34x_spi_init(void)
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
index 77fb4098705..bb9c10f9dfd 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);
diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h
index ea9093c15c8..bbbc80fda16 100644
--- a/drivers/input/misc/adxl34x.h
+++ b/drivers/input/misc/adxl34x.h
@@ -20,8 +20,8 @@ struct adxl34x_bus_ops {
20 int (*write)(struct device *, unsigned char, unsigned char); 20 int (*write)(struct device *, unsigned char, unsigned char);
21}; 21};
22 22
23void adxl34x_disable(struct adxl34x *ac); 23void adxl34x_suspend(struct adxl34x *ac);
24void adxl34x_enable(struct adxl34x *ac); 24void adxl34x_resume(struct adxl34x *ac);
25struct adxl34x *adxl34x_probe(struct device *dev, int irq, 25struct adxl34x *adxl34x_probe(struct device *dev, int irq,
26 bool fifo_delay_default, 26 bool fifo_delay_default,
27 const struct adxl34x_bus_ops *bops); 27 const struct adxl34x_bus_ops *bops);