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