X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Finput%2Fjoystick%2Fstinger.c;h=011ec4858e15553f60df86057eb42699f20a80b3;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=ce9be4563135328579ba810703e77c384c452ccc;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index ce9be4563..011ec4858 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -36,8 +36,10 @@ #include #include +#define DRIVER_DESC "Gravis Stinger gamepad driver" + MODULE_AUTHOR("Vojtech Pavlik "); -MODULE_DESCRIPTION("Gravis Stinger gamepad driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); /* @@ -46,14 +48,12 @@ MODULE_LICENSE("GPL"); #define STINGER_MAX_LENGTH 8 -static char *stinger_name = "Gravis Stinger"; - /* * Per-Stinger data. */ struct stinger { - struct input_dev dev; + struct input_dev *dev; int idx; unsigned char data[STINGER_MAX_LENGTH]; char phys[32]; @@ -66,7 +66,7 @@ struct stinger { static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs) { - struct input_dev *dev = &stinger->dev; + struct input_dev *dev = stinger->dev; unsigned char *data = stinger->data; if (!stinger->idx) return; @@ -101,7 +101,7 @@ static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs static irqreturn_t stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { - struct stinger* stinger = serio->private; + struct stinger *stinger = serio_get_drvdata(serio); /* All Stinger packets are 4 bytes */ @@ -122,90 +122,105 @@ static irqreturn_t stinger_interrupt(struct serio *serio, static void stinger_disconnect(struct serio *serio) { - struct stinger* stinger = serio->private; - input_unregister_device(&stinger->dev); + struct stinger *stinger = serio_get_drvdata(serio); + serio_close(serio); + serio_set_drvdata(serio, NULL); + input_unregister_device(stinger->dev); kfree(stinger); } /* * stinger_connect() is the routine that is called when someone adds a - * new serio device. It looks for the Stinger, and if found, registers - * it as an input device. + * new serio device that supports Stinger protocol and registers it as + * an input device. */ -static void stinger_connect(struct serio *serio, struct serio_dev *dev) +static int stinger_connect(struct serio *serio, struct serio_driver *drv) { struct stinger *stinger; - int i; - - if (serio->type != (SERIO_RS232 | SERIO_STINGER)) - return; - - if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL))) - return; - - memset(stinger, 0, sizeof(struct stinger)); - - stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \ - BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \ - BIT(BTN_START) | BIT(BTN_SELECT); - stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - - sprintf(stinger->phys, "%s/serio0", serio->phys); - - init_input_dev(&stinger->dev); - stinger->dev.name = stinger_name; - stinger->dev.phys = stinger->phys; - stinger->dev.id.bustype = BUS_RS232; - stinger->dev.id.vendor = SERIO_STINGER; - stinger->dev.id.product = 0x0001; - stinger->dev.id.version = 0x0100; - - for (i = 0; i < 2; i++) { - stinger->dev.absmax[ABS_X+i] = 64; - stinger->dev.absmin[ABS_X+i] = -64; - stinger->dev.absflat[ABS_X+i] = 4; - } - - stinger->dev.private = stinger; - serio->private = stinger; - - if (serio_open(serio, dev)) { - kfree(stinger); - return; - } - - input_register_device(&stinger->dev); - - printk(KERN_INFO "input: %s on %s\n", stinger_name, serio->phys); + struct input_dev *input_dev; + int err = -ENOMEM; + + stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!stinger || !input_dev) + goto fail; + + stinger->dev = input_dev; + snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); + + input_dev->name = "Gravis Stinger"; + input_dev->phys = stinger->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_STINGER; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->cdev.dev = &serio->dev; + input_dev->private = stinger; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | + BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | + BIT(BTN_START) | BIT(BTN_SELECT); + input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4); + input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4); + + serio_set_drvdata(serio, stinger); + + err = serio_open(serio, drv); + if (err) + goto fail; + + input_register_device(stinger->dev); + return 0; + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(stinger); + return err; } /* - * The serio device structure. + * The serio driver structure. */ -static struct serio_dev stinger_dev = { - .interrupt = stinger_interrupt, - .connect = stinger_connect, - .disconnect = stinger_disconnect, +static struct serio_device_id stinger_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_STINGER, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, stinger_serio_ids); + +static struct serio_driver stinger_drv = { + .driver = { + .name = "stinger", + }, + .description = DRIVER_DESC, + .id_table = stinger_serio_ids, + .interrupt = stinger_interrupt, + .connect = stinger_connect, + .disconnect = stinger_disconnect, }; /* * The functions for inserting/removing us as a module. */ -int __init stinger_init(void) +static int __init stinger_init(void) { - serio_register_device(&stinger_dev); + serio_register_driver(&stinger_drv); return 0; } -void __exit stinger_exit(void) +static void __exit stinger_exit(void) { - serio_unregister_device(&stinger_dev); + serio_unregister_driver(&stinger_drv); } module_init(stinger_init);