KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
};
-static char *nkbd_name = "Newton Keyboard";
-
struct nkbd {
unsigned char keycode[128];
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
char phys[32];
};
-irqreturn_t nkbd_interrupt(struct serio *serio,
+static irqreturn_t nkbd_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
- struct nkbd *nkbd = serio->private;
+ struct nkbd *nkbd = serio_get_drvdata(serio);
/* invalid scan codes are probably the init sequence, so we ignore them */
if (nkbd->keycode[data & NKBD_KEY]) {
- input_regs(&nkbd->dev, regs);
- input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
- input_sync(&nkbd->dev);
+ input_regs(nkbd->dev, regs);
+ input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
+ input_sync(nkbd->dev);
}
else if (data == 0xe7) /* end of init sequence */
- printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
+ printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys);
return IRQ_HANDLED;
}
-void nkbd_connect(struct serio *serio, struct serio_driver *drv)
+static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct nkbd *nkbd;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
int i;
- if (serio->type != (SERIO_RS232 | SERIO_NEWTON))
- return;
-
- if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
- return;
-
- memset(nkbd, 0, sizeof(struct nkbd));
-
- nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!nkbd || !input_dev)
+ goto fail;
nkbd->serio = serio;
-
- init_input_dev(&nkbd->dev);
- nkbd->dev.keycode = nkbd->keycode;
- nkbd->dev.keycodesize = sizeof(unsigned char);
- nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
- nkbd->dev.private = nkbd;
- serio->private = nkbd;
-
- if (serio_open(serio, drv)) {
- kfree(nkbd);
- return;
- }
-
+ nkbd->dev = input_dev;
+ sprintf(nkbd->phys, "%s/input0", serio->phys);
memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
+
+ input_dev->name = "Newton Keyboard";
+ input_dev->phys = nkbd->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_NEWTON;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = nkbd;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->keycode = nkbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
for (i = 0; i < 128; i++)
- set_bit(nkbd->keycode[i], nkbd->dev.keybit);
- clear_bit(0, nkbd->dev.keybit);
+ set_bit(nkbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
- sprintf(nkbd->phys, "%s/input0", serio->phys);
+ serio_set_drvdata(serio, nkbd);
- nkbd->dev.name = nkbd_name;
- nkbd->dev.phys = nkbd->phys;
- nkbd->dev.id.bustype = BUS_RS232;
- nkbd->dev.id.vendor = SERIO_NEWTON;
- nkbd->dev.id.product = 0x0001;
- nkbd->dev.id.version = 0x0100;
- nkbd->dev.dev = &serio->dev;
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail;
- input_register_device(&nkbd->dev);
+ input_register_device(nkbd->dev);
+ return 0;
- printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(nkbd);
+ return err;
}
-void nkbd_disconnect(struct serio *serio)
+static void nkbd_disconnect(struct serio *serio)
{
- struct nkbd *nkbd = serio->private;
- input_unregister_device(&nkbd->dev);
+ struct nkbd *nkbd = serio_get_drvdata(serio);
+
serio_close(serio);
+ serio_set_drvdata(serio, NULL);
+ input_unregister_device(nkbd->dev);
kfree(nkbd);
}
-struct serio_driver nkbd_drv = {
+static struct serio_device_id nkbd_serio_ids[] = {
+ {
+ .type = SERIO_RS232,
+ .proto = SERIO_NEWTON,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, nkbd_serio_ids);
+
+static struct serio_driver nkbd_drv = {
.driver = {
.name = "newtonkbd",
},
.description = DRIVER_DESC,
+ .id_table = nkbd_serio_ids,
.interrupt = nkbd_interrupt,
.connect = nkbd_connect,
.disconnect = nkbd_disconnect,
};
-int __init nkbd_init(void)
+static int __init nkbd_init(void)
{
serio_register_driver(&nkbd_drv);
return 0;
}
-void __exit nkbd_exit(void)
+static void __exit nkbd_exit(void)
{
serio_unregister_driver(&nkbd_drv);
}