blob: a981013564267d2a6da644ef805c07dd0e1229bf [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/input.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <linux/mfd/pmic8058.h>
21#include <linux/pmic8058-pwrkey.h>
22#include <linux/log2.h>
23#include <linux/spinlock.h>
24#include <linux/hrtimer.h>
25#include <linux/pm.h>
26#include <linux/slab.h>
27#include <linux/pm_runtime.h>
28
29#define PON_CNTL_1 0x1C
30#define PON_CNTL_PULL_UP BIT(7)
31#define PON_CNTL_TRIG_DELAY_MASK (0x7)
32
33struct pmic8058_pwrkey {
34 struct input_dev *pwr;
35 int key_press_irq;
36 int key_release_irq;
37 struct pm8058_chip *pm_chip;
38 struct hrtimer timer;
39 bool key_pressed;
40 bool pressed_first;
41 struct pmic8058_pwrkey_pdata *pdata;
42 spinlock_t lock;
43};
44
45static enum hrtimer_restart pmic8058_pwrkey_timer(struct hrtimer *timer)
46{
47 unsigned long flags;
48 struct pmic8058_pwrkey *pwrkey = container_of(timer,
49 struct pmic8058_pwrkey, timer);
50
51 spin_lock_irqsave(&pwrkey->lock, flags);
52 pwrkey->key_pressed = true;
53
54 input_report_key(pwrkey->pwr, KEY_POWER, 1);
55 input_sync(pwrkey->pwr);
56 spin_unlock_irqrestore(&pwrkey->lock, flags);
57
58 return HRTIMER_NORESTART;
59}
60
61static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey)
62{
63 struct pmic8058_pwrkey *pwrkey = _pwrkey;
64 struct pmic8058_pwrkey_pdata *pdata = pwrkey->pdata;
65 unsigned long flags;
66
67 spin_lock_irqsave(&pwrkey->lock, flags);
68 if (pwrkey->pressed_first) {
69 /*
70 * If pressed_first flag is set already then release interrupt
71 * has occured first. Events are handled in the release IRQ so
72 * return.
73 */
74 pwrkey->pressed_first = false;
75 spin_unlock_irqrestore(&pwrkey->lock, flags);
76 return IRQ_HANDLED;
77 } else {
78 pwrkey->pressed_first = true;
79 /*no pwrkey time duration, means no end key simulation*/
80 if (!pwrkey->pdata->pwrkey_time_ms) {
81 input_report_key(pwrkey->pwr, KEY_POWER, 1);
82 input_sync(pwrkey->pwr);
83 spin_unlock_irqrestore(&pwrkey->lock, flags);
84 return IRQ_HANDLED;
85 }
86
87 input_report_key(pwrkey->pwr, KEY_END, 1);
88 input_sync(pwrkey->pwr);
89
90 hrtimer_start(&pwrkey->timer,
91 ktime_set(pdata->pwrkey_time_ms / 1000,
92 (pdata->pwrkey_time_ms % 1000) * 1000000),
93 HRTIMER_MODE_REL);
94 }
95 spin_unlock_irqrestore(&pwrkey->lock, flags);
96
97 return IRQ_HANDLED;
98}
99
100static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey)
101{
102 struct pmic8058_pwrkey *pwrkey = _pwrkey;
103 unsigned long flags;
104
105 spin_lock_irqsave(&pwrkey->lock, flags);
106 if (pwrkey->pressed_first) {
107 pwrkey->pressed_first = false;
108 /* no pwrkey time, means no delay in pwr key reporting */
109 if (!pwrkey->pdata->pwrkey_time_ms) {
110 input_report_key(pwrkey->pwr, KEY_POWER, 0);
111 input_sync(pwrkey->pwr);
112 spin_unlock_irqrestore(&pwrkey->lock, flags);
113 return IRQ_HANDLED;
114 }
115
116 hrtimer_cancel(&pwrkey->timer);
117
118 if (pwrkey->key_pressed) {
119 pwrkey->key_pressed = false;
120 input_report_key(pwrkey->pwr, KEY_POWER, 0);
121 input_sync(pwrkey->pwr);
122 }
123
124 input_report_key(pwrkey->pwr, KEY_END, 0);
125 input_sync(pwrkey->pwr);
126 } else {
127 /*
128 * Set this flag true so that in the subsequent interrupt of
129 * press we can know release interrupt came first
130 */
131 pwrkey->pressed_first = true;
132 /* no pwrkey time, means no delay in pwr key reporting */
133 if (!pwrkey->pdata->pwrkey_time_ms) {
134 input_report_key(pwrkey->pwr, KEY_POWER, 1);
135 input_sync(pwrkey->pwr);
136 input_report_key(pwrkey->pwr, KEY_POWER, 0);
137 input_sync(pwrkey->pwr);
138 spin_unlock_irqrestore(&pwrkey->lock, flags);
139 return IRQ_HANDLED;
140 }
141 input_report_key(pwrkey->pwr, KEY_END, 1);
142 input_sync(pwrkey->pwr);
143 input_report_key(pwrkey->pwr, KEY_END, 0);
144 input_sync(pwrkey->pwr);
145 }
146 spin_unlock_irqrestore(&pwrkey->lock, flags);
147
148 return IRQ_HANDLED;
149}
150
151#ifdef CONFIG_PM
152static int pmic8058_pwrkey_suspend(struct device *dev)
153{
154 struct pmic8058_pwrkey *pwrkey = dev_get_drvdata(dev);
155
156 if (device_may_wakeup(dev)) {
157 enable_irq_wake(pwrkey->key_press_irq);
158 enable_irq_wake(pwrkey->key_release_irq);
159 }
160
161 return 0;
162}
163
164static int pmic8058_pwrkey_resume(struct device *dev)
165{
166 struct pmic8058_pwrkey *pwrkey = dev_get_drvdata(dev);
167
168 if (device_may_wakeup(dev)) {
169 disable_irq_wake(pwrkey->key_press_irq);
170 disable_irq_wake(pwrkey->key_release_irq);
171 }
172
173 return 0;
174}
175
176static struct dev_pm_ops pm8058_pwr_key_pm_ops = {
177 .suspend = pmic8058_pwrkey_suspend,
178 .resume = pmic8058_pwrkey_resume,
179};
180#endif
181
182static int __devinit pmic8058_pwrkey_probe(struct platform_device *pdev)
183{
184 struct input_dev *pwr;
185 int key_release_irq = platform_get_irq(pdev, 0);
186 int key_press_irq = platform_get_irq(pdev, 1);
187 int err;
188 unsigned int delay;
189 u8 pon_cntl;
190 struct pmic8058_pwrkey *pwrkey;
191 struct pmic8058_pwrkey_pdata *pdata = pdev->dev.platform_data;
192 struct pm8058_chip *pm_chip;
193
194 pm_chip = dev_get_drvdata(pdev->dev.parent);
195 if (pm_chip == NULL) {
196 dev_err(&pdev->dev, "no parent data passed in\n");
197 return -EFAULT;
198 }
199
200 if (!pdata) {
201 dev_err(&pdev->dev, "power key platform data not supplied\n");
202 return -EINVAL;
203 }
204
205 if (pdata->kpd_trigger_delay_us > 62500) {
206 dev_err(&pdev->dev, "invalid pwr key trigger delay\n");
207 return -EINVAL;
208 }
209
210 if (pdata->pwrkey_time_ms &&
211 (pdata->pwrkey_time_ms < 500 || pdata->pwrkey_time_ms > 1000)) {
212 dev_err(&pdev->dev, "invalid pwr key time supplied\n");
213 return -EINVAL;
214 }
215
216 pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
217 if (!pwrkey)
218 return -ENOMEM;
219
220 pwrkey->pm_chip = pm_chip;
221 pwrkey->pdata = pdata;
222 pwrkey->pressed_first = false;
223 /* Enable runtime PM ops, start in ACTIVE mode */
224 err = pm_runtime_set_active(&pdev->dev);
225 if (err < 0)
226 dev_dbg(&pdev->dev, "unable to set runtime pm state\n");
227 pm_runtime_enable(&pdev->dev);
228
229 pwr = input_allocate_device();
230 if (!pwr) {
231 dev_dbg(&pdev->dev, "Can't allocate power button\n");
232 err = -ENOMEM;
233 goto free_pwrkey;
234 }
235
236 input_set_capability(pwr, EV_KEY, KEY_POWER);
237 input_set_capability(pwr, EV_KEY, KEY_END);
238
239 pwr->name = "pmic8058_pwrkey";
240 pwr->phys = "pmic8058_pwrkey/input0";
241 pwr->dev.parent = &pdev->dev;
242
243 delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC;
244 delay = 1 + ilog2(delay);
245
246 err = pm8058_read(pwrkey->pm_chip, PON_CNTL_1, &pon_cntl, 1);
247 if (err < 0) {
248 dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err);
249 goto free_input_dev;
250 }
251
252
253 pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK;
254 pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK);
255 pon_cntl |= (pdata->pull_up ? PON_CNTL_PULL_UP : ~PON_CNTL_PULL_UP);
256 err = pm8058_write(pwrkey->pm_chip, PON_CNTL_1, &pon_cntl, 1);
257 if (err < 0) {
258 dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err);
259 goto free_input_dev;
260 }
261
262 hrtimer_init(&pwrkey->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
263 pwrkey->timer.function = pmic8058_pwrkey_timer;
264
265 spin_lock_init(&pwrkey->lock);
266
267 err = input_register_device(pwr);
268 if (err) {
269 dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);
270 goto free_input_dev;
271 }
272
273 pwrkey->key_press_irq = key_press_irq;
274 pwrkey->key_release_irq = key_release_irq;
275 pwrkey->pwr = pwr;
276
277 platform_set_drvdata(pdev, pwrkey);
278
279 /* Check if power-key is pressed at boot up */
280 err = pm8058_irq_get_rt_status(pwrkey->pm_chip, key_press_irq);
281 if (err < 0) {
282 dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",
283 err);
284 goto unreg_input_dev;
285 }
286 if (err) {
287 if (!pwrkey->pdata->pwrkey_time_ms)
288 input_report_key(pwrkey->pwr, KEY_POWER, 1);
289 else
290 input_report_key(pwrkey->pwr, KEY_END, 1);
291 input_sync(pwrkey->pwr);
292 pwrkey->pressed_first = true;
293 }
294
295 err = request_threaded_irq(key_press_irq, NULL, pwrkey_press_irq,
296 IRQF_TRIGGER_RISING, "pmic8058_pwrkey_press", pwrkey);
297 if (err < 0) {
298 dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
299 key_press_irq, err);
300 goto unreg_input_dev;
301 }
302
303 err = request_threaded_irq(key_release_irq, NULL, pwrkey_release_irq,
304 IRQF_TRIGGER_RISING, "pmic8058_pwrkey_release",
305 pwrkey);
306 if (err < 0) {
307 dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
308 key_release_irq, err);
309
310 goto free_press_irq;
311 }
312
313 device_init_wakeup(&pdev->dev, pdata->wakeup);
314
315 return 0;
316
317free_press_irq:
318 free_irq(key_press_irq, NULL);
319unreg_input_dev:
320 input_unregister_device(pwr);
321 pwr = NULL;
322free_input_dev:
323 input_free_device(pwr);
324free_pwrkey:
325 pm_runtime_set_suspended(&pdev->dev);
326 pm_runtime_disable(&pdev->dev);
327 kfree(pwrkey);
328 return err;
329}
330
331static int __devexit pmic8058_pwrkey_remove(struct platform_device *pdev)
332{
333 struct pmic8058_pwrkey *pwrkey = platform_get_drvdata(pdev);
334 int key_release_irq = platform_get_irq(pdev, 0);
335 int key_press_irq = platform_get_irq(pdev, 1);
336
337 pm_runtime_set_suspended(&pdev->dev);
338 pm_runtime_disable(&pdev->dev);
339 device_init_wakeup(&pdev->dev, 0);
340
341 free_irq(key_press_irq, pwrkey);
342 free_irq(key_release_irq, pwrkey);
343 input_unregister_device(pwrkey->pwr);
344 kfree(pwrkey);
345
346 return 0;
347}
348
349static struct platform_driver pmic8058_pwrkey_driver = {
350 .probe = pmic8058_pwrkey_probe,
351 .remove = __devexit_p(pmic8058_pwrkey_remove),
352 .driver = {
353 .name = "pm8058-pwrkey",
354 .owner = THIS_MODULE,
355#ifdef CONFIG_PM
356 .pm = &pm8058_pwr_key_pm_ops,
357#endif
358 },
359};
360
361static int __init pmic8058_pwrkey_init(void)
362{
363 return platform_driver_register(&pmic8058_pwrkey_driver);
364}
365module_init(pmic8058_pwrkey_init);
366
367static void __exit pmic8058_pwrkey_exit(void)
368{
369 platform_driver_unregister(&pmic8058_pwrkey_driver);
370}
371module_exit(pmic8058_pwrkey_exit);
372
373MODULE_ALIAS("platform:pmic8058_pwrkey");
374MODULE_DESCRIPTION("PMIC8058 Power Key");
375MODULE_LICENSE("GPL v2");