1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> |
4 | * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de> |
5 | * Copyright 2009, Boris Hajduk <boris@hajduk.org> |
6 | * |
7 | * ch341.c implements a serial port driver for the Winchiphead CH341. |
8 | * |
9 | * The CH341 device can be used to implement an RS232 asynchronous |
10 | * serial port, an IEEE-1284 parallel printer port or a memory-like |
11 | * interface. In all cases the CH341 supports an I2C interface as well. |
12 | * This driver only supports the asynchronous serial interface. |
13 | */ |
14 | |
15 | #include <linux/kernel.h> |
16 | #include <linux/tty.h> |
17 | #include <linux/module.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/usb.h> |
20 | #include <linux/usb/serial.h> |
21 | #include <linux/serial.h> |
22 | #include <linux/unaligned.h> |
23 | |
24 | #define DEFAULT_BAUD_RATE 9600 |
25 | #define DEFAULT_TIMEOUT 1000 |
26 | |
27 | /* flags for IO-Bits */ |
28 | #define CH341_BIT_RTS (1 << 6) |
29 | #define CH341_BIT_DTR (1 << 5) |
30 | |
31 | /******************************/ |
32 | /* interrupt pipe definitions */ |
33 | /******************************/ |
34 | /* always 4 interrupt bytes */ |
35 | /* first irq byte normally 0x08 */ |
36 | /* second irq byte base 0x7d + below */ |
37 | /* third irq byte base 0x94 + below */ |
38 | /* fourth irq byte normally 0xee */ |
39 | |
40 | /* second interrupt byte */ |
41 | #define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ |
42 | |
43 | /* status returned in third interrupt answer byte, inverted in data |
44 | from irq */ |
45 | #define CH341_BIT_CTS 0x01 |
46 | #define CH341_BIT_DSR 0x02 |
47 | #define CH341_BIT_RI 0x04 |
48 | #define CH341_BIT_DCD 0x08 |
49 | #define CH341_BITS_MODEM_STAT 0x0f /* all bits */ |
50 | |
51 | /* Break support - the information used to implement this was gleaned from |
52 | * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. |
53 | */ |
54 | |
55 | #define CH341_REQ_READ_VERSION 0x5F |
56 | #define CH341_REQ_WRITE_REG 0x9A |
57 | #define CH341_REQ_READ_REG 0x95 |
58 | #define CH341_REQ_SERIAL_INIT 0xA1 |
59 | #define CH341_REQ_MODEM_CTRL 0xA4 |
60 | |
61 | #define CH341_REG_BREAK 0x05 |
62 | #define CH341_REG_PRESCALER 0x12 |
63 | #define CH341_REG_DIVISOR 0x13 |
64 | #define CH341_REG_LCR 0x18 |
65 | #define CH341_REG_LCR2 0x25 |
66 | #define CH341_REG_FLOW_CTL 0x27 |
67 | |
68 | #define CH341_NBREAK_BITS 0x01 |
69 | |
70 | #define CH341_LCR_ENABLE_RX 0x80 |
71 | #define CH341_LCR_ENABLE_TX 0x40 |
72 | #define CH341_LCR_MARK_SPACE 0x20 |
73 | #define CH341_LCR_PAR_EVEN 0x10 |
74 | #define CH341_LCR_ENABLE_PAR 0x08 |
75 | #define CH341_LCR_STOP_BITS_2 0x04 |
76 | #define CH341_LCR_CS8 0x03 |
77 | #define CH341_LCR_CS7 0x02 |
78 | #define CH341_LCR_CS6 0x01 |
79 | #define CH341_LCR_CS5 0x00 |
80 | |
81 | #define CH341_FLOW_CTL_NONE 0x00 |
82 | #define CH341_FLOW_CTL_RTSCTS 0x01 |
83 | |
84 | #define CH341_QUIRK_LIMITED_PRESCALER BIT(0) |
85 | #define CH341_QUIRK_SIMULATE_BREAK BIT(1) |
86 | |
87 | static const struct usb_device_id id_table[] = { |
88 | { USB_DEVICE(0x1a86, 0x5523) }, |
89 | { USB_DEVICE(0x1a86, 0x7522) }, |
90 | { USB_DEVICE(0x1a86, 0x7523) }, |
91 | { USB_DEVICE(0x2184, 0x0057) }, |
92 | { USB_DEVICE(0x4348, 0x5523) }, |
93 | { USB_DEVICE(0x9986, 0x7523) }, |
94 | { }, |
95 | }; |
96 | MODULE_DEVICE_TABLE(usb, id_table); |
97 | |
98 | struct ch341_private { |
99 | spinlock_t lock; /* access lock */ |
100 | unsigned baud_rate; /* set baud rate */ |
101 | u8 mcr; |
102 | u8 msr; |
103 | u8 lcr; |
104 | |
105 | unsigned long quirks; |
106 | u8 version; |
107 | |
108 | unsigned long break_end; |
109 | }; |
110 | |
111 | static void ch341_set_termios(struct tty_struct *tty, |
112 | struct usb_serial_port *port, |
113 | const struct ktermios *old_termios); |
114 | |
115 | static int ch341_control_out(struct usb_device *dev, u8 request, |
116 | u16 value, u16 index) |
117 | { |
118 | int r; |
119 | |
120 | dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x)\n", __func__, |
121 | request, value, index); |
122 | |
123 | r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, |
124 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
125 | value, index, NULL, size: 0, DEFAULT_TIMEOUT); |
126 | if (r < 0) |
127 | dev_err(&dev->dev, "failed to send control message: %d\n", r); |
128 | |
129 | return r; |
130 | } |
131 | |
132 | static int ch341_control_in(struct usb_device *dev, |
133 | u8 request, u16 value, u16 index, |
134 | char *buf, unsigned bufsize) |
135 | { |
136 | int r; |
137 | |
138 | dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x,%u)\n", __func__, |
139 | request, value, index, bufsize); |
140 | |
141 | r = usb_control_msg_recv(dev, endpoint: 0, request, |
142 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
143 | value, index, data: buf, size: bufsize, DEFAULT_TIMEOUT, |
144 | GFP_KERNEL); |
145 | if (r) { |
146 | dev_err(&dev->dev, "failed to receive control message: %d\n", |
147 | r); |
148 | return r; |
149 | } |
150 | |
151 | return 0; |
152 | } |
153 | |
154 | #define CH341_CLKRATE 48000000 |
155 | #define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) |
156 | #define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) |
157 | |
158 | static const speed_t ch341_min_rates[] = { |
159 | CH341_MIN_RATE(0), |
160 | CH341_MIN_RATE(1), |
161 | CH341_MIN_RATE(2), |
162 | CH341_MIN_RATE(3), |
163 | }; |
164 | |
165 | /* Supported range is 46 to 3000000 bps. */ |
166 | #define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) |
167 | #define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) |
168 | |
169 | /* |
170 | * The device line speed is given by the following equation: |
171 | * |
172 | * baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where |
173 | * |
174 | * 0 <= ps <= 3, |
175 | * 0 <= fact <= 1, |
176 | * 2 <= div <= 256 if fact = 0, or |
177 | * 9 <= div <= 256 if fact = 1 |
178 | */ |
179 | static int ch341_get_divisor(struct ch341_private *priv, speed_t speed) |
180 | { |
181 | unsigned int fact, div, clk_div; |
182 | bool force_fact0 = false; |
183 | int ps; |
184 | |
185 | /* |
186 | * Clamp to supported range, this makes the (ps < 0) and (div < 2) |
187 | * sanity checks below redundant. |
188 | */ |
189 | speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); |
190 | |
191 | /* |
192 | * Start with highest possible base clock (fact = 1) that will give a |
193 | * divisor strictly less than 512. |
194 | */ |
195 | fact = 1; |
196 | for (ps = 3; ps >= 0; ps--) { |
197 | if (speed > ch341_min_rates[ps]) |
198 | break; |
199 | } |
200 | |
201 | if (ps < 0) |
202 | return -EINVAL; |
203 | |
204 | /* Determine corresponding divisor, rounding down. */ |
205 | clk_div = CH341_CLK_DIV(ps, fact); |
206 | div = CH341_CLKRATE / (clk_div * speed); |
207 | |
208 | /* Some devices require a lower base clock if ps < 3. */ |
209 | if (ps < 3 && (priv->quirks & CH341_QUIRK_LIMITED_PRESCALER)) |
210 | force_fact0 = true; |
211 | |
212 | /* Halve base clock (fact = 0) if required. */ |
213 | if (div < 9 || div > 255 || force_fact0) { |
214 | div /= 2; |
215 | clk_div *= 2; |
216 | fact = 0; |
217 | } |
218 | |
219 | if (div < 2) |
220 | return -EINVAL; |
221 | |
222 | /* |
223 | * Pick next divisor if resulting rate is closer to the requested one, |
224 | * scale up to avoid rounding errors on low rates. |
225 | */ |
226 | if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >= |
227 | 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) |
228 | div++; |
229 | |
230 | /* |
231 | * Prefer lower base clock (fact = 0) if even divisor. |
232 | * |
233 | * Note that this makes the receiver more tolerant to errors. |
234 | */ |
235 | if (fact == 1 && div % 2 == 0) { |
236 | div /= 2; |
237 | fact = 0; |
238 | } |
239 | |
240 | return (0x100 - div) << 8 | fact << 2 | ps; |
241 | } |
242 | |
243 | static int ch341_set_baudrate_lcr(struct usb_device *dev, |
244 | struct ch341_private *priv, |
245 | speed_t baud_rate, u8 lcr) |
246 | { |
247 | int val; |
248 | int r; |
249 | |
250 | if (!baud_rate) |
251 | return -EINVAL; |
252 | |
253 | val = ch341_get_divisor(priv, speed: baud_rate); |
254 | if (val < 0) |
255 | return -EINVAL; |
256 | |
257 | /* |
258 | * CH341A buffers data until a full endpoint-size packet (32 bytes) |
259 | * has been received unless bit 7 is set. |
260 | * |
261 | * At least one device with version 0x27 appears to have this bit |
262 | * inverted. |
263 | */ |
264 | if (priv->version > 0x27) |
265 | val |= BIT(7); |
266 | |
267 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
268 | CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, |
269 | index: val); |
270 | if (r) |
271 | return r; |
272 | |
273 | /* |
274 | * Chip versions before version 0x30 as read using |
275 | * CH341_REQ_READ_VERSION used separate registers for line control |
276 | * (stop bits, parity and word length). Version 0x30 and above use |
277 | * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. |
278 | */ |
279 | if (priv->version < 0x30) |
280 | return 0; |
281 | |
282 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
283 | CH341_REG_LCR2 << 8 | CH341_REG_LCR, index: lcr); |
284 | if (r) |
285 | return r; |
286 | |
287 | return r; |
288 | } |
289 | |
290 | static int ch341_set_handshake(struct usb_device *dev, u8 control) |
291 | { |
292 | return ch341_control_out(dev, CH341_REQ_MODEM_CTRL, value: ~control, index: 0); |
293 | } |
294 | |
295 | static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv) |
296 | { |
297 | const unsigned int size = 2; |
298 | u8 buffer[2]; |
299 | int r; |
300 | unsigned long flags; |
301 | |
302 | r = ch341_control_in(dev, CH341_REQ_READ_REG, value: 0x0706, index: 0, buf: buffer, bufsize: size); |
303 | if (r) |
304 | return r; |
305 | |
306 | spin_lock_irqsave(&priv->lock, flags); |
307 | priv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT; |
308 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
309 | |
310 | return 0; |
311 | } |
312 | |
313 | /* -------------------------------------------------------------------------- */ |
314 | |
315 | static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) |
316 | { |
317 | const unsigned int size = 2; |
318 | u8 buffer[2]; |
319 | int r; |
320 | |
321 | /* expect two bytes 0x27 0x00 */ |
322 | r = ch341_control_in(dev, CH341_REQ_READ_VERSION, value: 0, index: 0, buf: buffer, bufsize: size); |
323 | if (r) |
324 | return r; |
325 | |
326 | priv->version = buffer[0]; |
327 | dev_dbg(&dev->dev, "Chip version: 0x%02x\n", priv->version); |
328 | |
329 | r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, value: 0, index: 0); |
330 | if (r < 0) |
331 | return r; |
332 | |
333 | r = ch341_set_baudrate_lcr(dev, priv, baud_rate: priv->baud_rate, lcr: priv->lcr); |
334 | if (r < 0) |
335 | return r; |
336 | |
337 | r = ch341_set_handshake(dev, control: priv->mcr); |
338 | if (r < 0) |
339 | return r; |
340 | |
341 | return 0; |
342 | } |
343 | |
344 | static int ch341_detect_quirks(struct usb_serial_port *port) |
345 | { |
346 | struct ch341_private *priv = usb_get_serial_port_data(port); |
347 | struct usb_device *udev = port->serial->dev; |
348 | const unsigned int size = 2; |
349 | unsigned long quirks = 0; |
350 | u8 buffer[2]; |
351 | int r; |
352 | |
353 | /* |
354 | * A subset of CH34x devices does not support all features. The |
355 | * prescaler is limited and there is no support for sending a RS232 |
356 | * break condition. A read failure when trying to set up the latter is |
357 | * used to detect these devices. |
358 | */ |
359 | r = usb_control_msg_recv(dev: udev, endpoint: 0, CH341_REQ_READ_REG, |
360 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
361 | CH341_REG_BREAK, index: 0, data: &buffer, size, |
362 | DEFAULT_TIMEOUT, GFP_KERNEL); |
363 | if (r == -EPIPE) { |
364 | dev_info(&port->dev, "break control not supported, using simulated break\n"); |
365 | quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; |
366 | r = 0; |
367 | } else if (r) { |
368 | dev_err(&port->dev, "failed to read break control: %d\n", r); |
369 | } |
370 | |
371 | if (quirks) { |
372 | dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks); |
373 | priv->quirks |= quirks; |
374 | } |
375 | |
376 | return r; |
377 | } |
378 | |
379 | static int ch341_port_probe(struct usb_serial_port *port) |
380 | { |
381 | struct ch341_private *priv; |
382 | int r; |
383 | |
384 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); |
385 | if (!priv) |
386 | return -ENOMEM; |
387 | |
388 | spin_lock_init(&priv->lock); |
389 | priv->baud_rate = DEFAULT_BAUD_RATE; |
390 | /* |
391 | * Some CH340 devices appear unable to change the initial LCR |
392 | * settings, so set a sane 8N1 default. |
393 | */ |
394 | priv->lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8; |
395 | |
396 | r = ch341_configure(dev: port->serial->dev, priv); |
397 | if (r < 0) |
398 | goto error; |
399 | |
400 | usb_set_serial_port_data(port, data: priv); |
401 | |
402 | r = ch341_detect_quirks(port); |
403 | if (r < 0) |
404 | goto error; |
405 | |
406 | return 0; |
407 | |
408 | error: kfree(objp: priv); |
409 | return r; |
410 | } |
411 | |
412 | static void ch341_port_remove(struct usb_serial_port *port) |
413 | { |
414 | struct ch341_private *priv; |
415 | |
416 | priv = usb_get_serial_port_data(port); |
417 | kfree(objp: priv); |
418 | } |
419 | |
420 | static int ch341_carrier_raised(struct usb_serial_port *port) |
421 | { |
422 | struct ch341_private *priv = usb_get_serial_port_data(port); |
423 | if (priv->msr & CH341_BIT_DCD) |
424 | return 1; |
425 | return 0; |
426 | } |
427 | |
428 | static void ch341_dtr_rts(struct usb_serial_port *port, int on) |
429 | { |
430 | struct ch341_private *priv = usb_get_serial_port_data(port); |
431 | unsigned long flags; |
432 | |
433 | /* drop DTR and RTS */ |
434 | spin_lock_irqsave(&priv->lock, flags); |
435 | if (on) |
436 | priv->mcr |= CH341_BIT_RTS | CH341_BIT_DTR; |
437 | else |
438 | priv->mcr &= ~(CH341_BIT_RTS | CH341_BIT_DTR); |
439 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
440 | ch341_set_handshake(dev: port->serial->dev, control: priv->mcr); |
441 | } |
442 | |
443 | static void ch341_close(struct usb_serial_port *port) |
444 | { |
445 | usb_serial_generic_close(port); |
446 | usb_kill_urb(urb: port->interrupt_in_urb); |
447 | } |
448 | |
449 | |
450 | /* open this device, set default parameters */ |
451 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) |
452 | { |
453 | struct ch341_private *priv = usb_get_serial_port_data(port); |
454 | int r; |
455 | |
456 | if (tty) |
457 | ch341_set_termios(tty, port, NULL); |
458 | |
459 | dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__); |
460 | r = usb_submit_urb(urb: port->interrupt_in_urb, GFP_KERNEL); |
461 | if (r) { |
462 | dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n", |
463 | __func__, r); |
464 | return r; |
465 | } |
466 | |
467 | r = ch341_get_status(dev: port->serial->dev, priv); |
468 | if (r < 0) { |
469 | dev_err(&port->dev, "failed to read modem status: %d\n", r); |
470 | goto err_kill_interrupt_urb; |
471 | } |
472 | |
473 | r = usb_serial_generic_open(tty, port); |
474 | if (r) |
475 | goto err_kill_interrupt_urb; |
476 | |
477 | return 0; |
478 | |
479 | err_kill_interrupt_urb: |
480 | usb_kill_urb(urb: port->interrupt_in_urb); |
481 | |
482 | return r; |
483 | } |
484 | |
485 | static void ch341_set_flow_control(struct tty_struct *tty, |
486 | struct usb_serial_port *port, |
487 | const struct ktermios *old_termios) |
488 | { |
489 | u16 flow_ctl; |
490 | int r; |
491 | |
492 | if (C_CRTSCTS(tty)) |
493 | flow_ctl = CH341_FLOW_CTL_RTSCTS; |
494 | else |
495 | flow_ctl = CH341_FLOW_CTL_NONE; |
496 | |
497 | r = ch341_control_out(dev: port->serial->dev, |
498 | CH341_REQ_WRITE_REG, |
499 | value: (CH341_REG_FLOW_CTL << 8) | CH341_REG_FLOW_CTL, |
500 | index: (flow_ctl << 8) | flow_ctl); |
501 | if (r < 0 && old_termios) { |
502 | tty->termios.c_cflag &= ~CRTSCTS; |
503 | tty->termios.c_cflag |= (old_termios->c_cflag & CRTSCTS); |
504 | } |
505 | } |
506 | |
507 | /* Old_termios contains the original termios settings and |
508 | * tty->termios contains the new setting to be used. |
509 | */ |
510 | static void ch341_set_termios(struct tty_struct *tty, |
511 | struct usb_serial_port *port, |
512 | const struct ktermios *old_termios) |
513 | { |
514 | struct ch341_private *priv = usb_get_serial_port_data(port); |
515 | unsigned baud_rate; |
516 | unsigned long flags; |
517 | u8 lcr; |
518 | int r; |
519 | |
520 | /* redundant changes may cause the chip to lose bytes */ |
521 | if (old_termios && !tty_termios_hw_change(a: &tty->termios, b: old_termios)) |
522 | return; |
523 | |
524 | baud_rate = tty_get_baud_rate(tty); |
525 | |
526 | lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX; |
527 | |
528 | switch (C_CSIZE(tty)) { |
529 | case CS5: |
530 | lcr |= CH341_LCR_CS5; |
531 | break; |
532 | case CS6: |
533 | lcr |= CH341_LCR_CS6; |
534 | break; |
535 | case CS7: |
536 | lcr |= CH341_LCR_CS7; |
537 | break; |
538 | case CS8: |
539 | lcr |= CH341_LCR_CS8; |
540 | break; |
541 | } |
542 | |
543 | if (C_PARENB(tty)) { |
544 | lcr |= CH341_LCR_ENABLE_PAR; |
545 | if (C_PARODD(tty) == 0) |
546 | lcr |= CH341_LCR_PAR_EVEN; |
547 | if (C_CMSPAR(tty)) |
548 | lcr |= CH341_LCR_MARK_SPACE; |
549 | } |
550 | |
551 | if (C_CSTOPB(tty)) |
552 | lcr |= CH341_LCR_STOP_BITS_2; |
553 | |
554 | if (baud_rate) { |
555 | priv->baud_rate = baud_rate; |
556 | |
557 | r = ch341_set_baudrate_lcr(dev: port->serial->dev, priv, |
558 | baud_rate: priv->baud_rate, lcr); |
559 | if (r < 0 && old_termios) { |
560 | priv->baud_rate = tty_termios_baud_rate(termios: old_termios); |
561 | tty_termios_copy_hw(new: &tty->termios, old: old_termios); |
562 | } else if (r == 0) { |
563 | priv->lcr = lcr; |
564 | } |
565 | } |
566 | |
567 | spin_lock_irqsave(&priv->lock, flags); |
568 | if (C_BAUD(tty) == B0) |
569 | priv->mcr &= ~(CH341_BIT_DTR | CH341_BIT_RTS); |
570 | else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) |
571 | priv->mcr |= (CH341_BIT_DTR | CH341_BIT_RTS); |
572 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
573 | |
574 | ch341_set_handshake(dev: port->serial->dev, control: priv->mcr); |
575 | |
576 | ch341_set_flow_control(tty, port, old_termios); |
577 | } |
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 int 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, r2; |
599 | |
600 | if (break_state != 0) { |
601 | dev_dbg(&port->dev, "enter break state requested\n"); |
602 | |
603 | r = ch341_set_baudrate_lcr(dev: 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, c: '\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 0; |
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(timeout: delay); |
644 | } |
645 | |
646 | r = 0; |
647 | restore: |
648 | /* Restore original baud rate */ |
649 | r2 = ch341_set_baudrate_lcr(dev: port->serial->dev, priv, baud_rate: priv->baud_rate, |
650 | lcr: priv->lcr); |
651 | if (r2 < 0) { |
652 | dev_err(&port->dev, |
653 | "restoring original baud rate of %u failed: %d\n", |
654 | priv->baud_rate, r2); |
655 | return r2; |
656 | } |
657 | |
658 | return r; |
659 | } |
660 | |
661 | static int ch341_break_ctl(struct tty_struct *tty, int break_state) |
662 | { |
663 | const u16 ch341_break_reg = (CH341_REG_LCR << 8) | CH341_REG_BREAK; |
664 | struct usb_serial_port *port = tty->driver_data; |
665 | struct ch341_private *priv = usb_get_serial_port_data(port); |
666 | u16 reg_contents; |
667 | u8 break_reg[2]; |
668 | int r; |
669 | |
670 | if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) |
671 | return ch341_simulate_break(tty, break_state); |
672 | |
673 | r = ch341_control_in(dev: port->serial->dev, CH341_REQ_READ_REG, |
674 | value: ch341_break_reg, index: 0, buf: break_reg, bufsize: 2); |
675 | if (r) { |
676 | dev_err(&port->dev, "%s - USB control read error (%d)\n", |
677 | __func__, r); |
678 | if (r > 0) |
679 | r = -EIO; |
680 | return r; |
681 | } |
682 | dev_dbg(&port->dev, "%s - initial ch341 break register contents - reg1: %x, reg2: %x\n", |
683 | __func__, break_reg[0], break_reg[1]); |
684 | if (break_state != 0) { |
685 | dev_dbg(&port->dev, "%s - Enter break state requested\n", __func__); |
686 | break_reg[0] &= ~CH341_NBREAK_BITS; |
687 | break_reg[1] &= ~CH341_LCR_ENABLE_TX; |
688 | } else { |
689 | dev_dbg(&port->dev, "%s - Leave break state requested\n", __func__); |
690 | break_reg[0] |= CH341_NBREAK_BITS; |
691 | break_reg[1] |= CH341_LCR_ENABLE_TX; |
692 | } |
693 | dev_dbg(&port->dev, "%s - New ch341 break register contents - reg1: %x, reg2: %x\n", |
694 | __func__, break_reg[0], break_reg[1]); |
695 | reg_contents = get_unaligned_le16(p: break_reg); |
696 | r = ch341_control_out(dev: port->serial->dev, CH341_REQ_WRITE_REG, |
697 | value: ch341_break_reg, index: reg_contents); |
698 | if (r < 0) { |
699 | dev_err(&port->dev, "%s - USB control write error (%d)\n", |
700 | __func__, r); |
701 | return r; |
702 | } |
703 | |
704 | return 0; |
705 | } |
706 | |
707 | static int ch341_tiocmset(struct tty_struct *tty, |
708 | unsigned int set, unsigned int clear) |
709 | { |
710 | struct usb_serial_port *port = tty->driver_data; |
711 | struct ch341_private *priv = usb_get_serial_port_data(port); |
712 | unsigned long flags; |
713 | u8 control; |
714 | |
715 | spin_lock_irqsave(&priv->lock, flags); |
716 | if (set & TIOCM_RTS) |
717 | priv->mcr |= CH341_BIT_RTS; |
718 | if (set & TIOCM_DTR) |
719 | priv->mcr |= CH341_BIT_DTR; |
720 | if (clear & TIOCM_RTS) |
721 | priv->mcr &= ~CH341_BIT_RTS; |
722 | if (clear & TIOCM_DTR) |
723 | priv->mcr &= ~CH341_BIT_DTR; |
724 | control = priv->mcr; |
725 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
726 | |
727 | return ch341_set_handshake(dev: port->serial->dev, control); |
728 | } |
729 | |
730 | static void ch341_update_status(struct usb_serial_port *port, |
731 | unsigned char *data, size_t len) |
732 | { |
733 | struct ch341_private *priv = usb_get_serial_port_data(port); |
734 | struct tty_struct *tty; |
735 | unsigned long flags; |
736 | u8 status; |
737 | u8 delta; |
738 | |
739 | if (len < 4) |
740 | return; |
741 | |
742 | status = ~data[2] & CH341_BITS_MODEM_STAT; |
743 | |
744 | spin_lock_irqsave(&priv->lock, flags); |
745 | delta = status ^ priv->msr; |
746 | priv->msr = status; |
747 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
748 | |
749 | if (data[1] & CH341_MULT_STAT) |
750 | dev_dbg(&port->dev, "%s - multiple status change\n", __func__); |
751 | |
752 | if (!delta) |
753 | return; |
754 | |
755 | if (delta & CH341_BIT_CTS) |
756 | port->icount.cts++; |
757 | if (delta & CH341_BIT_DSR) |
758 | port->icount.dsr++; |
759 | if (delta & CH341_BIT_RI) |
760 | port->icount.rng++; |
761 | if (delta & CH341_BIT_DCD) { |
762 | port->icount.dcd++; |
763 | tty = tty_port_tty_get(port: &port->port); |
764 | if (tty) { |
765 | usb_serial_handle_dcd_change(usb_port: port, tty, |
766 | status: status & CH341_BIT_DCD); |
767 | tty_kref_put(tty); |
768 | } |
769 | } |
770 | |
771 | wake_up_interruptible(&port->port.delta_msr_wait); |
772 | } |
773 | |
774 | static void ch341_read_int_callback(struct urb *urb) |
775 | { |
776 | struct usb_serial_port *port = urb->context; |
777 | unsigned char *data = urb->transfer_buffer; |
778 | unsigned int len = urb->actual_length; |
779 | int status; |
780 | |
781 | switch (urb->status) { |
782 | case 0: |
783 | /* success */ |
784 | break; |
785 | case -ECONNRESET: |
786 | case -ENOENT: |
787 | case -ESHUTDOWN: |
788 | /* this urb is terminated, clean up */ |
789 | dev_dbg(&urb->dev->dev, "%s - urb shutting down: %d\n", |
790 | __func__, urb->status); |
791 | return; |
792 | default: |
793 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", |
794 | __func__, urb->status); |
795 | goto exit; |
796 | } |
797 | |
798 | usb_serial_debug_data(dev: &port->dev, function: __func__, size: len, data); |
799 | ch341_update_status(port, data, len); |
800 | exit: |
801 | status = usb_submit_urb(urb, GFP_ATOMIC); |
802 | if (status) { |
803 | dev_err(&urb->dev->dev, "%s - usb_submit_urb failed: %d\n", |
804 | __func__, status); |
805 | } |
806 | } |
807 | |
808 | static int ch341_tiocmget(struct tty_struct *tty) |
809 | { |
810 | struct usb_serial_port *port = tty->driver_data; |
811 | struct ch341_private *priv = usb_get_serial_port_data(port); |
812 | unsigned long flags; |
813 | u8 mcr; |
814 | u8 status; |
815 | unsigned int result; |
816 | |
817 | spin_lock_irqsave(&priv->lock, flags); |
818 | mcr = priv->mcr; |
819 | status = priv->msr; |
820 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
821 | |
822 | result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0) |
823 | | ((mcr & CH341_BIT_RTS) ? TIOCM_RTS : 0) |
824 | | ((status & CH341_BIT_CTS) ? TIOCM_CTS : 0) |
825 | | ((status & CH341_BIT_DSR) ? TIOCM_DSR : 0) |
826 | | ((status & CH341_BIT_RI) ? TIOCM_RI : 0) |
827 | | ((status & CH341_BIT_DCD) ? TIOCM_CD : 0); |
828 | |
829 | dev_dbg(&port->dev, "%s - result = %x\n", __func__, result); |
830 | |
831 | return result; |
832 | } |
833 | |
834 | static int ch341_reset_resume(struct usb_serial *serial) |
835 | { |
836 | struct usb_serial_port *port = serial->port[0]; |
837 | struct ch341_private *priv; |
838 | int ret; |
839 | |
840 | priv = usb_get_serial_port_data(port); |
841 | if (!priv) |
842 | return 0; |
843 | |
844 | /* reconfigure ch341 serial port after bus-reset */ |
845 | ch341_configure(dev: serial->dev, priv); |
846 | |
847 | if (tty_port_initialized(port: &port->port)) { |
848 | ret = usb_submit_urb(urb: port->interrupt_in_urb, GFP_NOIO); |
849 | if (ret) { |
850 | dev_err(&port->dev, "failed to submit interrupt urb: %d\n", |
851 | ret); |
852 | return ret; |
853 | } |
854 | |
855 | ret = ch341_get_status(dev: port->serial->dev, priv); |
856 | if (ret < 0) { |
857 | dev_err(&port->dev, "failed to read modem status: %d\n", |
858 | ret); |
859 | } |
860 | } |
861 | |
862 | return usb_serial_generic_resume(serial); |
863 | } |
864 | |
865 | static struct usb_serial_driver ch341_device = { |
866 | .driver = { |
867 | .name = "ch341-uart", |
868 | }, |
869 | .id_table = id_table, |
870 | .num_ports = 1, |
871 | .open = ch341_open, |
872 | .dtr_rts = ch341_dtr_rts, |
873 | .carrier_raised = ch341_carrier_raised, |
874 | .close = ch341_close, |
875 | .set_termios = ch341_set_termios, |
876 | .break_ctl = ch341_break_ctl, |
877 | .tiocmget = ch341_tiocmget, |
878 | .tiocmset = ch341_tiocmset, |
879 | .tiocmiwait = usb_serial_generic_tiocmiwait, |
880 | .read_int_callback = ch341_read_int_callback, |
881 | .port_probe = ch341_port_probe, |
882 | .port_remove = ch341_port_remove, |
883 | .reset_resume = ch341_reset_resume, |
884 | }; |
885 | |
886 | static struct usb_serial_driver * const serial_drivers[] = { |
887 | &ch341_device, NULL |
888 | }; |
889 | |
890 | module_usb_serial_driver(serial_drivers, id_table); |
891 | |
892 | MODULE_DESCRIPTION("Winchiphead CH341 USB Serial driver"); |
893 | MODULE_LICENSE("GPL v2"); |
894 |
Definitions
- id_table
- ch341_private
- ch341_control_out
- ch341_control_in
- ch341_min_rates
- ch341_get_divisor
- ch341_set_baudrate_lcr
- ch341_set_handshake
- ch341_get_status
- ch341_configure
- ch341_detect_quirks
- ch341_port_probe
- ch341_port_remove
- ch341_carrier_raised
- ch341_dtr_rts
- ch341_close
- ch341_open
- ch341_set_flow_control
- ch341_set_termios
- ch341_simulate_break
- ch341_break_ctl
- ch341_tiocmset
- ch341_update_status
- ch341_read_int_callback
- ch341_tiocmget
- ch341_reset_resume
- ch341_device
Improve your Profiling and Debugging skills
Find out more