FreeCalypso > hg > freecalypso-hwlab
comparison linux-patch/orig-202007/ftdi_sio.c.patch @ 82:e2161ac7d641
linux-patch: move original 2020-07 version into orig-202007
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 06 Dec 2020 01:20:27 +0000 |
parents | linux-patch/ftdi_sio.c.patch@749e1a14aa24 |
children |
comparison
equal
deleted
inserted
replaced
81:bbeec8f293dc | 82:e2161ac7d641 |
---|---|
1 --- ftdi_sio.c.orig 2016-06-24 09:18:38.000000000 -0800 | |
2 +++ ftdi_sio.c 2020-07-28 15:33:04.022945400 -0800 | |
3 @@ -73,6 +73,8 @@ | |
4 this value */ | |
5 int force_rtscts; /* if non-zero, force RTS-CTS to always | |
6 be enabled */ | |
7 + int no_auto_dtr_rts; /* if non-zero, suppress automatic assertion | |
8 + of DTR & RTS on device open */ | |
9 | |
10 unsigned int latency; /* latency setting in use */ | |
11 unsigned short max_packet_size; | |
12 @@ -83,15 +85,19 @@ | |
13 struct ftdi_sio_quirk { | |
14 int (*probe)(struct usb_serial *); | |
15 /* Special settings for probed ports. */ | |
16 - void (*port_probe)(struct ftdi_private *); | |
17 + void (*port_probe)(struct usb_serial_port *, struct ftdi_private *); | |
18 }; | |
19 | |
20 static int ftdi_jtag_probe(struct usb_serial *serial); | |
21 static int ftdi_NDI_device_setup(struct usb_serial *serial); | |
22 static int ftdi_stmclite_probe(struct usb_serial *serial); | |
23 static int ftdi_8u2232c_probe(struct usb_serial *serial); | |
24 -static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); | |
25 -static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | |
26 +static void ftdi_USB_UIRT_setup(struct usb_serial_port *port, | |
27 + struct ftdi_private *priv); | |
28 +static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port, | |
29 + struct ftdi_private *priv); | |
30 +static void ftdi_duart28c_setup(struct usb_serial_port *port, | |
31 + struct ftdi_private *priv); | |
32 | |
33 static struct ftdi_sio_quirk ftdi_jtag_quirk = { | |
34 .probe = ftdi_jtag_probe, | |
35 @@ -117,6 +123,10 @@ | |
36 .probe = ftdi_8u2232c_probe, | |
37 }; | |
38 | |
39 +static struct ftdi_sio_quirk ftdi_duart28c_quirk = { | |
40 + .port_probe = ftdi_duart28c_setup, | |
41 +}; | |
42 + | |
43 /* | |
44 * The 8U232AM has the same API as the sio except for: | |
45 * - it can support MUCH higher baudrates; up to: | |
46 @@ -1008,6 +1018,13 @@ | |
47 { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) }, | |
48 { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, | |
49 { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, | |
50 + /* FreeCalypso USB adapters */ | |
51 + { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID), | |
52 + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | |
53 + { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID), | |
54 + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | |
55 + { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID), | |
56 + .driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk }, | |
57 { } /* Terminating entry */ | |
58 }; | |
59 | |
60 @@ -1804,7 +1821,7 @@ | |
61 priv->flags = ASYNC_LOW_LATENCY; | |
62 | |
63 if (quirk && quirk->port_probe) | |
64 - quirk->port_probe(priv); | |
65 + quirk->port_probe(port, priv); | |
66 | |
67 usb_set_serial_port_data(port, priv); | |
68 | |
69 @@ -1820,7 +1837,8 @@ | |
70 /* Setup for the USB-UIRT device, which requires hardwired | |
71 * baudrate (38400 gets mapped to 312500) */ | |
72 /* Called from usbserial:serial_probe */ | |
73 -static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) | |
74 +static void ftdi_USB_UIRT_setup(struct usb_serial_port *port, | |
75 + struct ftdi_private *priv) | |
76 { | |
77 priv->flags |= ASYNC_SPD_CUST; | |
78 priv->custom_divisor = 77; | |
79 @@ -1830,7 +1848,8 @@ | |
80 /* Setup for the HE-TIRA1 device, which requires hardwired | |
81 * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ | |
82 | |
83 -static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) | |
84 +static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port, | |
85 + struct ftdi_private *priv) | |
86 { | |
87 priv->flags |= ASYNC_SPD_CUST; | |
88 priv->custom_divisor = 240; | |
89 @@ -1926,6 +1945,37 @@ | |
90 return 0; | |
91 } | |
92 | |
93 +/* | |
94 + * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter | |
95 + * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4 | |
96 + * on the chip) have been repurposed to drive power and reset controls | |
97 + * on Calypso targets. The circuit is wired such that BDBUS[24] high | |
98 + * (RTS/DTR inactive) is the normal state with power/reset control | |
99 + * NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON | |
100 + * the corresponding power/reset control drivers. | |
101 + * | |
102 + * A special ftdi_sio driver quirk is needed in order to suppress | |
103 + * automatic assertion of DTR & RTS on device open: this device's | |
104 + * special power and reset control drivers MUST NOT be activated | |
105 + * when the port is ordinarily opened for plain serial communication, | |
106 + * instead they must only be activated when a special userspace | |
107 + * application explicitly requests such activation with a TIOCMBIS ioctl. | |
108 + * | |
109 + * The special quirk must be applied only to FT2232D Channel B: | |
110 + * Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs | |
111 + * actually being RTS and DTR rather than something else. | |
112 + */ | |
113 +static void ftdi_duart28c_setup(struct usb_serial_port *port, | |
114 + struct ftdi_private *priv) | |
115 +{ | |
116 + struct usb_serial *serial = port->serial; | |
117 + struct usb_device *udev = serial->dev; | |
118 + struct usb_interface *interface = serial->interface; | |
119 + | |
120 + if (interface == udev->actconfig->interface[1]) | |
121 + priv->no_auto_dtr_rts = 1; | |
122 +} | |
123 + | |
124 static int ftdi_sio_port_remove(struct usb_serial_port *port) | |
125 { | |
126 struct ftdi_private *priv = usb_get_serial_port_data(port); | |
127 @@ -1976,9 +2026,10 @@ | |
128 } | |
129 } | |
130 /* drop RTS and DTR */ | |
131 - if (on) | |
132 - set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | |
133 - else | |
134 + if (on) { | |
135 + if (!priv->no_auto_dtr_rts) | |
136 + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | |
137 + } else | |
138 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | |
139 } | |
140 | |
141 @@ -2316,7 +2367,8 @@ | |
142 dev_err(ddev, "%s urb failed to set baudrate\n", __func__); | |
143 mutex_unlock(&priv->cfg_lock); | |
144 /* Ensure RTS and DTR are raised when baudrate changed from 0 */ | |
145 - if (old_termios && (old_termios->c_cflag & CBAUD) == B0) | |
146 + if (old_termios && (old_termios->c_cflag & CBAUD) == B0 | |
147 + && !priv->no_auto_dtr_rts) | |
148 set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | |
149 } | |
150 |