.. | .. |
---|
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; |
---|