File: /usr/src/linux/drivers/char/sh-sci.h
1 /* $Id: sh-sci.h,v 1.8 2000/03/08 15:19:39 gniibe Exp $
2 *
3 * linux/drivers/char/sh-sci.h
4 *
5 * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
6 * Copyright (C) 1999, 2000 Niibe Yutaka
7 * Copyright (C) 2000 Greg Banks
8 * Modified to support multiple serial ports. Stuart Menefy (May 2000).
9 *
10 */
11 #include <linux/config.h>
12
13 /* Values for sci_port->type */
14 #define PORT_SCI 0
15 #define PORT_SCIF 1
16 #define PORT_IRDA 1 /* XXX: temporary assignment */
17
18 /* Offsets into the sci_port->irqs array */
19 #define SCIx_ERI_IRQ 0
20 #define SCIx_RXI_IRQ 1
21 #define SCIx_TXI_IRQ 2
22
23 /* ERI, RXI, TXI, BRI */
24 #define SCI_IRQS { 23, 24, 25, 0 }
25 #define SH3_SCIF_IRQS { 56, 57, 59, 58 }
26 #define SH3_IRDA_IRQS { 52, 53, 55, 54 }
27 #define SH4_SCIF_IRQS { 40, 41, 43, 42 }
28 #define STB1_SCIF1_IRQS {23, 24, 26, 25 }
29
30 #if defined(CONFIG_CPU_SUBTYPE_SH7708)
31 # define SCI_NPORTS 1
32 # define SCI_INIT { \
33 { {}, PORT_SCI, 0xfffffe80, SCI_IRQS, sci_init_pins_sci } \
34 }
35 # define SCSPTR 0xffffff7c /* 8 bit */
36 # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
37 # define SCI_ONLY
38 #elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
39 # define SCI_NPORTS 3
40 # define SCI_INIT { \
41 { {}, PORT_SCI, 0xfffffe80, SCI_IRQS, sci_init_pins_sci }, \
42 { {}, PORT_SCIF, 0xA4000150, SH3_SCIF_IRQS, sci_init_pins_scif }, \
43 { {}, PORT_SCIF, 0xA4000140, SH3_IRDA_IRQS, sci_init_pins_irda } \
44 }
45 # define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */
46 # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */
47 # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
48 # define SCI_AND_SCIF
49 #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
50 # define SCI_NPORTS 2
51 # define SCI_INIT { \
52 { {}, PORT_SCI, 0xffe00000, SCI_IRQS, sci_init_pins_sci }, \
53 { {}, PORT_SCIF, 0xFFE80000, SH4_SCIF_IRQS, sci_init_pins_scif } \
54 }
55 # define SCSPTR1 0xffe0001c /* 8 bit SCI */
56 # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
57 # define SCIF_ORER 0x0001 /* overrun error bit */
58 # define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \
59 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \
60 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
61 # define SCI_AND_SCIF
62 #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
63 # define SCI_NPORTS 2
64 # define SCI_INIT { \
65 { {}, PORT_SCIF, 0xffe00000, STB1_SCIF1_IRQS, sci_init_pins_scif }, \
66 { {}, PORT_SCIF, 0xffe80000, SH4_SCIF_IRQS, sci_init_pins_scif } \
67 }
68 # define SCSPTR1 0xffe00020 /* 16 bit SCIF */
69 # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
70 # define SCIF_ORER 0x0001 /* overrun error bit */
71 # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
72 # define SCIF_ONLY
73 #else
74 # error CPU subtype not defined
75 #endif
76
77 /* SCSCR */
78 #define SCI_CTRL_FLAGS_TIE 0x80 /* all */
79 #define SCI_CTRL_FLAGS_RIE 0x40 /* all */
80 #define SCI_CTRL_FLAGS_TE 0x20 /* all */
81 #define SCI_CTRL_FLAGS_RE 0x10 /* all */
82 /* SCI_CTRL_FLAGS_REIE 0x08 * 7750 SCIF */
83 /* SCI_CTRL_FLAGS_MPIE 0x08 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
84 /* SCI_CTRL_FLAGS_TEIE 0x04 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
85 /* SCI_CTRL_FLAGS_CKE1 0x02 * all */
86 /* SCI_CTRL_FLAGS_CKE0 0x01 * 7707 SCI/SCIF, 7708 SCI, 7709 SCI/SCIF, 7750 SCI */
87
88 /* SCxSR SCI */
89 #define SCI_TDRE 0x80 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
90 #define SCI_RDRF 0x40 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
91 #define SCI_ORER 0x20 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
92 #define SCI_FER 0x10 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
93 #define SCI_PER 0x08 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
94 #define SCI_TEND 0x04 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
95 /* SCI_MPB 0x02 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
96 /* SCI_MPBT 0x01 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
97
98 #define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ORER)
99
100 /* SCxSR SCIF */
101 #define SCIF_ER 0x0080 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
102 #define SCIF_TEND 0x0040 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
103 #define SCIF_TDFE 0x0020 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
104 #define SCIF_BRK 0x0010 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
105 #define SCIF_FER 0x0008 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
106 #define SCIF_PER 0x0004 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
107 #define SCIF_RDF 0x0002 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
108 #define SCIF_DR 0x0001 /* 7707 SCIF, 7709 SCIF, 7750 SCIF */
109
110 #define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
111
112 #if defined(SCI_ONLY)
113 # define SCxSR_TEND(port) SCI_TEND
114 # define SCxSR_ERRORS(port) SCI_ERRORS
115 # define SCxSR_RDxF(port) SCI_RDRF
116 # define SCxSR_TDxE(port) SCI_TDRE
117 # define SCxSR_ORER(port) SCI_ORER
118 # define SCxSR_FER(port) SCI_FER
119 # define SCxSR_PER(port) SCI_PER
120 # define SCxSR_BRK(port) 0x00
121 # define SCxSR_RDxF_CLEAR(port) 0xbc
122 # define SCxSR_ERROR_CLEAR(port) 0xc4
123 # define SCxSR_TDxE_CLEAR(port) 0x78
124 # define SCxSR_BREAK_CLEAR(port) 0xc4
125 #elif defined(SCIF_ONLY)
126 # define SCxSR_TEND(port) SCIF_TEND
127 # define SCxSR_ERRORS(port) SCIF_ERRORS
128 # define SCxSR_RDxF(port) SCIF_RDF
129 # define SCxSR_TDxE(port) SCIF_TDFE
130 # define SCxSR_ORER(port) 0x0000
131 # define SCxSR_FER(port) SCIF_FER
132 # define SCxSR_PER(port) SCIF_PER
133 # define SCxSR_BRK(port) SCIF_BRK
134 # define SCxSR_RDxF_CLEAR(port) 0x00fc
135 # define SCxSR_ERROR_CLEAR(port) 0x0073
136 # define SCxSR_TDxE_CLEAR(port) 0x00df
137 # define SCxSR_BREAK_CLEAR(port) 0x00e3
138 #else
139 # define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
140 # define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
141 # define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
142 # define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
143 # define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : 0x0000)
144 # define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
145 # define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
146 # define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
147 # define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc)
148 # define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073)
149 # define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df)
150 # define SCxSR_BREAK_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x00e3)
151 #endif
152
153 /* SCFCR */
154 #define SCFCR_RFRST 0x0002
155 #define SCFCR_TFRST 0x0004
156 #define SCFCR_MCE 0x0008
157
158 #define SCI_MAJOR 204
159 #define SCI_MINOR_START 8
160
161 /* Generic serial flags */
162 #define SCI_RX_THROTTLE 0x0000001
163
164 /* generic serial tty */
165 #define O_OTHER(tty) \
166 ((O_OLCUC(tty)) ||\
167 (O_ONLCR(tty)) ||\
168 (O_OCRNL(tty)) ||\
169 (O_ONOCR(tty)) ||\
170 (O_ONLRET(tty)) ||\
171 (O_OFILL(tty)) ||\
172 (O_OFDEL(tty)) ||\
173 (O_NLDLY(tty)) ||\
174 (O_CRDLY(tty)) ||\
175 (O_TABDLY(tty)) ||\
176 (O_BSDLY(tty)) ||\
177 (O_VTDLY(tty)) ||\
178 (O_FFDLY(tty)))
179
180 #define I_OTHER(tty) \
181 ((I_INLCR(tty)) ||\
182 (I_IGNCR(tty)) ||\
183 (I_ICRNL(tty)) ||\
184 (I_IUCLC(tty)) ||\
185 (L_ISIG(tty)))
186
187 #define SCI_MAGIC 0xbabeface
188
189 /*
190 * Events are used to schedule things to happen at timer-interrupt
191 * time, instead of at rs interrupt time.
192 */
193 #define SCI_EVENT_WRITE_WAKEUP 0
194
195 struct sci_port {
196 struct gs_port gs;
197 int type;
198 unsigned int base;
199 unsigned char irqs[4]; /* ERI, RXI, TXI, BRI */
200 void (*init_pins)(struct sci_port* port, unsigned int cflag);
201 unsigned int old_cflag;
202 struct async_icount icount;
203 struct tq_struct tqueue;
204 unsigned long event;
205 };
206
207 #define SCI_IN(size, offset) \
208 unsigned int addr = port->base + (offset); \
209 if ((size) == 8) { \
210 return ctrl_inb(addr); \
211 } else { \
212 return ctrl_inw(addr); \
213 }
214 #define SCI_OUT(size, offset, value) \
215 unsigned int addr = port->base + (offset); \
216 if ((size) == 8) { \
217 ctrl_outb(value, addr); \
218 } else { \
219 ctrl_outw(value, addr); \
220 }
221
222 #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
223 static inline unsigned int sci_##name##_in(struct sci_port* port) \
224 { \
225 if (port->type == PORT_SCI) { \
226 SCI_IN(sci_size, sci_offset) \
227 } else { \
228 SCI_IN(scif_size, scif_offset); \
229 } \
230 } \
231 static inline void sci_##name##_out(struct sci_port* port, unsigned int value) \
232 { \
233 if (port->type == PORT_SCI) { \
234 SCI_OUT(sci_size, sci_offset, value) \
235 } else { \
236 SCI_OUT(scif_size, scif_offset, value); \
237 } \
238 }
239
240 #define CPU_SCIF_FNS(name, scif_offset, scif_size) \
241 static inline unsigned int sci_##name##_in(struct sci_port* port) \
242 { \
243 SCI_IN(scif_size, scif_offset); \
244 } \
245 static inline void sci_##name##_out(struct sci_port* port, unsigned int value) \
246 { \
247 SCI_OUT(scif_size, scif_offset, value); \
248 }
249
250 #ifdef __sh3__
251 #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
252 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
253 CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size)
254 #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
255 CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
256 #else
257 #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
258 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
259 CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
260 #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
261 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
262 #endif
263
264 /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 */
265 /* name off sz off sz off sz off sz */
266 SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16)
267 SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8)
268 SCIx_FNS(SCSCR, 0x04, 8, 0x08, 8, 0x04, 8, 0x08, 16)
269 SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8)
270 SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16)
271 SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8)
272 SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
273 SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
274 SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
275
276 #define sci_in(port, reg) sci_##reg##_in(port)
277 #define sci_out(port, reg, value) sci_##reg##_out(port, value)
278
279 #if defined(CONFIG_CPU_SUBTYPE_SH7708)
280 static inline int sci_rxd_in(struct sci_port *port)
281 {
282 if (port->base == 0xfffffe80)
283 return ctrl_inb(SCSPTR)&0x01 ? 1 : 0; /* SCI */
284 return 1;
285 }
286 #elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
287 static inline int sci_rxd_in(struct sci_port *port)
288 {
289 if (port->base == 0xfffffe80)
290 return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCI */
291 if (port->base == 0xa4000150)
292 return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
293 if (port->base == 0xa4000140)
294 return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
295 return 1;
296 }
297 #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
298 static inline int sci_rxd_in(struct sci_port *port)
299 {
300 #ifndef SCIF_ONLY
301 if (port->base == 0xffe00000)
302 return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */
303 #endif
304 #ifndef SCI_ONLY
305 if (port->base == 0xffe80000)
306 return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
307 #endif
308 return 1;
309 }
310 #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
311 static inline int sci_rxd_in(struct sci_port *port)
312 {
313 if (port->base == 0xffe00000)
314 return ctrl_inw(SCSPTR1)&0x0001 ? 1 : 0; /* SCIF */
315 else
316 return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
317
318 }
319 #endif
320
321 /*
322 * Values for the BitRate Register (SCBRR)
323 *
324 * The values are actually divisors for a frequency which can
325 * be internal to the SH3 (14.7456MHz) or derived from an external
326 * clock source. This driver assumes the internal clock is used;
327 * to support using an external clock source, config options or
328 * possibly command-line options would need to be added.
329 *
330 * Also, to support speeds below 2400 (why?) the lower 2 bits of
331 * the SCSMR register would also need to be set to non-zero values.
332 *
333 * -- Greg Banks 27Feb2000
334 *
335 * Answer: The SCBRR register is only eight bits, and the value in
336 * it gets larger with lower baud rates. At around 2400 (depending on
337 * the peripherial module clock) you run out of bits. However the
338 * lower two bits of SCSMR allow the module clock to be divided down,
339 * scaling the value which is needed in SCBRR.
340 *
341 * -- Stuart Menefy - 23 May 2000
342 *
343 * I meant, why would anyone bother with bitrates below 2400.
344 *
345 * -- Greg Banks - 7Jul2000
346 *
347 * You "speedist"! How will I use my 110bps ASR-33 teletype with paper
348 * tape reader as a console!
349 *
350 * -- Mitch Davis - 15 Jul 2000
351 */
352
353 #define PCLK (current_cpu_data.module_clock)
354
355 #define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1)
356 #define BPS_2400 SCBRR_VALUE(2400)
357 #define BPS_4800 SCBRR_VALUE(4800)
358 #define BPS_9600 SCBRR_VALUE(9600)
359 #define BPS_19200 SCBRR_VALUE(19200)
360 #define BPS_38400 SCBRR_VALUE(38400)
361 #define BPS_57600 SCBRR_VALUE(57600)
362 #define BPS_115200 SCBRR_VALUE(115200)
363
364