diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2010-05-21 06:53:25 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 17:35:34 -0400 |
commit | 89b54397909dd1d76737b65f682d2aae0781a33c (patch) | |
tree | 4cf55096f6ba9de6f31579a96e8aa3d041374f75 /drivers/usb/serial/iuu_phoenix.c | |
parent | 202380d913d4bf219fdb070b90368cf0275e7b06 (diff) |
USB: iuu_phoenix: Add support for different baud rates.
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/iuu_phoenix.c')
-rw-r--r-- | drivers/usb/serial/iuu_phoenix.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 74551cb2e8ee..efc72113216b 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Infinity Unlimited USB Phoenix driver | 2 | * Infinity Unlimited USB Phoenix driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 James Courtier-Dutton (James@superbug.co.uk) | ||
5 | |||
4 | * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) | 6 | * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) |
5 | * | 7 | * |
6 | * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás) | 8 | * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás) |
@@ -40,7 +42,7 @@ static int debug; | |||
40 | /* | 42 | /* |
41 | * Version Information | 43 | * Version Information |
42 | */ | 44 | */ |
43 | #define DRIVER_VERSION "v0.11" | 45 | #define DRIVER_VERSION "v0.12" |
44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" | 46 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" |
45 | 47 | ||
46 | static const struct usb_device_id id_table[] = { | 48 | static const struct usb_device_id id_table[] = { |
@@ -81,6 +83,9 @@ struct iuu_private { | |||
81 | u8 *dbgbuf; /* debug buffer */ | 83 | u8 *dbgbuf; /* debug buffer */ |
82 | u8 len; | 84 | u8 len; |
83 | int vcc; /* vcc (either 3 or 5 V) */ | 85 | int vcc; /* vcc (either 3 or 5 V) */ |
86 | u32 baud; | ||
87 | u32 boost; | ||
88 | u32 clk; | ||
84 | }; | 89 | }; |
85 | 90 | ||
86 | 91 | ||
@@ -157,13 +162,14 @@ static int iuu_tiocmset(struct tty_struct *tty, struct file *file, | |||
157 | port->number, set, clear); | 162 | port->number, set, clear); |
158 | 163 | ||
159 | spin_lock_irqsave(&priv->lock, flags); | 164 | spin_lock_irqsave(&priv->lock, flags); |
160 | if (set & TIOCM_RTS) | ||
161 | priv->tiostatus = TIOCM_RTS; | ||
162 | 165 | ||
163 | if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { | 166 | if ((set & TIOCM_RTS) && !(priv->tiostatus == TIOCM_RTS)) { |
164 | dbg("%s TIOCMSET RESET called !!!", __func__); | 167 | dbg("%s TIOCMSET RESET called !!!", __func__); |
165 | priv->reset = 1; | 168 | priv->reset = 1; |
166 | } | 169 | } |
170 | if (set & TIOCM_RTS) | ||
171 | priv->tiostatus = TIOCM_RTS; | ||
172 | |||
167 | spin_unlock_irqrestore(&priv->lock, flags); | 173 | spin_unlock_irqrestore(&priv->lock, flags); |
168 | return 0; | 174 | return 0; |
169 | } | 175 | } |
@@ -851,20 +857,24 @@ static int iuu_uart_off(struct usb_serial_port *port) | |||
851 | return status; | 857 | return status; |
852 | } | 858 | } |
853 | 859 | ||
854 | static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, | 860 | static int iuu_uart_baud(struct usb_serial_port *port, u32 baud_base, |
855 | u32 *actual, u8 parity) | 861 | u32 *actual, u8 parity) |
856 | { | 862 | { |
857 | int status; | 863 | int status; |
864 | u32 baud; | ||
858 | u8 *dataout; | 865 | u8 *dataout; |
859 | u8 DataCount = 0; | 866 | u8 DataCount = 0; |
860 | u8 T1Frekvens = 0; | 867 | u8 T1Frekvens = 0; |
861 | u8 T1reload = 0; | 868 | u8 T1reload = 0; |
862 | unsigned int T1FrekvensHZ = 0; | 869 | unsigned int T1FrekvensHZ = 0; |
863 | 870 | ||
871 | dbg("%s - enter baud_base=%d", __func__, baud_base); | ||
864 | dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL); | 872 | dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL); |
865 | 873 | ||
866 | if (!dataout) | 874 | if (!dataout) |
867 | return -ENOMEM; | 875 | return -ENOMEM; |
876 | /*baud = (((priv->clk / 35) * baud_base) / 100000); */ | ||
877 | baud = baud_base; | ||
868 | 878 | ||
869 | if (baud < 1200 || baud > 230400) { | 879 | if (baud < 1200 || baud > 230400) { |
870 | kfree(dataout); | 880 | kfree(dataout); |
@@ -948,15 +958,20 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
948 | struct usb_serial_port *port, struct ktermios *old_termios) | 958 | struct usb_serial_port *port, struct ktermios *old_termios) |
949 | { | 959 | { |
950 | const u32 supported_mask = CMSPAR|PARENB|PARODD; | 960 | const u32 supported_mask = CMSPAR|PARENB|PARODD; |
951 | 961 | struct iuu_private *priv = usb_get_serial_port_data(port); | |
952 | unsigned int cflag = tty->termios->c_cflag; | 962 | unsigned int cflag = tty->termios->c_cflag; |
953 | int status; | 963 | int status; |
954 | u32 actual; | 964 | u32 actual; |
955 | u32 parity; | 965 | u32 parity; |
956 | int csize = CS7; | 966 | int csize = CS7; |
957 | int baud = 9600; /* Fixed for the moment */ | 967 | int baud; |
958 | u32 newval = cflag & supported_mask; | 968 | u32 newval = cflag & supported_mask; |
959 | 969 | ||
970 | /* Just use the ospeed. ispeed should be the same. */ | ||
971 | baud = tty->termios->c_ospeed; | ||
972 | |||
973 | dbg("%s - enter c_ospeed or baud=%d", __func__, baud); | ||
974 | |||
960 | /* compute the parity parameter */ | 975 | /* compute the parity parameter */ |
961 | parity = 0; | 976 | parity = 0; |
962 | if (cflag & CMSPAR) { /* Using mark space */ | 977 | if (cflag & CMSPAR) { /* Using mark space */ |
@@ -976,15 +991,15 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
976 | 991 | ||
977 | /* set it */ | 992 | /* set it */ |
978 | status = iuu_uart_baud(port, | 993 | status = iuu_uart_baud(port, |
979 | (clockmode == 2) ? 16457 : 9600 * boost / 100, | 994 | baud * priv->boost / 100, |
980 | &actual, parity); | 995 | &actual, parity); |
981 | 996 | ||
982 | /* set the termios value to the real one, so the user now what has | 997 | /* set the termios value to the real one, so the user now what has |
983 | * changed. We support few fields so its easies to copy the old hw | 998 | * changed. We support few fields so its easies to copy the old hw |
984 | * settings back over and then adjust them | 999 | * settings back over and then adjust them |
985 | */ | 1000 | */ |
986 | if (old_termios) | 1001 | if (old_termios) |
987 | tty_termios_copy_hw(tty->termios, old_termios); | 1002 | tty_termios_copy_hw(tty->termios, old_termios); |
988 | if (status != 0) /* Set failed - return old bits */ | 1003 | if (status != 0) /* Set failed - return old bits */ |
989 | return; | 1004 | return; |
990 | /* Re-encode speed, parity and csize */ | 1005 | /* Re-encode speed, parity and csize */ |
@@ -1018,6 +1033,7 @@ static void iuu_close(struct usb_serial_port *port) | |||
1018 | 1033 | ||
1019 | static void iuu_init_termios(struct tty_struct *tty) | 1034 | static void iuu_init_termios(struct tty_struct *tty) |
1020 | { | 1035 | { |
1036 | dbg("%s - enter", __func__); | ||
1021 | *(tty->termios) = tty_std_termios; | 1037 | *(tty->termios) = tty_std_termios; |
1022 | tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 | 1038 | tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 |
1023 | | TIOCM_CTS | CSTOPB | PARENB; | 1039 | | TIOCM_CTS | CSTOPB | PARENB; |
@@ -1033,10 +1049,16 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1033 | struct usb_serial *serial = port->serial; | 1049 | struct usb_serial *serial = port->serial; |
1034 | u8 *buf; | 1050 | u8 *buf; |
1035 | int result; | 1051 | int result; |
1052 | int baud; | ||
1036 | u32 actual; | 1053 | u32 actual; |
1037 | struct iuu_private *priv = usb_get_serial_port_data(port); | 1054 | struct iuu_private *priv = usb_get_serial_port_data(port); |
1038 | 1055 | ||
1039 | dbg("%s - port %d", __func__, port->number); | 1056 | baud = tty->termios->c_ospeed; |
1057 | tty->termios->c_ispeed = baud; | ||
1058 | /* Re-encode speed */ | ||
1059 | tty_encode_baud_rate(tty, baud, baud); | ||
1060 | |||
1061 | dbg("%s - port %d, baud %d", __func__, port->number, baud); | ||
1040 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 1062 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
1041 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 1063 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
1042 | 1064 | ||
@@ -1071,23 +1093,29 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1071 | iuu_uart_on(port); | 1093 | iuu_uart_on(port); |
1072 | if (boost < 100) | 1094 | if (boost < 100) |
1073 | boost = 100; | 1095 | boost = 100; |
1096 | priv->boost = boost; | ||
1097 | priv->baud = baud; | ||
1074 | switch (clockmode) { | 1098 | switch (clockmode) { |
1075 | case 2: /* 3.680 Mhz */ | 1099 | case 2: /* 3.680 Mhz */ |
1100 | priv->clk = IUU_CLK_3680000; | ||
1076 | iuu_clk(port, IUU_CLK_3680000 * boost / 100); | 1101 | iuu_clk(port, IUU_CLK_3680000 * boost / 100); |
1077 | result = | 1102 | result = |
1078 | iuu_uart_baud(port, 9600 * boost / 100, &actual, | 1103 | iuu_uart_baud(port, baud * boost / 100, &actual, |
1079 | IUU_PARITY_EVEN); | 1104 | IUU_PARITY_EVEN); |
1080 | break; | 1105 | break; |
1081 | case 3: /* 6.00 Mhz */ | 1106 | case 3: /* 6.00 Mhz */ |
1082 | iuu_clk(port, IUU_CLK_6000000 * boost / 100); | 1107 | iuu_clk(port, IUU_CLK_6000000 * boost / 100); |
1108 | priv->clk = IUU_CLK_6000000; | ||
1109 | /* Ratio of 6000000 to 3500000 for baud 9600 */ | ||
1083 | result = | 1110 | result = |
1084 | iuu_uart_baud(port, 16457 * boost / 100, &actual, | 1111 | iuu_uart_baud(port, 16457 * boost / 100, &actual, |
1085 | IUU_PARITY_EVEN); | 1112 | IUU_PARITY_EVEN); |
1086 | break; | 1113 | break; |
1087 | default: /* 3.579 Mhz */ | 1114 | default: /* 3.579 Mhz */ |
1088 | iuu_clk(port, IUU_CLK_3579000 * boost / 100); | 1115 | iuu_clk(port, IUU_CLK_3579000 * boost / 100); |
1116 | priv->clk = IUU_CLK_3579000; | ||
1089 | result = | 1117 | result = |
1090 | iuu_uart_baud(port, 9600 * boost / 100, &actual, | 1118 | iuu_uart_baud(port, baud * boost / 100, &actual, |
1091 | IUU_PARITY_EVEN); | 1119 | IUU_PARITY_EVEN); |
1092 | } | 1120 | } |
1093 | 1121 | ||