Commit 47ec6e5a authored by Sylvain Rochet's avatar Sylvain Rochet Committed by Dmitry Torokhov

Input: rotary_encoder - add wake up support

This patch adds wake up support to GPIO rotary encoders.
Signed-off-by: default avatarSylvain Rochet <sylvain.rochet@finsecur.com>
Reviewed-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 027c71bb
...@@ -15,6 +15,7 @@ Optional properties: ...@@ -15,6 +15,7 @@ Optional properties:
- rotary-encoder,rollover: Automatic rollove when the rotary value becomes - rotary-encoder,rollover: Automatic rollove when the rotary value becomes
greater than the specified steps or smaller than 0. For absolute axis only. greater than the specified steps or smaller than 0. For absolute axis only.
- rotary-encoder,half-period: Makes the driver work on half-period mode. - rotary-encoder,half-period: Makes the driver work on half-period mode.
- wakeup-source: Boolean, rotary encoder can wake up the system.
See Documentation/input/rotary-encoder.txt for more information. See Documentation/input/rotary-encoder.txt for more information.
......
...@@ -109,6 +109,7 @@ static struct rotary_encoder_platform_data my_rotary_encoder_info = { ...@@ -109,6 +109,7 @@ static struct rotary_encoder_platform_data my_rotary_encoder_info = {
.inverted_a = 0, .inverted_a = 0,
.inverted_b = 0, .inverted_b = 0,
.half_period = false, .half_period = false,
.wakeup_source = false,
}; };
static struct platform_device rotary_encoder_device = { static struct platform_device rotary_encoder_device = {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/pm.h>
#define DRV_NAME "rotary-encoder" #define DRV_NAME "rotary-encoder"
...@@ -180,6 +181,8 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic ...@@ -180,6 +181,8 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
"rotary-encoder,rollover", NULL); "rotary-encoder,rollover", NULL);
pdata->half_period = !!of_get_property(np, pdata->half_period = !!of_get_property(np,
"rotary-encoder,half-period", NULL); "rotary-encoder,half-period", NULL);
pdata->wakeup_source = !!of_get_property(np,
"wakeup-source", NULL);
return pdata; return pdata;
} }
...@@ -280,6 +283,8 @@ static int rotary_encoder_probe(struct platform_device *pdev) ...@@ -280,6 +283,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
goto exit_free_irq_b; goto exit_free_irq_b;
} }
device_init_wakeup(&pdev->dev, pdata->wakeup_source);
platform_set_drvdata(pdev, encoder); platform_set_drvdata(pdev, encoder);
return 0; return 0;
...@@ -306,6 +311,8 @@ static int rotary_encoder_remove(struct platform_device *pdev) ...@@ -306,6 +311,8 @@ static int rotary_encoder_remove(struct platform_device *pdev)
struct rotary_encoder *encoder = platform_get_drvdata(pdev); struct rotary_encoder *encoder = platform_get_drvdata(pdev);
const struct rotary_encoder_platform_data *pdata = encoder->pdata; const struct rotary_encoder_platform_data *pdata = encoder->pdata;
device_init_wakeup(&pdev->dev, false);
free_irq(encoder->irq_a, encoder); free_irq(encoder->irq_a, encoder);
free_irq(encoder->irq_b, encoder); free_irq(encoder->irq_b, encoder);
gpio_free(pdata->gpio_a); gpio_free(pdata->gpio_a);
...@@ -320,11 +327,41 @@ static int rotary_encoder_remove(struct platform_device *pdev) ...@@ -320,11 +327,41 @@ static int rotary_encoder_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int rotary_encoder_suspend(struct device *dev)
{
struct rotary_encoder *encoder = dev_get_drvdata(dev);
if (device_may_wakeup(dev)) {
enable_irq_wake(encoder->irq_a);
enable_irq_wake(encoder->irq_b);
}
return 0;
}
static int rotary_encoder_resume(struct device *dev)
{
struct rotary_encoder *encoder = dev_get_drvdata(dev);
if (device_may_wakeup(dev)) {
disable_irq_wake(encoder->irq_a);
disable_irq_wake(encoder->irq_b);
}
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(rotary_encoder_pm_ops,
rotary_encoder_suspend, rotary_encoder_resume);
static struct platform_driver rotary_encoder_driver = { static struct platform_driver rotary_encoder_driver = {
.probe = rotary_encoder_probe, .probe = rotary_encoder_probe,
.remove = rotary_encoder_remove, .remove = rotary_encoder_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.pm = &rotary_encoder_pm_ops,
.of_match_table = of_match_ptr(rotary_encoder_of_match), .of_match_table = of_match_ptr(rotary_encoder_of_match),
} }
}; };
......
...@@ -11,6 +11,7 @@ struct rotary_encoder_platform_data { ...@@ -11,6 +11,7 @@ struct rotary_encoder_platform_data {
bool relative_axis; bool relative_axis;
bool rollover; bool rollover;
bool half_period; bool half_period;
bool wakeup_source;
}; };
#endif /* __ROTARY_ENCODER_H__ */ #endif /* __ROTARY_ENCODER_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment