xref: /openbsd/sys/dev/usb/uftdireg.h (revision bf3df6a1)
1*bf3df6a1Skevlo /*	$OpenBSD: uftdireg.h,v 1.14 2022/12/30 00:54:09 kevlo Exp $ 	*/
254ac236cSnate /*	$NetBSD: uftdireg.h,v 1.6 2002/07/11 21:14:28 augustss Exp $ */
30897b806Snate 
4d16b0402Snate /*
5d16b0402Snate  * Definitions for the FTDI USB Single Port Serial Converter -
6d16b0402Snate  * known as FTDI_SIO (Serial Input/Output application of the chipset)
7d16b0402Snate  *
8d16b0402Snate  * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
9d16b0402Snate  * USB on the other.
10d16b0402Snate  *
1134c004ffStdeval  * Thanks to FTDI (http://www.ftdi.co.uk) for so kindly providing details
1234c004ffStdeval  * of the protocol required to talk to the device and ongoing assistance
13d16b0402Snate  * during development.
14d16b0402Snate  *
15d16b0402Snate  * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc. is the original
16d16b0402Snate  * author of this file.
17d16b0402Snate  */
18d16b0402Snate /* Modified by Lennart Augustsson */
19d16b0402Snate 
20d16b0402Snate /* Vendor Request Interface */
21d16b0402Snate #define FTDI_SIO_RESET 		0 /* Reset the port */
22d16b0402Snate #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
23d16b0402Snate #define FTDI_SIO_SET_FLOW_CTRL	2 /* Set flow control register */
24d16b0402Snate #define FTDI_SIO_SET_BAUD_RATE	3 /* Set baud rate */
25d16b0402Snate #define FTDI_SIO_SET_DATA	4 /* Set the data characteristics of the port */
26d16b0402Snate #define FTDI_SIO_GET_STATUS	5 /* Retrieve current value of status reg */
27d16b0402Snate #define FTDI_SIO_SET_EVENT_CHAR	6 /* Set the event character */
28d16b0402Snate #define FTDI_SIO_SET_ERROR_CHAR	7 /* Set the error character */
29d16b0402Snate 
30d16b0402Snate /* Port Identifier Table */
31d16b0402Snate #define FTDI_PIT_DEFAULT 	0 /* SIOA */
32d16b0402Snate #define FTDI_PIT_SIOA		1 /* SIOA */
33d16b0402Snate #define FTDI_PIT_SIOB		2 /* SIOB */
34d16b0402Snate #define FTDI_PIT_PARALLEL	3 /* Parallel */
35d16b0402Snate 
36f72a8aaaSnate enum uftdi_type {
37f72a8aaaSnate 	UFTDI_TYPE_SIO,
38a485dc09Sderaadt 	UFTDI_TYPE_8U232AM,
39*bf3df6a1Skevlo 	UFTDI_TYPE_2232H,
40*bf3df6a1Skevlo 	UFTDI_TYPE_232R
41f72a8aaaSnate };
42f72a8aaaSnate 
43d16b0402Snate /*
44d16b0402Snate  * BmRequestType:  0100 0000B
45d16b0402Snate  * bRequest:       FTDI_SIO_RESET
46d16b0402Snate  * wValue:         Control Value
47d16b0402Snate  *                   0 = Reset SIO
48d16b0402Snate  *                   1 = Purge RX buffer
49d16b0402Snate  *                   2 = Purge TX buffer
50d16b0402Snate  * wIndex:         Port
51d16b0402Snate  * wLength:        0
52d16b0402Snate  * Data:           None
53d16b0402Snate  *
54d16b0402Snate  * The Reset SIO command has this effect:
55d16b0402Snate  *
56d16b0402Snate  *    Sets flow control set to 'none'
57d16b0402Snate  *    Event char = 0x0d
58d16b0402Snate  *    Event trigger = disabled
59d16b0402Snate  *    Purge RX buffer
60d16b0402Snate  *    Purge TX buffer
61d16b0402Snate  *    Clear DTR
62d16b0402Snate  *    Clear RTS
63d16b0402Snate  *    baud and data format not reset
64d16b0402Snate  *
65d16b0402Snate  * The Purge RX and TX buffer commands affect nothing except the buffers
66d16b0402Snate  *
67d16b0402Snate  */
68d16b0402Snate /* FTDI_SIO_RESET */
69d16b0402Snate #define FTDI_SIO_RESET_SIO 0
70d16b0402Snate #define FTDI_SIO_RESET_PURGE_RX 1
71d16b0402Snate #define FTDI_SIO_RESET_PURGE_TX 2
72d16b0402Snate 
73d16b0402Snate 
74d16b0402Snate /*
75d16b0402Snate  * BmRequestType:  0100 0000B
76d16b0402Snate  * bRequest:       FTDI_SIO_SET_BAUDRATE
77d16b0402Snate  * wValue:         BaudRate value - see below
78d16b0402Snate  * wIndex:         Port
79d16b0402Snate  * wLength:        0
80d16b0402Snate  * Data:           None
81d16b0402Snate  */
82d16b0402Snate /* FTDI_SIO_SET_BAUDRATE */
83d16b0402Snate enum {
84d16b0402Snate 	ftdi_sio_b300 = 0,
85d16b0402Snate 	ftdi_sio_b600 = 1,
86d16b0402Snate 	ftdi_sio_b1200 = 2,
87d16b0402Snate 	ftdi_sio_b2400 = 3,
88d16b0402Snate 	ftdi_sio_b4800 = 4,
89d16b0402Snate 	ftdi_sio_b9600 = 5,
90d16b0402Snate 	ftdi_sio_b19200 = 6,
91d16b0402Snate 	ftdi_sio_b38400 = 7,
92d16b0402Snate 	ftdi_sio_b57600 = 8,
93d16b0402Snate 	ftdi_sio_b115200 = 9
94d16b0402Snate };
95d16b0402Snate 
96a485dc09Sderaadt #define FTDI_8U232AM_FREQ 3000000 /* (48MHz / 16) */
97a485dc09Sderaadt #define FTDI_2232H_FREQ 12000000 /* (120MHz / 10) */
981d7e51deSderaadt 
991d7e51deSderaadt /* Bounds for normal divisors as 4-bit fixed precision ints. */
1001d7e51deSderaadt #define FTDI_8U232AM_MIN_DIV 0x20
1011d7e51deSderaadt #define FTDI_8U232AM_MAX_DIV 0x3fff8
102d16b0402Snate 
103d16b0402Snate /*
104d16b0402Snate  * BmRequestType:  0100 0000B
105d16b0402Snate  * bRequest:       FTDI_SIO_SET_DATA
106d16b0402Snate  * wValue:         Data characteristics (see below)
107d16b0402Snate  * wIndex:         Port
108d16b0402Snate  * wLength:        0
109d16b0402Snate  * Data:           No
110d16b0402Snate  *
111d16b0402Snate  * Data characteristics
112d16b0402Snate  *
113d16b0402Snate  *   B0..7   Number of data bits
114d16b0402Snate  *   B8..10  Parity
115d16b0402Snate  *           0 = None
116d16b0402Snate  *           1 = Odd
117d16b0402Snate  *           2 = Even
118d16b0402Snate  *           3 = Mark
119d16b0402Snate  *           4 = Space
120d16b0402Snate  *   B11..13 Stop Bits
121d16b0402Snate  *           0 = 1
122d16b0402Snate  *           1 = 1.5
123d16b0402Snate  *           2 = 2
124d16b0402Snate  *   B14..15 Reserved
125d16b0402Snate  *
126d16b0402Snate  */
127d16b0402Snate /* FTDI_SIO_SET_DATA */
128d16b0402Snate #define FTDI_SIO_SET_DATA_BITS(n) (n)
129d16b0402Snate #define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
130d16b0402Snate #define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
131d16b0402Snate #define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
132d16b0402Snate #define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
133d16b0402Snate #define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
134d16b0402Snate #define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
135d16b0402Snate #define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
136d16b0402Snate #define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
137f72a8aaaSnate #define FTDI_SIO_SET_BREAK (0x1 << 14)
138d16b0402Snate 
139d16b0402Snate 
140d16b0402Snate /*
141d16b0402Snate  * BmRequestType:   0100 0000B
142d16b0402Snate  * bRequest:        FTDI_SIO_MODEM_CTRL
143d16b0402Snate  * wValue:          ControlValue (see below)
144d16b0402Snate  * wIndex:          Port
145d16b0402Snate  * wLength:         0
146d16b0402Snate  * Data:            None
147d16b0402Snate  *
148d16b0402Snate  * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
149d16b0402Snate  * command will be IGNORED without an error being returned
150d16b0402Snate  * Also - you can not set DTR and RTS with one control message
151d16b0402Snate  *
152d16b0402Snate  * ControlValue
153d16b0402Snate  * B0    DTR state
154d16b0402Snate  *          0 = reset
155d16b0402Snate  *          1 = set
156d16b0402Snate  * B1    RTS state
157d16b0402Snate  *          0 = reset
158d16b0402Snate  *          1 = set
159d16b0402Snate  * B2..7 Reserved
160d16b0402Snate  * B8    DTR state enable
161d16b0402Snate  *          0 = ignore
162d16b0402Snate  *          1 = use DTR state
163d16b0402Snate  * B9    RTS state enable
164d16b0402Snate  *          0 = ignore
165d16b0402Snate  *          1 = use RTS state
166d16b0402Snate  * B10..15 Reserved
167d16b0402Snate  */
168d16b0402Snate /* FTDI_SIO_MODEM_CTRL */
169d16b0402Snate #define FTDI_SIO_SET_DTR_MASK 0x1
170d16b0402Snate #define FTDI_SIO_SET_DTR_HIGH (1 | ( FTDI_SIO_SET_DTR_MASK  << 8))
171d16b0402Snate #define FTDI_SIO_SET_DTR_LOW  (0 | ( FTDI_SIO_SET_DTR_MASK  << 8))
172d16b0402Snate #define FTDI_SIO_SET_RTS_MASK 0x2
173d16b0402Snate #define FTDI_SIO_SET_RTS_HIGH (2 | ( FTDI_SIO_SET_RTS_MASK << 8))
174d16b0402Snate #define FTDI_SIO_SET_RTS_LOW (0 | ( FTDI_SIO_SET_RTS_MASK << 8))
175d16b0402Snate 
176d16b0402Snate 
177d16b0402Snate /*
178d16b0402Snate  *   BmRequestType:  0100 0000b
179d16b0402Snate  *   bRequest:       FTDI_SIO_SET_FLOW_CTRL
180d16b0402Snate  *   wValue:         Xoff/Xon
18134c004ffStdeval  *   wIndex:         Protocol/Port - hIndex is protocol / lIndex is port
182d16b0402Snate  *   wLength:        0
183d16b0402Snate  *   Data:           None
184d16b0402Snate  *
185d16b0402Snate  * hIndex protocol is:
186d16b0402Snate  *   B0 Output handshaking using RTS/CTS
187d16b0402Snate  *       0 = disabled
188d16b0402Snate  *       1 = enabled
189d16b0402Snate  *   B1 Output handshaking using DTR/DSR
190d16b0402Snate  *       0 = disabled
191d16b0402Snate  *       1 = enabled
192d16b0402Snate  *   B2 Xon/Xoff handshaking
193d16b0402Snate  *       0 = disabled
194d16b0402Snate  *       1 = enabled
195d16b0402Snate  *
196d16b0402Snate  * A value of zero in the hIndex field disables handshaking
197d16b0402Snate  *
198d16b0402Snate  * If Xon/Xoff handshaking is specified, the hValue field should contain the
199d16b0402Snate  * XOFF character and the lValue field contains the XON character.
200d16b0402Snate  */
201d16b0402Snate /* FTDI_SIO_SET_FLOW_CTRL */
202d16b0402Snate #define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
203d16b0402Snate #define FTDI_SIO_RTS_CTS_HS 0x1
204d16b0402Snate #define FTDI_SIO_DTR_DSR_HS 0x2
205d16b0402Snate #define FTDI_SIO_XON_XOFF_HS 0x4
206d16b0402Snate 
207d16b0402Snate 
208d16b0402Snate /*
209d16b0402Snate  *  BmRequestType:   0100 0000b
210d16b0402Snate  *  bRequest:        FTDI_SIO_SET_EVENT_CHAR
211d16b0402Snate  *  wValue:          Event Char
212d16b0402Snate  *  wIndex:          Port
213d16b0402Snate  *  wLength:         0
214d16b0402Snate  *  Data:            None
215d16b0402Snate  *
216d16b0402Snate  * wValue:
217d16b0402Snate  *   B0..7   Event Character
218d16b0402Snate  *   B8      Event Character Processing
219d16b0402Snate  *             0 = disabled
220d16b0402Snate  *             1 = enabled
221d16b0402Snate  *   B9..15  Reserved
222d16b0402Snate  *
223d16b0402Snate  * FTDI_SIO_SET_EVENT_CHAR
224d16b0402Snate  *
225d16b0402Snate  * Set the special event character for the specified communications port.
226d16b0402Snate  * If the device sees this character it will immediately return the
227d16b0402Snate  * data read so far - rather than wait 40ms or until 62 bytes are read
228d16b0402Snate  * which is what normally happens.
229d16b0402Snate  */
230d16b0402Snate 
231d16b0402Snate 
232d16b0402Snate 
233d16b0402Snate /*
234d16b0402Snate  *  BmRequestType:  0100 0000b
235d16b0402Snate  *  bRequest:       FTDI_SIO_SET_ERROR_CHAR
236d16b0402Snate  *  wValue:         Error Char
237d16b0402Snate  *  wIndex:         Port
238d16b0402Snate  *  wLength:        0
239d16b0402Snate  *  Data:           None
240d16b0402Snate  *
241d16b0402Snate  *  Error Char
242d16b0402Snate  *  B0..7  Error Character
243d16b0402Snate  *  B8     Error Character Processing
244d16b0402Snate  *           0 = disabled
245d16b0402Snate  *           1 = enabled
246d16b0402Snate  *  B9..15 Reserved
247d16b0402Snate  *
248d16b0402Snate  *
249d16b0402Snate  * FTDI_SIO_SET_ERROR_CHAR
250d16b0402Snate  * Set the parity error replacement character for the specified communications
251d16b0402Snate  * port.
252d16b0402Snate  */
253d16b0402Snate 
254d16b0402Snate 
255d16b0402Snate /*
256d16b0402Snate  *   BmRequestType:   1100 0000b
257fda12999Smbalmer  *   bRequest:        FTDI_SIO_GET_STATUS
258d16b0402Snate  *   wValue:          zero
259d16b0402Snate  *   wIndex:          Port
260fda12999Smbalmer  *   wLength:         1		(2 for newer devices like the FT232R)
261d16b0402Snate  *   Data:            Status
262d16b0402Snate  *
263d16b0402Snate  * One byte of data is returned
264d16b0402Snate  * B0..3 0
265d16b0402Snate  * B4    CTS
266d16b0402Snate  *         0 = inactive
267d16b0402Snate  *         1 = active
268d16b0402Snate  * B5    DSR
269d16b0402Snate  *         0 = inactive
270d16b0402Snate  *         1 = active
271d16b0402Snate  * B6    Ring Indicator (RI)
272d16b0402Snate  *         0 = inactive
273d16b0402Snate  *         1 = active
274d16b0402Snate  * B7    Receive Line Signal Detect (RLSD)
275d16b0402Snate  *         0 = inactive
276d16b0402Snate  *         1 = active
277d16b0402Snate  *
278fda12999Smbalmer  * FTDI_SIO_GET_STATUS
2790897b806Snate  * Retrieve the current value of the modem status register.
280d16b0402Snate  */
281d16b0402Snate #define FTDI_SIO_CTS_MASK 0x10
282d16b0402Snate #define FTDI_SIO_DSR_MASK 0x20
283d16b0402Snate #define FTDI_SIO_RI_MASK  0x40
284d16b0402Snate #define FTDI_SIO_RLSD_MASK 0x80
285d16b0402Snate 
286d16b0402Snate 
287d16b0402Snate 
288d16b0402Snate /*
289d16b0402Snate  *
290d16b0402Snate  * DATA FORMAT
291d16b0402Snate  *
292d16b0402Snate  * IN Endpoint
293d16b0402Snate  *
294d16b0402Snate  * The device reserves the first two bytes of data on this endpoint to contain
295d16b0402Snate  * the current values of the modem and line status registers. In the absence of
296d16b0402Snate  * data, the device generates a message consisting of these two status bytes
297d16b0402Snate  * every 40 ms.
298d16b0402Snate  *
299d16b0402Snate  * Byte 0: Modem Status
300d16b0402Snate  *   NOTE: 4 upper bits have same layout as the MSR register in a 16550
301d16b0402Snate  *
302d16b0402Snate  * Offset	Description
303d16b0402Snate  * B0..3	Port
304d16b0402Snate  * B4		Clear to Send (CTS)
305d16b0402Snate  * B5		Data Set Ready (DSR)
306d16b0402Snate  * B6		Ring Indicator (RI)
307d16b0402Snate  * B7		Receive Line Signal Detect (RLSD)
308d16b0402Snate  *
309d16b0402Snate  * Byte 1: Line Status
310d16b0402Snate  *   NOTE: same layout as the LSR register in a 16550
311d16b0402Snate  *
312d16b0402Snate  * Offset	Description
313d16b0402Snate  * B0	Data Ready (DR)
314d16b0402Snate  * B1	Overrun Error (OE)
315d16b0402Snate  * B2	Parity Error (PE)
316d16b0402Snate  * B3	Framing Error (FE)
317d16b0402Snate  * B4	Break Interrupt (BI)
318d16b0402Snate  * B5	Transmitter Holding Register (THRE)
319d16b0402Snate  * B6	Transmitter Empty (TEMT)
320d16b0402Snate  * B7	Error in RCVR FIFO
321d16b0402Snate  *
322d16b0402Snate  *
323d16b0402Snate  * OUT Endpoint
324d16b0402Snate  *
325d16b0402Snate  * This device reserves the first bytes of data on this endpoint contain the
326d16b0402Snate  * length and port identifier of the message. For the FTDI USB Serial converter
327d16b0402Snate  * the port identifier is always 1.
328d16b0402Snate  *
329d16b0402Snate  * Byte 0: Port & length
330d16b0402Snate  *
331d16b0402Snate  * Offset	Description
332d16b0402Snate  * B0..1	Port
333d16b0402Snate  * B2..7	Length of message - (not including Byte 0)
334d16b0402Snate  *
335d16b0402Snate  */
336d16b0402Snate #define FTDI_PORT_MASK 0x0f
337d16b0402Snate #define FTDI_MSR_MASK 0xf0
338d16b0402Snate #define FTDI_GET_MSR(p) (((p)[0]) & FTDI_MSR_MASK)
339d16b0402Snate #define FTDI_GET_LSR(p) ((p)[1])
340d16b0402Snate #define FTDI_LSR_MASK (~0x60) /* interesting bits */
341d16b0402Snate #define FTDI_OUT_TAG(len, port) (((len) << 2) | (port))
342