@@ -400,6 +400,7 @@ struct cp210x_special_chars {
400400};
401401
402402/* CP210X_VENDOR_SPECIFIC values */
403+ #define CP210X_GET_FW_VER 0x000E
403404#define CP210X_READ_2NCONFIG 0x000E
404405#define CP210X_GET_FW_VER_2N 0x0010
405406#define CP210X_READ_LATCH 0x00C2
@@ -638,7 +639,7 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req,
638639 result = usb_control_msg (serial -> dev , usb_rcvctrlpipe (serial -> dev , 0 ),
639640 req , REQTYPE_INTERFACE_TO_HOST , 0 ,
640641 port_priv -> bInterfaceNumber , dmabuf , bufsize ,
641- USB_CTRL_SET_TIMEOUT );
642+ USB_CTRL_GET_TIMEOUT );
642643 if (result == bufsize ) {
643644 memcpy (buf , dmabuf , bufsize );
644645 result = 0 ;
@@ -1145,33 +1146,6 @@ static void cp210x_disable_event_mode(struct usb_serial_port *port)
11451146 port_priv -> event_mode = false;
11461147}
11471148
1148- static int cp210x_set_chars (struct usb_serial_port * port ,
1149- struct cp210x_special_chars * chars )
1150- {
1151- struct cp210x_port_private * port_priv = usb_get_serial_port_data (port );
1152- struct usb_serial * serial = port -> serial ;
1153- void * dmabuf ;
1154- int result ;
1155-
1156- dmabuf = kmemdup (chars , sizeof (* chars ), GFP_KERNEL );
1157- if (!dmabuf )
1158- return - ENOMEM ;
1159-
1160- result = usb_control_msg (serial -> dev , usb_sndctrlpipe (serial -> dev , 0 ),
1161- CP210X_SET_CHARS , REQTYPE_HOST_TO_INTERFACE , 0 ,
1162- port_priv -> bInterfaceNumber ,
1163- dmabuf , sizeof (* chars ), USB_CTRL_SET_TIMEOUT );
1164-
1165- kfree (dmabuf );
1166-
1167- if (result < 0 ) {
1168- dev_err (& port -> dev , "failed to set special chars: %d\n" , result );
1169- return result ;
1170- }
1171-
1172- return 0 ;
1173- }
1174-
11751149static bool cp210x_termios_change (const struct ktermios * a , const struct ktermios * b )
11761150{
11771151 bool iflag_change , cc_change ;
@@ -1192,6 +1166,7 @@ static void cp210x_set_flow_control(struct tty_struct *tty,
11921166 struct cp210x_flow_ctl flow_ctl ;
11931167 u32 flow_repl ;
11941168 u32 ctl_hs ;
1169+ bool crtscts ;
11951170 int ret ;
11961171
11971172 /*
@@ -1218,9 +1193,12 @@ static void cp210x_set_flow_control(struct tty_struct *tty,
12181193 chars .bXonChar = START_CHAR (tty );
12191194 chars .bXoffChar = STOP_CHAR (tty );
12201195
1221- ret = cp210x_set_chars (port , & chars );
1222- if (ret )
1223- return ;
1196+ ret = cp210x_write_reg_block (port , CP210X_SET_CHARS , & chars ,
1197+ sizeof (chars ));
1198+ if (ret ) {
1199+ dev_err (& port -> dev , "failed to set special chars: %d\n" ,
1200+ ret );
1201+ }
12241202 }
12251203
12261204 mutex_lock (& port_priv -> mutex );
@@ -1249,14 +1227,14 @@ static void cp210x_set_flow_control(struct tty_struct *tty,
12491227 flow_repl |= CP210X_SERIAL_RTS_FLOW_CTL ;
12501228 else
12511229 flow_repl |= CP210X_SERIAL_RTS_INACTIVE ;
1252- port_priv -> crtscts = true;
1230+ crtscts = true;
12531231 } else {
12541232 ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE ;
12551233 if (port_priv -> rts )
12561234 flow_repl |= CP210X_SERIAL_RTS_ACTIVE ;
12571235 else
12581236 flow_repl |= CP210X_SERIAL_RTS_INACTIVE ;
1259- port_priv -> crtscts = false;
1237+ crtscts = false;
12601238 }
12611239
12621240 if (I_IXOFF (tty )) {
@@ -1279,8 +1257,12 @@ static void cp210x_set_flow_control(struct tty_struct *tty,
12791257 flow_ctl .ulControlHandshake = cpu_to_le32 (ctl_hs );
12801258 flow_ctl .ulFlowReplace = cpu_to_le32 (flow_repl );
12811259
1282- cp210x_write_reg_block (port , CP210X_SET_FLOW , & flow_ctl ,
1260+ ret = cp210x_write_reg_block (port , CP210X_SET_FLOW , & flow_ctl ,
12831261 sizeof (flow_ctl ));
1262+ if (ret )
1263+ goto out_unlock ;
1264+
1265+ port_priv -> crtscts = crtscts ;
12841266out_unlock :
12851267 mutex_unlock (& port_priv -> mutex );
12861268}
@@ -2111,12 +2093,26 @@ static int cp210x_get_fw_version(struct usb_serial *serial, u16 value)
21112093 return 0 ;
21122094}
21132095
2114- static void cp210x_determine_quirks (struct usb_serial * serial )
2096+ static void cp210x_determine_type (struct usb_serial * serial )
21152097{
21162098 struct cp210x_serial_private * priv = usb_get_serial_data (serial );
21172099 int ret ;
21182100
2101+ ret = cp210x_read_vendor_block (serial , REQTYPE_DEVICE_TO_HOST ,
2102+ CP210X_GET_PARTNUM , & priv -> partnum ,
2103+ sizeof (priv -> partnum ));
2104+ if (ret < 0 ) {
2105+ dev_warn (& serial -> interface -> dev ,
2106+ "querying part number failed\n" );
2107+ priv -> partnum = CP210X_PARTNUM_UNKNOWN ;
2108+ return ;
2109+ }
2110+
21192111 switch (priv -> partnum ) {
2112+ case CP210X_PARTNUM_CP2105 :
2113+ case CP210X_PARTNUM_CP2108 :
2114+ cp210x_get_fw_version (serial , CP210X_GET_FW_VER );
2115+ break ;
21202116 case CP210X_PARTNUM_CP2102N_QFN28 :
21212117 case CP210X_PARTNUM_CP2102N_QFN24 :
21222118 case CP210X_PARTNUM_CP2102N_QFN20 :
@@ -2140,18 +2136,9 @@ static int cp210x_attach(struct usb_serial *serial)
21402136 if (!priv )
21412137 return - ENOMEM ;
21422138
2143- result = cp210x_read_vendor_block (serial , REQTYPE_DEVICE_TO_HOST ,
2144- CP210X_GET_PARTNUM , & priv -> partnum ,
2145- sizeof (priv -> partnum ));
2146- if (result < 0 ) {
2147- dev_warn (& serial -> interface -> dev ,
2148- "querying part number failed\n" );
2149- priv -> partnum = CP210X_PARTNUM_UNKNOWN ;
2150- }
2151-
21522139 usb_set_serial_data (serial , priv );
21532140
2154- cp210x_determine_quirks (serial );
2141+ cp210x_determine_type (serial );
21552142 cp210x_init_max_speed (serial );
21562143
21572144 result = cp210x_gpio_init (serial );
0 commit comments