USB: RTS/DTR signal patch for airprime driver
[powerpc.git] / drivers / usb / serial / airprime.c
index 18816bf..310a8b5 100644 (file)
@@ -44,8 +44,43 @@ struct airprime_private {
        int outstanding_urbs;
        int throttled;
        struct urb *read_urbp[NUM_READ_URBS];
+
+       /* Settings for the port */
+       int rts_state;  /* Handshaking pins (outputs) */
+       int dtr_state;
+       int cts_state;  /* Handshaking pins (inputs) */
+       int dsr_state;
+       int dcd_state;
+       int ri_state;
 };
 
+static int airprime_send_setup(struct usb_serial_port *port)
+{
+       struct usb_serial *serial = port->serial;
+       struct airprime_private *priv;
+
+       dbg("%s", __FUNCTION__);
+
+       if (port->number != 0)
+               return 0;
+
+       priv = usb_get_serial_port_data(port);
+
+       if (port->tty) {
+               int val = 0;
+               if (priv->dtr_state)
+                       val |= 0x01;
+               if (priv->rts_state)
+                       val |= 0x02;
+
+               return usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0),
+                               0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+       }
+
+       return 0;
+}
+
 static void airprime_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
@@ -118,6 +153,10 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                usb_set_serial_port_data(port, priv);
        }
 
+       /* Set some sane defaults */
+       priv->rts_state = 1;
+       priv->dtr_state = 1;
+
        for (i = 0; i < NUM_READ_URBS; ++i) {
                buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!buffer) {
@@ -151,6 +190,9 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                /* remember this urb so we can kill it when the port is closed */
                priv->read_urbp[i] = urb;
        }
+
+       airprime_send_setup(port);
+
        goto out;
 
  errout:
@@ -176,6 +218,11 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
+       priv->rts_state = 0;
+       priv->dtr_state = 0;
+
+       airprime_send_setup(port);
+
        for (i = 0; i < NUM_READ_URBS; ++i) {
                usb_kill_urb (priv->read_urbp[i]);
                kfree (priv->read_urbp[i]->transfer_buffer);