hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/usb/serial/f81232.c
....@@ -1,6 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
33 * Fintek F81232 USB to serial adaptor driver
4
+ * Fintek F81532A/534A/535/536 USB to 2/4/8/12 serial adaptor driver
45 *
56 * Copyright (C) 2012 Greg Kroah-Hartman (gregkh@linuxfoundation.org)
67 * Copyright (C) 2012 Linux Foundation
....@@ -21,19 +22,55 @@
2122 #include <linux/usb/serial.h>
2223 #include <linux/serial_reg.h>
2324
24
-static const struct usb_device_id id_table[] = {
25
- { USB_DEVICE(0x1934, 0x0706) },
25
+#define F81232_ID \
26
+ { USB_DEVICE(0x1934, 0x0706) } /* 1 port UART device */
27
+
28
+#define F81534A_SERIES_ID \
29
+ { USB_DEVICE(0x2c42, 0x1602) }, /* In-Box 2 port UART device */ \
30
+ { USB_DEVICE(0x2c42, 0x1604) }, /* In-Box 4 port UART device */ \
31
+ { USB_DEVICE(0x2c42, 0x1605) }, /* In-Box 8 port UART device */ \
32
+ { USB_DEVICE(0x2c42, 0x1606) }, /* In-Box 12 port UART device */ \
33
+ { USB_DEVICE(0x2c42, 0x1608) }, /* Non-Flash type */ \
34
+ { USB_DEVICE(0x2c42, 0x1632) }, /* 2 port UART device */ \
35
+ { USB_DEVICE(0x2c42, 0x1634) }, /* 4 port UART device */ \
36
+ { USB_DEVICE(0x2c42, 0x1635) }, /* 8 port UART device */ \
37
+ { USB_DEVICE(0x2c42, 0x1636) } /* 12 port UART device */
38
+
39
+#define F81534A_CTRL_ID \
40
+ { USB_DEVICE(0x2c42, 0x16f8) } /* Global control device */
41
+
42
+static const struct usb_device_id f81232_id_table[] = {
43
+ F81232_ID,
2644 { } /* Terminating entry */
2745 };
28
-MODULE_DEVICE_TABLE(usb, id_table);
46
+
47
+static const struct usb_device_id f81534a_id_table[] = {
48
+ F81534A_SERIES_ID,
49
+ { } /* Terminating entry */
50
+};
51
+
52
+static const struct usb_device_id f81534a_ctrl_id_table[] = {
53
+ F81534A_CTRL_ID,
54
+ { } /* Terminating entry */
55
+};
56
+
57
+static const struct usb_device_id combined_id_table[] = {
58
+ F81232_ID,
59
+ F81534A_SERIES_ID,
60
+ F81534A_CTRL_ID,
61
+ { } /* Terminating entry */
62
+};
63
+MODULE_DEVICE_TABLE(usb, combined_id_table);
2964
3065 /* Maximum baudrate for F81232 */
31
-#define F81232_MAX_BAUDRATE 115200
66
+#define F81232_MAX_BAUDRATE 1500000
67
+#define F81232_DEF_BAUDRATE 9600
3268
3369 /* USB Control EP parameter */
3470 #define F81232_REGISTER_REQUEST 0xa0
3571 #define F81232_GET_REGISTER 0xc0
3672 #define F81232_SET_REGISTER 0x40
73
+#define F81534A_ACCESS_REG_RETRY 2
3774
3875 #define SERIAL_BASE_ADDRESS 0x0120
3976 #define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS)
....@@ -41,19 +78,59 @@
4178 #define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS)
4279 #define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS)
4380 #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS)
81
+#define LINE_STATUS_REGISTER (0x05 + SERIAL_BASE_ADDRESS)
4482 #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS)
83
+
84
+/*
85
+ * F81232 Clock registers (106h)
86
+ *
87
+ * Bit1-0: Clock source selector
88
+ * 00: 1.846MHz.
89
+ * 01: 18.46MHz.
90
+ * 10: 24MHz.
91
+ * 11: 14.77MHz.
92
+ */
93
+#define F81232_CLK_REGISTER 0x106
94
+#define F81232_CLK_1_846_MHZ 0
95
+#define F81232_CLK_18_46_MHZ BIT(0)
96
+#define F81232_CLK_24_MHZ BIT(1)
97
+#define F81232_CLK_14_77_MHZ (BIT(1) | BIT(0))
98
+#define F81232_CLK_MASK GENMASK(1, 0)
99
+
100
+#define F81534A_MODE_REG 0x107
101
+#define F81534A_TRIGGER_MASK GENMASK(3, 2)
102
+#define F81534A_TRIGGER_MULTIPLE_4X BIT(3)
103
+#define F81534A_FIFO_128BYTE (BIT(1) | BIT(0))
104
+
105
+/* Serial port self GPIO control, 2bytes [control&output data][input data] */
106
+#define F81534A_GPIO_REG 0x10e
107
+#define F81534A_GPIO_MODE2_DIR BIT(6) /* 1: input, 0: output */
108
+#define F81534A_GPIO_MODE1_DIR BIT(5)
109
+#define F81534A_GPIO_MODE0_DIR BIT(4)
110
+#define F81534A_GPIO_MODE2_OUTPUT BIT(2)
111
+#define F81534A_GPIO_MODE1_OUTPUT BIT(1)
112
+#define F81534A_GPIO_MODE0_OUTPUT BIT(0)
113
+
114
+#define F81534A_CTRL_CMD_ENABLE_PORT 0x116
45115
46116 struct f81232_private {
47117 struct mutex lock;
48118 u8 modem_control;
49119 u8 modem_status;
120
+ u8 shadow_lcr;
121
+ speed_t baud_base;
122
+ struct work_struct lsr_work;
50123 struct work_struct interrupt_work;
51124 struct usb_serial_port *port;
52125 };
53126
54
-static int calc_baud_divisor(speed_t baudrate)
127
+static u32 const baudrate_table[] = { 115200, 921600, 1152000, 1500000 };
128
+static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ,
129
+ F81232_CLK_18_46_MHZ, F81232_CLK_24_MHZ };
130
+
131
+static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
55132 {
56
- return DIV_ROUND_CLOSEST(F81232_MAX_BAUDRATE, baudrate);
133
+ return DIV_ROUND_CLOSEST(clockrate, baudrate);
57134 }
58135
59136 static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val)
....@@ -125,6 +202,21 @@
125202
126203 kfree(tmp);
127204 return status;
205
+}
206
+
207
+static int f81232_set_mask_register(struct usb_serial_port *port, u16 reg,
208
+ u8 mask, u8 val)
209
+{
210
+ int status;
211
+ u8 tmp;
212
+
213
+ status = f81232_get_register(port, reg, &tmp);
214
+ if (status)
215
+ return status;
216
+
217
+ tmp = (tmp & ~mask) | (val & mask);
218
+
219
+ return f81232_set_register(port, reg, tmp);
128220 }
129221
130222 static void f81232_read_msr(struct usb_serial_port *port)
....@@ -279,6 +371,35 @@
279371 __func__, retval);
280372 }
281373
374
+static char f81232_handle_lsr(struct usb_serial_port *port, u8 lsr)
375
+{
376
+ struct f81232_private *priv = usb_get_serial_port_data(port);
377
+ char tty_flag = TTY_NORMAL;
378
+
379
+ if (!(lsr & UART_LSR_BRK_ERROR_BITS))
380
+ return tty_flag;
381
+
382
+ if (lsr & UART_LSR_BI) {
383
+ tty_flag = TTY_BREAK;
384
+ port->icount.brk++;
385
+ usb_serial_handle_break(port);
386
+ } else if (lsr & UART_LSR_PE) {
387
+ tty_flag = TTY_PARITY;
388
+ port->icount.parity++;
389
+ } else if (lsr & UART_LSR_FE) {
390
+ tty_flag = TTY_FRAME;
391
+ port->icount.frame++;
392
+ }
393
+
394
+ if (lsr & UART_LSR_OE) {
395
+ port->icount.overrun++;
396
+ schedule_work(&priv->lsr_work);
397
+ tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
398
+ }
399
+
400
+ return tty_flag;
401
+}
402
+
282403 static void f81232_process_read_urb(struct urb *urb)
283404 {
284405 struct usb_serial_port *port = urb->context;
....@@ -297,30 +418,10 @@
297418 /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */
298419
299420 for (i = 0; i < urb->actual_length; i += 2) {
300
- tty_flag = TTY_NORMAL;
301421 lsr = data[i];
422
+ tty_flag = f81232_handle_lsr(port, lsr);
302423
303
- if (lsr & UART_LSR_BRK_ERROR_BITS) {
304
- if (lsr & UART_LSR_BI) {
305
- tty_flag = TTY_BREAK;
306
- port->icount.brk++;
307
- usb_serial_handle_break(port);
308
- } else if (lsr & UART_LSR_PE) {
309
- tty_flag = TTY_PARITY;
310
- port->icount.parity++;
311
- } else if (lsr & UART_LSR_FE) {
312
- tty_flag = TTY_FRAME;
313
- port->icount.frame++;
314
- }
315
-
316
- if (lsr & UART_LSR_OE) {
317
- port->icount.overrun++;
318
- tty_insert_flip_char(&port->port, 0,
319
- TTY_OVERRUN);
320
- }
321
- }
322
-
323
- if (port->port.console && port->sysrq) {
424
+ if (port->sysrq) {
324425 if (usb_serial_handle_sysrq_char(port, data[i + 1]))
325426 continue;
326427 }
....@@ -331,24 +432,120 @@
331432 tty_flip_buffer_push(&port->port);
332433 }
333434
334
-static void f81232_break_ctl(struct tty_struct *tty, int break_state)
435
+static void f81534a_process_read_urb(struct urb *urb)
335436 {
336
- /* FIXME - Stubbed out for now */
437
+ struct usb_serial_port *port = urb->context;
438
+ unsigned char *data = urb->transfer_buffer;
439
+ char tty_flag;
440
+ unsigned int i;
441
+ u8 lsr;
442
+ u8 len;
337443
338
- /*
339
- * break_state = -1 to turn on break, and 0 to turn off break
340
- * see drivers/char/tty_io.c to see it used.
341
- * last_set_data_urb_value NEVER has the break bit set in it.
342
- */
444
+ if (urb->actual_length < 3) {
445
+ dev_err(&port->dev, "short message received: %d\n",
446
+ urb->actual_length);
447
+ return;
448
+ }
449
+
450
+ len = data[0];
451
+ if (len != urb->actual_length) {
452
+ dev_err(&port->dev, "malformed message received: %d (%d)\n",
453
+ urb->actual_length, len);
454
+ return;
455
+ }
456
+
457
+ /* bulk-in data: [LEN][Data.....][LSR] */
458
+ lsr = data[len - 1];
459
+ tty_flag = f81232_handle_lsr(port, lsr);
460
+
461
+ if (port->sysrq) {
462
+ for (i = 1; i < len - 1; ++i) {
463
+ if (!usb_serial_handle_sysrq_char(port, data[i])) {
464
+ tty_insert_flip_char(&port->port, data[i],
465
+ tty_flag);
466
+ }
467
+ }
468
+ } else {
469
+ tty_insert_flip_string_fixed_flag(&port->port, &data[1],
470
+ tty_flag, len - 2);
471
+ }
472
+
473
+ tty_flip_buffer_push(&port->port);
343474 }
344475
345
-static void f81232_set_baudrate(struct usb_serial_port *port, speed_t baudrate)
476
+static void f81232_break_ctl(struct tty_struct *tty, int break_state)
346477 {
478
+ struct usb_serial_port *port = tty->driver_data;
479
+ struct f81232_private *priv = usb_get_serial_port_data(port);
480
+ int status;
481
+
482
+ mutex_lock(&priv->lock);
483
+
484
+ if (break_state)
485
+ priv->shadow_lcr |= UART_LCR_SBC;
486
+ else
487
+ priv->shadow_lcr &= ~UART_LCR_SBC;
488
+
489
+ status = f81232_set_register(port, LINE_CONTROL_REGISTER,
490
+ priv->shadow_lcr);
491
+ if (status)
492
+ dev_err(&port->dev, "set break failed: %d\n", status);
493
+
494
+ mutex_unlock(&priv->lock);
495
+}
496
+
497
+static int f81232_find_clk(speed_t baudrate)
498
+{
499
+ int idx;
500
+
501
+ for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) {
502
+ if (baudrate <= baudrate_table[idx] &&
503
+ baudrate_table[idx] % baudrate == 0)
504
+ return idx;
505
+ }
506
+
507
+ return -EINVAL;
508
+}
509
+
510
+static void f81232_set_baudrate(struct tty_struct *tty,
511
+ struct usb_serial_port *port, speed_t baudrate,
512
+ speed_t old_baudrate)
513
+{
514
+ struct f81232_private *priv = usb_get_serial_port_data(port);
347515 u8 lcr;
348516 int divisor;
349517 int status = 0;
518
+ int i;
519
+ int idx;
520
+ speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE };
350521
351
- divisor = calc_baud_divisor(baudrate);
522
+ for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
523
+ baudrate = baud_list[i];
524
+ if (baudrate == 0) {
525
+ tty_encode_baud_rate(tty, 0, 0);
526
+ return;
527
+ }
528
+
529
+ idx = f81232_find_clk(baudrate);
530
+ if (idx >= 0) {
531
+ tty_encode_baud_rate(tty, baudrate, baudrate);
532
+ break;
533
+ }
534
+ }
535
+
536
+ if (idx < 0)
537
+ return;
538
+
539
+ priv->baud_base = baudrate_table[idx];
540
+ divisor = calc_baud_divisor(baudrate, priv->baud_base);
541
+
542
+ status = f81232_set_mask_register(port, F81232_CLK_REGISTER,
543
+ F81232_CLK_MASK, clock_table[idx]);
544
+ if (status) {
545
+ dev_err(&port->dev, "%s failed to set CLK_REG: %d\n",
546
+ __func__, status);
547
+ return;
548
+ }
352549
353550 status = f81232_get_register(port, LINE_CONTROL_REGISTER,
354551 &lcr); /* get LCR */
....@@ -435,9 +632,11 @@
435632 static void f81232_set_termios(struct tty_struct *tty,
436633 struct usb_serial_port *port, struct ktermios *old_termios)
437634 {
635
+ struct f81232_private *priv = usb_get_serial_port_data(port);
438636 u8 new_lcr = 0;
439637 int status = 0;
440638 speed_t baudrate;
639
+ speed_t old_baud;
441640
442641 /* Don't change anything if nothing has changed */
443642 if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
....@@ -450,11 +649,12 @@
450649
451650 baudrate = tty_get_baud_rate(tty);
452651 if (baudrate > 0) {
453
- if (baudrate > F81232_MAX_BAUDRATE) {
454
- baudrate = F81232_MAX_BAUDRATE;
455
- tty_encode_baud_rate(tty, baudrate, baudrate);
456
- }
457
- f81232_set_baudrate(port, baudrate);
652
+ if (old_termios)
653
+ old_baud = tty_termios_baud_rate(old_termios);
654
+ else
655
+ old_baud = F81232_DEF_BAUDRATE;
656
+
657
+ f81232_set_baudrate(tty, port, baudrate, old_baud);
458658 }
459659
460660 if (C_PARENB(tty)) {
....@@ -486,11 +686,18 @@
486686 break;
487687 }
488688
689
+ mutex_lock(&priv->lock);
690
+
691
+ new_lcr |= (priv->shadow_lcr & UART_LCR_SBC);
489692 status = f81232_set_register(port, LINE_CONTROL_REGISTER, new_lcr);
490693 if (status) {
491694 dev_err(&port->dev, "%s failed to set LCR: %d\n",
492695 __func__, status);
493696 }
697
+
698
+ priv->shadow_lcr = new_lcr;
699
+
700
+ mutex_unlock(&priv->lock);
494701 }
495702
496703 static int f81232_tiocmget(struct tty_struct *tty)
....@@ -554,6 +761,24 @@
554761 return 0;
555762 }
556763
764
+static int f81534a_open(struct tty_struct *tty, struct usb_serial_port *port)
765
+{
766
+ int status;
767
+ u8 mask;
768
+ u8 val;
769
+
770
+ val = F81534A_TRIGGER_MULTIPLE_4X | F81534A_FIFO_128BYTE;
771
+ mask = F81534A_TRIGGER_MASK | F81534A_FIFO_128BYTE;
772
+
773
+ status = f81232_set_mask_register(port, F81534A_MODE_REG, mask, val);
774
+ if (status) {
775
+ dev_err(&port->dev, "failed to set MODE_REG: %d\n", status);
776
+ return status;
777
+ }
778
+
779
+ return f81232_open(tty, port);
780
+}
781
+
557782 static void f81232_close(struct usb_serial_port *port)
558783 {
559784 struct f81232_private *port_priv = usb_get_serial_port_data(port);
....@@ -562,6 +787,7 @@
562787 usb_serial_generic_close(port);
563788 usb_kill_urb(port->interrupt_in_urb);
564789 flush_work(&port_priv->interrupt_work);
790
+ flush_work(&port_priv->lsr_work);
565791 }
566792
567793 static void f81232_dtr_rts(struct usb_serial_port *port, int on)
....@@ -570,6 +796,20 @@
570796 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
571797 else
572798 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
799
+}
800
+
801
+static bool f81232_tx_empty(struct usb_serial_port *port)
802
+{
803
+ int status;
804
+ u8 tmp;
805
+
806
+ status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
807
+ if (!status) {
808
+ if ((tmp & UART_LSR_TEMT) != UART_LSR_TEMT)
809
+ return false;
810
+ }
811
+
812
+ return true;
573813 }
574814
575815 static int f81232_carrier_raised(struct usb_serial_port *port)
....@@ -586,36 +826,17 @@
586826 return 0;
587827 }
588828
589
-static int f81232_get_serial_info(struct usb_serial_port *port,
590
- unsigned long arg)
591
-{
592
- struct serial_struct ser;
593
-
594
- memset(&ser, 0, sizeof(ser));
595
-
596
- ser.type = PORT_16550A;
597
- ser.line = port->minor;
598
- ser.port = port->port_number;
599
- ser.baud_base = F81232_MAX_BAUDRATE;
600
-
601
- if (copy_to_user((void __user *)arg, &ser, sizeof(ser)))
602
- return -EFAULT;
603
-
604
- return 0;
605
-}
606
-
607
-static int f81232_ioctl(struct tty_struct *tty,
608
- unsigned int cmd, unsigned long arg)
829
+static int f81232_get_serial_info(struct tty_struct *tty,
830
+ struct serial_struct *ss)
609831 {
610832 struct usb_serial_port *port = tty->driver_data;
833
+ struct f81232_private *priv = usb_get_serial_port_data(port);
611834
612
- switch (cmd) {
613
- case TIOCGSERIAL:
614
- return f81232_get_serial_info(port, arg);
615
- default:
616
- break;
617
- }
618
- return -ENOIOCTLCMD;
835
+ ss->type = PORT_16550A;
836
+ ss->line = port->minor;
837
+ ss->port = port->port_number;
838
+ ss->baud_base = priv->baud_base;
839
+ return 0;
619840 }
620841
621842 static void f81232_interrupt_work(struct work_struct *work)
....@@ -626,16 +847,119 @@
626847 f81232_read_msr(priv->port);
627848 }
628849
850
+static void f81232_lsr_worker(struct work_struct *work)
851
+{
852
+ struct f81232_private *priv;
853
+ struct usb_serial_port *port;
854
+ int status;
855
+ u8 tmp;
856
+
857
+ priv = container_of(work, struct f81232_private, lsr_work);
858
+ port = priv->port;
859
+
860
+ status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
861
+ if (status)
862
+ dev_warn(&port->dev, "read LSR failed: %d\n", status);
863
+}
864
+
865
+static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,
866
+ u16 size, void *val)
867
+{
868
+ struct usb_device *dev = interface_to_usbdev(intf);
869
+ int retry = F81534A_ACCESS_REG_RETRY;
870
+ int status;
871
+ u8 *tmp;
872
+
873
+ tmp = kmemdup(val, size, GFP_KERNEL);
874
+ if (!tmp)
875
+ return -ENOMEM;
876
+
877
+ while (retry--) {
878
+ status = usb_control_msg(dev,
879
+ usb_sndctrlpipe(dev, 0),
880
+ F81232_REGISTER_REQUEST,
881
+ F81232_SET_REGISTER,
882
+ reg,
883
+ 0,
884
+ tmp,
885
+ size,
886
+ USB_CTRL_SET_TIMEOUT);
887
+ if (status < 0) {
888
+ status = usb_translate_errors(status);
889
+ if (status == -EIO)
890
+ continue;
891
+ } else if (status != size) {
892
+ /* Retry on short transfers */
893
+ status = -EIO;
894
+ continue;
895
+ } else {
896
+ status = 0;
897
+ }
898
+
899
+ break;
900
+ }
901
+
902
+ if (status) {
903
+ dev_err(&intf->dev, "failed to set register 0x%x: %d\n",
904
+ reg, status);
905
+ }
906
+
907
+ kfree(tmp);
908
+ return status;
909
+}
910
+
911
+static int f81534a_ctrl_enable_all_ports(struct usb_interface *intf, bool en)
912
+{
913
+ unsigned char enable[2] = {0};
914
+ int status;
915
+
916
+ /*
917
+ * Enable all available serial ports, define as following:
918
+ * bit 15 : Reset behavior (when HUB got soft reset)
919
+ * 0: maintain all serial port enabled state.
920
+ * 1: disable all serial port.
921
+ * bit 0~11 : Serial port enable bit.
922
+ */
923
+ if (en) {
924
+ enable[0] = 0xff;
925
+ enable[1] = 0x8f;
926
+ }
927
+
928
+ status = f81534a_ctrl_set_register(intf, F81534A_CTRL_CMD_ENABLE_PORT,
929
+ sizeof(enable), enable);
930
+ if (status)
931
+ dev_err(&intf->dev, "failed to enable ports: %d\n", status);
932
+
933
+ return status;
934
+}
935
+
936
+static int f81534a_ctrl_probe(struct usb_interface *intf,
937
+ const struct usb_device_id *id)
938
+{
939
+ return f81534a_ctrl_enable_all_ports(intf, true);
940
+}
941
+
942
+static void f81534a_ctrl_disconnect(struct usb_interface *intf)
943
+{
944
+ f81534a_ctrl_enable_all_ports(intf, false);
945
+}
946
+
947
+static int f81534a_ctrl_resume(struct usb_interface *intf)
948
+{
949
+ return f81534a_ctrl_enable_all_ports(intf, true);
950
+}
951
+
629952 static int f81232_port_probe(struct usb_serial_port *port)
630953 {
631954 struct f81232_private *priv;
632955
633
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
956
+ priv = devm_kzalloc(&port->dev, sizeof(*priv), GFP_KERNEL);
634957 if (!priv)
635958 return -ENOMEM;
636959
637960 mutex_init(&priv->lock);
638961 INIT_WORK(&priv->interrupt_work, f81232_interrupt_work);
962
+ INIT_WORK(&priv->lsr_work, f81232_lsr_worker);
639963
640964 usb_set_serial_port_data(port, priv);
641965
....@@ -645,14 +969,17 @@
645969 return 0;
646970 }
647971
648
-static int f81232_port_remove(struct usb_serial_port *port)
972
+static int f81534a_port_probe(struct usb_serial_port *port)
649973 {
650
- struct f81232_private *priv;
974
+ int status;
651975
652
- priv = usb_get_serial_port_data(port);
653
- kfree(priv);
976
+ /* tri-state with pull-high, default RS232 Mode */
977
+ status = f81232_set_register(port, F81534A_GPIO_REG,
978
+ F81534A_GPIO_MODE2_DIR);
979
+ if (status)
980
+ return status;
654981
655
- return 0;
982
+ return f81232_port_probe(port);
656983 }
657984
658985 static int f81232_suspend(struct usb_serial *serial, pm_message_t message)
....@@ -666,8 +993,10 @@
666993
667994 usb_kill_urb(port->interrupt_in_urb);
668995
669
- if (port_priv)
996
+ if (port_priv) {
670997 flush_work(&port_priv->interrupt_work);
998
+ flush_work(&port_priv->lsr_work);
999
+ }
6711000
6721001 return 0;
6731002 }
....@@ -694,7 +1023,7 @@
6941023 .owner = THIS_MODULE,
6951024 .name = "f81232",
6961025 },
697
- .id_table = id_table,
1026
+ .id_table = f81232_id_table,
6981027 .num_ports = 1,
6991028 .bulk_in_size = 256,
7001029 .bulk_out_size = 256,
....@@ -702,28 +1031,88 @@
7021031 .close = f81232_close,
7031032 .dtr_rts = f81232_dtr_rts,
7041033 .carrier_raised = f81232_carrier_raised,
705
- .ioctl = f81232_ioctl,
1034
+ .get_serial = f81232_get_serial_info,
7061035 .break_ctl = f81232_break_ctl,
7071036 .set_termios = f81232_set_termios,
7081037 .tiocmget = f81232_tiocmget,
7091038 .tiocmset = f81232_tiocmset,
7101039 .tiocmiwait = usb_serial_generic_tiocmiwait,
1040
+ .tx_empty = f81232_tx_empty,
7111041 .process_read_urb = f81232_process_read_urb,
7121042 .read_int_callback = f81232_read_int_callback,
7131043 .port_probe = f81232_port_probe,
714
- .port_remove = f81232_port_remove,
1044
+ .suspend = f81232_suspend,
1045
+ .resume = f81232_resume,
1046
+};
1047
+
1048
+static struct usb_serial_driver f81534a_device = {
1049
+ .driver = {
1050
+ .owner = THIS_MODULE,
1051
+ .name = "f81534a",
1052
+ },
1053
+ .id_table = f81534a_id_table,
1054
+ .num_ports = 1,
1055
+ .open = f81534a_open,
1056
+ .close = f81232_close,
1057
+ .dtr_rts = f81232_dtr_rts,
1058
+ .carrier_raised = f81232_carrier_raised,
1059
+ .get_serial = f81232_get_serial_info,
1060
+ .break_ctl = f81232_break_ctl,
1061
+ .set_termios = f81232_set_termios,
1062
+ .tiocmget = f81232_tiocmget,
1063
+ .tiocmset = f81232_tiocmset,
1064
+ .tiocmiwait = usb_serial_generic_tiocmiwait,
1065
+ .tx_empty = f81232_tx_empty,
1066
+ .process_read_urb = f81534a_process_read_urb,
1067
+ .read_int_callback = f81232_read_int_callback,
1068
+ .port_probe = f81534a_port_probe,
7151069 .suspend = f81232_suspend,
7161070 .resume = f81232_resume,
7171071 };
7181072
7191073 static struct usb_serial_driver * const serial_drivers[] = {
7201074 &f81232_device,
1075
+ &f81534a_device,
7211076 NULL,
7221077 };
7231078
724
-module_usb_serial_driver(serial_drivers, id_table);
1079
+static struct usb_driver f81534a_ctrl_driver = {
1080
+ .name = "f81534a_ctrl",
1081
+ .id_table = f81534a_ctrl_id_table,
1082
+ .probe = f81534a_ctrl_probe,
1083
+ .disconnect = f81534a_ctrl_disconnect,
1084
+ .resume = f81534a_ctrl_resume,
1085
+};
7251086
726
-MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver");
1087
+static int __init f81232_init(void)
1088
+{
1089
+ int status;
1090
+
1091
+ status = usb_register_driver(&f81534a_ctrl_driver, THIS_MODULE,
1092
+ KBUILD_MODNAME);
1093
+ if (status)
1094
+ return status;
1095
+
1096
+ status = usb_serial_register_drivers(serial_drivers, KBUILD_MODNAME,
1097
+ combined_id_table);
1098
+ if (status) {
1099
+ usb_deregister(&f81534a_ctrl_driver);
1100
+ return status;
1101
+ }
1102
+
1103
+ return 0;
1104
+}
1105
+
1106
+static void __exit f81232_exit(void)
1107
+{
1108
+ usb_serial_deregister_drivers(serial_drivers);
1109
+ usb_deregister(&f81534a_ctrl_driver);
1110
+}
1111
+
1112
+module_init(f81232_init);
1113
+module_exit(f81232_exit);
1114
+
1115
+MODULE_DESCRIPTION("Fintek F81232/532A/534A/535/536 USB to serial driver");
7271116 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
7281117 MODULE_AUTHOR("Peter Hong <peter_hong@fintek.com.tw>");
7291118 MODULE_LICENSE("GPL v2");