1/* 2 * Macintosh ADB Mouse driver for Linux 3 * 4 * 27 Oct 1997 Michael Schmitz 5 * logitech fixes by anthony tong 6 * further hacking by Paul Mackerras 7 * 8 * Apple mouse protocol according to: 9 * 10 * Device code shamelessly stolen from: 11 */ 12/* 13 * Atari Mouse Driver for Linux 14 * by Robert de Vries (robert@and.nl) 19Jul93 15 * 16 * 16 Nov 1994 Andreas Schwab 17 * Compatibility with busmouse 18 * Support for three button mouse (shamelessly stolen from MiNT) 19 * third button wired to one of the joystick directions on joystick 1 20 * 21 * 1996/02/11 Andreas Schwab 22 * Module support 23 * Allow multiple open's 24 * 25 * Converted to use new generic busmouse code. 11 July 1998 26 * Russell King <rmk@arm.uk.linux.org> 27 */ 28 29#include <linux/module.h> 30 31#include <linux/sched.h> 32#include <linux/errno.h> 33#include <linux/miscdevice.h> 34#include <linux/mm.h> 35#include <linux/random.h> 36#include <linux/poll.h> 37#include <linux/init.h> 38#include <linux/adb_mouse.h> 39 40#ifdef __powerpc__ 41#include <asm/processor.h> 42#endif 43#if defined(__mc68000__) || defined(MODULE) 44#include <asm/setup.h> 45#endif 46 47#include "busmouse.h" 48 49static int msedev; 50static unsigned char adb_mouse_buttons[16]; 51 52extern void (*adb_mouse_interrupt_hook)(unsigned char *, int); 53extern int adb_emulate_buttons; 54extern int adb_button2_keycode; 55extern int adb_button3_keycode; 56 57static void adb_mouse_interrupt(unsigned char *buf, int nb) 58{ 59 int buttons, id; 60 char dx, dy; 61 62 /* 63 Handler 1 -- 100cpi original Apple mouse protocol. 64 Handler 2 -- 200cpi original Apple mouse protocol. 65 66 For Apple's standard one-button mouse protocol the data array will 67 contain the following values: 68 69 BITS COMMENTS 70 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. 71 data[1] = bxxx xxxx First button and x-axis motion. 72 data[2] = byyy yyyy Second button and y-axis motion. 73 74 Handler 4 -- Apple Extended mouse protocol. 75 76 For Apple's 3-button mouse protocol the data array will contain the 77 following values: 78 79 BITS COMMENTS 80 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd. 81 data[1] = bxxx xxxx Left button and x-axis motion. 82 data[2] = byyy yyyy Second button and y-axis motion. 83 data[3] = byyy bxxx Third button and fourth button. 84 Y is additiona. high bits of y-axis motion. 85 X is additional high bits of x-axis motion. 86 87 'buttons' here means 'button down' states! 88 Button 1 (left) : bit 2, busmouse button 3 89 Button 2 (right) : bit 0, busmouse button 1 90 Button 3 (middle): bit 1, busmouse button 2 91 */ 92 93 /* x/y and buttons swapped */ 94 95 id = (buf[0] >> 4) & 0xf; 96 97 buttons = adb_mouse_buttons[id]; 98 99 /* button 1 (left, bit 2) */ 100 buttons = (buttons & 3) | (buf[1] & 0x80 ? 4 : 0); /* 1+2 unchanged */ 101 102 /* button 2 (middle) */ 103 buttons = (buttons & 5) | (buf[2] & 0x80 ? 2 : 0); /* 2+3 unchanged */ 104 105 /* button 3 (right) present? 106 * on a logitech mouseman, the right and mid buttons sometimes behave 107 * strangely until they both have been pressed after booting. */ 108 /* data valid only if extended mouse format ! */ 109 if (nb >= 4) 110 buttons = (buttons & 6) | (buf[3] & 0x80 ? 1 : 0); /* 1+3 unchanged */ 111 112 adb_mouse_buttons[id] = buttons; 113 114 /* a button is down if it is down on any mouse */ 115 for (id = 0; id < 16; ++id) 116 buttons &= adb_mouse_buttons[id]; 117 118 dx = ((buf[2] & 0x7f) < 64 ? (buf[2] & 0x7f) : (buf[2] & 0x7f) - 128); 119 dy = ((buf[1] & 0x7f) < 64 ? (buf[1] & 0x7f) : (buf[1] & 0x7f) - 128); 120 busmouse_add_movementbuttons(msedev, dx, -dy, buttons); 121 122 if (console_loglevel >= 8) 123 printk(" %X %X %X dx %d dy %d \n", 124 buf[1], buf[2], buf[3], dx, dy); 125} 126 127static int release_mouse(struct inode *inode, struct file *file) 128{ 129 adb_mouse_interrupt_hook = NULL; 130 return 0; 131} 132 133static int open_mouse(struct inode *inode, struct file *file) 134{ 135 adb_mouse_interrupt_hook = adb_mouse_interrupt; 136 return 0; 137} 138 139static struct busmouse adb_mouse = 140{ 141 ADB_MOUSE_MINOR, "adbmouse", THIS_MODULE, open_mouse, release_mouse, 7 142}; 143 144static int __init adb_mouse_init(void) 145{ 146#ifdef __powerpc__ 147 if ((_machine != _MACH_chrp) && (_machine != _MACH_Pmac)) 148 return -ENODEV; 149#endif 150#ifdef __mc68000__ 151 if (!MACH_IS_MAC) 152 return -ENODEV; 153#endif 154 /* all buttons up */ 155 memset(adb_mouse_buttons, 7, sizeof(adb_mouse_buttons)); 156 157 msedev = register_busmouse(&adb_mouse); 158 if (msedev < 0) 159 printk(KERN_WARNING "Unable to register ADB mouse driver.\n"); 160 else 161 printk(KERN_INFO "Macintosh ADB mouse driver installed.\n"); 162 163 return msedev < 0 ? msedev : 0; 164} 165 166#ifndef MODULE 167 168static int __init adb_mouse_setup(char *str) 169{ 170 int ints[4]; 171 172 str = get_options(str, ARRAY_SIZE(ints), ints); 173 if (ints[0] >= 1) { 174 adb_emulate_buttons = ints[1]; 175 if (ints[0] >= 2) 176 adb_button2_keycode = ints[2]; 177 if (ints[0] >= 3) 178 adb_button3_keycode = ints[3]; 179 } 180 return 1; 181} 182 183__setup("adb_buttons=", adb_mouse_setup); 184 185#endif /* !MODULE */ 186 187static void __exit adb_mouse_cleanup(void) 188{ 189 unregister_busmouse(msedev); 190} 191 192module_init(adb_mouse_init); 193module_exit(adb_mouse_cleanup); 194 195MODULE_LICENSE("GPL"); 196