Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (c) 1998-2001 Vojtech Pavlik
0004  *
0005  *  Based on the work of:
0006  *  Steffen Schwenke
0007  */
0008 
0009 /*
0010  * TurboGraFX parallel port interface driver for Linux.
0011  */
0012 
0013 /*
0014  */
0015 
0016 #include <linux/kernel.h>
0017 #include <linux/parport.h>
0018 #include <linux/input.h>
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/mutex.h>
0022 #include <linux/slab.h>
0023 
0024 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
0025 MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
0026 MODULE_LICENSE("GPL");
0027 
0028 #define TGFX_MAX_PORTS      3
0029 #define TGFX_MAX_DEVICES    7
0030 
0031 struct tgfx_config {
0032     int args[TGFX_MAX_DEVICES + 1];
0033     unsigned int nargs;
0034 };
0035 
0036 static struct tgfx_config tgfx_cfg[TGFX_MAX_PORTS];
0037 
0038 module_param_array_named(map, tgfx_cfg[0].args, int, &tgfx_cfg[0].nargs, 0);
0039 MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
0040 module_param_array_named(map2, tgfx_cfg[1].args, int, &tgfx_cfg[1].nargs, 0);
0041 MODULE_PARM_DESC(map2, "Describes second set of devices");
0042 module_param_array_named(map3, tgfx_cfg[2].args, int, &tgfx_cfg[2].nargs, 0);
0043 MODULE_PARM_DESC(map3, "Describes third set of devices");
0044 
0045 #define TGFX_REFRESH_TIME   HZ/100  /* 10 ms */
0046 
0047 #define TGFX_TRIGGER        0x08
0048 #define TGFX_UP         0x10
0049 #define TGFX_DOWN       0x20
0050 #define TGFX_LEFT       0x40
0051 #define TGFX_RIGHT      0x80
0052 
0053 #define TGFX_THUMB      0x02
0054 #define TGFX_THUMB2     0x04
0055 #define TGFX_TOP        0x01
0056 #define TGFX_TOP2       0x08
0057 
0058 static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 };
0059 
0060 static struct tgfx {
0061     struct pardevice *pd;
0062     struct timer_list timer;
0063     struct input_dev *dev[TGFX_MAX_DEVICES];
0064     char name[TGFX_MAX_DEVICES][64];
0065     char phys[TGFX_MAX_DEVICES][32];
0066     int sticks;
0067     int used;
0068     int parportno;
0069     struct mutex sem;
0070 } *tgfx_base[TGFX_MAX_PORTS];
0071 
0072 /*
0073  * tgfx_timer() reads and analyzes TurboGraFX joystick data.
0074  */
0075 
0076 static void tgfx_timer(struct timer_list *t)
0077 {
0078     struct tgfx *tgfx = from_timer(tgfx, t, timer);
0079     struct input_dev *dev;
0080     int data1, data2, i;
0081 
0082     for (i = 0; i < 7; i++)
0083         if (tgfx->sticks & (1 << i)) {
0084 
0085             dev = tgfx->dev[i];
0086 
0087             parport_write_data(tgfx->pd->port, ~(1 << i));
0088             data1 = parport_read_status(tgfx->pd->port) ^ 0x7f;
0089             data2 = parport_read_control(tgfx->pd->port) ^ 0x04;    /* CAVEAT parport */
0090 
0091             input_report_abs(dev, ABS_X, !!(data1 & TGFX_RIGHT) - !!(data1 & TGFX_LEFT));
0092             input_report_abs(dev, ABS_Y, !!(data1 & TGFX_DOWN ) - !!(data1 & TGFX_UP  ));
0093 
0094             input_report_key(dev, BTN_TRIGGER, (data1 & TGFX_TRIGGER));
0095             input_report_key(dev, BTN_THUMB,   (data2 & TGFX_THUMB  ));
0096             input_report_key(dev, BTN_THUMB2,  (data2 & TGFX_THUMB2 ));
0097             input_report_key(dev, BTN_TOP,     (data2 & TGFX_TOP    ));
0098             input_report_key(dev, BTN_TOP2,    (data2 & TGFX_TOP2   ));
0099 
0100             input_sync(dev);
0101         }
0102 
0103     mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
0104 }
0105 
0106 static int tgfx_open(struct input_dev *dev)
0107 {
0108     struct tgfx *tgfx = input_get_drvdata(dev);
0109     int err;
0110 
0111     err = mutex_lock_interruptible(&tgfx->sem);
0112     if (err)
0113         return err;
0114 
0115     if (!tgfx->used++) {
0116         parport_claim(tgfx->pd);
0117         parport_write_control(tgfx->pd->port, 0x04);
0118         mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
0119     }
0120 
0121     mutex_unlock(&tgfx->sem);
0122     return 0;
0123 }
0124 
0125 static void tgfx_close(struct input_dev *dev)
0126 {
0127     struct tgfx *tgfx = input_get_drvdata(dev);
0128 
0129     mutex_lock(&tgfx->sem);
0130     if (!--tgfx->used) {
0131         del_timer_sync(&tgfx->timer);
0132         parport_write_control(tgfx->pd->port, 0x00);
0133         parport_release(tgfx->pd);
0134     }
0135     mutex_unlock(&tgfx->sem);
0136 }
0137 
0138 
0139 
0140 /*
0141  * tgfx_probe() probes for tg gamepads.
0142  */
0143 
0144 static void tgfx_attach(struct parport *pp)
0145 {
0146     struct tgfx *tgfx;
0147     struct input_dev *input_dev;
0148     struct pardevice *pd;
0149     int i, j, port_idx;
0150     int *n_buttons, n_devs;
0151     struct pardev_cb tgfx_parport_cb;
0152 
0153     for (port_idx = 0; port_idx < TGFX_MAX_PORTS; port_idx++) {
0154         if (tgfx_cfg[port_idx].nargs == 0 ||
0155             tgfx_cfg[port_idx].args[0] < 0)
0156             continue;
0157         if (tgfx_cfg[port_idx].args[0] == pp->number)
0158             break;
0159     }
0160 
0161     if (port_idx == TGFX_MAX_PORTS) {
0162         pr_debug("Not using parport%d.\n", pp->number);
0163         return;
0164     }
0165     n_buttons = tgfx_cfg[port_idx].args + 1;
0166     n_devs = tgfx_cfg[port_idx].nargs - 1;
0167 
0168     memset(&tgfx_parport_cb, 0, sizeof(tgfx_parport_cb));
0169     tgfx_parport_cb.flags = PARPORT_FLAG_EXCL;
0170 
0171     pd = parport_register_dev_model(pp, "turbografx", &tgfx_parport_cb,
0172                     port_idx);
0173     if (!pd) {
0174         pr_err("parport busy already - lp.o loaded?\n");
0175         return;
0176     }
0177 
0178     tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL);
0179     if (!tgfx) {
0180         printk(KERN_ERR "turbografx.c: Not enough memory\n");
0181         goto err_unreg_pardev;
0182     }
0183 
0184     mutex_init(&tgfx->sem);
0185     tgfx->pd = pd;
0186     tgfx->parportno = pp->number;
0187     timer_setup(&tgfx->timer, tgfx_timer, 0);
0188 
0189     for (i = 0; i < n_devs; i++) {
0190         if (n_buttons[i] < 1)
0191             continue;
0192 
0193         if (n_buttons[i] > ARRAY_SIZE(tgfx_buttons)) {
0194             printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
0195             goto err_unreg_devs;
0196         }
0197 
0198         tgfx->dev[i] = input_dev = input_allocate_device();
0199         if (!input_dev) {
0200             printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
0201             goto err_unreg_devs;
0202         }
0203 
0204         tgfx->sticks |= (1 << i);
0205         snprintf(tgfx->name[i], sizeof(tgfx->name[i]),
0206              "TurboGraFX %d-button Multisystem joystick", n_buttons[i]);
0207         snprintf(tgfx->phys[i], sizeof(tgfx->phys[i]),
0208              "%s/input%d", tgfx->pd->port->name, i);
0209 
0210         input_dev->name = tgfx->name[i];
0211         input_dev->phys = tgfx->phys[i];
0212         input_dev->id.bustype = BUS_PARPORT;
0213         input_dev->id.vendor = 0x0003;
0214         input_dev->id.product = n_buttons[i];
0215         input_dev->id.version = 0x0100;
0216 
0217         input_set_drvdata(input_dev, tgfx);
0218 
0219         input_dev->open = tgfx_open;
0220         input_dev->close = tgfx_close;
0221 
0222         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
0223         input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
0224         input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
0225 
0226         for (j = 0; j < n_buttons[i]; j++)
0227             set_bit(tgfx_buttons[j], input_dev->keybit);
0228 
0229         if (input_register_device(tgfx->dev[i]))
0230             goto err_free_dev;
0231     }
0232 
0233         if (!tgfx->sticks) {
0234         printk(KERN_ERR "turbografx.c: No valid devices specified\n");
0235         goto err_free_tgfx;
0236         }
0237 
0238     tgfx_base[port_idx] = tgfx;
0239     return;
0240 
0241  err_free_dev:
0242     input_free_device(tgfx->dev[i]);
0243  err_unreg_devs:
0244     while (--i >= 0)
0245         if (tgfx->dev[i])
0246             input_unregister_device(tgfx->dev[i]);
0247  err_free_tgfx:
0248     kfree(tgfx);
0249  err_unreg_pardev:
0250     parport_unregister_device(pd);
0251 }
0252 
0253 static void tgfx_detach(struct parport *port)
0254 {
0255     int i;
0256     struct tgfx *tgfx;
0257 
0258     for (i = 0; i < TGFX_MAX_PORTS; i++) {
0259         if (tgfx_base[i] && tgfx_base[i]->parportno == port->number)
0260             break;
0261     }
0262 
0263     if (i == TGFX_MAX_PORTS)
0264         return;
0265 
0266     tgfx = tgfx_base[i];
0267     tgfx_base[i] = NULL;
0268 
0269     for (i = 0; i < TGFX_MAX_DEVICES; i++)
0270         if (tgfx->dev[i])
0271             input_unregister_device(tgfx->dev[i]);
0272     parport_unregister_device(tgfx->pd);
0273     kfree(tgfx);
0274 }
0275 
0276 static struct parport_driver tgfx_parport_driver = {
0277     .name = "turbografx",
0278     .match_port = tgfx_attach,
0279     .detach = tgfx_detach,
0280     .devmodel = true,
0281 };
0282 
0283 static int __init tgfx_init(void)
0284 {
0285     int i;
0286     int have_dev = 0;
0287 
0288     for (i = 0; i < TGFX_MAX_PORTS; i++) {
0289         if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0)
0290             continue;
0291 
0292         if (tgfx_cfg[i].nargs < 2) {
0293             printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
0294             return -EINVAL;
0295         }
0296 
0297         have_dev = 1;
0298     }
0299 
0300     if (!have_dev)
0301         return -ENODEV;
0302 
0303     return parport_register_driver(&tgfx_parport_driver);
0304 }
0305 
0306 static void __exit tgfx_exit(void)
0307 {
0308     parport_unregister_driver(&tgfx_parport_driver);
0309 }
0310 
0311 module_init(tgfx_init);
0312 module_exit(tgfx_exit);