diff options
author | Johan Hovold <jhovold@gmail.com> | 2013-06-26 10:47:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-23 19:24:32 -0400 |
commit | b2d6d98fc71bb94ada78d433f26a93498802d3f8 (patch) | |
tree | d77698ef369aede2ae66e33cffb1defa6ac69b05 /drivers/usb/serial/pl2303.c | |
parent | 15e7cead1ed89d445cf86c75a72368e98a7a9039 (diff) |
USB: pl2303: clean up baud-rate handling
Clean up baud-rate handling somewhat.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r-- | drivers/usb/serial/pl2303.c | 90 |
1 files changed, 41 insertions, 49 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c15d64d6e1e7..dd59c640edcc 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
30 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
31 | #include <linux/usb/serial.h> | 31 | #include <linux/usb/serial.h> |
32 | #include <asm/unaligned.h> | ||
32 | #include "pl2303.h" | 33 | #include "pl2303.h" |
33 | 34 | ||
34 | /* | 35 | /* |
@@ -275,65 +276,56 @@ static void pl2303_encode_baudrate(struct tty_struct *tty, | |||
275 | struct usb_serial *serial = port->serial; | 276 | struct usb_serial *serial = port->serial; |
276 | struct pl2303_serial_private *spriv = usb_get_serial_data(serial); | 277 | struct pl2303_serial_private *spriv = usb_get_serial_data(serial); |
277 | int baud; | 278 | int baud; |
278 | int baud_floor, baud_ceil; | 279 | int i; |
279 | int k; | ||
280 | 280 | ||
281 | /* NOTE: Only the values defined in baud_sup are supported ! | 281 | /* |
282 | * NOTE: Only the values defined in baud_sup are supported! | ||
282 | * => if unsupported values are set, the PL2303 seems to use | 283 | * => if unsupported values are set, the PL2303 seems to use |
283 | * 9600 baud (at least my PL2303X always does) | 284 | * 9600 baud (at least my PL2303X always does) |
284 | */ | 285 | */ |
285 | baud = tty_get_baud_rate(tty); | 286 | baud = tty_get_baud_rate(tty); |
286 | dev_dbg(&port->dev, "baud requested = %d\n", baud); | 287 | dev_dbg(&port->dev, "baud requested = %d\n", baud); |
287 | if (baud) { | 288 | if (!baud) |
288 | /* Set baudrate to nearest supported value */ | 289 | return; |
289 | for (k=0; k<ARRAY_SIZE(baud_sup); k++) { | 290 | |
290 | if (baud_sup[k] / baud) { | 291 | /* Set baudrate to nearest supported value */ |
291 | baud_ceil = baud_sup[k]; | 292 | for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) { |
292 | if (k==0) { | 293 | if (baud_sup[i] > baud) |
293 | baud = baud_ceil; | 294 | break; |
294 | } else { | 295 | } |
295 | baud_floor = baud_sup[k-1]; | 296 | |
296 | if ((baud_ceil % baud) | 297 | if (i == ARRAY_SIZE(baud_sup)) |
297 | > (baud % baud_floor)) | 298 | baud = baud_sup[i - 1]; |
298 | baud = baud_floor; | 299 | else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) |
299 | else | 300 | baud = baud_sup[i - 1]; |
300 | baud = baud_ceil; | 301 | else |
301 | } | 302 | baud = baud_sup[i]; |
302 | break; | 303 | |
303 | } | 304 | /* type_0, type_1 only support up to 1228800 baud */ |
304 | } | 305 | if (spriv->type != HX) |
305 | if (baud > 1228800) { | 306 | baud = max_t(int, baud, 1228800); |
306 | /* type_0, type_1 only support up to 1228800 baud */ | 307 | |
307 | if (spriv->type != HX) | 308 | if (baud <= 115200) { |
308 | baud = 1228800; | 309 | put_unaligned_le32(baud, buf); |
309 | else if (baud > 6000000) | 310 | } else { |
310 | baud = 6000000; | 311 | /* |
311 | } | 312 | * Apparently the formula for higher speeds is: |
312 | dev_dbg(&port->dev, "baud set = %d\n", baud); | 313 | * baudrate = 12M * 32 / (2^buf[1]) / buf[0] |
313 | if (baud <= 115200) { | 314 | */ |
314 | buf[0] = baud & 0xff; | 315 | unsigned tmp = 12000000 * 32 / baud; |
315 | buf[1] = (baud >> 8) & 0xff; | 316 | buf[3] = 0x80; |
316 | buf[2] = (baud >> 16) & 0xff; | 317 | buf[2] = 0; |
317 | buf[3] = (baud >> 24) & 0xff; | 318 | buf[1] = (tmp >= 256); |
318 | } else { | 319 | while (tmp >= 256) { |
319 | /* apparently the formula for higher speeds is: | 320 | tmp >>= 2; |
320 | * baudrate = 12M * 32 / (2^buf[1]) / buf[0] | 321 | buf[1] <<= 1; |
321 | */ | ||
322 | unsigned tmp = 12*1000*1000*32 / baud; | ||
323 | buf[3] = 0x80; | ||
324 | buf[2] = 0; | ||
325 | buf[1] = (tmp >= 256); | ||
326 | while (tmp >= 256) { | ||
327 | tmp >>= 2; | ||
328 | buf[1] <<= 1; | ||
329 | } | ||
330 | buf[0] = tmp; | ||
331 | } | 322 | } |
323 | buf[0] = tmp; | ||
332 | } | 324 | } |
333 | 325 | ||
334 | /* Save resulting baud rate */ | 326 | /* Save resulting baud rate */ |
335 | if (baud) | 327 | tty_encode_baud_rate(tty, baud, baud); |
336 | tty_encode_baud_rate(tty, baud, baud); | 328 | dev_dbg(&port->dev, "baud set = %d\n", baud); |
337 | } | 329 | } |
338 | 330 | ||
339 | static void pl2303_set_termios(struct tty_struct *tty, | 331 | static void pl2303_set_termios(struct tty_struct *tty, |