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
7 Signed-off-by: Harald Welte <laforge@openmoko.org>
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
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.
23 +config KEYBOARD_NEO1973
24 + tristate "FIC Neo1973 buttons"
25 + depends on MACH_NEO1973
28 + Say Y here to enable the buttons on the FIC Neo1973
31 + To compile this driver as a module, choose M here: the
32 + module will be called neo1973kbd.
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
50 index 0000000..917d5ae
52 +++ b/drivers/input/keyboard/neo1973kbd.c
55 + * Keyboard driver for FIC Neo1973 GSM phone
57 + * (C) 2006-2007 by OpenMoko, Inc.
58 + * Author: Harald Welte <laforge@openmoko.org>
59 + * All rights reserved.
61 + * inspired by corkgbd.c by Richard Purdie
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.
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>
78 +#include <asm/hardware.h>
79 +#include <asm/arch/gta01.h>
80 +#include <asm/mach-types.h>
83 + struct input_dev *input;
84 + unsigned int suspended;
85 + unsigned long suspend_jiffies;
88 +static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev_id)
90 + struct neo1973kbd *neo1973kbd_data = dev_id;
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);
96 + input_report_key(neo1973kbd_data->input, KEY_PHONE, 1);
98 + input_sync(neo1973kbd_data->input);
100 + return IRQ_HANDLED;
103 +static irqreturn_t neo1973kbd_hold_irq(int irq, void *dev_id)
105 + struct neo1973kbd *neo1973kbd_data = dev_id;
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);
111 + input_report_key(neo1973kbd_data->input, KEY_PAUSE, 0);
113 + input_sync(neo1973kbd_data->input);
115 + return IRQ_HANDLED;
118 +static irqreturn_t neo1973kbd_headphone_irq(int irq, void *dev_id)
120 + struct neo1973kbd *neo1973kbd_data = dev_id;
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);
127 + input_report_switch(neo1973kbd_data->input,
128 + SW_HEADPHONE_INSERT, 0);
130 + input_sync(neo1973kbd_data->input);
132 + return IRQ_HANDLED;
136 +static int neo1973kbd_suspend(struct platform_device *dev, pm_message_t state)
138 + struct neo1973kbd *neo1973kbd = platform_get_drvdata(dev);
140 + neo1973kbd->suspended = 1;
145 +static int neo1973kbd_resume(struct platform_device *dev)
147 + struct neo1973kbd *neo1973kbd = platform_get_drvdata(dev);
149 + neo1973kbd->suspended = 0;
154 +#define neo1973kbd_suspend NULL
155 +#define neo1973kbd_resume NULL
158 +static int neo1973kbd_probe(struct platform_device *pdev)
160 + struct neo1973kbd *neo1973kbd;
161 + struct input_dev *input_dev;
162 + int rc, irq_aux, irq_hold, irq_jack;
164 + neo1973kbd = kzalloc(sizeof(struct neo1973kbd), GFP_KERNEL);
165 + input_dev = input_allocate_device();
166 + if (!neo1973kbd || !input_dev) {
168 + input_free_device(input_dev);
172 + if (pdev->resource[0].flags != 0)
175 + irq_aux = s3c2410_gpio_getirq(pdev->resource[0].start);
179 + irq_hold = s3c2410_gpio_getirq(pdev->resource[1].start);
183 + irq_jack = s3c2410_gpio_getirq(pdev->resource[2].start);
187 + platform_set_drvdata(pdev, neo1973kbd);
189 + neo1973kbd->input = input_dev;
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;
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);
205 + rc = input_register_device(neo1973kbd->input);
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);
217 + * GTA01 revisions before Bv4 can't be resumed by the PMU, so we use
220 + if (machine_is_neo1973_gta01())
221 + enable_irq_wake(irq_aux);
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);
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);
236 + enable_irq_wake(irq_jack);
241 + free_irq(irq_hold, neo1973kbd);
243 + free_irq(irq_aux, neo1973kbd);
245 + input_unregister_device(neo1973kbd->input);
247 + input_free_device(neo1973kbd->input);
248 + platform_set_drvdata(pdev, NULL);
254 +static int neo1973kbd_remove(struct platform_device *pdev)
256 + struct neo1973kbd *neo1973kbd = platform_get_drvdata(pdev);
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);
262 + input_unregister_device(neo1973kbd->input);
263 + input_free_device(neo1973kbd->input);
264 + platform_set_drvdata(pdev, NULL);
270 +static struct platform_driver neo1973kbd_driver = {
271 + .probe = neo1973kbd_probe,
272 + .remove = neo1973kbd_remove,
273 + .suspend = neo1973kbd_suspend,
274 + .resume = neo1973kbd_resume,
276 + .name = "neo1973-button",
280 +static int __devinit neo1973kbd_init(void)
282 + return platform_driver_register(&neo1973kbd_driver);
285 +static void __exit neo1973kbd_exit(void)
287 + platform_driver_unregister(&neo1973kbd_driver);
290 +module_init(neo1973kbd_init);
291 +module_exit(neo1973kbd_exit);
293 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
294 +MODULE_DESCRIPTION("FIC Neo1973 buttons input driver");
295 +MODULE_LICENSE("GPL");