added mtd driver
[linux-2.4.git] / drivers / acorn / char / mouse_rpc.c
1 /*
2  *  linux/drivers/char/mouse_rpc.c
3  *
4  *  Copyright (C) 1996-1998 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  This handles the Acorn RiscPCs mouse.  We basically have a couple
11  *  of hardware registers that track the sensor count for the X-Y movement
12  *  and another register holding the button state.  On every VSYNC interrupt
13  *  we read the complete state and then work out if something has changed.
14  */
15 #include <linux/module.h>
16 #include <linux/sched.h>
17 #include <linux/ptrace.h>
18 #include <linux/interrupt.h>
19 #include <linux/init.h>
20
21 #include <asm/hardware.h>
22 #include <asm/irq.h>
23 #include <asm/io.h>
24 #include <asm/hardware/iomd.h>
25
26 #include "../../char/busmouse.h"
27
28 static short old_x, old_y, old_b;
29 static int mousedev;
30
31 void
32 mouse_rpc_irq(int irq, void *dev_id, struct pt_regs *regs)
33 {
34         short x, y, dx, dy;
35         int buttons;
36
37         x = (short)iomd_readl(IOMD_MOUSEX);
38         y = (short)iomd_readl(IOMD_MOUSEY);
39         buttons = (__raw_readl(0xe0310000) >> 4) & 7;
40
41         dx = x - old_x;
42         old_x = x;
43         dy = y - old_y;
44         old_y = y;
45
46         if (dx || dy || buttons != old_b) {
47                 busmouse_add_movementbuttons(mousedev, dx, dy, buttons);
48                 old_b = buttons;
49         }
50 }
51
52 static struct busmouse rpcmouse = {
53         6, "arcmouse", NULL, NULL, NULL, 7
54 };
55
56 static int __init mouse_rpc_init(void)
57 {
58         mousedev = register_busmouse(&rpcmouse);
59
60         if (mousedev < 0)
61                 printk("rpcmouse: could not register mouse driver\n");
62         else {
63                 old_x = (short)iomd_readl(IOMD_MOUSEX);
64                 old_y = (short)iomd_readl(IOMD_MOUSEY);
65                 old_b = (__raw_readl(0xe0310000) >> 4) & 7;
66                 if (request_irq(IRQ_VSYNCPULSE, mouse_rpc_irq, SA_SHIRQ, "mouse", &mousedev)) {
67                         printk("rpcmouse: unable to allocate VSYNC interrupt\n");
68                         unregister_busmouse(mousedev);
69                         mousedev = -1;
70                 }
71         }
72
73         return mousedev >= 0 ? 0 : -ENODEV;
74 }
75
76 static void __exit mouse_rpc_exit(void)
77 {
78         if (mousedev >= 0) {
79                 unregister_busmouse(mousedev);
80                 free_irq(IRQ_VSYNCPULSE, &mousedev);
81         }
82 }
83
84 module_init(mouse_rpc_init);
85 module_exit(mouse_rpc_exit);
86
87 MODULE_AUTHOR("Russell King");
88 MODULE_DESCRIPTION("RiscPC mouse driver");
89 MODULE_LICENSE("GPL");
90 EXPORT_NO_SYMBOLS;