aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlain Degreffe <info@ecze.com>2007-10-26 07:51:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 17:34:47 -0500
commit60a8fc017103325db4b56e4f175f060a6aaac147 (patch)
treef3ded94b313365c6d3483532ac770f8e0184ead3
parentc74e809565b27085519c723a949761cea7badb4b (diff)
USB: add iuu_phoenix driver
Signed-off-by: Alain Degreffe <eczema@ecze.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Oliver Neukum <oliver@neukum.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/usb/iuu_phoenix.txt84
-rw-r--r--drivers/usb/serial/Kconfig11
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/iuu_phoenix.c1217
-rw-r--r--drivers/usb/serial/iuu_phoenix.h122
5 files changed, 1435 insertions, 0 deletions
diff --git a/Documentation/usb/iuu_phoenix.txt b/Documentation/usb/iuu_phoenix.txt
new file mode 100644
index 000000000000..e5f048067da4
--- /dev/null
+++ b/Documentation/usb/iuu_phoenix.txt
@@ -0,0 +1,84 @@
1Infinity Usb Unlimited Readme
2-----------------------------
3
4Hi all,
5
6
7This module provide a serial interface to use your
8IUU unit in phoenix mode. Loading this module will
9bring a ttyUSB[0-x] interface. This driver must be
10used by your favorite application to pilot the IUU
11
12This driver is still in beta stage, so bugs can
13occur and your system may freeze. As far I now,
14I never had any problem with it, but I'm not a real
15guru, so don't blame me if your system is unstable
16
17You can plug more than one IUU. Every unit will
18have his own device file(/dev/ttyUSB0,/dev/ttyUSB1,...)
19
20
21
22How to tune the reader speed ?
23
24 A few parameters can be used at load time
25 To use parameters, just unload the module if it is
26 already loaded and use modprobe iuu_phoenix param=value.
27 In case of prebuilt module, use the command
28 insmod iuu_phoenix param=value.
29
30 Example:
31
32 modprobe iuu_phoenix clockmode=3
33
34 The parameters are:
35
36 parm: clockmode:1=3Mhz579,2=3Mhz680,3=6Mhz (int)
37 parm: boost:overclock boost percent 100 to 500 (int)
38 parm: cdmode:Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, 4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING (int)
39 parm: xmas:xmas color enabled or not (bool)
40 parm: debug:Debug enabled or not (bool)
41
42- clockmode will provide 3 different base settings commonly adopted by
43 different software:
44 1. 3Mhz579
45 2. 3Mhz680
46 3. 6Mhz
47
48- boost provide a way to overclock the reader ( my favorite :-) )
49 For example to have best performance than a simple clockmode=3, try this:
50
51 modprobe boost=195
52
53 This will put the reader in a base of 3Mhz579 but boosted a 195 % !
54 the real clock will be now : 6979050 Hz ( 6Mhz979 ) and will increase
55 the speed to a score 10 to 20% better than the simple clockmode=3 !!!
56
57
58- cdmode permit to setup the signal used to inform the userland ( ioctl answer )
59 if the card is present or not. Eight signals are possible.
60
61- xmas is completely useless except for your eyes. This is one of my friend who was
62 so sad to have a nice device like the iuu without seeing all color range available.
63 So I have added this option to permit him to see a lot of color ( each activity change the color
64 and the frequency randomly )
65
66- debug will produce a lot of debugging messages...
67
68
69 Last notes:
70
71 Don't worry about the serial settings, the serial emulation
72 is an abstraction, so use any speed or parity setting will
73 work. ( This will not change anything ).Later I will perhaps
74 use this settings to deduce de boost but is that feature
75 really necessary ?
76 The autodetect feature used is the serial CD. If that doesn't
77 work for your software, disable detection mechanism in it.
78
79
80 Have fun !
81
82 Alain Degreffe
83
84 eczema(at)ecze.com
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 4a86696e6c7d..e2d1d928a1e4 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -282,6 +282,17 @@ config USB_SERIAL_IPW
282 To compile this driver as a module, choose M here: the 282 To compile this driver as a module, choose M here: the
283 module will be called ipw. 283 module will be called ipw.
284 284
285config USB_SERIAL_IUU
286 tristate "USB Infinity USB Unlimited Phoenix Driver (Experimental)"
287 depends on USB_SERIAL && EXPERIMENTAL
288 help
289 Say Y here if you want to use a IUU in phoenix mode and get
290 an extra ttyUSBx device. More information available on
291 http://eczema.ecze.com/iuu_phoenix.html
292
293 To compile this driver as a module, choose M here: the
294 module will be called iuu_phoenix.o
295
285config USB_SERIAL_KEYSPAN_PDA 296config USB_SERIAL_KEYSPAN_PDA
286 tristate "USB Keyspan PDA Single Port Serial Driver" 297 tristate "USB Keyspan PDA Single Port Serial Driver"
287 depends on USB_SERIAL 298 depends on USB_SERIAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index d6fb384e52b2..0db109a54d10 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o
30obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o 30obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o
31obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o 31obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o
32obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o 32obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o
33obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o
33obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o 34obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o
34obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o 35obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o
35obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o 36obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
new file mode 100644
index 000000000000..fde188e23ce1
--- /dev/null
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -0,0 +1,1217 @@
1/*
2 * Infinity Unlimited USB Phoenix driver
3 *
4 * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com)
5 *
6 * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * And tested with help of WB Electronics
14 *
15 */
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/tty.h>
21#include <linux/tty_driver.h>
22#include <linux/tty_flip.h>
23#include <linux/serial.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/spinlock.h>
27#include <linux/uaccess.h>
28#include <linux/usb.h>
29#include <linux/usb/serial.h>
30#include "iuu_phoenix.h"
31#include <linux/random.h>
32
33
34#ifdef CONFIG_USB_SERIAL_DEBUG
35static int debug = 1;
36#else
37static int debug;
38#endif
39
40/*
41 * Version Information
42 */
43#define DRIVER_VERSION "v0.5"
44#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
45
46static struct usb_device_id id_table[] = {
47 {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)},
48 {} /* Terminating entry */
49};
50MODULE_DEVICE_TABLE(usb, id_table);
51
52static struct usb_driver iuu_driver = {
53 .name = "iuu_phoenix",
54 .probe = usb_serial_probe,
55 .disconnect = usb_serial_disconnect,
56 .id_table = id_table,
57 .no_dynamic_id = 1,
58};
59
60/* turbo parameter */
61static int boost = 100;
62static int clockmode = 1;
63static int cdmode = 1;
64static int iuu_cardin;
65static int iuu_cardout;
66static int xmas;
67
68static void read_rxcmd_callback(struct urb *urb);
69
70struct iuu_private {
71 spinlock_t lock; /* store irq state */
72 wait_queue_head_t delta_msr_wait;
73 u8 line_control;
74 u8 line_status;
75 u8 termios_initialized;
76 int tiostatus; /* store IUART SIGNAL for tiocmget call */
77 u8 reset; /* if 1 reset is needed */
78 int poll; /* number of poll */
79 u8 *writebuf; /* buffer for writing to device */
80 int writelen; /* num of byte to write to device */
81 u8 *buf; /* used for initialize speed */
82 u8 *dbgbuf; /* debug buffer */
83 u8 len;
84};
85
86
87static void iuu_free_buf(struct iuu_private *priv)
88{
89 kfree(priv->buf);
90 kfree(priv->dbgbuf);
91 kfree(priv->writebuf);
92}
93
94static int iuu_alloc_buf(struct iuu_private *priv)
95{
96 priv->buf = kzalloc(256, GFP_KERNEL);
97 priv->dbgbuf = kzalloc(256, GFP_KERNEL);
98 priv->writebuf = kzalloc(256, GFP_KERNEL);
99 if (!priv->buf || !priv->dbgbuf || !priv->writebuf) {
100 iuu_free_buf(priv);
101 dbg("%s problem allocation buffer", __FUNCTION__);
102 return -ENOMEM;
103 }
104 dbg("%s - Privates buffers allocation success", __FUNCTION__);
105 return 0;
106}
107
108static int iuu_startup(struct usb_serial *serial)
109{
110 struct iuu_private *priv;
111 priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL);
112 dbg("%s- priv allocation success", __FUNCTION__);
113 if (!priv)
114 return -ENOMEM;
115 if (iuu_alloc_buf(priv)) {
116 kfree(priv);
117 return -ENOMEM;
118 }
119 spin_lock_init(&priv->lock);
120 init_waitqueue_head(&priv->delta_msr_wait);
121 usb_set_serial_port_data(serial->port[0], priv);
122 return 0;
123}
124
125/* Shutdown function */
126static void iuu_shutdown(struct usb_serial *serial)
127{
128 struct usb_serial_port *port = serial->port[0];
129 struct iuu_private *priv = usb_get_serial_port_data(port);
130 if (!port)
131 return;
132
133 dbg("%s", __FUNCTION__);
134
135 if (priv) {
136 iuu_free_buf(priv);
137 dbg("%s - I will free all", __FUNCTION__);
138 usb_set_serial_port_data(port, NULL);
139
140 dbg("%s - priv is not anymore in port structure", __FUNCTION__);
141 kfree(priv);
142
143 dbg("%s priv is now kfree", __FUNCTION__);
144 }
145}
146
147static int iuu_tiocmset(struct usb_serial_port *port, struct file *file,
148 unsigned int set, unsigned int clear)
149{
150 struct iuu_private *priv = usb_get_serial_port_data(port);
151 struct tty_struct *tty;
152 tty = port->tty;
153
154 dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__,
155 port->number, set, clear);
156 if (set & TIOCM_RTS)
157 priv->tiostatus = TIOCM_RTS;
158
159 if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) {
160 dbg("%s TIOCMSET RESET called !!!", __FUNCTION__);
161 priv->reset = 1;
162 return 0;
163 }
164
165 return 0;
166}
167
168/* This is used to provide a carrier detect mechanism
169 * When a card is present, the response is 0x00
170 * When no card , the reader respond with TIOCM_CD
171 * This is known as CD autodetect mechanism
172 */
173static int iuu_tiocmget(struct usb_serial_port *port, struct file *file)
174{
175 struct iuu_private *priv = usb_get_serial_port_data(port);
176 return priv->tiostatus;
177}
178
179static void iuu_rxcmd(struct urb *urb)
180{
181 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
182 int result;
183 dbg("%s - enter", __FUNCTION__);
184
185 if (urb->status) {
186 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
187 /* error stop all */
188 return;
189 }
190
191
192 memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1);
193 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
194 usb_sndbulkpipe(port->serial->dev,
195 port->bulk_out_endpointAddress),
196 port->write_urb->transfer_buffer, 1,
197 read_rxcmd_callback, port);
198 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
199}
200
201static int iuu_reset(struct usb_serial_port *port, u8 wt)
202{
203 struct iuu_private *priv = usb_get_serial_port_data(port);
204 int result;
205 char *buf_ptr = port->write_urb->transfer_buffer;
206 dbg("%s - enter", __FUNCTION__);
207
208 /* Prepare the reset sequence */
209
210 *buf_ptr++ = IUU_RST_SET;
211 *buf_ptr++ = IUU_DELAY_MS;
212 *buf_ptr++ = wt;
213 *buf_ptr = IUU_RST_CLEAR;
214
215 /* send the sequence */
216
217 usb_fill_bulk_urb(port->write_urb,
218 port->serial->dev,
219 usb_sndbulkpipe(port->serial->dev,
220 port->bulk_out_endpointAddress),
221 port->write_urb->transfer_buffer, 4, iuu_rxcmd, port);
222 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
223 priv->reset = 0;
224 return result;
225}
226
227/* Status Function
228 * Return value is
229 * 0x00 = no card
230 * 0x01 = smartcard
231 * 0x02 = sim card
232 */
233static void iuu_update_status_callback(struct urb *urb)
234{
235 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
236 struct iuu_private *priv = usb_get_serial_port_data(port);
237 u8 *st;
238 dbg("%s - enter", __FUNCTION__);
239
240 if (urb->status) {
241 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
242 /* error stop all */
243 return;
244 }
245
246 st = urb->transfer_buffer;
247 dbg("%s - enter", __FUNCTION__);
248 if (urb->actual_length == 1) {
249 switch (st[0]) {
250 case 0x1:
251 priv->tiostatus = iuu_cardout;
252 break;
253 case 0x0:
254 priv->tiostatus = iuu_cardin;
255 break;
256 default:
257 priv->tiostatus = iuu_cardin;
258 }
259 }
260 iuu_rxcmd(urb);
261}
262
263static void iuu_status_callback(struct urb *urb)
264{
265 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
266 int result;
267 dbg("%s - enter", __FUNCTION__);
268
269 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
270 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
271 usb_rcvbulkpipe(port->serial->dev,
272 port->bulk_in_endpointAddress),
273 port->read_urb->transfer_buffer, 256,
274 iuu_update_status_callback, port);
275 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
276}
277
278static int iuu_status(struct usb_serial_port *port)
279{
280 int result;
281
282 dbg("%s - enter", __FUNCTION__);
283
284 memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1);
285 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
286 usb_sndbulkpipe(port->serial->dev,
287 port->bulk_out_endpointAddress),
288 port->write_urb->transfer_buffer, 1,
289 iuu_status_callback, port);
290 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
291 return result;
292
293}
294
295static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
296{
297 int status;
298 struct usb_serial *serial = port->serial;
299 int actual = 0;
300
301 dbg("%s - enter", __FUNCTION__);
302
303 /* send the data out the bulk port */
304
305 status =
306 usb_bulk_msg(serial->dev,
307 usb_sndbulkpipe(serial->dev,
308 port->bulk_out_endpointAddress), buf,
309 count, &actual, HZ * 1);
310
311 if (status != IUU_OPERATION_OK) {
312 dbg("%s - error = %2x", __FUNCTION__, status);
313 } else {
314 dbg("%s - write OK !", __FUNCTION__);
315 }
316 return status;
317}
318
319static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
320{
321 int status;
322 struct usb_serial *serial = port->serial;
323 int actual = 0;
324
325 dbg("%s - enter", __FUNCTION__);
326
327 /* send the data out the bulk port */
328
329 status =
330 usb_bulk_msg(serial->dev,
331 usb_rcvbulkpipe(serial->dev,
332 port->bulk_in_endpointAddress), buf,
333 count, &actual, HZ * 1);
334
335 if (status != IUU_OPERATION_OK) {
336 dbg("%s - error = %2x", __FUNCTION__, status);
337 } else {
338 dbg("%s - read OK !", __FUNCTION__);
339 }
340
341 return status;
342}
343
344static int iuu_led(struct usb_serial_port *port, unsigned int R,
345 unsigned int G, unsigned int B, u8 f)
346{
347 int status;
348 u8 *buf;
349 buf = kmalloc(8, GFP_KERNEL);
350 if (!buf)
351 return -ENOMEM;
352
353 dbg("%s - enter", __FUNCTION__);
354
355 buf[0] = IUU_SET_LED;
356 buf[1] = R & 0xFF;
357 buf[2] = (R >> 8) & 0xFF;
358 buf[3] = G & 0xFF;
359 buf[4] = (G >> 8) & 0xFF;
360 buf[5] = B & 0xFF;
361 buf[6] = (B >> 8) & 0xFF;
362 buf[7] = f;
363 status = bulk_immediate(port, buf, 8);
364 kfree(buf);
365 if (status != IUU_OPERATION_OK)
366 dbg("%s - led error status = %2x", __FUNCTION__, status);
367 else
368 dbg("%s - led OK !", __FUNCTION__);
369 return IUU_OPERATION_OK;
370}
371
372static void iuu_rgbf_fill_buffer(u8 *buf, u8 r1, u8 r2, u8 g1, u8 g2, u8 b1,
373 u8 b2, u8 freq)
374{
375 *buf++ = IUU_SET_LED;
376 *buf++ = r1;
377 *buf++ = r2;
378 *buf++ = g1;
379 *buf++ = g2;
380 *buf++ = b1;
381 *buf++ = b2;
382 *buf = freq;
383}
384
385static void iuu_led_activity_on(struct urb *urb)
386{
387 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
388 int result;
389 char *buf_ptr = port->write_urb->transfer_buffer;
390 *buf_ptr++ = IUU_SET_LED;
391 if (xmas == 1) {
392 get_random_bytes(buf_ptr, 6);
393 *(buf_ptr+7) = 1;
394 } else {
395 iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255);
396 }
397
398 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
399 usb_sndbulkpipe(port->serial->dev,
400 port->bulk_out_endpointAddress),
401 port->write_urb->transfer_buffer, 8 ,
402 iuu_rxcmd, port);
403 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
404}
405
406static void iuu_led_activity_off(struct urb *urb)
407{
408 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
409 int result;
410 char *buf_ptr = port->write_urb->transfer_buffer;
411 if (xmas == 1) {
412 iuu_rxcmd(urb);
413 return;
414 } else {
415 *buf_ptr++ = IUU_SET_LED;
416 iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255);
417 }
418 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
419 usb_sndbulkpipe(port->serial->dev,
420 port->bulk_out_endpointAddress),
421 port->write_urb->transfer_buffer, 8 ,
422 iuu_rxcmd, port);
423 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
424}
425
426
427
428static int iuu_clk(struct usb_serial_port *port, int dwFrq)
429{
430 int status;
431 struct iuu_private *priv = usb_get_serial_port_data(port);
432 int Count = 0;
433 u8 FrqGenAdr = 0x69;
434 u8 DIV = 0; /* 8bit */
435 u8 XDRV = 0; /* 8bit */
436 u8 PUMP = 0; /* 3bit */
437 u8 PBmsb = 0; /* 2bit */
438 u8 PBlsb = 0; /* 8bit */
439 u8 PO = 0; /* 1bit */
440 u8 Q = 0; /* 7bit */
441 /* 24bit = 3bytes */
442 unsigned int P = 0;
443 unsigned int P2 = 0;
444 int frq = (int)dwFrq;
445
446 dbg("%s - enter", __FUNCTION__);
447
448 if (frq == 0) {
449 priv->buf[Count++] = IUU_UART_WRITE_I2C;
450 priv->buf[Count++] = FrqGenAdr << 1;
451 priv->buf[Count++] = 0x09;
452 priv->buf[Count++] = 0x00;
453
454 status = bulk_immediate(port, (u8 *) priv->buf, Count);
455 if (status != 0) {
456 dbg("%s - write error ", __FUNCTION__);
457 return status;
458 }
459 } else if (frq == 3579000) {
460 DIV = 100;
461 P = 1193;
462 Q = 40;
463 XDRV = 0;
464 } else if (frq == 3680000) {
465 DIV = 105;
466 P = 161;
467 Q = 5;
468 XDRV = 0;
469 } else if (frq == 6000000) {
470 DIV = 66;
471 P = 66;
472 Q = 2;
473 XDRV = 0x28;
474 } else {
475 unsigned int result = 0;
476 unsigned int tmp = 0;
477 unsigned int check;
478 unsigned int check2;
479 char found = 0x00;
480 unsigned int lQ = 2;
481 unsigned int lP = 2055;
482 unsigned int lDiv = 4;
483
484 for (lQ = 2; lQ <= 47 && !found; lQ++)
485 for (lP = 2055; lP >= 8 && !found; lP--)
486 for (lDiv = 4; lDiv <= 127 && !found; lDiv++) {
487 tmp = (12000000 / lDiv) * (lP / lQ);
488 if (abs((int)(tmp - frq)) <
489 abs((int)(frq - result))) {
490 check2 = (12000000 / lQ);
491 if (check2 < 250000)
492 continue;
493 check = (12000000 / lQ) * lP;
494 if (check > 400000000)
495 continue;
496 if (check < 100000000)
497 continue;
498 if (lDiv < 4 || lDiv > 127)
499 continue;
500 result = tmp;
501 P = lP;
502 DIV = lDiv;
503 Q = lQ;
504 if (result == frq)
505 found = 0x01;
506 }
507 }
508 }
509 P2 = ((P - PO) / 2) - 4;
510 DIV = DIV;
511 PUMP = 0x04;
512 PBmsb = (P2 >> 8 & 0x03);
513 PBlsb = P2 & 0xFF;
514 PO = (P >> 10) & 0x01;
515 Q = Q - 2;
516
517 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
518 priv->buf[Count++] = FrqGenAdr << 1;
519 priv->buf[Count++] = 0x09;
520 priv->buf[Count++] = 0x20; /* Adr = 0x09 */
521 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
522 priv->buf[Count++] = FrqGenAdr << 1;
523 priv->buf[Count++] = 0x0C;
524 priv->buf[Count++] = DIV; /* Adr = 0x0C */
525 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
526 priv->buf[Count++] = FrqGenAdr << 1;
527 priv->buf[Count++] = 0x12;
528 priv->buf[Count++] = XDRV; /* Adr = 0x12 */
529 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
530 priv->buf[Count++] = FrqGenAdr << 1;
531 priv->buf[Count++] = 0x13;
532 priv->buf[Count++] = 0x6B; /* Adr = 0x13 */
533 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
534 priv->buf[Count++] = FrqGenAdr << 1;
535 priv->buf[Count++] = 0x40;
536 priv->buf[Count++] = (0xC0 | ((PUMP & 0x07) << 2)) |
537 (PBmsb & 0x03); /* Adr = 0x40 */
538 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
539 priv->buf[Count++] = FrqGenAdr << 1;
540 priv->buf[Count++] = 0x41;
541 priv->buf[Count++] = PBlsb; /* Adr = 0x41 */
542 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
543 priv->buf[Count++] = FrqGenAdr << 1;
544 priv->buf[Count++] = 0x42;
545 priv->buf[Count++] = Q | (((PO & 0x01) << 7)); /* Adr = 0x42 */
546 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
547 priv->buf[Count++] = FrqGenAdr << 1;
548 priv->buf[Count++] = 0x44;
549 priv->buf[Count++] = (char)0xFF; /* Adr = 0x44 */
550 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
551 priv->buf[Count++] = FrqGenAdr << 1;
552 priv->buf[Count++] = 0x45;
553 priv->buf[Count++] = (char)0xFE; /* Adr = 0x45 */
554 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
555 priv->buf[Count++] = FrqGenAdr << 1;
556 priv->buf[Count++] = 0x46;
557 priv->buf[Count++] = 0x7F; /* Adr = 0x46 */
558 priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */
559 priv->buf[Count++] = FrqGenAdr << 1;
560 priv->buf[Count++] = 0x47;
561 priv->buf[Count++] = (char)0x84; /* Adr = 0x47 */
562
563 status = bulk_immediate(port, (u8 *) priv->buf, Count);
564 if (status != IUU_OPERATION_OK)
565 dbg("%s - write error ", __FUNCTION__);
566 return status;
567}
568
569static int iuu_uart_flush(struct usb_serial_port *port)
570{
571 int i;
572 int status;
573 u8 rxcmd = IUU_UART_RX;
574 struct iuu_private *priv = usb_get_serial_port_data(port);
575
576 dbg("%s - enter", __FUNCTION__);
577
578 if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
579 return -EIO;
580
581 for (i = 0; i < 2; i++) {
582 status = bulk_immediate(port, &rxcmd, 1);
583 if (status != IUU_OPERATION_OK) {
584 dbg("%s - uart_flush_write error", __FUNCTION__);
585 return status;
586 }
587
588 status = read_immediate(port, &priv->len, 1);
589 if (status != IUU_OPERATION_OK) {
590 dbg("%s - uart_flush_read error", __FUNCTION__);
591 return status;
592 }
593
594 if (priv->len > 0) {
595 dbg("%s - uart_flush datalen is : %i ", __FUNCTION__,
596 priv->len);
597 status = read_immediate(port, priv->buf, priv->len);
598 if (status != IUU_OPERATION_OK) {
599 dbg("%s - uart_flush_read error", __FUNCTION__);
600 return status;
601 }
602 }
603 }
604 dbg("%s - uart_flush_read OK!", __FUNCTION__);
605 iuu_led(port, 0, 0xF000, 0, 0xFF);
606 return status;
607}
608
609static void read_buf_callback(struct urb *urb)
610{
611 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
612 unsigned char *data = urb->transfer_buffer;
613 struct tty_struct *tty;
614 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
615
616 if (urb->status) {
617 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
618 if (urb->status == -EPROTO) {
619 /* reschedule needed */
620 }
621 return;
622 }
623
624 dbg("%s - %i chars to write", __FUNCTION__, urb->actual_length);
625 tty = port->tty;
626 if (data == NULL)
627 dbg("%s - data is NULL !!!", __FUNCTION__);
628 if (tty && urb->actual_length && data) {
629 tty_insert_flip_string(tty, data, urb->actual_length);
630 tty_flip_buffer_push(tty);
631 }
632 iuu_led_activity_on(urb);
633}
634
635static int iuu_bulk_write(struct usb_serial_port *port)
636{
637 struct iuu_private *priv = usb_get_serial_port_data(port);
638 unsigned int flags;
639 int result;
640 int i;
641 char *buf_ptr = port->write_urb->transfer_buffer;
642 dbg("%s - enter", __FUNCTION__);
643
644 *buf_ptr++ = IUU_UART_ESC;
645 *buf_ptr++ = IUU_UART_TX;
646 *buf_ptr++ = priv->writelen;
647
648 memcpy(buf_ptr, priv->writebuf,
649 priv->writelen);
650 if (debug == 1) {
651 for (i = 0; i < priv->writelen; i++)
652 sprintf(priv->dbgbuf + i*2 ,
653 "%02X", priv->writebuf[i]);
654 priv->dbgbuf[priv->writelen+i*2] = 0;
655 dbg("%s - writing %i chars : %s", __FUNCTION__,
656 priv->writelen, priv->dbgbuf);
657 }
658 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
659 usb_sndbulkpipe(port->serial->dev,
660 port->bulk_out_endpointAddress),
661 port->write_urb->transfer_buffer, priv->writelen + 3,
662 iuu_rxcmd, port);
663 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
664 spin_lock_irqsave(&priv->lock, flags);
665 priv->writelen = 0;
666 spin_unlock_irqrestore(&priv->lock, flags);
667 usb_serial_port_softint(port);
668 return result;
669}
670
671static int iuu_read_buf(struct usb_serial_port *port, int len)
672{
673 int result;
674 dbg("%s - enter", __FUNCTION__);
675
676 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
677 usb_rcvbulkpipe(port->serial->dev,
678 port->bulk_in_endpointAddress),
679 port->read_urb->transfer_buffer, len,
680 read_buf_callback, port);
681 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
682 return result;
683}
684
685static void iuu_uart_read_callback(struct urb *urb)
686{
687 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
688 struct iuu_private *priv = usb_get_serial_port_data(port);
689 unsigned int flags;
690 int status;
691 int error = 0;
692 int len = 0;
693 unsigned char *data = urb->transfer_buffer;
694 priv->poll++;
695
696 dbg("%s - enter", __FUNCTION__);
697
698 if (urb->status) {
699 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
700 /* error stop all */
701 return;
702 }
703 if (data == NULL)
704 dbg("%s - data is NULL !!!", __FUNCTION__);
705
706 if (urb->actual_length == 1 && data != NULL)
707 len = (int) data[0];
708
709 if (urb->actual_length > 1) {
710 dbg("%s - urb->actual_length = %i", __FUNCTION__,
711 urb->actual_length);
712 error = 1;
713 return;
714 }
715 /* if len > 0 call readbuf */
716
717 if (len > 0 && error == 0) {
718 dbg("%s - call read buf - len to read is %i ",
719 __FUNCTION__, len);
720 status = iuu_read_buf(port, len);
721 return;
722 }
723 /* need to update status ? */
724 if (priv->poll > 99) {
725 status = iuu_status(port);
726 priv->poll = 0;
727 return;
728 }
729
730 /* reset waiting ? */
731
732 if (priv->reset == 1) {
733 status = iuu_reset(port, 0xC);
734 return;
735 }
736 /* Writebuf is waiting */
737 spin_lock_irqsave(&priv->lock, flags);
738 if (priv->writelen > 0) {
739 spin_unlock_irqrestore(&priv->lock, flags);
740 status = iuu_bulk_write(port);
741 return;
742 }
743 spin_unlock_irqrestore(&priv->lock, flags);
744 /* if nothing to write call again rxcmd */
745 dbg("%s - rxcmd recall", __FUNCTION__);
746 iuu_led_activity_off(urb);
747 return;
748}
749
750static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf,
751 int count)
752{
753 struct iuu_private *priv = usb_get_serial_port_data(port);
754 unsigned int flags;
755 dbg("%s - enter", __FUNCTION__);
756
757 if (count > 256)
758 return -ENOMEM;
759
760 spin_lock_irqsave(&priv->lock, flags);
761 if (priv->writelen > 0) {
762 /* buffer already filled but not commited */
763 spin_unlock_irqrestore(&priv->lock, flags);
764 return (0);
765 }
766 /* fill the buffer */
767 memcpy(priv->writebuf, buf, count);
768 priv->writelen = count;
769 spin_unlock_irqrestore(&priv->lock, flags);
770
771 return (count);
772}
773
774static void read_rxcmd_callback(struct urb *urb)
775{
776 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
777 int result;
778 dbg("%s - enter", __FUNCTION__);
779
780 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
781
782 if (urb->status) {
783 dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
784 /* error stop all */
785 return;
786 }
787
788 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
789 usb_rcvbulkpipe(port->serial->dev,
790 port->bulk_in_endpointAddress),
791 port->read_urb->transfer_buffer, 256,
792 iuu_uart_read_callback, port);
793 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
794 dbg("%s - submit result = %d", __FUNCTION__, result);
795 return;
796}
797
798static int iuu_uart_on(struct usb_serial_port *port)
799{
800 int status;
801 u8 *buf;
802
803 buf = kmalloc(sizeof(u8) * 4, GFP_KERNEL);
804
805 if (!buf)
806 return -ENOMEM;
807
808 buf[0] = IUU_UART_ENABLE;
809 buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF);
810 buf[2] = (u8) (0x00FF & IUU_BAUD_9600);
811 buf[3] = (u8) (0x0F0 & IUU_TWO_STOP_BITS) | (0x07 & IUU_PARITY_EVEN);
812
813 status = bulk_immediate(port, buf, 4);
814 if (status != IUU_OPERATION_OK) {
815 dbg("%s - uart_on error", __FUNCTION__);
816 goto uart_enable_failed;
817 }
818 /* iuu_reset() the card after iuu_uart_on() */
819 status = iuu_uart_flush(port);
820 if (status != IUU_OPERATION_OK)
821 dbg("%s - uart_flush error", __FUNCTION__);
822uart_enable_failed:
823 kfree(buf);
824 return status;
825}
826
827/* Diables the IUU UART (a.k.a. the Phoenix voiderface) */
828static int iuu_uart_off(struct usb_serial_port *port)
829{
830 int status;
831 u8 *buf;
832 buf = kmalloc(1, GFP_KERNEL);
833 if (!buf)
834 return -ENOMEM;
835 buf[0] = IUU_UART_DISABLE;
836
837 status = bulk_immediate(port, buf, 1);
838 if (status != IUU_OPERATION_OK)
839 dbg("%s - uart_off error", __FUNCTION__);
840
841 kfree(buf);
842 return status;
843}
844
845static int iuu_uart_baud(struct usb_serial_port *port, u32 baud,
846 u32 *actual, u8 parity)
847{
848 int status;
849 u8 *dataout;
850 u8 DataCount = 0;
851 u8 T1Frekvens = 0;
852 u8 T1reload = 0;
853 unsigned int T1FrekvensHZ = 0;
854
855 dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL);
856
857 if (!dataout)
858 return -ENOMEM;
859
860 if (baud < 1200 || baud > 230400) {
861 kfree(dataout);
862 return IUU_INVALID_PARAMETER;
863 }
864 if (baud > 977) {
865 T1Frekvens = 3;
866 T1FrekvensHZ = 500000;
867 }
868
869 if (baud > 3906) {
870 T1Frekvens = 2;
871 T1FrekvensHZ = 2000000;
872 }
873
874 if (baud > 11718) {
875 T1Frekvens = 1;
876 T1FrekvensHZ = 6000000;
877 }
878
879 if (baud > 46875) {
880 T1Frekvens = 0;
881 T1FrekvensHZ = 24000000;
882 }
883
884 T1reload = 256 - (u8) (T1FrekvensHZ / (baud * 2));
885
886 /* magic number here: ENTER_FIRMWARE_UPDATE; */
887 dataout[DataCount++] = IUU_UART_ESC;
888 /* magic number here: CHANGE_BAUD; */
889 dataout[DataCount++] = IUU_UART_CHANGE;
890 dataout[DataCount++] = T1Frekvens;
891 dataout[DataCount++] = T1reload;
892
893 *actual = (T1FrekvensHZ / (256 - T1reload)) / 2;
894
895 switch (parity & 0x0F) {
896 case IUU_PARITY_NONE:
897 dataout[DataCount++] = 0x00;
898 break;
899 case IUU_PARITY_EVEN:
900 dataout[DataCount++] = 0x01;
901 break;
902 case IUU_PARITY_ODD:
903 dataout[DataCount++] = 0x02;
904 break;
905 case IUU_PARITY_MARK:
906 dataout[DataCount++] = 0x03;
907 break;
908 case IUU_PARITY_SPACE:
909 dataout[DataCount++] = 0x04;
910 break;
911 default:
912 kfree(dataout);
913 return IUU_INVALID_PARAMETER;
914 break;
915 }
916
917 switch (parity & 0xF0) {
918 case IUU_ONE_STOP_BIT:
919 dataout[DataCount - 1] |= IUU_ONE_STOP_BIT;
920 break;
921
922 case IUU_TWO_STOP_BITS:
923 dataout[DataCount - 1] |= IUU_TWO_STOP_BITS;
924 break;
925 default:
926 kfree(dataout);
927 return IUU_INVALID_PARAMETER;
928 break;
929 }
930
931 status = bulk_immediate(port, dataout, DataCount);
932 if (status != IUU_OPERATION_OK)
933 dbg("%s - uart_off error", __FUNCTION__);
934 kfree(dataout);
935 return status;
936}
937
938static int set_control_lines(struct usb_device *dev, u8 value)
939{
940 return 0;
941}
942
943static void iuu_close(struct usb_serial_port *port, struct file *filp)
944{
945 /* iuu_led (port,255,0,0,0); */
946 struct usb_serial *serial;
947 struct iuu_private *priv = usb_get_serial_port_data(port);
948 unsigned long flags;
949 unsigned int c_cflag;
950
951 serial = port->serial;
952 if (!serial)
953 return;
954
955 dbg("%s - port %d", __FUNCTION__, port->number);
956
957 iuu_uart_off(port);
958 if (serial->dev) {
959 if (port->tty) {
960 c_cflag = port->tty->termios->c_cflag;
961 if (c_cflag & HUPCL) {
962 /* drop DTR and RTS */
963 priv = usb_get_serial_port_data(port);
964 spin_lock_irqsave(&priv->lock, flags);
965 priv->line_control = 0;
966 spin_unlock_irqrestore(&priv->lock, flags);
967 set_control_lines(port->serial->dev, 0);
968 }
969 }
970 /* free writebuf */
971 /* shutdown our urbs */
972 dbg("%s - shutting down urbs", __FUNCTION__);
973 usb_kill_urb(port->write_urb);
974 usb_kill_urb(port->read_urb);
975 usb_kill_urb(port->interrupt_in_urb);
976 msleep(1000);
977 /* wait one second to free all buffers */
978 iuu_led(port, 0, 0, 0xF000, 0xFF);
979 msleep(1000);
980 usb_reset_device(port->serial->dev);
981 }
982}
983
984static int iuu_open(struct usb_serial_port *port, struct file *filp)
985{
986 struct usb_serial *serial = port->serial;
987 u8 *buf;
988 int result;
989 u32 actual;
990 unsigned long flags;
991 struct iuu_private *priv = usb_get_serial_port_data(port);
992
993 dbg("%s - port %d", __FUNCTION__, port->number);
994 usb_clear_halt(serial->dev, port->write_urb->pipe);
995 usb_clear_halt(serial->dev, port->read_urb->pipe);
996
997 buf = kmalloc(10, GFP_KERNEL);
998 if (buf == NULL)
999 return -ENOMEM;
1000
1001 /* fixup the endpoint buffer size */
1002 kfree(port->bulk_out_buffer);
1003 port->bulk_out_buffer = kmalloc(512, GFP_KERNEL);
1004 port->bulk_out_size = 512;
1005 kfree(port->bulk_in_buffer);
1006 port->bulk_in_buffer = kmalloc(512, GFP_KERNEL);
1007 port->bulk_in_size = 512;
1008
1009 if (!port->bulk_out_buffer || !port->bulk_in_buffer) {
1010 kfree(port->bulk_out_buffer);
1011 kfree(port->bulk_in_buffer);
1012 kfree(buf);
1013 return -ENOMEM;
1014 }
1015
1016 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
1017 usb_sndbulkpipe(port->serial->dev,
1018 port->bulk_out_endpointAddress),
1019 port->bulk_out_buffer, 512,
1020 NULL, NULL);
1021
1022
1023 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
1024 usb_rcvbulkpipe(port->serial->dev,
1025 port->bulk_in_endpointAddress),
1026 port->bulk_in_buffer, 512,
1027 NULL, NULL);
1028
1029 /* set the termios structure */
1030 spin_lock_irqsave(&priv->lock, flags);
1031 if (!priv->termios_initialized) {
1032 *(port->tty->termios) = tty_std_termios;
1033 port->tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
1034 | TIOCM_CTS | CSTOPB | PARENB;
1035 port->tty->termios->c_lflag = 0;
1036 port->tty->termios->c_oflag = 0;
1037 port->tty->termios->c_iflag = 0;
1038 priv->termios_initialized = 1;
1039 port->tty->low_latency = 1;
1040 priv->poll = 0;
1041 }
1042 spin_unlock_irqrestore(&priv->lock, flags);
1043
1044 /* initialize writebuf */
1045#define FISH(a, b, c, d) do { \
1046 result = usb_control_msg(port->serial->dev, \
1047 usb_rcvctrlpipe(port->serial->dev, 0), \
1048 b, a, c, d, buf, 1, 1000); \
1049 dbg("0x%x:0x%x:0x%x:0x%x %d - %x", a, b, c, d, result, \
1050 buf[0]); } while (0);
1051
1052#define SOUP(a, b, c, d) do { \
1053 result = usb_control_msg(port->serial->dev, \
1054 usb_sndctrlpipe(port->serial->dev, 0), \
1055 b, a, c, d, NULL, 0, 1000); \
1056 dbg("0x%x:0x%x:0x%x:0x%x %d", a, b, c, d, result); } while (0)
1057
1058 /* This is not UART related but IUU USB driver related or something */
1059 /* like that. Basically no IUU will accept any commands from the USB */
1060 /* host unless it has received the following message */
1061 /* sprintf(buf ,"%c%c%c%c",0x03,0x02,0x02,0x0); */
1062
1063 SOUP(0x03, 0x02, 0x02, 0x0);
1064 kfree(buf);
1065 iuu_led(port, 0xF000, 0xF000, 0, 0xFF);
1066 iuu_uart_on(port);
1067 if (boost < 100)
1068 boost = 100;
1069 switch (clockmode) {
1070 case 2: /* 3.680 Mhz */
1071 iuu_clk(port, IUU_CLK_3680000 * boost / 100);
1072 result =
1073 iuu_uart_baud(port, 9600 * boost / 100, &actual,
1074 IUU_PARITY_EVEN);
1075 break;
1076 case 3: /* 6.00 Mhz */
1077 iuu_clk(port, IUU_CLK_6000000 * boost / 100);
1078 result =
1079 iuu_uart_baud(port, 16457 * boost / 100, &actual,
1080 IUU_PARITY_EVEN);
1081 break;
1082 default: /* 3.579 Mhz */
1083 iuu_clk(port, IUU_CLK_3579000 * boost / 100);
1084 result =
1085 iuu_uart_baud(port, 9600 * boost / 100, &actual,
1086 IUU_PARITY_EVEN);
1087 }
1088
1089 /* set the cardin cardout signals */
1090 switch (cdmode) {
1091 case 0:
1092 iuu_cardin = 0;
1093 iuu_cardout = 0;
1094 break;
1095 case 1:
1096 iuu_cardin = TIOCM_CD;
1097 iuu_cardout = 0;
1098 break;
1099 case 2:
1100 iuu_cardin = 0;
1101 iuu_cardout = TIOCM_CD;
1102 break;
1103 case 3:
1104 iuu_cardin = TIOCM_DSR;
1105 iuu_cardout = 0;
1106 break;
1107 case 4:
1108 iuu_cardin = 0;
1109 iuu_cardout = TIOCM_DSR;
1110 break;
1111 case 5:
1112 iuu_cardin = TIOCM_CTS;
1113 iuu_cardout = 0;
1114 break;
1115 case 6:
1116 iuu_cardin = 0;
1117 iuu_cardout = TIOCM_CTS;
1118 break;
1119 case 7:
1120 iuu_cardin = TIOCM_RNG;
1121 iuu_cardout = 0;
1122 break;
1123 case 8:
1124 iuu_cardin = 0;
1125 iuu_cardout = TIOCM_RNG;
1126 }
1127
1128 iuu_uart_flush(port);
1129
1130 dbg("%s - initialization done", __FUNCTION__);
1131
1132 memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1);
1133 usb_fill_bulk_urb(port->write_urb, port->serial->dev,
1134 usb_sndbulkpipe(port->serial->dev,
1135 port->bulk_out_endpointAddress),
1136 port->write_urb->transfer_buffer, 1,
1137 read_rxcmd_callback, port);
1138 result = usb_submit_urb(port->write_urb, GFP_KERNEL);
1139
1140 if (result) {
1141 dev_err(&port->dev, "%s - failed submitting read urb,"
1142 " error %d\n", __FUNCTION__, result);
1143 iuu_close(port, NULL);
1144 return -EPROTO;
1145 } else {
1146 dbg("%s - rxcmd OK", __FUNCTION__);
1147 }
1148 return result;
1149}
1150
1151static struct usb_serial_driver iuu_device = {
1152 .driver = {
1153 .owner = THIS_MODULE,
1154 .name = "iuu_phoenix",
1155 },
1156 .id_table = id_table,
1157 .num_interrupt_in = NUM_DONT_CARE,
1158 .num_bulk_in = 1,
1159 .num_bulk_out = 1,
1160 .num_ports = 1,
1161 .open = iuu_open,
1162 .close = iuu_close,
1163 .write = iuu_uart_write,
1164 .read_bulk_callback = iuu_uart_read_callback,
1165 .tiocmget = iuu_tiocmget,
1166 .tiocmset = iuu_tiocmset,
1167 .attach = iuu_startup,
1168 .shutdown = iuu_shutdown,
1169};
1170
1171static int __init iuu_init(void)
1172{
1173 int retval;
1174 retval = usb_serial_register(&iuu_device);
1175 if (retval)
1176 goto failed_usb_serial_register;
1177 retval = usb_register(&iuu_driver);
1178 if (retval)
1179 goto failed_usb_register;
1180 info(DRIVER_DESC " " DRIVER_VERSION);
1181 return 0;
1182failed_usb_register:
1183 usb_serial_deregister(&iuu_device);
1184failed_usb_serial_register:
1185 return retval;
1186}
1187
1188static void __exit iuu_exit(void)
1189{
1190 usb_deregister(&iuu_driver);
1191 usb_serial_deregister(&iuu_device);
1192}
1193
1194module_init(iuu_init);
1195module_exit(iuu_exit);
1196
1197MODULE_AUTHOR("Alain Degreffe eczema@ecze.com");
1198
1199MODULE_DESCRIPTION(DRIVER_DESC);
1200MODULE_LICENSE("GPL");
1201
1202MODULE_VERSION(DRIVER_VERSION);
1203module_param(debug, bool, S_IRUGO | S_IWUSR);
1204MODULE_PARM_DESC(debug, "Debug enabled or not");
1205
1206module_param(xmas, bool, S_IRUGO | S_IWUSR);
1207MODULE_PARM_DESC(xmas, "xmas color enabled or not");
1208
1209module_param(boost, int, S_IRUGO | S_IWUSR);
1210MODULE_PARM_DESC(boost, "overclock boost percent 100 to 500");
1211
1212module_param(clockmode, int, S_IRUGO | S_IWUSR);
1213MODULE_PARM_DESC(clockmode, "1=3Mhz579,2=3Mhz680,3=6Mhz");
1214
1215module_param(cdmode, int, S_IRUGO | S_IWUSR);
1216MODULE_PARM_DESC(cdmode, "Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, "
1217 "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING");
diff --git a/drivers/usb/serial/iuu_phoenix.h b/drivers/usb/serial/iuu_phoenix.h
new file mode 100644
index 000000000000..b82630a3b8fd
--- /dev/null
+++ b/drivers/usb/serial/iuu_phoenix.h
@@ -0,0 +1,122 @@
1/*
2 * Infinity Unlimited USB Phoenix driver
3 *
4 * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com)
5 *
6 *
7 * Original code taken from iuutool ( Copyright (C) 2006 Juan Carlos Borrás )
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * And tested with help of WB Electronics
15 *
16 */
17
18#define IUU_USB_VENDOR_ID 0x104f
19#define IUU_USB_PRODUCT_ID 0x0004
20#define IUU_USB_OP_TIMEOUT 0x0200
21
22/* Programmer commands */
23
24#define IUU_NO_OPERATION 0x00
25#define IUU_GET_FIRMWARE_VERSION 0x01
26#define IUU_GET_PRODUCT_NAME 0x02
27#define IUU_GET_STATE_REGISTER 0x03
28#define IUU_SET_LED 0x04
29#define IUU_WAIT_MUS 0x05
30#define IUU_WAIT_MS 0x06
31#define IUU_GET_LOADER_VERSION 0x50
32#define IUU_RST_SET 0x52
33#define IUU_RST_CLEAR 0x53
34#define IUU_SET_VCC 0x59
35#define IUU_UART_ENABLE 0x49
36#define IUU_UART_DISABLE 0x4A
37#define IUU_UART_WRITE_I2C 0x4C
38#define IUU_UART_ESC 0x5E
39#define IUU_UART_TRAP 0x54
40#define IUU_UART_TRAP_BREAK 0x5B
41#define IUU_UART_RX 0x56
42#define IUU_AVR_ON 0x21
43#define IUU_AVR_OFF 0x22
44#define IUU_AVR_1CLK 0x23
45#define IUU_AVR_RESET 0x24
46#define IUU_AVR_RESET_PC 0x25
47#define IUU_AVR_INC_PC 0x26
48#define IUU_AVR_INCN_PC 0x27
49#define IUU_AVR_PREAD 0x29
50#define IUU_AVR_PREADN 0x2A
51#define IUU_AVR_PWRITE 0x28
52#define IUU_AVR_DREAD 0x2C
53#define IUU_AVR_DREADN 0x2D
54#define IUU_AVR_DWRITE 0x2B
55#define IUU_AVR_PWRITEN 0x2E
56#define IUU_EEPROM_ON 0x37
57#define IUU_EEPROM_OFF 0x38
58#define IUU_EEPROM_WRITE 0x39
59#define IUU_EEPROM_WRITEX 0x3A
60#define IUU_EEPROM_WRITE8 0x3B
61#define IUU_EEPROM_WRITE16 0x3C
62#define IUU_EEPROM_WRITEX32 0x3D
63#define IUU_EEPROM_WRITEX64 0x3E
64#define IUU_EEPROM_READ 0x3F
65#define IUU_EEPROM_READX 0x40
66#define IUU_EEPROM_BREAD 0x41
67#define IUU_EEPROM_BREADX 0x42
68#define IUU_PIC_CMD 0x0A
69#define IUU_PIC_CMD_LOAD 0x0B
70#define IUU_PIC_CMD_READ 0x0C
71#define IUU_PIC_ON 0x0D
72#define IUU_PIC_OFF 0x0E
73#define IUU_PIC_RESET 0x16
74#define IUU_PIC_INC_PC 0x0F
75#define IUU_PIC_INCN_PC 0x10
76#define IUU_PIC_PWRITE 0x11
77#define IUU_PIC_PREAD 0x12
78#define IUU_PIC_PREADN 0x13
79#define IUU_PIC_DWRITE 0x14
80#define IUU_PIC_DREAD 0x15
81#define IUU_UART_NOP 0x00
82#define IUU_UART_CHANGE 0x02
83#define IUU_UART_TX 0x04
84#define IUU_DELAY_MS 0x06
85
86#define IUU_OPERATION_OK 0x00
87#define IUU_DEVICE_NOT_FOUND 0x01
88#define IUU_INVALID_HANDLE 0x02
89#define IUU_INVALID_PARAMETER 0x03
90#define IUU_INVALID_voidERFACE 0x04
91#define IUU_INVALID_REQUEST_LENGTH 0x05
92#define IUU_UART_NOT_ENABLED 0x06
93#define IUU_WRITE_ERROR 0x07
94#define IUU_READ_ERROR 0x08
95#define IUU_TX_ERROR 0x09
96#define IUU_RX_ERROR 0x0A
97
98#define IUU_PARITY_NONE 0x00
99#define IUU_PARITY_EVEN 0x01
100#define IUU_PARITY_ODD 0x02
101#define IUU_PARITY_MARK 0x03
102#define IUU_PARITY_SPACE 0x04
103#define IUU_SC_INSERTED 0x01
104#define IUU_VERIFY_ERROR 0x02
105#define IUU_SIM_INSERTED 0x04
106#define IUU_TWO_STOP_BITS 0x00
107#define IUU_ONE_STOP_BIT 0x20
108#define IUU_BAUD_2400 0x0398
109#define IUU_BAUD_9600 0x0298
110#define IUU_BAUD_19200 0x0164
111#define IUU_BAUD_28800 0x0198
112#define IUU_BAUD_38400 0x01B2
113#define IUU_BAUD_57600 0x0030
114#define IUU_BAUD_115200 0x0098
115#define IUU_CLK_3579000 3579000
116#define IUU_CLK_3680000 3680000
117#define IUU_CLK_6000000 6000000
118#define IUU_FULLCARD_IN 0x01
119#define IUU_DEV_ERROR 0x02
120#define IUU_MINICARD_IN 0x04
121#define IUU_VCC_5V 0x00
122#define IUU_VCC_3V 0x01