Import 2.3.18pre1
[davej-history.git] / drivers / sbus / char / sunserial.c
blob60ff763e6022a3a9013e62f41309c00c9f19a50e
1 /* $Id: sunserial.c,v 1.70 1999/09/04 20:28:17 davem Exp $
2 * serial.c: Serial port driver infrastructure for the Sparc.
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 */
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/errno.h>
10 #include <linux/tty.h>
11 #include <linux/serial.h>
12 #include <linux/string.h>
13 #include <linux/kbd_diacr.h>
14 #include <linux/version.h>
15 #include <linux/init.h>
17 #include <asm/oplib.h>
19 #include "sunserial.h"
21 int serial_console;
23 int __init con_is_present(void)
25 return serial_console ? 0 : 1;
28 static void __init nop_rs_kgdb_hook(int channel)
30 printk("Oops: %s called\n", __FUNCTION__);
33 static void nop_rs_change_mouse_baud(int baud)
35 printk("Oops: %s called\n", __FUNCTION__);
38 static int nop_rs_read_proc(char *page, char **start, off_t off, int count,
39 int *eof, void *data)
41 printk("Oops: %s called\n", __FUNCTION__);
42 return 0;
45 struct sunserial_operations rs_ops = {
47 nop_rs_kgdb_hook,
48 nop_rs_change_mouse_baud,
49 nop_rs_read_proc
52 int rs_init(void)
54 struct initfunc *init;
55 int err = -ENODEV;
57 init = rs_ops.rs_init;
58 while (init) {
59 err = init->init();
60 init = init->next;
62 return err;
65 void __init rs_kgdb_hook(int channel)
67 rs_ops.rs_kgdb_hook(channel);
70 long __init serial_console_init(long kmem_start, long kmem_end)
72 return kmem_start;
75 void rs_change_mouse_baud(int baud)
77 rs_ops.rs_change_mouse_baud(baud);
80 int rs_read_proc(char *page, char **start, off_t off, int count,
81 int *eof, void *data)
83 return rs_ops.rs_read_proc(page, start, off, count, eof, data);
86 int register_serial(struct serial_struct *req)
88 return -1;
91 void unregister_serial(int line)
96 static void nop_compute_shiftstate (void)
98 printk("Oops: %s called\n", __FUNCTION__);
101 static void nop_setledstate (struct kbd_struct *kbd, unsigned int ledstate)
103 printk("Oops: %s called\n", __FUNCTION__);
106 static unsigned char nop_getledstate (void)
108 printk("Oops: %s called\n", __FUNCTION__);
109 return 0;
112 static int nop_setkeycode (unsigned int scancode, unsigned int keycode)
114 printk("Oops: %s called\n", __FUNCTION__);
115 return -EINVAL;
118 static int nop_getkeycode (unsigned int scancode)
120 printk("Oops: %s called\n", __FUNCTION__);
121 return -EINVAL;
124 struct sunkbd_operations kbd_ops = {
126 nop_compute_shiftstate,
127 nop_setledstate,
128 nop_getledstate,
129 nop_setkeycode,
130 nop_getkeycode
133 int kbd_init(void)
135 struct initfunc *init;
136 int err = -ENODEV;
138 init = kbd_ops.kbd_init;
139 while (init) {
140 err = init->init();
141 init = init->next;
143 return err;
146 void compute_shiftstate (void)
148 kbd_ops.compute_shiftstate();
151 void setledstate (struct kbd_struct *kbd, unsigned int ledstate)
153 kbd_ops.setledstate(kbd, ledstate);
156 unsigned char getledstate (void)
158 return kbd_ops.getledstate();
161 int setkeycode (unsigned int scancode, unsigned int keycode)
163 return kbd_ops.setkeycode(scancode, keycode);
166 int getkeycode (unsigned int scancode)
168 return kbd_ops.getkeycode(scancode);
171 void
172 sunserial_setinitfunc(unsigned long *memory_start, int (*init) (void))
174 struct initfunc *rs_init;
176 *memory_start = (*memory_start + 7) & ~(7);
177 rs_init = (struct initfunc *) *memory_start;
178 *memory_start += sizeof(struct initfunc);
180 rs_init->init = init;
181 rs_init->next = rs_ops.rs_init;
182 rs_ops.rs_init = rs_init;
185 void
186 sunserial_console_termios(struct console *con)
188 char mode[16], buf[16], *s;
189 char *mode_prop = "ttyX-mode";
190 char *cd_prop = "ttyX-ignore-cd";
191 char *dtr_prop = "ttyX-rts-dtr-off";
192 int baud, bits, stop, cflag;
193 char parity;
194 int carrier = 0;
195 int rtsdtr = 1;
196 int topnd, nd;
198 if (!serial_console)
199 return;
201 if (serial_console == 1) {
202 mode_prop[3] = 'a';
203 cd_prop[3] = 'a';
204 dtr_prop[3] = 'a';
205 } else {
206 mode_prop[3] = 'b';
207 cd_prop[3] = 'b';
208 dtr_prop[3] = 'b';
211 topnd = prom_getchild(prom_root_node);
212 nd = prom_searchsiblings(topnd, "options");
213 if (!nd) {
214 strcpy(mode, "9600,8,n,1,-");
215 goto no_options;
218 if (!prom_node_has_property(nd, mode_prop)) {
219 strcpy(mode, "9600,8,n,1,-");
220 goto no_options;
223 memset(mode, 0, sizeof(mode));
224 prom_getstring(nd, mode_prop, mode, sizeof(mode));
226 if (prom_node_has_property(nd, cd_prop)) {
227 memset(buf, 0, sizeof(buf));
228 prom_getstring(nd, cd_prop, buf, sizeof(buf));
229 if (!strcmp(buf, "false"))
230 carrier = 1;
232 /* XXX: this is unused below. */
235 if (prom_node_has_property(nd, cd_prop)) {
236 memset(buf, 0, sizeof(buf));
237 prom_getstring(nd, cd_prop, buf, sizeof(buf));
238 if (!strcmp(buf, "false"))
239 rtsdtr = 0;
241 /* XXX: this is unused below. */
244 no_options:
245 cflag = CREAD | HUPCL | CLOCAL;
247 s = mode;
248 baud = simple_strtoul(s, 0, 0);
249 s = strchr(s, ',');
250 bits = simple_strtoul(++s, 0, 0);
251 s = strchr(s, ',');
252 parity = *(++s);
253 s = strchr(s, ',');
254 stop = simple_strtoul(++s, 0, 0);
255 s = strchr(s, ',');
256 /* XXX handshake is not handled here. */
258 switch (baud) {
259 case 150: cflag |= B150; break;
260 case 300: cflag |= B300; break;
261 case 600: cflag |= B600; break;
262 case 1200: cflag |= B1200; break;
263 case 2400: cflag |= B2400; break;
264 case 4800: cflag |= B4800; break;
265 case 9600: cflag |= B9600; break;
266 case 19200: cflag |= B19200; break;
267 case 38400: cflag |= B38400; break;
268 default: cflag |= B9600; break;
271 switch (bits) {
272 case 5: cflag |= CS5; break;
273 case 6: cflag |= CS6; break;
274 case 7: cflag |= CS7; break;
275 case 8: cflag |= CS8; break;
276 default: cflag |= CS8; break;
279 switch (parity) {
280 case 'o': cflag |= (PARENB | PARODD); break;
281 case 'e': cflag |= PARENB; break;
282 case 'n': default: break;
285 switch (stop) {
286 case 2: cflag |= CSTOPB; break;
287 case 1: default: break;
290 con->cflag = cflag;
293 void
294 sunkbd_setinitfunc(unsigned long *memory_start, int (*init) (void))
296 struct initfunc *kbd_init;
298 *memory_start = (*memory_start + 7) & ~(7);
299 kbd_init = (struct initfunc *) *memory_start;
300 *memory_start += sizeof(struct initfunc);
302 kbd_init->init = init;
303 kbd_init->next = kbd_ops.kbd_init;
304 kbd_ops.kbd_init = kbd_init;
307 #ifdef CONFIG_PCI
308 void
309 sunkbd_install_keymaps(unsigned long *memory_start,
310 ushort **src_key_maps, unsigned int src_keymap_count,
311 char *src_func_buf, char **src_func_table,
312 int src_funcbufsize, int src_funcbufleft,
313 struct kbdiacr *src_accent_table,
314 unsigned int src_accent_table_size)
316 extern unsigned int keymap_count;
317 int i, j;
319 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
320 if (src_key_maps[i]) {
321 if (!key_maps[i]) {
322 key_maps[i] = (ushort *)*memory_start;
323 *memory_start += NR_KEYS * sizeof(ushort);
325 for (j = 0; j < NR_KEYS; j++)
326 key_maps[i][j] = src_key_maps[i][j];
328 key_maps[i] = src_key_maps[i];
330 keymap_count = src_keymap_count;
332 for (i = 0; i < MAX_NR_FUNC; i++)
333 func_table[i] = src_func_table[i];
334 funcbufptr = src_func_buf;
335 funcbufsize = src_funcbufsize;
336 funcbufleft = src_funcbufleft;
338 for (i = 0; i < MAX_DIACR; i++)
339 accent_table[i] = src_accent_table[i];
340 accent_table_size = src_accent_table_size;
342 #endif
344 extern int su_probe(unsigned long *);
345 extern int zs_probe(unsigned long *);
346 #ifdef CONFIG_SAB82532
347 extern int sab82532_probe(unsigned long *);
348 #endif
349 #ifdef CONFIG_PCI
350 extern int ps2kbd_probe(unsigned long *);
351 #endif
353 unsigned long __init sun_serial_setup(unsigned long memory_start)
355 int ret = 1;
357 #if defined(CONFIG_PCI) && !defined(__sparc_v9__)
359 * Probing sequence on sparc differs from sparc64.
360 * Keyboard is probed ahead of su because we want su function
361 * when keyboard is active. su is probed ahead of zs in order to
362 * get console on MrCoffee with fine but disconnected zs.
364 if (!serial_console)
365 ps2kbd_probe(&memory_start);
366 if (su_probe(&memory_start) == 0)
367 return memory_start;
368 #endif
370 if (zs_probe(&memory_start) == 0)
371 return memory_start;
373 #ifdef CONFIG_SAB82532
374 ret = sab82532_probe(&memory_start);
375 #endif
377 #if defined(CONFIG_PCI) && defined(__sparc_v9__)
379 * Keyboard serial devices.
381 * Well done, Sun, prom_devopen("/pci@1f,4000/ebus@1/su@14,3083f8")
382 * hangs the machine if no keyboard is connected to the device...
383 * All PCI PROMs seem to do this, I have seen this on the Ultra 450
384 * with version 3.5 PROM, and on the Ultra/AX with 3.1.5 PROM.
386 * So be very careful not to probe for keyboards if we are on a
387 * serial console.
389 if (!serial_console)
390 ps2kbd_probe(&memory_start);
391 if (su_probe(&memory_start) == 0)
392 return memory_start;
393 #endif
395 if (!ret)
396 return memory_start;
398 #ifdef __sparc_v9__
399 { extern int this_is_starfire;
400 /* Hello, Starfire. Pleased to meet you :) */
401 if(this_is_starfire != 0)
402 return memory_start;
404 #endif
406 prom_printf("No serial devices found, bailing out.\n");
407 prom_halt();
408 return memory_start;