a7c5a3298d0db08c41872621aed4900c1a6b5bb9
[people/mcb30/quickusb.git] / kernel / quickusb.c
1 /*
2  * QuickUSB driver
3  *
4  * Copyright 2006 Michael Brown <mbrown@fensystems.co.uk>
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; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  */
12
13 #include <linux/module.h>
14 #include <linux/fs.h>
15 #include <linux/devfs_fs_kernel.h>
16 #include <linux/kref.h>
17 #include <linux/usb.h>
18 #include <asm/uaccess.h>
19 #include "quickusb.h"
20
21 #define QUICKUSB_VENDOR_ID 0x0fbb
22 #define QUICKUSB_DEVICE_ID 0x0001
23
24 #define QUICKUSB_MAX_SUBDEVS 16
25 #define QUICKUSB_SUBDEV_MASK ( QUICKUSB_MAX_SUBDEVS - 1 )
26 #define QUICKUSB_MINOR_BOARD( dev_minor ) \
27         ( (dev_minor) / QUICKUSB_MAX_SUBDEVS )
28 #define QUICKUSB_MINOR_SUBDEV( dev_minor ) \
29         ( (dev_minor) & QUICKUSB_SUBDEV_MASK )
30 #define QUICKUSB_MINOR( board, subdev ) \
31         ( (board) * QUICKUSB_MAX_SUBDEVS + (subdev) )
32
33 #define QUICKUSB_MAX_GPPIO 5
34
35 struct quickusb_gppio {
36         struct quickusb_device *quickusb;
37         unsigned int port;
38 };
39
40 struct quickusb_hspio {
41         struct quickusb_device *quickusb;
42 };
43
44 struct quickusb_subdev {
45         struct file_operations *f_op;
46         void *private_data;
47         dev_t dev;
48         unsigned char name[32];
49         struct class_device *class_dev;
50 };
51
52 struct quickusb_device {
53         struct usb_device *usb;
54         struct usb_interface *interface;
55         struct kref kref;
56         struct list_head list;
57         unsigned int board;
58         struct quickusb_gppio gppio[QUICKUSB_MAX_GPPIO];
59         struct quickusb_hspio hspio;
60         struct quickusb_subdev subdev[QUICKUSB_MAX_SUBDEVS];
61 };
62
63 static void quickusb_delete ( struct kref *kref ) {
64         struct quickusb_device *quickusb;
65
66         quickusb = container_of ( kref, struct quickusb_device, kref );
67         usb_put_dev ( quickusb->usb );
68         kfree ( quickusb );
69 }
70
71 static LIST_HEAD ( quickusb_list );
72
73 static DECLARE_MUTEX ( quickusb_lock );
74
75 static struct class_simple *quickusb_class;
76
77 static int debug = 0;
78 static int dev_major = 0;
79
80 /****************************************************************************
81  *
82  * GPPIO char device operations
83  *
84  */
85
86 static ssize_t quickusb_gppio_read ( struct file *file, char __user *user_data,
87                                      size_t len, loff_t *ppos ) {
88         struct quickusb_gppio *gppio = file->private_data;
89         unsigned char data[QUICKUSB_MAX_DATA_LEN];
90         int rc;
91
92         if ( len > sizeof ( data ) )
93                 len = sizeof ( data );
94
95         if ( ( rc = quickusb_read_port ( gppio->quickusb->usb, gppio->port,
96                                          data, len ) ) != 0 )
97                 return rc;
98
99         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
100                 return rc;
101
102         *ppos += len;
103         return len;
104 }
105
106 static ssize_t quickusb_gppio_write ( struct file *file,
107                                       const char __user *user_data,
108                                       size_t len, loff_t *ppos ) {
109         struct quickusb_gppio *gppio = file->private_data;
110         unsigned char data[QUICKUSB_MAX_DATA_LEN];
111         int rc;
112
113         if ( len > sizeof ( data ) )
114                 len = sizeof ( data );
115
116         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
117                 return rc;
118
119         if ( ( rc = quickusb_write_port ( gppio->quickusb->usb, gppio->port,
120                                           data, len ) ) != 0 )
121                 return rc;
122
123         *ppos += len;
124         return len;
125 }
126
127 static int quickusb_gppio_ioctl ( struct inode *inode, struct file *file,
128                                   unsigned int cmd, unsigned long arg ) {
129         struct quickusb_gppio *gppio = file->private_data;
130         void __user *user_data = ( void __user * ) arg;
131         quickusb_gppio_ioctl_data_t data;
132         unsigned char outputs;
133         int rc;
134
135         if ( ( rc = copy_from_user ( &data, user_data, sizeof (data) ) ) != 0 )
136                 return rc;
137
138         switch ( cmd ) {
139         case QUICKUSB_IOC_GPPIO_GET_OUTPUTS:
140                 if ( ( rc = quickusb_read_port_dir ( gppio->quickusb->usb,
141                                                      gppio->port,
142                                                      &outputs ) ) != 0 )
143                         return rc;
144                 data = outputs;
145                 break;
146         case QUICKUSB_IOC_GPPIO_SET_OUTPUTS:
147                 outputs = data;
148                 if ( ( rc = quickusb_write_port_dir ( gppio->quickusb->usb,
149                                                       gppio->port,
150                                                       outputs ) ) != 0 )
151                         return rc;
152                 break;
153         default:
154                 return -ENOTTY;
155         }
156
157         if ( ( rc = copy_to_user ( user_data, &data, sizeof ( data ) ) ) != 0 )
158                 return rc;
159
160         return 0;
161 }
162
163 static int quickusb_gppio_release ( struct inode *inode, struct file *file ) {
164         struct quickusb_gppio *gppio = file->private_data;
165         
166         kref_put ( &gppio->quickusb->kref, quickusb_delete );
167         return 0;
168 }
169
170 static struct file_operations quickusb_gppio_fops = {
171         .owner          = THIS_MODULE,
172         .read           = quickusb_gppio_read,
173         .write          = quickusb_gppio_write,
174         .ioctl          = quickusb_gppio_ioctl,
175         .release        = quickusb_gppio_release,
176 };
177
178 /****************************************************************************
179  *
180  * HSPIO char device operations
181  *
182  */
183
184 static ssize_t quickusb_hspio_read_command ( struct file *file,
185                                              char __user *user_data,
186                                              size_t len, loff_t *ppos ) {
187         struct quickusb_hspio *hspio = file->private_data;
188         unsigned char data[QUICKUSB_MAX_DATA_LEN];
189         int rc;
190
191         if ( len > sizeof ( data ) )
192                 len = sizeof ( data );
193
194         if ( ( rc = quickusb_read_command ( hspio->quickusb->usb, *ppos,
195                                             data, len ) ) != 0 )
196                 return rc;
197
198         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
199                 return rc;
200
201         *ppos += len;
202         return len;
203 }
204
205 static ssize_t quickusb_hspio_write_command ( struct file *file,
206                                               const char __user *user_data,
207                                               size_t len, loff_t *ppos ) {
208         struct quickusb_hspio *hspio = file->private_data;
209         unsigned char data[QUICKUSB_MAX_DATA_LEN];
210         int rc;
211
212         if ( len > sizeof ( data ) )
213                 len = sizeof ( data );
214
215         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
216                 return rc;
217
218         if ( ( rc = quickusb_write_command ( hspio->quickusb->usb, *ppos,
219                                              data, len ) ) != 0 )
220                 return rc;
221
222         *ppos += len;
223         return len;
224 }
225
226 static ssize_t quickusb_hspio_read_data ( struct file *file,
227                                           char __user *user_data,
228                                           size_t len, loff_t *ppos ) {
229         struct quickusb_hspio *hspio = file->private_data;
230         unsigned char data[QUICKUSB_MAX_BULK_DATA_LEN];
231         int rc;
232
233         if ( len > sizeof ( data ) )
234                 len = sizeof ( data );
235
236         if ( ( rc = quickusb_read_data ( hspio->quickusb->usb,
237                                          data, len ) ) != 0 )
238                 return rc;
239
240         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
241                 return rc;
242
243         *ppos += len;
244         return len;
245 }
246
247 static ssize_t quickusb_hspio_write_data ( struct file *file,
248                                            const char __user *user_data,
249                                            size_t len, loff_t *ppos ) {
250         struct quickusb_hspio *hspio = file->private_data;
251         unsigned char data[QUICKUSB_MAX_BULK_DATA_LEN];
252         int rc;
253
254         if ( len > sizeof ( data ) )
255                 len = sizeof ( data );
256
257         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
258                 return rc;
259
260         if ( ( rc = quickusb_write_data ( hspio->quickusb->usb,
261                                           data, len ) ) != 0 )
262                 return rc;
263
264         *ppos += len;
265         return len;
266 }
267
268 static int quickusb_hspio_release ( struct inode *inode, struct file *file ) {
269         struct quickusb_hspio *hspio = file->private_data;
270         
271         kref_put ( &hspio->quickusb->kref, quickusb_delete );
272         return 0;
273 }
274
275 static struct file_operations quickusb_hspio_command_fops = {
276         .owner          = THIS_MODULE,
277         .read           = quickusb_hspio_read_command,
278         .write          = quickusb_hspio_write_command,
279         .release        = quickusb_hspio_release,
280 };
281
282 static struct file_operations quickusb_hspio_data_fops = {
283         .owner          = THIS_MODULE,
284         .read           = quickusb_hspio_read_data,
285         .write          = quickusb_hspio_write_data,
286         .release        = quickusb_hspio_release,
287 };
288
289 /****************************************************************************
290  *
291  * Char device (subdev) operations
292  *
293  */
294
295 static int quickusb_open ( struct inode *inode, struct file *file ) {
296         unsigned int board = QUICKUSB_MINOR_BOARD ( iminor ( inode ) );
297         unsigned int subdev = QUICKUSB_MINOR_SUBDEV ( iminor ( inode ) );
298         struct quickusb_device *quickusb;
299         int found = 0;
300         int rc = 0;
301
302         /* Locate board and increase refcount */
303         down ( &quickusb_lock );
304         list_for_each_entry ( quickusb, &quickusb_list, list ) {
305                 if ( quickusb->board == board ) {
306                         kref_get ( &quickusb->kref );
307                         found = 1;
308                         break;
309                 }
310         }
311         up ( &quickusb_lock );
312         if ( ! found ) {
313                 quickusb = NULL;
314                 rc = -ENODEV;
315                 goto out;
316         }
317
318         /* Set up per-subdevice file operations and private data */
319         file->f_op = quickusb->subdev[subdev].f_op;
320         file->private_data = quickusb->subdev[subdev].private_data;
321         if ( ! file->f_op ) {
322                 rc = -ENODEV;
323                 goto out;
324         }
325         
326         /* Perform any subdev-specific open operation */
327         if ( file->f_op->open )
328                 rc = file->f_op->open ( inode, file );
329
330  out:
331         if ( ( rc != 0 ) && quickusb )
332                 kref_put ( &quickusb->kref, quickusb_delete );
333         return rc;
334 }
335
336 static struct file_operations quickusb_fops = {
337         .owner          = THIS_MODULE,
338         .open           = quickusb_open,
339 };
340
341 /****************************************************************************
342  *
343  * Char device (subdev) registration/deregistration
344  *
345  */
346
347 static int quickusb_register_subdev ( struct quickusb_device *quickusb,
348                                       unsigned int subdev_idx,
349                                       struct file_operations *f_op,
350                                       void *private_data,
351                                       const char *subdev_fmt, ... ) {
352         struct quickusb_subdev *subdev = &quickusb->subdev[subdev_idx];
353         struct device *device = &quickusb->interface->dev;
354         unsigned int dev_minor;
355         va_list ap;
356         int rc;
357
358         /* Construct device number */
359         dev_minor = QUICKUSB_MINOR ( quickusb->board, subdev_idx );
360         subdev->dev = MKDEV ( dev_major, dev_minor );
361
362         /* Fill subdev structure */
363         subdev->f_op = f_op;
364         subdev->private_data = private_data;
365
366         /* Construct device name */
367         va_start ( ap, subdev_fmt );
368         vsnprintf ( subdev->name, sizeof ( subdev->name ), subdev_fmt, ap );
369         va_end ( ap );
370
371         /* Create devfs device */
372         if ( ( rc = devfs_mk_cdev ( subdev->dev,
373                                     ( S_IFCHR | S_IRUSR | S_IWUSR |
374                                       S_IRGRP | S_IWGRP ),
375                                     subdev->name ) ) != 0 )
376                 goto err_devfs;
377
378         /* Create class device */
379         subdev->class_dev = class_simple_device_add ( quickusb_class,
380                                                       subdev->dev, device,
381                                                       subdev->name );
382         if ( IS_ERR ( subdev->class_dev ) ) {
383                 rc = PTR_ERR ( subdev->class_dev );
384                 goto err_class;
385         }
386
387         return 0;
388
389  err_class:
390         devfs_remove ( subdev->name );
391  err_devfs:
392         memset ( subdev, 0, sizeof ( *subdev ) );
393         return rc;
394 }
395                                       
396 static void quickusb_deregister_subdev ( struct quickusb_device *quickusb,
397                                          unsigned int subdev_idx ) {
398         struct quickusb_subdev *subdev = &quickusb->subdev[subdev_idx];
399
400         if ( ! subdev->f_op )
401                 return;
402
403         /* Remove class device */
404         class_simple_device_remove ( subdev->dev );
405
406         /* Remove devfs device */
407         devfs_remove ( subdev->name );
408
409         /* Clear subdev structure */
410         memset ( subdev, 0, sizeof ( *subdev ) );
411 }
412
413 /****************************************************************************
414  *
415  * Device creation / destruction
416  *
417  */
418
419 static int quickusb_register_devices ( struct quickusb_device *quickusb ) {
420         unsigned int subdev_idx = 0;
421         struct quickusb_gppio *gppio;
422         unsigned char gppio_char;
423         int i;
424         int rc;
425
426         /* Register GPPIO ports as subdevs */
427         for ( i = 0 ; i < QUICKUSB_MAX_GPPIO ; i++ ) {
428                 gppio = &quickusb->gppio[i];
429                 gppio_char = ( 'a' + gppio->port );
430                 if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
431                                                        &quickusb_gppio_fops,
432                                                        gppio,
433                                                        "qu%dg%c",
434                                                        quickusb->board,
435                                                        gppio_char ) ) != 0 )
436                         return rc;
437         }
438
439         /* Register HSPIO port in all its variants */
440         if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
441                                                &quickusb_hspio_command_fops,
442                                                &quickusb->hspio,
443                                                "qu%dhc",
444                                                quickusb->board ) ) != 0 )
445                 return rc;
446         if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
447                                                &quickusb_hspio_data_fops,
448                                                &quickusb->hspio,
449                                                "qu%dhd",
450                                                quickusb->board ) ) != 0 )
451                 return rc;
452         
453         return 0;
454 }
455
456 static void quickusb_deregister_devices ( struct quickusb_device *quickusb ) {
457         int i;
458
459         /* Deregister all subdevs */
460         for ( i = 0 ; i < QUICKUSB_MAX_SUBDEVS ; i++ ) {
461                 quickusb_deregister_subdev ( quickusb, i );
462         }
463 }
464
465 /****************************************************************************
466  *
467  * USB hotplug add/remove
468  *
469  */
470
471 static int quickusb_probe ( struct usb_interface *interface,
472                             const struct usb_device_id *id ) {
473         struct quickusb_device *quickusb = NULL;
474         struct quickusb_device *pre_existing_quickusb;
475         unsigned int board = 0;
476         int i;
477         int rc = 0;
478
479         down ( &quickusb_lock );
480
481         /* Create new quickusb device structure */
482         quickusb = kmalloc ( sizeof ( *quickusb ), GFP_KERNEL );
483         if ( ! quickusb ) {
484                 rc = -ENOMEM;
485                 goto err;
486         }
487         memset ( quickusb, 0, sizeof ( *quickusb ) );
488         kref_init ( &quickusb->kref );
489         INIT_LIST_HEAD ( &quickusb_list );
490         quickusb->usb = usb_get_dev ( interface_to_usbdev ( interface ) );
491         quickusb->interface = interface;
492         for ( i = 0 ; i < QUICKUSB_MAX_GPPIO ; i++ ) {
493                 quickusb->gppio[i].quickusb = quickusb;
494                 quickusb->gppio[i].port = i;
495         }
496         quickusb->hspio.quickusb = quickusb;
497         
498         /* Obtain a free board board and link into list */
499         list_for_each_entry ( pre_existing_quickusb, &quickusb_list, list ) {
500                 if ( pre_existing_quickusb->board != board )
501                         break;
502                 board++;
503         }
504         quickusb->board = board;
505         list_add_tail ( &quickusb->list, &pre_existing_quickusb->list );
506
507         /* Record driver private data */
508         usb_set_intfdata ( interface, quickusb );
509
510         /* Register devices */
511         if ( ( rc = quickusb_register_devices ( quickusb ) ) != 0 ) {
512                 printk ( KERN_ERR "quickusb unable to register devices\n" );
513                 goto err;
514         }
515
516         printk ( KERN_INFO "quickusb%d connected\n", quickusb->board ); 
517         goto out;
518
519  err:
520         usb_set_intfdata ( interface, NULL );
521         if ( quickusb ) {
522                 quickusb_deregister_devices ( quickusb );
523                 list_del ( &quickusb->list );
524                 kref_put ( &quickusb->kref, quickusb_delete );
525         }
526  out:
527         up ( &quickusb_lock );
528         return rc;
529 }
530
531 static void quickusb_disconnect ( struct usb_interface *interface ) {
532         struct quickusb_device *quickusb = usb_get_intfdata ( interface );
533
534         printk ( KERN_INFO "quickusb%d disconnected\n", quickusb->board );
535
536         down ( &quickusb_lock );
537         usb_set_intfdata ( interface, NULL );
538         quickusb_deregister_devices ( quickusb );
539         list_del ( &quickusb->list );
540         up ( &quickusb_lock );
541
542         kref_put ( &quickusb->kref, quickusb_delete );
543 }
544
545 static struct usb_device_id quickusb_ids[] = {
546         { USB_DEVICE ( QUICKUSB_VENDOR_ID, QUICKUSB_DEVICE_ID ) },
547         { },
548 };
549
550 static struct usb_driver quickusb_driver = {
551         .owner          = THIS_MODULE,
552         .name           = "quickusb",
553         .probe          = quickusb_probe,
554         .disconnect     = quickusb_disconnect,
555         .id_table       = quickusb_ids,
556 };
557
558 /****************************************************************************
559  *
560  * Kernel module interface
561  *
562  */
563
564 static int quickusb_init ( void ) {
565         int rc;
566
567         /* Register major char device */
568         if ( ( rc = register_chrdev ( dev_major, "quickusb",
569                                       &quickusb_fops ) ) < 0 ) {
570                 printk ( KERN_ERR "quickusb could not register char device: "
571                          "error %d\n", rc );
572                 goto err_chrdev;
573         }
574         if ( ! dev_major ) {
575                 dev_major = rc;
576                 printk ( KERN_INFO "quickusb using major device %d\n",
577                          dev_major );
578         }
579         
580         /* Create device class */
581         quickusb_class = class_simple_create ( THIS_MODULE, "quickusb" );
582         if ( IS_ERR ( quickusb_class ) ) {
583                 rc = PTR_ERR ( quickusb_class );
584                 printk ( KERN_ERR "quickusb could not create device class: "
585                          "error %d\n", rc );
586                 goto err_class;
587         }
588
589         if ( ( rc = usb_register ( &quickusb_driver ) ) != 0 )
590                 goto err_usb;
591
592         return 0;
593
594  err_usb:
595         class_simple_destroy ( quickusb_class );
596  err_class:
597         unregister_chrdev ( dev_major, "quickusb" );
598  err_chrdev:
599         return rc;
600 }
601
602 static void quickusb_exit ( void ) {
603         usb_deregister ( &quickusb_driver );
604         class_simple_destroy ( quickusb_class );
605         unregister_chrdev ( dev_major, "quickusb" );
606 }
607
608 module_init ( quickusb_init );
609 module_exit ( quickusb_exit );
610
611 MODULE_AUTHOR ( "Michael Brown <mbrown@fensystems.co.uk>" );
612 MODULE_DESCRIPTION ( "QuickUSB serial driver" );
613 MODULE_LICENSE ( "GPL" );
614 MODULE_DEVICE_TABLE ( usb, quickusb_ids );
615
616 module_param ( debug, bool, S_IRUGO | S_IWUSR );
617 MODULE_PARM_DESC ( debug, "Enable debugging" );
618
619 module_param ( dev_major, uint, S_IRUGO | S_IWUSR );
620 MODULE_PARM_DESC ( dev_major, "Major device number" );