Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2014, National Instruments Corp. All rights reserved.
0004  *
0005  * Driver for NI Ettus Research USRP E3x0 Button Driver
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/input.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/of.h>
0015 #include <linux/slab.h>
0016 
0017 static irqreturn_t e3x0_button_release_handler(int irq, void *data)
0018 {
0019     struct input_dev *idev = data;
0020 
0021     input_report_key(idev, KEY_POWER, 0);
0022     input_sync(idev);
0023 
0024     return IRQ_HANDLED;
0025 }
0026 
0027 static irqreturn_t e3x0_button_press_handler(int irq, void *data)
0028 {
0029     struct input_dev *idev = data;
0030 
0031     input_report_key(idev, KEY_POWER, 1);
0032     pm_wakeup_event(idev->dev.parent, 0);
0033     input_sync(idev);
0034 
0035     return IRQ_HANDLED;
0036 }
0037 
0038 static int __maybe_unused e3x0_button_suspend(struct device *dev)
0039 {
0040     struct platform_device *pdev = to_platform_device(dev);
0041 
0042     if (device_may_wakeup(dev))
0043         enable_irq_wake(platform_get_irq_byname(pdev, "press"));
0044 
0045     return 0;
0046 }
0047 
0048 static int __maybe_unused e3x0_button_resume(struct device *dev)
0049 {
0050     struct platform_device *pdev = to_platform_device(dev);
0051 
0052     if (device_may_wakeup(dev))
0053         disable_irq_wake(platform_get_irq_byname(pdev, "press"));
0054 
0055     return 0;
0056 }
0057 
0058 static SIMPLE_DEV_PM_OPS(e3x0_button_pm_ops,
0059              e3x0_button_suspend, e3x0_button_resume);
0060 
0061 static int e3x0_button_probe(struct platform_device *pdev)
0062 {
0063     struct input_dev *input;
0064     int irq_press, irq_release;
0065     int error;
0066 
0067     irq_press = platform_get_irq_byname(pdev, "press");
0068     if (irq_press < 0)
0069         return irq_press;
0070 
0071     irq_release = platform_get_irq_byname(pdev, "release");
0072     if (irq_release < 0)
0073         return irq_release;
0074 
0075     input = devm_input_allocate_device(&pdev->dev);
0076     if (!input)
0077         return -ENOMEM;
0078 
0079     input->name = "NI Ettus Research USRP E3x0 Button Driver";
0080     input->phys = "e3x0_button/input0";
0081     input->dev.parent = &pdev->dev;
0082 
0083     input_set_capability(input, EV_KEY, KEY_POWER);
0084 
0085     error = devm_request_irq(&pdev->dev, irq_press,
0086                  e3x0_button_press_handler, 0,
0087                  "e3x0-button", input);
0088     if (error) {
0089         dev_err(&pdev->dev, "Failed to request 'press' IRQ#%d: %d\n",
0090             irq_press, error);
0091         return error;
0092     }
0093 
0094     error = devm_request_irq(&pdev->dev, irq_release,
0095                  e3x0_button_release_handler, 0,
0096                  "e3x0-button", input);
0097     if (error) {
0098         dev_err(&pdev->dev, "Failed to request 'release' IRQ#%d: %d\n",
0099             irq_release, error);
0100         return error;
0101     }
0102 
0103     error = input_register_device(input);
0104     if (error) {
0105         dev_err(&pdev->dev, "Can't register input device: %d\n", error);
0106         return error;
0107     }
0108 
0109     device_init_wakeup(&pdev->dev, 1);
0110     return 0;
0111 }
0112 
0113 #ifdef CONFIG_OF
0114 static const struct of_device_id e3x0_button_match[] = {
0115     { .compatible = "ettus,e3x0-button", },
0116     { }
0117 };
0118 MODULE_DEVICE_TABLE(of, e3x0_button_match);
0119 #endif
0120 
0121 static struct platform_driver e3x0_button_driver = {
0122     .driver     = {
0123         .name   = "e3x0-button",
0124         .of_match_table = of_match_ptr(e3x0_button_match),
0125         .pm = &e3x0_button_pm_ops,
0126     },
0127     .probe      = e3x0_button_probe,
0128 };
0129 
0130 module_platform_driver(e3x0_button_driver);
0131 
0132 MODULE_LICENSE("GPL v2");
0133 MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
0134 MODULE_DESCRIPTION("NI Ettus Research USRP E3x0 Button driver");
0135 MODULE_ALIAS("platform:e3x0-button");