diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 38 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.h | 4 |
2 files changed, 40 insertions, 2 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 128c20a043c9..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 | }; |
@@ -527,6 +533,8 @@ static struct usb_device_id id_table_combined [] = { | |||
527 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 533 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
528 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 534 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
529 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_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 }, | ||
530 | { }, /* Optional parameter entry */ | 538 | { }, /* Optional parameter entry */ |
531 | { } /* Terminating entry */ | 539 | { } /* Terminating entry */ |
532 | }; | 540 | }; |
@@ -671,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
671 | 679 | ||
672 | /* | 680 | /* |
673 | * *************************************************************************** | 681 | * *************************************************************************** |
674 | * Utlity functions | 682 | * Utility functions |
675 | * *************************************************************************** | 683 | * *************************************************************************** |
676 | */ | 684 | */ |
677 | 685 | ||
@@ -1173,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1173 | /* Probe function to check for special devices */ | 1181 | /* Probe function to check for special devices */ |
1174 | 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) |
1175 | { | 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 | |||
1176 | usb_set_serial_data(serial, (void *)id->driver_info); | 1192 | usb_set_serial_data(serial, (void *)id->driver_info); |
1177 | 1193 | ||
1178 | return (0); | 1194 | return 0; |
1179 | } | 1195 | } |
1180 | 1196 | ||
1181 | static int ftdi_sio_port_probe(struct usb_serial_port *port) | 1197 | static int ftdi_sio_port_probe(struct usb_serial_port *port) |
@@ -1270,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) | |||
1270 | priv->force_rtscts = 1; | 1286 | priv->force_rtscts = 1; |
1271 | } /* ftdi_HE_TIRA1_setup */ | 1287 | } /* ftdi_HE_TIRA1_setup */ |
1272 | 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 | } | ||
1273 | 1307 | ||
1274 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | 1308 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect |
1275 | * it is called when the usb device is disconnected | 1309 | * it is called when the usb device is disconnected |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 0a56b89530a8..33aee9047242 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -526,6 +526,10 @@ | |||
526 | */ | 526 | */ |
527 | #define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ | 527 | #define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ |
528 | 528 | ||
529 | /* Olimex */ | ||
530 | #define OLIMEX_VID 0x15BA | ||
531 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 | ||
532 | |||
529 | /* Commands */ | 533 | /* Commands */ |
530 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 534 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
531 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 535 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |