root/drivers/input/misc/cpcap-pwrbutton.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. powerbutton_irq
  2. cpcap_power_button_probe

   1 /**
   2  * CPCAP Power Button Input Driver
   3  *
   4  * Copyright (C) 2017 Sebastian Reichel <sre@kernel.org>
   5  *
   6  * This file is subject to the terms and conditions of the GNU General
   7  * Public License. See the file "COPYING" in the main directory of this
   8  * archive for more details.
   9  *
  10  * This program is distributed in the hope that it will be useful,
  11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  * GNU General Public License for more details.
  14  */
  15 
  16 #include <linux/module.h>
  17 #include <linux/init.h>
  18 #include <linux/kernel.h>
  19 #include <linux/errno.h>
  20 #include <linux/input.h>
  21 #include <linux/interrupt.h>
  22 #include <linux/regmap.h>
  23 #include <linux/of.h>
  24 #include <linux/platform_device.h>
  25 #include <linux/mfd/motorola-cpcap.h>
  26 
  27 #define CPCAP_IRQ_ON 23
  28 #define CPCAP_IRQ_ON_BITMASK (1 << (CPCAP_IRQ_ON % 16))
  29 
  30 struct cpcap_power_button {
  31         struct regmap *regmap;
  32         struct input_dev *idev;
  33         struct device *dev;
  34 };
  35 
  36 static irqreturn_t powerbutton_irq(int irq, void *_button)
  37 {
  38         struct cpcap_power_button *button = _button;
  39         int val;
  40 
  41         val = cpcap_sense_virq(button->regmap, irq);
  42         if (val < 0) {
  43                 dev_err(button->dev, "irq read failed: %d", val);
  44                 return IRQ_HANDLED;
  45         }
  46 
  47         pm_wakeup_event(button->dev, 0);
  48         input_report_key(button->idev, KEY_POWER, val);
  49         input_sync(button->idev);
  50 
  51         return IRQ_HANDLED;
  52 }
  53 
  54 static int cpcap_power_button_probe(struct platform_device *pdev)
  55 {
  56         struct cpcap_power_button *button;
  57         int irq = platform_get_irq(pdev, 0);
  58         int err;
  59 
  60         button = devm_kmalloc(&pdev->dev, sizeof(*button), GFP_KERNEL);
  61         if (!button)
  62                 return -ENOMEM;
  63 
  64         button->idev = devm_input_allocate_device(&pdev->dev);
  65         if (!button->idev)
  66                 return -ENOMEM;
  67 
  68         button->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  69         if (!button->regmap)
  70                 return -ENODEV;
  71 
  72         button->dev = &pdev->dev;
  73 
  74         button->idev->name = "cpcap-pwrbutton";
  75         button->idev->phys = "cpcap-pwrbutton/input0";
  76         button->idev->dev.parent = button->dev;
  77         input_set_capability(button->idev, EV_KEY, KEY_POWER);
  78 
  79         err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
  80                 powerbutton_irq, IRQF_ONESHOT, "cpcap_pwrbutton", button);
  81         if (err < 0) {
  82                 dev_err(&pdev->dev, "IRQ request failed: %d\n", err);
  83                 return err;
  84         }
  85 
  86         err = input_register_device(button->idev);
  87         if (err) {
  88                 dev_err(&pdev->dev, "Input register failed: %d\n", err);
  89                 return err;
  90         }
  91 
  92         device_init_wakeup(&pdev->dev, true);
  93 
  94         return 0;
  95 }
  96 
  97 #ifdef CONFIG_OF
  98 static const struct of_device_id cpcap_pwrbutton_dt_match_table[] = {
  99         { .compatible = "motorola,cpcap-pwrbutton" },
 100         {},
 101 };
 102 MODULE_DEVICE_TABLE(of, cpcap_pwrbutton_dt_match_table);
 103 #endif
 104 
 105 static struct platform_driver cpcap_power_button_driver = {
 106         .probe          = cpcap_power_button_probe,
 107         .driver         = {
 108                 .name   = "cpcap-pwrbutton",
 109                 .of_match_table = of_match_ptr(cpcap_pwrbutton_dt_match_table),
 110         },
 111 };
 112 module_platform_driver(cpcap_power_button_driver);
 113 
 114 MODULE_ALIAS("platform:cpcap-pwrbutton");
 115 MODULE_DESCRIPTION("CPCAP Power Button");
 116 MODULE_LICENSE("GPL");
 117 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");

/* [<][>][^][v][top][bottom][index][help] */