hh.org updates
[hh.org.git] / arch / arm / mach-pxa / asus730 / a730_joypad.c
blob96c9370c21030c7f263c88680d7fc9251cb9f202
1 /*
2 * based on arch/arm/mach-pxa/pxa_keys.c
3 * and on arch/arm/mach-pxa/asus716/a716_buttons.c
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * 03 Apr 2006:
10 * Serge Nikolaenko split a730_keys.c to a730_buttons.c & a730_joupad.c
13 #include <linux/input.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/interrupt.h>
17 #include <linux/irq.h>
19 #include <asm/mach-types.h>
20 #include <asm/mach/arch.h>
21 #include <asm/mach/map.h>
22 #include <asm/mach-types.h>
23 #include <asm/hardware.h>
24 #include <asm/arch/pxa-regs.h>
25 #include <asm/arch/irqs.h>
26 #include <asm/arch/asus730-gpio.h>
28 #include <linux/platform_device.h>
30 static struct workqueue_struct *a730_pca9535_workqueue;
31 static struct work_struct a730_pca9535_irq_task;
32 static DECLARE_MUTEX_LOCKED(pca_mutex);
34 #define GET_GPIO(gpio) (GPLR(gpio) & GPIO_bit(gpio))
35 #define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
37 //static int __init a730_joy_probe(struct device *dev);
38 static int a730_joy_suspend(struct device *dev, pm_message_t state);
39 static int a730_joy_resume(struct device *dev);
41 /*static struct device_driver a730_joystick_driver = {
42 .name = "a730_joystick",
43 .bus = &platform_bus_type,
44 .probe = a730_joy_probe,
45 #ifdef CONFIG_PM
46 .suspend = a730_joy_suspend,
47 .resume = a730_joy_resume,
48 #endif
49 };*/
51 static struct input_dev *joy_dev = NULL;
53 u32 pca9535_read_input(void);//pca9535.ko
55 static struct
57 int keycode;
58 int mask;
59 char *desc;
60 } joypad[] =
62 {KEY_UP, 0x01, "UP"},
63 {KEY_RIGHT, 0x02, "RIGHT"},
64 {KEY_DOWN, 0x04, "DOWN"},
65 {KEY_LEFT, 0x08, "LEFT"},
66 {KEY_ENTER, 0x10, "PUSH"},
69 static u32 joypad_prev;
71 static void a730_pca9535_handler(void *dummy)
73 u32 dd, data, bits_changed;
74 int i;
76 dd = data = pca9535_read_input();
78 if (data == (u32)-1) return;
80 data = (~(data >> 8) & 0x1f);
81 bits_changed = joypad_prev ^ data;
83 if (!bits_changed)
85 DPRINTK("!bits_changed E=%d D=%d 4=%d 2=%d 1=%d\n", (dd>>14)&1,(dd>>13)&1,(dd>>4)&1,(dd>>2)&1,(dd>>1)&1);
86 return;
89 for (i = 0; i < ARRAY_SIZE(joypad); i++)
91 if (bits_changed & joypad[i].mask)
93 int state = ((bits_changed & data) != 0);
94 //printk("desc=%s %s\n", joypad[i].desc, (state ? "P" : "R"));
95 input_report_key(joy_dev, joypad[i].keycode, state);
98 input_sync(joy_dev);
99 joypad_prev = data;
100 up(&pca_mutex);
101 return;
104 static irqreturn_t a730_joy_handle(int irq, void *dev_id, struct pt_regs *regs)
106 if (!down_trylock(&pca_mutex)) queue_work(a730_pca9535_workqueue, &a730_pca9535_irq_task);
107 return IRQ_HANDLED;
110 /*static int __init a730_joy_probe(struct device *dev)
112 return 0;
115 static int __init a730_joy_init(void)
117 int irqflag = IRQF_DISABLED;
118 #ifdef CONFIG_PREEMPT_RT
119 irqflag |= IRQF_NODELAY;
120 #endif
121 if (!machine_is_a730()) return -ENODEV;
123 if (!(joy_dev = input_allocate_device())) return -ENOMEM;
125 joy_dev->name = "Asus MyPal 730(W) joypad";
126 joy_dev->id.bustype = BUS_I2C;
127 joy_dev->phys = "a730joy/input0";
129 set_bit(EV_KEY, joy_dev->evbit);
131 joy_dev->keybit[LONG(KEY_UP)] |= BIT(KEY_UP);
132 joy_dev->keybit[LONG(KEY_DOWN)] |= BIT(KEY_DOWN);
133 joy_dev->keybit[LONG(KEY_LEFT)] |= BIT(KEY_LEFT);
134 joy_dev->keybit[LONG(KEY_RIGHT)] |= BIT(KEY_RIGHT);
135 joy_dev->keybit[LONG(KEY_ENTER)] |= BIT(KEY_ENTER);
137 request_irq(A730_IRQ(PCA9535_IRQ), a730_joy_handle, irqflag, "Joystick", NULL);
138 set_irq_type(A730_IRQ(PCA9535_IRQ), IRQF_TRIGGER_FALLING);
140 input_register_device(joy_dev);
142 a730_pca9535_workqueue = create_singlethread_workqueue("joypad");
143 INIT_WORK(&a730_pca9535_irq_task, a730_pca9535_handler, NULL);
145 up(&pca_mutex);
146 return 0;
149 static void __exit a730_joy_exit(void)
151 input_unregister_device(joy_dev);
152 free_irq(A730_IRQ(PCA9535_IRQ), NULL);
153 input_free_device(joy_dev);
156 static int a730_joy_suspend(struct device *dev, pm_message_t state)
158 //disable_irq(A730_IRQ(PCA9535_IRQ));
159 return 0;
162 static int a730_joy_resume(struct device *dev)
164 //enable_irq(A730_IRQ(PCA9535_IRQ));
165 return 0;
168 module_init(a730_joy_init);
169 module_exit(a730_joy_exit);
171 MODULE_LICENSE("GPL");
172 MODULE_AUTHOR("Michal Sroczynski <msroczyn@elka.pw.edu.pl>");
173 MODULE_DESCRIPTION("Keyboard driver for Asus MyPal 730");