root/drivers/input/misc/stpmic1_onkey.c

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

DEFINITIONS

This source file includes following definitions.
  1. onkey_falling_irq
  2. onkey_rising_irq
  3. stpmic1_onkey_probe
  4. stpmic1_onkey_suspend
  5. stpmic1_onkey_resume

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (C) STMicroelectronics 2018
   3 // Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
   4 
   5 #include <linux/input.h>
   6 #include <linux/interrupt.h>
   7 #include <linux/mfd/stpmic1.h>
   8 #include <linux/module.h>
   9 #include <linux/of.h>
  10 #include <linux/platform_device.h>
  11 #include <linux/property.h>
  12 #include <linux/regmap.h>
  13 
  14 /**
  15  * struct stpmic1_onkey - OnKey data
  16  * @input_dev:          pointer to input device
  17  * @irq_falling:        irq that we are hooked on to
  18  * @irq_rising:         irq that we are hooked on to
  19  */
  20 struct stpmic1_onkey {
  21         struct input_dev *input_dev;
  22         int irq_falling;
  23         int irq_rising;
  24 };
  25 
  26 static irqreturn_t onkey_falling_irq(int irq, void *ponkey)
  27 {
  28         struct stpmic1_onkey *onkey = ponkey;
  29         struct input_dev *input_dev = onkey->input_dev;
  30 
  31         input_report_key(input_dev, KEY_POWER, 1);
  32         pm_wakeup_event(input_dev->dev.parent, 0);
  33         input_sync(input_dev);
  34 
  35         return IRQ_HANDLED;
  36 }
  37 
  38 static irqreturn_t onkey_rising_irq(int irq, void *ponkey)
  39 {
  40         struct stpmic1_onkey *onkey = ponkey;
  41         struct input_dev *input_dev = onkey->input_dev;
  42 
  43         input_report_key(input_dev, KEY_POWER, 0);
  44         pm_wakeup_event(input_dev->dev.parent, 0);
  45         input_sync(input_dev);
  46 
  47         return IRQ_HANDLED;
  48 }
  49 
  50 static int stpmic1_onkey_probe(struct platform_device *pdev)
  51 {
  52         struct stpmic1 *pmic = dev_get_drvdata(pdev->dev.parent);
  53         struct device *dev = &pdev->dev;
  54         struct input_dev *input_dev;
  55         struct stpmic1_onkey *onkey;
  56         unsigned int val, reg = 0;
  57         int error;
  58 
  59         onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL);
  60         if (!onkey)
  61                 return -ENOMEM;
  62 
  63         onkey->irq_falling = platform_get_irq_byname(pdev, "onkey-falling");
  64         if (onkey->irq_falling < 0)
  65                 return onkey->irq_falling;
  66 
  67         onkey->irq_rising = platform_get_irq_byname(pdev, "onkey-rising");
  68         if (onkey->irq_rising < 0)
  69                 return onkey->irq_rising;
  70 
  71         if (!device_property_read_u32(dev, "power-off-time-sec", &val)) {
  72                 if (val > 0 && val <= 16) {
  73                         dev_dbg(dev, "power-off-time=%d seconds\n", val);
  74                         reg |= PONKEY_PWR_OFF;
  75                         reg |= ((16 - val) & PONKEY_TURNOFF_TIMER_MASK);
  76                 } else {
  77                         dev_err(dev, "power-off-time-sec out of range\n");
  78                         return -EINVAL;
  79                 }
  80         }
  81 
  82         if (device_property_present(dev, "st,onkey-clear-cc-flag"))
  83                 reg |= PONKEY_CC_FLAG_CLEAR;
  84 
  85         error = regmap_update_bits(pmic->regmap, PKEY_TURNOFF_CR,
  86                                    PONKEY_TURNOFF_MASK, reg);
  87         if (error) {
  88                 dev_err(dev, "PKEY_TURNOFF_CR write failed: %d\n", error);
  89                 return error;
  90         }
  91 
  92         if (device_property_present(dev, "st,onkey-pu-inactive")) {
  93                 error = regmap_update_bits(pmic->regmap, PADS_PULL_CR,
  94                                            PONKEY_PU_INACTIVE,
  95                                            PONKEY_PU_INACTIVE);
  96                 if (error) {
  97                         dev_err(dev, "ONKEY Pads configuration failed: %d\n",
  98                                 error);
  99                         return error;
 100                 }
 101         }
 102 
 103         input_dev = devm_input_allocate_device(dev);
 104         if (!input_dev) {
 105                 dev_err(dev, "Can't allocate Pwr Onkey Input Device\n");
 106                 return -ENOMEM;
 107         }
 108 
 109         input_dev->name = "pmic_onkey";
 110         input_dev->phys = "pmic_onkey/input0";
 111 
 112         input_set_capability(input_dev, EV_KEY, KEY_POWER);
 113 
 114         onkey->input_dev = input_dev;
 115 
 116         /* interrupt is nested in a thread */
 117         error = devm_request_threaded_irq(dev, onkey->irq_falling, NULL,
 118                                           onkey_falling_irq, IRQF_ONESHOT,
 119                                           dev_name(dev), onkey);
 120         if (error) {
 121                 dev_err(dev, "Can't get IRQ Onkey Falling: %d\n", error);
 122                 return error;
 123         }
 124 
 125         error = devm_request_threaded_irq(dev, onkey->irq_rising, NULL,
 126                                           onkey_rising_irq, IRQF_ONESHOT,
 127                                           dev_name(dev), onkey);
 128         if (error) {
 129                 dev_err(dev, "Can't get IRQ Onkey Rising: %d\n", error);
 130                 return error;
 131         }
 132 
 133         error = input_register_device(input_dev);
 134         if (error) {
 135                 dev_err(dev, "Can't register power button: %d\n", error);
 136                 return error;
 137         }
 138 
 139         platform_set_drvdata(pdev, onkey);
 140         device_init_wakeup(dev, true);
 141 
 142         return 0;
 143 }
 144 
 145 static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
 146 {
 147         struct platform_device *pdev = to_platform_device(dev);
 148         struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
 149 
 150         if (device_may_wakeup(dev)) {
 151                 enable_irq_wake(onkey->irq_falling);
 152                 enable_irq_wake(onkey->irq_rising);
 153         }
 154         return 0;
 155 }
 156 
 157 static int __maybe_unused stpmic1_onkey_resume(struct device *dev)
 158 {
 159         struct platform_device *pdev = to_platform_device(dev);
 160         struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
 161 
 162         if (device_may_wakeup(dev)) {
 163                 disable_irq_wake(onkey->irq_falling);
 164                 disable_irq_wake(onkey->irq_rising);
 165         }
 166         return 0;
 167 }
 168 
 169 static SIMPLE_DEV_PM_OPS(stpmic1_onkey_pm,
 170                          stpmic1_onkey_suspend,
 171                          stpmic1_onkey_resume);
 172 
 173 static const struct of_device_id of_stpmic1_onkey_match[] = {
 174         { .compatible = "st,stpmic1-onkey" },
 175         { },
 176 };
 177 
 178 MODULE_DEVICE_TABLE(of, of_stpmic1_onkey_match);
 179 
 180 static struct platform_driver stpmic1_onkey_driver = {
 181         .probe  = stpmic1_onkey_probe,
 182         .driver = {
 183                 .name   = "stpmic1_onkey",
 184                 .of_match_table = of_match_ptr(of_stpmic1_onkey_match),
 185                 .pm     = &stpmic1_onkey_pm,
 186         },
 187 };
 188 module_platform_driver(stpmic1_onkey_driver);
 189 
 190 MODULE_DESCRIPTION("Onkey driver for STPMIC1");
 191 MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
 192 MODULE_LICENSE("GPL v2");

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