diff options
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 95a1805b064f..2353679f601e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -273,12 +273,18 @@ static __u16 product; | |||
273 | 273 | ||
274 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 274 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
275 | struct ftdi_sio_quirk { | 275 | struct ftdi_sio_quirk { |
276 | int (*probe)(struct usb_serial *); | ||
276 | void (*setup)(struct usb_serial *); /* Special settings during startup. */ | 277 | void (*setup)(struct usb_serial *); /* Special settings during startup. */ |
277 | }; | 278 | }; |
278 | 279 | ||
280 | static int ftdi_olimex_probe (struct usb_serial *serial); | ||
279 | static void ftdi_USB_UIRT_setup (struct usb_serial *serial); | 281 | static void ftdi_USB_UIRT_setup (struct usb_serial *serial); |
280 | static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); | 282 | static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); |
281 | 283 | ||
284 | static struct ftdi_sio_quirk ftdi_olimex_quirk = { | ||
285 | .probe = ftdi_olimex_probe, | ||
286 | }; | ||
287 | |||
282 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 288 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
283 | .setup = ftdi_USB_UIRT_setup, | 289 | .setup = ftdi_USB_UIRT_setup, |
284 | }; | 290 | }; |
@@ -319,6 +325,7 @@ static struct usb_device_id id_table_combined [] = { | |||
319 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | 325 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, |
320 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | 326 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, |
321 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | 327 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, |
328 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, | ||
322 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | 329 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, |
323 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | 330 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, |
324 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, | 331 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, |
@@ -525,6 +532,9 @@ static struct usb_device_id id_table_combined [] = { | |||
525 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, | 532 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, |
526 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 533 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
527 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 534 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
535 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | ||
536 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), | ||
537 | .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk }, | ||
528 | { }, /* Optional parameter entry */ | 538 | { }, /* Optional parameter entry */ |
529 | { } /* Terminating entry */ | 539 | { } /* Terminating entry */ |
530 | }; | 540 | }; |
@@ -669,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
669 | 679 | ||
670 | /* | 680 | /* |
671 | * *************************************************************************** | 681 | * *************************************************************************** |
672 | * Utlity functions | 682 | * Utility functions |
673 | * *************************************************************************** | 683 | * *************************************************************************** |
674 | */ | 684 | */ |
675 | 685 | ||
@@ -1171,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1171 | /* Probe function to check for special devices */ | 1181 | /* Probe function to check for special devices */ |
1172 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) | 1182 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) |
1173 | { | 1183 | { |
1184 | struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info; | ||
1185 | |||
1186 | if (quirk && quirk->probe) { | ||
1187 | int ret = quirk->probe(serial); | ||
1188 | if (ret != 0) | ||
1189 | return ret; | ||
1190 | } | ||
1191 | |||
1174 | usb_set_serial_data(serial, (void *)id->driver_info); | 1192 | usb_set_serial_data(serial, (void *)id->driver_info); |
1175 | 1193 | ||
1176 | return (0); | 1194 | return 0; |
1177 | } | 1195 | } |
1178 | 1196 | ||
1179 | static int ftdi_sio_port_probe(struct usb_serial_port *port) | 1197 | static int ftdi_sio_port_probe(struct usb_serial_port *port) |
@@ -1268,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) | |||
1268 | priv->force_rtscts = 1; | 1286 | priv->force_rtscts = 1; |
1269 | } /* ftdi_HE_TIRA1_setup */ | 1287 | } /* ftdi_HE_TIRA1_setup */ |
1270 | 1288 | ||
1289 | /* | ||
1290 | * First port on Olimex arm-usb-ocd is reserved for JTAG interface | ||
1291 | * and can be accessed from userspace using openocd. | ||
1292 | */ | ||
1293 | static int ftdi_olimex_probe(struct usb_serial *serial) | ||
1294 | { | ||
1295 | struct usb_device *udev = serial->dev; | ||
1296 | struct usb_interface *interface = serial->interface; | ||
1297 | |||
1298 | dbg("%s",__FUNCTION__); | ||
1299 | |||
1300 | if (interface == udev->actconfig->interface[0]) { | ||
1301 | info("Ignoring reserved serial port on Olimex arm-usb-ocd\n"); | ||
1302 | return -ENODEV; | ||
1303 | } | ||
1304 | |||
1305 | return 0; | ||
1306 | } | ||
1271 | 1307 | ||
1272 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | 1308 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect |
1273 | * it is called when the usb device is disconnected | 1309 | * it is called when the usb device is disconnected |