2 * Copyright (C) ST-Ericsson SA 2010
4 * License Terms: GNU General Public License v2
5 * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
7 * AB8500 Power-On Key handler
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/input.h>
14 #include <linux/interrupt.h>
15 #include <linux/mfd/abx500/ab8500.h>
17 #include <linux/slab.h>
20 * struct ab8500_ponkey - ab8500 ponkey information
21 * @input_dev: pointer to input device
22 * @ab8500: ab8500 parent
23 * @irq_dbf: irq number for falling transition
24 * @irq_dbr: irq number for rising transition
26 struct ab8500_ponkey
{
27 struct input_dev
*idev
;
28 struct ab8500
*ab8500
;
33 /* AB8500 gives us an interrupt when ONKEY is held */
34 static irqreturn_t
ab8500_ponkey_handler(int irq
, void *data
)
36 struct ab8500_ponkey
*ponkey
= data
;
38 if (irq
== ponkey
->irq_dbf
)
39 input_report_key(ponkey
->idev
, KEY_POWER
, true);
40 else if (irq
== ponkey
->irq_dbr
)
41 input_report_key(ponkey
->idev
, KEY_POWER
, false);
43 input_sync(ponkey
->idev
);
48 static int ab8500_ponkey_probe(struct platform_device
*pdev
)
50 struct ab8500
*ab8500
= dev_get_drvdata(pdev
->dev
.parent
);
51 struct ab8500_ponkey
*ponkey
;
52 struct input_dev
*input
;
56 irq_dbf
= platform_get_irq_byname(pdev
, "ONKEY_DBF");
58 dev_err(&pdev
->dev
, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf
);
62 irq_dbr
= platform_get_irq_byname(pdev
, "ONKEY_DBR");
64 dev_err(&pdev
->dev
, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr
);
68 ponkey
= kzalloc(sizeof(struct ab8500_ponkey
), GFP_KERNEL
);
69 input
= input_allocate_device();
70 if (!ponkey
|| !input
) {
76 ponkey
->ab8500
= ab8500
;
77 ponkey
->irq_dbf
= irq_dbf
;
78 ponkey
->irq_dbr
= irq_dbr
;
80 input
->name
= "AB8500 POn(PowerOn) Key";
81 input
->dev
.parent
= &pdev
->dev
;
83 input_set_capability(input
, EV_KEY
, KEY_POWER
);
85 error
= request_any_context_irq(ponkey
->irq_dbf
, ab8500_ponkey_handler
,
86 0, "ab8500-ponkey-dbf", ponkey
);
88 dev_err(ab8500
->dev
, "Failed to request dbf IRQ#%d: %d\n",
89 ponkey
->irq_dbf
, error
);
93 error
= request_any_context_irq(ponkey
->irq_dbr
, ab8500_ponkey_handler
,
94 0, "ab8500-ponkey-dbr", ponkey
);
96 dev_err(ab8500
->dev
, "Failed to request dbr IRQ#%d: %d\n",
97 ponkey
->irq_dbr
, error
);
98 goto err_free_dbf_irq
;
101 error
= input_register_device(ponkey
->idev
);
103 dev_err(ab8500
->dev
, "Can't register input device: %d\n", error
);
104 goto err_free_dbr_irq
;
107 platform_set_drvdata(pdev
, ponkey
);
111 free_irq(ponkey
->irq_dbr
, ponkey
);
113 free_irq(ponkey
->irq_dbf
, ponkey
);
115 input_free_device(input
);
121 static int ab8500_ponkey_remove(struct platform_device
*pdev
)
123 struct ab8500_ponkey
*ponkey
= platform_get_drvdata(pdev
);
125 free_irq(ponkey
->irq_dbf
, ponkey
);
126 free_irq(ponkey
->irq_dbr
, ponkey
);
127 input_unregister_device(ponkey
->idev
);
134 static const struct of_device_id ab8500_ponkey_match
[] = {
135 { .compatible
= "stericsson,ab8500-ponkey", },
140 static struct platform_driver ab8500_ponkey_driver
= {
142 .name
= "ab8500-poweron-key",
143 .owner
= THIS_MODULE
,
144 .of_match_table
= of_match_ptr(ab8500_ponkey_match
),
146 .probe
= ab8500_ponkey_probe
,
147 .remove
= ab8500_ponkey_remove
,
149 module_platform_driver(ab8500_ponkey_driver
);
151 MODULE_LICENSE("GPL v2");
152 MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
153 MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver");