usb: option: add/modify Olivetti Olicard modems
[pandora-kernel.git] / drivers / usb / serial / option.c
index 948a19f..ac73f49 100644 (file)
@@ -352,6 +352,9 @@ static void option_instat_callback(struct urb *urb);
 /* Zoom */
 #define ZOOM_PRODUCT_4597                      0x9607
 
+/* SpeedUp SU9800 usb 3g modem */
+#define SPEEDUP_PRODUCT_SU9800                 0x9800
+
 /* Haier products */
 #define HAIER_VENDOR_ID                                0x201e
 #define HAIER_PRODUCT_CE100                    0x2009
@@ -372,8 +375,12 @@ static void option_instat_callback(struct urb *urb);
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
 #define OLIVETTI_PRODUCT_OLICARD100            0xc000
+#define OLIVETTI_PRODUCT_OLICARD120            0xc001
+#define OLIVETTI_PRODUCT_OLICARD140            0xc002
 #define OLIVETTI_PRODUCT_OLICARD145            0xc003
+#define OLIVETTI_PRODUCT_OLICARD155            0xc004
 #define OLIVETTI_PRODUCT_OLICARD200            0xc005
+#define OLIVETTI_PRODUCT_OLICARD160            0xc00a
 #define OLIVETTI_PRODUCT_OLICARD500            0xc00b
 
 /* Celot products */
@@ -1577,6 +1584,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
          .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
        },
+       { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) },
        { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
        { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
        { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
@@ -1611,15 +1619,21 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
-
-       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD140),
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD155),
+               .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200),
-               .driver_info = (kernel_ulong_t)&net_intf6_blacklist
-       },
+               .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD160),
+               .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500),
-               .driver_info = (kernel_ulong_t)&net_intf4_blacklist
-       },
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
        { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
@@ -1731,7 +1745,6 @@ static struct usb_serial_driver option_1port_device = {
        .write             = usb_wwan_write,
        .write_room        = usb_wwan_write_room,
        .chars_in_buffer   = usb_wwan_chars_in_buffer,
-       .set_termios       = usb_wwan_set_termios,
        .tiocmget          = usb_wwan_tiocmget,
        .tiocmset          = usb_wwan_tiocmset,
        .ioctl             = usb_wwan_ioctl,
@@ -1906,6 +1919,7 @@ static void option_instat_callback(struct urb *urb)
 
        /* Resubmit urb so we continue receiving IRQ data */
        if (status != -ESHUTDOWN && status != -ENOENT) {
+               usb_mark_last_busy(port->serial->dev);
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
                        dev_dbg(dev, "%s: resubmit intr urb failed. (%d)\n",
@@ -1925,6 +1939,7 @@ static int option_send_setup(struct usb_serial_port *port)
        struct option_private *priv = intfdata->private;
        struct usb_wwan_port_private *portdata;
        int val = 0;
+       int res;
 
        portdata = usb_get_serial_port_data(port);
 
@@ -1933,9 +1948,17 @@ static int option_send_setup(struct usb_serial_port *port)
        if (portdata->rts_state)
                val |= 0x02;
 
-       return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+       res = usb_autopm_get_interface(serial->interface);
+       if (res)
+               return res;
+
+       res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                0x22, 0x21, val, priv->bInterfaceNumber, NULL,
                                0, USB_CTRL_SET_TIMEOUT);
+
+       usb_autopm_put_interface(serial->interface);
+
+       return res;
 }
 
 MODULE_AUTHOR(DRIVER_AUTHOR);