diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2008-06-27 13:55:00 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-06-27 13:55:00 -0700 |
| commit | d3d8f7cbd2aa88b680430dfea88dea6bb3a73250 (patch) | |
| tree | c8d1190e3bfae031938f762db9306ff3249ea66e | |
| parent | 64e03ec8de0d2eb3741c6c76abdffe43f78bc90a (diff) | |
| download | patches-d3d8f7cbd2aa88b680430dfea88dea6bb3a73250.tar.gz | |
deleted input driver as it moved to staging tree
| -rw-r--r-- | input-add-mimio-xi-driver.patch | 968 | ||||
| -rw-r--r-- | series | 1 |
2 files changed, 0 insertions, 969 deletions
diff --git a/input-add-mimio-xi-driver.patch b/input-add-mimio-xi-driver.patch deleted file mode 100644 index 286bbc788be7be..00000000000000 --- a/input-add-mimio-xi-driver.patch +++ /dev/null @@ -1,968 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Tue, 24 Jun 2008 15:19:47 +0100 -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: input: add mimio xi driver - -This patch adds the Mimio Xi interactive whiteboard driver to the tree. - -It was originally written by mwilder@cs.nmsu.edu, but cleaned up and -forward ported by me to the latest kernel version. - - -Cc: Phil Hannent <phil@hannent.co.uk> -Cc: <mwilder@cs.nmsu.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/input/misc/Kconfig | 11 - drivers/input/misc/Makefile | 1 - drivers/input/misc/mimio.c | 913 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 925 insertions(+) - ---- a/drivers/input/misc/Kconfig -+++ b/drivers/input/misc/Kconfig -@@ -164,6 +164,17 @@ config INPUT_POWERMATE - To compile this driver as a module, choose M here: the - module will be called powermate. - -+config INPUT_MIMIO -+ tristate "Mimio Xi interactive whiteboard support" -+ depends on USB_ARCH_HAS_HCD -+ select USB -+ help -+ Say Y here if you want to use a Mimio Xi interactive -+ whiteboard device. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called mimio. -+ - config INPUT_YEALINK - tristate "Yealink usb-p1k voip phone" - depends on EXPERIMENTAL ---- a/drivers/input/misc/Makefile -+++ b/drivers/input/misc/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_r - obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o - obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o - obj-$(CONFIG_INPUT_POWERMATE) += powermate.o -+obj-$(CONFIG_INPUT_MIMIO) += mimio.o - obj-$(CONFIG_INPUT_YEALINK) += yealink.o - obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o - obj-$(CONFIG_INPUT_UINPUT) += uinput.o ---- /dev/null -+++ b/drivers/input/misc/mimio.c -@@ -0,0 +1,913 @@ -+/* -+ * Hardware event => input event mapping: -+ * -+ * -+ * -+ input.h:#define BTN_TOOL_PEN 0x140 black -+ input.h:#define BTN_TOOL_RUBBER 0x141 blue -+ input.h:#define BTN_TOOL_BRUSH 0x142 green -+ input.h:#define BTN_TOOL_PENCIL 0x143 red -+ input.h:#define BTN_TOOL_AIRBRUSH 0x144 eraser -+ input.h:#define BTN_TOOL_FINGER 0x145 small eraser -+ input.h:#define BTN_TOOL_MOUSE 0x146 mimio interactive -+ input.h:#define BTN_TOOL_LENS 0x147 mimio interactive but1 -+ input.h:#define LOCALBTN_TOOL_EXTRA1 0x14a mimio interactive but2 == BTN_TOUCH -+ input.h:#define LOCALBTN_TOOL_EXTRA2 0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS -+ input.h:#define LOCALBTN_TOOL_EXTRA3 0x14c unused == BTN_STYLUS2 -+ input.h:#define BTN_TOOL_DOUBLETAP 0x14d unused -+ input.h:#define BTN_TOOL_TRIPLETAP 0x14e unused -+ * -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_K) => EV_KEY BIT(BTN_TOOL_PEN) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_B) => EV_KEY BIT(BTN_TOOL_RUBBER) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_G) => EV_KEY BIT(BTN_TOOL_BRUSH) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_R) => EV_KEY BIT(BTN_TOOL_PENCIL) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_E) => EV_KEY BIT(BTN_TOOL_AIRBRUSH) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_ES) => EV_KEY BIT(BTN_TOOL_FINGER) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_I) => EV_KEY BIT(BTN_TOOL_MOUSE) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_IL) => EV_KEY BIT(BTN_TOOL_LENS) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_IR) => EV_KEY BIT(BTN_TOOL_DOUBLETAP) -+ * MIMIO_EV_PENDOWN(MIMIO_PEN_EX) => EV_KEY BIT(BTN_TOOL_TRIPLETAP) -+ * MIMIO_EV_PENDATA => EV_ABS BIT(ABS_X), BIT(ABS_Y) -+ * MIMIO_EV_MEMRESET => EV_KEY BIT(BTN_0) -+ * MIMIO_EV_ACC(ACC_NEWPAGE) => EV_KEY BIT(BTN_1) -+ * MIMIO_EV_ACC(ACC_TAGPAGE) => EV_KEY BIT(BTN_2) -+ * MIMIO_EV_ACC(ACC_PRINTPAGE) => EV_KEY BIT(BTN_3) -+ * MIMIO_EV_ACC(ACC_MAXIMIZE) => EV_KEY BIT(BTN_4) -+ * MIMIO_EV_ACC(ACC_FINDCTLPNL) => EV_KEY BIT(BTN_5) -+ * -+ * -+ * open issues: -+ * - cold-load of data captured when mimio in standalone mode not yet -+ * supported; need to snoop Win32 box to see datastream for this. -+ * - mimio mouse not yet supported; need to snoop Win32 box to see the -+ * datastream for this. -+ */ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/spinlock.h> -+#include <linux/input.h> -+#include <linux/usb.h> -+ -+#define DRIVER_VERSION "v0.031" -+#define DRIVER_AUTHOR "mwilder@cs.nmsu.edu" -+#define DRIVER_DESC "USB mimio-xi driver" -+ -+enum {UPVALUE, DOWNVALUE, MOVEVALUE}; -+ -+#define MIMIO_XRANGE_MAX 9600 -+#define MIMIO_YRANGE_MAX 4800 -+ -+#define LOCALBTN_TOOL_EXTRA1 BTN_TOUCH -+#define LOCALBTN_TOOL_EXTRA2 BTN_STYLUS -+#define LOCALBTN_TOOL_EXTRA3 BTN_STYLUS2 -+ -+#define MIMIO_VENDOR_ID 0x08d3 -+#define MIMIO_PRODUCT_ID 0x0001 -+#define MIMIO_MAXPAYLOAD (8) -+#define MIMIO_MAXNAMELEN (64) -+#define MIMIO_TXWAIT (1) -+#define MIMIO_TXDONE (2) -+ -+#define MIMIO_EV_PENDOWN (0x22) -+#define MIMIO_EV_PENDATA (0x24) -+#define MIMIO_EV_PENUP (0x51) -+#define MIMIO_EV_MEMRESET (0x45) -+#define MIMIO_EV_ACC (0xb2) -+ -+#define MIMIO_PEN_K (1) /* black pen */ -+#define MIMIO_PEN_B (2) /* blue pen */ -+#define MIMIO_PEN_G (3) /* green pen */ -+#define MIMIO_PEN_R (4) /* red pen */ -+/* 5, 6, 7, 8 are extra pens */ -+#define MIMIO_PEN_E (9) /* big eraser */ -+#define MIMIO_PEN_ES (10) /* lil eraser */ -+#define MIMIO_PENJUMP_START (10) -+#define MIMIO_PENJUMP (6) -+#define MIMIO_PEN_I (17) /* mimio interactive */ -+#define MIMIO_PEN_IL (18) /* mimio interactive button 1 */ -+#define MIMIO_PEN_IR (19) /* mimio interactive button 2 */ -+ -+#define MIMIO_PEN_MAX (MIMIO_PEN_IR) -+ -+#define ACC_DONE (0) -+#define ACC_NEWPAGE (1) -+#define ACC_TAGPAGE (2) -+#define ACC_PRINTPAGE (4) -+#define ACC_MAXIMIZE (8) -+#define ACC_FINDCTLPNL (16) -+ -+#define isvalidtxsize(n) ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD) -+ -+ -+struct pktbuf { -+ unsigned char instr; -+ unsigned char buf[16]; -+ unsigned char *p; -+ unsigned char *q; -+}; -+ -+struct usbintendpt { -+ dma_addr_t dma; -+ struct urb *urb; -+ unsigned char *buf; -+ struct usb_endpoint_descriptor *desc; -+}; -+ -+struct mimio { -+ struct input_dev *idev; -+ struct usb_device *udev; -+ struct usb_interface *uifc; -+ int open; -+ int present; -+ int greeted; -+ int txflags; -+ char phys[MIMIO_MAXNAMELEN]; -+ struct usbintendpt in; -+ struct usbintendpt out; -+ struct pktbuf pktbuf; -+ unsigned char minor; -+ wait_queue_head_t waitq; -+ spinlock_t txlock; -+ void (*rxhandler)(struct mimio *, unsigned char *, unsigned int); -+ int last_pen_down; -+}; -+ -+static void mimio_close(struct input_dev *); -+static void mimio_dealloc(struct mimio *); -+static void mimio_disconnect(struct usb_interface *); -+static int mimio_greet(struct mimio *); -+static void mimio_irq_in(struct urb *); -+static void mimio_irq_out(struct urb *); -+static int mimio_open(struct input_dev *); -+static int mimio_probe(struct usb_interface *, const struct usb_device_id *); -+static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int); -+static int mimio_tx(struct mimio *, const char *, int); -+ -+static char mimio_name[] = "VirtualInk mimio-Xi"; -+static struct usb_device_id mimio_table [] = { -+ { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) }, -+ { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */ -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, mimio_table); -+ -+static struct usb_driver mimio_driver = { -+ .name = "mimio", -+ .probe = mimio_probe, -+ .disconnect = mimio_disconnect, -+ .id_table = mimio_table, -+}; -+ -+static DECLARE_MUTEX(disconnect_sem); -+ -+static void mimio_close(struct input_dev *idev) -+{ -+ struct mimio *mimio; -+ -+ mimio = input_get_drvdata(idev); -+ if (!mimio) { -+ dev_err(&idev->dev, "null mimio attached to input device\n"); -+ return; -+ } -+ -+ if (mimio->open <= 0) -+ dev_err(&idev->dev, "mimio not open.\n"); -+ else -+ mimio->open--; -+ -+ if (mimio->present == 0 && mimio->open == 0) -+ mimio_dealloc(mimio); -+} -+ -+static void mimio_dealloc(struct mimio *mimio) -+{ -+ if (mimio == NULL) -+ return; -+ -+ usb_kill_urb(mimio->in.urb); -+ -+ usb_kill_urb(mimio->out.urb); -+ -+ if (mimio->idev) { -+ input_unregister_device(mimio->idev); -+ if (mimio->idev->grab) -+ input_close_device(mimio->idev->grab); -+ else -+ dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL" -+ " -- didn't call input_close_device\n"); -+ } -+ -+ usb_free_urb(mimio->in.urb); -+ -+ usb_free_urb(mimio->out.urb); -+ -+ if (mimio->in.buf) { -+ usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf, -+ mimio->in.dma); -+ } -+ -+ if (mimio->out.buf) -+ usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf, -+ mimio->out.dma); -+ -+ if (mimio->idev) -+ input_free_device(mimio->idev); -+ -+ kfree(mimio); -+} -+ -+static void mimio_disconnect(struct usb_interface *ifc) -+{ -+ struct mimio *mimio; -+ -+ down(&disconnect_sem); -+ -+ mimio = usb_get_intfdata(ifc); -+ usb_set_intfdata(ifc, NULL); -+ dev_dbg(&mimio->idev->dev, "disconnect\n"); -+ -+ if (mimio) { -+ mimio->present = 0; -+ -+ if (mimio->open <= 0) -+ mimio_dealloc(mimio); -+ } -+ -+ up(&disconnect_sem); -+} -+ -+static int mimio_greet(struct mimio *mimio) -+{ -+ const struct grtpkt { -+ int nbytes; -+ unsigned delay; -+ char data[8]; -+ } grtpkts[] = { -+ { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } }, -+ { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } }, -+ { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } }, -+ { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } }, -+ { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } }, -+ { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, -+ }; -+ int rslt; -+ const struct grtpkt *pkt; -+ -+ for (pkt = grtpkts; pkt->nbytes; pkt++) { -+ rslt = mimio_tx(mimio, pkt->data, pkt->nbytes); -+ if (rslt) -+ return rslt; -+ if (pkt->delay) -+ msleep(pkt->delay); -+ } -+ -+ return 0; -+} -+ -+static void mimio_irq_in(struct urb *urb) -+{ -+ int rslt; -+ char *data; -+ const char *reason = "going down"; -+ struct mimio *mimio; -+ -+ mimio = urb->context; -+ -+ if (mimio == NULL) -+ /* paranoia */ -+ return; -+ -+ switch (urb->status) { -+ case 0: -+ /* success */ -+ break; -+ case -ETIMEDOUT: -+ reason = "timeout -- unplugged?"; -+ case -ECONNRESET: -+ case -ENOENT: -+ case -ESHUTDOWN: -+ dev_dbg(&mimio->idev->dev, "%s.\n", reason); -+ return; -+ default: -+ dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n", -+ urb->status); -+ goto exit; -+ } -+ data = mimio->in.buf; -+ -+ if (mimio->rxhandler) -+ mimio->rxhandler(mimio, data, urb->actual_length); -+exit: -+ /* -+ * Keep listening to device on same urb. -+ */ -+ rslt = usb_submit_urb(urb, GFP_ATOMIC); -+ if (rslt) -+ dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", -+ rslt); -+} -+ -+static void mimio_irq_out(struct urb *urb) -+{ -+ unsigned long flags; -+ struct mimio *mimio; -+ -+ mimio = urb->context; -+ -+ if (urb->status) -+ dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status); -+ -+ spin_lock_irqsave(&mimio->txlock, flags); -+ mimio->txflags |= MIMIO_TXDONE; -+ spin_unlock_irqrestore(&mimio->txlock, flags); -+ wmb(); -+ wake_up(&mimio->waitq); -+} -+ -+static int mimio_open(struct input_dev *idev) -+{ -+ int rslt; -+ struct mimio *mimio; -+ -+ rslt = 0; -+ down(&disconnect_sem); -+ mimio = input_get_drvdata(idev); -+ dev_dbg(&idev->dev, "mimio_open\n"); -+ -+ if (mimio == NULL) { -+ dev_err(&idev->dev, "null mimio.\n"); -+ rslt = -ENODEV; -+ goto exit; -+ } -+ -+ if (mimio->open++) -+ goto exit; -+ -+ if (mimio->present && !mimio->greeted) { -+ struct urb *urb = mimio->in.urb; -+ mimio->in.urb->dev = mimio->udev; -+ rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL); -+ if (rslt) { -+ dev_err(&idev->dev, "usb_submit_urb failure " -+ "(res = %d: %s). Not greeting.\n", -+ rslt, -+ (!urb ? "urb is NULL" : -+ (urb->hcpriv ? "urb->hcpriv is non-NULL" : -+ (!urb->complete ? "urb is not complete" : -+ (urb->number_of_packets <= 0 ? "urb has no packets" : -+ (urb->interval <= 0 ? "urb interval too small" : -+ "urb interval too large or some other error")))))); -+ rslt = -EIO; -+ goto exit; -+ } -+ rslt = mimio_greet(mimio); -+ if (rslt == 0) { -+ dev_dbg(&idev->dev, "Mimio greeted OK.\n"); -+ mimio->greeted = 1; -+ } else { -+ dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n", -+ rslt); -+ } -+ } -+ -+exit: -+ up(&disconnect_sem); -+ return rslt; -+} -+ -+static int mimio_probe(struct usb_interface *ifc, -+ const struct usb_device_id *id) -+{ -+ char path[64]; -+ int pipe, maxp; -+ struct mimio *mimio; -+ struct usb_device *udev; -+ struct usb_host_interface *hostifc; -+ struct input_dev *input_dev; -+ int res = 0; -+ int i; -+ -+ udev = interface_to_usbdev(ifc); -+ -+ mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL); -+ if (!mimio) -+ return -ENOMEM; -+ -+ input_dev = input_allocate_device(); -+ if (!input_dev) { -+ mimio_dealloc(mimio); -+ return -ENOMEM; -+ } -+ -+ mimio->uifc = ifc; -+ mimio->udev = udev; -+ mimio->pktbuf.p = mimio->pktbuf.buf; -+ mimio->pktbuf.q = mimio->pktbuf.buf; -+ /* init_input_dev(mimio->idev); */ -+ mimio->idev = input_dev; -+ init_waitqueue_head(&mimio->waitq); -+ spin_lock_init(&mimio->txlock); -+ hostifc = ifc->cur_altsetting; -+ -+ if (hostifc->desc.bNumEndpoints != 2) { -+ dev_err(&udev->dev, "Unexpected endpoint count: %d.\n", -+ hostifc->desc.bNumEndpoints); -+ mimio_dealloc(mimio); -+ return -ENODEV; -+ } -+ -+ mimio->in.desc = &(hostifc->endpoint[0].desc); -+ mimio->out.desc = &(hostifc->endpoint[1].desc); -+ -+ mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, -+ &mimio->in.dma); -+ mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, -+ &mimio->out.dma); -+ -+ if (mimio->in.buf == NULL || mimio->out.buf == NULL) { -+ dev_err(&udev->dev, "usb_buffer_alloc failure.\n"); -+ mimio_dealloc(mimio); -+ return -ENOMEM; -+ } -+ -+ mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL); -+ mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL); -+ -+ if (mimio->in.urb == NULL || mimio->out.urb == NULL) { -+ dev_err(&udev->dev, "usb_alloc_urb failure.\n"); -+ mimio_dealloc(mimio); -+ return -ENOMEM; -+ } -+ -+ /* -+ * Build the input urb. -+ */ -+ pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress); -+ maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); -+ if (maxp > MIMIO_MAXPAYLOAD) -+ maxp = MIMIO_MAXPAYLOAD; -+ usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp, -+ mimio_irq_in, mimio, mimio->in.desc->bInterval); -+ mimio->in.urb->transfer_dma = mimio->in.dma; -+ mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -+ -+ /* -+ * Build the output urb. -+ */ -+ pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress); -+ maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); -+ if (maxp > MIMIO_MAXPAYLOAD) -+ maxp = MIMIO_MAXPAYLOAD; -+ usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp, -+ mimio_irq_out, mimio, mimio->out.desc->bInterval); -+ mimio->out.urb->transfer_dma = mimio->out.dma; -+ mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -+ -+ /* -+ * Build input device info -+ */ -+ usb_make_path(udev, path, 64); -+ snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path); -+ input_set_drvdata(input_dev, mimio); -+ /* input_dev->dev = &ifc->dev; */ -+ input_dev->open = mimio_open; -+ input_dev->close = mimio_close; -+ input_dev->name = mimio_name; -+ input_dev->phys = mimio->phys; -+ input_dev->dev.parent = &ifc->dev; -+ -+ input_dev->id.bustype = BUS_USB; -+ input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor); -+ input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct); -+ input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice); -+ -+ input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); -+ for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i) -+ set_bit(i, input_dev->keybit); -+ -+ input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | -+ BIT_MASK(BTN_1) | -+ BIT_MASK(BTN_2) | -+ BIT_MASK(BTN_3) | -+ BIT_MASK(BTN_4) | -+ BIT_MASK(BTN_5); -+ /* input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */ -+ input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); -+ input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0); -+ input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0); -+ input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); -+ -+#if 0 -+ input_dev->absmin[ABS_X] = 0; -+ input_dev->absmin[ABS_Y] = 0; -+ input_dev->absmax[ABS_X] = 9600; -+ input_dev->absmax[ABS_Y] = 4800; -+ input_dev->absfuzz[ABS_X] = 0; -+ input_dev->absfuzz[ABS_Y] = 0; -+ input_dev->absflat[ABS_X] = 0; -+ input_dev->absflat[ABS_Y] = 0; -+#endif -+ -+#if 0 -+ /* this will just reduce the precision */ -+ input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */ -+ input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */ -+#endif -+ -+ /* -+ * Register the input device. -+ */ -+ res = input_register_device(mimio->idev); -+ if (res) { -+ dev_err(&udev->dev, "input_register_device failure (%d)\n", -+ res); -+ mimio_dealloc(mimio); -+ return -EIO; -+ } -+ dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n", -+ input_dev->name, input_dev->phys, res); -+ -+ usb_set_intfdata(ifc, mimio); -+ mimio->present = 1; -+ -+ /* -+ * Submit the input urb to the usb subsystem. -+ */ -+ mimio->in.urb->dev = mimio->udev; -+ res = usb_submit_urb(mimio->in.urb, GFP_KERNEL); -+ if (res) { -+ dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n", -+ res); -+ mimio_dealloc(mimio); -+ return -EIO; -+ } -+ -+ /* -+ * Attempt to greet the mimio after giving -+ * it some post-init settling time. -+ * -+ * note: sometimes this sleep interval isn't -+ * long enough to permit the device to re-init -+ * after a hot-swap; maybe need to bump it up. -+ * -+ * As it is, this probably breaks module unloading support! -+ */ -+ msleep(1024); -+ -+ res = mimio_greet(mimio); -+ if (res == 0) { -+ dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n"); -+ mimio->greeted = 1; -+ mimio->rxhandler = mimio_rx_handler; -+ } else { -+ dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res); -+ } -+ -+ return 0; -+} -+ -+static int handle_mimio_rx_penupdown(struct mimio *mimio, -+ int down, -+ const char *const instr[], -+ const int instr_ofst[]) -+{ -+ int penid, x; -+ if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3)) -+ return 1; /* partial pkt */ -+ -+ if (down) { -+ x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ -+ *(mimio->pktbuf.p + 2); -+ if (x != *(mimio->pktbuf.p + 3)) { -+ dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n", -+ down ? "DOWN":"UP"); -+ /* skip this event data */ -+ mimio->pktbuf.p += 4; -+ /* decode any remaining events */ -+ return 0; -+ } -+ penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2); -+ if (penid > MIMIO_PEN_MAX) { -+ dev_dbg(&mimio->idev->dev, -+ "Unmapped penID (not in [0, %d]): %d\n", -+ MIMIO_PEN_MAX, (int)mimio->pktbuf.instr); -+ penid = mimio->pktbuf.instr = 0; -+ } -+ mimio->last_pen_down = penid; -+ } else { -+ penid = mimio->last_pen_down; -+ } -+ dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid], -+ instr_ofst[penid], penid, down ? "down" : "up"); -+ -+ if (instr_ofst[penid] >= 0) { -+ int code = BTN_TOOL_PEN + instr_ofst[penid]; -+ int value = down ? DOWNVALUE : UPVALUE; -+ if (code > KEY_MAX) -+ dev_dbg(&mimio->idev->dev, "input_event will ignore " -+ "-- code (%d) > KEY_MAX\n", code); -+ if (!test_bit(code, mimio->idev->keybit)) -+ dev_dbg(&mimio->idev->dev, "input_event will ignore " -+ "-- bit for code (%d) not enabled\n", code); -+ if (!!test_bit(code, mimio->idev->key) == value) -+ dev_dbg(&mimio->idev->dev, "input_event will ignore " -+ "-- bit for code (%d) already set to %d\n", -+ code, value); -+ if (value != DOWNVALUE) { -+ /* input_regs(mimio->idev, regs); */ -+ input_report_key(mimio->idev, code, value); -+ input_sync(mimio->idev); -+ } else { -+ /* wait until we get some coordinates */ -+ } -+ } else { -+ dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 " -+ "- not sending\n", penid, instr_ofst[penid]); -+ } -+ mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */ -+ return 0; -+} -+ -+/* -+ * Stay tuned for partial-packet excitement. -+ * -+ * This routine buffers data packets received from the mimio device -+ * in the mimio's data space. This buffering is necessary because -+ * the mimio's in endpoint can serve us partial packets of data, and -+ * we want the driver to support the servicing of multiple mimios. -+ * Empirical evidence gathered so far suggests that the method of -+ * buffering packet data in the mimio's data space works. Previous -+ * versions of this driver did not buffer packet data in each mimio's -+ * data-space, and were therefore not able to service multiple mimios. -+ * Note that since the caller of this routine is running in interrupt -+ * context, care needs to be taken to ensure that this routine does not -+ * become bloated, and it may be that another spinlock is needed in each -+ * mimio to guard the buffered packet data properly. -+ */ -+static void mimio_rx_handler(struct mimio *mimio, -+ unsigned char *data, -+ unsigned int nbytes) -+{ -+ struct device *dev = &mimio->idev->dev; -+ unsigned int x; -+ unsigned int y; -+ static const char * const instr[] = { -+ "?0", -+ "black pen", "blue pen", "green pen", "red pen", -+ "brown pen", "orange pen", "purple pen", "yellow pen", -+ "big eraser", "lil eraser", -+ "?11", "?12", "?13", "?14", "?15", "?16", -+ "mimio interactive", "interactive button1", -+ "interactive button2" -+ }; -+ -+ /* Mimio Interactive gives: -+ * down: [0x22 0x01 0x11 0x32 0x24] -+ * b1 : [0x22 0x01 0x12 0x31 0x24] -+ * b2 : [0x22 0x01 0x13 0x30 0x24] -+ */ -+ static const int instr_ofst[] = { -+ -1, -+ 0, 1, 2, 3, -+ 9, 9, 9, 9, -+ 4, 5, -+ -1, -1, -1, -1, -1, -1, -+ 6, 7, 8, -+ }; -+ -+ memcpy(mimio->pktbuf.q, data, nbytes); -+ mimio->pktbuf.q += nbytes; -+ -+ while (mimio->pktbuf.p < mimio->pktbuf.q) { -+ int t = *mimio->pktbuf.p; -+ switch (t) { -+ case MIMIO_EV_PENUP: -+ case MIMIO_EV_PENDOWN: -+ if (handle_mimio_rx_penupdown(mimio, -+ t == MIMIO_EV_PENDOWN, -+ instr, instr_ofst)) -+ return; /* partial packet */ -+ break; -+ -+ case MIMIO_EV_PENDATA: -+ if (mimio->pktbuf.q - mimio->pktbuf.p < 6) -+ /* partial pkt */ -+ return; -+ x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ -+ *(mimio->pktbuf.p + 2) ^ -+ *(mimio->pktbuf.p + 3) ^ -+ *(mimio->pktbuf.p + 4); -+ if (x != *(mimio->pktbuf.p + 5)) { -+ dev_dbg(dev, "EV_PENDATA: bad xsum.\n"); -+ mimio->pktbuf.p += 6; /* skip this event data */ -+ break; /* decode any remaining events */ -+ } -+ x = *(mimio->pktbuf.p + 1); -+ x <<= 8; -+ x |= *(mimio->pktbuf.p + 2); -+ y = *(mimio->pktbuf.p + 3); -+ y <<= 8; -+ y |= *(mimio->pktbuf.p + 4); -+ dev_dbg(dev, "coord: (%d, %d)\n", x, y); -+ if (instr_ofst[mimio->pktbuf.instr] >= 0) { -+ int code = BTN_TOOL_PEN + -+ instr_ofst[mimio->last_pen_down]; -+#if 0 -+ /* Utter hack to ensure we get forwarded _AND_ -+ * so we can identify when a complete signal is -+ * received */ -+ mimio->idev->abs[ABS_Y] = -1; -+ mimio->idev->abs[ABS_X] = -1; -+#endif -+ /* input_regs(mimio->idev, regs); */ -+ input_report_abs(mimio->idev, ABS_X, x); -+ input_report_abs(mimio->idev, ABS_Y, y); -+ /* fake a penup */ -+ change_bit(code, mimio->idev->key); -+ input_report_key(mimio->idev, -+ code, -+ DOWNVALUE); -+ /* always sync here */ -+ mimio->idev->sync = 0; -+ input_sync(mimio->idev); -+ } -+ mimio->pktbuf.p += 6; -+ break; -+ case MIMIO_EV_MEMRESET: -+ if (mimio->pktbuf.q - mimio->pktbuf.p < 7) -+ /* partial pkt */ -+ return; -+ dev_dbg(dev, "mem-reset.\n"); -+ /* input_regs(mimio->idev, regs); */ -+ input_event(mimio->idev, EV_KEY, BTN_0, 1); -+ input_event(mimio->idev, EV_KEY, BTN_0, 0); -+ input_sync(mimio->idev); -+ mimio->pktbuf.p += 7; -+ break; -+ case MIMIO_EV_ACC: -+ if (mimio->pktbuf.q - mimio->pktbuf.p < 4) -+ /* partial pkt */ -+ return; -+ x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ -+ *(mimio->pktbuf.p + 2); -+ if (x != *(mimio->pktbuf.p + 3)) { -+ dev_dbg(dev, "EV_ACC: bad xsum.\n"); -+ mimio->pktbuf.p += 4; /* skip this event data */ -+ break; /* decode any remaining events */ -+ } -+ switch (*(mimio->pktbuf.p + 2)) { -+ case ACC_NEWPAGE: -+ dev_dbg(&mimio->idev->dev, "new-page.\n"); -+ /* input_regs(mimio->idev, regs); */ -+ input_event(mimio->idev, EV_KEY, BTN_1, 1); -+ input_event(mimio->idev, EV_KEY, BTN_1, 0); -+ input_sync(mimio->idev); -+ break; -+ case ACC_TAGPAGE: -+ dev_dbg(&mimio->idev->dev, "tag-page.\n"); -+ /* input_regs(mimio->idev, regs); */ -+ input_event(mimio->idev, EV_KEY, BTN_2, 1); -+ input_event(mimio->idev, EV_KEY, BTN_2, 0); -+ input_sync(mimio->idev); -+ break; -+ case ACC_PRINTPAGE: -+ dev_dbg(&mimio->idev->dev, "print-page.\n"); -+ /* input_regs(mimio->idev, regs);*/ -+ input_event(mimio->idev, EV_KEY, BTN_3, 1); -+ input_event(mimio->idev, EV_KEY, BTN_3, 0); -+ input_sync(mimio->idev); -+ break; -+ case ACC_MAXIMIZE: -+ dev_dbg(&mimio->idev->dev, -+ "maximize-window.\n"); -+ /* input_regs(mimio->idev, regs); */ -+ input_event(mimio->idev, EV_KEY, BTN_4, 1); -+ input_event(mimio->idev, EV_KEY, BTN_4, 0); -+ input_sync(mimio->idev); -+ break; -+ case ACC_FINDCTLPNL: -+ dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n"); -+ /* input_regs(mimio->idev, regs); */ -+ input_event(mimio->idev, EV_KEY, BTN_5, 1); -+ input_event(mimio->idev, EV_KEY, BTN_5, 0); -+ input_sync(mimio->idev); -+ break; -+ case ACC_DONE: -+ dev_dbg(&mimio->idev->dev, "acc-done.\n"); -+ /* no event is dispatched to the input -+ * subsystem for this device event. -+ */ -+ break; -+ default: -+ dev_dbg(dev, "unknown acc event.\n"); -+ break; -+ } -+ mimio->pktbuf.p += 4; -+ break; -+ default: -+ mimio->pktbuf.p++; -+ break; -+ } -+ } -+ -+ /* -+ * No partial event was received, so reset mimio's pktbuf ptrs. -+ */ -+ mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf; -+} -+ -+static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes) -+{ -+ int rslt; -+ int timeout; -+ unsigned long flags; -+ DECLARE_WAITQUEUE(wait, current); -+ -+ if (!(isvalidtxsize(nbytes))) { -+ dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n", -+ nbytes); -+ return -EINVAL; -+ } -+ -+ /* -+ * Init the out urb and copy the data to send. -+ */ -+ mimio->out.urb->dev = mimio->udev; -+ mimio->out.urb->transfer_buffer_length = nbytes; -+ memcpy(mimio->out.urb->transfer_buffer, buf, nbytes); -+ -+ /* -+ * Send the data. -+ */ -+ spin_lock_irqsave(&mimio->txlock, flags); -+ mimio->txflags = MIMIO_TXWAIT; -+ rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC); -+ spin_unlock_irqrestore(&mimio->txlock, flags); -+ dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt); -+ -+ if (rslt) { -+ dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", -+ rslt); -+ return rslt; -+ } -+ -+ /* -+ * Wait for completion to be signalled (the mimio_irq_out -+ * completion routine will or MIMIO_TXDONE in with txflags). -+ */ -+ timeout = HZ; -+ set_current_state(TASK_INTERRUPTIBLE); -+ add_wait_queue(&mimio->waitq, &wait); -+ -+ while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) { -+ timeout = schedule_timeout(timeout); -+ rmb(); -+ } -+ -+ if ((mimio->txflags & MIMIO_TXDONE) == 0) -+ dev_dbg(&mimio->idev->dev, "tx timed out.\n"); -+ -+ /* -+ * Now that completion has been signalled, -+ * unlink the urb so that it can be recycled. -+ */ -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&mimio->waitq, &wait); -+ usb_unlink_urb(mimio->out.urb); -+ -+ return rslt; -+} -+ -+static int __init mimio_init(void) -+{ -+ int rslt; -+ -+ rslt = usb_register(&mimio_driver); -+ if (rslt != 0) { -+ err("%s: usb_register failure: %d", __func__, rslt); -+ return rslt; -+ } -+ -+ info(DRIVER_DESC " " DRIVER_VERSION); -+ return rslt; -+} -+ -+static void __exit mimio_exit(void) -+{ -+ usb_deregister(&mimio_driver); -+} -+ -+module_init(mimio_init); -+module_exit(mimio_exit); -+ -+MODULE_AUTHOR(DRIVER_AUTHOR); -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_LICENSE("GPL"); @@ -292,4 +292,3 @@ usb/usb-gotemp.patch #module-usb-serial.patch #modpost -input-add-mimio-xi-driver.patch |
