patch-2_6_7-vs1_9_1_12
[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 #define SIUIRSEL_TYPE1          KSEG1ADDR(0x0c000008)
44 #define SIUIRSEL_TYPE2          KSEG1ADDR(0x0f000808)
45  #define USE_RS232C             0x00
46  #define USE_IRDA               0x01
47  #define SIU_USES_IRDA          0x00
48  #define FIR_USES_IRDA          0x02
49  #define IRDA_MODULE_SHARP      0x00
50  #define IRDA_MODULE_TEMIC      0x04
51  #define IRDA_MODULE_HP         0x08
52  #define TMICTX                 0x10
53  #define TMICMODE               0x20
54
55 #define SIU_BASE_TYPE1          0x0c000000UL    /* VR4111 and VR4121 */
56 #define SIU_BASE_TYPE2          0x0f000800UL    /* VR4122, VR4131 and VR4133 */
57 #define SIU_SIZE                0x8UL
58
59 #define SIU_BASE_BAUD           1152000
60
61 /* VR4122, VR4131 and VR4133 DSIU Registers */
62 #define DSIU_BASE               0x0f000820UL
63 #define DSIU_SIZE               0x8UL
64
65 #define DSIU_BASE_BAUD          1152000
66
67 int vr41xx_serial_ports = 0;
68
69 void vr41xx_select_siu_interface(siu_interface_t interface,
70                                  irda_module_t module)
71 {
72         uint16_t val = USE_RS232C;      /* Select RS-232C */
73
74         /* Select IrDA */
75         if (interface == SIU_IRDA) {
76                 switch (module) {
77                 case IRDA_SHARP:
78                         val = IRDA_MODULE_SHARP;
79                         break;
80                 case IRDA_TEMIC:
81                         val = IRDA_MODULE_TEMIC;
82                         break;
83                 case IRDA_HP:
84                         val = IRDA_MODULE_HP;
85                         break;
86                 default:
87                         printk(KERN_ERR "SIU: unknown IrDA module\n");
88                         return;
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_ERR "SIU: unsupported CPU of NEC VR4100 series\n");
105                 break;
106         }
107 }
108
109 void __init vr41xx_siu_init(void)
110 {
111         struct uart_port port;
112
113         memset(&port, 0, sizeof(port));
114
115         port.line = vr41xx_serial_ports;
116         port.uartclk = SIU_BASE_BAUD * 16;
117         port.irq = SIU_IRQ;
118         port.flags = UPF_RESOURCES | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
119         switch (current_cpu_data.cputype) {
120         case CPU_VR4111:
121         case CPU_VR4121:
122                 port.mapbase = SIU_BASE_TYPE1;
123                 break;
124         case CPU_VR4122:
125         case CPU_VR4131:
126         case CPU_VR4133:
127                 port.mapbase = SIU_BASE_TYPE2;
128                 break;
129         default:
130                 printk(KERN_ERR "SIU: unsupported CPU of NEC VR4100 series\n");
131                 return;
132         }
133         port.regshift = 0;
134         port.iotype = UPIO_MEM;
135         port.membase = ioremap(port.mapbase, SIU_SIZE);
136         if (port.membase != NULL) {
137                 if (early_serial_setup(&port) == 0) {
138                         vr41xx_supply_clock(SIU_CLOCK);
139                         vr41xx_serial_ports++;
140                         return;
141                 }
142         }
143
144         printk(KERN_ERR "SIU: setup failed!\n");
145 }
146
147 void __init vr41xx_dsiu_init(void)
148 {
149         struct uart_port port;
150
151         if (current_cpu_data.cputype != CPU_VR4122 &&
152             current_cpu_data.cputype != CPU_VR4131 &&
153             current_cpu_data.cputype != CPU_VR4133) {
154                 printk(KERN_ERR "DSIU: unsupported CPU of NEC VR4100 series\n");
155                 return;
156         }
157
158         memset(&port, 0, sizeof(port));
159
160         port.line = vr41xx_serial_ports;
161         port.uartclk = DSIU_BASE_BAUD * 16;
162         port.irq = DSIU_IRQ;
163         port.flags = UPF_RESOURCES | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
164         port.mapbase = DSIU_BASE;
165         port.regshift = 0;
166         port.iotype = UPIO_MEM;
167         port.membase = ioremap(port.mapbase, DSIU_SIZE);
168         if (port.membase != NULL) {
169                 if (early_serial_setup(&port) == 0) {
170                         vr41xx_supply_clock(DSIU_CLOCK);
171                         vr41xx_enable_dsiuint();
172                         vr41xx_serial_ports++;
173                         return;
174                 }
175         }
176
177         printk(KERN_ERR "DSIU: setup failed!\n");
178 }