Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: rotary_encoder - add wake up support

This patch adds wake up support to GPIO rotary encoders.

Signed-off-by: Sylvain Rochet <sylvain.rochet@finsecur.com>
Reviewed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Sylvain Rochet and committed by
Dmitry Torokhov
47ec6e5a 027c71bb

+40
+1
Documentation/devicetree/bindings/input/rotary-encoder.txt
··· 15 15 - rotary-encoder,rollover: Automatic rollove when the rotary value becomes 16 16 greater than the specified steps or smaller than 0. For absolute axis only. 17 17 - rotary-encoder,half-period: Makes the driver work on half-period mode. 18 + - wakeup-source: Boolean, rotary encoder can wake up the system. 18 19 19 20 See Documentation/input/rotary-encoder.txt for more information. 20 21
+1
Documentation/input/rotary-encoder.txt
··· 109 109 .inverted_a = 0, 110 110 .inverted_b = 0, 111 111 .half_period = false, 112 + .wakeup_source = false, 112 113 }; 113 114 114 115 static struct platform_device rotary_encoder_device = {
+37
drivers/input/misc/rotary_encoder.c
··· 26 26 #include <linux/of.h> 27 27 #include <linux/of_platform.h> 28 28 #include <linux/of_gpio.h> 29 + #include <linux/pm.h> 29 30 30 31 #define DRV_NAME "rotary-encoder" 31 32 ··· 181 180 "rotary-encoder,rollover", NULL); 182 181 pdata->half_period = !!of_get_property(np, 183 182 "rotary-encoder,half-period", NULL); 183 + pdata->wakeup_source = !!of_get_property(np, 184 + "wakeup-source", NULL); 184 185 185 186 return pdata; 186 187 } ··· 283 280 goto exit_free_irq_b; 284 281 } 285 282 283 + device_init_wakeup(&pdev->dev, pdata->wakeup_source); 284 + 286 285 platform_set_drvdata(pdev, encoder); 287 286 288 287 return 0; ··· 311 306 struct rotary_encoder *encoder = platform_get_drvdata(pdev); 312 307 const struct rotary_encoder_platform_data *pdata = encoder->pdata; 313 308 309 + device_init_wakeup(&pdev->dev, false); 310 + 314 311 free_irq(encoder->irq_a, encoder); 315 312 free_irq(encoder->irq_b, encoder); 316 313 gpio_free(pdata->gpio_a); ··· 327 320 return 0; 328 321 } 329 322 323 + #ifdef CONFIG_PM_SLEEP 324 + static int rotary_encoder_suspend(struct device *dev) 325 + { 326 + struct rotary_encoder *encoder = dev_get_drvdata(dev); 327 + 328 + if (device_may_wakeup(dev)) { 329 + enable_irq_wake(encoder->irq_a); 330 + enable_irq_wake(encoder->irq_b); 331 + } 332 + 333 + return 0; 334 + } 335 + 336 + static int rotary_encoder_resume(struct device *dev) 337 + { 338 + struct rotary_encoder *encoder = dev_get_drvdata(dev); 339 + 340 + if (device_may_wakeup(dev)) { 341 + disable_irq_wake(encoder->irq_a); 342 + disable_irq_wake(encoder->irq_b); 343 + } 344 + 345 + return 0; 346 + } 347 + #endif 348 + 349 + static SIMPLE_DEV_PM_OPS(rotary_encoder_pm_ops, 350 + rotary_encoder_suspend, rotary_encoder_resume); 351 + 330 352 static struct platform_driver rotary_encoder_driver = { 331 353 .probe = rotary_encoder_probe, 332 354 .remove = rotary_encoder_remove, 333 355 .driver = { 334 356 .name = DRV_NAME, 357 + .pm = &rotary_encoder_pm_ops, 335 358 .of_match_table = of_match_ptr(rotary_encoder_of_match), 336 359 } 337 360 };
+1
include/linux/rotary_encoder.h
··· 11 11 bool relative_axis; 12 12 bool rollover; 13 13 bool half_period; 14 + bool wakeup_source; 14 15 }; 15 16 16 17 #endif /* __ROTARY_ENCODER_H__ */