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