ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / vr41xx / common / serial.c
1 /*
2  *  serial.c, Serial Interface Unit routines for NEC VR4100 series.
3  *
4  *  Copyright (C) 2002  MontaVista Software Inc.
5  *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6  *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 /*
23  * Changes:
24  *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
25  *  - New creation, NEC VR4122 and VR4131 are supported.
26  *  - Added support for NEC VR4111 and VR4121.
27  *
28  *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
29  *  - Added support for NEC VR4133.
30  */
31 #include <linux/init.h>
32 #include <linux/types.h>
33 #include <linux/tty.h>
34 #include <linux/serial.h>
35 #include <linux/serial_core.h>
36 #include <linux/smp.h>
37
38 #include <asm/addrspace.h>
39 #include <asm/cpu.h>
40 #include <asm/io.h>
41 #include <asm/vr41xx/vr41xx.h>
42
43 /* VR4111 and VR4121 SIU Registers */
44 #define SIURB_TYPE1             KSEG1ADDR(0x0c000000)
45 #define SIUIRSEL_TYPE1          KSEG1ADDR(0x0c000008)
46
47 /* VR4122, VR4131 and VR4133 SIU Registers */
48 #define SIURB_TYPE2             KSEG1ADDR(0x0f000800)
49 #define SIUIRSEL_TYPE2          KSEG1ADDR(0x0f000808)
50
51  #define USE_RS232C             0x00
52  #define USE_IRDA               0x01
53  #define SIU_USES_IRDA          0x00
54  #define FIR_USES_IRDA          0x02
55  #define IRDA_MODULE_SHARP      0x00
56  #define IRDA_MODULE_TEMIC      0x04
57  #define IRDA_MODULE_HP         0x08
58  #define TMICTX                 0x10
59  #define TMICMODE               0x20
60
61 #define SIU_BASE_BAUD           1152000
62
63 /* VR4122 and VR4131 DSIU Registers */
64 #define DSIURB                  KSEG1ADDR(0x0f000820)
65
66 #define MDSIUINTREG             KSEG1ADDR(0x0f000096)
67  #define INTDSIU                0x0800
68
69 #define DSIU_BASE_BAUD          1152000
70
71 int vr41xx_serial_ports = 0;
72
73 void vr41xx_siu_ifselect(int interface, int module)
74 {
75         u16 val = USE_RS232C;   /* Select RS-232C */
76
77         /* Select IrDA */
78         if (interface == SIU_IRDA) {
79                 switch (module) {
80                 case IRDA_SHARP:
81                         val = IRDA_MODULE_SHARP;
82                         break;
83                 case IRDA_TEMIC:
84                         val = IRDA_MODULE_TEMIC;
85                         break;
86                 case IRDA_HP:
87                         val = IRDA_MODULE_HP;
88                         break;
89                 }
90                 val |= USE_IRDA | SIU_USES_IRDA;
91         }
92
93         switch (current_cpu_data.cputype) {
94         case CPU_VR4111:
95         case CPU_VR4121:
96                 writew(val, SIUIRSEL_TYPE1);
97                 break;
98         case CPU_VR4122:
99         case CPU_VR4131:
100         case CPU_VR4133:
101                 writew(val, SIUIRSEL_TYPE2);
102                 break;
103         default:
104                 printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
105                 break;
106         }
107 }
108
109 void __init vr41xx_siu_init(int interface, int module)
110 {
111         struct uart_port port;
112
113         vr41xx_siu_ifselect(interface, module);
114
115         memset(&port, 0, sizeof(port));
116
117         port.line = vr41xx_serial_ports;
118         port.uartclk = SIU_BASE_BAUD;
119         port.irq = SIU_IRQ;
120         port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
121         switch (current_cpu_data.cputype) {
122         case CPU_VR4111:
123         case CPU_VR4121:
124                 port.membase = (char *)SIURB_TYPE1;
125                 break;
126         case CPU_VR4122:
127         case CPU_VR4131:
128         case CPU_VR4133:
129                 port.membase = (char *)SIURB_TYPE2;
130                 break;
131         default:
132                 panic("Unexpected CPU of NEC VR4100 series");
133                 break;
134         }
135         port.regshift = 0;
136         port.iotype = UPIO_MEM;
137         if (early_serial_setup(&port) != 0)
138                 printk(KERN_ERR "SIU setup failed!\n");
139
140         vr41xx_supply_clock(SIU_CLOCK);
141
142         vr41xx_serial_ports++;
143 }
144
145 void __init vr41xx_dsiu_init(void)
146 {
147         struct uart_port port;
148
149         if (current_cpu_data.cputype != CPU_VR4122 &&
150             current_cpu_data.cputype != CPU_VR4131 &&
151             current_cpu_data.cputype != CPU_VR4133)
152                 return;
153
154         memset(&port, 0, sizeof(port));
155
156         port.line = vr41xx_serial_ports;
157         port.uartclk = DSIU_BASE_BAUD;
158         port.irq = DSIU_IRQ;
159         port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
160         port.membase = (char *)DSIURB;
161         port.regshift = 0;
162         port.iotype = UPIO_MEM;
163         if (early_serial_setup(&port) != 0)
164                 printk(KERN_ERR "DSIU setup failed!\n");
165
166         vr41xx_supply_clock(DSIU_CLOCK);
167
168         writew(INTDSIU, MDSIUINTREG);
169
170         vr41xx_serial_ports++;
171 }