2 * Input driver for Rover P1.
3 * Based on Input driver for Dell Axim X5.
4 * Creates input events for the buttons on the device
6 * Copyright 2004 Matthew Garrett
7 * Konstantine A. Beklemishev
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for
14 #include <linux/input.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/interrupt.h>
19 #include <asm/mach/arch.h>
20 #include <asm/mach/map.h>
21 #include <asm/mach-types.h>
22 #include <asm/hardware.h>
23 #include <asm/arch/irqs.h>
24 #include <asm/arch/roverp1-gpio.h>
26 #define GET_GPIO(gpio) (GPLR(gpio) & GPIO_bit(gpio))
28 struct input_dev button_dev
;
29 static volatile int joypad_event_count
;
30 static wait_queue_head_t joypad_event
;
31 struct completion thread_comp
;
32 static volatile int must_die
;
33 /* Current joystick state bits: ENTER (bit 0), UP (1), RIGHT, DOWN, LEFT */
42 #define KEY_DEF(x) ROVERP1_IRQ (x), GPIO_NR_ROVERP1_##x
43 { KEY_SLEEP
, KEY_DEF (POWER_BTN
), "Sleep button" },
44 { KEY_RECORD
, KEY_DEF (REC_BTN
), "Record button" },
45 { KEY_CALENDAR
, KEY_DEF (CALENDAR
), "Calendar button" },
46 { KEY_CONTACTS
, KEY_DEF (CONTACTS
), "Contacts button" },
47 { KEY_MEMO
, KEY_DEF (MEMO
), "Memo button" },
48 { KEY_TASK
, KEY_DEF (TASK
), "Task button" },
52 static u8 joyirq
[] = {
53 ROVERP1_IRQ (JOG_ENTER
),
55 ROVERP1_IRQ (JOG_DOWN
),
56 ROVERP1_IRQ (JOG_LEFT
),
57 ROVERP1_IRQ (JOG_RIGHT
),
60 static char *joyirqdesc
[] =
69 /* This table is used to convert 4-bit joystick state into key indices.
70 * If the bit combination have no logical meaning (say NW/SE are set at
71 * the same time), we default to 0 (e.g. KEY_SELECT). At any given time
72 * joystick cannot generate more than two pressed keys. So we're using
73 * the lower nibble for key index 1 and upper nibble for key index 2
74 * (if upper nibble is f, the particular bit combination generates just
75 * one key press). Also note that a bit value of '0' means key is pressed,
76 * while '1' means key is not pressed.
78 static u8 joydecode
[16] = {
97 /* This table is used to convert key indices into actual key codes.
99 static u16 joykeycode
[5] = {
107 irqreturn_t
roverp1_button_handle (int irq
, void *dev_id
, struct pt_regs
*regs
)
111 /* look up the keyno */
112 for (button
= 0; button
< ARRAY_SIZE (buttontab
); button
++)
113 if (buttontab
[button
].irq
== irq
)
116 /* This happens with 100% probability */
117 if (likely (button
< ARRAY_SIZE (buttontab
))) {
118 down
= GET_GPIO (buttontab
[button
].gpio
) ? 1 : 0;
119 if (buttontab
[button
].keyno
== KEY_SLEEP
)
121 input_report_key (&button_dev
, buttontab
[button
].keyno
, down
);
122 /* printk(KERN_INFO "%s button %d\n", (down ? "Pushed" : "Released"), button ); */
123 input_sync (&button_dev
);
129 irqreturn_t
roverp1_joy_handle (int irq
, void* dev_id
, struct pt_regs
*regs
)
131 joypad_event_count
++;
132 wake_up_interruptible (&joypad_event
);
136 static void joypad_decode (void)
138 u32 i
, code
, newstate
;
140 /* Decode current joystick bit combination */
141 code
= joydecode
[GPIO_JOY_DIR
];
143 newstate
= GET_ROVERP1_GPIO (JOG_ENTER
) ? 0 :
144 ((1 << (code
& 15)) | (1 << (code
>> 4)));
145 /* We're not interested in other bits (e.g. 1 << 0xf) */
148 /* Find out which bits have changed */
149 joystate
^= newstate
;
150 for (i
= 0; i
<= 5; i
++)
151 if (joystate
& (1 << i
)) {
152 int down
= (newstate
& (1 << i
)) ? 1 : 0;
153 input_report_key (&button_dev
, joykeycode
[i
], down
);
154 input_sync (&button_dev
);
157 /* printk(KERN_INFO "Keys state: %02x\n", joystate); */
160 static int joypad_thread (void *arg
)
164 daemonize ("kjoypad");
165 set_user_nice (current
, 5);
173 old_count
= joypad_event_count
;
174 wait_event_interruptible (joypad_event
, old_count
!= joypad_event_count
);
180 old_count
= joypad_event_count
;
181 set_current_state (TASK_INTERRUPTIBLE
);
182 schedule_timeout (HZ
/50);
183 } while (old_count
!= joypad_event_count
);
186 complete_and_exit (&thread_comp
, 0);
189 static int __init
roverp1_button_init (void)
196 set_bit (EV_KEY
, button_dev
.evbit
);
198 /* Joystick emmits UP/DOWN/LEFT/RIGHT/SELECT key events */
199 button_dev
.keybit
[LONG (KEY_UP
)] |= BIT (KEY_UP
);
200 button_dev
.keybit
[LONG (KEY_DOWN
)] |= BIT (KEY_DOWN
);
201 button_dev
.keybit
[LONG (KEY_LEFT
)] |= BIT (KEY_LEFT
);
202 button_dev
.keybit
[LONG (KEY_RIGHT
)] |= BIT (KEY_RIGHT
);
203 button_dev
.keybit
[LONG (KEY_SELECT
)] |= BIT (KEY_SELECT
);
205 for (i
= 0; i
< ARRAY_SIZE (buttontab
); i
++) {
206 request_irq (buttontab
[i
].irq
, roverp1_button_handle
,
207 SA_SAMPLE_RANDOM
, buttontab
[i
].desc
, NULL
);
208 set_irq_type (buttontab
[i
].irq
, IRQT_BOTHEDGE
);
209 button_dev
.keybit
[LONG (buttontab
[i
].keyno
)] =
210 BIT (buttontab
[i
].keyno
);
213 for (i
= 0; i
< ARRAY_SIZE (joyirq
); i
++) {
214 request_irq (joyirq
[i
], roverp1_joy_handle
,
215 SA_SAMPLE_RANDOM
, joyirqdesc
[i
], NULL
);
216 set_irq_type (joyirq
[i
], IRQT_BOTHEDGE
);
219 button_dev
.name
= "Rover P1 buttons driver";
220 input_register_device (&button_dev
);
222 init_waitqueue_head (&joypad_event
);
223 init_completion (&thread_comp
);
224 kernel_thread (joypad_thread
, NULL
, 0);
226 printk (KERN_INFO
"%s installed\n", button_dev
.name
);
231 static void __exit
roverp1_button_exit (void)
235 /* First of all, kill kthread */
237 joypad_event_count
++;
238 wake_up_interruptible (&joypad_event
);
239 wait_for_completion (&thread_comp
);
241 input_unregister_device (&button_dev
);
243 for (i
= 0; i
< ARRAY_SIZE (joyirq
); i
++)
244 free_irq (joyirq
[i
], NULL
);
246 for (i
= 0; i
< ARRAY_SIZE (buttontab
); i
++)
247 free_irq (buttontab
[i
].irq
, NULL
);
250 module_init (roverp1_button_init
);
251 module_exit (roverp1_button_exit
);
253 MODULE_AUTHOR ("Konstantine A. Beklemishev <konstantine .at. r66 .dot. ru>");
254 MODULE_DESCRIPTION ("Button support for Rover P1");
255 MODULE_LICENSE ("GPL");