aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2007-05-04 21:23:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-05-23 02:45:51 -0400
commitfa91d43b914b77637653d984416e17e182f7b807 (patch)
treec517a05ed00bbd492b322a445521a74705d091d1 /drivers/usb/serial/ftdi_sio.c
parent5b7da8f6ff1aaf5a500dc798f4d1c2d6e98420a5 (diff)
USB: Add support for Olimex arm-usb-ocd JTAG interface serial port
This patch adds support for the serial port on Olimex arm-usb-ocd JTAG interface. The device appears as two serial ports, but the first one is reserved for the JTAG interface. The JTAG interface can be used with OpenOCD from userspace. For more information, please see: http://openocd.berlios.de/web/ http://www.olimex.com/dev/arm-usb-ocd.html Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c38
1 files changed, 36 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. */
275struct ftdi_sio_quirk { 275struct 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
280static int ftdi_olimex_probe (struct usb_serial *serial);
279static void ftdi_USB_UIRT_setup (struct usb_serial *serial); 281static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
280static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); 282static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
281 283
284static struct ftdi_sio_quirk ftdi_olimex_quirk = {
285 .probe = ftdi_olimex_probe,
286};
287
282static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { 288static 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 */
1174static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) 1182static 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
1181static int ftdi_sio_port_probe(struct usb_serial_port *port) 1197static 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 */
1293static 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