USB: serial: option: add support for Novatel E371 PCIe card
[pandora-kernel.git] / drivers / usb / serial / ftdi_sio.c
index 8d686cb..6e08639 100644 (file)
@@ -163,6 +163,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) },
@@ -202,6 +203,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
+       { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_LP101_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_P200X_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
@@ -588,6 +591,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        /*
         * ELV devices:
         */
@@ -743,9 +748,34 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
                .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
        { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
-       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
-       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
-       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57B_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29A_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29B_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29F_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62B_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S01_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29C_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_81B_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_82B_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5D_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K4Y_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5G_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S05_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_60_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_61_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63B_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_64_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_65_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92D_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_W5R_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_A5R_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_PW1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
        { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
@@ -889,6 +919,42 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
        /* Crucible Devices */
        { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
+       /* Cressi Devices */
+       { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) },
+       /* Brainboxes Devices */
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) },
+       { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -2167,9 +2233,33 @@ static void ftdi_set_termios(struct tty_struct *tty,
                termios->c_cflag |= CRTSCTS;
        }
 
+       /*
+        * All FTDI UART chips are limited to CS7/8. We shouldn't pretend to
+        * support CS5/6 and revert the CSIZE setting instead.
+        *
+        * CS5 however is used to control some smartcard readers which abuse
+        * this limitation to switch modes. Original FTDI chips fall back to
+        * eight data bits.
+        *
+        * TODO: Implement a quirk to only allow this with mentioned
+        *       readers. One I know of (Argolis Smartreader V1)
+        *       returns "USB smartcard server" as iInterface string.
+        *       The vendor didn't bother with a custom VID/PID of
+        *       course.
+        */
+       if (C_CSIZE(tty) == CS6) {
+               dev_warn(&port->dev, "requested CSIZE setting not supported\n");
+
+               termios->c_cflag &= ~CSIZE;
+               if (old_termios)
+                       termios->c_cflag |= old_termios->c_cflag & CSIZE;
+               else
+                       termios->c_cflag |= CS8;
+       }
+
        cflag = termios->c_cflag;
 
-       if (old_termios == 0)
+       if (!old_termios)
                goto no_skip;
 
        if (old_termios->c_cflag == termios->c_cflag
@@ -2203,13 +2293,19 @@ no_skip:
        } else {
                urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE;
        }
-       if (cflag & CSIZE) {
-               switch (cflag & CSIZE) {
-               case CS7: urb_value |= 7; dbg("Setting CS7"); break;
-               case CS8: urb_value |= 8; dbg("Setting CS8"); break;
-               default:
-                       dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n");
-               }
+       switch (cflag & CSIZE) {
+       case CS5:
+               dev_dbg(&port->dev, "Setting CS5 quirk\n");
+               break;
+       case CS7:
+               urb_value |= 7;
+               dev_dbg(&port->dev, "Setting CS7\n");
+               break;
+       default:
+       case CS8:
+               urb_value |= 8;
+               dev_dbg(&port->dev, "Setting CS8\n");
+               break;
        }
 
        /* This is needed by the break command since it uses the same command