1 /* $Id: sunserial.c,v 1.1.1.1 2005/04/11 02:50:34 jack Exp $
2 * serial.c: Serial port driver infrastructure for the Sparc.
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
7 #include <linux/config.h>
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/module.h>
11 #include <linux/errno.h>
12 #include <linux/tty.h>
13 #include <linux/serial.h>
14 #include <linux/serialP.h>
15 #include <linux/string.h>
16 #include <linux/kbd_diacr.h>
17 #include <linux/version.h>
18 #include <linux/init.h>
19 #include <linux/bootmem.h>
21 #include <asm/oplib.h>
23 #include "sunserial.h"
26 int stop_a_enabled = 1;
28 int __init con_is_present(void)
30 return serial_console ? 0 : 1;
33 static void __init nop_rs_kgdb_hook(int channel)
35 printk("Oops: %s called\n", __FUNCTION__);
38 static void nop_rs_change_mouse_baud(int baud)
40 printk("Oops: %s called\n", __FUNCTION__);
43 static int nop_rs_read_proc(char *page, char **start, off_t off, int count,
46 printk("Oops: %s called\n", __FUNCTION__);
50 struct sunserial_operations rs_ops = {
53 nop_rs_change_mouse_baud,
59 static int invoked = 0;
62 struct initfunc *init;
66 init = rs_ops.rs_init;
74 void __init rs_kgdb_hook(int channel)
76 rs_ops.rs_kgdb_hook(channel);
79 void __init serial_console_init(void)
84 void rs_change_mouse_baud(int baud)
86 rs_ops.rs_change_mouse_baud(baud);
89 int rs_read_proc(char *page, char **start, off_t off, int count,
92 return rs_ops.rs_read_proc(page, start, off, count, eof, data);
95 int register_serial(struct serial_struct *req)
100 void unregister_serial(int line)
105 static void nop_compute_shiftstate (void)
107 printk("Oops: %s called\n", __FUNCTION__);
110 static void nop_setledstate (struct kbd_struct *kbd, unsigned int ledstate)
112 printk("Oops: %s called\n", __FUNCTION__);
115 static unsigned char nop_getledstate (void)
117 printk("Oops: %s called\n", __FUNCTION__);
121 static int nop_setkeycode (unsigned int scancode, unsigned int keycode)
123 printk("Oops: %s called\n", __FUNCTION__);
127 static int nop_getkeycode (unsigned int scancode)
129 printk("Oops: %s called\n", __FUNCTION__);
133 struct sunkbd_operations kbd_ops = {
135 nop_compute_shiftstate,
142 #if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
143 extern void pci_compute_shiftstate(void);
144 extern int pci_setkeycode(unsigned int, unsigned int);
145 extern int pci_getkeycode(unsigned int);
146 extern void pci_setledstate(struct kbd_struct *, unsigned int);
147 extern unsigned char pci_getledstate(void);
148 extern int pcikbd_init(void);
153 struct initfunc *init;
156 init = kbd_ops.kbd_init;
161 #if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
162 if (!serial_console &&
163 kbd_ops.compute_shiftstate == nop_compute_shiftstate) {
164 printk("kbd_init: Assuming USB keyboard.\n");
165 kbd_ops.compute_shiftstate = pci_compute_shiftstate;
166 kbd_ops.setledstate = pci_setledstate;
167 kbd_ops.getledstate = pci_getledstate;
168 kbd_ops.setkeycode = pci_setkeycode;
169 kbd_ops.getkeycode = pci_getkeycode;
176 void compute_shiftstate (void)
178 kbd_ops.compute_shiftstate();
181 void setledstate (struct kbd_struct *kbd, unsigned int ledstate)
183 kbd_ops.setledstate(kbd, ledstate);
186 unsigned char getledstate (void)
188 return kbd_ops.getledstate();
191 int setkeycode (unsigned int scancode, unsigned int keycode)
193 return kbd_ops.setkeycode(scancode, keycode);
196 int getkeycode (unsigned int scancode)
198 return kbd_ops.getkeycode(scancode);
201 void * __init sunserial_alloc_bootmem(unsigned long size)
205 ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
207 memset(ret, 0, size);
213 sunserial_setinitfunc(int (*init) (void))
215 struct initfunc *rs_init;
217 rs_init = sunserial_alloc_bootmem(sizeof(struct initfunc));
218 if (rs_init == NULL) {
219 prom_printf("sunserial_setinitfunc: Cannot alloc initfunc.\n");
223 rs_init->init = init;
224 rs_init->next = rs_ops.rs_init;
225 rs_ops.rs_init = rs_init;
229 sunserial_console_termios(struct console *con)
231 char mode[16], buf[16], *s;
232 char *mode_prop = "ttyX-mode";
233 char *cd_prop = "ttyX-ignore-cd";
234 char *dtr_prop = "ttyX-rts-dtr-off";
235 int baud, bits, stop, cflag;
244 if (serial_console == 1) {
254 topnd = prom_getchild(prom_root_node);
255 nd = prom_searchsiblings(topnd, "options");
257 strcpy(mode, "9600,8,n,1,-");
261 if (!prom_node_has_property(nd, mode_prop)) {
262 strcpy(mode, "9600,8,n,1,-");
266 memset(mode, 0, sizeof(mode));
267 prom_getstring(nd, mode_prop, mode, sizeof(mode));
269 if (prom_node_has_property(nd, cd_prop)) {
270 memset(buf, 0, sizeof(buf));
271 prom_getstring(nd, cd_prop, buf, sizeof(buf));
272 if (!strcmp(buf, "false"))
275 /* XXX: this is unused below. */
278 if (prom_node_has_property(nd, cd_prop)) {
279 memset(buf, 0, sizeof(buf));
280 prom_getstring(nd, cd_prop, buf, sizeof(buf));
281 if (!strcmp(buf, "false"))
284 /* XXX: this is unused below. */
288 cflag = CREAD | HUPCL | CLOCAL;
291 baud = simple_strtoul(s, 0, 0);
293 bits = simple_strtoul(++s, 0, 0);
297 stop = simple_strtoul(++s, 0, 0);
299 /* XXX handshake is not handled here. */
302 case 150: cflag |= B150; break;
303 case 300: cflag |= B300; break;
304 case 600: cflag |= B600; break;
305 case 1200: cflag |= B1200; break;
306 case 2400: cflag |= B2400; break;
307 case 4800: cflag |= B4800; break;
308 case 9600: cflag |= B9600; break;
309 case 19200: cflag |= B19200; break;
310 case 38400: cflag |= B38400; break;
311 default: baud = 9600; cflag |= B9600; break;
315 case 5: cflag |= CS5; break;
316 case 6: cflag |= CS6; break;
317 case 7: cflag |= CS7; break;
318 case 8: cflag |= CS8; break;
319 default: cflag |= CS8; break;
323 case 'o': cflag |= (PARENB | PARODD); break;
324 case 'e': cflag |= PARENB; break;
325 case 'n': default: break;
329 case 2: cflag |= CSTOPB; break;
330 case 1: default: break;
337 sunkbd_setinitfunc(int (*init) (void))
339 struct initfunc *kbd_init;
341 kbd_init = sunserial_alloc_bootmem(sizeof(struct initfunc));
342 if (kbd_init == NULL) {
343 prom_printf("sunkbd_setinitfunc: Cannot alloc initfunc.\n");
347 kbd_init->init = init;
348 kbd_init->next = kbd_ops.kbd_init;
349 kbd_ops.kbd_init = kbd_init;
354 sunkbd_install_keymaps(ushort **src_key_maps, unsigned int src_keymap_count,
355 char *src_func_buf, char **src_func_table,
356 int src_funcbufsize, int src_funcbufleft,
357 struct kbdiacr *src_accent_table,
358 unsigned int src_accent_table_size)
360 extern unsigned int keymap_count;
363 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
364 if (src_key_maps[i]) {
366 key_maps[i] = (ushort *)
367 sunserial_alloc_bootmem(NR_KEYS * sizeof(ushort));
368 if (key_maps[i] == NULL) {
369 prom_printf("sunkbd_install_keymaps: "
370 "Cannot alloc key_map(%d).\n", i);
374 for (j = 0; j < NR_KEYS; j++)
375 key_maps[i][j] = src_key_maps[i][j];
377 key_maps[i] = src_key_maps[i];
379 keymap_count = src_keymap_count;
381 for (i = 0; i < MAX_NR_FUNC; i++)
382 func_table[i] = src_func_table[i];
383 funcbufptr = src_func_buf;
384 funcbufsize = src_funcbufsize;
385 funcbufleft = src_funcbufleft;
387 for (i = 0; i < MAX_DIACR; i++)
388 accent_table[i] = src_accent_table[i];
389 accent_table_size = src_accent_table_size;
393 extern int su_probe(void);
394 extern int zs_probe(void);
395 #ifdef CONFIG_SAB82532
396 extern int sab82532_probe(void);
399 extern int ps2kbd_probe(void);
402 void __init sun_serial_setup(void)
406 #if defined(CONFIG_PCI) && !defined(__sparc_v9__)
408 * Probing sequence on sparc differs from sparc64.
409 * Keyboard is probed ahead of su because we want su function
410 * when keyboard is active. su is probed ahead of zs in order to
411 * get console on MrCoffee with fine but disconnected zs.
422 #ifdef CONFIG_SAB82532
423 ret = sab82532_probe();
426 #if defined(CONFIG_PCI) && defined(__sparc_v9__)
428 * Keyboard serial devices.
430 * Well done, Sun, prom_devopen("/pci@1f,4000/ebus@1/su@14,3083f8")
431 * hangs the machine if no keyboard is connected to the device...
432 * All PCI PROMs seem to do this, I have seen this on the Ultra 450
433 * with version 3.5 PROM, and on the Ultra/AX with 3.1.5 PROM.
435 * So be very careful not to probe for keyboards if we are on a
448 { extern int this_is_starfire;
449 /* Hello, Starfire. Pleased to meet you :) */
450 if(this_is_starfire != 0)
455 prom_printf("No serial devices found, bailing out.\n");