Re: [PATCH] input: support maple controller on SEGA Dreamcast

2008-02-24 Thread Adrian McMenamin
Add support for the Dreamcast maple controller (as a joystick).

Earlier patches caused subdevice detection headaches. Please use this one.

Signed-off-by: Adrian McMenamin <[EMAIL PROTECTED]>
---

diff -ruN ./a/drivers/input/joystick/Kconfig ./b/drivers/input/joystick/Kconfig
--- ./a/drivers/input/joystick/Kconfig  2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Kconfig  2008-02-24 13:59:04.0 +
@@ -282,4 +282,17 @@
  This option enables support for the LED which surrounds the Big X on
  XBox 360 controller.
 
+config JOYSTICK_MAPLE
+   tristate "Dreamcast control pad"
+   depends on SH_DREAMCAST
+   select MAPLE
+   help
+ Say Y here if you have a SEGA Dreamcast and want to use your
+ controller.
+
+ Most Dreamcast users will say Y.
+
+ To compile this as a module choose M here: the
+ module will be called maplecontrol.
+
 endif
diff -ruN ./a/drivers/input/joystick/Makefile 
./b/drivers/input/joystick/Makefile
--- ./a/drivers/input/joystick/Makefile 2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Makefile 2008-02-24 13:59:04.0 +
@@ -27,5 +27,6 @@
 obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
 obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
 obj-$(CONFIG_JOYSTICK_XPAD)+= xpad.o
+obj-$(CONFIG_JOYSTICK_MAPLE)   += maplecontrol.o
 
 obj-$(CONFIG_JOYSTICK_IFORCE)  += iforce/
diff -ruN ./a/drivers/input/joystick/maplecontrol.c 
./b/drivers/input/joystick/maplecontrol.c
--- ./a/drivers/input/joystick/maplecontrol.c   1970-01-01 01:00:00.0 
+0100
+++ ./b/drivers/input/joystick/maplecontrol.c   2008-02-24 22:56:31.0 
+
@@ -0,0 +1,222 @@
+/*
+ * SEGA Dreamcast controller driver
+ * Based on drivers/usb/iforce.c
+ *
+ * Copyright Yaegashi Takeshi, 2001
+ * Porting to 2.6 by Adrian McMenamin, copyright 2008
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_AUTHOR("YAEGASHI Takeshi <[EMAIL PROTECTED]>");
+MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
+MODULE_LICENSE("GPL");
+
+struct dc_pad {
+   struct input_dev *dev;
+   struct maple_device *mdev;
+   int open;
+};
+
+static void dc_pad_callback(struct mapleq *mq)
+{
+   unsigned short buttons;
+   struct maple_device *mapledev = mq->dev;
+   struct dc_pad *pad = mapledev->private_data;
+   struct input_dev *dev = pad->dev;
+   unsigned char *res = mq->recvbuf;
+
+   buttons = ~cpu_to_le16(*(unsigned short *)(res + 8));
+
+   input_report_abs(dev, ABS_HAT0Y,
+(buttons & 0x0010 ? -1:0) + (buttons & 0x0020 ? 1:0));
+   input_report_abs(dev, ABS_HAT0X,
+(buttons & 0x0040 ? -1:0) + (buttons & 0x0080 ? 1:0));
+   input_report_abs(dev, ABS_HAT1Y,
+(buttons & 0x1000 ? -1:0) + (buttons & 0x2000 ? 1:0));
+   input_report_abs(dev, ABS_HAT1X,
+(buttons & 0x4000 ? -1:0) + (buttons & 0x8000 ? 1:0));
+
+   input_report_key(dev, BTN_C,  buttons & 0x0001);
+   input_report_key(dev, BTN_B,  buttons & 0x0002);
+   input_report_key(dev, BTN_A,  buttons & 0x0004);
+   input_report_key(dev, BTN_START,  buttons & 0x0008);
+   input_report_key(dev, BTN_Z,  buttons & 0x0100);
+   input_report_key(dev, BTN_Y,  buttons & 0x0200);
+   input_report_key(dev, BTN_X,  buttons & 0x0400);
+   input_report_key(dev, BTN_SELECT, buttons & 0x0800);
+
+   input_report_abs(dev, ABS_GAS,   res[10]);
+   input_report_abs(dev, ABS_BRAKE, res[11]);
+   input_report_abs(dev, ABS_X, res[12]);
+   input_report_abs(dev, ABS_Y, res[13]);
+   input_report_abs(dev, ABS_RX,res[14]);
+   input_report_abs(dev, ABS_RY,res[15]);
+}
+
+static int dc_pad_connect(struct maple_device *mdev)
+{
+   int i, error;
+   unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);
+   struct dc_pad *pad;
+   struct input_dev *dev;
+
+   const short btn_bit[32] = {
+   BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
+   BTN_Z, BTN_Y, BTN_X, BTN_SELECT, -1, -1, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1,
+   };
+
+   const short abs_bit[32] = {
+   -1, -1, -1, -1, ABS_HAT0Y, ABS_HAT0Y, ABS_HAT0X, ABS_HAT0X,
+   -1, -1, -1, -1, ABS_HAT1Y, ABS_HAT1Y, ABS_HAT1X, ABS_HAT1X,
+   ABS_GAS, ABS_BRAKE, ABS_X, ABS_Y, ABS_RX, ABS_RY, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1,
+   };
+
+   pad = kzalloc(sizeof(struct dc_pad), GFP_KERNEL);
+   if (!pad){
+   error = ENOMEM;
+   goto fail_nomem_1;
+   }
+
+   dev = input_allocate_device();
+   if (!dev) {
+   error = ENOMEM;
+   goto fail_nomem_2;
+ 

[PATCH] input: support maple controller on SEGA Dreamcast

2008-02-24 Thread Adrian McMenamin
This is a port of the old (never in mainline) 2.4 driver.

(It also fixes some issues with earlier patches which should be
discarded for this)


Signed-off-by: Adrian McMenamin <[EMAIL PROTECTED]>
---

diff -ruN ./a/drivers/input/joystick/Kconfig ./b/drivers/input/joystick/Kconfig
--- ./a/drivers/input/joystick/Kconfig  2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Kconfig  2008-02-24 13:59:04.0 +
@@ -282,4 +282,17 @@
  This option enables support for the LED which surrounds the Big X on
  XBox 360 controller.
 
+config JOYSTICK_MAPLE
+   tristate "Dreamcast control pad"
+   depends on SH_DREAMCAST
+   select MAPLE
+   help
+ Say Y here if you have a SEGA Dreamcast and want to use your
+ controller.
+
+ Most Dreamcast users will say Y.
+
+ To compile this as a module choose M here: the
+ module will be called maplecontrol.
+
 endif
diff -ruN ./a/drivers/input/joystick/Makefile 
./b/drivers/input/joystick/Makefile
--- ./a/drivers/input/joystick/Makefile 2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Makefile 2008-02-24 13:59:04.0 +
@@ -27,5 +27,6 @@
 obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
 obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
 obj-$(CONFIG_JOYSTICK_XPAD)+= xpad.o
+obj-$(CONFIG_JOYSTICK_MAPLE)   += maplecontrol.o
 
 obj-$(CONFIG_JOYSTICK_IFORCE)  += iforce/
diff -ruN ./a/drivers/input/joystick/maplecontrol.c 
./b/drivers/input/joystick/maplecontrol.c
--- ./a/drivers/input/joystick/maplecontrol.c   1970-01-01 01:00:00.0 
+0100
+++ ./b/drivers/input/joystick/maplecontrol.c   2008-02-24 13:59:04.0 
+
@@ -0,0 +1,252 @@
+/*
+ * SEGA Dreamcast controller driver
+ * Based on drivers/usb/iforce.c
+ *
+ * Copyright Yaegashi Takeshi, 2001
+ * Porting to 2.6 by Adrian McMenamin, copyright 2008
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_AUTHOR("YAEGASHI Takeshi <[EMAIL PROTECTED]>");
+MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
+MODULE_LICENSE("GPL");
+
+struct dc_pad {
+   struct input_dev *dev;
+   struct maple_device *mdev;
+   int open;
+};
+
+static void dc_pad_callback_idle(struct mapleq *mq)
+{
+}
+
+static void dc_pad_callback(struct mapleq *mq)
+{
+   unsigned short buttons;
+   struct maple_device *mapledev = mq->dev;
+   struct dc_pad *pad = mapledev->private_data;
+   struct input_dev *dev = pad->dev;
+   unsigned char *res = mq->recvbuf;
+
+   buttons = ~cpu_to_le16(*(unsigned short *)(res + 8));
+
+   input_report_abs(dev, ABS_HAT0Y,
+(buttons & 0x0010 ? -1:0) + (buttons & 0x0020 ? 1:0));
+   input_report_abs(dev, ABS_HAT0X,
+(buttons & 0x0040 ? -1:0) + (buttons & 0x0080 ? 1:0));
+   input_report_abs(dev, ABS_HAT1Y,
+(buttons & 0x1000 ? -1:0) + (buttons & 0x2000 ? 1:0));
+   input_report_abs(dev, ABS_HAT1X,
+(buttons & 0x4000 ? -1:0) + (buttons & 0x8000 ? 1:0));
+
+   input_report_key(dev, BTN_C,  buttons & 0x0001);
+   input_report_key(dev, BTN_B,  buttons & 0x0002);
+   input_report_key(dev, BTN_A,  buttons & 0x0004);
+   input_report_key(dev, BTN_START,  buttons & 0x0008);
+   input_report_key(dev, BTN_Z,  buttons & 0x0100);
+   input_report_key(dev, BTN_Y,  buttons & 0x0200);
+   input_report_key(dev, BTN_X,  buttons & 0x0400);
+   input_report_key(dev, BTN_SELECT, buttons & 0x0800);
+
+   input_report_abs(dev, ABS_GAS,   res[10]);
+   input_report_abs(dev, ABS_BRAKE, res[11]);
+   input_report_abs(dev, ABS_X, res[12]);
+   input_report_abs(dev, ABS_Y, res[13]);
+   input_report_abs(dev, ABS_RX,res[14]);
+   input_report_abs(dev, ABS_RY,res[15]);
+}
+
+static int dc_pad_open(struct input_dev *dev)
+{
+   struct dc_pad *pad = dev->private;
+   if (!pad->open)
+   maple_getcond_callback(pad->mdev, dc_pad_callback, HZ/50,
+   MAPLE_FUNC_CONTROLLER);
+   pad->open++;
+   return 0;
+
+}
+
+static void dc_pad_close(struct input_dev *dev)
+{
+   struct dc_pad *pad = dev->private;
+
+   pad->open--;
+   if (pad->open)
+   return;
+
+   /* Almost never call something that does nothing */
+   maple_getcond_callback(pad->mdev, dc_pad_callback_idle, 0x,
+   MAPLE_FUNC_CONTROLLER);
+}
+
+static int dc_pad_connect(struct maple_device *mdev)
+{
+   int i, error;
+   unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);
+   struct dc_pad *pad;
+   struct input_dev *dev;
+
+   const short btn_bit[32] = {
+   BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
+   BTN_Z, BTN_Y, BTN_X, BTN_SELECT, -1, -1, -1, -1,
+   -1, 

[PATCH] input: support maple controller on SEGA Dreamcast

2008-02-24 Thread Adrian McMenamin
This is a port of the old (never in mainline) 2.4 driver.

(It also fixes some issues with earlier patches which should be
discarded for this)


Signed-off-by: Adrian McMenamin [EMAIL PROTECTED]
---

diff -ruN ./a/drivers/input/joystick/Kconfig ./b/drivers/input/joystick/Kconfig
--- ./a/drivers/input/joystick/Kconfig  2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Kconfig  2008-02-24 13:59:04.0 +
@@ -282,4 +282,17 @@
  This option enables support for the LED which surrounds the Big X on
  XBox 360 controller.
 
+config JOYSTICK_MAPLE
+   tristate Dreamcast control pad
+   depends on SH_DREAMCAST
+   select MAPLE
+   help
+ Say Y here if you have a SEGA Dreamcast and want to use your
+ controller.
+
+ Most Dreamcast users will say Y.
+
+ To compile this as a module choose M here: the
+ module will be called maplecontrol.
+
 endif
diff -ruN ./a/drivers/input/joystick/Makefile 
./b/drivers/input/joystick/Makefile
--- ./a/drivers/input/joystick/Makefile 2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Makefile 2008-02-24 13:59:04.0 +
@@ -27,5 +27,6 @@
 obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
 obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
 obj-$(CONFIG_JOYSTICK_XPAD)+= xpad.o
+obj-$(CONFIG_JOYSTICK_MAPLE)   += maplecontrol.o
 
 obj-$(CONFIG_JOYSTICK_IFORCE)  += iforce/
diff -ruN ./a/drivers/input/joystick/maplecontrol.c 
./b/drivers/input/joystick/maplecontrol.c
--- ./a/drivers/input/joystick/maplecontrol.c   1970-01-01 01:00:00.0 
+0100
+++ ./b/drivers/input/joystick/maplecontrol.c   2008-02-24 13:59:04.0 
+
@@ -0,0 +1,252 @@
+/*
+ * SEGA Dreamcast controller driver
+ * Based on drivers/usb/iforce.c
+ *
+ * Copyright Yaegashi Takeshi, 2001
+ * Porting to 2.6 by Adrian McMenamin, copyright 2008
+ */
+
+#include linux/kernel.h
+#include linux/slab.h
+#include linux/input.h
+#include linux/module.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/maple.h
+#include asm/mach/maple.h
+
+MODULE_AUTHOR(YAEGASHI Takeshi [EMAIL PROTECTED]);
+MODULE_DESCRIPTION(SEGA Dreamcast controller driver);
+MODULE_LICENSE(GPL);
+
+struct dc_pad {
+   struct input_dev *dev;
+   struct maple_device *mdev;
+   int open;
+};
+
+static void dc_pad_callback_idle(struct mapleq *mq)
+{
+}
+
+static void dc_pad_callback(struct mapleq *mq)
+{
+   unsigned short buttons;
+   struct maple_device *mapledev = mq-dev;
+   struct dc_pad *pad = mapledev-private_data;
+   struct input_dev *dev = pad-dev;
+   unsigned char *res = mq-recvbuf;
+
+   buttons = ~cpu_to_le16(*(unsigned short *)(res + 8));
+
+   input_report_abs(dev, ABS_HAT0Y,
+(buttons  0x0010 ? -1:0) + (buttons  0x0020 ? 1:0));
+   input_report_abs(dev, ABS_HAT0X,
+(buttons  0x0040 ? -1:0) + (buttons  0x0080 ? 1:0));
+   input_report_abs(dev, ABS_HAT1Y,
+(buttons  0x1000 ? -1:0) + (buttons  0x2000 ? 1:0));
+   input_report_abs(dev, ABS_HAT1X,
+(buttons  0x4000 ? -1:0) + (buttons  0x8000 ? 1:0));
+
+   input_report_key(dev, BTN_C,  buttons  0x0001);
+   input_report_key(dev, BTN_B,  buttons  0x0002);
+   input_report_key(dev, BTN_A,  buttons  0x0004);
+   input_report_key(dev, BTN_START,  buttons  0x0008);
+   input_report_key(dev, BTN_Z,  buttons  0x0100);
+   input_report_key(dev, BTN_Y,  buttons  0x0200);
+   input_report_key(dev, BTN_X,  buttons  0x0400);
+   input_report_key(dev, BTN_SELECT, buttons  0x0800);
+
+   input_report_abs(dev, ABS_GAS,   res[10]);
+   input_report_abs(dev, ABS_BRAKE, res[11]);
+   input_report_abs(dev, ABS_X, res[12]);
+   input_report_abs(dev, ABS_Y, res[13]);
+   input_report_abs(dev, ABS_RX,res[14]);
+   input_report_abs(dev, ABS_RY,res[15]);
+}
+
+static int dc_pad_open(struct input_dev *dev)
+{
+   struct dc_pad *pad = dev-private;
+   if (!pad-open)
+   maple_getcond_callback(pad-mdev, dc_pad_callback, HZ/50,
+   MAPLE_FUNC_CONTROLLER);
+   pad-open++;
+   return 0;
+
+}
+
+static void dc_pad_close(struct input_dev *dev)
+{
+   struct dc_pad *pad = dev-private;
+
+   pad-open--;
+   if (pad-open)
+   return;
+
+   /* Almost never call something that does nothing */
+   maple_getcond_callback(pad-mdev, dc_pad_callback_idle, 0x,
+   MAPLE_FUNC_CONTROLLER);
+}
+
+static int dc_pad_connect(struct maple_device *mdev)
+{
+   int i, error;
+   unsigned long data = be32_to_cpu(mdev-devinfo.function_data[0]);
+   struct dc_pad *pad;
+   struct input_dev *dev;
+
+   const short btn_bit[32] = {
+   BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
+   

Re: [PATCH] input: support maple controller on SEGA Dreamcast

2008-02-24 Thread Adrian McMenamin
Add support for the Dreamcast maple controller (as a joystick).

Earlier patches caused subdevice detection headaches. Please use this one.

Signed-off-by: Adrian McMenamin [EMAIL PROTECTED]
---

diff -ruN ./a/drivers/input/joystick/Kconfig ./b/drivers/input/joystick/Kconfig
--- ./a/drivers/input/joystick/Kconfig  2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Kconfig  2008-02-24 13:59:04.0 +
@@ -282,4 +282,17 @@
  This option enables support for the LED which surrounds the Big X on
  XBox 360 controller.
 
+config JOYSTICK_MAPLE
+   tristate Dreamcast control pad
+   depends on SH_DREAMCAST
+   select MAPLE
+   help
+ Say Y here if you have a SEGA Dreamcast and want to use your
+ controller.
+
+ Most Dreamcast users will say Y.
+
+ To compile this as a module choose M here: the
+ module will be called maplecontrol.
+
 endif
diff -ruN ./a/drivers/input/joystick/Makefile 
./b/drivers/input/joystick/Makefile
--- ./a/drivers/input/joystick/Makefile 2008-02-21 20:42:07.0 +
+++ ./b/drivers/input/joystick/Makefile 2008-02-24 13:59:04.0 +
@@ -27,5 +27,6 @@
 obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
 obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
 obj-$(CONFIG_JOYSTICK_XPAD)+= xpad.o
+obj-$(CONFIG_JOYSTICK_MAPLE)   += maplecontrol.o
 
 obj-$(CONFIG_JOYSTICK_IFORCE)  += iforce/
diff -ruN ./a/drivers/input/joystick/maplecontrol.c 
./b/drivers/input/joystick/maplecontrol.c
--- ./a/drivers/input/joystick/maplecontrol.c   1970-01-01 01:00:00.0 
+0100
+++ ./b/drivers/input/joystick/maplecontrol.c   2008-02-24 22:56:31.0 
+
@@ -0,0 +1,222 @@
+/*
+ * SEGA Dreamcast controller driver
+ * Based on drivers/usb/iforce.c
+ *
+ * Copyright Yaegashi Takeshi, 2001
+ * Porting to 2.6 by Adrian McMenamin, copyright 2008
+ */
+
+#include linux/kernel.h
+#include linux/slab.h
+#include linux/input.h
+#include linux/module.h
+#include linux/init.h
+#include linux/timer.h
+#include linux/maple.h
+#include asm/mach/maple.h
+
+MODULE_AUTHOR(YAEGASHI Takeshi [EMAIL PROTECTED]);
+MODULE_DESCRIPTION(SEGA Dreamcast controller driver);
+MODULE_LICENSE(GPL);
+
+struct dc_pad {
+   struct input_dev *dev;
+   struct maple_device *mdev;
+   int open;
+};
+
+static void dc_pad_callback(struct mapleq *mq)
+{
+   unsigned short buttons;
+   struct maple_device *mapledev = mq-dev;
+   struct dc_pad *pad = mapledev-private_data;
+   struct input_dev *dev = pad-dev;
+   unsigned char *res = mq-recvbuf;
+
+   buttons = ~cpu_to_le16(*(unsigned short *)(res + 8));
+
+   input_report_abs(dev, ABS_HAT0Y,
+(buttons  0x0010 ? -1:0) + (buttons  0x0020 ? 1:0));
+   input_report_abs(dev, ABS_HAT0X,
+(buttons  0x0040 ? -1:0) + (buttons  0x0080 ? 1:0));
+   input_report_abs(dev, ABS_HAT1Y,
+(buttons  0x1000 ? -1:0) + (buttons  0x2000 ? 1:0));
+   input_report_abs(dev, ABS_HAT1X,
+(buttons  0x4000 ? -1:0) + (buttons  0x8000 ? 1:0));
+
+   input_report_key(dev, BTN_C,  buttons  0x0001);
+   input_report_key(dev, BTN_B,  buttons  0x0002);
+   input_report_key(dev, BTN_A,  buttons  0x0004);
+   input_report_key(dev, BTN_START,  buttons  0x0008);
+   input_report_key(dev, BTN_Z,  buttons  0x0100);
+   input_report_key(dev, BTN_Y,  buttons  0x0200);
+   input_report_key(dev, BTN_X,  buttons  0x0400);
+   input_report_key(dev, BTN_SELECT, buttons  0x0800);
+
+   input_report_abs(dev, ABS_GAS,   res[10]);
+   input_report_abs(dev, ABS_BRAKE, res[11]);
+   input_report_abs(dev, ABS_X, res[12]);
+   input_report_abs(dev, ABS_Y, res[13]);
+   input_report_abs(dev, ABS_RX,res[14]);
+   input_report_abs(dev, ABS_RY,res[15]);
+}
+
+static int dc_pad_connect(struct maple_device *mdev)
+{
+   int i, error;
+   unsigned long data = be32_to_cpu(mdev-devinfo.function_data[0]);
+   struct dc_pad *pad;
+   struct input_dev *dev;
+
+   const short btn_bit[32] = {
+   BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
+   BTN_Z, BTN_Y, BTN_X, BTN_SELECT, -1, -1, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1,
+   };
+
+   const short abs_bit[32] = {
+   -1, -1, -1, -1, ABS_HAT0Y, ABS_HAT0Y, ABS_HAT0X, ABS_HAT0X,
+   -1, -1, -1, -1, ABS_HAT1Y, ABS_HAT1Y, ABS_HAT1X, ABS_HAT1X,
+   ABS_GAS, ABS_BRAKE, ABS_X, ABS_Y, ABS_RX, ABS_RY, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1,
+   };
+
+   pad = kzalloc(sizeof(struct dc_pad), GFP_KERNEL);
+   if (!pad){
+   error = ENOMEM;
+   goto fail_nomem_1;
+   }
+
+   dev = input_allocate_device();
+   if (!dev)