1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 1998-2001 Vojtech Pavlik
5 * Based on the work of:
10 * TurboGraFX parallel port interface driver for Linux.
16 #include <linux/kernel.h>
17 #include <linux/parport.h>
18 #include <linux/input.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/mutex.h>
22 #include <linux/slab.h>
24 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
25 MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
26 MODULE_LICENSE("GPL");
28 #define TGFX_MAX_PORTS 3
29 #define TGFX_MAX_DEVICES 7
32 int args
[TGFX_MAX_DEVICES
+ 1];
36 static struct tgfx_config tgfx_cfg
[TGFX_MAX_PORTS
];
38 module_param_array_named(map
, tgfx_cfg
[0].args
, int, &tgfx_cfg
[0].nargs
, 0);
39 MODULE_PARM_DESC(map
, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
40 module_param_array_named(map2
, tgfx_cfg
[1].args
, int, &tgfx_cfg
[1].nargs
, 0);
41 MODULE_PARM_DESC(map2
, "Describes second set of devices");
42 module_param_array_named(map3
, tgfx_cfg
[2].args
, int, &tgfx_cfg
[2].nargs
, 0);
43 MODULE_PARM_DESC(map3
, "Describes third set of devices");
45 #define TGFX_REFRESH_TIME HZ/100 /* 10 ms */
47 #define TGFX_TRIGGER 0x08
49 #define TGFX_DOWN 0x20
50 #define TGFX_LEFT 0x40
51 #define TGFX_RIGHT 0x80
53 #define TGFX_THUMB 0x02
54 #define TGFX_THUMB2 0x04
56 #define TGFX_TOP2 0x08
58 static int tgfx_buttons
[] = { BTN_TRIGGER
, BTN_THUMB
, BTN_THUMB2
, BTN_TOP
, BTN_TOP2
};
62 struct timer_list timer
;
63 struct input_dev
*dev
[TGFX_MAX_DEVICES
];
64 char name
[TGFX_MAX_DEVICES
][64];
65 char phys
[TGFX_MAX_DEVICES
][32];
70 } *tgfx_base
[TGFX_MAX_PORTS
];
73 * tgfx_timer() reads and analyzes TurboGraFX joystick data.
76 static void tgfx_timer(struct timer_list
*t
)
78 struct tgfx
*tgfx
= from_timer(tgfx
, t
, timer
);
79 struct input_dev
*dev
;
82 for (i
= 0; i
< 7; i
++)
83 if (tgfx
->sticks
& (1 << i
)) {
87 parport_write_data(tgfx
->pd
->port
, ~(1 << i
));
88 data1
= parport_read_status(tgfx
->pd
->port
) ^ 0x7f;
89 data2
= parport_read_control(tgfx
->pd
->port
) ^ 0x04; /* CAVEAT parport */
91 input_report_abs(dev
, ABS_X
, !!(data1
& TGFX_RIGHT
) - !!(data1
& TGFX_LEFT
));
92 input_report_abs(dev
, ABS_Y
, !!(data1
& TGFX_DOWN
) - !!(data1
& TGFX_UP
));
94 input_report_key(dev
, BTN_TRIGGER
, (data1
& TGFX_TRIGGER
));
95 input_report_key(dev
, BTN_THUMB
, (data2
& TGFX_THUMB
));
96 input_report_key(dev
, BTN_THUMB2
, (data2
& TGFX_THUMB2
));
97 input_report_key(dev
, BTN_TOP
, (data2
& TGFX_TOP
));
98 input_report_key(dev
, BTN_TOP2
, (data2
& TGFX_TOP2
));
103 mod_timer(&tgfx
->timer
, jiffies
+ TGFX_REFRESH_TIME
);
106 static int tgfx_open(struct input_dev
*dev
)
108 struct tgfx
*tgfx
= input_get_drvdata(dev
);
111 err
= mutex_lock_interruptible(&tgfx
->sem
);
116 parport_claim(tgfx
->pd
);
117 parport_write_control(tgfx
->pd
->port
, 0x04);
118 mod_timer(&tgfx
->timer
, jiffies
+ TGFX_REFRESH_TIME
);
121 mutex_unlock(&tgfx
->sem
);
125 static void tgfx_close(struct input_dev
*dev
)
127 struct tgfx
*tgfx
= input_get_drvdata(dev
);
129 mutex_lock(&tgfx
->sem
);
131 del_timer_sync(&tgfx
->timer
);
132 parport_write_control(tgfx
->pd
->port
, 0x00);
133 parport_release(tgfx
->pd
);
135 mutex_unlock(&tgfx
->sem
);
141 * tgfx_probe() probes for tg gamepads.
144 static void tgfx_attach(struct parport
*pp
)
147 struct input_dev
*input_dev
;
148 struct pardevice
*pd
;
150 int *n_buttons
, n_devs
;
151 struct pardev_cb tgfx_parport_cb
;
153 for (port_idx
= 0; port_idx
< TGFX_MAX_PORTS
; port_idx
++) {
154 if (tgfx_cfg
[port_idx
].nargs
== 0 ||
155 tgfx_cfg
[port_idx
].args
[0] < 0)
157 if (tgfx_cfg
[port_idx
].args
[0] == pp
->number
)
161 if (port_idx
== TGFX_MAX_PORTS
) {
162 pr_debug("Not using parport%d.\n", pp
->number
);
165 n_buttons
= tgfx_cfg
[port_idx
].args
+ 1;
166 n_devs
= tgfx_cfg
[port_idx
].nargs
- 1;
168 memset(&tgfx_parport_cb
, 0, sizeof(tgfx_parport_cb
));
169 tgfx_parport_cb
.flags
= PARPORT_FLAG_EXCL
;
171 pd
= parport_register_dev_model(pp
, "turbografx", &tgfx_parport_cb
,
174 pr_err("parport busy already - lp.o loaded?\n");
178 tgfx
= kzalloc(sizeof(struct tgfx
), GFP_KERNEL
);
180 printk(KERN_ERR
"turbografx.c: Not enough memory\n");
181 goto err_unreg_pardev
;
184 mutex_init(&tgfx
->sem
);
186 tgfx
->parportno
= pp
->number
;
187 timer_setup(&tgfx
->timer
, tgfx_timer
, 0);
189 for (i
= 0; i
< n_devs
; i
++) {
190 if (n_buttons
[i
] < 1)
193 if (n_buttons
[i
] > ARRAY_SIZE(tgfx_buttons
)) {
194 printk(KERN_ERR
"turbografx.c: Invalid number of buttons %d\n", n_buttons
[i
]);
198 tgfx
->dev
[i
] = input_dev
= input_allocate_device();
200 printk(KERN_ERR
"turbografx.c: Not enough memory for input device\n");
204 tgfx
->sticks
|= (1 << i
);
205 snprintf(tgfx
->name
[i
], sizeof(tgfx
->name
[i
]),
206 "TurboGraFX %d-button Multisystem joystick", n_buttons
[i
]);
207 snprintf(tgfx
->phys
[i
], sizeof(tgfx
->phys
[i
]),
208 "%s/input%d", tgfx
->pd
->port
->name
, i
);
210 input_dev
->name
= tgfx
->name
[i
];
211 input_dev
->phys
= tgfx
->phys
[i
];
212 input_dev
->id
.bustype
= BUS_PARPORT
;
213 input_dev
->id
.vendor
= 0x0003;
214 input_dev
->id
.product
= n_buttons
[i
];
215 input_dev
->id
.version
= 0x0100;
217 input_set_drvdata(input_dev
, tgfx
);
219 input_dev
->open
= tgfx_open
;
220 input_dev
->close
= tgfx_close
;
222 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
223 input_set_abs_params(input_dev
, ABS_X
, -1, 1, 0, 0);
224 input_set_abs_params(input_dev
, ABS_Y
, -1, 1, 0, 0);
226 for (j
= 0; j
< n_buttons
[i
]; j
++)
227 set_bit(tgfx_buttons
[j
], input_dev
->keybit
);
229 if (input_register_device(tgfx
->dev
[i
]))
234 printk(KERN_ERR
"turbografx.c: No valid devices specified\n");
238 tgfx_base
[port_idx
] = tgfx
;
242 input_free_device(tgfx
->dev
[i
]);
246 input_unregister_device(tgfx
->dev
[i
]);
250 parport_unregister_device(pd
);
253 static void tgfx_detach(struct parport
*port
)
258 for (i
= 0; i
< TGFX_MAX_PORTS
; i
++) {
259 if (tgfx_base
[i
] && tgfx_base
[i
]->parportno
== port
->number
)
263 if (i
== TGFX_MAX_PORTS
)
269 for (i
= 0; i
< TGFX_MAX_DEVICES
; i
++)
271 input_unregister_device(tgfx
->dev
[i
]);
272 parport_unregister_device(tgfx
->pd
);
276 static struct parport_driver tgfx_parport_driver
= {
277 .name
= "turbografx",
278 .match_port
= tgfx_attach
,
279 .detach
= tgfx_detach
,
283 static int __init
tgfx_init(void)
288 for (i
= 0; i
< TGFX_MAX_PORTS
; i
++) {
289 if (tgfx_cfg
[i
].nargs
== 0 || tgfx_cfg
[i
].args
[0] < 0)
292 if (tgfx_cfg
[i
].nargs
< 2) {
293 printk(KERN_ERR
"turbografx.c: at least one joystick must be specified\n");
303 return parport_register_driver(&tgfx_parport_driver
);
306 static void __exit
tgfx_exit(void)
308 parport_unregister_driver(&tgfx_parport_driver
);
311 module_init(tgfx_init
);
312 module_exit(tgfx_exit
);