0001
0002
0003
0004
0005 #include <linux/input.h>
0006 #include <linux/interrupt.h>
0007 #include <linux/mfd/stpmic1.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/property.h>
0012 #include <linux/regmap.h>
0013
0014
0015
0016
0017
0018
0019
0020 struct stpmic1_onkey {
0021 struct input_dev *input_dev;
0022 int irq_falling;
0023 int irq_rising;
0024 };
0025
0026 static irqreturn_t onkey_falling_irq(int irq, void *ponkey)
0027 {
0028 struct stpmic1_onkey *onkey = ponkey;
0029 struct input_dev *input_dev = onkey->input_dev;
0030
0031 input_report_key(input_dev, KEY_POWER, 1);
0032 pm_wakeup_event(input_dev->dev.parent, 0);
0033 input_sync(input_dev);
0034
0035 return IRQ_HANDLED;
0036 }
0037
0038 static irqreturn_t onkey_rising_irq(int irq, void *ponkey)
0039 {
0040 struct stpmic1_onkey *onkey = ponkey;
0041 struct input_dev *input_dev = onkey->input_dev;
0042
0043 input_report_key(input_dev, KEY_POWER, 0);
0044 pm_wakeup_event(input_dev->dev.parent, 0);
0045 input_sync(input_dev);
0046
0047 return IRQ_HANDLED;
0048 }
0049
0050 static int stpmic1_onkey_probe(struct platform_device *pdev)
0051 {
0052 struct stpmic1 *pmic = dev_get_drvdata(pdev->dev.parent);
0053 struct device *dev = &pdev->dev;
0054 struct input_dev *input_dev;
0055 struct stpmic1_onkey *onkey;
0056 unsigned int val, reg = 0;
0057 int error;
0058
0059 onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL);
0060 if (!onkey)
0061 return -ENOMEM;
0062
0063 onkey->irq_falling = platform_get_irq_byname(pdev, "onkey-falling");
0064 if (onkey->irq_falling < 0)
0065 return onkey->irq_falling;
0066
0067 onkey->irq_rising = platform_get_irq_byname(pdev, "onkey-rising");
0068 if (onkey->irq_rising < 0)
0069 return onkey->irq_rising;
0070
0071 if (!device_property_read_u32(dev, "power-off-time-sec", &val)) {
0072 if (val > 0 && val <= 16) {
0073 dev_dbg(dev, "power-off-time=%d seconds\n", val);
0074 reg |= PONKEY_PWR_OFF;
0075 reg |= ((16 - val) & PONKEY_TURNOFF_TIMER_MASK);
0076 } else {
0077 dev_err(dev, "power-off-time-sec out of range\n");
0078 return -EINVAL;
0079 }
0080 }
0081
0082 if (device_property_present(dev, "st,onkey-clear-cc-flag"))
0083 reg |= PONKEY_CC_FLAG_CLEAR;
0084
0085 error = regmap_update_bits(pmic->regmap, PKEY_TURNOFF_CR,
0086 PONKEY_TURNOFF_MASK, reg);
0087 if (error) {
0088 dev_err(dev, "PKEY_TURNOFF_CR write failed: %d\n", error);
0089 return error;
0090 }
0091
0092 if (device_property_present(dev, "st,onkey-pu-inactive")) {
0093 error = regmap_update_bits(pmic->regmap, PADS_PULL_CR,
0094 PONKEY_PU_INACTIVE,
0095 PONKEY_PU_INACTIVE);
0096 if (error) {
0097 dev_err(dev, "ONKEY Pads configuration failed: %d\n",
0098 error);
0099 return error;
0100 }
0101 }
0102
0103 input_dev = devm_input_allocate_device(dev);
0104 if (!input_dev) {
0105 dev_err(dev, "Can't allocate Pwr Onkey Input Device\n");
0106 return -ENOMEM;
0107 }
0108
0109 input_dev->name = "pmic_onkey";
0110 input_dev->phys = "pmic_onkey/input0";
0111
0112 input_set_capability(input_dev, EV_KEY, KEY_POWER);
0113
0114 onkey->input_dev = input_dev;
0115
0116
0117 error = devm_request_threaded_irq(dev, onkey->irq_falling, NULL,
0118 onkey_falling_irq, IRQF_ONESHOT,
0119 dev_name(dev), onkey);
0120 if (error) {
0121 dev_err(dev, "Can't get IRQ Onkey Falling: %d\n", error);
0122 return error;
0123 }
0124
0125 error = devm_request_threaded_irq(dev, onkey->irq_rising, NULL,
0126 onkey_rising_irq, IRQF_ONESHOT,
0127 dev_name(dev), onkey);
0128 if (error) {
0129 dev_err(dev, "Can't get IRQ Onkey Rising: %d\n", error);
0130 return error;
0131 }
0132
0133 error = input_register_device(input_dev);
0134 if (error) {
0135 dev_err(dev, "Can't register power button: %d\n", error);
0136 return error;
0137 }
0138
0139 platform_set_drvdata(pdev, onkey);
0140 device_init_wakeup(dev, true);
0141
0142 return 0;
0143 }
0144
0145 static int __maybe_unused stpmic1_onkey_suspend(struct device *dev)
0146 {
0147 struct platform_device *pdev = to_platform_device(dev);
0148 struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
0149
0150 if (device_may_wakeup(dev)) {
0151 enable_irq_wake(onkey->irq_falling);
0152 enable_irq_wake(onkey->irq_rising);
0153 }
0154 return 0;
0155 }
0156
0157 static int __maybe_unused stpmic1_onkey_resume(struct device *dev)
0158 {
0159 struct platform_device *pdev = to_platform_device(dev);
0160 struct stpmic1_onkey *onkey = platform_get_drvdata(pdev);
0161
0162 if (device_may_wakeup(dev)) {
0163 disable_irq_wake(onkey->irq_falling);
0164 disable_irq_wake(onkey->irq_rising);
0165 }
0166 return 0;
0167 }
0168
0169 static SIMPLE_DEV_PM_OPS(stpmic1_onkey_pm,
0170 stpmic1_onkey_suspend,
0171 stpmic1_onkey_resume);
0172
0173 static const struct of_device_id of_stpmic1_onkey_match[] = {
0174 { .compatible = "st,stpmic1-onkey" },
0175 { },
0176 };
0177
0178 MODULE_DEVICE_TABLE(of, of_stpmic1_onkey_match);
0179
0180 static struct platform_driver stpmic1_onkey_driver = {
0181 .probe = stpmic1_onkey_probe,
0182 .driver = {
0183 .name = "stpmic1_onkey",
0184 .of_match_table = of_match_ptr(of_stpmic1_onkey_match),
0185 .pm = &stpmic1_onkey_pm,
0186 },
0187 };
0188 module_platform_driver(stpmic1_onkey_driver);
0189
0190 MODULE_DESCRIPTION("Onkey driver for STPMIC1");
0191 MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
0192 MODULE_LICENSE("GPL v2");