| .. | .. |
|---|
| 48 | 48 | #define CH341_BIT_DCD 0x08 |
|---|
| 49 | 49 | #define CH341_BITS_MODEM_STAT 0x0f /* all bits */ |
|---|
| 50 | 50 | |
|---|
| 51 | | -/*******************************/ |
|---|
| 52 | | -/* baudrate calculation factor */ |
|---|
| 53 | | -/*******************************/ |
|---|
| 54 | | -#define CH341_BAUDBASE_FACTOR 1532620800 |
|---|
| 55 | | -#define CH341_BAUDBASE_DIVMAX 3 |
|---|
| 56 | | - |
|---|
| 57 | 51 | /* Break support - the information used to implement this was gleaned from |
|---|
| 58 | 52 | * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. |
|---|
| 59 | 53 | */ |
|---|
| .. | .. |
|---|
| 65 | 59 | #define CH341_REQ_MODEM_CTRL 0xA4 |
|---|
| 66 | 60 | |
|---|
| 67 | 61 | #define CH341_REG_BREAK 0x05 |
|---|
| 62 | +#define CH341_REG_PRESCALER 0x12 |
|---|
| 63 | +#define CH341_REG_DIVISOR 0x13 |
|---|
| 68 | 64 | #define CH341_REG_LCR 0x18 |
|---|
| 65 | +#define CH341_REG_LCR2 0x25 |
|---|
| 66 | + |
|---|
| 69 | 67 | #define CH341_NBREAK_BITS 0x01 |
|---|
| 70 | 68 | |
|---|
| 71 | 69 | #define CH341_LCR_ENABLE_RX 0x80 |
|---|
| .. | .. |
|---|
| 78 | 76 | #define CH341_LCR_CS7 0x02 |
|---|
| 79 | 77 | #define CH341_LCR_CS6 0x01 |
|---|
| 80 | 78 | #define CH341_LCR_CS5 0x00 |
|---|
| 79 | + |
|---|
| 80 | +#define CH341_QUIRK_LIMITED_PRESCALER BIT(0) |
|---|
| 81 | +#define CH341_QUIRK_SIMULATE_BREAK BIT(1) |
|---|
| 81 | 82 | |
|---|
| 82 | 83 | static const struct usb_device_id id_table[] = { |
|---|
| 83 | 84 | { USB_DEVICE(0x1a86, 0x5523) }, |
|---|
| .. | .. |
|---|
| 96 | 97 | u8 mcr; |
|---|
| 97 | 98 | u8 msr; |
|---|
| 98 | 99 | u8 lcr; |
|---|
| 100 | + |
|---|
| 101 | + unsigned long quirks; |
|---|
| 102 | + u8 version; |
|---|
| 103 | + |
|---|
| 104 | + unsigned long break_end; |
|---|
| 99 | 105 | }; |
|---|
| 100 | 106 | |
|---|
| 101 | 107 | static void ch341_set_termios(struct tty_struct *tty, |
|---|
| .. | .. |
|---|
| 147 | 153 | return 0; |
|---|
| 148 | 154 | } |
|---|
| 149 | 155 | |
|---|
| 150 | | -static int ch341_set_baudrate_lcr(struct usb_device *dev, |
|---|
| 151 | | - struct ch341_private *priv, u8 lcr) |
|---|
| 156 | +#define CH341_CLKRATE 48000000 |
|---|
| 157 | +#define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) |
|---|
| 158 | +#define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) |
|---|
| 159 | + |
|---|
| 160 | +static const speed_t ch341_min_rates[] = { |
|---|
| 161 | + CH341_MIN_RATE(0), |
|---|
| 162 | + CH341_MIN_RATE(1), |
|---|
| 163 | + CH341_MIN_RATE(2), |
|---|
| 164 | + CH341_MIN_RATE(3), |
|---|
| 165 | +}; |
|---|
| 166 | + |
|---|
| 167 | +/* Supported range is 46 to 3000000 bps. */ |
|---|
| 168 | +#define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) |
|---|
| 169 | +#define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) |
|---|
| 170 | + |
|---|
| 171 | +/* |
|---|
| 172 | + * The device line speed is given by the following equation: |
|---|
| 173 | + * |
|---|
| 174 | + * baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where |
|---|
| 175 | + * |
|---|
| 176 | + * 0 <= ps <= 3, |
|---|
| 177 | + * 0 <= fact <= 1, |
|---|
| 178 | + * 2 <= div <= 256 if fact = 0, or |
|---|
| 179 | + * 9 <= div <= 256 if fact = 1 |
|---|
| 180 | + */ |
|---|
| 181 | +static int ch341_get_divisor(struct ch341_private *priv, speed_t speed) |
|---|
| 152 | 182 | { |
|---|
| 153 | | - short a; |
|---|
| 154 | | - int r; |
|---|
| 155 | | - unsigned long factor; |
|---|
| 156 | | - short divisor; |
|---|
| 183 | + unsigned int fact, div, clk_div; |
|---|
| 184 | + bool force_fact0 = false; |
|---|
| 185 | + int ps; |
|---|
| 157 | 186 | |
|---|
| 158 | | - if (!priv->baud_rate) |
|---|
| 159 | | - return -EINVAL; |
|---|
| 160 | | - factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate); |
|---|
| 161 | | - divisor = CH341_BAUDBASE_DIVMAX; |
|---|
| 187 | + /* |
|---|
| 188 | + * Clamp to supported range, this makes the (ps < 0) and (div < 2) |
|---|
| 189 | + * sanity checks below redundant. |
|---|
| 190 | + */ |
|---|
| 191 | + speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); |
|---|
| 162 | 192 | |
|---|
| 163 | | - while ((factor > 0xfff0) && divisor) { |
|---|
| 164 | | - factor >>= 3; |
|---|
| 165 | | - divisor--; |
|---|
| 193 | + /* |
|---|
| 194 | + * Start with highest possible base clock (fact = 1) that will give a |
|---|
| 195 | + * divisor strictly less than 512. |
|---|
| 196 | + */ |
|---|
| 197 | + fact = 1; |
|---|
| 198 | + for (ps = 3; ps >= 0; ps--) { |
|---|
| 199 | + if (speed > ch341_min_rates[ps]) |
|---|
| 200 | + break; |
|---|
| 166 | 201 | } |
|---|
| 167 | 202 | |
|---|
| 168 | | - if (factor > 0xfff0) |
|---|
| 203 | + if (ps < 0) |
|---|
| 169 | 204 | return -EINVAL; |
|---|
| 170 | 205 | |
|---|
| 171 | | - factor = 0x10000 - factor; |
|---|
| 172 | | - a = (factor & 0xff00) | divisor; |
|---|
| 206 | + /* Determine corresponding divisor, rounding down. */ |
|---|
| 207 | + clk_div = CH341_CLK_DIV(ps, fact); |
|---|
| 208 | + div = CH341_CLKRATE / (clk_div * speed); |
|---|
| 209 | + |
|---|
| 210 | + /* Some devices require a lower base clock if ps < 3. */ |
|---|
| 211 | + if (ps < 3 && (priv->quirks & CH341_QUIRK_LIMITED_PRESCALER)) |
|---|
| 212 | + force_fact0 = true; |
|---|
| 213 | + |
|---|
| 214 | + /* Halve base clock (fact = 0) if required. */ |
|---|
| 215 | + if (div < 9 || div > 255 || force_fact0) { |
|---|
| 216 | + div /= 2; |
|---|
| 217 | + clk_div *= 2; |
|---|
| 218 | + fact = 0; |
|---|
| 219 | + } |
|---|
| 220 | + |
|---|
| 221 | + if (div < 2) |
|---|
| 222 | + return -EINVAL; |
|---|
| 223 | + |
|---|
| 224 | + /* |
|---|
| 225 | + * Pick next divisor if resulting rate is closer to the requested one, |
|---|
| 226 | + * scale up to avoid rounding errors on low rates. |
|---|
| 227 | + */ |
|---|
| 228 | + if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >= |
|---|
| 229 | + 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) |
|---|
| 230 | + div++; |
|---|
| 231 | + |
|---|
| 232 | + /* |
|---|
| 233 | + * Prefer lower base clock (fact = 0) if even divisor. |
|---|
| 234 | + * |
|---|
| 235 | + * Note that this makes the receiver more tolerant to errors. |
|---|
| 236 | + */ |
|---|
| 237 | + if (fact == 1 && div % 2 == 0) { |
|---|
| 238 | + div /= 2; |
|---|
| 239 | + fact = 0; |
|---|
| 240 | + } |
|---|
| 241 | + |
|---|
| 242 | + return (0x100 - div) << 8 | fact << 2 | ps; |
|---|
| 243 | +} |
|---|
| 244 | + |
|---|
| 245 | +static int ch341_set_baudrate_lcr(struct usb_device *dev, |
|---|
| 246 | + struct ch341_private *priv, |
|---|
| 247 | + speed_t baud_rate, u8 lcr) |
|---|
| 248 | +{ |
|---|
| 249 | + int val; |
|---|
| 250 | + int r; |
|---|
| 251 | + |
|---|
| 252 | + if (!baud_rate) |
|---|
| 253 | + return -EINVAL; |
|---|
| 254 | + |
|---|
| 255 | + val = ch341_get_divisor(priv, baud_rate); |
|---|
| 256 | + if (val < 0) |
|---|
| 257 | + return -EINVAL; |
|---|
| 173 | 258 | |
|---|
| 174 | 259 | /* |
|---|
| 175 | 260 | * CH341A buffers data until a full endpoint-size packet (32 bytes) |
|---|
| 176 | 261 | * has been received unless bit 7 is set. |
|---|
| 262 | + * |
|---|
| 263 | + * At least one device with version 0x27 appears to have this bit |
|---|
| 264 | + * inverted. |
|---|
| 177 | 265 | */ |
|---|
| 178 | | - a |= BIT(7); |
|---|
| 266 | + if (priv->version > 0x27) |
|---|
| 267 | + val |= BIT(7); |
|---|
| 179 | 268 | |
|---|
| 180 | | - r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a); |
|---|
| 269 | + r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
|---|
| 270 | + CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, |
|---|
| 271 | + val); |
|---|
| 181 | 272 | if (r) |
|---|
| 182 | 273 | return r; |
|---|
| 183 | 274 | |
|---|
| 184 | | - r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr); |
|---|
| 275 | + /* |
|---|
| 276 | + * Chip versions before version 0x30 as read using |
|---|
| 277 | + * CH341_REQ_READ_VERSION used separate registers for line control |
|---|
| 278 | + * (stop bits, parity and word length). Version 0x30 and above use |
|---|
| 279 | + * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. |
|---|
| 280 | + */ |
|---|
| 281 | + if (priv->version < 0x30) |
|---|
| 282 | + return 0; |
|---|
| 283 | + |
|---|
| 284 | + r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
|---|
| 285 | + CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr); |
|---|
| 185 | 286 | if (r) |
|---|
| 186 | 287 | return r; |
|---|
| 187 | 288 | |
|---|
| .. | .. |
|---|
| 232 | 333 | r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size); |
|---|
| 233 | 334 | if (r < 0) |
|---|
| 234 | 335 | goto out; |
|---|
| 235 | | - dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]); |
|---|
| 336 | + |
|---|
| 337 | + priv->version = buffer[0]; |
|---|
| 338 | + dev_dbg(&dev->dev, "Chip version: 0x%02x\n", priv->version); |
|---|
| 236 | 339 | |
|---|
| 237 | 340 | r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0); |
|---|
| 238 | 341 | if (r < 0) |
|---|
| 239 | 342 | goto out; |
|---|
| 240 | 343 | |
|---|
| 241 | | - r = ch341_set_baudrate_lcr(dev, priv, priv->lcr); |
|---|
| 344 | + r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr); |
|---|
| 242 | 345 | if (r < 0) |
|---|
| 243 | 346 | goto out; |
|---|
| 244 | 347 | |
|---|
| 245 | 348 | r = ch341_set_handshake(dev, priv->mcr); |
|---|
| 246 | 349 | |
|---|
| 247 | 350 | out: kfree(buffer); |
|---|
| 351 | + return r; |
|---|
| 352 | +} |
|---|
| 353 | + |
|---|
| 354 | +static int ch341_detect_quirks(struct usb_serial_port *port) |
|---|
| 355 | +{ |
|---|
| 356 | + struct ch341_private *priv = usb_get_serial_port_data(port); |
|---|
| 357 | + struct usb_device *udev = port->serial->dev; |
|---|
| 358 | + const unsigned int size = 2; |
|---|
| 359 | + unsigned long quirks = 0; |
|---|
| 360 | + char *buffer; |
|---|
| 361 | + int r; |
|---|
| 362 | + |
|---|
| 363 | + buffer = kmalloc(size, GFP_KERNEL); |
|---|
| 364 | + if (!buffer) |
|---|
| 365 | + return -ENOMEM; |
|---|
| 366 | + |
|---|
| 367 | + /* |
|---|
| 368 | + * A subset of CH34x devices does not support all features. The |
|---|
| 369 | + * prescaler is limited and there is no support for sending a RS232 |
|---|
| 370 | + * break condition. A read failure when trying to set up the latter is |
|---|
| 371 | + * used to detect these devices. |
|---|
| 372 | + */ |
|---|
| 373 | + r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), CH341_REQ_READ_REG, |
|---|
| 374 | + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
|---|
| 375 | + CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); |
|---|
| 376 | + if (r == -EPIPE) { |
|---|
| 377 | + dev_info(&port->dev, "break control not supported, using simulated break\n"); |
|---|
| 378 | + quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; |
|---|
| 379 | + r = 0; |
|---|
| 380 | + goto out; |
|---|
| 381 | + } |
|---|
| 382 | + |
|---|
| 383 | + if (r != size) { |
|---|
| 384 | + if (r >= 0) |
|---|
| 385 | + r = -EIO; |
|---|
| 386 | + dev_err(&port->dev, "failed to read break control: %d\n", r); |
|---|
| 387 | + goto out; |
|---|
| 388 | + } |
|---|
| 389 | + |
|---|
| 390 | + r = 0; |
|---|
| 391 | +out: |
|---|
| 392 | + kfree(buffer); |
|---|
| 393 | + |
|---|
| 394 | + if (quirks) { |
|---|
| 395 | + dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks); |
|---|
| 396 | + priv->quirks |= quirks; |
|---|
| 397 | + } |
|---|
| 398 | + |
|---|
| 248 | 399 | return r; |
|---|
| 249 | 400 | } |
|---|
| 250 | 401 | |
|---|
| .. | .. |
|---|
| 270 | 421 | goto error; |
|---|
| 271 | 422 | |
|---|
| 272 | 423 | usb_set_serial_port_data(port, priv); |
|---|
| 424 | + |
|---|
| 425 | + r = ch341_detect_quirks(port); |
|---|
| 426 | + if (r < 0) |
|---|
| 427 | + goto error; |
|---|
| 428 | + |
|---|
| 273 | 429 | return 0; |
|---|
| 274 | 430 | |
|---|
| 275 | 431 | error: kfree(priv); |
|---|
| .. | .. |
|---|
| 400 | 556 | if (baud_rate) { |
|---|
| 401 | 557 | priv->baud_rate = baud_rate; |
|---|
| 402 | 558 | |
|---|
| 403 | | - r = ch341_set_baudrate_lcr(port->serial->dev, priv, lcr); |
|---|
| 559 | + r = ch341_set_baudrate_lcr(port->serial->dev, priv, |
|---|
| 560 | + priv->baud_rate, lcr); |
|---|
| 404 | 561 | if (r < 0 && old_termios) { |
|---|
| 405 | 562 | priv->baud_rate = tty_termios_baud_rate(old_termios); |
|---|
| 406 | 563 | tty_termios_copy_hw(&tty->termios, old_termios); |
|---|
| .. | .. |
|---|
| 419 | 576 | ch341_set_handshake(port->serial->dev, priv->mcr); |
|---|
| 420 | 577 | } |
|---|
| 421 | 578 | |
|---|
| 579 | +/* |
|---|
| 580 | + * A subset of all CH34x devices don't support a real break condition and |
|---|
| 581 | + * reading CH341_REG_BREAK fails (see also ch341_detect_quirks). This function |
|---|
| 582 | + * simulates a break condition by lowering the baud rate to the minimum |
|---|
| 583 | + * supported by the hardware upon enabling the break condition and sending |
|---|
| 584 | + * a NUL byte. |
|---|
| 585 | + * |
|---|
| 586 | + * Incoming data is corrupted while the break condition is being simulated. |
|---|
| 587 | + * |
|---|
| 588 | + * Normally the duration of the break condition can be controlled individually |
|---|
| 589 | + * by userspace using TIOCSBRK and TIOCCBRK or by passing an argument to |
|---|
| 590 | + * TCSBRKP. Due to how the simulation is implemented the duration can't be |
|---|
| 591 | + * controlled. The duration is always about (1s / 46bd * 9bit) = 196ms. |
|---|
| 592 | + */ |
|---|
| 593 | +static void ch341_simulate_break(struct tty_struct *tty, int break_state) |
|---|
| 594 | +{ |
|---|
| 595 | + struct usb_serial_port *port = tty->driver_data; |
|---|
| 596 | + struct ch341_private *priv = usb_get_serial_port_data(port); |
|---|
| 597 | + unsigned long now, delay; |
|---|
| 598 | + int r; |
|---|
| 599 | + |
|---|
| 600 | + if (break_state != 0) { |
|---|
| 601 | + dev_dbg(&port->dev, "enter break state requested\n"); |
|---|
| 602 | + |
|---|
| 603 | + r = ch341_set_baudrate_lcr(port->serial->dev, priv, |
|---|
| 604 | + CH341_MIN_BPS, |
|---|
| 605 | + CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8); |
|---|
| 606 | + if (r < 0) { |
|---|
| 607 | + dev_err(&port->dev, |
|---|
| 608 | + "failed to change baud rate to %u: %d\n", |
|---|
| 609 | + CH341_MIN_BPS, r); |
|---|
| 610 | + goto restore; |
|---|
| 611 | + } |
|---|
| 612 | + |
|---|
| 613 | + r = tty_put_char(tty, '\0'); |
|---|
| 614 | + if (r < 0) { |
|---|
| 615 | + dev_err(&port->dev, |
|---|
| 616 | + "failed to write NUL byte for simulated break condition: %d\n", |
|---|
| 617 | + r); |
|---|
| 618 | + goto restore; |
|---|
| 619 | + } |
|---|
| 620 | + |
|---|
| 621 | + /* |
|---|
| 622 | + * Compute expected transmission duration including safety |
|---|
| 623 | + * margin. The original baud rate is only restored after the |
|---|
| 624 | + * computed point in time. |
|---|
| 625 | + * |
|---|
| 626 | + * 11 bits = 1 start, 8 data, 1 stop, 1 margin |
|---|
| 627 | + */ |
|---|
| 628 | + priv->break_end = jiffies + (11 * HZ / CH341_MIN_BPS); |
|---|
| 629 | + |
|---|
| 630 | + return; |
|---|
| 631 | + } |
|---|
| 632 | + |
|---|
| 633 | + dev_dbg(&port->dev, "leave break state requested\n"); |
|---|
| 634 | + |
|---|
| 635 | + now = jiffies; |
|---|
| 636 | + |
|---|
| 637 | + if (time_before(now, priv->break_end)) { |
|---|
| 638 | + /* Wait until NUL byte is written */ |
|---|
| 639 | + delay = priv->break_end - now; |
|---|
| 640 | + dev_dbg(&port->dev, |
|---|
| 641 | + "wait %d ms while transmitting NUL byte at %u baud\n", |
|---|
| 642 | + jiffies_to_msecs(delay), CH341_MIN_BPS); |
|---|
| 643 | + schedule_timeout_interruptible(delay); |
|---|
| 644 | + } |
|---|
| 645 | + |
|---|
| 646 | +restore: |
|---|
| 647 | + /* Restore original baud rate */ |
|---|
| 648 | + r = ch341_set_baudrate_lcr(port->serial->dev, priv, priv->baud_rate, |
|---|
| 649 | + priv->lcr); |
|---|
| 650 | + if (r < 0) |
|---|
| 651 | + dev_err(&port->dev, |
|---|
| 652 | + "restoring original baud rate of %u failed: %d\n", |
|---|
| 653 | + priv->baud_rate, r); |
|---|
| 654 | +} |
|---|
| 655 | + |
|---|
| 422 | 656 | static void ch341_break_ctl(struct tty_struct *tty, int break_state) |
|---|
| 423 | 657 | { |
|---|
| 424 | 658 | const uint16_t ch341_break_reg = |
|---|
| 425 | 659 | ((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK; |
|---|
| 426 | 660 | struct usb_serial_port *port = tty->driver_data; |
|---|
| 661 | + struct ch341_private *priv = usb_get_serial_port_data(port); |
|---|
| 427 | 662 | int r; |
|---|
| 428 | 663 | uint16_t reg_contents; |
|---|
| 429 | 664 | uint8_t *break_reg; |
|---|
| 430 | 665 | |
|---|
| 666 | + if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) { |
|---|
| 667 | + ch341_simulate_break(tty, break_state); |
|---|
| 668 | + return; |
|---|
| 669 | + } |
|---|
| 670 | + |
|---|
| 431 | 671 | break_reg = kmalloc(2, GFP_KERNEL); |
|---|
| 432 | 672 | if (!break_reg) |
|---|
| 433 | 673 | return; |
|---|