1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 1998-2001 Vojtech Pavlik
7 * Driver for Amiga joysticks for Linux/m68k
13 #include <linux/types.h>
14 #include <linux/errno.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/input.h>
19 #include <linux/interrupt.h>
20 #include <linux/mutex.h>
22 #include <asm/amigahw.h>
23 #include <asm/amigaints.h>
25 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
26 MODULE_DESCRIPTION("Driver for Amiga joysticks");
27 MODULE_LICENSE("GPL");
29 static int amijoy
[2] = { 0, 1 };
30 module_param_array_named(map
, amijoy
, uint
, NULL
, 0);
31 MODULE_PARM_DESC(map
, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
33 static int amijoy_used
;
34 static DEFINE_MUTEX(amijoy_mutex
);
35 static struct input_dev
*amijoy_dev
[2];
36 static char *amijoy_phys
[2] = { "amijoy/input0", "amijoy/input1" };
38 static irqreturn_t
amijoy_interrupt(int irq
, void *dummy
)
40 int i
, data
= 0, button
= 0;
42 for (i
= 0; i
< 2; i
++)
46 case 0: data
= ~amiga_custom
.joy0dat
; button
= (~ciaa
.pra
>> 6) & 1; break;
47 case 1: data
= ~amiga_custom
.joy1dat
; button
= (~ciaa
.pra
>> 7) & 1; break;
50 input_report_key(amijoy_dev
[i
], BTN_TRIGGER
, button
);
52 input_report_abs(amijoy_dev
[i
], ABS_X
, ((data
>> 1) & 1) - ((data
>> 9) & 1));
53 data
= ~(data
^ (data
<< 1));
54 input_report_abs(amijoy_dev
[i
], ABS_Y
, ((data
>> 1) & 1) - ((data
>> 9) & 1));
56 input_sync(amijoy_dev
[i
]);
61 static int amijoy_open(struct input_dev
*dev
)
65 err
= mutex_lock_interruptible(&amijoy_mutex
);
69 if (!amijoy_used
&& request_irq(IRQ_AMIGA_VERTB
, amijoy_interrupt
, 0, "amijoy", amijoy_interrupt
)) {
70 printk(KERN_ERR
"amijoy.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB
);
77 mutex_unlock(&amijoy_mutex
);
81 static void amijoy_close(struct input_dev
*dev
)
83 mutex_lock(&amijoy_mutex
);
85 free_irq(IRQ_AMIGA_VERTB
, amijoy_interrupt
);
86 mutex_unlock(&amijoy_mutex
);
89 static int __init
amijoy_init(void)
97 for (i
= 0; i
< 2; i
++) {
101 amijoy_dev
[i
] = input_allocate_device();
102 if (!amijoy_dev
[i
]) {
107 if (!request_mem_region(CUSTOM_PHYSADDR
+ 10 + i
* 2, 2, "amijoy [Denise]")) {
108 input_free_device(amijoy_dev
[i
]);
113 amijoy_dev
[i
]->name
= "Amiga joystick";
114 amijoy_dev
[i
]->phys
= amijoy_phys
[i
];
115 amijoy_dev
[i
]->id
.bustype
= BUS_AMIGA
;
116 amijoy_dev
[i
]->id
.vendor
= 0x0001;
117 amijoy_dev
[i
]->id
.product
= 0x0003;
118 amijoy_dev
[i
]->id
.version
= 0x0100;
120 amijoy_dev
[i
]->open
= amijoy_open
;
121 amijoy_dev
[i
]->close
= amijoy_close
;
123 amijoy_dev
[i
]->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
124 amijoy_dev
[i
]->absbit
[0] = BIT_MASK(ABS_X
) | BIT_MASK(ABS_Y
);
125 amijoy_dev
[i
]->keybit
[BIT_WORD(BTN_LEFT
)] = BIT_MASK(BTN_LEFT
) |
126 BIT_MASK(BTN_MIDDLE
) | BIT_MASK(BTN_RIGHT
);
127 for (j
= 0; j
< 2; j
++) {
128 input_set_abs_params(amijoy_dev
[i
], ABS_X
+ j
,
132 err
= input_register_device(amijoy_dev
[i
]);
134 input_free_device(amijoy_dev
[i
]);
140 fail
: while (--i
>= 0)
142 input_unregister_device(amijoy_dev
[i
]);
143 release_mem_region(CUSTOM_PHYSADDR
+ 10 + i
* 2, 2);
148 static void __exit
amijoy_exit(void)
152 for (i
= 0; i
< 2; i
++)
154 input_unregister_device(amijoy_dev
[i
]);
155 release_mem_region(CUSTOM_PHYSADDR
+ 10 + i
* 2, 2);
159 module_init(amijoy_init
);
160 module_exit(amijoy_exit
);