1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_USBSER_USBFTDI_UFTDI_REG_H
28 #define	_USBSER_USBFTDI_UFTDI_REG_H
29 
30 /*
31  * $NetBSD: uftdireg.h,v 1.6 2002/07/11 21:14:28 augustss Exp $
32  * $FreeBSD: src/sys/dev/usb/uftdireg.h,v 1.2 2004/07/01 17:16:20 brooks Exp $
33  */
34 
35 /*
36  * Definitions for the FTDI USB Single Port Serial Converter -
37  * known as FTDI_SIO (Serial Input/Output application of the chipset)
38  *
39  * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
40  * of the protocol required to talk to the device and ongoing assistence
41  * during development.
42  *
43  * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc. is the original
44  * author of this file.
45  */
46 /* Modified by Lennart Augustsson */
47 
48 #ifdef	__cplusplus
49 extern "C" {
50 #endif
51 
52 /* Vendor Request Interface */
53 #define	FTDI_SIO_RESET 		0 /* Reset the port */
54 #define	FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
55 #define	FTDI_SIO_SET_FLOW_CTRL	2 /* Set flow control register */
56 #define	FTDI_SIO_SET_BAUD_RATE	3 /* Set baud rate */
57 #define	FTDI_SIO_SET_DATA	4 /* Set the data characteristics of the port */
58 #define	FTDI_SIO_GET_STATUS	5 /* Retrieve current value of status reg */
59 #define	FTDI_SIO_SET_EVENT_CHAR	6 /* Set the event character */
60 #define	FTDI_SIO_SET_ERROR_CHAR	7 /* Set the error character */
61 
62 /* Port Identifier Table */
63 #define	FTDI_PIT_DEFAULT 	0 /* SIOA */
64 #define	FTDI_PIT_SIOA		1 /* SIOA */
65 #define	FTDI_PIT_SIOB		2 /* SIOB */
66 #define	FTDI_PIT_PARALLEL	3 /* Parallel */
67 
68 enum uftdi_type {
69 	UFTDI_TYPE_SIO,
70 	UFTDI_TYPE_8U232AM
71 };
72 
73 /*
74  * BmRequestType:  0100 0000B
75  * bRequest:       FTDI_SIO_RESET
76  * wValue:         Control Value
77  *                   0 = Reset SIO
78  *                   1 = Purge RX buffer
79  *                   2 = Purge TX buffer
80  * wIndex:         Port
81  * wLength:        0
82  * Data:           None
83  *
84  * The Reset SIO command has this effect:
85  *
86  *    Sets flow control set to 'none'
87  *    Event char = 0x0d
88  *    Event trigger = disabled
89  *    Purge RX buffer
90  *    Purge TX buffer
91  *    Clear DTR
92  *    Clear RTS
93  *    baud and data format not reset
94  *
95  * The Purge RX and TX buffer commands affect nothing except the buffers
96  *
97  */
98 /* FTDI_SIO_RESET */
99 #define	FTDI_SIO_RESET_SIO 0
100 #define	FTDI_SIO_RESET_PURGE_RX 1
101 #define	FTDI_SIO_RESET_PURGE_TX 2
102 
103 
104 /*
105  * BmRequestType:  0100 0000B
106  * bRequest:       FTDI_SIO_SET_BAUDRATE
107  * wValue:         BaudRate value - see below
108  * wIndex:         Port
109  * wLength:        0
110  * Data:           None
111  */
112 /* FTDI_SIO_SET_BAUDRATE */
113 enum {
114 	ftdi_sio_b300 = 0,
115 	ftdi_sio_b600 = 1,
116 	ftdi_sio_b1200 = 2,
117 	ftdi_sio_b2400 = 3,
118 	ftdi_sio_b4800 = 4,
119 	ftdi_sio_b9600 = 5,
120 	ftdi_sio_b19200 = 6,
121 	ftdi_sio_b38400 = 7,
122 	ftdi_sio_b57600 = 8,
123 	ftdi_sio_b115200 = 9
124 };
125 
126 enum {
127 	ftdi_8u232am_b300 = 0x2710,
128 	ftdi_8u232am_b600 = 0x1388,
129 	ftdi_8u232am_b1200 = 0x09c4,
130 	ftdi_8u232am_b2400 = 0x04e2,
131 	ftdi_8u232am_b4800 = 0x0271,
132 	ftdi_8u232am_b9600 = 0x4138,
133 	ftdi_8u232am_b19200 = 0x809c,
134 	ftdi_8u232am_b38400 = 0xc04e,
135 	ftdi_8u232am_b57600 = 0x0034,
136 	ftdi_8u232am_b115200 = 0x001a,
137 	ftdi_8u232am_b230400 = 0x000d,
138 	ftdi_8u232am_b460800 = 0x4006,
139 	ftdi_8u232am_b921600 = 0x8003,
140 	ftdi_8u232am_b2000000 = 0x0001,	/* special case for 2M baud */
141 	ftdi_8u232am_b3000000 = 0x0000,	/* special case for 3M baud */
142 };
143 
144 /*
145  * BmRequestType:  0100 0000B
146  * bRequest:       FTDI_SIO_SET_DATA
147  * wValue:         Data characteristics (see below)
148  * wIndex:         Port
149  * wLength:        0
150  * Data:           No
151  *
152  * Data characteristics
153  *
154  *   B0..7   Number of data bits
155  *   B8..10  Parity
156  *           0 = None
157  *           1 = Odd
158  *           2 = Even
159  *           3 = Mark
160  *           4 = Space
161  *   B11..13 Stop Bits
162  *           0 = 1
163  *           1 = 1.5
164  *           2 = 2
165  *   B14..15 Reserved
166  *
167  */
168 /* FTDI_SIO_SET_DATA */
169 #define	FTDI_SIO_SET_DATA_BITS(n) (n)
170 #define	FTDI_SIO_SET_DATA_BITS_MASK	0xff
171 
172 #define	FTDI_SIO_SET_DATA_PARITY_SHIFT		8
173 #define	FTDI_SIO_SET_DATA_PARITY_MASK		0x7
174 #define	FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
175 #define	FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
176 #define	FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
177 #define	FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
178 #define	FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
179 
180 #define	FTDI_SIO_SET_DATA_STOP_BITS_SHIFT	11
181 #define	FTDI_SIO_SET_DATA_STOP_BITS_MASK	0x3
182 #define	FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
183 #define	FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
184 #define	FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
185 
186 #define	FTDI_SIO_SET_BREAK (0x1 << 14)
187 
188 
189 /*
190  * BmRequestType:   0100 0000B
191  * bRequest:        FTDI_SIO_MODEM_CTRL
192  * wValue:          ControlValue (see below)
193  * wIndex:          Port
194  * wLength:         0
195  * Data:            None
196  *
197  * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
198  * command will be IGNORED without an error being returned
199  * Also - you can not set DTR and RTS with one control message
200  *
201  * ControlValue
202  * B0    DTR state
203  *          0 = reset
204  *          1 = set
205  * B1    RTS state
206  *          0 = reset
207  *          1 = set
208  * B2..7 Reserved
209  * B8    DTR state enable
210  *          0 = ignore
211  *          1 = use DTR state
212  * B9    RTS state enable
213  *          0 = ignore
214  *          1 = use RTS state
215  * B10..15 Reserved
216  */
217 /* FTDI_SIO_MODEM_CTRL */
218 #define	FTDI_SIO_SET_DTR_MASK	0x1
219 #define	FTDI_SIO_SET_DTR_HIGH	(1 | (FTDI_SIO_SET_DTR_MASK  << 8))
220 #define	FTDI_SIO_SET_DTR_LOW 	(0 | (FTDI_SIO_SET_DTR_MASK  << 8))
221 #define	FTDI_SIO_SET_RTS_MASK	0x2
222 #define	FTDI_SIO_SET_RTS_HIGH	(2 | (FTDI_SIO_SET_RTS_MASK << 8))
223 #define	FTDI_SIO_SET_RTS_LOW	(0 | (FTDI_SIO_SET_RTS_MASK << 8))
224 
225 
226 /*
227  *   BmRequestType:  0100 0000b
228  *   bRequest:       FTDI_SIO_SET_FLOW_CTRL
229  *   wValue:         Xoff/Xon
230  *   wIndex:         Protocol/Port - hIndex is protocl / lIndex is port
231  *   wLength:        0
232  *   Data:           None
233  *
234  * hIndex protocol is:
235  *   B0 Output handshaking using RTS/CTS
236  *       0 = disabled
237  *       1 = enabled
238  *   B1 Output handshaking using DTR/DSR
239  *       0 = disabled
240  *       1 = enabled
241  *   B2 Xon/Xoff handshaking
242  *       0 = disabled
243  *       1 = enabled
244  *
245  * A value of zero in the hIndex field disables handshaking
246  *
247  * If Xon/Xoff handshaking is specified, the hValue field should contain the
248  * XOFF character and the lValue field contains the XON character.
249  */
250 /* FTDI_SIO_SET_FLOW_CTRL */
251 #define	FTDI_SIO_DISABLE_FLOW_CTRL 0x0
252 #define	FTDI_SIO_RTS_CTS_HS 0x1
253 #define	FTDI_SIO_DTR_DSR_HS 0x2
254 #define	FTDI_SIO_XON_XOFF_HS 0x4
255 
256 
257 /*
258  *  BmRequestType:   0100 0000b
259  *  bRequest:        FTDI_SIO_SET_EVENT_CHAR
260  *  wValue:          Event Char
261  *  wIndex:          Port
262  *  wLength:         0
263  *  Data:            None
264  *
265  * wValue:
266  *   B0..7   Event Character
267  *   B8      Event Character Processing
268  *             0 = disabled
269  *             1 = enabled
270  *   B9..15  Reserved
271  *
272  * FTDI_SIO_SET_EVENT_CHAR
273  *
274  * Set the special event character for the specified communications port.
275  * If the device sees this character it will immediately return the
276  * data read so far - rather than wait 40ms or until 62 bytes are read
277  * which is what normally happens.
278  */
279 
280 
281 
282 /*
283  *  BmRequestType:  0100 0000b
284  *  bRequest:       FTDI_SIO_SET_ERROR_CHAR
285  *  wValue:         Error Char
286  *  wIndex:         Port
287  *  wLength:        0
288  *  Data:           None
289  *
290  *  Error Char
291  *  B0..7  Error Character
292  *  B8     Error Character Processing
293  *           0 = disabled
294  *           1 = enabled
295  *  B9..15 Reserved
296  *
297  *
298  * FTDI_SIO_SET_ERROR_CHAR
299  * Set the parity error replacement character for the specified communications
300  * port.
301  */
302 
303 
304 /*
305  *   BmRequestType:   1100 0000b
306  *   bRequest:        FTDI_SIO_GET_MODEM_STATUS
307  *   wValue:          zero
308  *   wIndex:          Port
309  *   wLength:         1
310  *   Data:            Status
311  *
312  * One byte of data is returned
313  * B0..3 0
314  * B4    CTS
315  *         0 = inactive
316  *         1 = active
317  * B5    DSR
318  *         0 = inactive
319  *         1 = active
320  * B6    Ring Indicator (RI)
321  *         0 = inactive
322  *         1 = active
323  * B7    Receive Line Signal Detect (RLSD)
324  *         0 = inactive
325  *         1 = active
326  *
327  * FTDI_SIO_GET_MODEM_STATUS
328  * Retrieve the current value of the modem status register.
329  */
330 #define	FTDI_SIO_CTS_MASK 0x10
331 #define	FTDI_SIO_DSR_MASK 0x20
332 #define	FTDI_SIO_RI_MASK  0x40
333 #define	FTDI_SIO_RLSD_MASK 0x80
334 
335 
336 
337 /*
338  *
339  * DATA FORMAT
340  *
341  * IN Endpoint
342  *
343  * The device reserves the first two bytes of data on this endpoint to contain
344  * the current values of the modem and line status registers. In the absence of
345  * data, the device generates a message consisting of these two status bytes
346  * every 40 ms.
347  *
348  * Byte 0: Modem Status
349  *   NOTE: 4 upper bits have same layout as the MSR register in a 16550
350  *
351  * Offset	Description
352  * B0..3	Port
353  * B4		Clear to Send (CTS)
354  * B5		Data Set Ready (DSR)
355  * B6		Ring Indicator (RI)
356  * B7		Receive Line Signal Detect (RLSD)
357  *
358  * Byte 1: Line Status
359  *   NOTE: same layout as the LSR register in a 16550
360  *
361  * Offset	Description
362  * B0	Data Ready (DR)
363  * B1	Overrun Error (OE)
364  * B2	Parity Error (PE)
365  * B3	Framing Error (FE)
366  * B4	Break Interrupt (BI)
367  * B5	Transmitter Holding Register (THRE)
368  * B6	Transmitter Empty (TEMT)
369  * B7	Error in RCVR FIFO
370  *
371  *
372  * OUT Endpoint
373  *
374  * This device reserves the first bytes of data on this endpoint contain the
375  * length and port identifier of the message. For the FTDI USB Serial converter
376  * the port identifier is always 1.
377  *
378  * Byte 0: Port & length
379  *
380  * Offset	Description
381  * B0..1	Port
382  * B2..7	Length of message - (not including Byte 0)
383  *
384  */
385 #define	FTDI_PORT_MASK 0x0f
386 #define	FTDI_MSR_MASK 0xf0
387 #define	FTDI_GET_MSR(p) (((p)[0]) & FTDI_MSR_MASK)
388 #define	FTDI_GET_LSR(p) ((p)[1])
389 #define	FTDI_LSR_MASK		(~0x60)	/* interesting rx bits */
390 
391 #define	FTDI_MSR_STATUS_CTS	0x10
392 #define	FTDI_MSR_STATUS_DSR	0x20
393 #define	FTDI_MSR_STATUS_RI	0x40
394 #define	FTDI_MSR_STATUS_RLSD	0x80	/* aka Carrier Detect */
395 
396 #define	FTDI_LSR_STATUS_OE	0x02	/* overrun */
397 #define	FTDI_LSR_STATUS_PE	0x04	/* parity */
398 #define	FTDI_LSR_STATUS_FE	0x08	/* framing */
399 #define	FTDI_LSR_STATUS_BI	0x10	/* break */
400 #define	FTDI_LSR_STATUS_THRE	0x20	/* tx hold register is now empty */
401 #define	FTDI_LSR_STATUS_TEMT	0x40	/* tx shift register is now empty */
402 
403 #define	FTDI_OUT_TAG(len, port) (((len) << 2) | (port))
404 
405 #ifdef	__cplusplus
406 }
407 #endif
408 
409 #endif	/* _USBSER_USBFTDI_UFTDI_REG_H */
410