diff options
| author | Frank Schäfer <fschaefer.oss@googlemail.com> | 2013-08-06 13:26:26 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-12 18:43:40 -0400 |
| commit | e917ba01d69ad705a4cd6a6c77538f55d84f5907 (patch) | |
| tree | 96207a01da6024ae47e9d150aea6bea4220c2e56 | |
| parent | b9208c721ce736125fe58d398319513a27850fd8 (diff) | |
usb: pl2303: move the two baud rate encoding methods to separate functions
Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/usb/serial/pl2303.c | 215 |
1 files changed, 114 insertions, 101 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index a0ea92ed35c6..693ed7e4871a 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -269,115 +269,128 @@ static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value) | |||
| 269 | return retval; | 269 | return retval; |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, | ||
| 273 | u8 buf[4]) | ||
| 274 | { | ||
| 275 | /* | ||
| 276 | * NOTE: Only the values defined in baud_sup are supported ! | ||
| 277 | * => if unsupported values are set, the PL2303 seems to | ||
| 278 | * use 9600 baud (at least my PL2303X always does) | ||
| 279 | */ | ||
| 280 | const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, | ||
| 281 | 4800, 7200, 9600, 14400, 19200, 28800, 38400, | ||
| 282 | 57600, 115200, 230400, 460800, 614400, 921600, | ||
| 283 | 1228800, 2457600, 3000000, 6000000 }; | ||
| 284 | int i; | ||
| 285 | |||
| 286 | /* Set baudrate to nearest supported value */ | ||
| 287 | for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) { | ||
| 288 | if (baud_sup[i] > baud) | ||
| 289 | break; | ||
| 290 | } | ||
| 291 | if (i == ARRAY_SIZE(baud_sup)) | ||
| 292 | baud = baud_sup[i - 1]; | ||
| 293 | else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) | ||
| 294 | baud = baud_sup[i - 1]; | ||
| 295 | else | ||
| 296 | baud = baud_sup[i]; | ||
| 297 | /* type_0, type_1 only support up to 1228800 baud */ | ||
| 298 | if (type != HX) | ||
| 299 | baud = min_t(int, baud, 1228800); | ||
| 300 | /* Direct (standard) baud rate encoding method */ | ||
| 301 | put_unaligned_le32(baud, buf); | ||
| 302 | |||
| 303 | return baud; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type, | ||
| 307 | u8 buf[4]) | ||
| 308 | { | ||
| 309 | /* | ||
| 310 | * Divisor based baud rate encoding method | ||
| 311 | * | ||
| 312 | * NOTE: it's not clear if the type_0/1 chips support this method | ||
| 313 | * | ||
| 314 | * divisor = 12MHz * 32 / baudrate = 2^A * B | ||
| 315 | * | ||
| 316 | * with | ||
| 317 | * | ||
| 318 | * A = buf[1] & 0x0e | ||
| 319 | * B = buf[0] + (buf[1] & 0x01) << 8 | ||
| 320 | * | ||
| 321 | * Special cases: | ||
| 322 | * => 8 < B < 16: device seems to work not properly | ||
| 323 | * => B <= 8: device uses the max. value B = 512 instead | ||
| 324 | */ | ||
| 325 | unsigned int A, B; | ||
| 326 | |||
| 327 | /* Respect the specified baud rate limits */ | ||
| 328 | baud = max_t(int, baud, 75); | ||
| 329 | if (type == HX) | ||
| 330 | baud = min_t(int, baud, 6000000); | ||
| 331 | else | ||
| 332 | baud = min_t(int, baud, 1228800); | ||
| 333 | /* Determine factors A and B */ | ||
| 334 | A = 0; | ||
| 335 | B = 12000000 * 32 / baud; /* 12MHz */ | ||
| 336 | B <<= 1; /* Add one bit for rounding */ | ||
| 337 | while (B > (512 << 1) && A <= 14) { | ||
| 338 | A += 2; | ||
| 339 | B >>= 2; | ||
| 340 | } | ||
| 341 | if (A > 14) { /* max. divisor = min. baudrate reached */ | ||
| 342 | A = 14; | ||
| 343 | B = 512; | ||
| 344 | /* => ~45.78 baud */ | ||
| 345 | } else { | ||
| 346 | B = (B + 1) >> 1; /* Round the last bit */ | ||
| 347 | } | ||
| 348 | /* Handle special cases */ | ||
| 349 | if (B == 512) | ||
| 350 | B = 0; /* also: 1 to 8 */ | ||
| 351 | else if (B < 16) | ||
| 352 | /* | ||
| 353 | * NOTE: With the current algorithm this happens | ||
| 354 | * only for A=0 and means that the min. divisor | ||
| 355 | * (respectively: the max. baudrate) is reached. | ||
| 356 | */ | ||
| 357 | B = 16; /* => 24 MBaud */ | ||
| 358 | /* Encode the baud rate */ | ||
| 359 | buf[3] = 0x80; /* Select divisor encoding method */ | ||
| 360 | buf[2] = 0; | ||
| 361 | buf[1] = (A & 0x0e); /* A */ | ||
| 362 | buf[1] |= ((B & 0x100) >> 8); /* MSB of B */ | ||
| 363 | buf[0] = B & 0xff; /* 8 LSBs of B */ | ||
| 364 | /* Calculate the actual/resulting baud rate */ | ||
| 365 | if (B <= 8) | ||
| 366 | B = 512; | ||
| 367 | baud = 12000000 * 32 / ((1 << A) * B); | ||
| 368 | |||
| 369 | return baud; | ||
| 370 | } | ||
| 371 | |||
| 272 | static void pl2303_encode_baudrate(struct tty_struct *tty, | 372 | static void pl2303_encode_baudrate(struct tty_struct *tty, |
| 273 | struct usb_serial_port *port, | 373 | struct usb_serial_port *port, |
| 374 | enum pl2303_type type, | ||
| 274 | u8 buf[4]) | 375 | u8 buf[4]) |
| 275 | { | 376 | { |
| 276 | struct usb_serial *serial = port->serial; | ||
| 277 | struct pl2303_serial_private *spriv = usb_get_serial_data(serial); | ||
| 278 | int baud; | 377 | int baud; |
| 279 | 378 | ||
| 280 | baud = tty_get_baud_rate(tty); | 379 | baud = tty_get_baud_rate(tty); |
| 281 | dev_dbg(&port->dev, "baud requested = %d\n", baud); | 380 | dev_dbg(&port->dev, "baud requested = %d\n", baud); |
| 282 | if (!baud) | 381 | if (!baud) |
| 283 | return; | 382 | return; |
| 284 | 383 | /* | |
| 285 | if (spriv->type != HX || baud <= 115200) { | 384 | * There are two methods for setting/encoding the baud rate |
| 286 | /* | 385 | * 1) Direct method: encodes the baud rate value directly |
| 287 | * NOTE: Only the values defined in baud_sup are supported ! | 386 | * => supported by all chip types |
| 288 | * => if unsupported values are set, the PL2303 seems to | 387 | * 2) Divisor based method: encodes a divisor to a base value (12MHz*32) |
| 289 | * use 9600 baud (at least my PL2303X always does) | 388 | * => supported by HX chips (and likely not by type_0/1 chips) |
| 290 | */ | 389 | */ |
| 291 | const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, | 390 | if (type != HX || baud <= 115200) |
| 292 | 3600, 4800, 7200, 9600, 14400, 19200, | 391 | baud = pl2303_baudrate_encode_direct(baud, type, buf); |
| 293 | 28800, 38400, 57600, 115200, 230400, | 392 | else |
| 294 | 460800, 614400, 921600, 1228800, | 393 | baud = pl2303_baudrate_encode_divisor(baud, type, buf); |
| 295 | 2457600, 3000000, 6000000 }; | ||
| 296 | int i; | ||
| 297 | |||
| 298 | /* Set baudrate to nearest supported value */ | ||
| 299 | for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) { | ||
| 300 | if (baud_sup[i] > baud) | ||
| 301 | break; | ||
| 302 | } | ||
| 303 | |||
| 304 | if (i == ARRAY_SIZE(baud_sup)) | ||
| 305 | baud = baud_sup[i - 1]; | ||
| 306 | else if (i > 0 | ||
| 307 | && (baud_sup[i] - baud) > (baud - baud_sup[i - 1])) | ||
| 308 | baud = baud_sup[i - 1]; | ||
| 309 | else | ||
| 310 | baud = baud_sup[i]; | ||
| 311 | |||
| 312 | /* type_0, type_1 only support up to 1228800 baud */ | ||
| 313 | if (spriv->type != HX) | ||
| 314 | baud = min_t(int, baud, 1228800); | ||
| 315 | |||
| 316 | /* Direct (standard) baud rate encoding method */ | ||
| 317 | put_unaligned_le32(baud, buf); | ||
| 318 | } else { | ||
| 319 | /* | ||
| 320 | * Divisor based baud rate encoding method | ||
| 321 | * | ||
| 322 | * NOTE: it's not clear if the type_0/1 chips | ||
| 323 | * support this method | ||
| 324 | * | ||
| 325 | * divisor = 12MHz * 32 / baudrate = 2^A * B | ||
| 326 | * | ||
| 327 | * with | ||
| 328 | * | ||
| 329 | * A = buf[1] & 0x0e | ||
| 330 | * B = buf[0] + (buf[1] & 0x01) << 8 | ||
| 331 | * | ||
| 332 | * Special cases: | ||
| 333 | * => 8 < B < 16: device seems to work not properly | ||
| 334 | * => B <= 8: device uses the max. value B = 512 instead | ||
| 335 | */ | ||
| 336 | unsigned int A, B; | ||
| 337 | |||
| 338 | /* Respect the specified baud rate limits */ | ||
| 339 | baud = max_t(int, baud, 75); | ||
| 340 | if (spriv->type == HX) | ||
| 341 | baud = min_t(int, baud, 6000000); | ||
| 342 | else | ||
| 343 | baud = min_t(int, baud, 1228800); | ||
| 344 | /* Determine factors A and B */ | ||
| 345 | A = 0; | ||
| 346 | B = 12000000 * 32 / baud; /* 12MHz */ | ||
| 347 | B <<= 1; /* Add one bit for rounding */ | ||
| 348 | while (B > (512 << 1) && A <= 14) { | ||
| 349 | A += 2; | ||
| 350 | B >>= 2; | ||
| 351 | } | ||
| 352 | if (A > 14) { /* max. divisor = min. baudrate reached */ | ||
| 353 | A = 14; | ||
| 354 | B = 512; | ||
| 355 | /* => ~45.78 baud */ | ||
| 356 | } else { | ||
| 357 | B = (B + 1) >> 1; /* Round the last bit */ | ||
| 358 | } | ||
| 359 | /* Handle special cases */ | ||
| 360 | if (B == 512) | ||
| 361 | B = 0; /* also: 1 to 8 */ | ||
| 362 | else if (B < 16) | ||
| 363 | /* | ||
| 364 | * NOTE: With the current algorithm this happens | ||
| 365 | * only for A=0 and means that the min. divisor | ||
| 366 | * (respectively: the max. baudrate) is reached. | ||
| 367 | */ | ||
| 368 | B = 16; /* => 24 MBaud */ | ||
| 369 | /* Encode the baud rate */ | ||
| 370 | buf[3] = 0x80; /* Select divisor encoding method */ | ||
| 371 | buf[2] = 0; | ||
| 372 | buf[1] = (A & 0x0e); /* A */ | ||
| 373 | buf[1] |= ((B & 0x100) >> 8); /* MSB of B */ | ||
| 374 | buf[0] = B & 0xff; /* 8 LSBs of B */ | ||
| 375 | /* Calculate the actual/resulting baud rate */ | ||
| 376 | if (B <= 8) | ||
| 377 | B = 512; | ||
| 378 | baud = 12000000 * 32 / ((1 << A) * B); | ||
| 379 | } | ||
| 380 | |||
| 381 | /* Save resulting baud rate */ | 394 | /* Save resulting baud rate */ |
| 382 | tty_encode_baud_rate(tty, baud, baud); | 395 | tty_encode_baud_rate(tty, baud, baud); |
| 383 | dev_dbg(&port->dev, "baud set = %d\n", baud); | 396 | dev_dbg(&port->dev, "baud set = %d\n", baud); |
| @@ -434,8 +447,8 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 434 | dev_dbg(&port->dev, "data bits = %d\n", buf[6]); | 447 | dev_dbg(&port->dev, "data bits = %d\n", buf[6]); |
| 435 | } | 448 | } |
| 436 | 449 | ||
| 437 | /* For reference buf[0]:buf[3] baud rate value */ | 450 | /* For reference: buf[0]:buf[3] baud rate value */ |
| 438 | pl2303_encode_baudrate(tty, port, &buf[0]); | 451 | pl2303_encode_baudrate(tty, port, spriv->type, buf); |
| 439 | 452 | ||
| 440 | /* For reference buf[4]=0 is 1 stop bits */ | 453 | /* For reference buf[4]=0 is 1 stop bits */ |
| 441 | /* For reference buf[4]=1 is 1.5 stop bits */ | 454 | /* For reference buf[4]=1 is 1.5 stop bits */ |
