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