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 */ |
