0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/kernel.h>
0016 #include <linux/sched/signal.h>
0017 #include <linux/errno.h>
0018 #include <linux/delay.h>
0019 #include <linux/slab.h>
0020 #include <linux/module.h>
0021 #include <linux/completion.h>
0022 #include <linux/mutex.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/usb.h>
0025
0026
0027 #define WIDTH 225
0028 #define HEIGHT 289
0029 #define HEADER "P5 225 289 255 "
0030 #define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1)
0031
0032 #define DRIVER_SHORT "idmouse"
0033 #define DRIVER_AUTHOR "Florian 'Floe' Echtler <echtler@fs.tum.de>"
0034 #define DRIVER_DESC "Siemens ID Mouse FingerTIP Sensor Driver"
0035
0036
0037 #define USB_IDMOUSE_MINOR_BASE 132
0038
0039
0040 #define ID_SIEMENS 0x0681
0041 #define ID_IDMOUSE 0x0005
0042 #define ID_CHERRY 0x0010
0043
0044
0045 static const struct usb_device_id idmouse_table[] = {
0046 {USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)},
0047 {USB_DEVICE(ID_SIEMENS, ID_CHERRY )},
0048 {}
0049 };
0050
0051
0052 #define FTIP_RESET 0x20
0053 #define FTIP_ACQUIRE 0x21
0054 #define FTIP_RELEASE 0x22
0055 #define FTIP_BLINK 0x23
0056 #define FTIP_SCROLL 0x24
0057
0058 #define ftip_command(dev, command, value, index) \
0059 usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), command, \
0060 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
0061
0062 MODULE_DEVICE_TABLE(usb, idmouse_table);
0063
0064
0065 struct usb_idmouse {
0066
0067 struct usb_device *udev;
0068 struct usb_interface *interface;
0069
0070 unsigned char *bulk_in_buffer;
0071 size_t bulk_in_size;
0072 size_t orig_bi_size;
0073 __u8 bulk_in_endpointAddr;
0074
0075 int open;
0076 int present;
0077 struct mutex lock;
0078
0079 };
0080
0081
0082 static ssize_t idmouse_read(struct file *file, char __user *buffer,
0083 size_t count, loff_t * ppos);
0084
0085 static int idmouse_open(struct inode *inode, struct file *file);
0086 static int idmouse_release(struct inode *inode, struct file *file);
0087
0088 static int idmouse_probe(struct usb_interface *interface,
0089 const struct usb_device_id *id);
0090
0091 static void idmouse_disconnect(struct usb_interface *interface);
0092 static int idmouse_suspend(struct usb_interface *intf, pm_message_t message);
0093 static int idmouse_resume(struct usb_interface *intf);
0094
0095
0096 static const struct file_operations idmouse_fops = {
0097 .owner = THIS_MODULE,
0098 .read = idmouse_read,
0099 .open = idmouse_open,
0100 .release = idmouse_release,
0101 .llseek = default_llseek,
0102 };
0103
0104
0105 static struct usb_class_driver idmouse_class = {
0106 .name = "idmouse%d",
0107 .fops = &idmouse_fops,
0108 .minor_base = USB_IDMOUSE_MINOR_BASE,
0109 };
0110
0111
0112 static struct usb_driver idmouse_driver = {
0113 .name = DRIVER_SHORT,
0114 .probe = idmouse_probe,
0115 .disconnect = idmouse_disconnect,
0116 .suspend = idmouse_suspend,
0117 .resume = idmouse_resume,
0118 .reset_resume = idmouse_resume,
0119 .id_table = idmouse_table,
0120 .supports_autosuspend = 1,
0121 };
0122
0123 static int idmouse_create_image(struct usb_idmouse *dev)
0124 {
0125 int bytes_read;
0126 int bulk_read;
0127 int result;
0128
0129 memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1);
0130 bytes_read = sizeof(HEADER)-1;
0131
0132
0133 result = ftip_command(dev, FTIP_RELEASE, 0, 0);
0134 if (result < 0)
0135 goto reset;
0136 result = ftip_command(dev, FTIP_BLINK, 1, 0);
0137 if (result < 0)
0138 goto reset;
0139
0140
0141
0142 result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
0143 if (result < 0)
0144 goto reset;
0145 result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
0146 if (result < 0)
0147 goto reset;
0148
0149
0150
0151 result = ftip_command(dev, FTIP_RESET, 0, 0);
0152 if (result < 0)
0153 goto reset;
0154 result = ftip_command(dev, FTIP_RESET, 0, 0);
0155 if (result < 0)
0156 goto reset;
0157
0158
0159 while (bytes_read < IMGSIZE) {
0160 result = usb_bulk_msg(dev->udev,
0161 usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
0162 dev->bulk_in_buffer + bytes_read,
0163 dev->bulk_in_size, &bulk_read, 5000);
0164 if (result < 0) {
0165
0166
0167 if (dev->bulk_in_size != dev->orig_bi_size) {
0168 dev->bulk_in_size = dev->orig_bi_size;
0169 result = -EAGAIN;
0170 }
0171 break;
0172 }
0173 if (signal_pending(current)) {
0174 result = -EINTR;
0175 break;
0176 }
0177 bytes_read += bulk_read;
0178 }
0179
0180
0181 reset:
0182 ftip_command(dev, FTIP_RELEASE, 0, 0);
0183
0184
0185
0186 for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH)
0187 if (dev->bulk_in_buffer[bytes_read] != 0x00)
0188 return -EAGAIN;
0189
0190
0191 for (bytes_read = IMGSIZE-WIDTH; bytes_read < IMGSIZE-1; bytes_read++)
0192 if (dev->bulk_in_buffer[bytes_read] != 0xFF)
0193 return -EAGAIN;
0194
0195
0196 dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n",
0197 bytes_read);
0198 return result;
0199 }
0200
0201
0202 static int idmouse_suspend(struct usb_interface *intf, pm_message_t message)
0203 {
0204 return 0;
0205 }
0206
0207 static int idmouse_resume(struct usb_interface *intf)
0208 {
0209 return 0;
0210 }
0211
0212 static inline void idmouse_delete(struct usb_idmouse *dev)
0213 {
0214 kfree(dev->bulk_in_buffer);
0215 kfree(dev);
0216 }
0217
0218 static int idmouse_open(struct inode *inode, struct file *file)
0219 {
0220 struct usb_idmouse *dev;
0221 struct usb_interface *interface;
0222 int result;
0223
0224
0225 interface = usb_find_interface(&idmouse_driver, iminor(inode));
0226 if (!interface)
0227 return -ENODEV;
0228
0229
0230 dev = usb_get_intfdata(interface);
0231 if (!dev)
0232 return -ENODEV;
0233
0234
0235 mutex_lock(&dev->lock);
0236
0237
0238 if (dev->open) {
0239
0240
0241 result = -EBUSY;
0242
0243 } else {
0244
0245
0246 result = usb_autopm_get_interface(interface);
0247 if (result)
0248 goto error;
0249 result = idmouse_create_image(dev);
0250 usb_autopm_put_interface(interface);
0251 if (result)
0252 goto error;
0253
0254
0255 ++dev->open;
0256
0257
0258 file->private_data = dev;
0259
0260 }
0261
0262 error:
0263
0264
0265 mutex_unlock(&dev->lock);
0266 return result;
0267 }
0268
0269 static int idmouse_release(struct inode *inode, struct file *file)
0270 {
0271 struct usb_idmouse *dev;
0272
0273 dev = file->private_data;
0274
0275 if (dev == NULL)
0276 return -ENODEV;
0277
0278
0279 mutex_lock(&dev->lock);
0280
0281 --dev->open;
0282
0283 if (!dev->present) {
0284
0285 mutex_unlock(&dev->lock);
0286 idmouse_delete(dev);
0287 } else {
0288 mutex_unlock(&dev->lock);
0289 }
0290 return 0;
0291 }
0292
0293 static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count,
0294 loff_t * ppos)
0295 {
0296 struct usb_idmouse *dev = file->private_data;
0297 int result;
0298
0299
0300 mutex_lock(&dev->lock);
0301
0302
0303 if (!dev->present) {
0304 mutex_unlock(&dev->lock);
0305 return -ENODEV;
0306 }
0307
0308 result = simple_read_from_buffer(buffer, count, ppos,
0309 dev->bulk_in_buffer, IMGSIZE);
0310
0311 mutex_unlock(&dev->lock);
0312 return result;
0313 }
0314
0315 static int idmouse_probe(struct usb_interface *interface,
0316 const struct usb_device_id *id)
0317 {
0318 struct usb_device *udev = interface_to_usbdev(interface);
0319 struct usb_idmouse *dev;
0320 struct usb_host_interface *iface_desc;
0321 struct usb_endpoint_descriptor *endpoint;
0322 int result;
0323
0324
0325 iface_desc = interface->cur_altsetting;
0326 if (iface_desc->desc.bInterfaceClass != 0x0A)
0327 return -ENODEV;
0328
0329 if (iface_desc->desc.bNumEndpoints < 1)
0330 return -ENODEV;
0331
0332
0333 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0334 if (dev == NULL)
0335 return -ENOMEM;
0336
0337 mutex_init(&dev->lock);
0338 dev->udev = udev;
0339 dev->interface = interface;
0340
0341
0342 result = usb_find_bulk_in_endpoint(iface_desc, &endpoint);
0343 if (result) {
0344 dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
0345 idmouse_delete(dev);
0346 return result;
0347 }
0348
0349 dev->orig_bi_size = usb_endpoint_maxp(endpoint);
0350 dev->bulk_in_size = 0x200;
0351 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
0352 dev->bulk_in_buffer = kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
0353 if (!dev->bulk_in_buffer) {
0354 idmouse_delete(dev);
0355 return -ENOMEM;
0356 }
0357
0358
0359 dev->present = 1;
0360
0361
0362 usb_set_intfdata(interface, dev);
0363 result = usb_register_dev(interface, &idmouse_class);
0364 if (result) {
0365
0366 dev_err(&interface->dev, "Unable to allocate minor number.\n");
0367 idmouse_delete(dev);
0368 return result;
0369 }
0370
0371
0372 dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
0373
0374 return 0;
0375 }
0376
0377 static void idmouse_disconnect(struct usb_interface *interface)
0378 {
0379 struct usb_idmouse *dev = usb_get_intfdata(interface);
0380
0381
0382 usb_deregister_dev(interface, &idmouse_class);
0383
0384
0385 mutex_lock(&dev->lock);
0386
0387
0388 dev->present = 0;
0389
0390
0391 if (!dev->open) {
0392 mutex_unlock(&dev->lock);
0393 idmouse_delete(dev);
0394 } else {
0395
0396 mutex_unlock(&dev->lock);
0397 }
0398
0399 dev_info(&interface->dev, "disconnected\n");
0400 }
0401
0402 module_usb_driver(idmouse_driver);
0403
0404 MODULE_AUTHOR(DRIVER_AUTHOR);
0405 MODULE_DESCRIPTION(DRIVER_DESC);
0406 MODULE_LICENSE("GPL");
0407