#include <linux/gameport.h>
#include <linux/input.h>
+#define DRIVER_DESC "Guillemot Digital joystick driver"
+
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Guillemot Digital joystick driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
#define GUILLEMOT_MAX_START 600 /* 600 us */
#define GUILLEMOT_MAX_STROBE 60 /* 60 us */
#define GUILLEMOT_MAX_LENGTH 17 /* 17 bytes */
-#define GUILLEMOT_REFRESH_TIME HZ/50 /* 20 ms */
static short guillemot_abs_pad[] =
{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };
struct guillemot {
struct gameport *gameport;
struct input_dev dev;
- struct timer_list timer;
- int used;
int bads;
int reads;
struct guillemot_type *type;
}
/*
- * guillemot_timer() reads and analyzes Guillemot joystick data.
+ * guillemot_poll() reads and analyzes Guillemot joystick data.
*/
-static void guillemot_timer(unsigned long private)
+static void guillemot_poll(struct gameport *gameport)
{
- struct guillemot *guillemot = (struct guillemot *) private;
+ struct guillemot *guillemot = gameport_get_drvdata(gameport);
struct input_dev *dev = &guillemot->dev;
u8 data[GUILLEMOT_MAX_LENGTH];
int i;
}
input_sync(dev);
-
- mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
}
/*
static int guillemot_open(struct input_dev *dev)
{
struct guillemot *guillemot = dev->private;
- if (!guillemot->used++)
- mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
+
+ gameport_start_polling(guillemot->gameport);
return 0;
}
static void guillemot_close(struct input_dev *dev)
{
struct guillemot *guillemot = dev->private;
- if (!--guillemot->used)
- del_timer(&guillemot->timer);
+
+ gameport_stop_polling(guillemot->gameport);
}
/*
* guillemot_connect() probes for Guillemot joysticks.
*/
-static void guillemot_connect(struct gameport *gameport, struct gameport_dev *dev)
+static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct guillemot *guillemot;
u8 data[GUILLEMOT_MAX_LENGTH];
int i, t;
+ int err;
- if (!(guillemot = kmalloc(sizeof(struct guillemot), GFP_KERNEL)))
- return;
- memset(guillemot, 0, sizeof(struct guillemot));
-
- gameport->private = guillemot;
+ if (!(guillemot = kcalloc(1, sizeof(struct guillemot), GFP_KERNEL)))
+ return -ENOMEM;
guillemot->gameport = gameport;
- init_timer(&guillemot->timer);
- guillemot->timer.data = (long) guillemot;
- guillemot->timer.function = guillemot_timer;
- if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW))
+ gameport_set_drvdata(gameport, guillemot);
+
+ err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
+ if (err)
goto fail1;
i = guillemot_read_packet(gameport, data);
- if (i != GUILLEMOT_MAX_LENGTH * 8 || data[0] != 0x55 || data[16] != 0xaa)
+ if (i != GUILLEMOT_MAX_LENGTH * 8 || data[0] != 0x55 || data[16] != 0xaa) {
+ err = -ENODEV;
goto fail2;
+ }
for (i = 0; guillemot_type[i].name; i++)
if (guillemot_type[i].id == data[11])
if (!guillemot_type[i].name) {
printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n",
gameport->phys, data[12], data[13], data[11], data[14], data[15]);
+ err = -ENODEV;
goto fail2;
}
+ gameport_set_poll_handler(gameport, guillemot_poll);
+ gameport_set_poll_interval(gameport, 20);
+
sprintf(guillemot->phys, "%s/input0", gameport->phys);
guillemot->type = guillemot_type + i;
guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++) {
- set_bit(t, guillemot->dev.absbit);
- guillemot->dev.absmin[t] = 0;
- guillemot->dev.absmax[t] = 255;
- }
+ for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
+ input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0);
- if (guillemot->type->hat)
- for (i = 0; i < 2; i++) {
- t = ABS_HAT0X + i;
- set_bit(t, guillemot->dev.absbit);
- guillemot->dev.absmin[t] = -1;
- guillemot->dev.absmax[t] = 1;
- }
+ if (guillemot->type->hat) {
+ input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0);
+ input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0);
+ }
for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++)
set_bit(t, guillemot->dev.keybit);
printk(KERN_INFO "input: %s ver %d.%02d on %s\n",
guillemot->type->name, data[14], data[15], gameport->phys);
- return;
+ return 0;
+
fail2: gameport_close(gameport);
-fail1: kfree(guillemot);
+fail1: gameport_set_drvdata(gameport, NULL);
+ kfree(guillemot);
+ return err;
}
static void guillemot_disconnect(struct gameport *gameport)
{
- struct guillemot *guillemot = gameport->private;
+ struct guillemot *guillemot = gameport_get_drvdata(gameport);
+
printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys);
input_unregister_device(&guillemot->dev);
gameport_close(gameport);
kfree(guillemot);
}
-static struct gameport_dev guillemot_dev = {
- .connect = guillemot_connect,
- .disconnect = guillemot_disconnect,
+static struct gameport_driver guillemot_drv = {
+ .driver = {
+ .name = "guillemot",
+ },
+ .description = DRIVER_DESC,
+ .connect = guillemot_connect,
+ .disconnect = guillemot_disconnect,
};
-int __init guillemot_init(void)
+static int __init guillemot_init(void)
{
- gameport_register_device(&guillemot_dev);
+ gameport_register_driver(&guillemot_drv);
return 0;
}
-void __exit guillemot_exit(void)
+static void __exit guillemot_exit(void)
{
- gameport_unregister_device(&guillemot_dev);
+ gameport_unregister_driver(&guillemot_drv);
}
module_init(guillemot_init);