Commit 4de27a63 authored by Sudip Mukherjee's avatar Sudip Mukherjee Committed by Dmitry Torokhov

Input: turbografx - use parallel port device model

Modify turbografx driver to use the new Parallel Port device model.
Signed-off-by: default avatarSudip Mukherjee <sudip@vectorindia.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent a517e87c
...@@ -49,7 +49,7 @@ struct tgfx_config { ...@@ -49,7 +49,7 @@ struct tgfx_config {
unsigned int nargs; unsigned int nargs;
}; };
static struct tgfx_config tgfx_cfg[TGFX_MAX_PORTS] __initdata; static struct tgfx_config tgfx_cfg[TGFX_MAX_PORTS];
module_param_array_named(map, tgfx_cfg[0].args, int, &tgfx_cfg[0].nargs, 0); module_param_array_named(map, tgfx_cfg[0].args, int, &tgfx_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>"); MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
...@@ -81,6 +81,7 @@ static struct tgfx { ...@@ -81,6 +81,7 @@ static struct tgfx {
char phys[TGFX_MAX_DEVICES][32]; char phys[TGFX_MAX_DEVICES][32];
int sticks; int sticks;
int used; int used;
int parportno;
struct mutex sem; struct mutex sem;
} *tgfx_base[TGFX_MAX_PORTS]; } *tgfx_base[TGFX_MAX_PORTS];
...@@ -156,38 +157,46 @@ static void tgfx_close(struct input_dev *dev) ...@@ -156,38 +157,46 @@ static void tgfx_close(struct input_dev *dev)
* tgfx_probe() probes for tg gamepads. * tgfx_probe() probes for tg gamepads.
*/ */
static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) static void tgfx_attach(struct parport *pp)
{ {
struct tgfx *tgfx; struct tgfx *tgfx;
struct input_dev *input_dev; struct input_dev *input_dev;
struct parport *pp;
struct pardevice *pd; struct pardevice *pd;
int i, j; int i, j;
int err; int *n_buttons, n_devs;
struct pardev_cb tgfx_parport_cb;
for (i = 0; i < TGFX_MAX_PORTS; i++) {
if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0)
continue;
if (tgfx_cfg[i].args[0] == pp->number)
break;
}
pp = parport_find_number(parport); if (i == TGFX_MAX_PORTS) {
if (!pp) { pr_debug("Not using parport%d.\n", pp->number);
printk(KERN_ERR "turbografx.c: no such parport\n"); return;
err = -EINVAL;
goto err_out;
} }
n_buttons = tgfx_cfg[i].args + 1;
n_devs = tgfx_cfg[i].nargs - 1;
pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); tgfx_parport_cb.flags = PARPORT_FLAG_EXCL;
pd = parport_register_dev_model(pp, "turbografx", &tgfx_parport_cb, i);
if (!pd) { if (!pd) {
printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n"); pr_err("parport busy already - lp.o loaded?\n");
err = -EBUSY; return;
goto err_put_pp;
} }
tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL); tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL);
if (!tgfx) { if (!tgfx) {
printk(KERN_ERR "turbografx.c: Not enough memory\n"); printk(KERN_ERR "turbografx.c: Not enough memory\n");
err = -ENOMEM;
goto err_unreg_pardev; goto err_unreg_pardev;
} }
mutex_init(&tgfx->sem); mutex_init(&tgfx->sem);
tgfx->pd = pd; tgfx->pd = pd;
tgfx->parportno = pp->number;
init_timer(&tgfx->timer); init_timer(&tgfx->timer);
tgfx->timer.data = (long) tgfx; tgfx->timer.data = (long) tgfx;
tgfx->timer.function = tgfx_timer; tgfx->timer.function = tgfx_timer;
...@@ -198,14 +207,12 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) ...@@ -198,14 +207,12 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
if (n_buttons[i] > 6) { if (n_buttons[i] > 6) {
printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]); printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
err = -EINVAL;
goto err_unreg_devs; goto err_unreg_devs;
} }
tgfx->dev[i] = input_dev = input_allocate_device(); tgfx->dev[i] = input_dev = input_allocate_device();
if (!input_dev) { if (!input_dev) {
printk(KERN_ERR "turbografx.c: Not enough memory for input device\n"); printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
err = -ENOMEM;
goto err_unreg_devs; goto err_unreg_devs;
} }
...@@ -234,19 +241,17 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) ...@@ -234,19 +241,17 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
for (j = 0; j < n_buttons[i]; j++) for (j = 0; j < n_buttons[i]; j++)
set_bit(tgfx_buttons[j], input_dev->keybit); set_bit(tgfx_buttons[j], input_dev->keybit);
err = input_register_device(tgfx->dev[i]); if (input_register_device(tgfx->dev[i]))
if (err)
goto err_free_dev; goto err_free_dev;
} }
if (!tgfx->sticks) { if (!tgfx->sticks) {
printk(KERN_ERR "turbografx.c: No valid devices specified\n"); printk(KERN_ERR "turbografx.c: No valid devices specified\n");
err = -EINVAL;
goto err_free_tgfx; goto err_free_tgfx;
} }
parport_put_port(pp); tgfx_base[i] = tgfx;
return tgfx; return;
err_free_dev: err_free_dev:
input_free_device(tgfx->dev[i]); input_free_device(tgfx->dev[i]);
...@@ -258,15 +263,23 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) ...@@ -258,15 +263,23 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
kfree(tgfx); kfree(tgfx);
err_unreg_pardev: err_unreg_pardev:
parport_unregister_device(pd); parport_unregister_device(pd);
err_put_pp:
parport_put_port(pp);
err_out:
return ERR_PTR(err);
} }
static void tgfx_remove(struct tgfx *tgfx) static void tgfx_detach(struct parport *port)
{ {
int i; int i;
struct tgfx *tgfx;
for (i = 0; i < TGFX_MAX_PORTS; i++) {
if (tgfx_base[i] && tgfx_base[i]->parportno == port->number)
break;
}
if (i == TGFX_MAX_PORTS)
return;
tgfx = tgfx_base[i];
tgfx_base[i] = NULL;
for (i = 0; i < TGFX_MAX_DEVICES; i++) for (i = 0; i < TGFX_MAX_DEVICES; i++)
if (tgfx->dev[i]) if (tgfx->dev[i])
...@@ -275,11 +288,17 @@ static void tgfx_remove(struct tgfx *tgfx) ...@@ -275,11 +288,17 @@ static void tgfx_remove(struct tgfx *tgfx)
kfree(tgfx); kfree(tgfx);
} }
static struct parport_driver tgfx_parport_driver = {
.name = "turbografx",
.match_port = tgfx_attach,
.detach = tgfx_detach,
.devmodel = true,
};
static int __init tgfx_init(void) static int __init tgfx_init(void)
{ {
int i; int i;
int have_dev = 0; int have_dev = 0;
int err = 0;
for (i = 0; i < TGFX_MAX_PORTS; i++) { for (i = 0; i < TGFX_MAX_PORTS; i++) {
if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0) if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0)
...@@ -287,38 +306,21 @@ static int __init tgfx_init(void) ...@@ -287,38 +306,21 @@ static int __init tgfx_init(void)
if (tgfx_cfg[i].nargs < 2) { if (tgfx_cfg[i].nargs < 2) {
printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n"); printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
err = -EINVAL; return -EINVAL;
break;
}
tgfx_base[i] = tgfx_probe(tgfx_cfg[i].args[0],
tgfx_cfg[i].args + 1,
tgfx_cfg[i].nargs - 1);
if (IS_ERR(tgfx_base[i])) {
err = PTR_ERR(tgfx_base[i]);
break;
} }
have_dev = 1; have_dev = 1;
} }
if (err) { if (!have_dev)
while (--i >= 0) return -ENODEV;
if (tgfx_base[i])
tgfx_remove(tgfx_base[i]);
return err;
}
return have_dev ? 0 : -ENODEV; return parport_register_driver(&tgfx_parport_driver);
} }
static void __exit tgfx_exit(void) static void __exit tgfx_exit(void)
{ {
int i; parport_unregister_driver(&tgfx_parport_driver);
for (i = 0; i < TGFX_MAX_PORTS; i++)
if (tgfx_base[i])
tgfx_remove(tgfx_base[i]);
} }
module_init(tgfx_init); module_init(tgfx_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment