diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-07-01 12:07:33 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-07-03 16:13:21 -0400 |
commit | af6e1d99ea525161f70f68ecb83d0d0f54f1bf62 (patch) | |
tree | 5d805e4e6da3f252bd9b4d8a958b25723970837f | |
parent | 963ce8ae6dbc7c8dffb1b117ba14673d40b22dda (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.c | 22 | ||||
-rw-r--r-- | drivers/input/misc/adxl34x-spi.c | 16 | ||||
-rw-r--r-- | drivers/input/misc/adxl34x.c | 76 | ||||
-rw-r--r-- | drivers/input/misc/adxl34x.h | 4 |
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 | ||
61 | static const struct adxl34x_bus_ops adx134x_smbus_bops = { | 61 | static 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 | ||
68 | static const struct adxl34x_bus_ops adx134x_i2c_bops = { | 68 | static 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 |
108 | static int adxl34x_suspend(struct i2c_client *client, pm_message_t message) | 108 | static 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 | ||
117 | static int adxl34x_resume(struct i2c_client *client) | 117 | static 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 | ||
130 | static const struct i2c_device_id adxl34x_id[] = { | 130 | static 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 |
97 | static int adxl34x_suspend(struct spi_device *spi, pm_message_t message) | 97 | static 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 | ||
106 | static int adxl34x_resume(struct spi_device *spi) | 106 | static 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 | ||
119 | static struct spi_driver adxl34x_driver = { | 119 | static 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 | ||
131 | static int __init adxl34x_spi_init(void) | 131 | static 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 | ||
400 | static void __adxl34x_disable(struct adxl34x *ac) | 401 | static 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 | ||
413 | static void __adxl34x_enable(struct adxl34x *ac) | 410 | static 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 | ||
421 | void adxl34x_disable(struct adxl34x *ac) | 415 | void 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 | } |
427 | EXPORT_SYMBOL_GPL(adxl34x_disable); | 426 | EXPORT_SYMBOL_GPL(adxl34x_suspend); |
428 | 427 | ||
429 | void adxl34x_enable(struct adxl34x *ac) | 428 | void 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 | ||
436 | EXPORT_SYMBOL_GPL(adxl34x_enable); | 440 | EXPORT_SYMBOL_GPL(adxl34x_resume); |
437 | 441 | ||
438 | static ssize_t adxl34x_disable_show(struct device *dev, | 442 | static 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 | ||
879 | int adxl34x_remove(struct adxl34x *ac) | 902 | int 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 | ||
23 | void adxl34x_disable(struct adxl34x *ac); | 23 | void adxl34x_suspend(struct adxl34x *ac); |
24 | void adxl34x_enable(struct adxl34x *ac); | 24 | void adxl34x_resume(struct adxl34x *ac); |
25 | struct adxl34x *adxl34x_probe(struct device *dev, int irq, | 25 | struct 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); |