Commit 89b54397 authored by James Courtier-Dutton's avatar James Courtier-Dutton Committed by Greg Kroah-Hartman

USB: iuu_phoenix: Add support for different baud rates.

Signed-off-by: default avatarJames Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 202380d9
/* /*
* Infinity Unlimited USB Phoenix driver * Infinity Unlimited USB Phoenix driver
* *
* Copyright (C) 2010 James Courtier-Dutton (James@superbug.co.uk)
* Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com)
* *
* Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás) * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás)
...@@ -40,7 +42,7 @@ static int debug; ...@@ -40,7 +42,7 @@ static int debug;
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v0.11" #define DRIVER_VERSION "v0.12"
#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
static const struct usb_device_id id_table[] = { static const struct usb_device_id id_table[] = {
...@@ -81,6 +83,9 @@ struct iuu_private { ...@@ -81,6 +83,9 @@ struct iuu_private {
u8 *dbgbuf; /* debug buffer */ u8 *dbgbuf; /* debug buffer */
u8 len; u8 len;
int vcc; /* vcc (either 3 or 5 V) */ int vcc; /* vcc (either 3 or 5 V) */
u32 baud;
u32 boost;
u32 clk;
}; };
...@@ -157,13 +162,14 @@ static int iuu_tiocmset(struct tty_struct *tty, struct file *file, ...@@ -157,13 +162,14 @@ static int iuu_tiocmset(struct tty_struct *tty, struct file *file,
port->number, set, clear); port->number, set, clear);
spin_lock_irqsave(&priv->lock, flags); 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__); dbg("%s TIOCMSET RESET called !!!", __func__);
priv->reset = 1; priv->reset = 1;
} }
if (set & TIOCM_RTS)
priv->tiostatus = TIOCM_RTS;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
return 0; return 0;
} }
...@@ -851,20 +857,24 @@ static int iuu_uart_off(struct usb_serial_port *port) ...@@ -851,20 +857,24 @@ static int iuu_uart_off(struct usb_serial_port *port)
return status; 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) u32 *actual, u8 parity)
{ {
int status; int status;
u32 baud;
u8 *dataout; u8 *dataout;
u8 DataCount = 0; u8 DataCount = 0;
u8 T1Frekvens = 0; u8 T1Frekvens = 0;
u8 T1reload = 0; u8 T1reload = 0;
unsigned int T1FrekvensHZ = 0; unsigned int T1FrekvensHZ = 0;
dbg("%s - enter baud_base=%d", __func__, baud_base);
dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL); dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL);
if (!dataout) if (!dataout)
return -ENOMEM; return -ENOMEM;
/*baud = (((priv->clk / 35) * baud_base) / 100000); */
baud = baud_base;
if (baud < 1200 || baud > 230400) { if (baud < 1200 || baud > 230400) {
kfree(dataout); kfree(dataout);
...@@ -948,15 +958,20 @@ static void iuu_set_termios(struct tty_struct *tty, ...@@ -948,15 +958,20 @@ static void iuu_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios) struct usb_serial_port *port, struct ktermios *old_termios)
{ {
const u32 supported_mask = CMSPAR|PARENB|PARODD; const u32 supported_mask = CMSPAR|PARENB|PARODD;
struct iuu_private *priv = usb_get_serial_port_data(port);
unsigned int cflag = tty->termios->c_cflag; unsigned int cflag = tty->termios->c_cflag;
int status; int status;
u32 actual; u32 actual;
u32 parity; u32 parity;
int csize = CS7; int csize = CS7;
int baud = 9600; /* Fixed for the moment */ int baud;
u32 newval = cflag & supported_mask; u32 newval = cflag & supported_mask;
/* Just use the ospeed. ispeed should be the same. */
baud = tty->termios->c_ospeed;
dbg("%s - enter c_ospeed or baud=%d", __func__, baud);
/* compute the parity parameter */ /* compute the parity parameter */
parity = 0; parity = 0;
if (cflag & CMSPAR) { /* Using mark space */ if (cflag & CMSPAR) { /* Using mark space */
...@@ -976,7 +991,7 @@ static void iuu_set_termios(struct tty_struct *tty, ...@@ -976,7 +991,7 @@ static void iuu_set_termios(struct tty_struct *tty,
/* set it */ /* set it */
status = iuu_uart_baud(port, status = iuu_uart_baud(port,
(clockmode == 2) ? 16457 : 9600 * boost / 100, baud * priv->boost / 100,
&actual, parity); &actual, parity);
/* set the termios value to the real one, so the user now what has /* set the termios value to the real one, so the user now what has
...@@ -1018,6 +1033,7 @@ static void iuu_close(struct usb_serial_port *port) ...@@ -1018,6 +1033,7 @@ static void iuu_close(struct usb_serial_port *port)
static void iuu_init_termios(struct tty_struct *tty) static void iuu_init_termios(struct tty_struct *tty)
{ {
dbg("%s - enter", __func__);
*(tty->termios) = tty_std_termios; *(tty->termios) = tty_std_termios;
tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
| TIOCM_CTS | CSTOPB | PARENB; | TIOCM_CTS | CSTOPB | PARENB;
...@@ -1033,10 +1049,16 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -1033,10 +1049,16 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
u8 *buf; u8 *buf;
int result; int result;
int baud;
u32 actual; u32 actual;
struct iuu_private *priv = usb_get_serial_port_data(port); struct iuu_private *priv = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number); baud = tty->termios->c_ospeed;
tty->termios->c_ispeed = baud;
/* Re-encode speed */
tty_encode_baud_rate(tty, baud, baud);
dbg("%s - port %d, baud %d", __func__, port->number, baud);
usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->write_urb->pipe);
usb_clear_halt(serial->dev, port->read_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe);
...@@ -1071,23 +1093,29 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -1071,23 +1093,29 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
iuu_uart_on(port); iuu_uart_on(port);
if (boost < 100) if (boost < 100)
boost = 100; boost = 100;
priv->boost = boost;
priv->baud = baud;
switch (clockmode) { switch (clockmode) {
case 2: /* 3.680 Mhz */ case 2: /* 3.680 Mhz */
priv->clk = IUU_CLK_3680000;
iuu_clk(port, IUU_CLK_3680000 * boost / 100); iuu_clk(port, IUU_CLK_3680000 * boost / 100);
result = result =
iuu_uart_baud(port, 9600 * boost / 100, &actual, iuu_uart_baud(port, baud * boost / 100, &actual,
IUU_PARITY_EVEN); IUU_PARITY_EVEN);
break; break;
case 3: /* 6.00 Mhz */ case 3: /* 6.00 Mhz */
iuu_clk(port, IUU_CLK_6000000 * boost / 100); iuu_clk(port, IUU_CLK_6000000 * boost / 100);
priv->clk = IUU_CLK_6000000;
/* Ratio of 6000000 to 3500000 for baud 9600 */
result = result =
iuu_uart_baud(port, 16457 * boost / 100, &actual, iuu_uart_baud(port, 16457 * boost / 100, &actual,
IUU_PARITY_EVEN); IUU_PARITY_EVEN);
break; break;
default: /* 3.579 Mhz */ default: /* 3.579 Mhz */
iuu_clk(port, IUU_CLK_3579000 * boost / 100); iuu_clk(port, IUU_CLK_3579000 * boost / 100);
priv->clk = IUU_CLK_3579000;
result = result =
iuu_uart_baud(port, 9600 * boost / 100, &actual, iuu_uart_baud(port, baud * boost / 100, &actual,
IUU_PARITY_EVEN); IUU_PARITY_EVEN);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment