Automatically set port direction for read-only or write-only opens
authorMichael Brown <mbrown@fensystems.co.uk>
Sun, 12 Mar 2006 19:00:12 +0000 (19:00 +0000)
committerMichael Brown <mbrown@fensystems.co.uk>
Sun, 12 Mar 2006 19:00:12 +0000 (19:00 +0000)
kernel/quickusb.c
kernel/quickusb.h

index a271a48..b4ee016 100644 (file)
@@ -78,6 +78,29 @@ static int dev_major = 0;
  *
  */
 
+static int quickusb_gppio_open ( struct inode *inode, struct file *file ) {
+       struct quickusb_gppio *gppio = file->private_data;
+       struct usb_device *usb = gppio->quickusb->usb;
+       unsigned int fmode_rw;
+
+       fmode_rw = ( file->f_mode & ( FMODE_READ | FMODE_WRITE ) );
+       switch ( fmode_rw ) {
+       case FMODE_READ:
+               quickusb_write_port_dir ( usb, gppio->port, 0 );
+               break;
+       case FMODE_WRITE:
+               quickusb_write_port_dir ( usb, gppio->port, 0xff );
+               break;
+       default:
+               /* Do not set port direction; opener must use ioctl to
+                * set individual bits
+                */
+               break;
+       }
+
+       return 0;
+}
+
 static ssize_t quickusb_gppio_read ( struct file *file, char __user *user_data,
                                     size_t len, loff_t *ppos ) {
        struct quickusb_gppio *gppio = file->private_data;
@@ -130,6 +153,7 @@ static int quickusb_gppio_release ( struct inode *inode, struct file *file ) {
 
 static struct file_operations quickusb_gppio_fops = {
        .owner          = THIS_MODULE,
+       .open           = quickusb_gppio_open,
        .read           = quickusb_gppio_read,
        .write          = quickusb_gppio_write,
        .release        = quickusb_gppio_release,
index 7c279f8..4906d3c 100644 (file)
@@ -8,7 +8,34 @@
 #define QUICKUSB_TIMEOUT ( 1 * HZ )
 
 /**
- * QuickUsbReadPort - read data from GPPIO port
+ * quickusb_write_port_dir
+ *
+ * @usb: USB device
+ * @address: Port number
+ * @outputs: Output bit mask
+ *
+ * Returns 0 for success, or negative error number
+ */
+static inline int quickusb_write_port_dir ( struct usb_device *usb,
+                                           unsigned int address,
+                                           unsigned char outputs ) {
+       int ret;
+
+       ret =  usb_control_msg ( usb, usb_sndctrlpipe ( usb, 0 ),
+                                QUICKUSB_BREQUEST,
+                                QUICKUSB_BREQUESTTYPE_WRITE, 0, 0,
+                                &outputs, sizeof ( outputs ),
+                                QUICKUSB_TIMEOUT );
+
+       if ( ret > 0 ) {
+               ret = 0;
+       }
+
+       return ret;
+}
+
+/**
+ * quickusb_read_port - read data from GPPIO port
  *
  * @usb: USB device
  * @address: Port number
@@ -18,7 +45,7 @@
  * Returns 0 for success, or negative error number
  */
 static inline int quickusb_read_port ( struct usb_device *usb,
-                                      unsigned char address,
+                                      unsigned int address,
                                       unsigned char *data,
                                       size_t *len ) {
        int ret;
@@ -36,7 +63,7 @@ static inline int quickusb_read_port ( struct usb_device *usb,
 }
 
 /**
- * QuickUsbWritePort - write data to GPPIO port
+ * quickusb_write_port - write data to GPPIO port
  *
  * @usb: USB device
  * @address: Port number
@@ -46,7 +73,7 @@ static inline int quickusb_read_port ( struct usb_device *usb,
  * Returns 0 for success, or negative error number
  */
 static inline int quickusb_write_port ( struct usb_device *usb,
-                                       unsigned char address,
+                                       unsigned int address,
                                        unsigned char *data,
                                        size_t *len ) {
        int ret;