Commit 692ed4dd authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Revert "usb: pl2303: move the two baud rate encoding methods to separate functions"

This reverts commit e917ba01.

Revert all of the pl2303 changes that went into 3.12-rc1 and -rc2 as
they cause regressions on some versions of the chip.  This will all be
revisited for later kernel versions when we can figure out how to handle
this in a way that does not break working devices.
Reported-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Cc: Frank Schäfer <fschaefer.oss@googlemail.com>
Acked-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 92dfe410
...@@ -269,18 +269,30 @@ static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value) ...@@ -269,18 +269,30 @@ static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value)
return retval; return retval;
} }
static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, static void pl2303_encode_baudrate(struct tty_struct *tty,
struct usb_serial_port *port,
u8 buf[4]) u8 buf[4])
{ {
struct usb_serial *serial = port->serial;
struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
int baud;
baud = tty_get_baud_rate(tty);
dev_dbg(&port->dev, "baud requested = %d\n", baud);
if (!baud)
return;
if (spriv->type != HX || baud <= 115200) {
/* /*
* NOTE: Only the values defined in baud_sup are supported ! * NOTE: Only the values defined in baud_sup are supported !
* => if unsupported values are set, the PL2303 seems to * => if unsupported values are set, the PL2303 seems to
* use 9600 baud (at least my PL2303X always does) * use 9600 baud (at least my PL2303X always does)
*/ */
const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400,
4800, 7200, 9600, 14400, 19200, 28800, 38400, 3600, 4800, 7200, 9600, 14400, 19200,
57600, 115200, 230400, 460800, 614400, 921600, 28800, 38400, 57600, 115200, 230400,
1228800, 2457600, 3000000, 6000000 }; 460800, 614400, 921600, 1228800,
2457600, 3000000, 6000000 };
int i; int i;
/* Set baudrate to nearest supported value */ /* Set baudrate to nearest supported value */
...@@ -288,28 +300,27 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, ...@@ -288,28 +300,27 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type,
if (baud_sup[i] > baud) if (baud_sup[i] > baud)
break; break;
} }
if (i == ARRAY_SIZE(baud_sup)) if (i == ARRAY_SIZE(baud_sup))
baud = baud_sup[i - 1]; baud = baud_sup[i - 1];
else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) else if (i > 0
&& (baud_sup[i] - baud) > (baud - baud_sup[i - 1]))
baud = baud_sup[i - 1]; baud = baud_sup[i - 1];
else else
baud = baud_sup[i]; baud = baud_sup[i];
/* type_0, type_1 only support up to 1228800 baud */ /* type_0, type_1 only support up to 1228800 baud */
if (type != HX) if (spriv->type != HX)
baud = min_t(int, baud, 1228800); baud = min_t(int, baud, 1228800);
/* Direct (standard) baud rate encoding method */ /* Direct (standard) baud rate encoding method */
put_unaligned_le32(baud, buf); put_unaligned_le32(baud, buf);
} else {
return baud;
}
static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type,
u8 buf[4])
{
/* /*
* Divisor based baud rate encoding method * Divisor based baud rate encoding method
* *
* NOTE: it's not clear if the type_0/1 chips support this method * NOTE: it's not clear if the type_0/1 chips
* support this method
* *
* divisor = 12MHz * 32 / baudrate = 2^A * B * divisor = 12MHz * 32 / baudrate = 2^A * B
* *
...@@ -326,7 +337,7 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type, ...@@ -326,7 +337,7 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type,
/* Respect the specified baud rate limits */ /* Respect the specified baud rate limits */
baud = max_t(int, baud, 75); baud = max_t(int, baud, 75);
if (type == HX) if (spriv->type == HX)
baud = min_t(int, baud, 6000000); baud = min_t(int, baud, 6000000);
else else
baud = min_t(int, baud, 1228800); baud = min_t(int, baud, 1228800);
...@@ -365,32 +376,8 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type, ...@@ -365,32 +376,8 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type,
if (B <= 8) if (B <= 8)
B = 512; B = 512;
baud = 12000000 * 32 / ((1 << A) * B); baud = 12000000 * 32 / ((1 << A) * B);
}
return baud;
}
static void pl2303_encode_baudrate(struct tty_struct *tty,
struct usb_serial_port *port,
enum pl2303_type type,
u8 buf[4])
{
int baud;
baud = tty_get_baud_rate(tty);
dev_dbg(&port->dev, "baud requested = %d\n", baud);
if (!baud)
return;
/*
* There are two methods for setting/encoding the baud rate
* 1) Direct method: encodes the baud rate value directly
* => supported by all chip types
* 2) Divisor based method: encodes a divisor to a base value (12MHz*32)
* => supported by HX chips (and likely not by type_0/1 chips)
*/
if (type != HX || baud <= 115200)
baud = pl2303_baudrate_encode_direct(baud, type, buf);
else
baud = pl2303_baudrate_encode_divisor(baud, type, buf);
/* Save resulting baud rate */ /* Save resulting baud rate */
tty_encode_baud_rate(tty, baud, baud); tty_encode_baud_rate(tty, baud, baud);
dev_dbg(&port->dev, "baud set = %d\n", baud); dev_dbg(&port->dev, "baud set = %d\n", baud);
...@@ -447,8 +434,8 @@ static void pl2303_set_termios(struct tty_struct *tty, ...@@ -447,8 +434,8 @@ static void pl2303_set_termios(struct tty_struct *tty,
dev_dbg(&port->dev, "data bits = %d\n", buf[6]); dev_dbg(&port->dev, "data bits = %d\n", buf[6]);
} }
/* For reference: buf[0]:buf[3] baud rate value */ /* For reference buf[0]:buf[3] baud rate value */
pl2303_encode_baudrate(tty, port, spriv->type, buf); pl2303_encode_baudrate(tty, port, &buf[0]);
/* For reference buf[4]=0 is 1 stop bits */ /* For reference buf[4]=0 is 1 stop bits */
/* For reference buf[4]=1 is 1.5 stop bits */ /* For reference buf[4]=1 is 1.5 stop bits */
......
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