]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/serial/airprime.c
Pull asus into release branch
[linux-2.6-omap-h63xx.git] / drivers / usb / serial / airprime.c
index 18816bf96a4d6152da19a062c5f21d3247eaca60..77bb893bf2e922c51bb51ef4e2ac69f6d2cd2a86 100644 (file)
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
-       { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
-       { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */
-       { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */
-       { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
-       { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
-       { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -44,20 +38,56 @@ 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;
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
+       if (status) {
                dbg("%s - nonzero read bulk status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                return;
        }
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -79,6 +109,7 @@ static void airprime_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct airprime_private *priv = usb_get_serial_port_data(port);
+       int status = urb->status;
        unsigned long flags;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -86,9 +117,9 @@ static void airprime_write_bulk_callback(struct urb *urb)
        /* free up the transfer buffer, as usb_free_urb() does not do this */
        kfree (urb->transfer_buffer);
 
-       if (urb->status)
+       if (status)
                dbg("%s - nonzero write bulk status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
        spin_lock_irqsave(&priv->lock, flags);
        --priv->outstanding_urbs;
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -118,6 +149,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 +186,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 +214,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);