aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAshish Jangam <ashish.jangam@kpitcummins.com>2012-10-30 03:27:25 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-10-30 03:47:09 -0400
commit8ed2757edd0c6bacf20c1c55bd53a0acba565be8 (patch)
treeb180d022fbcd97fc94549e2c9a0a85592da383a7 /drivers
parent3b11292381aa5c57ceb6e089797afdd2e4066085 (diff)
Input: add DA9055 Onkey driver
This is the ONKEY driver of the Dialog DA9055 PMIC and depends on the DA9055 MFD core driver. This driver was functionally tested on SMDK6410 board. Signed-off-by: David Dajun Chen <dchen@diasemi.com> Signed-off-by: Ashish Jangam <ashish.jangam@kpitcummins.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/da9055_onkey.c171
3 files changed, 182 insertions, 0 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a7719a22d17e..c8353570344c 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -483,6 +483,16 @@ config INPUT_DA9052_ONKEY
483 To compile this driver as a module, choose M here: the 483 To compile this driver as a module, choose M here: the
484 module will be called da9052_onkey. 484 module will be called da9052_onkey.
485 485
486config INPUT_DA9055_ONKEY
487 tristate "Dialog Semiconductor DA9055 ONKEY"
488 depends on MFD_DA9055
489 help
490 Support the ONKEY of DA9055 PMICs as an input device
491 reporting power button status.
492
493 To compile this driver as a module, choose M here: the module
494 will be called da9055_onkey.
495
486config INPUT_DM355EVM 496config INPUT_DM355EVM
487 tristate "TI DaVinci DM355 EVM Keypad and IR Remote" 497 tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
488 depends on MFD_DM355EVM_MSP 498 depends on MFD_DM355EVM_MSP
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 83fe6f5b77d1..23347e3f7e96 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o
23obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o 23obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o
24obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o 24obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
25obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o 25obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o
26obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o
26obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o 27obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
27obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o 28obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o
28obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o 29obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o
diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c
new file mode 100644
index 000000000000..10ebf15070d7
--- /dev/null
+++ b/drivers/input/misc/da9055_onkey.c
@@ -0,0 +1,171 @@
1/*
2 * ON pin driver for Dialog DA9055 PMICs
3 *
4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
5 *
6 * Author: David Dajun Chen <dchen@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/input.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18
19#include <linux/mfd/da9055/core.h>
20#include <linux/mfd/da9055/reg.h>
21
22struct da9055_onkey {
23 struct da9055 *da9055;
24 struct input_dev *input;
25 struct delayed_work work;
26};
27
28static void da9055_onkey_query(struct da9055_onkey *onkey)
29{
30 int key_stat;
31
32 key_stat = da9055_reg_read(onkey->da9055, DA9055_REG_STATUS_A);
33 if (key_stat < 0) {
34 dev_err(onkey->da9055->dev,
35 "Failed to read onkey event %d\n", key_stat);
36 } else {
37 key_stat &= DA9055_NOKEY_STS;
38 /*
39 * Onkey status bit is cleared when onkey button is relased.
40 */
41 if (!key_stat) {
42 input_report_key(onkey->input, KEY_POWER, 0);
43 input_sync(onkey->input);
44 }
45 }
46
47 /*
48 * Interrupt is generated only when the ONKEY pin is asserted.
49 * Hence the deassertion of the pin is simulated through work queue.
50 */
51 if (key_stat)
52 schedule_delayed_work(&onkey->work, msecs_to_jiffies(10));
53
54}
55
56static void da9055_onkey_work(struct work_struct *work)
57{
58 struct da9055_onkey *onkey = container_of(work, struct da9055_onkey,
59 work.work);
60
61 da9055_onkey_query(onkey);
62}
63
64static irqreturn_t da9055_onkey_irq(int irq, void *data)
65{
66 struct da9055_onkey *onkey = data;
67
68 input_report_key(onkey->input, KEY_POWER, 1);
69 input_sync(onkey->input);
70
71 da9055_onkey_query(onkey);
72
73 return IRQ_HANDLED;
74}
75
76static int __devinit da9055_onkey_probe(struct platform_device *pdev)
77{
78 struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
79 struct da9055_onkey *onkey;
80 struct input_dev *input_dev;
81 int irq, err;
82
83 irq = platform_get_irq_byname(pdev, "ONKEY");
84 if (irq < 0) {
85 dev_err(&pdev->dev,
86 "Failed to get an IRQ for input device, %d\n", irq);
87 return -EINVAL;
88 }
89
90 onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
91 if (!onkey) {
92 dev_err(&pdev->dev, "Failed to allocate memory\n");
93 return -ENOMEM;
94 }
95
96 input_dev = input_allocate_device();
97 if (!input_dev) {
98 dev_err(&pdev->dev, "Failed to allocate memory\n");
99 return -ENOMEM;
100 }
101
102 onkey->input = input_dev;
103 onkey->da9055 = da9055;
104 input_dev->name = "da9055-onkey";
105 input_dev->phys = "da9055-onkey/input0";
106 input_dev->dev.parent = &pdev->dev;
107
108 input_dev->evbit[0] = BIT_MASK(EV_KEY);
109 __set_bit(KEY_POWER, input_dev->keybit);
110
111 INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work);
112
113 irq = regmap_irq_get_virq(da9055->irq_data, irq);
114 err = request_threaded_irq(irq, NULL, da9055_onkey_irq,
115 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
116 "ONKEY", onkey);
117 if (err < 0) {
118 dev_err(&pdev->dev,
119 "Failed to register ONKEY IRQ %d, error = %d\n",
120 irq, err);
121 goto err_free_input;
122 }
123
124 err = input_register_device(input_dev);
125 if (err) {
126 dev_err(&pdev->dev, "Unable to register input device, %d\n",
127 err);
128 goto err_free_irq;
129 }
130
131 platform_set_drvdata(pdev, onkey);
132
133 return 0;
134
135err_free_irq:
136 free_irq(irq, onkey);
137 cancel_delayed_work_sync(&onkey->work);
138err_free_input:
139 input_free_device(input_dev);
140
141 return err;
142}
143
144static int __devexit da9055_onkey_remove(struct platform_device *pdev)
145{
146 struct da9055_onkey *onkey = platform_get_drvdata(pdev);
147 int irq = platform_get_irq_byname(pdev, "ONKEY");
148
149 irq = regmap_irq_get_virq(onkey->da9055->irq_data, irq);
150 free_irq(irq, onkey);
151 cancel_delayed_work_sync(&onkey->work);
152 input_unregister_device(onkey->input);
153
154 return 0;
155}
156
157static struct platform_driver da9055_onkey_driver = {
158 .probe = da9055_onkey_probe,
159 .remove = __devexit_p(da9055_onkey_remove),
160 .driver = {
161 .name = "da9055-onkey",
162 .owner = THIS_MODULE,
163 },
164};
165
166module_platform_driver(da9055_onkey_driver);
167
168MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
169MODULE_DESCRIPTION("Onkey driver for DA9055");
170MODULE_LICENSE("GPL");
171MODULE_ALIAS("platform:da9055-onkey");