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.
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,
46 .suspend = a730_joy_suspend,
47 .resume = a730_joy_resume,
51 static struct input_dev
*joy_dev
= NULL
;
53 u32
pca9535_read_input(void);//pca9535.ko
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
;
76 dd
= data
= pca9535_read_input();
78 if (data
== (u32
)-1) return;
80 data
= (~(data
>> 8) & 0x1f);
81 bits_changed
= joypad_prev
^ data
;
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);
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
);
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
);
110 /*static int __init a730_joy_probe(struct device *dev)
115 static int __init
a730_joy_init(void)
117 int irqflag
= IRQF_DISABLED
;
118 #ifdef CONFIG_PREEMPT_RT
119 irqflag
|= IRQF_NODELAY
;
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
);
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));
162 static int a730_joy_resume(struct device
*dev
)
164 //enable_irq(A730_IRQ(PCA9535_IRQ));
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");