idmouse.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /* Siemens ID Mouse driver v0.6
  3. Copyright (C) 2004-5 by Florian 'Floe' Echtler <[email protected]>
  4. and Andreas 'ad' Deresch <[email protected]>
  5. Derived from the USB Skeleton driver 1.1,
  6. Copyright (C) 2003 Greg Kroah-Hartman ([email protected])
  7. Additional information provided by Martin Reising
  8. <[email protected]>
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/sched/signal.h>
  12. #include <linux/errno.h>
  13. #include <linux/delay.h>
  14. #include <linux/slab.h>
  15. #include <linux/module.h>
  16. #include <linux/completion.h>
  17. #include <linux/mutex.h>
  18. #include <linux/uaccess.h>
  19. #include <linux/usb.h>
  20. /* image constants */
  21. #define WIDTH 225
  22. #define HEIGHT 289
  23. #define HEADER "P5 225 289 255 "
  24. #define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1)
  25. #define DRIVER_SHORT "idmouse"
  26. #define DRIVER_AUTHOR "Florian 'Floe' Echtler <[email protected]>"
  27. #define DRIVER_DESC "Siemens ID Mouse FingerTIP Sensor Driver"
  28. /* minor number for misc USB devices */
  29. #define USB_IDMOUSE_MINOR_BASE 132
  30. /* vendor and device IDs */
  31. #define ID_SIEMENS 0x0681
  32. #define ID_IDMOUSE 0x0005
  33. #define ID_CHERRY 0x0010
  34. /* device ID table */
  35. static const struct usb_device_id idmouse_table[] = {
  36. {USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)}, /* Siemens ID Mouse (Professional) */
  37. {USB_DEVICE(ID_SIEMENS, ID_CHERRY )}, /* Cherry FingerTIP ID Board */
  38. {} /* terminating null entry */
  39. };
  40. /* sensor commands */
  41. #define FTIP_RESET 0x20
  42. #define FTIP_ACQUIRE 0x21
  43. #define FTIP_RELEASE 0x22
  44. #define FTIP_BLINK 0x23 /* LSB of value = blink pulse width */
  45. #define FTIP_SCROLL 0x24
  46. #define ftip_command(dev, command, value, index) \
  47. usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), command, \
  48. USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
  49. MODULE_DEVICE_TABLE(usb, idmouse_table);
  50. /* structure to hold all of our device specific stuff */
  51. struct usb_idmouse {
  52. struct usb_device *udev; /* save off the usb device pointer */
  53. struct usb_interface *interface; /* the interface for this device */
  54. unsigned char *bulk_in_buffer; /* the buffer to receive data */
  55. size_t bulk_in_size; /* the maximum bulk packet size */
  56. size_t orig_bi_size; /* same as above, but reported by the device */
  57. __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
  58. int open; /* if the port is open or not */
  59. int present; /* if the device is not disconnected */
  60. struct mutex lock; /* locks this structure */
  61. };
  62. /* local function prototypes */
  63. static ssize_t idmouse_read(struct file *file, char __user *buffer,
  64. size_t count, loff_t * ppos);
  65. static int idmouse_open(struct inode *inode, struct file *file);
  66. static int idmouse_release(struct inode *inode, struct file *file);
  67. static int idmouse_probe(struct usb_interface *interface,
  68. const struct usb_device_id *id);
  69. static void idmouse_disconnect(struct usb_interface *interface);
  70. static int idmouse_suspend(struct usb_interface *intf, pm_message_t message);
  71. static int idmouse_resume(struct usb_interface *intf);
  72. /* file operation pointers */
  73. static const struct file_operations idmouse_fops = {
  74. .owner = THIS_MODULE,
  75. .read = idmouse_read,
  76. .open = idmouse_open,
  77. .release = idmouse_release,
  78. .llseek = default_llseek,
  79. };
  80. /* class driver information */
  81. static struct usb_class_driver idmouse_class = {
  82. .name = "idmouse%d",
  83. .fops = &idmouse_fops,
  84. .minor_base = USB_IDMOUSE_MINOR_BASE,
  85. };
  86. /* usb specific object needed to register this driver with the usb subsystem */
  87. static struct usb_driver idmouse_driver = {
  88. .name = DRIVER_SHORT,
  89. .probe = idmouse_probe,
  90. .disconnect = idmouse_disconnect,
  91. .suspend = idmouse_suspend,
  92. .resume = idmouse_resume,
  93. .reset_resume = idmouse_resume,
  94. .id_table = idmouse_table,
  95. .supports_autosuspend = 1,
  96. };
  97. static int idmouse_create_image(struct usb_idmouse *dev)
  98. {
  99. int bytes_read;
  100. int bulk_read;
  101. int result;
  102. memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1);
  103. bytes_read = sizeof(HEADER)-1;
  104. /* reset the device and set a fast blink rate */
  105. result = ftip_command(dev, FTIP_RELEASE, 0, 0);
  106. if (result < 0)
  107. goto reset;
  108. result = ftip_command(dev, FTIP_BLINK, 1, 0);
  109. if (result < 0)
  110. goto reset;
  111. /* initialize the sensor - sending this command twice */
  112. /* significantly reduces the rate of failed reads */
  113. result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
  114. if (result < 0)
  115. goto reset;
  116. result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
  117. if (result < 0)
  118. goto reset;
  119. /* start the readout - sending this command twice */
  120. /* presumably enables the high dynamic range mode */
  121. result = ftip_command(dev, FTIP_RESET, 0, 0);
  122. if (result < 0)
  123. goto reset;
  124. result = ftip_command(dev, FTIP_RESET, 0, 0);
  125. if (result < 0)
  126. goto reset;
  127. /* loop over a blocking bulk read to get data from the device */
  128. while (bytes_read < IMGSIZE) {
  129. result = usb_bulk_msg(dev->udev,
  130. usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
  131. dev->bulk_in_buffer + bytes_read,
  132. dev->bulk_in_size, &bulk_read, 5000);
  133. if (result < 0) {
  134. /* Maybe this error was caused by the increased packet size? */
  135. /* Reset to the original value and tell userspace to retry. */
  136. if (dev->bulk_in_size != dev->orig_bi_size) {
  137. dev->bulk_in_size = dev->orig_bi_size;
  138. result = -EAGAIN;
  139. }
  140. break;
  141. }
  142. if (signal_pending(current)) {
  143. result = -EINTR;
  144. break;
  145. }
  146. bytes_read += bulk_read;
  147. }
  148. /* check for valid image */
  149. /* right border should be black (0x00) */
  150. for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH)
  151. if (dev->bulk_in_buffer[bytes_read] != 0x00)
  152. return -EAGAIN;
  153. /* lower border should be white (0xFF) */
  154. for (bytes_read = IMGSIZE-WIDTH; bytes_read < IMGSIZE-1; bytes_read++)
  155. if (dev->bulk_in_buffer[bytes_read] != 0xFF)
  156. return -EAGAIN;
  157. /* reset the device */
  158. reset:
  159. ftip_command(dev, FTIP_RELEASE, 0, 0);
  160. /* should be IMGSIZE == 65040 */
  161. dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n",
  162. bytes_read);
  163. return result;
  164. }
  165. /* PM operations are nops as this driver does IO only during open() */
  166. static int idmouse_suspend(struct usb_interface *intf, pm_message_t message)
  167. {
  168. return 0;
  169. }
  170. static int idmouse_resume(struct usb_interface *intf)
  171. {
  172. return 0;
  173. }
  174. static inline void idmouse_delete(struct usb_idmouse *dev)
  175. {
  176. kfree(dev->bulk_in_buffer);
  177. kfree(dev);
  178. }
  179. static int idmouse_open(struct inode *inode, struct file *file)
  180. {
  181. struct usb_idmouse *dev;
  182. struct usb_interface *interface;
  183. int result;
  184. /* get the interface from minor number and driver information */
  185. interface = usb_find_interface(&idmouse_driver, iminor(inode));
  186. if (!interface)
  187. return -ENODEV;
  188. /* get the device information block from the interface */
  189. dev = usb_get_intfdata(interface);
  190. if (!dev)
  191. return -ENODEV;
  192. /* lock this device */
  193. mutex_lock(&dev->lock);
  194. /* check if already open */
  195. if (dev->open) {
  196. /* already open, so fail */
  197. result = -EBUSY;
  198. } else {
  199. /* create a new image and check for success */
  200. result = usb_autopm_get_interface(interface);
  201. if (result)
  202. goto error;
  203. result = idmouse_create_image(dev);
  204. usb_autopm_put_interface(interface);
  205. if (result)
  206. goto error;
  207. /* increment our usage count for the driver */
  208. ++dev->open;
  209. /* save our object in the file's private structure */
  210. file->private_data = dev;
  211. }
  212. error:
  213. /* unlock this device */
  214. mutex_unlock(&dev->lock);
  215. return result;
  216. }
  217. static int idmouse_release(struct inode *inode, struct file *file)
  218. {
  219. struct usb_idmouse *dev;
  220. dev = file->private_data;
  221. if (dev == NULL)
  222. return -ENODEV;
  223. /* lock our device */
  224. mutex_lock(&dev->lock);
  225. --dev->open;
  226. if (!dev->present) {
  227. /* the device was unplugged before the file was released */
  228. mutex_unlock(&dev->lock);
  229. idmouse_delete(dev);
  230. } else {
  231. mutex_unlock(&dev->lock);
  232. }
  233. return 0;
  234. }
  235. static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count,
  236. loff_t * ppos)
  237. {
  238. struct usb_idmouse *dev = file->private_data;
  239. int result;
  240. /* lock this object */
  241. mutex_lock(&dev->lock);
  242. /* verify that the device wasn't unplugged */
  243. if (!dev->present) {
  244. mutex_unlock(&dev->lock);
  245. return -ENODEV;
  246. }
  247. result = simple_read_from_buffer(buffer, count, ppos,
  248. dev->bulk_in_buffer, IMGSIZE);
  249. /* unlock the device */
  250. mutex_unlock(&dev->lock);
  251. return result;
  252. }
  253. static int idmouse_probe(struct usb_interface *interface,
  254. const struct usb_device_id *id)
  255. {
  256. struct usb_device *udev = interface_to_usbdev(interface);
  257. struct usb_idmouse *dev;
  258. struct usb_host_interface *iface_desc;
  259. struct usb_endpoint_descriptor *endpoint;
  260. int result;
  261. /* check if we have gotten the data or the hid interface */
  262. iface_desc = interface->cur_altsetting;
  263. if (iface_desc->desc.bInterfaceClass != 0x0A)
  264. return -ENODEV;
  265. if (iface_desc->desc.bNumEndpoints < 1)
  266. return -ENODEV;
  267. /* allocate memory for our device state and initialize it */
  268. dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  269. if (dev == NULL)
  270. return -ENOMEM;
  271. mutex_init(&dev->lock);
  272. dev->udev = udev;
  273. dev->interface = interface;
  274. /* set up the endpoint information - use only the first bulk-in endpoint */
  275. result = usb_find_bulk_in_endpoint(iface_desc, &endpoint);
  276. if (result) {
  277. dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
  278. idmouse_delete(dev);
  279. return result;
  280. }
  281. dev->orig_bi_size = usb_endpoint_maxp(endpoint);
  282. dev->bulk_in_size = 0x200; /* works _much_ faster */
  283. dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
  284. dev->bulk_in_buffer = kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
  285. if (!dev->bulk_in_buffer) {
  286. idmouse_delete(dev);
  287. return -ENOMEM;
  288. }
  289. /* allow device read, write and ioctl */
  290. dev->present = 1;
  291. /* we can register the device now, as it is ready */
  292. usb_set_intfdata(interface, dev);
  293. result = usb_register_dev(interface, &idmouse_class);
  294. if (result) {
  295. /* something prevented us from registering this device */
  296. dev_err(&interface->dev, "Unable to allocate minor number.\n");
  297. idmouse_delete(dev);
  298. return result;
  299. }
  300. /* be noisy */
  301. dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
  302. return 0;
  303. }
  304. static void idmouse_disconnect(struct usb_interface *interface)
  305. {
  306. struct usb_idmouse *dev = usb_get_intfdata(interface);
  307. /* give back our minor */
  308. usb_deregister_dev(interface, &idmouse_class);
  309. /* lock the device */
  310. mutex_lock(&dev->lock);
  311. /* prevent device read, write and ioctl */
  312. dev->present = 0;
  313. /* if the device is opened, idmouse_release will clean this up */
  314. if (!dev->open) {
  315. mutex_unlock(&dev->lock);
  316. idmouse_delete(dev);
  317. } else {
  318. /* unlock */
  319. mutex_unlock(&dev->lock);
  320. }
  321. dev_info(&interface->dev, "disconnected\n");
  322. }
  323. module_usb_driver(idmouse_driver);
  324. MODULE_AUTHOR(DRIVER_AUTHOR);
  325. MODULE_DESCRIPTION(DRIVER_DESC);
  326. MODULE_LICENSE("GPL");