diff options
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 96 |
1 files changed, 51 insertions, 45 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c525b42dadde..8ff9d54b21e6 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -315,6 +315,7 @@ static struct usb_device_id id_table_combined [] = { | |||
315 | { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, | 315 | { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, |
316 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, | 316 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, |
317 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, | 317 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, |
318 | { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, | ||
318 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | 319 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, |
319 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | 320 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, |
320 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | 321 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, |
@@ -420,6 +421,14 @@ static struct usb_device_id id_table_combined [] = { | |||
420 | { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, | 421 | { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, |
421 | { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, | 422 | { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, |
422 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, | 423 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, |
424 | { USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) }, | ||
425 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) }, | ||
426 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) }, | ||
427 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) }, | ||
428 | { USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) }, | ||
429 | { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) }, | ||
430 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, | ||
431 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, | ||
423 | /* | 432 | /* |
424 | * These will probably use user-space drivers. Uncomment them if | 433 | * These will probably use user-space drivers. Uncomment them if |
425 | * you need them or use the user-specified vendor/product module | 434 | * you need them or use the user-specified vendor/product module |
@@ -459,6 +468,7 @@ static struct usb_device_id id_table_combined [] = { | |||
459 | { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, | 468 | { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, |
460 | { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) }, | 469 | { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) }, |
461 | { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, | 470 | { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, |
471 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, | ||
462 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, | 472 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, |
463 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | 473 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
464 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 474 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
@@ -533,6 +543,7 @@ static const char *ftdi_chip_name[] = { | |||
533 | [FT8U232AM] = "FT8U232AM", | 543 | [FT8U232AM] = "FT8U232AM", |
534 | [FT232BM] = "FT232BM", | 544 | [FT232BM] = "FT232BM", |
535 | [FT2232C] = "FT2232C", | 545 | [FT2232C] = "FT2232C", |
546 | [FT232RL] = "FT232RL", | ||
536 | }; | 547 | }; |
537 | 548 | ||
538 | 549 | ||
@@ -588,6 +599,8 @@ struct ftdi_private { | |||
588 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); | 599 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); |
589 | static int ftdi_sio_attach (struct usb_serial *serial); | 600 | static int ftdi_sio_attach (struct usb_serial *serial); |
590 | static void ftdi_shutdown (struct usb_serial *serial); | 601 | static void ftdi_shutdown (struct usb_serial *serial); |
602 | static int ftdi_sio_port_probe (struct usb_serial_port *port); | ||
603 | static int ftdi_sio_port_remove (struct usb_serial_port *port); | ||
591 | static int ftdi_open (struct usb_serial_port *port, struct file *filp); | 604 | static int ftdi_open (struct usb_serial_port *port, struct file *filp); |
592 | static void ftdi_close (struct usb_serial_port *port, struct file *filp); | 605 | static void ftdi_close (struct usb_serial_port *port, struct file *filp); |
593 | static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); | 606 | static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); |
@@ -622,6 +635,8 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
622 | .num_bulk_out = 1, | 635 | .num_bulk_out = 1, |
623 | .num_ports = 1, | 636 | .num_ports = 1, |
624 | .probe = ftdi_sio_probe, | 637 | .probe = ftdi_sio_probe, |
638 | .port_probe = ftdi_sio_port_probe, | ||
639 | .port_remove = ftdi_sio_port_remove, | ||
625 | .open = ftdi_open, | 640 | .open = ftdi_open, |
626 | .close = ftdi_close, | 641 | .close = ftdi_close, |
627 | .throttle = ftdi_throttle, | 642 | .throttle = ftdi_throttle, |
@@ -864,6 +879,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) | |||
864 | break; | 879 | break; |
865 | case FT232BM: /* FT232BM chip */ | 880 | case FT232BM: /* FT232BM chip */ |
866 | case FT2232C: /* FT2232C chip */ | 881 | case FT2232C: /* FT2232C chip */ |
882 | case FT232RL: | ||
867 | if (baud <= 3000000) { | 883 | if (baud <= 3000000) { |
868 | div_value = ftdi_232bm_baud_to_divisor(baud); | 884 | div_value = ftdi_232bm_baud_to_divisor(baud); |
869 | } else { | 885 | } else { |
@@ -1006,9 +1022,12 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1006 | /* (It might be a BM because of the iSerialNumber bug, | 1022 | /* (It might be a BM because of the iSerialNumber bug, |
1007 | * but it will still work as an AM device.) */ | 1023 | * but it will still work as an AM device.) */ |
1008 | priv->chip_type = FT8U232AM; | 1024 | priv->chip_type = FT8U232AM; |
1009 | } else { | 1025 | } else if (version < 0x600) { |
1010 | /* Assume its an FT232BM (or FT245BM) */ | 1026 | /* Assume its an FT232BM (or FT245BM) */ |
1011 | priv->chip_type = FT232BM; | 1027 | priv->chip_type = FT232BM; |
1028 | } else { | ||
1029 | /* Assume its an FT232R */ | ||
1030 | priv->chip_type = FT232RL; | ||
1012 | } | 1031 | } |
1013 | info("Detected %s", ftdi_chip_name[priv->chip_type]); | 1032 | info("Detected %s", ftdi_chip_name[priv->chip_type]); |
1014 | } | 1033 | } |
@@ -1024,11 +1043,10 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a | |||
1024 | { | 1043 | { |
1025 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1044 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1026 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1045 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1027 | struct usb_device *udev; | 1046 | struct usb_device *udev = port->serial->dev; |
1028 | unsigned short latency = 0; | 1047 | unsigned short latency = 0; |
1029 | int rv = 0; | 1048 | int rv = 0; |
1030 | 1049 | ||
1031 | udev = to_usb_device(dev); | ||
1032 | 1050 | ||
1033 | dbg("%s",__FUNCTION__); | 1051 | dbg("%s",__FUNCTION__); |
1034 | 1052 | ||
@@ -1052,13 +1070,11 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * | |||
1052 | { | 1070 | { |
1053 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1071 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1054 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1072 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1055 | struct usb_device *udev; | 1073 | struct usb_device *udev = port->serial->dev; |
1056 | char buf[1]; | 1074 | char buf[1]; |
1057 | int v = simple_strtoul(valbuf, NULL, 10); | 1075 | int v = simple_strtoul(valbuf, NULL, 10); |
1058 | int rv = 0; | 1076 | int rv = 0; |
1059 | 1077 | ||
1060 | udev = to_usb_device(dev); | ||
1061 | |||
1062 | dbg("%s: setting latency timer = %i", __FUNCTION__, v); | 1078 | dbg("%s: setting latency timer = %i", __FUNCTION__, v); |
1063 | 1079 | ||
1064 | rv = usb_control_msg(udev, | 1080 | rv = usb_control_msg(udev, |
@@ -1083,13 +1099,11 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att | |||
1083 | { | 1099 | { |
1084 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1100 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1085 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1101 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1086 | struct usb_device *udev; | 1102 | struct usb_device *udev = port->serial->dev; |
1087 | char buf[1]; | 1103 | char buf[1]; |
1088 | int v = simple_strtoul(valbuf, NULL, 10); | 1104 | int v = simple_strtoul(valbuf, NULL, 10); |
1089 | int rv = 0; | 1105 | int rv = 0; |
1090 | 1106 | ||
1091 | udev = to_usb_device(dev); | ||
1092 | |||
1093 | dbg("%s: setting event char = %i", __FUNCTION__, v); | 1107 | dbg("%s: setting event char = %i", __FUNCTION__, v); |
1094 | 1108 | ||
1095 | rv = usb_control_msg(udev, | 1109 | rv = usb_control_msg(udev, |
@@ -1110,46 +1124,38 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att | |||
1110 | static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer); | 1124 | static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer); |
1111 | static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); | 1125 | static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); |
1112 | 1126 | ||
1113 | static int create_sysfs_attrs(struct usb_serial *serial) | 1127 | static int create_sysfs_attrs(struct usb_serial_port *port) |
1114 | { | 1128 | { |
1115 | struct ftdi_private *priv; | 1129 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1116 | struct usb_device *udev; | ||
1117 | int retval = 0; | 1130 | int retval = 0; |
1118 | 1131 | ||
1119 | dbg("%s",__FUNCTION__); | 1132 | dbg("%s",__FUNCTION__); |
1120 | 1133 | ||
1121 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1122 | udev = serial->dev; | ||
1123 | |||
1124 | /* XXX I've no idea if the original SIO supports the event_char | 1134 | /* XXX I've no idea if the original SIO supports the event_char |
1125 | * sysfs parameter, so I'm playing it safe. */ | 1135 | * sysfs parameter, so I'm playing it safe. */ |
1126 | if (priv->chip_type != SIO) { | 1136 | if (priv->chip_type != SIO) { |
1127 | dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); | 1137 | dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); |
1128 | retval = device_create_file(&udev->dev, &dev_attr_event_char); | 1138 | retval = device_create_file(&port->dev, &dev_attr_event_char); |
1129 | if ((!retval) && | 1139 | if ((!retval) && |
1130 | (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { | 1140 | (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { |
1131 | retval = device_create_file(&udev->dev, | 1141 | retval = device_create_file(&port->dev, |
1132 | &dev_attr_latency_timer); | 1142 | &dev_attr_latency_timer); |
1133 | } | 1143 | } |
1134 | } | 1144 | } |
1135 | return retval; | 1145 | return retval; |
1136 | } | 1146 | } |
1137 | 1147 | ||
1138 | static void remove_sysfs_attrs(struct usb_serial *serial) | 1148 | static void remove_sysfs_attrs(struct usb_serial_port *port) |
1139 | { | 1149 | { |
1140 | struct ftdi_private *priv; | 1150 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1141 | struct usb_device *udev; | ||
1142 | 1151 | ||
1143 | dbg("%s",__FUNCTION__); | 1152 | dbg("%s",__FUNCTION__); |
1144 | 1153 | ||
1145 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1146 | udev = serial->dev; | ||
1147 | |||
1148 | /* XXX see create_sysfs_attrs */ | 1154 | /* XXX see create_sysfs_attrs */ |
1149 | if (priv->chip_type != SIO) { | 1155 | if (priv->chip_type != SIO) { |
1150 | device_remove_file(&udev->dev, &dev_attr_event_char); | 1156 | device_remove_file(&port->dev, &dev_attr_event_char); |
1151 | if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { | 1157 | if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { |
1152 | device_remove_file(&udev->dev, &dev_attr_latency_timer); | 1158 | device_remove_file(&port->dev, &dev_attr_latency_timer); |
1153 | } | 1159 | } |
1154 | } | 1160 | } |
1155 | 1161 | ||
@@ -1169,13 +1175,9 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id | |||
1169 | return (0); | 1175 | return (0); |
1170 | } | 1176 | } |
1171 | 1177 | ||
1172 | /* attach subroutine */ | 1178 | static int ftdi_sio_port_probe(struct usb_serial_port *port) |
1173 | static int ftdi_sio_attach (struct usb_serial *serial) | ||
1174 | { | 1179 | { |
1175 | struct usb_serial_port *port = serial->port[0]; | ||
1176 | struct ftdi_private *priv; | 1180 | struct ftdi_private *priv; |
1177 | struct ftdi_sio_quirk *quirk; | ||
1178 | int retval; | ||
1179 | 1181 | ||
1180 | dbg("%s",__FUNCTION__); | 1182 | dbg("%s",__FUNCTION__); |
1181 | 1183 | ||
@@ -1215,19 +1217,21 @@ static int ftdi_sio_attach (struct usb_serial *serial) | |||
1215 | kfree(port->bulk_out_buffer); | 1217 | kfree(port->bulk_out_buffer); |
1216 | port->bulk_out_buffer = NULL; | 1218 | port->bulk_out_buffer = NULL; |
1217 | 1219 | ||
1218 | usb_set_serial_port_data(serial->port[0], priv); | 1220 | usb_set_serial_port_data(port, priv); |
1219 | 1221 | ||
1220 | ftdi_determine_type (serial->port[0]); | 1222 | ftdi_determine_type (port); |
1221 | retval = create_sysfs_attrs(serial); | 1223 | create_sysfs_attrs(port); |
1222 | if (retval) | 1224 | return 0; |
1223 | dev_err(&serial->dev->dev, "Error creating sysfs files, " | 1225 | } |
1224 | "continuing\n"); | ||
1225 | 1226 | ||
1227 | /* attach subroutine */ | ||
1228 | static int ftdi_sio_attach (struct usb_serial *serial) | ||
1229 | { | ||
1226 | /* Check for device requiring special set up. */ | 1230 | /* Check for device requiring special set up. */ |
1227 | quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial); | 1231 | struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial); |
1228 | if (quirk && quirk->setup) { | 1232 | |
1233 | if (quirk && quirk->setup) | ||
1229 | quirk->setup(serial); | 1234 | quirk->setup(serial); |
1230 | } | ||
1231 | 1235 | ||
1232 | return 0; | 1236 | return 0; |
1233 | } /* ftdi_sio_attach */ | 1237 | } /* ftdi_sio_attach */ |
@@ -1271,17 +1275,18 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) | |||
1271 | * calls __serial_close for each open of the port | 1275 | * calls __serial_close for each open of the port |
1272 | * shutdown is called then (ie ftdi_shutdown) | 1276 | * shutdown is called then (ie ftdi_shutdown) |
1273 | */ | 1277 | */ |
1274 | |||
1275 | |||
1276 | static void ftdi_shutdown (struct usb_serial *serial) | 1278 | static void ftdi_shutdown (struct usb_serial *serial) |
1277 | { /* ftdi_shutdown */ | 1279 | { |
1280 | dbg("%s", __FUNCTION__); | ||
1281 | } | ||
1278 | 1282 | ||
1279 | struct usb_serial_port *port = serial->port[0]; | 1283 | static int ftdi_sio_port_remove(struct usb_serial_port *port) |
1284 | { | ||
1280 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1285 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1281 | 1286 | ||
1282 | dbg("%s", __FUNCTION__); | 1287 | dbg("%s", __FUNCTION__); |
1283 | 1288 | ||
1284 | remove_sysfs_attrs(serial); | 1289 | remove_sysfs_attrs(port); |
1285 | 1290 | ||
1286 | /* all open ports are closed at this point | 1291 | /* all open ports are closed at this point |
1287 | * (by usbserial.c:__serial_close, which calls ftdi_close) | 1292 | * (by usbserial.c:__serial_close, which calls ftdi_close) |
@@ -1291,8 +1296,9 @@ static void ftdi_shutdown (struct usb_serial *serial) | |||
1291 | usb_set_serial_port_data(port, NULL); | 1296 | usb_set_serial_port_data(port, NULL); |
1292 | kfree(priv); | 1297 | kfree(priv); |
1293 | } | 1298 | } |
1294 | } /* ftdi_shutdown */ | ||
1295 | 1299 | ||
1300 | return 0; | ||
1301 | } | ||
1296 | 1302 | ||
1297 | static int ftdi_open (struct usb_serial_port *port, struct file *filp) | 1303 | static int ftdi_open (struct usb_serial_port *port, struct file *filp) |
1298 | { /* ftdi_open */ | 1304 | { /* ftdi_open */ |