Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alain Degreffe and committed by
Greg Kroah-Hartman
60a8fc01 c74e8095

+1435
+84
Documentation/usb/iuu_phoenix.txt
··· 1 + Infinity Usb Unlimited Readme 2 + ----------------------------- 3 + 4 + Hi all, 5 + 6 + 7 + This module provide a serial interface to use your 8 + IUU unit in phoenix mode. Loading this module will 9 + bring a ttyUSB[0-x] interface. This driver must be 10 + used by your favorite application to pilot the IUU 11 + 12 + This driver is still in beta stage, so bugs can 13 + occur and your system may freeze. As far I now, 14 + I never had any problem with it, but I'm not a real 15 + guru, so don't blame me if your system is unstable 16 + 17 + You can plug more than one IUU. Every unit will 18 + have his own device file(/dev/ttyUSB0,/dev/ttyUSB1,...) 19 + 20 + 21 + 22 + How 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
+11
drivers/usb/serial/Kconfig
··· 282 282 To compile this driver as a module, choose M here: the 283 283 module will be called ipw. 284 284 285 + config 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 + 285 296 config USB_SERIAL_KEYSPAN_PDA 286 297 tristate "USB Keyspan PDA Single Port Serial Driver" 287 298 depends on USB_SERIAL
+1
drivers/usb/serial/Makefile
··· 30 30 obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o 31 31 obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o 32 32 obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o 33 + obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o 33 34 obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o 34 35 obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o 35 36 obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o
+1217
drivers/usb/serial/iuu_phoenix.c
··· 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 35 + static int debug = 1; 36 + #else 37 + static 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 + 46 + static struct usb_device_id id_table[] = { 47 + {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, 48 + {} /* Terminating entry */ 49 + }; 50 + MODULE_DEVICE_TABLE(usb, id_table); 51 + 52 + static 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 */ 61 + static int boost = 100; 62 + static int clockmode = 1; 63 + static int cdmode = 1; 64 + static int iuu_cardin; 65 + static int iuu_cardout; 66 + static int xmas; 67 + 68 + static void read_rxcmd_callback(struct urb *urb); 69 + 70 + struct 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 + 87 + static void iuu_free_buf(struct iuu_private *priv) 88 + { 89 + kfree(priv->buf); 90 + kfree(priv->dbgbuf); 91 + kfree(priv->writebuf); 92 + } 93 + 94 + static 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 + 108 + static 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 */ 126 + static 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 + 147 + static 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 + */ 173 + static 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 + 179 + static 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 + 201 + static 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 + */ 233 + static 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 + 263 + static 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 + 278 + static 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 + 295 + static 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 + 319 + static 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 + 344 + static 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 + 372 + static 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 + 385 + static 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 + 406 + static 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 + 428 + static 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 + 569 + static 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 + 609 + static 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 + 635 + static 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 + 671 + static 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 + 685 + static 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 + 750 + static 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 + 774 + static 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 + 798 + static 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__); 822 + uart_enable_failed: 823 + kfree(buf); 824 + return status; 825 + } 826 + 827 + /* Diables the IUU UART (a.k.a. the Phoenix voiderface) */ 828 + static 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 + 845 + static 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 + 938 + static int set_control_lines(struct usb_device *dev, u8 value) 939 + { 940 + return 0; 941 + } 942 + 943 + static 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 + 984 + static 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 + 1151 + static 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 + 1171 + static 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; 1182 + failed_usb_register: 1183 + usb_serial_deregister(&iuu_device); 1184 + failed_usb_serial_register: 1185 + return retval; 1186 + } 1187 + 1188 + static void __exit iuu_exit(void) 1189 + { 1190 + usb_deregister(&iuu_driver); 1191 + usb_serial_deregister(&iuu_device); 1192 + } 1193 + 1194 + module_init(iuu_init); 1195 + module_exit(iuu_exit); 1196 + 1197 + MODULE_AUTHOR("Alain Degreffe eczema@ecze.com"); 1198 + 1199 + MODULE_DESCRIPTION(DRIVER_DESC); 1200 + MODULE_LICENSE("GPL"); 1201 + 1202 + MODULE_VERSION(DRIVER_VERSION); 1203 + module_param(debug, bool, S_IRUGO | S_IWUSR); 1204 + MODULE_PARM_DESC(debug, "Debug enabled or not"); 1205 + 1206 + module_param(xmas, bool, S_IRUGO | S_IWUSR); 1207 + MODULE_PARM_DESC(xmas, "xmas color enabled or not"); 1208 + 1209 + module_param(boost, int, S_IRUGO | S_IWUSR); 1210 + MODULE_PARM_DESC(boost, "overclock boost percent 100 to 500"); 1211 + 1212 + module_param(clockmode, int, S_IRUGO | S_IWUSR); 1213 + MODULE_PARM_DESC(clockmode, "1=3Mhz579,2=3Mhz680,3=6Mhz"); 1214 + 1215 + module_param(cdmode, int, S_IRUGO | S_IWUSR); 1216 + MODULE_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");
+122
drivers/usb/serial/iuu_phoenix.h
··· 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