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>
16 #include <linux/slab.h>
19 * struct ab8500_ponkey - ab8500 ponkey information
20 * @input_dev: pointer to input device
21 * @ab8500: ab8500 parent
22 * @irq_dbf: irq number for falling transition
23 * @irq_dbr: irq number for rising transition
25 struct ab8500_ponkey
{
26 struct input_dev
*idev
;
27 struct ab8500
*ab8500
;
32 /* AB8500 gives us an interrupt when ONKEY is held */
33 static irqreturn_t
ab8500_ponkey_handler(int irq
, void *data
)
35 struct ab8500_ponkey
*ponkey
= data
;
37 if (irq
== ponkey
->irq_dbf
)
38 input_report_key(ponkey
->idev
, KEY_POWER
, true);
39 else if (irq
== ponkey
->irq_dbr
)
40 input_report_key(ponkey
->idev
, KEY_POWER
, false);
42 input_sync(ponkey
->idev
);
47 static int __devinit
ab8500_ponkey_probe(struct platform_device
*pdev
)
49 struct ab8500
*ab8500
= dev_get_drvdata(pdev
->dev
.parent
);
50 struct ab8500_ponkey
*ponkey
;
51 struct input_dev
*input
;
55 irq_dbf
= platform_get_irq_byname(pdev
, "ONKEY_DBF");
57 dev_err(&pdev
->dev
, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf
);
61 irq_dbr
= platform_get_irq_byname(pdev
, "ONKEY_DBR");
63 dev_err(&pdev
->dev
, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr
);
67 ponkey
= kzalloc(sizeof(struct ab8500_ponkey
), GFP_KERNEL
);
68 input
= input_allocate_device();
69 if (!ponkey
|| !input
) {
75 ponkey
->ab8500
= ab8500
;
76 ponkey
->irq_dbf
= irq_dbf
;
77 ponkey
->irq_dbr
= irq_dbr
;
79 input
->name
= "AB8500 POn(PowerOn) Key";
80 input
->dev
.parent
= &pdev
->dev
;
82 input_set_capability(input
, EV_KEY
, KEY_POWER
);
84 error
= request_any_context_irq(ponkey
->irq_dbf
, ab8500_ponkey_handler
,
85 0, "ab8500-ponkey-dbf", ponkey
);
87 dev_err(ab8500
->dev
, "Failed to request dbf IRQ#%d: %d\n",
88 ponkey
->irq_dbf
, error
);
92 error
= request_any_context_irq(ponkey
->irq_dbr
, ab8500_ponkey_handler
,
93 0, "ab8500-ponkey-dbr", ponkey
);
95 dev_err(ab8500
->dev
, "Failed to request dbr IRQ#%d: %d\n",
96 ponkey
->irq_dbr
, error
);
97 goto err_free_dbf_irq
;
100 error
= input_register_device(ponkey
->idev
);
102 dev_err(ab8500
->dev
, "Can't register input device: %d\n", error
);
103 goto err_free_dbr_irq
;
106 platform_set_drvdata(pdev
, ponkey
);
110 free_irq(ponkey
->irq_dbr
, ponkey
);
112 free_irq(ponkey
->irq_dbf
, ponkey
);
114 input_free_device(input
);
120 static int __devexit
ab8500_ponkey_remove(struct platform_device
*pdev
)
122 struct ab8500_ponkey
*ponkey
= platform_get_drvdata(pdev
);
124 free_irq(ponkey
->irq_dbf
, ponkey
);
125 free_irq(ponkey
->irq_dbr
, ponkey
);
126 input_unregister_device(ponkey
->idev
);
129 platform_set_drvdata(pdev
, NULL
);
134 static struct platform_driver ab8500_ponkey_driver
= {
136 .name
= "ab8500-poweron-key",
137 .owner
= THIS_MODULE
,
139 .probe
= ab8500_ponkey_probe
,
140 .remove
= __devexit_p(ab8500_ponkey_remove
),
142 module_platform_driver(ab8500_ponkey_driver
);
144 MODULE_LICENSE("GPL v2");
145 MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
146 MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver");