0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/kernel.h>
0022 #include <linux/module.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/i2c.h>
0025 #include <linux/input.h>
0026 #include <linux/interrupt.h>
0027 #include <linux/mfd/88pm860x.h>
0028 #include <linux/slab.h>
0029 #include <linux/device.h>
0030
0031 #define PM8607_WAKEUP 0x0b
0032
0033 #define LONG_ONKEY_EN (1 << 1)
0034 #define ONKEY_STATUS (1 << 0)
0035
0036 struct pm860x_onkey_info {
0037 struct input_dev *idev;
0038 struct pm860x_chip *chip;
0039 struct i2c_client *i2c;
0040 struct device *dev;
0041 int irq;
0042 };
0043
0044
0045 static irqreturn_t pm860x_onkey_handler(int irq, void *data)
0046 {
0047 struct pm860x_onkey_info *info = data;
0048 int ret;
0049
0050 ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
0051 ret &= ONKEY_STATUS;
0052 input_report_key(info->idev, KEY_POWER, ret);
0053 input_sync(info->idev);
0054
0055
0056 pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN);
0057 return IRQ_HANDLED;
0058 }
0059
0060 static int pm860x_onkey_probe(struct platform_device *pdev)
0061 {
0062 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
0063 struct pm860x_onkey_info *info;
0064 int irq, ret;
0065
0066 irq = platform_get_irq(pdev, 0);
0067 if (irq < 0)
0068 return -EINVAL;
0069
0070 info = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_onkey_info),
0071 GFP_KERNEL);
0072 if (!info)
0073 return -ENOMEM;
0074 info->chip = chip;
0075 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
0076 info->dev = &pdev->dev;
0077 info->irq = irq;
0078
0079 info->idev = devm_input_allocate_device(&pdev->dev);
0080 if (!info->idev) {
0081 dev_err(chip->dev, "Failed to allocate input dev\n");
0082 return -ENOMEM;
0083 }
0084
0085 info->idev->name = "88pm860x_on";
0086 info->idev->phys = "88pm860x_on/input0";
0087 info->idev->id.bustype = BUS_I2C;
0088 info->idev->dev.parent = &pdev->dev;
0089 info->idev->evbit[0] = BIT_MASK(EV_KEY);
0090 info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
0091
0092 ret = input_register_device(info->idev);
0093 if (ret) {
0094 dev_err(chip->dev, "Can't register input device: %d\n", ret);
0095 return ret;
0096 }
0097
0098 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
0099 pm860x_onkey_handler, IRQF_ONESHOT,
0100 "onkey", info);
0101 if (ret < 0) {
0102 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
0103 info->irq, ret);
0104 return ret;
0105 }
0106
0107 platform_set_drvdata(pdev, info);
0108 device_init_wakeup(&pdev->dev, 1);
0109
0110 return 0;
0111 }
0112
0113 static int __maybe_unused pm860x_onkey_suspend(struct device *dev)
0114 {
0115 struct platform_device *pdev = to_platform_device(dev);
0116 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
0117
0118 if (device_may_wakeup(dev))
0119 chip->wakeup_flag |= 1 << PM8607_IRQ_ONKEY;
0120 return 0;
0121 }
0122 static int __maybe_unused pm860x_onkey_resume(struct device *dev)
0123 {
0124 struct platform_device *pdev = to_platform_device(dev);
0125 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
0126
0127 if (device_may_wakeup(dev))
0128 chip->wakeup_flag &= ~(1 << PM8607_IRQ_ONKEY);
0129 return 0;
0130 }
0131
0132 static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey_resume);
0133
0134 static struct platform_driver pm860x_onkey_driver = {
0135 .driver = {
0136 .name = "88pm860x-onkey",
0137 .pm = &pm860x_onkey_pm_ops,
0138 },
0139 .probe = pm860x_onkey_probe,
0140 };
0141 module_platform_driver(pm860x_onkey_driver);
0142
0143 MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver");
0144 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
0145 MODULE_LICENSE("GPL");