]> Git Repo - J-linux.git/blob - drivers/usb/serial/xr_serial.c
Merge tag 'orphan-handling-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[J-linux.git] / drivers / usb / serial / xr_serial.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * MaxLinear/Exar USB to Serial driver
4  *
5  * Copyright (c) 2020 Manivannan Sadhasivam <[email protected]>
6  *
7  * Based on the initial driver written by Patong Yang:
8  *
9  *   https://lore.kernel.org/r/20180404070634.nhspvmxcjwfgjkcv@advantechmxl-desktop
10  *
11  *   Copyright (c) 2018 Patong Yang <[email protected]>
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/tty.h>
18 #include <linux/usb.h>
19 #include <linux/usb/serial.h>
20
21 struct xr_txrx_clk_mask {
22         u16 tx;
23         u16 rx0;
24         u16 rx1;
25 };
26
27 #define XR_INT_OSC_HZ                   48000000U
28 #define XR21V141X_MIN_SPEED             46U
29 #define XR21V141X_MAX_SPEED             XR_INT_OSC_HZ
30
31 /* USB Requests */
32 #define XR21V141X_SET_REQ               0
33 #define XR21V141X_GET_REQ               1
34
35 #define XR21V141X_CLOCK_DIVISOR_0       0x04
36 #define XR21V141X_CLOCK_DIVISOR_1       0x05
37 #define XR21V141X_CLOCK_DIVISOR_2       0x06
38 #define XR21V141X_TX_CLOCK_MASK_0       0x07
39 #define XR21V141X_TX_CLOCK_MASK_1       0x08
40 #define XR21V141X_RX_CLOCK_MASK_0       0x09
41 #define XR21V141X_RX_CLOCK_MASK_1       0x0a
42
43 /* XR21V141X register blocks */
44 #define XR21V141X_UART_REG_BLOCK        0
45 #define XR21V141X_UM_REG_BLOCK          4
46 #define XR21V141X_UART_CUSTOM_BLOCK     0x66
47
48 /* XR21V141X UART Manager Registers */
49 #define XR21V141X_UM_FIFO_ENABLE_REG    0x10
50 #define XR21V141X_UM_ENABLE_TX_FIFO     0x01
51 #define XR21V141X_UM_ENABLE_RX_FIFO     0x02
52
53 #define XR21V141X_UM_RX_FIFO_RESET      0x18
54 #define XR21V141X_UM_TX_FIFO_RESET      0x1c
55
56 #define XR21V141X_UART_ENABLE_TX        0x1
57 #define XR21V141X_UART_ENABLE_RX        0x2
58
59 #define XR21V141X_UART_MODE_RI          BIT(0)
60 #define XR21V141X_UART_MODE_CD          BIT(1)
61 #define XR21V141X_UART_MODE_DSR         BIT(2)
62 #define XR21V141X_UART_MODE_DTR         BIT(3)
63 #define XR21V141X_UART_MODE_CTS         BIT(4)
64 #define XR21V141X_UART_MODE_RTS         BIT(5)
65
66 #define XR21V141X_UART_BREAK_ON         0xff
67 #define XR21V141X_UART_BREAK_OFF        0
68
69 #define XR21V141X_UART_DATA_MASK        GENMASK(3, 0)
70 #define XR21V141X_UART_DATA_7           0x7
71 #define XR21V141X_UART_DATA_8           0x8
72
73 #define XR21V141X_UART_PARITY_MASK      GENMASK(6, 4)
74 #define XR21V141X_UART_PARITY_SHIFT     4
75 #define XR21V141X_UART_PARITY_NONE      (0x0 << XR21V141X_UART_PARITY_SHIFT)
76 #define XR21V141X_UART_PARITY_ODD       (0x1 << XR21V141X_UART_PARITY_SHIFT)
77 #define XR21V141X_UART_PARITY_EVEN      (0x2 << XR21V141X_UART_PARITY_SHIFT)
78 #define XR21V141X_UART_PARITY_MARK      (0x3 << XR21V141X_UART_PARITY_SHIFT)
79 #define XR21V141X_UART_PARITY_SPACE     (0x4 << XR21V141X_UART_PARITY_SHIFT)
80
81 #define XR21V141X_UART_STOP_MASK        BIT(7)
82 #define XR21V141X_UART_STOP_SHIFT       7
83 #define XR21V141X_UART_STOP_1           (0x0 << XR21V141X_UART_STOP_SHIFT)
84 #define XR21V141X_UART_STOP_2           (0x1 << XR21V141X_UART_STOP_SHIFT)
85
86 #define XR21V141X_UART_FLOW_MODE_NONE   0x0
87 #define XR21V141X_UART_FLOW_MODE_HW     0x1
88 #define XR21V141X_UART_FLOW_MODE_SW     0x2
89
90 #define XR21V141X_UART_MODE_GPIO_MASK   GENMASK(2, 0)
91 #define XR21V141X_UART_MODE_RTS_CTS     0x1
92 #define XR21V141X_UART_MODE_DTR_DSR     0x2
93 #define XR21V141X_UART_MODE_RS485       0x3
94 #define XR21V141X_UART_MODE_RS485_ADDR  0x4
95
96 #define XR21V141X_REG_ENABLE            0x03
97 #define XR21V141X_REG_FORMAT            0x0b
98 #define XR21V141X_REG_FLOW_CTRL         0x0c
99 #define XR21V141X_REG_XON_CHAR          0x10
100 #define XR21V141X_REG_XOFF_CHAR         0x11
101 #define XR21V141X_REG_LOOPBACK          0x12
102 #define XR21V141X_REG_TX_BREAK          0x14
103 #define XR21V141X_REG_RS845_DELAY       0x15
104 #define XR21V141X_REG_GPIO_MODE         0x1a
105 #define XR21V141X_REG_GPIO_DIR          0x1b
106 #define XR21V141X_REG_GPIO_INT_MASK     0x1c
107 #define XR21V141X_REG_GPIO_SET          0x1d
108 #define XR21V141X_REG_GPIO_CLR          0x1e
109 #define XR21V141X_REG_GPIO_STATUS       0x1f
110
111 static int xr_set_reg(struct usb_serial_port *port, u8 block, u8 reg, u8 val)
112 {
113         struct usb_serial *serial = port->serial;
114         int ret;
115
116         ret = usb_control_msg(serial->dev,
117                               usb_sndctrlpipe(serial->dev, 0),
118                               XR21V141X_SET_REQ,
119                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
120                               val, reg | (block << 8), NULL, 0,
121                               USB_CTRL_SET_TIMEOUT);
122         if (ret < 0) {
123                 dev_err(&port->dev, "Failed to set reg 0x%02x: %d\n", reg, ret);
124                 return ret;
125         }
126
127         return 0;
128 }
129
130 static int xr_get_reg(struct usb_serial_port *port, u8 block, u8 reg, u8 *val)
131 {
132         struct usb_serial *serial = port->serial;
133         u8 *dmabuf;
134         int ret;
135
136         dmabuf = kmalloc(1, GFP_KERNEL);
137         if (!dmabuf)
138                 return -ENOMEM;
139
140         ret = usb_control_msg(serial->dev,
141                               usb_rcvctrlpipe(serial->dev, 0),
142                               XR21V141X_GET_REQ,
143                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
144                               0, reg | (block << 8), dmabuf, 1,
145                               USB_CTRL_GET_TIMEOUT);
146         if (ret == 1) {
147                 *val = *dmabuf;
148                 ret = 0;
149         } else {
150                 dev_err(&port->dev, "Failed to get reg 0x%02x: %d\n", reg, ret);
151                 if (ret >= 0)
152                         ret = -EIO;
153         }
154
155         kfree(dmabuf);
156
157         return ret;
158 }
159
160 static int xr_set_reg_uart(struct usb_serial_port *port, u8 reg, u8 val)
161 {
162         return xr_set_reg(port, XR21V141X_UART_REG_BLOCK, reg, val);
163 }
164
165 static int xr_get_reg_uart(struct usb_serial_port *port, u8 reg, u8 *val)
166 {
167         return xr_get_reg(port, XR21V141X_UART_REG_BLOCK, reg, val);
168 }
169
170 static int xr_set_reg_um(struct usb_serial_port *port, u8 reg, u8 val)
171 {
172         return xr_set_reg(port, XR21V141X_UM_REG_BLOCK, reg, val);
173 }
174
175 /*
176  * According to datasheet, below is the recommended sequence for enabling UART
177  * module in XR21V141X:
178  *
179  * Enable Tx FIFO
180  * Enable Tx and Rx
181  * Enable Rx FIFO
182  */
183 static int xr_uart_enable(struct usb_serial_port *port)
184 {
185         int ret;
186
187         ret = xr_set_reg_um(port, XR21V141X_UM_FIFO_ENABLE_REG,
188                             XR21V141X_UM_ENABLE_TX_FIFO);
189         if (ret)
190                 return ret;
191
192         ret = xr_set_reg_uart(port, XR21V141X_REG_ENABLE,
193                               XR21V141X_UART_ENABLE_TX | XR21V141X_UART_ENABLE_RX);
194         if (ret)
195                 return ret;
196
197         ret = xr_set_reg_um(port, XR21V141X_UM_FIFO_ENABLE_REG,
198                             XR21V141X_UM_ENABLE_TX_FIFO | XR21V141X_UM_ENABLE_RX_FIFO);
199
200         if (ret)
201                 xr_set_reg_uart(port, XR21V141X_REG_ENABLE, 0);
202
203         return ret;
204 }
205
206 static int xr_uart_disable(struct usb_serial_port *port)
207 {
208         int ret;
209
210         ret = xr_set_reg_uart(port, XR21V141X_REG_ENABLE, 0);
211         if (ret)
212                 return ret;
213
214         ret = xr_set_reg_um(port, XR21V141X_UM_FIFO_ENABLE_REG, 0);
215
216         return ret;
217 }
218
219 static int xr_tiocmget(struct tty_struct *tty)
220 {
221         struct usb_serial_port *port = tty->driver_data;
222         u8 status;
223         int ret;
224
225         ret = xr_get_reg_uart(port, XR21V141X_REG_GPIO_STATUS, &status);
226         if (ret)
227                 return ret;
228
229         /*
230          * Modem control pins are active low, so reading '0' means it is active
231          * and '1' means not active.
232          */
233         ret = ((status & XR21V141X_UART_MODE_DTR) ? 0 : TIOCM_DTR) |
234               ((status & XR21V141X_UART_MODE_RTS) ? 0 : TIOCM_RTS) |
235               ((status & XR21V141X_UART_MODE_CTS) ? 0 : TIOCM_CTS) |
236               ((status & XR21V141X_UART_MODE_DSR) ? 0 : TIOCM_DSR) |
237               ((status & XR21V141X_UART_MODE_RI) ? 0 : TIOCM_RI) |
238               ((status & XR21V141X_UART_MODE_CD) ? 0 : TIOCM_CD);
239
240         return ret;
241 }
242
243 static int xr_tiocmset_port(struct usb_serial_port *port,
244                             unsigned int set, unsigned int clear)
245 {
246         u8 gpio_set = 0;
247         u8 gpio_clr = 0;
248         int ret = 0;
249
250         /* Modem control pins are active low, so set & clr are swapped */
251         if (set & TIOCM_RTS)
252                 gpio_clr |= XR21V141X_UART_MODE_RTS;
253         if (set & TIOCM_DTR)
254                 gpio_clr |= XR21V141X_UART_MODE_DTR;
255         if (clear & TIOCM_RTS)
256                 gpio_set |= XR21V141X_UART_MODE_RTS;
257         if (clear & TIOCM_DTR)
258                 gpio_set |= XR21V141X_UART_MODE_DTR;
259
260         /* Writing '0' to gpio_{set/clr} bits has no effect, so no need to do */
261         if (gpio_clr)
262                 ret = xr_set_reg_uart(port, XR21V141X_REG_GPIO_CLR, gpio_clr);
263
264         if (gpio_set)
265                 ret = xr_set_reg_uart(port, XR21V141X_REG_GPIO_SET, gpio_set);
266
267         return ret;
268 }
269
270 static int xr_tiocmset(struct tty_struct *tty,
271                        unsigned int set, unsigned int clear)
272 {
273         struct usb_serial_port *port = tty->driver_data;
274
275         return xr_tiocmset_port(port, set, clear);
276 }
277
278 static void xr_dtr_rts(struct usb_serial_port *port, int on)
279 {
280         if (on)
281                 xr_tiocmset_port(port, TIOCM_DTR | TIOCM_RTS, 0);
282         else
283                 xr_tiocmset_port(port, 0, TIOCM_DTR | TIOCM_RTS);
284 }
285
286 static void xr_break_ctl(struct tty_struct *tty, int break_state)
287 {
288         struct usb_serial_port *port = tty->driver_data;
289         u8 state;
290
291         if (break_state == 0)
292                 state = XR21V141X_UART_BREAK_OFF;
293         else
294                 state = XR21V141X_UART_BREAK_ON;
295
296         dev_dbg(&port->dev, "Turning break %s\n",
297                 state == XR21V141X_UART_BREAK_OFF ? "off" : "on");
298         xr_set_reg_uart(port, XR21V141X_REG_TX_BREAK, state);
299 }
300
301 /* Tx and Rx clock mask values obtained from section 3.3.4 of datasheet */
302 static const struct xr_txrx_clk_mask xr21v141x_txrx_clk_masks[] = {
303         { 0x000, 0x000, 0x000 },
304         { 0x000, 0x000, 0x000 },
305         { 0x100, 0x000, 0x100 },
306         { 0x020, 0x400, 0x020 },
307         { 0x010, 0x100, 0x010 },
308         { 0x208, 0x040, 0x208 },
309         { 0x104, 0x820, 0x108 },
310         { 0x844, 0x210, 0x884 },
311         { 0x444, 0x110, 0x444 },
312         { 0x122, 0x888, 0x224 },
313         { 0x912, 0x448, 0x924 },
314         { 0x492, 0x248, 0x492 },
315         { 0x252, 0x928, 0x292 },
316         { 0x94a, 0x4a4, 0xa52 },
317         { 0x52a, 0xaa4, 0x54a },
318         { 0xaaa, 0x954, 0x4aa },
319         { 0xaaa, 0x554, 0xaaa },
320         { 0x555, 0xad4, 0x5aa },
321         { 0xb55, 0xab4, 0x55a },
322         { 0x6b5, 0x5ac, 0xb56 },
323         { 0x5b5, 0xd6c, 0x6d6 },
324         { 0xb6d, 0xb6a, 0xdb6 },
325         { 0x76d, 0x6da, 0xbb6 },
326         { 0xedd, 0xdda, 0x76e },
327         { 0xddd, 0xbba, 0xeee },
328         { 0x7bb, 0xf7a, 0xdde },
329         { 0xf7b, 0xef6, 0x7de },
330         { 0xdf7, 0xbf6, 0xf7e },
331         { 0x7f7, 0xfee, 0xefe },
332         { 0xfdf, 0xfbe, 0x7fe },
333         { 0xf7f, 0xefe, 0xffe },
334         { 0xfff, 0xffe, 0xffd },
335 };
336
337 static int xr_set_baudrate(struct tty_struct *tty,
338                            struct usb_serial_port *port)
339 {
340         u32 divisor, baud, idx;
341         u16 tx_mask, rx_mask;
342         int ret;
343
344         baud = tty->termios.c_ospeed;
345         if (!baud)
346                 return 0;
347
348         baud = clamp(baud, XR21V141X_MIN_SPEED, XR21V141X_MAX_SPEED);
349         divisor = XR_INT_OSC_HZ / baud;
350         idx = ((32 * XR_INT_OSC_HZ) / baud) & 0x1f;
351         tx_mask = xr21v141x_txrx_clk_masks[idx].tx;
352
353         if (divisor & 0x01)
354                 rx_mask = xr21v141x_txrx_clk_masks[idx].rx1;
355         else
356                 rx_mask = xr21v141x_txrx_clk_masks[idx].rx0;
357
358         dev_dbg(&port->dev, "Setting baud rate: %u\n", baud);
359         /*
360          * XR21V141X uses fractional baud rate generator with 48MHz internal
361          * oscillator and 19-bit programmable divisor. So theoretically it can
362          * generate most commonly used baud rates with high accuracy.
363          */
364         ret = xr_set_reg_uart(port, XR21V141X_CLOCK_DIVISOR_0,
365                               divisor & 0xff);
366         if (ret)
367                 return ret;
368
369         ret = xr_set_reg_uart(port, XR21V141X_CLOCK_DIVISOR_1,
370                               (divisor >>  8) & 0xff);
371         if (ret)
372                 return ret;
373
374         ret = xr_set_reg_uart(port, XR21V141X_CLOCK_DIVISOR_2,
375                               (divisor >> 16) & 0xff);
376         if (ret)
377                 return ret;
378
379         ret = xr_set_reg_uart(port, XR21V141X_TX_CLOCK_MASK_0,
380                               tx_mask & 0xff);
381         if (ret)
382                 return ret;
383
384         ret = xr_set_reg_uart(port, XR21V141X_TX_CLOCK_MASK_1,
385                               (tx_mask >>  8) & 0xff);
386         if (ret)
387                 return ret;
388
389         ret = xr_set_reg_uart(port, XR21V141X_RX_CLOCK_MASK_0,
390                               rx_mask & 0xff);
391         if (ret)
392                 return ret;
393
394         ret = xr_set_reg_uart(port, XR21V141X_RX_CLOCK_MASK_1,
395                               (rx_mask >>  8) & 0xff);
396         if (ret)
397                 return ret;
398
399         tty_encode_baud_rate(tty, baud, baud);
400
401         return 0;
402 }
403
404 static void xr_set_flow_mode(struct tty_struct *tty,
405                              struct usb_serial_port *port,
406                              struct ktermios *old_termios)
407 {
408         u8 flow, gpio_mode;
409         int ret;
410
411         ret = xr_get_reg_uart(port, XR21V141X_REG_GPIO_MODE, &gpio_mode);
412         if (ret)
413                 return;
414
415         /* Set GPIO mode for controlling the pins manually by default. */
416         gpio_mode &= ~XR21V141X_UART_MODE_GPIO_MASK;
417
418         if (C_CRTSCTS(tty) && C_BAUD(tty) != B0) {
419                 dev_dbg(&port->dev, "Enabling hardware flow ctrl\n");
420                 gpio_mode |= XR21V141X_UART_MODE_RTS_CTS;
421                 flow = XR21V141X_UART_FLOW_MODE_HW;
422         } else if (I_IXON(tty)) {
423                 u8 start_char = START_CHAR(tty);
424                 u8 stop_char = STOP_CHAR(tty);
425
426                 dev_dbg(&port->dev, "Enabling sw flow ctrl\n");
427                 flow = XR21V141X_UART_FLOW_MODE_SW;
428
429                 xr_set_reg_uart(port, XR21V141X_REG_XON_CHAR, start_char);
430                 xr_set_reg_uart(port, XR21V141X_REG_XOFF_CHAR, stop_char);
431         } else {
432                 dev_dbg(&port->dev, "Disabling flow ctrl\n");
433                 flow = XR21V141X_UART_FLOW_MODE_NONE;
434         }
435
436         /*
437          * As per the datasheet, UART needs to be disabled while writing to
438          * FLOW_CONTROL register.
439          */
440         xr_uart_disable(port);
441         xr_set_reg_uart(port, XR21V141X_REG_FLOW_CTRL, flow);
442         xr_uart_enable(port);
443
444         xr_set_reg_uart(port, XR21V141X_REG_GPIO_MODE, gpio_mode);
445
446         if (C_BAUD(tty) == B0)
447                 xr_dtr_rts(port, 0);
448         else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
449                 xr_dtr_rts(port, 1);
450 }
451
452 static void xr_set_termios(struct tty_struct *tty,
453                            struct usb_serial_port *port,
454                            struct ktermios *old_termios)
455 {
456         struct ktermios *termios = &tty->termios;
457         u8 bits = 0;
458         int ret;
459
460         if (!old_termios || (tty->termios.c_ospeed != old_termios->c_ospeed))
461                 xr_set_baudrate(tty, port);
462
463         switch (C_CSIZE(tty)) {
464         case CS5:
465         case CS6:
466                 /* CS5 and CS6 are not supported, so just restore old setting */
467                 termios->c_cflag &= ~CSIZE;
468                 if (old_termios)
469                         termios->c_cflag |= old_termios->c_cflag & CSIZE;
470                 else
471                         bits |= XR21V141X_UART_DATA_8;
472                 break;
473         case CS7:
474                 bits |= XR21V141X_UART_DATA_7;
475                 break;
476         case CS8:
477         default:
478                 bits |= XR21V141X_UART_DATA_8;
479                 break;
480         }
481
482         if (C_PARENB(tty)) {
483                 if (C_CMSPAR(tty)) {
484                         if (C_PARODD(tty))
485                                 bits |= XR21V141X_UART_PARITY_MARK;
486                         else
487                                 bits |= XR21V141X_UART_PARITY_SPACE;
488                 } else {
489                         if (C_PARODD(tty))
490                                 bits |= XR21V141X_UART_PARITY_ODD;
491                         else
492                                 bits |= XR21V141X_UART_PARITY_EVEN;
493                 }
494         }
495
496         if (C_CSTOPB(tty))
497                 bits |= XR21V141X_UART_STOP_2;
498         else
499                 bits |= XR21V141X_UART_STOP_1;
500
501         ret = xr_set_reg_uart(port, XR21V141X_REG_FORMAT, bits);
502         if (ret)
503                 return;
504
505         xr_set_flow_mode(tty, port, old_termios);
506 }
507
508 static int xr_open(struct tty_struct *tty, struct usb_serial_port *port)
509 {
510         u8 gpio_dir;
511         int ret;
512
513         ret = xr_uart_enable(port);
514         if (ret) {
515                 dev_err(&port->dev, "Failed to enable UART\n");
516                 return ret;
517         }
518
519         /*
520          * Configure DTR and RTS as outputs and RI, CD, DSR and CTS as
521          * inputs.
522          */
523         gpio_dir = XR21V141X_UART_MODE_DTR | XR21V141X_UART_MODE_RTS;
524         xr_set_reg_uart(port, XR21V141X_REG_GPIO_DIR, gpio_dir);
525
526         /* Setup termios */
527         if (tty)
528                 xr_set_termios(tty, port, NULL);
529
530         ret = usb_serial_generic_open(tty, port);
531         if (ret) {
532                 xr_uart_disable(port);
533                 return ret;
534         }
535
536         return 0;
537 }
538
539 static void xr_close(struct usb_serial_port *port)
540 {
541         usb_serial_generic_close(port);
542
543         xr_uart_disable(port);
544 }
545
546 static int xr_probe(struct usb_serial *serial, const struct usb_device_id *id)
547 {
548         struct usb_driver *driver = serial->type->usb_driver;
549         struct usb_interface *control_interface;
550         int ret;
551
552         /* Don't bind to control interface */
553         if (serial->interface->cur_altsetting->desc.bInterfaceNumber == 0)
554                 return -ENODEV;
555
556         /* But claim the control interface during data interface probe */
557         control_interface = usb_ifnum_to_if(serial->dev, 0);
558         if (!control_interface)
559                 return -ENODEV;
560
561         ret = usb_driver_claim_interface(driver, control_interface, NULL);
562         if (ret) {
563                 dev_err(&serial->interface->dev, "Failed to claim control interface\n");
564                 return ret;
565         }
566
567         return 0;
568 }
569
570 static void xr_disconnect(struct usb_serial *serial)
571 {
572         struct usb_driver *driver = serial->type->usb_driver;
573         struct usb_interface *control_interface;
574
575         control_interface = usb_ifnum_to_if(serial->dev, 0);
576         usb_driver_release_interface(driver, control_interface);
577 }
578
579 static const struct usb_device_id id_table[] = {
580         { USB_DEVICE(0x04e2, 0x1410) }, /* XR21V141X */
581         { }
582 };
583 MODULE_DEVICE_TABLE(usb, id_table);
584
585 static struct usb_serial_driver xr_device = {
586         .driver = {
587                 .owner = THIS_MODULE,
588                 .name = "xr_serial",
589         },
590         .id_table               = id_table,
591         .num_ports              = 1,
592         .probe                  = xr_probe,
593         .disconnect             = xr_disconnect,
594         .open                   = xr_open,
595         .close                  = xr_close,
596         .break_ctl              = xr_break_ctl,
597         .set_termios            = xr_set_termios,
598         .tiocmget               = xr_tiocmget,
599         .tiocmset               = xr_tiocmset,
600         .dtr_rts                = xr_dtr_rts
601 };
602
603 static struct usb_serial_driver * const serial_drivers[] = {
604         &xr_device, NULL
605 };
606
607 module_usb_serial_driver(serial_drivers, id_table);
608
609 MODULE_AUTHOR("Manivannan Sadhasivam <[email protected]>");
610 MODULE_DESCRIPTION("MaxLinear/Exar USB to Serial driver");
611 MODULE_LICENSE("GPL");
This page took 0.065604 seconds and 4 git commands to generate.