Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

kernel: Commit

kernel


Commit MetaInfo

Revisione55eff121bd732afdbcbf78ae2adcd012a3fe5bf (tree)
Time2019-02-12 15:40:31
AuthorSupratim <sup270792@gmai...>
CommiterChih-Wei Huang

Log Message

Input: add PQ Labs IR touchscreen driver

Signed-off-by: Chih-Wei Huang <cwhuang@linux.org.tw>

Change Summary

Incremental Difference

--- a/arch/x86/configs/android-x86_64_defconfig
+++ b/arch/x86/configs/android-x86_64_defconfig
@@ -3019,6 +3019,7 @@ CONFIG_TOUCHSCREEN_ZFORCE=m
30193019 CONFIG_TOUCHSCREEN_ROHM_BU21023=m
30203020 CONFIG_TOUCHSCREEN_NWFERMI=m
30213021 CONFIG_TOUCHSCREEN_DWAV_USB_MT=m
3022+CONFIG_TOUCHSCREEN_PQLABS_USB=m
30223023 CONFIG_INPUT_MISC=y
30233024 CONFIG_INPUT_88PM80X_ONKEY=m
30243025 CONFIG_INPUT_AD714X=m
--- a/arch/x86/configs/android-x86_defconfig
+++ b/arch/x86/configs/android-x86_defconfig
@@ -3079,6 +3079,7 @@ CONFIG_TOUCHSCREEN_ZFORCE=m
30793079 CONFIG_TOUCHSCREEN_ROHM_BU21023=m
30803080 CONFIG_TOUCHSCREEN_NWFERMI=m
30813081 CONFIG_TOUCHSCREEN_DWAV_USB_MT=m
3082+CONFIG_TOUCHSCREEN_PQLABS_USB=m
30823083 CONFIG_INPUT_MISC=y
30833084 CONFIG_INPUT_88PM80X_ONKEY=m
30843085 CONFIG_INPUT_AD714X=m
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1321,4 +1321,14 @@ config TOUCHSCREEN_DWAV_USB_MT
13211321 To compile this driver as a module, choose M here: the
13221322 module will be called dwav-usb-mt.
13231323
1324+config TOUCHSCREEN_PQLABS_USB
1325+ tristate "PQ Labs IR MultiTouch Screen Driver"
1326+ depends on USB
1327+ help
1328+ Say Y here if you have a PQ LABS IR MultiTouch Screen
1329+ connected to your system.
1330+
1331+ To compile this driver as a module, choose M here: the
1332+ module will be called usb_pqlabs.
1333+
13241334 endif
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -111,3 +111,4 @@ obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
111111 obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
112112 obj-$(CONFIG_TOUCHSCREEN_NWFERMI) += nw-fermi.o
113113 obj-$(CONFIG_TOUCHSCREEN_DWAV_USB_MT) += dwav-usb-mt.o
114+obj-$(CONFIG_TOUCHSCREEN_PQLABS_USB) += usb_pqlabs.o
--- /dev/null
+++ b/drivers/input/touchscreen/usb_pqlabs.c
@@ -0,0 +1,1088 @@
1+/*
2+ * USB pqlabs driver - 130101
3+ *
4+ * Copyright (C) 2001-2004 Jemini
5+ *
6+ * This program is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU General Public License as
8+ * published by the Free Software Foundation, version 2.
9+ *
10+ * This driver is based on the 2.6.3 version of drivers/usb/usb-pqlabseton.c
11+ * but has been rewritten to be easier to read and use.
12+ *
13+ */
14+
15+#include <linux/kernel.h>
16+#include <linux/errno.h>
17+#include <linux/init.h>
18+#include <linux/slab.h>
19+#include <linux/module.h>
20+#include <linux/kref.h>
21+#include <linux/uaccess.h>
22+#include <linux/usb.h>
23+#include <linux/mutex.h>
24+#include <linux/compat.h>
25+#include <linux/input.h>
26+#include <linux/input/mt.h>
27+#include <linux/hiddev.h>
28+#include <linux/mm.h>
29+#include <linux/version.h>
30+
31+#define PQ 2
32+#define PRODUCT PQ
33+
34+/* Define these values to match your devices */
35+#define USB_PQLABS_VENDOR_ID 0x1EF1
36+#define USB_PQLABS_PRODUCT_ID 0x0001
37+#define USB_PQLABS_PRODUCT_BULK_ID 0x0011
38+
39+#define USB_PQLABS_INTERFACE_CLASS 0xFF
40+#define USB_PQLABS_INTERFACE_SUBCLASS 0x0
41+#define USB_PQLABS_INTERFACE_PROTOCOL 0x0
42+#define CUR_DRIVER_VERSION 0x140729
43+
44+static const char *TOUCHSCREEN_NAME = "PQLABS Multi TouchScreen";
45+
46+struct pqlabs_string_descriptor
47+{
48+ __s32 index;
49+ char value[256];
50+};
51+
52+struct pqlabs_cmd_string
53+{
54+ __s32 index;
55+ char buf[64];
56+};
57+
58+#define USB_IOCTL_GET_STRING _IOR('Q', 0x04, struct pqlabs_string_descriptor)
59+#define USB_IOCTL_CLEAR_FEATURE _IOR('Q', 0x05, int)
60+#define USB_IOCTL_WRITE_HID_CMD _IOR('Q', 0x06, struct pqlabs_cmd_string)
61+#define USB_IOCTL_GET_DRIVER_VERSION _IOR('Q', 0x07, unsigned int)
62+#define USB_IOCTL_CLEAR_URB _IOR('Q', 0x08, unsigned int)
63+#define USB_IOCTL_RESET_DEVICE _IOR('Q', 0x09, unsigned int)
64+
65+
66+#if 1
67+#define pq_trace(msg...) \
68+ do { \
69+ printk(KERN_DEBUG "pqlabs: " msg); \
70+ } while (0)
71+
72+#define err(msg...) \
73+ do { \
74+ printk(KERN_DEBUG "pqlabs: " msg); \
75+ } while (0)
76+#endif
77+
78+/* table of devices that work with this driver */
79+static struct usb_device_id pqlabs_table[] = {
80+ {USB_DEVICE_AND_INTERFACE_INFO(USB_PQLABS_VENDOR_ID,
81+ USB_PQLABS_PRODUCT_ID,
82+ USB_PQLABS_INTERFACE_CLASS,
83+ USB_PQLABS_INTERFACE_SUBCLASS,
84+ USB_PQLABS_INTERFACE_PROTOCOL)},
85+ {USB_DEVICE_AND_INTERFACE_INFO(USB_PQLABS_VENDOR_ID,
86+ USB_PQLABS_PRODUCT_BULK_ID,
87+ USB_PQLABS_INTERFACE_CLASS,
88+ USB_PQLABS_INTERFACE_SUBCLASS,
89+ USB_PQLABS_INTERFACE_PROTOCOL)},
90+ { } /* Terminating entry */
91+};
92+MODULE_DEVICE_TABLE(usb, pqlabs_table);
93+
94+/* Get a minor range for your devices from the usb maintainer */
95+#define USB_pqlabs_MINOR_BASE 192
96+
97+/* our private defines. if this grows any larger, use your own .h file */
98+#define MAX_TRANSFER (PAGE_SIZE - 512)
99+/* MAX_TRANSFER is chosen so that the VM is not stressed by
100+ allocations > PAGE_SIZE and the number of packets in a page
101+ is an integer 512 is the largest possible packet on EHCI */
102+#define WRITES_IN_FLIGHT 8
103+#define MAX_BUFFER_NUMBER 1
104+/* arbitrarily chosen */
105+
106+/* Structure to hold all of our device specific stuff */
107+struct usb_pqlabs {
108+ struct usb_device *udev; /* the usb device for this device */
109+ struct usb_interface *interface; /* the interface for this device */
110+ struct semaphore limit_sem; /* limiting the number of writes in progress */
111+ struct usb_anchor submitted; /* in case we need to retract our submissions */
112+ struct urb *bulk_in_urb; /* the urb to read data with */
113+ unsigned char *bulk_in_buffer; /* the buffer to receive data */
114+ size_t bulk_in_size; /* the size of the receive buffer */
115+ size_t bulk_in_filled; /* number of bytes in the buffer */
116+ size_t bulk_in_copied; /* already copied to user space */
117+ size_t bulk_total;
118+ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
119+ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
120+ int errors; /* the last request tanked */
121+ int open_count; /* count the number of openers */
122+ bool ongoing_read; /* a read is going on */
123+ bool processed_urb; /* indicates we haven't processed the urb */
124+ bool submitted_urb;
125+ spinlock_t err_lock; /* lock for errors */
126+ struct kref kref;
127+ struct mutex io_mutex; /* synchronize I/O with disconnect */
128+ struct completion bulk_in_completion; /* to wait for an ongoing read */
129+ bool disconnecting;
130+ struct input_dev *input_dev;
131+ char phys[32];
132+
133+ int bufferIndex;
134+ size_t total_size;
135+ char extraFlag;
136+};
137+#define to_pqlabs_dev(d) container_of(d, struct usb_pqlabs, kref)
138+#define MAX_SUPPORT_POINTS 32
139+
140+
141+static struct usb_driver pqlabs_driver;
142+static void pqlabs_draw_down(struct usb_pqlabs *dev);
143+
144+static void pqlabs_delete(struct kref *kref)
145+{
146+ struct usb_pqlabs *dev = to_pqlabs_dev(kref);
147+
148+ usb_free_urb(dev->bulk_in_urb);
149+ usb_put_dev(dev->udev);
150+ kfree(dev->bulk_in_buffer);
151+ kfree(dev);
152+}
153+
154+static int pqlabs_open(struct inode *inode, struct file *file)
155+{
156+ struct usb_pqlabs *dev;
157+ struct usb_interface *interface;
158+ int subminor;
159+ int retval = 0;
160+
161+ subminor = iminor(inode);
162+
163+ interface = usb_find_interface(&pqlabs_driver, subminor);
164+ if (!interface)
165+ {
166+ err("%s - error, can't find device for minor %d", __func__, subminor);
167+ retval = -ENODEV;
168+ goto exit;
169+ }
170+
171+ dev = usb_get_intfdata(interface);
172+ if (!dev) {
173+ retval = -ENODEV;
174+ goto exit;
175+ }
176+
177+ /* increment our usage count for the device */
178+ kref_get(&dev->kref);
179+
180+ /* lock the device to allow correctly handling errors
181+ * in resumption */
182+ mutex_lock(&dev->io_mutex);
183+
184+ if (!dev->open_count++) {
185+ retval = usb_autopm_get_interface(interface);
186+ if (retval) {
187+ dev->open_count--;
188+ mutex_unlock(&dev->io_mutex);
189+ kref_put(&dev->kref, pqlabs_delete);
190+ goto exit;
191+ }
192+ } else { //uncomment this block if you want exclusive open
193+ retval = -EBUSY;
194+ dev->open_count--;
195+ mutex_unlock(&dev->io_mutex);
196+ kref_put(&dev->kref, pqlabs_delete);
197+ goto exit;
198+ }
199+ /* prevent the device from being autosuspended */
200+
201+ /* save our object in the file's private structure */
202+ dev->bufferIndex = 0;
203+ file->private_data = dev;
204+ mutex_unlock(&dev->io_mutex);
205+
206+exit:
207+ return retval;
208+}
209+
210+static int pqlabs_release(struct inode *inode, struct file *file)
211+{
212+ struct usb_pqlabs *dev;
213+
214+ dev = (struct usb_pqlabs *)file->private_data;
215+ if (dev == NULL)
216+ return -ENODEV;
217+
218+ /* allow the device to be autosuspended */
219+ mutex_lock(&dev->io_mutex);
220+ if (!--dev->open_count && dev->interface)
221+ usb_autopm_put_interface(dev->interface);
222+ mutex_unlock(&dev->io_mutex);
223+
224+ printk("%s: submitted_urb = %d\n", __func__, dev->submitted_urb);
225+ if (dev->submitted_urb);
226+ complete(&dev->bulk_in_completion);
227+
228+ spin_lock(&dev->err_lock);
229+ dev->ongoing_read = 0;
230+ dev->submitted_urb = 0;
231+ spin_unlock(&dev->err_lock);
232+
233+ /* decrement the count on our device */
234+ kref_put(&dev->kref, pqlabs_delete);
235+ return 0;
236+}
237+
238+static int pqlabs_flush(struct file *file, fl_owner_t id)
239+{
240+ struct usb_pqlabs *dev;
241+ int res;
242+
243+ dev = (struct usb_pqlabs *)file->private_data;
244+ if (dev == NULL)
245+ return -ENODEV;
246+
247+ /* wait for io to stop */
248+ mutex_lock(&dev->io_mutex);
249+ pqlabs_draw_down(dev);
250+
251+ /* read out errors, leave subsequent opens a clean slate */
252+ spin_lock_irq(&dev->err_lock);
253+ res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0;
254+ dev->errors = 0;
255+ spin_unlock_irq(&dev->err_lock);
256+
257+ mutex_unlock(&dev->io_mutex);
258+
259+ return res;
260+}
261+
262+static void pqlabs_read_bulk_callback(struct urb *urb)
263+{
264+ struct usb_pqlabs *dev;
265+ dev = urb->context;
266+
267+ /* sync/async unlink faults aren't errors */
268+ if (urb->status)
269+ {
270+ if (!(urb->status == -ENOENT ||
271+ urb->status == -ECONNRESET ||
272+ urb->status == -ESHUTDOWN))
273+ err("%s - nonzero read bulk status received: %d\n", __func__, urb->status);
274+ dev->errors = urb->status;
275+ }
276+ else
277+ {
278+ dev->bulk_in_filled = urb->actual_length;
279+ //if (dev->bulk_in_filled == 0) dev->bulk_in_filled = dev->bulk_in_size + 1;
280+ }
281+
282+ dev->submitted_urb = 0;
283+ complete(&dev->bulk_in_completion);
284+}
285+
286+static int pqlabs_do_read_io(struct usb_pqlabs *dev, size_t count)
287+{
288+ int rv;
289+
290+ /* prepare a read */
291+ usb_fill_bulk_urb(dev->bulk_in_urb,
292+ dev->udev,
293+ usb_rcvbulkpipe(dev->udev,
294+ dev->bulk_in_endpointAddr),
295+ dev->bulk_in_buffer,
296+ min(dev->bulk_in_size, count),
297+ pqlabs_read_bulk_callback,
298+ dev);
299+
300+ /* do it */
301+ rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
302+ if (rv < 0)
303+ {
304+ err("%s - failed submitting read urb, error %d", __func__, rv);
305+ dev->bulk_in_filled = 0;
306+ rv = (rv == -ENOMEM) ? rv : -EIO;
307+ }
308+ else
309+ {
310+ dev->submitted_urb = 1;
311+ }
312+ return rv;
313+}
314+
315+#define READ_USB_MAX_LENGTH (8 * 1024)
316+#define READ_USB_TIMEOUT (1000) //(3000)
317+static ssize_t pqlabs_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
318+{
319+ struct usb_pqlabs *dev;
320+ int rv;
321+ // bool ongoing_io;
322+
323+ dev = (struct usb_pqlabs *)file->private_data;
324+
325+ /* if we cannot read at all, return EOF */
326+ if (!dev->bulk_in_urb || !count || count > READ_USB_MAX_LENGTH) return 0;
327+
328+ if (dev->disconnecting || dev->open_count == 0) return -ENODEV;
329+
330+ /* no concurrent readers */
331+ rv = mutex_lock_interruptible(&dev->io_mutex);
332+ if (rv < 0)
333+ {
334+ return rv;
335+ }
336+
337+ if (!dev->interface)
338+ {
339+ /* disconnect() was called */
340+ rv = -ENODEV;
341+ goto exit;
342+ }
343+
344+ dev->bulk_in_filled = 0;
345+ dev->processed_urb = 0;
346+
347+ //printk("%s: Enter\n", __func__);
348+
349+ if (!(dev->processed_urb) && dev->submitted_urb)
350+ {
351+ rv = wait_for_completion_interruptible_timeout(&dev->bulk_in_completion, msecs_to_jiffies(READ_USB_TIMEOUT));
352+ //rv = wait_for_completion_interruptible(&dev->bulk_in_completion);
353+ if (rv <= 0)
354+ {
355+ err("%s: processed_urb = 0 && submitted_urb = 1\n", __func__);
356+ usb_kill_urb(dev->bulk_in_urb);
357+ dev->submitted_urb = 0;
358+ goto exit;
359+ }
360+ }
361+ else
362+ {
363+ rv = pqlabs_do_read_io(dev, count);
364+ if (rv < 0)
365+ {
366+ err("%s: pqlabs_do_read_io failed!\n", __func__);
367+ goto exit;
368+ }
369+
370+ while(1)
371+ {
372+
373+ rv = wait_for_completion_interruptible_timeout(&dev->bulk_in_completion, msecs_to_jiffies(READ_USB_TIMEOUT));
374+ if (rv == msecs_to_jiffies(READ_USB_TIMEOUT) && dev->bulk_in_filled == 0)
375+ {
376+ rv = wait_for_completion_interruptible_timeout(&dev->bulk_in_completion, msecs_to_jiffies(READ_USB_TIMEOUT));
377+ }
378+
379+ //printk("before wait for completion\n");
380+ //wait_for_completion(&dev->bulk_in_completion);
381+ //printk("after wait for completion\n");
382+
383+ if (rv > 0) break;
384+
385+ if (rv == 0)
386+ {
387+ err("%s: timeout!\n", __func__);
388+ if (dev->disconnecting == 1)
389+ {
390+ err("%s: disconnected break!\n", __func__);
391+ goto exit;
392+ }
393+ dev->submitted_urb = 0;
394+ rv = -ETIME;
395+ usb_kill_urb(dev->bulk_in_urb);
396+ goto exit;
397+ }
398+
399+ if (rv < 0)
400+ {
401+ err("%s: rv < 0\n", __func__);
402+ usb_kill_urb(dev->bulk_in_urb);
403+ dev->submitted_urb = 0;
404+ goto exit;
405+ }
406+ }
407+ }
408+
409+ rv = dev->errors;
410+ if (rv < 0)
411+ {
412+ dev->errors = 0;
413+ rv = (rv == -EPIPE) ? rv : -EIO;
414+ err("%s: dev->error < 0\n", __func__);
415+ goto exit;
416+ }
417+
418+ if (dev->bulk_in_filled == 0)
419+ {
420+ rv = 0;
421+ err("%s: bulk_in_filled = 0\n", __func__);
422+ goto exit;
423+ }
424+
425+ //if (dev->bulk_in_filled)
426+ //printk("head: 0x%08X\n", *(unsigned int *)(dev->bulk_in_buffer));
427+ if (copy_to_user(buffer, dev->bulk_in_buffer, dev->bulk_in_filled))
428+ rv = -EFAULT;
429+ else
430+ rv = dev->bulk_in_filled;
431+exit:
432+ mutex_unlock(&dev->io_mutex);
433+ return rv;
434+}
435+
436+static void pqlabs_write_bulk_callback(struct urb *urb)
437+{
438+ struct usb_pqlabs *dev;
439+
440+ dev = urb->context;
441+
442+ /* sync/async unlink faults aren't errors */
443+ if (urb->status) {
444+ /*
445+ if (!(urb->status == -ENOENT ||
446+ urb->status == -ECONNRESET ||
447+ urb->status == -ESHUTDOWN))
448+ err("%s - nonzero write bulk status received: %d",
449+ __func__, urb->status);
450+ */
451+ spin_lock(&dev->err_lock);
452+ dev->errors = urb->status;
453+ spin_unlock(&dev->err_lock);
454+ }
455+
456+ /* free up our allocated buffer */
457+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
458+ urb->transfer_buffer, urb->transfer_dma);
459+ up(&dev->limit_sem);
460+}
461+
462+static ssize_t pqlabs_write(struct file *file, const char *user_buffer,
463+ size_t count, loff_t *ppos)
464+{
465+ struct usb_pqlabs *dev;
466+ int retval = -1;
467+ struct urb *urb = NULL;
468+ char *buf = NULL;
469+ size_t writesize = min(count, (size_t)MAX_TRANSFER);
470+
471+ dev = (struct usb_pqlabs*)file->private_data;
472+
473+ /* verify that we actually have some data to write */
474+ if (count == 0)
475+ goto exit;
476+
477+ if (dev->disconnecting || dev->open_count == 0) return -ENODEV;
478+
479+ /*
480+ * limit the number of URBs in flight to stop a user from using up all
481+ * RAM
482+ */
483+ if (!(file->f_flags & O_NONBLOCK)) {
484+ if (down_interruptible(&dev->limit_sem)) {
485+ retval = -ERESTARTSYS;
486+ goto exit;
487+ }
488+ } else {
489+ if (down_trylock(&dev->limit_sem)) {
490+ retval = -EAGAIN;
491+ goto exit;
492+ }
493+ }
494+
495+ spin_lock_irq(&dev->err_lock);
496+ retval = dev->errors;
497+ if (retval < 0) {
498+ /* any error is reported once */
499+ dev->errors = 0;
500+ /* to preserve notifications about reset */
501+ retval = (retval == -EPIPE) ? retval : -EIO;
502+ }
503+ spin_unlock_irq(&dev->err_lock);
504+ if (retval < 0)
505+ goto error;
506+
507+ /* create a urb, and a buffer for it, and copy the data to the urb */
508+ urb = usb_alloc_urb(0, GFP_KERNEL);
509+ if (!urb) {
510+ retval = -ENOMEM;
511+ goto error;
512+ }
513+
514+ buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
515+ &urb->transfer_dma);
516+ if (!buf) {
517+ retval = -ENOMEM;
518+ goto error;
519+ }
520+
521+ if (copy_from_user(buf, user_buffer, writesize)) {
522+ retval = -EFAULT;
523+ goto error;
524+ }
525+
526+ /* this lock makes sure we don't submit URBs to gone devices */
527+ mutex_lock(&dev->io_mutex);
528+ if (!dev->interface) { /* disconnect() was called */
529+ mutex_unlock(&dev->io_mutex);
530+ retval = -ENODEV;
531+ goto error;
532+ }
533+
534+ /* initialize the urb properly */
535+ usb_fill_bulk_urb(urb, dev->udev,
536+ usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
537+ buf, writesize, pqlabs_write_bulk_callback, dev);
538+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
539+ usb_anchor_urb(urb, &dev->submitted);
540+
541+ /* send the data out the bulk port */
542+ retval = usb_submit_urb(urb, GFP_KERNEL);
543+ mutex_unlock(&dev->io_mutex);
544+ if (retval) {
545+// err("%s - failed submitting write urb, error %d", __func__, retval);
546+ goto error_unanchor;
547+ }
548+
549+ /*
550+ * release our reference to this urb, the USB core will eventually free
551+ * it entirely
552+ */
553+ usb_free_urb(urb);
554+
555+
556+ return writesize;
557+
558+error_unanchor:
559+ usb_unanchor_urb(urb);
560+error:
561+ if (urb) {
562+ usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
563+ usb_free_urb(urb);
564+ }
565+ up(&dev->limit_sem);
566+
567+exit:
568+ return retval;
569+}
570+
571+static long pqlabs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
572+{
573+ struct usb_device *udev;
574+ struct usb_pqlabs *dev;
575+ int ret, result;
576+ int len, idx;
577+ char *buf;
578+ int i;
579+ void __user *user_arg = (void __user *)arg;
580+
581+ ret = 0;
582+ len = 0;
583+ dev = (struct usb_pqlabs *)file->private_data;
584+ udev = dev->udev;
585+
586+ if (cmd == USB_IOCTL_GET_STRING)
587+ {
588+ if (get_user(idx, (int __user *)user_arg))
589+ {
590+ err("pqlabs: get idx failed!\n");
591+ return -EFAULT;
592+ }
593+
594+ if (udev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH;
595+
596+ if ((buf = kmalloc(256, GFP_KERNEL)) == NULL) return -ENOMEM;
597+
598+ for(i = 0; i < 3; i++)
599+ {
600+ result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
601+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
602+ (USB_DT_STRING << 8) + idx, 0x0409, buf, 255,
603+ USB_CTRL_GET_TIMEOUT);
604+ if (result == 0 || result == -EPIPE) continue;
605+
606+ if (result > 1 && ((u8 *)buf)[1] != USB_DT_STRING)
607+ {
608+ result = -ENODATA;
609+ continue;
610+ }
611+ break;
612+ }
613+
614+ if (result > 0)
615+ {
616+ len = buf[0];
617+ if (copy_to_user(user_arg + sizeof(int), buf, len + 1))
618+ {
619+ kfree(buf);
620+ return -EFAULT;
621+ }
622+ }
623+ kfree(buf);
624+ return len;
625+ }
626+ else if (cmd == USB_IOCTL_CLEAR_FEATURE)
627+ {
628+ char dBuf[8];
629+ if (udev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH;
630+
631+
632+ result = usb_control_msg(udev,
633+ usb_sndctrlpipe(udev, 0),
634+ USB_REQ_CLEAR_FEATURE,
635+ USB_TYPE_STANDARD | USB_RECIP_ENDPOINT,
636+ 0, 0x82, dBuf, 8,
637+ 500);
638+ return result;
639+ }
640+ else if (cmd == USB_IOCTL_CLEAR_URB)
641+ {
642+
643+ //if (dev->disconnecting == 0)
644+ //usb_reset_endpoint(dev->udev, 0x82);
645+ //usb_queue_reset_device(dev->interface);
646+ //usb_reset_device(dev->udev);
647+ return 0;
648+ }
649+ else if (cmd == HIDIOCGSTRING)
650+ {
651+ if (get_user(idx, (int __user *)user_arg))
652+ {
653+ err("pqlabs: get hid idx failed!\n");
654+ return -EFAULT;
655+ }
656+
657+ if (udev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH;
658+
659+ if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL) return -ENOMEM;
660+
661+ if ((len = usb_string(udev, idx, buf, HID_STRING_SIZE-1)) < 0)
662+ {
663+ kfree(buf);
664+ return -EINVAL;
665+ }
666+
667+ if (copy_to_user(user_arg+sizeof(int), buf, len+1))
668+ {
669+ kfree(buf);
670+ return -EFAULT;
671+ }
672+
673+ kfree(buf);
674+ return len;
675+ }
676+ else if (cmd == USB_IOCTL_WRITE_HID_CMD)
677+ {
678+ if (get_user(idx, (int __user *)user_arg))
679+ {
680+ err("pqlabs: get write command length failed!\n");
681+ return -EFAULT;
682+ }
683+
684+ if (idx > 64) idx = 64;
685+
686+ if (udev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH;
687+
688+ if ((buf = kmalloc(64, GFP_KERNEL)) == NULL) return -ENOMEM;
689+
690+ if (copy_from_user(buf, user_arg + sizeof(int), idx))
691+ {
692+ kfree(buf);
693+ return -EFAULT;
694+ }
695+
696+ pq_trace("idx = %d, buf[0] = %d\n", idx, buf[0]);
697+ ret = usb_control_msg(udev,
698+ usb_rcvctrlpipe(udev, 0),
699+ 0xF0,
700+ USB_TYPE_VENDOR | USB_DIR_IN,
701+ buf[0], 0, buf, idx,
702+ USB_CTRL_GET_TIMEOUT);
703+ kfree(buf);
704+ } else if (cmd == USB_IOCTL_RESET_DEVICE) {
705+ usb_queue_reset_device(dev->interface);
706+ }
707+
708+ return ret;
709+}
710+
711+#define PT_SIZE 10
712+
713+/* Sysfs method to input simulated
714+ coordinates to the virtual
715+ mouse driver */
716+static ssize_t write_vms(struct device *device, struct device_attribute *attr, const char *buffer, size_t count)
717+{
718+ int type, slot;
719+ int ptCount;
720+ int i;
721+// int ret;
722+ int x, y, w, h;
723+ struct usb_interface *iface = to_usb_interface(device);
724+ struct usb_pqlabs *dev = (struct usb_pqlabs *)usb_get_intfdata(iface);
725+// char *pWalk = buffer;
726+
727+ /* ID Counts + \n
728+ contactid + x + y + width + height + \n
729+ */
730+ ptCount = buffer[0];
731+ for (i = 0; i < ptCount; i++)
732+ {
733+ type = buffer[i * PT_SIZE + 1];
734+ slot = buffer[i * PT_SIZE + 2];
735+ x = buffer[i * PT_SIZE + 3] | (buffer[i * PT_SIZE + 4] << 8);
736+ y = buffer[i * PT_SIZE + 5] | (buffer[i * PT_SIZE + 6] << 8);
737+ w = buffer[i * PT_SIZE + 7] | (buffer[i * PT_SIZE + 8] << 8);
738+ h = buffer[i * PT_SIZE + 9] | (buffer[i * PT_SIZE + 10] << 8);
739+
740+ if (type == 0x3) // DOWN OR MOVE
741+ {
742+ input_mt_slot(dev->input_dev, slot);
743+ input_mt_report_slot_state(dev->input_dev, MT_TOOL_FINGER, true);
744+ input_report_abs(dev->input_dev, ABS_MT_POSITION_X, x);
745+ input_report_abs(dev->input_dev, ABS_MT_POSITION_Y, y);
746+ input_report_abs(dev->input_dev, ABS_MT_ORIENTATION, w > h);
747+ input_report_abs(dev->input_dev, ABS_MT_TOUCH_MAJOR, w);
748+ input_report_abs(dev->input_dev, ABS_MT_TOUCH_MINOR, h);
749+
750+ }
751+ else if (type == 0x2) // UP
752+ {
753+ input_mt_slot(dev->input_dev, slot);
754+ input_mt_report_slot_state(dev->input_dev, MT_TOOL_FINGER, false);
755+ }
756+ }
757+ input_sync(dev->input_dev);
758+
759+ return ptCount;
760+}
761+
762+/* Attach the sysfs write method */
763+DEVICE_ATTR(coordinates, 0644, NULL, write_vms);
764+
765+
766+static ssize_t write_flag(struct device *device, struct device_attribute *attr, const char *buffer, size_t count)
767+{
768+ struct usb_interface *iface = to_usb_interface(device);
769+ struct usb_pqlabs *dev = (struct usb_pqlabs *)usb_get_intfdata(iface);
770+ dev->extraFlag = buffer[0];
771+
772+ return 1;
773+}
774+
775+static ssize_t read_flag(struct device *device, struct device_attribute *attr, char *buffer)
776+{
777+ struct usb_interface *iface = to_usb_interface(device);
778+ struct usb_pqlabs *dev = (struct usb_pqlabs *)usb_get_intfdata(iface);
779+ buffer[0] = dev->extraFlag;
780+
781+ return 1;
782+}
783+
784+DEVICE_ATTR(flag, 0770, read_flag, write_flag);
785+
786+
787+/* Attribute Descriptor */
788+static struct attribute *vms_attrs[] = {
789+ &dev_attr_coordinates.attr,
790+ &dev_attr_flag.attr,
791+ NULL
792+};
793+
794+
795+/* Attribute group */
796+static struct attribute_group vms_attr_group = {
797+ .attrs = vms_attrs,
798+};
799+
800+
801+
802+#if defined CONFIG_COMPAT
803+static long pqlabs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
804+{
805+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
806+ return pqlabs_ioctl(file, cmd, translated_arg);
807+}
808+#endif
809+
810+static const struct file_operations pqlabs_fops = {
811+ .owner = THIS_MODULE,
812+ .read = pqlabs_read,
813+ .write = pqlabs_write,
814+ .open = pqlabs_open,
815+ .release = pqlabs_release,
816+ .flush = pqlabs_flush,
817+ .unlocked_ioctl = pqlabs_ioctl,
818+#if defined CONFIG_COMPAT
819+ .compat_ioctl = pqlabs_compat_ioctl,
820+#endif
821+};
822+
823+/*
824+ * usb class driver info in order to get a minor number from the usb core,
825+ * and to have the device registered with the driver core
826+ */
827+static struct usb_class_driver pqlabs_class = {
828+ .name = "pqlabs_bulk%d",
829+ .fops = &pqlabs_fops,
830+ .minor_base = USB_pqlabs_MINOR_BASE,
831+};
832+
833+static int pqlabs_probe(struct usb_interface *interface,
834+ const struct usb_device_id *id)
835+{
836+ struct usb_pqlabs *dev;
837+ struct usb_host_interface *iface_desc;
838+ struct usb_endpoint_descriptor *endpoint;
839+ size_t buffer_size;
840+ int i;
841+ int retval = -ENOMEM;
842+
843+ /* allocate memory for our device state and initialize it */
844+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
845+ if (!dev)
846+ {
847+ //err("Out of memory");
848+ goto error;
849+ }
850+ kref_init(&dev->kref);
851+ sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
852+ mutex_init(&dev->io_mutex);
853+ spin_lock_init(&dev->err_lock);
854+ init_usb_anchor(&dev->submitted);
855+ init_completion(&dev->bulk_in_completion);
856+
857+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
858+ dev->interface = interface;
859+ dev->disconnecting = false;
860+ dev->extraFlag = 0;
861+
862+ /* set up the endpoint information */
863+ /* use only the first bulk-in and bulk-out endpoints */
864+ iface_desc = interface->cur_altsetting;
865+
866+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
867+ {
868+ endpoint = &iface_desc->endpoint[i].desc;
869+ if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint))
870+ {
871+ /* we found a bulk in endpoint */
872+ buffer_size = READ_USB_MAX_LENGTH; //le16_to_cpu(endpoint->wMaxPacketSize);
873+ dev->total_size = buffer_size * MAX_BUFFER_NUMBER;
874+ dev->bulk_in_size = buffer_size;
875+ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
876+ dev->bulk_in_buffer = kmalloc(dev->total_size, GFP_KERNEL);
877+ if (!dev->bulk_in_buffer)
878+ {
879+ err("Could not allocate bulk_in_buffer");
880+ goto error;
881+ }
882+
883+ dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
884+ if (!dev->bulk_in_urb)
885+ {
886+ err("Could not allocate bulk_in_urb");
887+ goto error;
888+ }
889+ }
890+
891+ if (!dev->bulk_out_endpointAddr &&
892+ usb_endpoint_is_bulk_out(endpoint)) {
893+ /* we found a bulk out endpoint */
894+ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
895+ }
896+ }
897+
898+ /* save our data pointer in this interface device */
899+ usb_set_intfdata(interface, dev);
900+
901+ /* we can register the device now, as it is ready */
902+ retval = usb_register_dev(interface, &pqlabs_class);
903+ if (retval) {
904+ /* something prevented us from registering this driver */
905+ //err("Not able to get a minor for this device.");
906+ usb_set_intfdata(interface, NULL);
907+ goto error;
908+ }
909+
910+ dev->input_dev = input_allocate_device();
911+ if (dev->input_dev == NULL)
912+ {
913+ retval = -ENOMEM;
914+ printk("Failed to allocate input device\n");
915+ goto error;
916+ }
917+
918+ __set_bit(INPUT_PROP_DIRECT, dev->input_dev->propbit);
919+ __set_bit(EV_ABS, dev->input_dev->evbit);
920+
921+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
922+ input_mt_init_slots(dev->input_dev, MAX_SUPPORT_POINTS, 0);
923+#else
924+ input_mt_init_slots(dev->input_dev, MAX_SUPPORT_POINTS);
925+#endif
926+ input_set_abs_params(dev->input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
927+ input_set_abs_params(dev->input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFFFF, 0, 0);
928+ input_set_abs_params(dev->input_dev, ABS_MT_TOUCH_MINOR, 0, 0xFFFF, 0, 0);
929+ input_set_abs_params(dev->input_dev, ABS_MT_POSITION_X, 0, 0xFFFF, 0, 0);
930+ input_set_abs_params(dev->input_dev, ABS_MT_POSITION_Y, 0, 0xFFFF, 0, 0);
931+ input_set_abs_params(dev->input_dev, ABS_X, 0, 0xFFFF, 0, 0);
932+ input_set_abs_params(dev->input_dev, ABS_Y, 0, 0xFFFF, 0, 0);
933+ sprintf(dev->phys, "input/pqlabs");
934+ dev->input_dev->name = TOUCHSCREEN_NAME;
935+ dev->input_dev->phys = dev->phys;
936+ dev->input_dev->id.bustype = BUS_USB;
937+ dev->input_dev->id.vendor = 0x1EF1;
938+ dev->input_dev->id.product = 0x0002;
939+ dev->input_dev->id.version = 0x0001; //screen firmware version
940+
941+ retval = input_register_device(dev->input_dev);
942+ if (retval)
943+ {
944+ printk("Probe: Unable to register %s input device\n", dev->input_dev->name);
945+ retval = -1;
946+ goto error;
947+ }
948+
949+ /* Create a sysfs node to read simulated coordinates */
950+ sysfs_create_group(&interface->dev.kobj, &vms_attr_group);
951+ //sysfs_create_group(&dev->input_dev->dev.kobj, &vms_attr_group);
952+
953+ /* let the user know what node this device is now attached to */
954+ dev_info(&interface->dev,
955+ "USB pqlabs bulk device now attached to USBpqlabs-%d",
956+ interface->minor);
957+ return 0;
958+
959+error:
960+ if (dev->input_dev)
961+ {
962+ input_free_device(dev->input_dev);
963+ }
964+
965+ if (dev)
966+ /* this frees allocated memory */
967+ kref_put(&dev->kref, pqlabs_delete);
968+ return retval;
969+}
970+
971+static void pqlabs_disconnect(struct usb_interface *interface)
972+{
973+ struct usb_pqlabs *dev;
974+ //int minor = interface->minor;
975+
976+ dev = usb_get_intfdata(interface);
977+ dev->disconnecting = true;
978+ printk("%s: submitted_urb = %d\n", __func__, dev->submitted_urb);
979+ if (dev->submitted_urb);
980+ complete(&dev->bulk_in_completion);
981+
982+ mutex_lock(&dev->io_mutex);
983+
984+ sysfs_remove_group(&interface->dev.kobj, &vms_attr_group);
985+ //sysfs_remove_group(&dev->input_dev->dev.kobj, &vms_attr_group);
986+ input_mt_destroy_slots(dev->input_dev);
987+ input_unregister_device(dev->input_dev);
988+ if (dev->input_dev)
989+ {
990+ input_free_device(dev->input_dev);
991+ }
992+ usb_set_intfdata(interface, NULL);
993+
994+ /* give back our minor */
995+ usb_deregister_dev(interface, &pqlabs_class);
996+
997+ /* prevent more I/O from starting */
998+ dev->interface = NULL;
999+ mutex_unlock(&dev->io_mutex);
1000+
1001+ usb_kill_anchored_urbs(&dev->submitted);
1002+
1003+ /* decrement our usage count */
1004+ kref_put(&dev->kref, pqlabs_delete);
1005+
1006+ //dev_info(&interface->dev, "USB pqlabseton #%d now disconnected", minor);
1007+}
1008+
1009+static void pqlabs_draw_down(struct usb_pqlabs *dev)
1010+{
1011+ int time;
1012+
1013+ time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);
1014+ if (!time)
1015+ usb_kill_anchored_urbs(&dev->submitted);
1016+ usb_kill_urb(dev->bulk_in_urb);
1017+}
1018+
1019+static int pqlabs_suspend(struct usb_interface *intf, pm_message_t message)
1020+{
1021+ struct usb_pqlabs *dev = usb_get_intfdata(intf);
1022+
1023+ if (!dev)
1024+ return 0;
1025+ pqlabs_draw_down(dev);
1026+ return 0;
1027+}
1028+
1029+static int pqlabs_resume(struct usb_interface *intf)
1030+{
1031+ return 0;
1032+}
1033+
1034+static int pqlabs_pre_reset(struct usb_interface *intf)
1035+{
1036+ struct usb_pqlabs *dev = usb_get_intfdata(intf);
1037+
1038+ mutex_lock(&dev->io_mutex);
1039+ pqlabs_draw_down(dev);
1040+
1041+ return 0;
1042+}
1043+
1044+static int pqlabs_post_reset(struct usb_interface *intf)
1045+{
1046+ struct usb_pqlabs *dev = usb_get_intfdata(intf);
1047+
1048+ /* we are sure no URBs are active - no locking needed */
1049+ dev->errors = -EPIPE;
1050+ mutex_unlock(&dev->io_mutex);
1051+
1052+ return 0;
1053+}
1054+
1055+static struct usb_driver pqlabs_driver = {
1056+ .name = "pqlabs_bulk",
1057+ .probe = pqlabs_probe,
1058+ .disconnect = pqlabs_disconnect,
1059+ .suspend = pqlabs_suspend,
1060+ .resume = pqlabs_resume,
1061+ .pre_reset = pqlabs_pre_reset,
1062+ .post_reset = pqlabs_post_reset,
1063+ .id_table = pqlabs_table,
1064+ .supports_autosuspend = 1,
1065+};
1066+
1067+static int __init usb_pqlabs_init(void)
1068+{
1069+ int result;
1070+
1071+ /* register this driver with the USB subsystem */
1072+ result = usb_register(&pqlabs_driver);
1073+ if (result)
1074+ err("usb_register failed. Error number %d", result);
1075+
1076+ return result;
1077+}
1078+
1079+static void __exit usb_pqlabs_exit(void)
1080+{
1081+ /* deregister this driver with the USB subsystem */
1082+ usb_deregister(&pqlabs_driver);
1083+}
1084+
1085+module_init(usb_pqlabs_init);
1086+module_exit(usb_pqlabs_exit);
1087+
1088+MODULE_LICENSE("GPL");
Show on old repository browser