forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/drivers/usb/serial/cp210x.c
....@@ -50,6 +50,9 @@
5050 static int cp210x_port_probe(struct usb_serial_port *);
5151 static int cp210x_port_remove(struct usb_serial_port *);
5252 static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
53
+static void cp210x_process_read_urb(struct urb *urb);
54
+static void cp210x_enable_event_mode(struct usb_serial_port *port);
55
+static void cp210x_disable_event_mode(struct usb_serial_port *port);
5356
5457 static const struct usb_device_id id_table[] = {
5558 { USB_DEVICE(0x0404, 0x034C) }, /* NCR Retail IO Box */
....@@ -61,6 +64,7 @@
6164 { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */
6265 { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
6366 { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
67
+ { USB_DEVICE(0x0908, 0x0070) }, /* Siemens SCALANCE LPE-9000 USB Serial Console */
6468 { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */
6569 { USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */
6670 { USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */
....@@ -120,6 +124,7 @@
120124 { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
121125 { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
122126 { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
127
+ { USB_DEVICE(0x10C4, 0x82AA) }, /* Silicon Labs IFS-USB-DATACABLE used with Quint UPS */
123128 { USB_DEVICE(0x10C4, 0x82EF) }, /* CESINEL FALCO 6105 AC Power Supply */
124129 { USB_DEVICE(0x10C4, 0x82F1) }, /* CESINEL MEDCAL EFD Earth Fault Detector */
125130 { USB_DEVICE(0x10C4, 0x82F2) }, /* CESINEL MEDCAL ST Network Analyzer */
....@@ -131,6 +136,7 @@
131136 { USB_DEVICE(0x10C4, 0x83AA) }, /* Mark-10 Digital Force Gauge */
132137 { USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */
133138 { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
139
+ { USB_DEVICE(0x10C4, 0x8414) }, /* Decagon USB Cable Adapter */
134140 { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
135141 { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
136142 { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */
....@@ -195,6 +201,10 @@
195201 { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
196202 { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
197203 { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
204
+ { USB_DEVICE(0x17A8, 0x0011) }, /* Kamstrup 444 MHz RF sniffer */
205
+ { USB_DEVICE(0x17A8, 0x0013) }, /* Kamstrup 870 MHz RF sniffer */
206
+ { USB_DEVICE(0x17A8, 0x0101) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Int Ant) */
207
+ { USB_DEVICE(0x17A8, 0x0102) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Ext Ant) */
198208 { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
199209 { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
200210 { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
....@@ -257,13 +267,27 @@
257267 u8 gpio_input;
258268 #endif
259269 u8 partnum;
270
+ speed_t min_speed;
260271 speed_t max_speed;
261272 bool use_actual_rate;
273
+ bool no_event_mode;
274
+};
275
+
276
+enum cp210x_event_state {
277
+ ES_DATA,
278
+ ES_ESCAPE,
279
+ ES_LSR,
280
+ ES_LSR_DATA_0,
281
+ ES_LSR_DATA_1,
282
+ ES_MSR
262283 };
263284
264285 struct cp210x_port_private {
265
- __u8 bInterfaceNumber;
286
+ u8 bInterfaceNumber;
266287 bool has_swapped_line_ctl;
288
+ bool event_mode;
289
+ enum cp210x_event_state event_state;
290
+ u8 lsr;
267291 };
268292
269293 static struct usb_serial_driver cp210x_device = {
....@@ -284,12 +308,14 @@
284308 .unthrottle = usb_serial_generic_unthrottle,
285309 .tiocmget = cp210x_tiocmget,
286310 .tiocmset = cp210x_tiocmset,
311
+ .get_icount = usb_serial_generic_get_icount,
287312 .attach = cp210x_attach,
288313 .disconnect = cp210x_disconnect,
289314 .release = cp210x_release,
290315 .port_probe = cp210x_port_probe,
291316 .port_remove = cp210x_port_remove,
292
- .dtr_rts = cp210x_dtr_rts
317
+ .dtr_rts = cp210x_dtr_rts,
318
+ .process_read_urb = cp210x_process_read_urb,
293319 };
294320
295321 static struct usb_serial_driver * const serial_drivers[] = {
....@@ -411,13 +437,22 @@
411437 */
412438 #define PURGE_ALL 0x000f
413439
440
+/* CP210X_EMBED_EVENTS */
441
+#define CP210X_ESCCHAR 0xec
442
+
443
+#define CP210X_LSR_OVERRUN BIT(1)
444
+#define CP210X_LSR_PARITY BIT(2)
445
+#define CP210X_LSR_FRAME BIT(3)
446
+#define CP210X_LSR_BREAK BIT(4)
447
+
448
+
414449 /* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */
415450 struct cp210x_flow_ctl {
416451 __le32 ulControlHandshake;
417452 __le32 ulFlowReplace;
418453 __le32 ulXonLimit;
419454 __le32 ulXoffLimit;
420
-} __packed;
455
+};
421456
422457 /* cp210x_flow_ctl::ulControlHandshake */
423458 #define CP210X_SERIAL_DTR_MASK GENMASK(1, 0)
....@@ -451,16 +486,16 @@
451486 struct cp210x_pin_mode {
452487 u8 eci;
453488 u8 sci;
454
-} __packed;
489
+};
455490
456491 #define CP210X_PIN_MODE_MODEM 0
457492 #define CP210X_PIN_MODE_GPIO BIT(0)
458493
459494 /*
460
- * CP210X_VENDOR_SPECIFIC, CP210X_GET_PORTCONFIG call reads these 0xf bytes.
461
- * Structure needs padding due to unused/unspecified bytes.
495
+ * CP210X_VENDOR_SPECIFIC, CP210X_GET_PORTCONFIG call reads these 0xf bytes
496
+ * on a CP2105 chip. Structure needs padding due to unused/unspecified bytes.
462497 */
463
-struct cp210x_config {
498
+struct cp210x_dual_port_config {
464499 __le16 gpio_mode;
465500 u8 __pad0[2];
466501 __le16 reset_state;
....@@ -471,6 +506,19 @@
471506 u8 device_cfg;
472507 } __packed;
473508
509
+/*
510
+ * CP210X_VENDOR_SPECIFIC, CP210X_GET_PORTCONFIG call reads these 0xd bytes
511
+ * on a CP2104 chip. Structure needs padding due to unused/unspecified bytes.
512
+ */
513
+struct cp210x_single_port_config {
514
+ __le16 gpio_mode;
515
+ u8 __pad0[2];
516
+ __le16 reset_state;
517
+ u8 __pad1[4];
518
+ __le16 suspend_state;
519
+ u8 device_cfg;
520
+} __packed;
521
+
474522 /* GPIO modes */
475523 #define CP210X_SCI_GPIO_MODE_OFFSET 9
476524 #define CP210X_SCI_GPIO_MODE_MASK GENMASK(11, 9)
....@@ -478,10 +526,18 @@
478526 #define CP210X_ECI_GPIO_MODE_OFFSET 2
479527 #define CP210X_ECI_GPIO_MODE_MASK GENMASK(3, 2)
480528
529
+#define CP210X_GPIO_MODE_OFFSET 8
530
+#define CP210X_GPIO_MODE_MASK GENMASK(11, 8)
531
+
481532 /* CP2105 port configuration values */
482533 #define CP2105_GPIO0_TXLED_MODE BIT(0)
483534 #define CP2105_GPIO1_RXLED_MODE BIT(1)
484535 #define CP2105_GPIO1_RS485_MODE BIT(2)
536
+
537
+/* CP2104 port configuration values */
538
+#define CP2104_GPIO0_TXLED_MODE BIT(0)
539
+#define CP2104_GPIO1_RXLED_MODE BIT(1)
540
+#define CP2104_GPIO2_RS485_MODE BIT(2)
485541
486542 /* CP2102N configuration array indices */
487543 #define CP210X_2NCONFIG_CONFIG_VERSION_IDX 2
....@@ -499,7 +555,7 @@
499555 struct cp210x_gpio_write {
500556 u8 mask;
501557 u8 state;
502
-} __packed;
558
+};
503559
504560 /*
505561 * Helper to get interface number when we only have struct usb_serial.
....@@ -802,6 +858,7 @@
802858
803859 static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
804860 {
861
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
805862 int result;
806863
807864 result = cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_ENABLE);
....@@ -813,21 +870,144 @@
813870 /* Configure the termios structure */
814871 cp210x_get_termios(tty, port);
815872
816
- /* The baud rate must be initialised on cp2104 */
817
- if (tty)
873
+ if (tty) {
874
+ /* The baud rate must be initialised on cp2104 */
818875 cp210x_change_speed(tty, port, NULL);
819876
820
- return usb_serial_generic_open(tty, port);
877
+ if (I_INPCK(tty))
878
+ cp210x_enable_event_mode(port);
879
+ }
880
+
881
+ result = usb_serial_generic_open(tty, port);
882
+ if (result)
883
+ goto err_disable;
884
+
885
+ return 0;
886
+
887
+err_disable:
888
+ cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE);
889
+ port_priv->event_mode = false;
890
+
891
+ return result;
821892 }
822893
823894 static void cp210x_close(struct usb_serial_port *port)
824895 {
896
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
897
+
825898 usb_serial_generic_close(port);
826899
827900 /* Clear both queues; cp2108 needs this to avoid an occasional hang */
828901 cp210x_write_u16_reg(port, CP210X_PURGE, PURGE_ALL);
829902
830903 cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_DISABLE);
904
+
905
+ /* Disabling the interface disables event-insertion mode. */
906
+ port_priv->event_mode = false;
907
+}
908
+
909
+static void cp210x_process_lsr(struct usb_serial_port *port, unsigned char lsr, char *flag)
910
+{
911
+ if (lsr & CP210X_LSR_BREAK) {
912
+ port->icount.brk++;
913
+ *flag = TTY_BREAK;
914
+ } else if (lsr & CP210X_LSR_PARITY) {
915
+ port->icount.parity++;
916
+ *flag = TTY_PARITY;
917
+ } else if (lsr & CP210X_LSR_FRAME) {
918
+ port->icount.frame++;
919
+ *flag = TTY_FRAME;
920
+ }
921
+
922
+ if (lsr & CP210X_LSR_OVERRUN) {
923
+ port->icount.overrun++;
924
+ tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
925
+ }
926
+}
927
+
928
+static bool cp210x_process_char(struct usb_serial_port *port, unsigned char *ch, char *flag)
929
+{
930
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
931
+
932
+ switch (port_priv->event_state) {
933
+ case ES_DATA:
934
+ if (*ch == CP210X_ESCCHAR) {
935
+ port_priv->event_state = ES_ESCAPE;
936
+ break;
937
+ }
938
+ return false;
939
+ case ES_ESCAPE:
940
+ switch (*ch) {
941
+ case 0:
942
+ dev_dbg(&port->dev, "%s - escape char\n", __func__);
943
+ *ch = CP210X_ESCCHAR;
944
+ port_priv->event_state = ES_DATA;
945
+ return false;
946
+ case 1:
947
+ port_priv->event_state = ES_LSR_DATA_0;
948
+ break;
949
+ case 2:
950
+ port_priv->event_state = ES_LSR;
951
+ break;
952
+ case 3:
953
+ port_priv->event_state = ES_MSR;
954
+ break;
955
+ default:
956
+ dev_err(&port->dev, "malformed event 0x%02x\n", *ch);
957
+ port_priv->event_state = ES_DATA;
958
+ break;
959
+ }
960
+ break;
961
+ case ES_LSR_DATA_0:
962
+ port_priv->lsr = *ch;
963
+ port_priv->event_state = ES_LSR_DATA_1;
964
+ break;
965
+ case ES_LSR_DATA_1:
966
+ dev_dbg(&port->dev, "%s - lsr = 0x%02x, data = 0x%02x\n",
967
+ __func__, port_priv->lsr, *ch);
968
+ cp210x_process_lsr(port, port_priv->lsr, flag);
969
+ port_priv->event_state = ES_DATA;
970
+ return false;
971
+ case ES_LSR:
972
+ dev_dbg(&port->dev, "%s - lsr = 0x%02x\n", __func__, *ch);
973
+ port_priv->lsr = *ch;
974
+ cp210x_process_lsr(port, port_priv->lsr, flag);
975
+ port_priv->event_state = ES_DATA;
976
+ break;
977
+ case ES_MSR:
978
+ dev_dbg(&port->dev, "%s - msr = 0x%02x\n", __func__, *ch);
979
+ /* unimplemented */
980
+ port_priv->event_state = ES_DATA;
981
+ break;
982
+ }
983
+
984
+ return true;
985
+}
986
+
987
+static void cp210x_process_read_urb(struct urb *urb)
988
+{
989
+ struct usb_serial_port *port = urb->context;
990
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
991
+ unsigned char *ch = urb->transfer_buffer;
992
+ char flag;
993
+ int i;
994
+
995
+ if (!urb->actual_length)
996
+ return;
997
+
998
+ if (port_priv->event_mode) {
999
+ for (i = 0; i < urb->actual_length; i++, ch++) {
1000
+ flag = TTY_NORMAL;
1001
+
1002
+ if (cp210x_process_char(port, ch, &flag))
1003
+ continue;
1004
+
1005
+ tty_insert_flip_char(&port->port, *ch, flag);
1006
+ }
1007
+ } else {
1008
+ tty_insert_flip_string(&port->port, ch, urb->actual_length);
1009
+ }
1010
+ tty_flip_buffer_push(&port->port);
8311011 }
8321012
8331013 /*
....@@ -1088,13 +1268,10 @@
10881268 return cp210x_an205_table1[i].rate;
10891269 }
10901270
1091
-static speed_t cp210x_get_actual_rate(struct usb_serial *serial, speed_t baud)
1271
+static speed_t cp210x_get_actual_rate(speed_t baud)
10921272 {
1093
- struct cp210x_serial_private *priv = usb_get_serial_data(serial);
10941273 unsigned int prescale = 1;
10951274 unsigned int div;
1096
-
1097
- baud = clamp(baud, 300u, priv->max_speed);
10981275
10991276 if (baud <= 365)
11001277 prescale = 4;
....@@ -1138,20 +1315,18 @@
11381315 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
11391316 u32 baud;
11401317
1141
- baud = tty->termios.c_ospeed;
1142
-
11431318 /*
11441319 * This maps the requested rate to the actual rate, a valid rate on
11451320 * cp2102 or cp2103, or to an arbitrary rate in [1M, max_speed].
11461321 *
11471322 * NOTE: B0 is not implemented.
11481323 */
1324
+ baud = clamp(tty->termios.c_ospeed, priv->min_speed, priv->max_speed);
1325
+
11491326 if (priv->use_actual_rate)
1150
- baud = cp210x_get_actual_rate(serial, baud);
1327
+ baud = cp210x_get_actual_rate(baud);
11511328 else if (baud < 1000000)
11521329 baud = cp210x_get_an205_rate(baud);
1153
- else if (baud > priv->max_speed)
1154
- baud = priv->max_speed;
11551330
11561331 dev_dbg(&port->dev, "%s - setting baud rate to %u\n", __func__, baud);
11571332 if (cp210x_write_u32_reg(port, CP210X_SET_BAUDRATE, baud)) {
....@@ -1163,6 +1338,45 @@
11631338 }
11641339
11651340 tty_encode_baud_rate(tty, baud, baud);
1341
+}
1342
+
1343
+static void cp210x_enable_event_mode(struct usb_serial_port *port)
1344
+{
1345
+ struct cp210x_serial_private *priv = usb_get_serial_data(port->serial);
1346
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
1347
+ int ret;
1348
+
1349
+ if (port_priv->event_mode)
1350
+ return;
1351
+
1352
+ if (priv->no_event_mode)
1353
+ return;
1354
+
1355
+ port_priv->event_state = ES_DATA;
1356
+ port_priv->event_mode = true;
1357
+
1358
+ ret = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, CP210X_ESCCHAR);
1359
+ if (ret) {
1360
+ dev_err(&port->dev, "failed to enable events: %d\n", ret);
1361
+ port_priv->event_mode = false;
1362
+ }
1363
+}
1364
+
1365
+static void cp210x_disable_event_mode(struct usb_serial_port *port)
1366
+{
1367
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
1368
+ int ret;
1369
+
1370
+ if (!port_priv->event_mode)
1371
+ return;
1372
+
1373
+ ret = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, 0);
1374
+ if (ret) {
1375
+ dev_err(&port->dev, "failed to disable events: %d\n", ret);
1376
+ return;
1377
+ }
1378
+
1379
+ port_priv->event_mode = false;
11661380 }
11671381
11681382 static void cp210x_set_termios(struct tty_struct *tty,
....@@ -1287,6 +1501,14 @@
12871501 sizeof(flow_ctl));
12881502 }
12891503
1504
+ /*
1505
+ * Enable event-insertion mode only if input parity checking is
1506
+ * enabled for now.
1507
+ */
1508
+ if (I_INPCK(tty))
1509
+ cp210x_enable_event_mode(port);
1510
+ else
1511
+ cp210x_disable_event_mode(port);
12901512 }
12911513
12921514 static int cp210x_tiocmset(struct tty_struct *tty,
....@@ -1518,7 +1740,7 @@
15181740 {
15191741 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
15201742 struct cp210x_pin_mode mode;
1521
- struct cp210x_config config;
1743
+ struct cp210x_dual_port_config config;
15221744 u8 intf_num = cp210x_interface_num(serial);
15231745 u8 iface_config;
15241746 int result;
....@@ -1579,6 +1801,56 @@
15791801 return 0;
15801802 }
15811803
1804
+static int cp2104_gpioconf_init(struct usb_serial *serial)
1805
+{
1806
+ struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1807
+ struct cp210x_single_port_config config;
1808
+ u8 iface_config;
1809
+ u8 gpio_latch;
1810
+ int result;
1811
+ u8 i;
1812
+
1813
+ result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST,
1814
+ CP210X_GET_PORTCONFIG, &config,
1815
+ sizeof(config));
1816
+ if (result < 0)
1817
+ return result;
1818
+
1819
+ priv->gc.ngpio = 4;
1820
+
1821
+ iface_config = config.device_cfg;
1822
+ priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
1823
+ CP210X_GPIO_MODE_MASK) >>
1824
+ CP210X_GPIO_MODE_OFFSET);
1825
+ gpio_latch = (u8)((le16_to_cpu(config.reset_state) &
1826
+ CP210X_GPIO_MODE_MASK) >>
1827
+ CP210X_GPIO_MODE_OFFSET);
1828
+
1829
+ /* mark all pins which are not in GPIO mode */
1830
+ if (iface_config & CP2104_GPIO0_TXLED_MODE) /* GPIO 0 */
1831
+ priv->gpio_altfunc |= BIT(0);
1832
+ if (iface_config & CP2104_GPIO1_RXLED_MODE) /* GPIO 1 */
1833
+ priv->gpio_altfunc |= BIT(1);
1834
+ if (iface_config & CP2104_GPIO2_RS485_MODE) /* GPIO 2 */
1835
+ priv->gpio_altfunc |= BIT(2);
1836
+
1837
+ /*
1838
+ * Like CP2102N, CP2104 has also no strict input and output pin
1839
+ * modes.
1840
+ * Do the same input mode emulation as CP2102N.
1841
+ */
1842
+ for (i = 0; i < priv->gc.ngpio; ++i) {
1843
+ /*
1844
+ * Set direction to "input" iff pin is open-drain and reset
1845
+ * value is 1.
1846
+ */
1847
+ if (!(priv->gpio_pushpull & BIT(i)) && (gpio_latch & BIT(i)))
1848
+ priv->gpio_input |= BIT(i);
1849
+ }
1850
+
1851
+ return 0;
1852
+}
1853
+
15821854 static int cp2102n_gpioconf_init(struct usb_serial *serial)
15831855 {
15841856 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
....@@ -1624,12 +1896,6 @@
16241896 if (config_version != 0x01)
16251897 return -ENOTSUPP;
16261898
1627
- /*
1628
- * We only support 4 GPIOs even on the QFN28 package, because
1629
- * config locations of GPIOs 4-6 determined using reverse
1630
- * engineering revealed conflicting offsets with other
1631
- * documented functions. So we'll just play it safe for now.
1632
- */
16331899 priv->gc.ngpio = 4;
16341900
16351901 /*
....@@ -1654,6 +1920,19 @@
16541920 priv->gpio_altfunc |= BIT(3);
16551921 } else {
16561922 priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f;
1923
+ }
1924
+
1925
+ if (priv->partnum == CP210X_PARTNUM_CP2102N_QFN28) {
1926
+ /*
1927
+ * For the QFN28 package, GPIO4-6 are controlled by
1928
+ * the low three bits of the mode/latch fields.
1929
+ * Contrary to the document linked above, the bits for
1930
+ * the SUSPEND pins are elsewhere. No alternate
1931
+ * function is available for these pins.
1932
+ */
1933
+ priv->gc.ngpio = 7;
1934
+ gpio_latch |= (gpio_rst_latch & 7) << 4;
1935
+ priv->gpio_pushpull |= (gpio_pushpull & 7) << 4;
16571936 }
16581937
16591938 /*
....@@ -1682,6 +1961,9 @@
16821961 int result;
16831962
16841963 switch (priv->partnum) {
1964
+ case CP210X_PARTNUM_CP2104:
1965
+ result = cp2104_gpioconf_init(serial);
1966
+ break;
16851967 case CP210X_PARTNUM_CP2105:
16861968 result = cp2105_gpioconf_init(serial);
16871969 break;
....@@ -1778,6 +2060,7 @@
17782060 {
17792061 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
17802062 bool use_actual_rate = false;
2063
+ speed_t min = 300;
17812064 speed_t max;
17822065
17832066 switch (priv->partnum) {
....@@ -1800,6 +2083,7 @@
18002083 use_actual_rate = true;
18012084 max = 2000000; /* ECI */
18022085 } else {
2086
+ min = 2400;
18032087 max = 921600; /* SCI */
18042088 }
18052089 break;
....@@ -1814,8 +2098,49 @@
18142098 break;
18152099 }
18162100
2101
+ priv->min_speed = min;
18172102 priv->max_speed = max;
18182103 priv->use_actual_rate = use_actual_rate;
2104
+}
2105
+
2106
+static void cp2102_determine_quirks(struct usb_serial *serial)
2107
+{
2108
+ struct cp210x_serial_private *priv = usb_get_serial_data(serial);
2109
+ u8 *buf;
2110
+ int ret;
2111
+
2112
+ buf = kmalloc(2, GFP_KERNEL);
2113
+ if (!buf)
2114
+ return;
2115
+ /*
2116
+ * Some (possibly counterfeit) CP2102 do not support event-insertion
2117
+ * mode and respond differently to malformed vendor requests.
2118
+ * Specifically, they return one instead of two bytes when sent a
2119
+ * two-byte part-number request.
2120
+ */
2121
+ ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
2122
+ CP210X_VENDOR_SPECIFIC, REQTYPE_DEVICE_TO_HOST,
2123
+ CP210X_GET_PARTNUM, 0, buf, 2, USB_CTRL_GET_TIMEOUT);
2124
+ if (ret == 1) {
2125
+ dev_dbg(&serial->interface->dev,
2126
+ "device does not support event-insertion mode\n");
2127
+ priv->no_event_mode = true;
2128
+ }
2129
+
2130
+ kfree(buf);
2131
+}
2132
+
2133
+static void cp210x_determine_quirks(struct usb_serial *serial)
2134
+{
2135
+ struct cp210x_serial_private *priv = usb_get_serial_data(serial);
2136
+
2137
+ switch (priv->partnum) {
2138
+ case CP210X_PARTNUM_CP2102:
2139
+ cp2102_determine_quirks(serial);
2140
+ break;
2141
+ default:
2142
+ break;
2143
+ }
18192144 }
18202145
18212146 static int cp210x_attach(struct usb_serial *serial)
....@@ -1838,6 +2163,7 @@
18382163
18392164 usb_set_serial_data(serial, priv);
18402165
2166
+ cp210x_determine_quirks(serial);
18412167 cp210x_init_max_speed(serial);
18422168
18432169 result = cp210x_gpio_init(serial);