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> 24314c926fSGeert Uytterhoeven #include <linux/platform_device.h> 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds #include <asm/irq.h> 271da177e4SLinus Torvalds #include <asm/setup.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; 371da177e4SLinus Torvalds 38314c926fSGeert Uytterhoeven static irqreturn_t amimouse_interrupt(int irq, void *data) 391da177e4SLinus Torvalds { 40314c926fSGeert Uytterhoeven struct input_dev *dev = data; 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 62314c926fSGeert Uytterhoeven input_report_rel(dev, REL_X, dx); 63314c926fSGeert Uytterhoeven input_report_rel(dev, REL_Y, dy); 641da177e4SLinus Torvalds 65314c926fSGeert Uytterhoeven input_report_key(dev, BTN_LEFT, ciaa.pra & 0x40); 66314c926fSGeert Uytterhoeven input_report_key(dev, BTN_MIDDLE, potgor & 0x0100); 67314c926fSGeert Uytterhoeven input_report_key(dev, BTN_RIGHT, potgor & 0x0400); 681da177e4SLinus Torvalds 69314c926fSGeert Uytterhoeven input_sync(dev); 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds return IRQ_HANDLED; 721da177e4SLinus Torvalds } 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds static int amimouse_open(struct input_dev *dev) 751da177e4SLinus Torvalds { 761da177e4SLinus Torvalds unsigned short joy0dat; 77314c926fSGeert Uytterhoeven int error; 781da177e4SLinus Torvalds 79b4290a23SAl Viro joy0dat = amiga_custom.joy0dat; 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds amimouse_lastx = joy0dat & 0xff; 821da177e4SLinus Torvalds amimouse_lasty = joy0dat >> 8; 831da177e4SLinus Torvalds 84314c926fSGeert Uytterhoeven error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", 85314c926fSGeert Uytterhoeven dev); 86314c926fSGeert Uytterhoeven if (error) 87314c926fSGeert Uytterhoeven dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB); 881da177e4SLinus Torvalds 89314c926fSGeert Uytterhoeven return error; 901da177e4SLinus Torvalds } 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds static void amimouse_close(struct input_dev *dev) 931da177e4SLinus Torvalds { 94314c926fSGeert Uytterhoeven free_irq(IRQ_AMIGA_VERTB, dev); 951da177e4SLinus Torvalds } 961da177e4SLinus Torvalds 97314c926fSGeert Uytterhoeven static int __init amimouse_probe(struct platform_device *pdev) 981da177e4SLinus Torvalds { 9972155615SDmitry Torokhov int err; 100314c926fSGeert Uytterhoeven struct input_dev *dev; 10172155615SDmitry Torokhov 102314c926fSGeert Uytterhoeven dev = input_allocate_device(); 103314c926fSGeert Uytterhoeven if (!dev) 1042e5b636bSDmitry Torokhov return -ENOMEM; 1051da177e4SLinus Torvalds 106314c926fSGeert Uytterhoeven dev->name = pdev->name; 107314c926fSGeert Uytterhoeven dev->phys = "amimouse/input0"; 108314c926fSGeert Uytterhoeven dev->id.bustype = BUS_AMIGA; 109314c926fSGeert Uytterhoeven dev->id.vendor = 0x0001; 110314c926fSGeert Uytterhoeven dev->id.product = 0x0002; 111314c926fSGeert Uytterhoeven dev->id.version = 0x0100; 1121da177e4SLinus Torvalds 113314c926fSGeert Uytterhoeven dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 114314c926fSGeert Uytterhoeven dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 115314c926fSGeert Uytterhoeven dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | 1167b19ada2SJiri Slaby BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); 117314c926fSGeert Uytterhoeven dev->open = amimouse_open; 118314c926fSGeert Uytterhoeven dev->close = amimouse_close; 119314c926fSGeert Uytterhoeven dev->dev.parent = &pdev->dev; 1201da177e4SLinus Torvalds 121314c926fSGeert Uytterhoeven err = input_register_device(dev); 12272155615SDmitry Torokhov if (err) { 123314c926fSGeert Uytterhoeven input_free_device(dev); 12472155615SDmitry Torokhov return err; 12572155615SDmitry Torokhov } 1262e5b636bSDmitry Torokhov 127314c926fSGeert Uytterhoeven platform_set_drvdata(pdev, dev); 128314c926fSGeert Uytterhoeven 1291da177e4SLinus Torvalds return 0; 1301da177e4SLinus Torvalds } 1311da177e4SLinus Torvalds 132314c926fSGeert Uytterhoeven static int __exit amimouse_remove(struct platform_device *pdev) 1331da177e4SLinus Torvalds { 134314c926fSGeert Uytterhoeven struct input_dev *dev = platform_get_drvdata(pdev); 135314c926fSGeert Uytterhoeven 136314c926fSGeert Uytterhoeven platform_set_drvdata(pdev, NULL); 137314c926fSGeert Uytterhoeven input_unregister_device(dev); 138314c926fSGeert Uytterhoeven return 0; 139314c926fSGeert Uytterhoeven } 140314c926fSGeert Uytterhoeven 141314c926fSGeert Uytterhoeven static struct platform_driver amimouse_driver = { 142314c926fSGeert Uytterhoeven .remove = __exit_p(amimouse_remove), 143314c926fSGeert Uytterhoeven .driver = { 144314c926fSGeert Uytterhoeven .name = "amiga-mouse", 145314c926fSGeert Uytterhoeven .owner = THIS_MODULE, 146314c926fSGeert Uytterhoeven }, 147314c926fSGeert Uytterhoeven }; 148d3d25808SDmitry Torokhov 149e492fe27SSachin Kamat module_platform_driver_probe(amimouse_driver, amimouse_probe); 150314c926fSGeert Uytterhoeven 151314c926fSGeert Uytterhoeven MODULE_ALIAS("platform:amiga-mouse"); 152