2 Keyspan USB to Serial Converter driver
5 Hugh Blemings <hugh@linuxcare.com>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 See http://www.linuxcare.com.au/hugh/keyspan.html for more
13 information on this driver.
15 Code in this driver inspired by and in a number of places taken
16 from Brian Warner's original Keyspan-PDA driver.
18 This driver has been put together with the support of Innosys, Inc.
19 and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
22 Tip 'o the hat to Linuxcare for supporting staff in their work on
25 Sat Jul 8 11:11:48 EST 2000 Hugh
26 First public release - nothing works except the firmware upload.
27 Tested on PPC and x86 architectures, seems to behave...
32 #include <linux/config.h>
34 #ifdef CONFIG_USB_SERIAL_KEYSPAN
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/signal.h>
39 #include <linux/errno.h>
40 #include <linux/poll.h>
41 #include <linux/init.h>
42 #include <linux/malloc.h>
43 #include <linux/fcntl.h>
44 #include <linux/tty_driver.h>
45 #include <linux/tty_flip.h>
46 #include <linux/tty.h>
47 #include <linux/module.h>
48 #include <linux/spinlock.h>
50 #ifdef CONFIG_USB_SERIAL_DEBUG
55 #include <linux/usb.h>
57 #include "usb-serial.h"
59 struct ezusb_hex_record
{
65 /* Conditionally include firmware images, if they aren't
66 included create a null pointer instead. Current
67 firmware images aren't optimised to remove duplicate
69 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28
70 #include "keyspan_usa28_fw.h"
72 static const struct ezusb_hex_record
*keyspan_usa28_firmware
= NULL
;
75 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28X
76 #include "keyspan_usa28x_fw.h"
78 static const struct ezusb_hex_record
*keyspan_usa28x_firmware
= NULL
;
81 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19
82 #include "keyspan_usa19_fw.h"
84 static const struct ezusb_hex_record
*keyspan_usa19_firmware
= NULL
;
87 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA18X
88 #include "keyspan_usa18x_fw.h"
90 static const struct ezusb_hex_record
*keyspan_usa18x_firmware
= NULL
;
93 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19W
94 #include "keyspan_usa19w_fw.h"
96 static const struct ezusb_hex_record
*keyspan_usa19w_firmware
= NULL
;
99 /* Include Keyspan message headers (not here yet, need some tweaks
100 to get clean build) */
101 /*#include "keyspan_usa26msg.h"*/
102 /*#include "keyspan_usa28msg.h"*/
104 /* If you don't get debugging output, uncomment the following
105 two lines to enable cheat. */
110 /* function prototypes for Keyspan serial converter */
111 static int keyspan_open (struct usb_serial_port
*port
,
113 static void keyspan_close (struct usb_serial_port
*port
,
115 static int keyspan_startup (struct usb_serial
*serial
);
116 static void keyspan_shutdown (struct usb_serial
*serial
);
117 static void keyspan_rx_interrupt (struct urb
*urb
);
118 static void keyspan_rx_throttle (struct usb_serial_port
*port
);
119 static void keyspan_rx_unthrottle (struct usb_serial_port
*port
);
120 static int keyspan_write_room (struct usb_serial_port
*port
);
121 static int keyspan_write (struct usb_serial_port
*port
,
123 const unsigned char *buf
,
125 static void keyspan_write_bulk_callback (struct urb
*urb
);
126 static int keyspan_chars_in_buffer (struct usb_serial_port
*port
);
127 static int keyspan_ioctl (struct usb_serial_port
*port
,
131 static void keyspan_set_termios (struct usb_serial_port
*port
,
132 struct termios
*old
);
133 static void keyspan_break_ctl (struct usb_serial_port
*port
,
135 static int keyspan_fake_startup (struct usb_serial
*serial
);
138 /* Functions - mostly stubs for now */
140 static void keyspan_rx_interrupt (struct urb
*urb
)
146 static void keyspan_rx_throttle (struct usb_serial_port
*port
)
148 dbg("keyspan_rx_throttle port %d", port
->number
);
152 static void keyspan_rx_unthrottle (struct usb_serial_port
*port
)
154 dbg("keyspan_rx_unthrottle port %d", port
->number
);
158 static void keyspan_break_ctl (struct usb_serial_port
*port
, int break_state
)
160 dbg("keyspan_break_ctl");
164 static void keyspan_set_termios (struct usb_serial_port
*port
,
165 struct termios
*old_termios
)
167 dbg("keyspan_set_termios");
170 static int keyspan_ioctl(struct usb_serial_port
*port
, struct file
*file
,
171 unsigned int cmd
, unsigned long arg
)
174 dbg("keyspan_ioctl_info");
179 static int keyspan_write(struct usb_serial_port
*port
, int from_user
,
180 const unsigned char *buf
, int count
)
182 dbg("keyspan_write called\n");
187 static void keyspan_write_bulk_callback (struct urb
*urb
)
190 dbg("keyspan_write_bulk_callback called\n");
194 static int keyspan_write_room (struct usb_serial_port
*port
)
196 dbg("keyspan_write_room called\n");
202 static int keyspan_chars_in_buffer (struct usb_serial_port
*port
)
208 static int keyspan_open (struct usb_serial_port
*port
, struct file
*filp
)
210 dbg("keyspan_open called\n");
215 static void keyspan_close(struct usb_serial_port
*port
, struct file
*filp
)
217 dbg("keyspan_close called\n");
221 /* download the firmware to a pre-renumeration device */
222 static int keyspan_fake_startup (struct usb_serial
*serial
)
225 const struct ezusb_hex_record
*record
;
228 dbg("Keyspan startup version %04x product %04x\n", serial
->dev
->descriptor
.bcdDevice
,
229 serial
->dev
->descriptor
.idProduct
);
231 if ((serial
->dev
->descriptor
.bcdDevice
& 0x8000) != 0x8000) {
232 dbg("Firmware already loaded. Quitting.\n");
236 /* Select firmware image on the basis of idProduct */
237 switch (serial
->dev
->descriptor
.idProduct
) {
238 case 0x0101: record
= &keyspan_usa28_firmware
[0];
242 case 0x0102: record
= &keyspan_usa28x_firmware
[0];
246 case 0x0103: record
= &keyspan_usa19_firmware
[0];
250 case 0x0105: record
= &keyspan_usa18x_firmware
[0];
254 case 0x0106: record
= &keyspan_usa19w_firmware
[0];
258 default: record
= NULL
;
263 if (record
== NULL
) {
264 err("Required keyspan firmware image (%s) unavailable.\n", fw_name
);
268 dbg("Uploading Keyspan %s firmware.\n", fw_name
);
270 /* download the firmware image */
271 response
= ezusb_set_reset(serial
, 1);
273 while(record
->address
!= 0xffff) {
274 response
= ezusb_writememory(serial
, record
->address
,
275 (unsigned char *)record
->data
,
276 record
->data_size
, 0xa0);
278 err("ezusb_writememory failed for Keyspan"
279 "firmware (%d %04X %p %d)",
281 record
->address
, record
->data
, record
->data_size
);
286 /* bring device out of reset. Renumeration will occur in a moment
287 and the new device will bind to the real driver */
288 response
= ezusb_set_reset(serial
, 0);
290 /* we want this device to fail to have a driver assigned to it. */
295 /* Gets called by the "real" driver (ie once firmware is loaded
296 and renumeration has taken place. */
297 static int keyspan_startup (struct usb_serial
*serial
)
299 dbg("keyspan_startup called.\n");
304 static void keyspan_shutdown (struct usb_serial
*serial
)
306 dbg("keyspan_shutdown called.\n");
310 /* Miscellaneous defines, datastructures etc. */
312 #define KEYSPAN_VENDOR_ID 0x06cd
314 /* Device info needed for the Keyspan serial converter */
315 static __u16 keyspan_vendor_id
= KEYSPAN_VENDOR_ID
;
317 /* Product IDs for the five products supported, pre-renumeration */
318 static __u16 keyspan_usa18x_pre_product_id
= 0x0105;
319 static __u16 keyspan_usa19_pre_product_id
= 0x0103;
320 static __u16 keyspan_usa19w_pre_product_id
= 0x0106;
321 static __u16 keyspan_usa28_pre_product_id
= 0x0101;
322 static __u16 keyspan_usa28x_pre_product_id
= 0x0102;
324 /* Product IDs post-renumeration */
325 static __u16 keyspan_usa18x_product_id
= 0x0112;
326 static __u16 keyspan_usa19_product_id
= 0x0107;
327 static __u16 keyspan_usa19w_product_id
= 0x0108;
328 static __u16 keyspan_usa28_product_id
= 0x010f;
329 static __u16 keyspan_usa28x_product_id
= 0x0110;
331 /* Structs for the devices, pre and post renumeration.
332 These are incomplete at present - HAB 20000708 */
333 struct usb_serial_device_type keyspan_usa18x_pre_device
= {
334 name
: "Keyspan USA18X - (prerenumeration)",
335 idVendor
: &keyspan_vendor_id
,
336 idProduct
: &keyspan_usa18x_pre_product_id
,
337 needs_interrupt_in
: DONT_CARE
,
338 needs_bulk_in
: DONT_CARE
,
339 needs_bulk_out
: DONT_CARE
,
340 num_interrupt_in
: NUM_DONT_CARE
,
341 num_bulk_in
: NUM_DONT_CARE
,
342 num_bulk_out
: NUM_DONT_CARE
,
344 startup
: keyspan_fake_startup
347 struct usb_serial_device_type keyspan_usa19_pre_device
= {
348 name
: "Keyspan USA19 - (prerenumeration)",
349 idVendor
: &keyspan_vendor_id
,
350 idProduct
: &keyspan_usa19_pre_product_id
,
351 needs_interrupt_in
: DONT_CARE
,
352 needs_bulk_in
: DONT_CARE
,
353 needs_bulk_out
: DONT_CARE
,
354 num_interrupt_in
: NUM_DONT_CARE
,
355 num_bulk_in
: NUM_DONT_CARE
,
356 num_bulk_out
: NUM_DONT_CARE
,
358 startup
: keyspan_fake_startup
362 struct usb_serial_device_type keyspan_usa19w_pre_device
= {
363 name
: "Keyspan USA19W - (prerenumeration)",
364 idVendor
: &keyspan_vendor_id
,
365 idProduct
: &keyspan_usa19w_pre_product_id
,
366 needs_interrupt_in
: DONT_CARE
,
367 needs_bulk_in
: DONT_CARE
,
368 needs_bulk_out
: DONT_CARE
,
369 num_interrupt_in
: NUM_DONT_CARE
,
370 num_bulk_in
: NUM_DONT_CARE
,
371 num_bulk_out
: NUM_DONT_CARE
,
373 startup
: keyspan_fake_startup
377 struct usb_serial_device_type keyspan_usa28_pre_device
= {
378 name
: "Keyspan USA28 - (prerenumeration)",
379 idVendor
: &keyspan_vendor_id
,
380 idProduct
: &keyspan_usa28_pre_product_id
,
381 needs_interrupt_in
: DONT_CARE
,
382 needs_bulk_in
: DONT_CARE
,
383 needs_bulk_out
: DONT_CARE
,
384 num_interrupt_in
: NUM_DONT_CARE
,
385 num_bulk_in
: NUM_DONT_CARE
,
386 num_bulk_out
: NUM_DONT_CARE
,
388 startup
: keyspan_fake_startup
391 struct usb_serial_device_type keyspan_usa28x_pre_device
= {
392 name
: "Keyspan USA28X - (prerenumeration)",
393 idVendor
: &keyspan_vendor_id
,
394 idProduct
: &keyspan_usa28x_pre_product_id
,
395 needs_interrupt_in
: DONT_CARE
,
396 needs_bulk_in
: DONT_CARE
,
397 needs_bulk_out
: DONT_CARE
,
398 num_interrupt_in
: NUM_DONT_CARE
,
399 num_bulk_in
: NUM_DONT_CARE
,
400 num_bulk_out
: NUM_DONT_CARE
,
402 startup
: keyspan_fake_startup
406 struct usb_serial_device_type keyspan_usa18x_device
= {
407 name
: "Keyspan USA18X",
408 idVendor
: &keyspan_vendor_id
,
409 idProduct
: &keyspan_usa18x_product_id
,
410 needs_interrupt_in
: DONT_CARE
,
411 needs_bulk_in
: DONT_CARE
,
412 needs_bulk_out
: DONT_CARE
,
413 num_interrupt_in
: NUM_DONT_CARE
,
414 num_bulk_in
: NUM_DONT_CARE
,
415 num_bulk_out
: NUM_DONT_CARE
,
418 close
: keyspan_close
,
419 throttle
: keyspan_rx_throttle
,
420 unthrottle
: keyspan_rx_unthrottle
,
421 set_termios
: keyspan_set_termios
,
424 struct usb_serial_device_type keyspan_usa19_device
= {
425 name
: "Keyspan USA19",
426 idVendor
: &keyspan_vendor_id
,
427 idProduct
: &keyspan_usa19_product_id
,
428 needs_interrupt_in
: DONT_CARE
,
429 needs_bulk_in
: DONT_CARE
,
430 needs_bulk_out
: DONT_CARE
,
431 num_interrupt_in
: NUM_DONT_CARE
,
432 num_bulk_in
: NUM_DONT_CARE
,
433 num_bulk_out
: NUM_DONT_CARE
,
436 close
: keyspan_close
,
437 write
: keyspan_write
,
438 write_room
: keyspan_write_room
,
439 write_bulk_callback
: keyspan_write_bulk_callback
,
440 read_int_callback
: keyspan_rx_interrupt
,
441 chars_in_buffer
: keyspan_chars_in_buffer
,
442 throttle
: keyspan_rx_throttle
,
443 unthrottle
: keyspan_rx_unthrottle
,
444 ioctl
: keyspan_ioctl
,
445 set_termios
: keyspan_set_termios
,
446 break_ctl
: keyspan_break_ctl
,
447 startup
: keyspan_startup
,
448 shutdown
: keyspan_shutdown
,
452 struct usb_serial_device_type keyspan_usa19w_device
= {
453 name
: "Keyspan USA19W",
454 idVendor
: &keyspan_vendor_id
,
455 idProduct
: &keyspan_usa19w_product_id
,
456 needs_interrupt_in
: DONT_CARE
,
457 needs_bulk_in
: DONT_CARE
,
458 needs_bulk_out
: DONT_CARE
,
459 num_interrupt_in
: NUM_DONT_CARE
,
460 num_bulk_in
: NUM_DONT_CARE
,
461 num_bulk_out
: NUM_DONT_CARE
,
464 close
: keyspan_close
,
465 throttle
: keyspan_rx_throttle
,
466 unthrottle
: keyspan_rx_unthrottle
,
467 set_termios
: keyspan_set_termios
,
471 struct usb_serial_device_type keyspan_usa28_device
= {
472 name
: "Keyspan USA28",
473 idVendor
: &keyspan_vendor_id
,
474 idProduct
: &keyspan_usa28_product_id
,
475 needs_interrupt_in
: DONT_CARE
,
476 needs_bulk_in
: DONT_CARE
,
477 needs_bulk_out
: DONT_CARE
,
478 num_interrupt_in
: NUM_DONT_CARE
,
479 num_bulk_in
: NUM_DONT_CARE
,
480 num_bulk_out
: NUM_DONT_CARE
,
483 close
: keyspan_close
,
484 throttle
: keyspan_rx_throttle
,
485 unthrottle
: keyspan_rx_unthrottle
,
486 set_termios
: keyspan_set_termios
,
490 struct usb_serial_device_type keyspan_usa28x_device
= {
491 name
: "Keyspan USA28X",
492 idVendor
: &keyspan_vendor_id
,
493 idProduct
: &keyspan_usa28x_product_id
,
494 needs_interrupt_in
: DONT_CARE
,
495 needs_bulk_in
: DONT_CARE
,
496 needs_bulk_out
: DONT_CARE
,
497 num_interrupt_in
: NUM_DONT_CARE
,
498 num_bulk_in
: NUM_DONT_CARE
,
499 num_bulk_out
: NUM_DONT_CARE
,
502 close
: keyspan_close
,
503 throttle
: keyspan_rx_throttle
,
504 unthrottle
: keyspan_rx_unthrottle
,
505 set_termios
: keyspan_set_termios
,
511 #endif /* CONFIG_USB_SERIAL_KEYSPAN */