fix IMQ on linux 2.6.27 and 2.6.28
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1013-gta01-inputdevice.patch.patch
1 From 042ef688ad9f49101fcb5a195a5ecdbad8fde2f8 Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 4 Apr 2008 11:31:24 +0100
4 Subject: [PATCH] gta01-inputdevice.patch
5 This provides support for the GTA01 keyboard
6
7 Signed-off-by: Harald Welte <laforge@openmoko.org>
8 ---
9 drivers/input/keyboard/Kconfig | 12 ++
10 drivers/input/keyboard/Makefile | 1 +
11 drivers/input/keyboard/neo1973kbd.c | 242 +++++++++++++++++++++++++++++++++++
12 3 files changed, 255 insertions(+), 0 deletions(-)
13 create mode 100644 drivers/input/keyboard/neo1973kbd.c
14
15 diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
16 index 086d58c..3b9990e 100644
17 --- a/drivers/input/keyboard/Kconfig
18 +++ b/drivers/input/keyboard/Kconfig
19 @@ -293,4 +293,16 @@ config KEYBOARD_BFIN
20 To compile this driver as a module, choose M here: the
21 module will be called bf54x-keys.
22
23 +config KEYBOARD_NEO1973
24 + tristate "FIC Neo1973 buttons"
25 + depends on MACH_NEO1973
26 + default y
27 + help
28 + Say Y here to enable the buttons on the FIC Neo1973
29 + GSM phone.
30 +
31 + To compile this driver as a module, choose M here: the
32 + module will be called neo1973kbd.
33 +
34 +
35 endif
36 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
37 index e97455f..68ecfc5 100644
38 --- a/drivers/input/keyboard/Makefile
39 +++ b/drivers/input/keyboard/Makefile
40 @@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
41 obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
42 obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
43 obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
44 +obj-$(CONFIG_KEYBOARD_NEO1973) += neo1973kbd.o
45 obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
46 obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
47 obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
48 diff --git a/drivers/input/keyboard/neo1973kbd.c b/drivers/input/keyboard/neo1973kbd.c
49 new file mode 100644
50 index 0000000..917d5ae
51 --- /dev/null
52 +++ b/drivers/input/keyboard/neo1973kbd.c
53 @@ -0,0 +1,242 @@
54 +/*
55 + * Keyboard driver for FIC Neo1973 GSM phone
56 + *
57 + * (C) 2006-2007 by OpenMoko, Inc.
58 + * Author: Harald Welte <laforge@openmoko.org>
59 + * All rights reserved.
60 + *
61 + * inspired by corkgbd.c by Richard Purdie
62 + *
63 + * This program is free software; you can redistribute it and/or modify
64 + * it under the terms of the GNU General Public License version 2 as
65 + * published by the Free Software Foundation.
66 + *
67 + */
68 +
69 +#include <linux/delay.h>
70 +#include <linux/platform_device.h>
71 +#include <linux/init.h>
72 +#include <linux/input.h>
73 +#include <linux/interrupt.h>
74 +#include <linux/jiffies.h>
75 +#include <linux/module.h>
76 +#include <linux/slab.h>
77 +
78 +#include <asm/hardware.h>
79 +#include <asm/arch/gta01.h>
80 +#include <asm/mach-types.h>
81 +
82 +struct neo1973kbd {
83 + struct input_dev *input;
84 + unsigned int suspended;
85 + unsigned long suspend_jiffies;
86 +};
87 +
88 +static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev_id)
89 +{
90 + struct neo1973kbd *neo1973kbd_data = dev_id;
91 +
92 + /* FIXME: use GPIO from platform_dev resources */
93 + if (s3c2410_gpio_getpin(GTA01_GPIO_AUX_KEY))
94 + input_report_key(neo1973kbd_data->input, KEY_PHONE, 0);
95 + else
96 + input_report_key(neo1973kbd_data->input, KEY_PHONE, 1);
97 +
98 + input_sync(neo1973kbd_data->input);
99 +
100 + return IRQ_HANDLED;
101 +}
102 +
103 +static irqreturn_t neo1973kbd_hold_irq(int irq, void *dev_id)
104 +{
105 + struct neo1973kbd *neo1973kbd_data = dev_id;
106 +
107 + /* FIXME: use GPIO from platform_dev resources */
108 + if (s3c2410_gpio_getpin(GTA01_GPIO_HOLD_KEY))
109 + input_report_key(neo1973kbd_data->input, KEY_PAUSE, 1);
110 + else
111 + input_report_key(neo1973kbd_data->input, KEY_PAUSE, 0);
112 +
113 + input_sync(neo1973kbd_data->input);
114 +
115 + return IRQ_HANDLED;
116 +}
117 +
118 +static irqreturn_t neo1973kbd_headphone_irq(int irq, void *dev_id)
119 +{
120 + struct neo1973kbd *neo1973kbd_data = dev_id;
121 +
122 + /* FIXME: use GPIO from platform_dev resources */
123 + if (s3c2410_gpio_getpin(GTA01_GPIO_JACK_INSERT))
124 + input_report_switch(neo1973kbd_data->input,
125 + SW_HEADPHONE_INSERT, 1);
126 + else
127 + input_report_switch(neo1973kbd_data->input,
128 + SW_HEADPHONE_INSERT, 0);
129 +
130 + input_sync(neo1973kbd_data->input);
131 +
132 + return IRQ_HANDLED;
133 +}
134 +
135 +#ifdef CONFIG_PM
136 +static int neo1973kbd_suspend(struct platform_device *dev, pm_message_t state)
137 +{
138 + struct neo1973kbd *neo1973kbd = platform_get_drvdata(dev);
139 +
140 + neo1973kbd->suspended = 1;
141 +
142 + return 0;
143 +}
144 +
145 +static int neo1973kbd_resume(struct platform_device *dev)
146 +{
147 + struct neo1973kbd *neo1973kbd = platform_get_drvdata(dev);
148 +
149 + neo1973kbd->suspended = 0;
150 +
151 + return 0;
152 +}
153 +#else
154 +#define neo1973kbd_suspend NULL
155 +#define neo1973kbd_resume NULL
156 +#endif
157 +
158 +static int neo1973kbd_probe(struct platform_device *pdev)
159 +{
160 + struct neo1973kbd *neo1973kbd;
161 + struct input_dev *input_dev;
162 + int rc, irq_aux, irq_hold, irq_jack;
163 +
164 + neo1973kbd = kzalloc(sizeof(struct neo1973kbd), GFP_KERNEL);
165 + input_dev = input_allocate_device();
166 + if (!neo1973kbd || !input_dev) {
167 + kfree(neo1973kbd);
168 + input_free_device(input_dev);
169 + return -ENOMEM;
170 + }
171 +
172 + if (pdev->resource[0].flags != 0)
173 + return -EINVAL;
174 +
175 + irq_aux = s3c2410_gpio_getirq(pdev->resource[0].start);
176 + if (irq_aux < 0)
177 + return -EINVAL;
178 +
179 + irq_hold = s3c2410_gpio_getirq(pdev->resource[1].start);
180 + if (irq_hold < 0)
181 + return -EINVAL;
182 +
183 + irq_jack = s3c2410_gpio_getirq(pdev->resource[2].start);
184 + if (irq_jack < 0)
185 + return -EINVAL;
186 +
187 + platform_set_drvdata(pdev, neo1973kbd);
188 +
189 + neo1973kbd->input = input_dev;
190 +
191 + input_dev->name = "Neo1973 Buttons";
192 + input_dev->phys = "neo1973kbd/input0";
193 + input_dev->id.bustype = BUS_HOST;
194 + input_dev->id.vendor = 0x0001;
195 + input_dev->id.product = 0x0001;
196 + input_dev->id.version = 0x0100;
197 + input_dev->cdev.dev = &pdev->dev;
198 + input_dev->private = neo1973kbd;
199 +
200 + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_SW);
201 + set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
202 + set_bit(KEY_PHONE, input_dev->keybit);
203 + set_bit(KEY_PAUSE, input_dev->keybit);
204 +
205 + rc = input_register_device(neo1973kbd->input);
206 + if (rc)
207 + goto out_register;
208 +
209 + if (request_irq(irq_aux, neo1973kbd_aux_irq, IRQF_DISABLED |
210 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
211 + "Neo1973 AUX button", neo1973kbd)) {
212 + dev_err(&pdev->dev, "Can't get IRQ %u\n", irq_aux);
213 + goto out_aux;
214 + }
215 +
216 + /*
217 + * GTA01 revisions before Bv4 can't be resumed by the PMU, so we use
218 + * resume by AUX.
219 + */
220 + if (machine_is_neo1973_gta01())
221 + enable_irq_wake(irq_aux);
222 +
223 + if (request_irq(irq_hold, neo1973kbd_hold_irq, IRQF_DISABLED |
224 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
225 + "Neo1973 HOLD button", neo1973kbd)) {
226 + dev_err(&pdev->dev, "Can't get IRQ %u\n", irq_hold);
227 + goto out_hold;
228 + }
229 +
230 + if (request_irq(irq_jack, neo1973kbd_headphone_irq, IRQF_DISABLED |
231 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
232 + "Neo1973 Headphone Jack", neo1973kbd)) {
233 + dev_err(&pdev->dev, "Can't get IRQ %u\n", irq_jack);
234 + goto out_jack;
235 + }
236 + enable_irq_wake(irq_jack);
237 +
238 + return 0;
239 +
240 +out_jack:
241 + free_irq(irq_hold, neo1973kbd);
242 +out_hold:
243 + free_irq(irq_aux, neo1973kbd);
244 +out_aux:
245 + input_unregister_device(neo1973kbd->input);
246 +out_register:
247 + input_free_device(neo1973kbd->input);
248 + platform_set_drvdata(pdev, NULL);
249 + kfree(neo1973kbd);
250 +
251 + return -ENODEV;
252 +}
253 +
254 +static int neo1973kbd_remove(struct platform_device *pdev)
255 +{
256 + struct neo1973kbd *neo1973kbd = platform_get_drvdata(pdev);
257 +
258 + free_irq(s3c2410_gpio_getirq(pdev->resource[2].start), neo1973kbd);
259 + free_irq(s3c2410_gpio_getirq(pdev->resource[1].start), neo1973kbd);
260 + free_irq(s3c2410_gpio_getirq(pdev->resource[0].start), neo1973kbd);
261 +
262 + input_unregister_device(neo1973kbd->input);
263 + input_free_device(neo1973kbd->input);
264 + platform_set_drvdata(pdev, NULL);
265 + kfree(neo1973kbd);
266 +
267 + return 0;
268 +}
269 +
270 +static struct platform_driver neo1973kbd_driver = {
271 + .probe = neo1973kbd_probe,
272 + .remove = neo1973kbd_remove,
273 + .suspend = neo1973kbd_suspend,
274 + .resume = neo1973kbd_resume,
275 + .driver = {
276 + .name = "neo1973-button",
277 + },
278 +};
279 +
280 +static int __devinit neo1973kbd_init(void)
281 +{
282 + return platform_driver_register(&neo1973kbd_driver);
283 +}
284 +
285 +static void __exit neo1973kbd_exit(void)
286 +{
287 + platform_driver_unregister(&neo1973kbd_driver);
288 +}
289 +
290 +module_init(neo1973kbd_init);
291 +module_exit(neo1973kbd_exit);
292 +
293 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
294 +MODULE_DESCRIPTION("FIC Neo1973 buttons input driver");
295 +MODULE_LICENSE("GPL");
296 --
297 1.5.6.5
298
This page took 0.053976 seconds and 5 git commands to generate.