0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <linux/kernel.h>
0023 #include <linux/module.h>
0024 #include <linux/input.h>
0025 #include <linux/mfd/88pm80x.h>
0026 #include <linux/regmap.h>
0027 #include <linux/slab.h>
0028
0029 #define PM800_LONG_ONKEY_EN (1 << 0)
0030 #define PM800_LONG_KEY_DELAY (8)
0031 #define PM800_LONKEY_PRESS_TIME ((PM800_LONG_KEY_DELAY-1) << 4)
0032 #define PM800_LONKEY_PRESS_TIME_MASK (0xF0)
0033 #define PM800_SW_PDOWN (1 << 5)
0034
0035 struct pm80x_onkey_info {
0036 struct input_dev *idev;
0037 struct pm80x_chip *pm80x;
0038 struct regmap *map;
0039 int irq;
0040 };
0041
0042
0043 static irqreturn_t pm80x_onkey_handler(int irq, void *data)
0044 {
0045 struct pm80x_onkey_info *info = data;
0046 int ret = 0;
0047 unsigned int val;
0048
0049 ret = regmap_read(info->map, PM800_STATUS_1, &val);
0050 if (ret < 0) {
0051 dev_err(info->idev->dev.parent, "failed to read status: %d\n", ret);
0052 return IRQ_NONE;
0053 }
0054 val &= PM800_ONKEY_STS1;
0055
0056 input_report_key(info->idev, KEY_POWER, val);
0057 input_sync(info->idev);
0058
0059 return IRQ_HANDLED;
0060 }
0061
0062 static SIMPLE_DEV_PM_OPS(pm80x_onkey_pm_ops, pm80x_dev_suspend,
0063 pm80x_dev_resume);
0064
0065 static int pm80x_onkey_probe(struct platform_device *pdev)
0066 {
0067
0068 struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
0069 struct pm80x_onkey_info *info;
0070 int err;
0071
0072 info = kzalloc(sizeof(struct pm80x_onkey_info), GFP_KERNEL);
0073 if (!info)
0074 return -ENOMEM;
0075
0076 info->pm80x = chip;
0077
0078 info->irq = platform_get_irq(pdev, 0);
0079 if (info->irq < 0) {
0080 err = -EINVAL;
0081 goto out;
0082 }
0083
0084 info->map = info->pm80x->regmap;
0085 if (!info->map) {
0086 dev_err(&pdev->dev, "no regmap!\n");
0087 err = -EINVAL;
0088 goto out;
0089 }
0090
0091 info->idev = input_allocate_device();
0092 if (!info->idev) {
0093 dev_err(&pdev->dev, "Failed to allocate input dev\n");
0094 err = -ENOMEM;
0095 goto out;
0096 }
0097
0098 info->idev->name = "88pm80x_on";
0099 info->idev->phys = "88pm80x_on/input0";
0100 info->idev->id.bustype = BUS_I2C;
0101 info->idev->dev.parent = &pdev->dev;
0102 info->idev->evbit[0] = BIT_MASK(EV_KEY);
0103 __set_bit(KEY_POWER, info->idev->keybit);
0104
0105 err = pm80x_request_irq(info->pm80x, info->irq, pm80x_onkey_handler,
0106 IRQF_ONESHOT, "onkey", info);
0107 if (err < 0) {
0108 dev_err(&pdev->dev, "Failed to request IRQ: #%d: %d\n",
0109 info->irq, err);
0110 goto out_reg;
0111 }
0112
0113 err = input_register_device(info->idev);
0114 if (err) {
0115 dev_err(&pdev->dev, "Can't register input device: %d\n", err);
0116 goto out_irq;
0117 }
0118
0119 platform_set_drvdata(pdev, info);
0120
0121
0122 regmap_update_bits(info->map, PM800_RTC_MISC4, PM800_LONG_ONKEY_EN,
0123 PM800_LONG_ONKEY_EN);
0124
0125 regmap_update_bits(info->map, PM800_RTC_MISC3,
0126 PM800_LONKEY_PRESS_TIME_MASK,
0127 PM800_LONKEY_PRESS_TIME);
0128
0129 device_init_wakeup(&pdev->dev, 1);
0130 return 0;
0131
0132 out_irq:
0133 pm80x_free_irq(info->pm80x, info->irq, info);
0134 out_reg:
0135 input_free_device(info->idev);
0136 out:
0137 kfree(info);
0138 return err;
0139 }
0140
0141 static int pm80x_onkey_remove(struct platform_device *pdev)
0142 {
0143 struct pm80x_onkey_info *info = platform_get_drvdata(pdev);
0144
0145 pm80x_free_irq(info->pm80x, info->irq, info);
0146 input_unregister_device(info->idev);
0147 kfree(info);
0148 return 0;
0149 }
0150
0151 static struct platform_driver pm80x_onkey_driver = {
0152 .driver = {
0153 .name = "88pm80x-onkey",
0154 .pm = &pm80x_onkey_pm_ops,
0155 },
0156 .probe = pm80x_onkey_probe,
0157 .remove = pm80x_onkey_remove,
0158 };
0159
0160 module_platform_driver(pm80x_onkey_driver);
0161
0162 MODULE_LICENSE("GPL");
0163 MODULE_DESCRIPTION("Marvell 88PM80x ONKEY driver");
0164 MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
0165 MODULE_ALIAS("platform:88pm80x-onkey");