Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | // SPDX-License-Identifier: GPL-2.0-only /* * Amiga mouse driver for Linux/m68k * * Copyright (c) 2000-2002 Vojtech Pavlik * * Based on the work of: * Michael Rausch James Banks * Matther Dillon David Giller * Nathan Laredo Linus Torvalds * Johan Myreen Jes Sorensen * Russell King */ #include <linux/module.h> #include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <asm/irq.h> #include <asm/setup.h> #include <linux/uaccess.h> #include <asm/amigahw.h> #include <asm/amigaints.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("Amiga mouse driver"); MODULE_LICENSE("GPL"); static int amimouse_lastx, amimouse_lasty; static irqreturn_t amimouse_interrupt(int irq, void *data) { struct input_dev *dev = data; unsigned short joy0dat, potgor; int nx, ny, dx, dy; joy0dat = amiga_custom.joy0dat; nx = joy0dat & 0xff; ny = joy0dat >> 8; dx = nx - amimouse_lastx; dy = ny - amimouse_lasty; if (dx < -127) dx = (256 + nx) - amimouse_lastx; if (dx > 127) dx = (nx - 256) - amimouse_lastx; if (dy < -127) dy = (256 + ny) - amimouse_lasty; if (dy > 127) dy = (ny - 256) - amimouse_lasty; amimouse_lastx = nx; amimouse_lasty = ny; potgor = amiga_custom.potgor; input_report_rel(dev, REL_X, dx); input_report_rel(dev, REL_Y, dy); input_report_key(dev, BTN_LEFT, ciaa.pra & 0x40); input_report_key(dev, BTN_MIDDLE, potgor & 0x0100); input_report_key(dev, BTN_RIGHT, potgor & 0x0400); input_sync(dev); return IRQ_HANDLED; } static int amimouse_open(struct input_dev *dev) { unsigned short joy0dat; int error; joy0dat = amiga_custom.joy0dat; amimouse_lastx = joy0dat & 0xff; amimouse_lasty = joy0dat >> 8; error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", dev); if (error) dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB); return error; } static void amimouse_close(struct input_dev *dev) { free_irq(IRQ_AMIGA_VERTB, dev); } static int __init amimouse_probe(struct platform_device *pdev) { int err; struct input_dev *dev; dev = input_allocate_device(); if (!dev) return -ENOMEM; dev->name = pdev->name; dev->phys = "amimouse/input0"; dev->id.bustype = BUS_AMIGA; dev->id.vendor = 0x0001; dev->id.product = 0x0002; dev->id.version = 0x0100; dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); dev->open = amimouse_open; dev->close = amimouse_close; dev->dev.parent = &pdev->dev; err = input_register_device(dev); if (err) { input_free_device(dev); return err; } platform_set_drvdata(pdev, dev); return 0; } static int __exit amimouse_remove(struct platform_device *pdev) { struct input_dev *dev = platform_get_drvdata(pdev); input_unregister_device(dev); return 0; } static struct platform_driver amimouse_driver = { .remove = __exit_p(amimouse_remove), .driver = { .name = "amiga-mouse", }, }; module_platform_driver_probe(amimouse_driver, amimouse_probe); MODULE_ALIAS("platform:amiga-mouse"); |