11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Amiga mouse driver for Linux/m68k 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (c) 2000-2002 Vojtech Pavlik 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Based on the work of: 71da177e4SLinus Torvalds * Michael Rausch James Banks 81da177e4SLinus Torvalds * Matther Dillon David Giller 91da177e4SLinus Torvalds * Nathan Laredo Linus Torvalds 101da177e4SLinus Torvalds * Johan Myreen Jes Sorensen 111da177e4SLinus Torvalds * Russell King 121da177e4SLinus Torvalds */ 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds /* 151da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify it 161da177e4SLinus Torvalds * under the terms of the GNU General Public License version 2 as published by 171da177e4SLinus Torvalds * the Free Software Foundation 181da177e4SLinus Torvalds */ 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds #include <linux/module.h> 211da177e4SLinus Torvalds #include <linux/init.h> 221da177e4SLinus Torvalds #include <linux/input.h> 231da177e4SLinus Torvalds #include <linux/interrupt.h> 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds #include <asm/irq.h> 261da177e4SLinus Torvalds #include <asm/setup.h> 271da177e4SLinus Torvalds #include <asm/system.h> 281da177e4SLinus Torvalds #include <asm/uaccess.h> 291da177e4SLinus Torvalds #include <asm/amigahw.h> 301da177e4SLinus Torvalds #include <asm/amigaints.h> 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 331da177e4SLinus Torvalds MODULE_DESCRIPTION("Amiga mouse driver"); 341da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds static int amimouse_lastx, amimouse_lasty; 372e5b636bSDmitry Torokhov static struct input_dev *amimouse_dev; 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) 401da177e4SLinus Torvalds { 411da177e4SLinus Torvalds unsigned short joy0dat, potgor; 421da177e4SLinus Torvalds int nx, ny, dx, dy; 431da177e4SLinus Torvalds 44b4290a23SAl Viro joy0dat = amiga_custom.joy0dat; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds nx = joy0dat & 0xff; 471da177e4SLinus Torvalds ny = joy0dat >> 8; 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds dx = nx - amimouse_lastx; 501da177e4SLinus Torvalds dy = ny - amimouse_lasty; 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds if (dx < -127) dx = (256 + nx) - amimouse_lastx; 531da177e4SLinus Torvalds if (dx > 127) dx = (nx - 256) - amimouse_lastx; 541da177e4SLinus Torvalds if (dy < -127) dy = (256 + ny) - amimouse_lasty; 551da177e4SLinus Torvalds if (dy > 127) dy = (ny - 256) - amimouse_lasty; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds amimouse_lastx = nx; 581da177e4SLinus Torvalds amimouse_lasty = ny; 591da177e4SLinus Torvalds 60b4290a23SAl Viro potgor = amiga_custom.potgor; 611da177e4SLinus Torvalds 622e5b636bSDmitry Torokhov input_regs(amimouse_dev, fp); 631da177e4SLinus Torvalds 642e5b636bSDmitry Torokhov input_report_rel(amimouse_dev, REL_X, dx); 652e5b636bSDmitry Torokhov input_report_rel(amimouse_dev, REL_Y, dy); 661da177e4SLinus Torvalds 672e5b636bSDmitry Torokhov input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); 682e5b636bSDmitry Torokhov input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100); 692e5b636bSDmitry Torokhov input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400); 701da177e4SLinus Torvalds 712e5b636bSDmitry Torokhov input_sync(amimouse_dev); 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds return IRQ_HANDLED; 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds static int amimouse_open(struct input_dev *dev) 771da177e4SLinus Torvalds { 781da177e4SLinus Torvalds unsigned short joy0dat; 791da177e4SLinus Torvalds 80b4290a23SAl Viro joy0dat = amiga_custom.joy0dat; 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds amimouse_lastx = joy0dat & 0xff; 831da177e4SLinus Torvalds amimouse_lasty = joy0dat >> 8; 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { 861da177e4SLinus Torvalds printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); 871da177e4SLinus Torvalds return -EBUSY; 881da177e4SLinus Torvalds } 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds return 0; 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds static void amimouse_close(struct input_dev *dev) 941da177e4SLinus Torvalds { 951da177e4SLinus Torvalds free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); 961da177e4SLinus Torvalds } 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds static int __init amimouse_init(void) 991da177e4SLinus Torvalds { 1001da177e4SLinus Torvalds if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) 1011da177e4SLinus Torvalds return -ENODEV; 1021da177e4SLinus Torvalds 1032e5b636bSDmitry Torokhov if (!(amimouse_dev = input_allocate_device())) 1042e5b636bSDmitry Torokhov return -ENOMEM; 1051da177e4SLinus Torvalds 1062e5b636bSDmitry Torokhov amimouse_dev->name = "Amiga mouse"; 1072e5b636bSDmitry Torokhov amimouse_dev->phys = "amimouse/input0"; 1082e5b636bSDmitry Torokhov amimouse_dev->id.bustype = BUS_AMIGA; 1092e5b636bSDmitry Torokhov amimouse_dev->id.vendor = 0x0001; 1102e5b636bSDmitry Torokhov amimouse_dev->id.product = 0x0002; 1112e5b636bSDmitry Torokhov amimouse_dev->id.version = 0x0100; 1121da177e4SLinus Torvalds 1132e5b636bSDmitry Torokhov amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); 1142e5b636bSDmitry Torokhov amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); 1152e5b636bSDmitry Torokhov amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 1162e5b636bSDmitry Torokhov amimouse_dev->open = amimouse_open; 1172e5b636bSDmitry Torokhov amimouse_dev->close = amimouse_close; 1181da177e4SLinus Torvalds 1192e5b636bSDmitry Torokhov input_register_device(amimouse_dev); 1202e5b636bSDmitry Torokhov 1211da177e4SLinus Torvalds return 0; 1221da177e4SLinus Torvalds } 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds static void __exit amimouse_exit(void) 1251da177e4SLinus Torvalds { 1262e5b636bSDmitry Torokhov input_unregister_device(amimouse_dev); 1271da177e4SLinus Torvalds } 1281da177e4SLinus Torvalds 1291da177e4SLinus Torvalds module_init(amimouse_init); 1301da177e4SLinus Torvalds module_exit(amimouse_exit); 131