2 * Copyright (C) 2011 Philippe Rétornaz
4 * Based on twl4030-pwrbutton driver by:
5 * Peter De Schrijver <peter.de-schrijver@nokia.com>
6 * Felipe Balbi <felipe.balbi@nokia.com>
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file "COPYING" in the main directory of this
10 * archive for more details.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/errno.h>
25 #include <linux/input.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/mfd/mc13783.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
33 struct input_dev
*pwr
;
34 struct mc13xxx
*mc13783
;
35 #define MC13783_PWRB_B1_POL_INVERT (1 << 0)
36 #define MC13783_PWRB_B2_POL_INVERT (1 << 1)
37 #define MC13783_PWRB_B3_POL_INVERT (1 << 2)
39 unsigned short keymap
[3];
42 #define MC13783_REG_INTERRUPT_SENSE_1 5
43 #define MC13783_IRQSENSE1_ONOFD1S (1 << 3)
44 #define MC13783_IRQSENSE1_ONOFD2S (1 << 4)
45 #define MC13783_IRQSENSE1_ONOFD3S (1 << 5)
47 #define MC13783_REG_POWER_CONTROL_2 15
48 #define MC13783_POWER_CONTROL_2_ON1BDBNC 4
49 #define MC13783_POWER_CONTROL_2_ON2BDBNC 6
50 #define MC13783_POWER_CONTROL_2_ON3BDBNC 8
51 #define MC13783_POWER_CONTROL_2_ON1BRSTEN (1 << 1)
52 #define MC13783_POWER_CONTROL_2_ON2BRSTEN (1 << 2)
53 #define MC13783_POWER_CONTROL_2_ON3BRSTEN (1 << 3)
55 static irqreturn_t
button_irq(int irq
, void *_priv
)
57 struct mc13783_pwrb
*priv
= _priv
;
60 mc13xxx_irq_ack(priv
->mc13783
, irq
);
61 mc13xxx_reg_read(priv
->mc13783
, MC13783_REG_INTERRUPT_SENSE_1
, &val
);
64 case MC13783_IRQ_ONOFD1
:
65 val
= val
& MC13783_IRQSENSE1_ONOFD1S
? 1 : 0;
66 if (priv
->flags
& MC13783_PWRB_B1_POL_INVERT
)
68 input_report_key(priv
->pwr
, priv
->keymap
[0], val
);
71 case MC13783_IRQ_ONOFD2
:
72 val
= val
& MC13783_IRQSENSE1_ONOFD2S
? 1 : 0;
73 if (priv
->flags
& MC13783_PWRB_B2_POL_INVERT
)
75 input_report_key(priv
->pwr
, priv
->keymap
[1], val
);
78 case MC13783_IRQ_ONOFD3
:
79 val
= val
& MC13783_IRQSENSE1_ONOFD3S
? 1 : 0;
80 if (priv
->flags
& MC13783_PWRB_B3_POL_INVERT
)
82 input_report_key(priv
->pwr
, priv
->keymap
[2], val
);
86 input_sync(priv
->pwr
);
91 static int mc13783_pwrbutton_probe(struct platform_device
*pdev
)
93 const struct mc13xxx_buttons_platform_data
*pdata
;
94 struct mc13xxx
*mc13783
= dev_get_drvdata(pdev
->dev
.parent
);
95 struct input_dev
*pwr
;
96 struct mc13783_pwrb
*priv
;
100 pdata
= dev_get_platdata(&pdev
->dev
);
102 dev_err(&pdev
->dev
, "missing platform data\n");
106 pwr
= input_allocate_device();
108 dev_dbg(&pdev
->dev
, "Can't allocate power button\n");
112 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
115 dev_dbg(&pdev
->dev
, "Can't allocate power button\n");
119 reg
|= (pdata
->b1on_flags
& 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC
;
120 reg
|= (pdata
->b2on_flags
& 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC
;
121 reg
|= (pdata
->b3on_flags
& 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC
;
124 priv
->mc13783
= mc13783
;
126 mc13xxx_lock(mc13783
);
128 if (pdata
->b1on_flags
& MC13783_BUTTON_ENABLE
) {
129 priv
->keymap
[0] = pdata
->b1on_key
;
130 if (pdata
->b1on_key
!= KEY_RESERVED
)
131 __set_bit(pdata
->b1on_key
, pwr
->keybit
);
133 if (pdata
->b1on_flags
& MC13783_BUTTON_POL_INVERT
)
134 priv
->flags
|= MC13783_PWRB_B1_POL_INVERT
;
136 if (pdata
->b1on_flags
& MC13783_BUTTON_RESET_EN
)
137 reg
|= MC13783_POWER_CONTROL_2_ON1BRSTEN
;
139 err
= mc13xxx_irq_request(mc13783
, MC13783_IRQ_ONOFD1
,
140 button_irq
, "b1on", priv
);
142 dev_dbg(&pdev
->dev
, "Can't request irq\n");
147 if (pdata
->b2on_flags
& MC13783_BUTTON_ENABLE
) {
148 priv
->keymap
[1] = pdata
->b2on_key
;
149 if (pdata
->b2on_key
!= KEY_RESERVED
)
150 __set_bit(pdata
->b2on_key
, pwr
->keybit
);
152 if (pdata
->b2on_flags
& MC13783_BUTTON_POL_INVERT
)
153 priv
->flags
|= MC13783_PWRB_B2_POL_INVERT
;
155 if (pdata
->b2on_flags
& MC13783_BUTTON_RESET_EN
)
156 reg
|= MC13783_POWER_CONTROL_2_ON2BRSTEN
;
158 err
= mc13xxx_irq_request(mc13783
, MC13783_IRQ_ONOFD2
,
159 button_irq
, "b2on", priv
);
161 dev_dbg(&pdev
->dev
, "Can't request irq\n");
166 if (pdata
->b3on_flags
& MC13783_BUTTON_ENABLE
) {
167 priv
->keymap
[2] = pdata
->b3on_key
;
168 if (pdata
->b3on_key
!= KEY_RESERVED
)
169 __set_bit(pdata
->b3on_key
, pwr
->keybit
);
171 if (pdata
->b3on_flags
& MC13783_BUTTON_POL_INVERT
)
172 priv
->flags
|= MC13783_PWRB_B3_POL_INVERT
;
174 if (pdata
->b3on_flags
& MC13783_BUTTON_RESET_EN
)
175 reg
|= MC13783_POWER_CONTROL_2_ON3BRSTEN
;
177 err
= mc13xxx_irq_request(mc13783
, MC13783_IRQ_ONOFD3
,
178 button_irq
, "b3on", priv
);
180 dev_dbg(&pdev
->dev
, "Can't request irq: %d\n", err
);
185 mc13xxx_reg_rmw(mc13783
, MC13783_REG_POWER_CONTROL_2
, 0x3FE, reg
);
187 mc13xxx_unlock(mc13783
);
189 pwr
->name
= "mc13783_pwrbutton";
190 pwr
->phys
= "mc13783_pwrbutton/input0";
191 pwr
->dev
.parent
= &pdev
->dev
;
193 pwr
->keycode
= priv
->keymap
;
194 pwr
->keycodemax
= ARRAY_SIZE(priv
->keymap
);
195 pwr
->keycodesize
= sizeof(priv
->keymap
[0]);
196 __set_bit(EV_KEY
, pwr
->evbit
);
198 err
= input_register_device(pwr
);
200 dev_dbg(&pdev
->dev
, "Can't register power button: %d\n", err
);
204 platform_set_drvdata(pdev
, priv
);
209 mc13xxx_lock(mc13783
);
211 if (pdata
->b3on_flags
& MC13783_BUTTON_ENABLE
)
212 mc13xxx_irq_free(mc13783
, MC13783_IRQ_ONOFD3
, priv
);
215 if (pdata
->b2on_flags
& MC13783_BUTTON_ENABLE
)
216 mc13xxx_irq_free(mc13783
, MC13783_IRQ_ONOFD2
, priv
);
219 if (pdata
->b1on_flags
& MC13783_BUTTON_ENABLE
)
220 mc13xxx_irq_free(mc13783
, MC13783_IRQ_ONOFD1
, priv
);
223 mc13xxx_unlock(mc13783
);
227 input_free_device(pwr
);
232 static int mc13783_pwrbutton_remove(struct platform_device
*pdev
)
234 struct mc13783_pwrb
*priv
= platform_get_drvdata(pdev
);
235 const struct mc13xxx_buttons_platform_data
*pdata
;
237 pdata
= dev_get_platdata(&pdev
->dev
);
239 mc13xxx_lock(priv
->mc13783
);
241 if (pdata
->b3on_flags
& MC13783_BUTTON_ENABLE
)
242 mc13xxx_irq_free(priv
->mc13783
, MC13783_IRQ_ONOFD3
, priv
);
243 if (pdata
->b2on_flags
& MC13783_BUTTON_ENABLE
)
244 mc13xxx_irq_free(priv
->mc13783
, MC13783_IRQ_ONOFD2
, priv
);
245 if (pdata
->b1on_flags
& MC13783_BUTTON_ENABLE
)
246 mc13xxx_irq_free(priv
->mc13783
, MC13783_IRQ_ONOFD1
, priv
);
248 mc13xxx_unlock(priv
->mc13783
);
250 input_unregister_device(priv
->pwr
);
256 static struct platform_driver mc13783_pwrbutton_driver
= {
257 .probe
= mc13783_pwrbutton_probe
,
258 .remove
= mc13783_pwrbutton_remove
,
260 .name
= "mc13783-pwrbutton",
261 .owner
= THIS_MODULE
,
265 module_platform_driver(mc13783_pwrbutton_driver
);
267 MODULE_ALIAS("platform:mc13783-pwrbutton");
268 MODULE_DESCRIPTION("MC13783 Power Button");
269 MODULE_LICENSE("GPL v2");
270 MODULE_AUTHOR("Philippe Retornaz");