Hi, I have a patch for the current version of iuu_phoenix.c to let is support different baud rates. This is required for some cards that one would wish to change baud rates after ATR. Signed off by: James Courtier-Dutton <James@xxxxxxxxxxxxxx> Kind Regards James
--- iuu_phoenix.c.org 2010-04-05 09:07:09.220865033 +0100 +++ iuu_phoenix.c 2010-04-05 09:10:38.200861768 +0100 @@ -1,6 +1,8 @@ /* * Infinity Unlimited USB Phoenix driver * + * Copyright (C) 2010 James Courtier-Dutton (James@xxxxxxxxxxxxxx) + * * Copyright (C) 2007 Alain Degreffe (eczema@xxxxxxxx) * * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borr�¡s) @@ -81,6 +83,9 @@ u8 *dbgbuf; /* debug buffer */ u8 len; int vcc; /* vcc (either 3 or 5 V) */ + u32 baud; + u32 boost; + u32 clk; }; @@ -157,13 +162,14 @@ port->number, set, clear); spin_lock_irqsave(&priv->lock, flags); - if (set & TIOCM_RTS) - priv->tiostatus = TIOCM_RTS; - if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { + if ((set & TIOCM_RTS) && !(priv->tiostatus == TIOCM_RTS)) { dbg("%s TIOCMSET RESET called !!!", __func__); priv->reset = 1; } + if (set & TIOCM_RTS) + priv->tiostatus = TIOCM_RTS; + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -851,10 +857,11 @@ return status; } -static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, +static int iuu_uart_baud(struct usb_serial_port *port, u32 baud_base, u32 *actual, u8 parity) { int status; + u32 baud; u8 *dataout; u8 DataCount = 0; u8 T1Frekvens = 0; @@ -865,6 +872,8 @@ if (!dataout) return -ENOMEM; + /*baud = (((priv->clk / 35) * baud_base) / 100000); */ + baud = baud_base; if (baud < 1200 || baud > 230400) { kfree(dataout); @@ -948,15 +957,18 @@ struct usb_serial_port *port, struct ktermios *old_termios) { const u32 supported_mask = CMSPAR|PARENB|PARODD; - + struct iuu_private *priv = usb_get_serial_port_data(port); unsigned int cflag = tty->termios->c_cflag; int status; u32 actual; u32 parity; int csize = CS7; - int baud = 9600; /* Fixed for the moment */ + int baud; u32 newval = cflag & supported_mask; + /* Just use the ospeed. ispeed should be the same. */ + baud = tty->termios->c_ospeed; + /* compute the parity parameter */ parity = 0; if (cflag & CMSPAR) { /* Using mark space */ @@ -976,15 +988,15 @@ /* set it */ status = iuu_uart_baud(port, - (clockmode == 2) ? 16457 : 9600 * boost / 100, + baud * priv->boost / 100, &actual, parity); /* set the termios value to the real one, so the user now what has * changed. We support few fields so its easies to copy the old hw * settings back over and then adjust them */ - if (old_termios) - tty_termios_copy_hw(tty->termios, old_termios); + if (old_termios) + tty_termios_copy_hw(tty->termios, old_termios); if (status != 0) /* Set failed - return old bits */ return; /* Re-encode speed, parity and csize */ @@ -1033,6 +1045,7 @@ struct usb_serial *serial = port->serial; u8 *buf; int result; + int baud = 9600; /* Fixed for the moment */ u32 actual; struct iuu_private *priv = usb_get_serial_port_data(port); @@ -1099,23 +1112,29 @@ iuu_uart_on(port); if (boost < 100) boost = 100; + priv->boost = boost; + priv->baud = baud; switch (clockmode) { case 2: /* 3.680 Mhz */ + priv->clk = IUU_CLK_3680000; iuu_clk(port, IUU_CLK_3680000 * boost / 100); result = - iuu_uart_baud(port, 9600 * boost / 100, &actual, + iuu_uart_baud(port, baud * boost / 100, &actual, IUU_PARITY_EVEN); break; case 3: /* 6.00 Mhz */ iuu_clk(port, IUU_CLK_6000000 * boost / 100); + priv->clk = IUU_CLK_6000000; + /* Ratio of 6000000 to 3500000 for baud 9600 */ result = iuu_uart_baud(port, 16457 * boost / 100, &actual, IUU_PARITY_EVEN); break; default: /* 3.579 Mhz */ iuu_clk(port, IUU_CLK_3579000 * boost / 100); + priv->clk = IUU_CLK_3579000; result = - iuu_uart_baud(port, 9600 * boost / 100, &actual, + iuu_uart_baud(port, baud * boost / 100, &actual, IUU_PARITY_EVEN); } @@ -1248,6 +1267,16 @@ return count; } +static int iuu_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + dbg("%s cmd 0x%04x", __func__, cmd); + + /* Old interface. Returning -ENOIOCTLCMD for proper termios use. */ + return -ENOIOCTLCMD; +} + + static DEVICE_ATTR(vcc_mode, S_IRUSR | S_IWUSR, show_vcc_mode, store_vcc_mode); @@ -1285,6 +1314,7 @@ .read_bulk_callback = iuu_uart_read_callback, .tiocmget = iuu_tiocmget, .tiocmset = iuu_tiocmset, + .ioctl = iuu_ioctl, .set_termios = iuu_set_termios, .init_termios = iuu_init_termios, .attach = iuu_startup,