diff options
author | Tony Lindgren <tony@atomide.com> | 2007-05-04 21:23:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-23 02:45:51 -0400 |
commit | fa91d43b914b77637653d984416e17e182f7b807 (patch) | |
tree | c517a05ed00bbd492b322a445521a74705d091d1 /drivers/usb/serial/ftdi_sio.c | |
parent | 5b7da8f6ff1aaf5a500dc798f4d1c2d6e98420a5 (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.c | 38 |
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. */ |
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 |