More meth updates.
[linux-2.6/linux-mips.git] / drivers / serial / serial98.c
blobc34f8996853024f0b4e74199c58bb1eff004a611
1 /*
2 * linux/drivers/serial/serial98.c
4 * Driver for NEC PC-9801/PC-9821 standard serial ports
6 * Based on drivers/serial/8250.c, by Russell King.
7 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
9 * Copyright (C) 2002 Osamu Tomita <tomita@cinet.co.jp>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
17 #include <linux/config.h>
18 #include <linux/module.h>
19 #include <linux/tty.h>
20 #include <linux/ioport.h>
21 #include <linux/init.h>
22 #include <linux/serial.h>
23 #include <linux/console.h>
24 #include <linux/sysrq.h>
25 #include <linux/serial_reg.h>
26 #include <linux/delay.h>
28 #include <asm/io.h>
29 #include <asm/irq.h>
30 #include <asm/pc9800.h>
31 #include <asm/pc9800_sca.h>
33 #if defined(CONFIG_SERIAL98_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
34 #define SUPPORT_SYSRQ
35 #endif
37 #include <linux/serial_core.h>
39 #define SERIAL98_NR 1
40 #define SERIAL98_ISR_PASS_LIMIT 256
41 #define SERIAL98_EXT 0x434
43 //#define RX_8251F 0x130 /* In: Receive buffer */
44 //#define TX_8251F 0x130 /* Out: Transmit buffer */
45 //#define LSR_8251F 0x132 /* In: Line Status Register */
46 //#define MSR_8251F 0x134 /* In: Modem Status Register */
47 #define IIR_8251F 0x136 /* In: Interrupt ID Register */
48 #define FCR_8251F 0x138 /* I/O: FIFO Control Register */
49 #define VFAST_8251F 0x13a /* I/O: VFAST mode Register */
51 #define CMD_8251F 0x32 /* Out: 8251 Command Resister */
52 #define IER2_8251F 0x34 /* I/O: Interrupt Enable Register */
53 #define IER1_8251F 0x35 /* I/O: Interrupt Enable Register */
54 #define IER1_CTL 0x37 /* Out: Interrupt Enable Register */
55 #define DIS_RXR_INT 0x00 /* disable RxRDY Interrupt */
56 #define ENA_RXR_INT 0x01 /* enable RxRDY Interrupt */
57 #define DIS_TXE_INT 0x02 /* disable TxEMPTY Interrupt */
58 #define ENA_TXE_INT 0x03 /* enable TxEMPTY Interrupt */
59 #define DIS_TXR_INT 0x04 /* disable TxRDY Interrupt */
60 #define ENA_TXR_INT 0x05 /* enable TxRDY Interrupt */
62 #define CMD_RESET 0x40 /* Reset Command */
63 #define CMD_RTS 0x20 /* Set RTS line */
64 #define CMD_CLR_ERR 0x10 /* Clear error flag */
65 #define CMD_BREAK 0x08 /* Send Break */
66 #define CMD_RXE 0x04 /* Enable receive */
67 #define CMD_DTR 0x02 /* Set DTR line */
68 #define CMD_TXE 0x01 /* Enable send */
69 #define CMD_DUMMY 0x00 /* Dummy Command */
71 #define VFAST_ENABLE 0x80 /* V.Fast mode Enable */
73 /* Interrupt masks */
74 #define INTR_8251_TXRE 0x04
75 #define INTR_8251_TXEE 0x02
76 #define INTR_8251_RXRE 0x01
77 /* I/O Port */
78 //#define PORT_8251_DATA 0
79 //#define PORT_8251_CMD 2
80 //#define PORT_8251_MOD 2
81 //#define PORT_8251_STS 2
82 /* status read */
83 #define STAT_8251_TXRDY 0x01
84 #define STAT_8251_RXRDY 0x02
85 #define STAT_8251_TXEMP 0x04
86 #define STAT_8251_PER 0x08
87 #define STAT_8251_OER 0x10
88 #define STAT_8251_FER 0x20
89 #define STAT_8251_BRK 0x40
90 #define STAT_8251_DSR 0x80
91 #if 1
92 #define STAT_8251F_TXEMP 0x01
93 #define STAT_8251F_TXRDY 0x02
94 #define STAT_8251F_RXRDY 0x04
95 #define STAT_8251F_DSR 0x08
96 #define STAT_8251F_OER 0x10
97 #define STAT_8251F_PER 0x20
98 #define STAT_8251F_FER 0x40
99 #define STAT_8251F_BRK 0x80
100 #else
101 #define STAT_8251F_TXEMP 0x01
102 #define STAT_8251F_TEMT 0x01
103 #define STAT_8251F_TXRDY 0x02
104 #define STAT_8251F_THRE 0x02
105 #define STAT_8251F_RXRDY 0x04
106 #define STAT_8251F_DSR 0x04
107 #define STAT_8251F_PER 0x08
108 #define STAT_8251F_OER 0x10
109 #define STAT_8251F_FER 0x20
110 #define STAT_8251F_BRK 0x40
111 #endif
114 * We wrap our port structure around the generic uart_port.
116 struct serial98_port {
117 struct uart_port port;
118 unsigned int type;
119 unsigned int ext;
120 unsigned int lsr_break_flag;
121 unsigned char cmd;
122 unsigned char mode;
123 unsigned char msr;
124 unsigned char ier;
125 unsigned char rxchk;
126 unsigned char txemp;
127 unsigned char txrdy;
128 unsigned char rxrdy;
129 unsigned char brk;
130 unsigned char fe;
131 unsigned char oe;
132 unsigned char pe;
133 unsigned char dr;
136 #ifdef CONFIG_SERIAL98_CONSOLE
137 static void
138 serial98_console_write(struct console *co, const char *s, unsigned int count);
139 static int __init serial98_console_setup(struct console *co, char *options);
141 extern struct uart_driver serial98_reg;
142 static struct console serial98_console = {
143 .name = "ttyS",
144 .write = serial98_console_write,
145 .device = uart_console_device,
146 .setup = serial98_console_setup,
147 .flags = CON_PRINTBUFFER,
148 .index = -1,
149 .data = &serial98_reg,
152 #define SERIAL98_CONSOLE &serial98_console
153 #else
154 #define SERIAL98_CONSOLE NULL
155 #endif
157 static struct uart_driver serial98_reg = {
158 .owner = THIS_MODULE,
159 .driver_name = "serial98",
160 .dev_name = "ttyS",
161 .major = TTY_MAJOR,
162 .minor = 64,
163 .nr = SERIAL98_NR,
164 .cons = SERIAL98_CONSOLE,
167 static int serial98_clk;
168 static char type_str[48];
170 #define PORT98 ((struct serial98_port *)port)
171 #define PORT (PORT98->port)
173 static void serial98_fifo_enable(struct uart_port *port, int enable)
175 unsigned char fcr;
177 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
178 fcr = inb(FCR_8251F);
179 if (enable)
180 fcr |= UART_FCR_ENABLE_FIFO;
181 else
182 fcr &= ~UART_FCR_ENABLE_FIFO;
183 outb(fcr, FCR_8251F);
186 if (!enable)
187 return;
189 outb(0, 0x5f); /* wait */
190 outb(0, 0x5f);
191 outb(0, 0x5f);
192 outb(0, 0x5f);
195 static void serial98_cmd_out(struct uart_port *port, unsigned char cmd)
197 serial98_fifo_enable(port, 0);
198 outb(cmd, CMD_8251F);
199 serial98_fifo_enable(port, 1);
202 static void serial98_mode_set(struct uart_port *port)
204 serial98_cmd_out(port, CMD_DUMMY);
205 serial98_cmd_out(port, CMD_DUMMY);
206 serial98_cmd_out(port, CMD_DUMMY);
207 serial98_cmd_out(port, CMD_RESET);
208 serial98_cmd_out(port, PORT98->mode);
211 static unsigned char serial98_msr_in(struct uart_port *port)
213 unsigned long flags;
214 unsigned int ms, st;
215 unsigned int tmp;
217 spin_lock_irqsave(&PORT.lock, flags);
218 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
219 PORT98->msr = inb(PORT.iobase + 4);
220 } else {
221 ms = inb(0x33);
222 st = inb(0x32);
223 tmp = 0;
224 if(!(ms & 0x20))
225 tmp |= UART_MSR_DCD;
226 if(!(ms & 0x80)) {
227 tmp |= UART_MSR_RI;
228 PORT98->msr |= UART_MSR_RI;
230 if(!(ms & 0x40))
231 tmp |= UART_MSR_CTS;
232 if(st & 0x80)
233 tmp |= UART_MSR_DSR;
234 PORT98->msr = ((PORT98->msr ^ tmp) >> 4) | tmp;
237 spin_unlock_irqrestore(&PORT.lock, flags);
238 return PORT98->msr;
241 static void serial98_stop_tx(struct uart_port *port, unsigned int tty_stop)
243 unsigned int ier = inb(IER1_8251F);
245 ier &= ~(INTR_8251_TXRE | INTR_8251_TXEE);
246 outb(ier, IER1_8251F);
249 static void serial98_start_tx(struct uart_port *port, unsigned int tty_start)
251 unsigned int ier = inb(IER1_8251F);
253 ier |= INTR_8251_TXRE | INTR_8251_TXEE;
254 outb(ier, IER1_8251F);
257 static void serial98_stop_rx(struct uart_port *port)
259 PORT.read_status_mask &= ~PORT98->dr;
260 outb(DIS_RXR_INT, IER1_CTL);
263 static void serial98_enable_ms(struct uart_port *port)
265 outb(PORT98->ier | 0x80, IER2_8251F);
268 static void serial98_rx_chars(struct uart_port *port, int *status,
269 struct pt_regs *regs)
271 struct tty_struct *tty = PORT.info->tty;
272 unsigned char ch;
273 int max_count = 256;
275 do {
276 if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
277 tty->flip.work.func((void *)tty);
278 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
279 return; // if TTY_DONT_FLIP is set
281 ch = inb(PORT.iobase);
282 *tty->flip.char_buf_ptr = ch;
283 *tty->flip.flag_buf_ptr = TTY_NORMAL;
284 PORT.icount.rx++;
286 if (unlikely(*status & (PORT98->brk | PORT98->pe |
287 PORT98->fe | PORT98->oe))) {
289 * For statistics only
291 if (*status & PORT98->brk) {
292 *status &= ~(PORT98->fe | PORT98->pe);
293 PORT.icount.brk++;
295 * We do the SysRQ and SAK checking
296 * here because otherwise the break
297 * may get masked by ignore_status_mask
298 * or read_status_mask.
300 if (uart_handle_break(&PORT))
301 goto ignore_char;
302 } else if (*status & PORT98->pe)
303 PORT.icount.parity++;
304 else if (*status & PORT98->fe)
305 PORT.icount.frame++;
306 if (*status & PORT98->oe)
307 PORT.icount.overrun++;
310 * Mask off conditions which should be ingored.
312 *status &= PORT.read_status_mask;
314 #ifdef CONFIG_SERIAL98_CONSOLE
315 if (PORT.line == PORT.cons->index) {
316 /* Recover the break flag from console xmit */
317 *status |= PORT98->lsr_break_flag;
318 PORT98->lsr_break_flag = 0;
320 #endif
321 if (*status & PORT98->brk) {
322 *tty->flip.flag_buf_ptr = TTY_BREAK;
323 } else if (*status & PORT98->pe)
324 *tty->flip.flag_buf_ptr = TTY_PARITY;
325 else if (*status & PORT98->fe)
326 *tty->flip.flag_buf_ptr = TTY_FRAME;
328 if (uart_handle_sysrq_char(&PORT, ch, regs))
329 goto ignore_char;
330 if ((*status & PORT.ignore_status_mask) == 0) {
331 tty->flip.flag_buf_ptr++;
332 tty->flip.char_buf_ptr++;
333 tty->flip.count++;
335 if ((*status & PORT98->oe) &&
336 tty->flip.count < TTY_FLIPBUF_SIZE) {
338 * Overrun is special, since it's reported
339 * immediately, and doesn't affect the current
340 * character.
342 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
343 tty->flip.flag_buf_ptr++;
344 tty->flip.char_buf_ptr++;
345 tty->flip.count++;
347 ignore_char:
348 *status = inb(PORT.iobase + 2);
349 } while ((*status & PORT98->rxchk) && (max_count-- > 0));
350 tty_flip_buffer_push(tty);
353 static void serial98_tx_chars(struct uart_port *port)
355 struct circ_buf *xmit = &PORT.info->xmit;
356 int count;
358 if (PORT.x_char) {
359 outb(PORT.x_char, PORT.iobase);
360 PORT.icount.tx++;
361 PORT.x_char = 0;
362 return;
364 if (uart_circ_empty(xmit) || uart_tx_stopped(&PORT)) {
365 serial98_stop_tx(port, 0);
366 return;
369 count = PORT.fifosize;
370 do {
371 outb(xmit->buf[xmit->tail], PORT.iobase);
372 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
373 PORT.icount.tx++;
374 if (uart_circ_empty(xmit))
375 break;
376 } while (--count > 0);
378 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
379 uart_write_wakeup(&PORT);
381 if (uart_circ_empty(xmit))
382 serial98_stop_tx(&PORT, 0);
385 static void serial98_modem_status(struct uart_port *port)
387 int status;
389 status = serial98_msr_in(port);
391 if ((status & UART_MSR_ANY_DELTA) == 0)
392 return;
394 if (status & UART_MSR_TERI)
395 PORT.icount.rng++;
396 if (status & UART_MSR_DDSR)
397 PORT.icount.dsr++;
398 if (status & UART_MSR_DDCD)
399 uart_handle_dcd_change(&PORT, status & UART_MSR_DCD);
400 if (status & UART_MSR_DCTS)
401 uart_handle_cts_change(&PORT, status & UART_MSR_CTS);
403 wake_up_interruptible(&PORT.info->delta_msr_wait);
406 static void serial98_int(int irq, void *port, struct pt_regs *regs)
408 unsigned int status;
410 spin_lock(&PORT.lock);
411 status = inb(PORT.iobase + 2);
412 if (status & PORT98->rxrdy) {
413 serial98_rx_chars(port, &status, regs);
415 serial98_modem_status(port);
416 if (status & PORT98->txrdy) {
417 serial98_tx_chars(port);
419 spin_unlock(&PORT.lock);
422 static unsigned int serial98_tx_empty(struct uart_port *port)
424 unsigned long flags;
425 unsigned int ret = 0;
427 spin_lock_irqsave(&PORT.lock, flags);
428 if (inb(PORT.iobase + 2) & PORT98->txemp)
429 ret = TIOCSER_TEMT;
431 spin_unlock_irqrestore(&PORT.lock, flags);
432 return ret;
435 static unsigned int serial98_get_mctrl(struct uart_port *port)
437 unsigned char status;
438 unsigned int ret = 0;
440 status = serial98_msr_in(port);
441 if (status & UART_MSR_DCD)
442 ret |= TIOCM_CAR;
443 if (status & UART_MSR_RI)
444 ret |= TIOCM_RNG;
445 if (status & UART_MSR_DSR)
446 ret |= TIOCM_DSR;
447 if (status & UART_MSR_CTS)
448 ret |= TIOCM_CTS;
449 return ret;
452 static void serial98_set_mctrl(struct uart_port *port, unsigned int mctrl)
454 PORT98->cmd &= 0xdd;
455 if (mctrl & TIOCM_RTS)
456 PORT98->cmd |= CMD_RTS;
458 if (mctrl & TIOCM_DTR)
459 PORT98->cmd |= CMD_DTR;
461 serial98_cmd_out(port, PORT98->cmd);
464 static void serial98_break_ctl(struct uart_port *port, int break_state)
466 unsigned long flags;
468 spin_lock_irqsave(&PORT.lock, flags);
469 if (break_state == -1)
470 PORT98->cmd |= CMD_BREAK;
471 else
472 PORT98->cmd &= ~CMD_BREAK;
474 serial98_cmd_out(port, PORT98->cmd);
475 spin_unlock_irqrestore(&PORT.lock, flags);
478 static int serial98_startup(struct uart_port *port)
480 int retval;
482 if (PORT.type == PORT_8251_PC98) {
483 /* Wake up UART */
484 PORT98->mode = 0xfc;
485 serial98_mode_set(port);
486 outb(DIS_RXR_INT, IER1_CTL);
487 outb(DIS_TXE_INT, IER1_CTL);
488 outb(DIS_TXR_INT, IER1_CTL);
489 PORT98->mode = 0;
490 serial98_mode_set(port);
494 * Clear the FIFO buffers and disable them.
495 * (they will be reeanbled in set_termios())
497 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
498 outb(UART_FCR_ENABLE_FIFO, FCR_8251F);
499 outb((UART_FCR_ENABLE_FIFO
500 | UART_FCR_CLEAR_RCVR
501 | UART_FCR_CLEAR_XMIT), FCR_8251F);
502 outb(0, FCR_8251F);
505 /* Clear the interrupt registers. */
506 inb(0x30);
507 inb(0x32);
508 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
509 inb(PORT.iobase);
510 inb(PORT.iobase + 2);
511 inb(PORT.iobase + 4);
512 inb(PORT.iobase + 6);
515 /* Allocate the IRQ */
516 retval = request_irq(PORT.irq, serial98_int, 0,
517 serial98_reg.driver_name, port);
518 if (retval)
519 return retval;
522 * Now, initialize the UART
524 PORT98->mode = 0x4e;
525 serial98_mode_set(port);
526 PORT98->cmd = 0x15;
527 serial98_cmd_out(port, PORT98->cmd);
528 PORT98->cmd = 0x05;
531 * Finally, enable interrupts
533 outb(0x00, IER2_8251F);
534 outb(ENA_RXR_INT, IER1_CTL);
537 * And clear the interrupt registers again for luck.
539 inb(0x30);
540 inb(0x32);
541 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
542 inb(PORT.iobase);
543 inb(PORT.iobase + 2);
544 inb(PORT.iobase + 4);
545 inb(PORT.iobase + 6);
548 return 0;
551 static void serial98_shutdown(struct uart_port *port)
553 unsigned long flags;
556 * disable all interrupts
558 spin_lock_irqsave(&PORT.lock, flags);
559 if (PORT.type == PORT_VFAST_PC98)
560 outb(0, VFAST_8251F); /* V.FAST mode off */
562 /* disnable all modem status interrupt */
563 outb(0x80, IER2_8251F);
565 /* disnable TX/RX interrupt */
566 outb(0x00, IER2_8251F);
567 outb(DIS_RXR_INT, IER1_CTL);
568 outb(DIS_TXE_INT, IER1_CTL);
569 outb(DIS_TXR_INT, IER1_CTL);
570 PORT98->ier = 0;
572 spin_unlock_irqrestore(&PORT.lock, flags);
575 * Free the interrupt
577 free_irq(PORT.irq, port);
579 /* disable break condition and disable the port */
580 serial98_mode_set(port);
582 /* disable FIFO's */
583 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
584 outb((UART_FCR_ENABLE_FIFO
585 | UART_FCR_CLEAR_RCVR
586 | UART_FCR_CLEAR_XMIT), FCR_8251F);
587 outb(0, FCR_8251F);
590 inb(PORT.iobase);
593 static void
594 serial98_set_termios(struct uart_port *port, struct termios *termios,
595 struct termios *old)
597 unsigned char stopbit, cval, fcr = 0, ier = 0;
598 unsigned long flags;
599 unsigned int baud, quot;
601 stopbit = 0x80;
602 switch (termios->c_cflag & CSIZE) {
603 case CS5:
604 cval = 0x42;
605 stopbit = 0xc0;
606 break;
607 case CS6:
608 cval = 0x46;
609 break;
610 case CS7:
611 cval = 0x4a;
612 break;
613 default:
614 case CS8:
615 cval = 0x4e;
616 break;
619 if (termios->c_cflag & CSTOPB)
620 cval ^= stopbit;
621 if (termios->c_cflag & PARENB)
622 cval |= 0x10;
623 if (!(termios->c_cflag & PARODD))
624 cval |= 0x20;
627 * Ask the core to calculate the divisor for us.
629 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
630 quot = uart_get_divisor(port, baud);
632 if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
633 if ((PORT.uartclk / quot) < (2400 * 16))
634 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
635 else
636 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
640 * Ok, we're now changing the port state. Do it with
641 * interrupts disabled.
643 spin_lock_irqsave(&PORT.lock, flags);
646 * Update the per-port timeout.
648 uart_update_timeout(port, termios->c_cflag, baud);
650 PORT.read_status_mask = PORT98->oe | PORT98->txemp | PORT98->dr;
651 if (termios->c_iflag & INPCK)
652 PORT.read_status_mask |= PORT98->fe | PORT98->pe;
654 if (termios->c_iflag & (BRKINT | PARMRK))
655 PORT.read_status_mask |= PORT98->brk;
657 * Characters to ignore
659 PORT.ignore_status_mask = 0;
660 if (termios->c_iflag & IGNPAR)
661 PORT.ignore_status_mask |= PORT98->fe | PORT98->pe;
663 if (termios->c_iflag & IGNBRK) {
664 PORT.ignore_status_mask |= PORT98->brk;
666 * If we're ignoring parity and break indicators,
667 * ignore overruns too (for real raw support).
669 if (termios->c_iflag & IGNPAR)
670 PORT.ignore_status_mask |= PORT98->oe;
674 * ignore all characters if CREAD is not set
676 if ((termios->c_cflag & CREAD) == 0)
677 PORT.ignore_status_mask |= PORT98->dr;
680 * CTS flow control flag and modem status interrupts
682 if (PORT.flags & UPF_HARDPPS_CD)
683 ier |= 0x80; /* enable modem status interrupt */
684 if (termios->c_cflag & CRTSCTS) {
685 ier |= 0x08; /* enable CTS interrupt */
686 ier |= 0x80; /* enable modem status interrupt */
688 if (!(termios->c_cflag & CLOCAL)) {
689 ier |= 0x20; /* enable CD interrupt */
690 ier |= 0x80; /* enable modem status interrupt */
692 PORT98->ier = ier;
694 PORT98->mode = cval;
695 serial98_mode_set(port);
696 if (PORT.type == PORT_VFAST_PC98 && quot <= 48) {
697 quot /= 4;
698 if (quot < 1)
699 quot = 1;
700 outb(quot | VFAST_ENABLE, VFAST_8251F);
701 } else {
702 quot /= 3;
703 if (quot < 1)
704 quot = 1;
705 if (PORT.type == PORT_VFAST_PC98)
706 outb(0, VFAST_8251F); /* V.FAST mode off */
707 outb(0xb6, 0x77);
708 outb(quot & 0xff, 0x75); /* LS of divisor */
709 outb(quot >> 8, 0x75); /* MS of divisor */
712 if (fcr & UART_FCR_ENABLE_FIFO) {
713 outb(UART_FCR_ENABLE_FIFO, FCR_8251F);
714 outb(fcr, FCR_8251F);
717 /* enable RX/TX */
718 PORT98->cmd = 0x15;
719 serial98_cmd_out(port, PORT98->cmd);
720 PORT98->cmd = 0x05;
721 /* enable interrupts */
722 outb(0x00, IER2_8251F);
723 outb(ENA_RXR_INT, IER1_CTL);
724 spin_unlock_irqrestore(&PORT.lock, flags);
727 static const char *serial98_type(struct uart_port *port)
729 char *p;
731 switch (PORT.type) {
732 case PORT_8251_PC98:
733 p = "PC98 onboard legacy 8251";
734 break;
735 case PORT_19K_PC98:
736 p = "PC98 onboard max 19200bps";
737 break;
738 case PORT_FIFO_PC98:
739 p = "PC98 onboard with FIFO";
740 break;
741 case PORT_VFAST_PC98:
742 p = "PC98 onboard V.FAST";
743 break;
744 case PORT_PC9861:
745 p = "PC-9861K RS-232C ext. board";
746 break;
747 case PORT_PC9801_101:
748 p = "PC-9801-101 RS-232C ext. board";
749 break;
750 default:
751 return NULL;
754 sprintf(type_str, "%s Clock %dMHz", p, serial98_clk);
755 return type_str;
758 /* Release the region(s) being used by 'port' */
759 static void serial98_release_port(struct uart_port *port)
761 switch (PORT.type) {
762 case PORT_VFAST_PC98:
763 release_region(PORT.iobase + 0xa, 1);
764 case PORT_FIFO_PC98:
765 release_region(PORT.iobase + 8, 1);
766 release_region(PORT.iobase + 6, 1);
767 release_region(PORT.iobase + 4, 1);
768 release_region(PORT.iobase + 2, 1);
769 release_region(PORT.iobase, 1);
770 case PORT_19K_PC98:
771 release_region(SERIAL98_EXT, 1);
772 release_region(0x34, 1);
773 case PORT_8251_PC98:
774 release_region(0x32, 1);
775 release_region(0x30, 1);
779 /* Request the region(s) being used by 'port' */
780 #define REQ_REGION98(base) (request_region((base), 1, serial98_reg.driver_name))
781 static int serial98_request_region(unsigned int type)
783 if (!REQ_REGION98(0x30))
784 return -EBUSY;
785 if (REQ_REGION98(0x32)) {
786 if (type == PORT_8251_PC98)
787 return 0;
788 if (REQ_REGION98(0x34)) {
789 if (REQ_REGION98(SERIAL98_EXT)) {
790 unsigned long base;
792 if (type == PORT_19K_PC98)
793 return 0;
794 for (base = 0x130; base <= 0x138; base += 2) {
795 if (!REQ_REGION98(base)) {
796 base -= 2;
797 goto err;
800 if (type == PORT_FIFO_PC98)
801 return 0;
802 if (type == PORT_VFAST_PC98) {
803 if (REQ_REGION98(0x13a))
804 return 0;
806 err:
807 while (base >= 0x130) {
808 release_region(base, 1);
809 base -= 2;
811 release_region(SERIAL98_EXT, 1);
813 release_region(0x34, 1);
815 release_region(0x32, 1);
817 release_region(0x30, 1);
818 return -EBUSY;
821 static int serial98_request_port(struct uart_port *port)
823 return serial98_request_region(PORT.type);
827 * Configure/autoconfigure the port.
829 static void serial98_config_port(struct uart_port *port, int flags)
831 if (flags & UART_CONFIG_TYPE)
832 PORT.type = PORT98->type;
836 * verify the new serial_struct (for TIOCSSERIAL).
838 static int serial98_verify_port(struct uart_port *port, struct serial_struct *ser)
840 switch (ser->type) {
841 case PORT_VFAST_PC98:
842 case PORT_FIFO_PC98:
843 case PORT_19K_PC98:
844 case PORT_8251_PC98:
845 /* not implemented yet
846 case PORT_PC9861:
847 case PORT_PC9801_101:
849 case PORT_UNKNOWN:
850 break;
851 default:
852 return -EINVAL;
854 if (ser->irq < 0 || ser->irq >= NR_IRQS)
855 return -EINVAL;
856 if (ser->baud_base < 9600)
857 return -EINVAL;
858 return 0;
861 static struct uart_ops serial98_ops = {
862 .tx_empty = serial98_tx_empty,
863 .set_mctrl = serial98_set_mctrl,
864 .get_mctrl = serial98_get_mctrl,
865 .stop_tx = serial98_stop_tx,
866 .start_tx = serial98_start_tx,
867 .stop_rx = serial98_stop_rx,
868 .enable_ms = serial98_enable_ms,
869 .break_ctl = serial98_break_ctl,
870 .startup = serial98_startup,
871 .shutdown = serial98_shutdown,
872 .set_termios = serial98_set_termios,
873 .type = serial98_type,
874 .release_port = serial98_release_port,
875 .request_port = serial98_request_port,
876 .config_port = serial98_config_port,
877 .verify_port = serial98_verify_port,
880 static struct serial98_port serial98_ports[SERIAL98_NR] = {
882 .port = {
883 .iobase = 0x30,
884 .iotype = SERIAL_IO_PORT,
885 .irq = 4,
886 .fifosize = 1,
887 .ops = &serial98_ops,
888 .flags = ASYNC_BOOT_AUTOCONF,
889 .line = 0,
891 .rxchk = STAT_8251_RXRDY,
892 .txemp = STAT_8251_TXEMP,
893 .txrdy = STAT_8251_TXRDY,
894 .rxrdy = STAT_8251_RXRDY,
895 .brk = STAT_8251_BRK,
896 .fe = STAT_8251_FER,
897 .oe = STAT_8251_OER,
898 .pe = STAT_8251_PER,
899 .dr = STAT_8251_DSR,
903 #ifdef CONFIG_SERIAL98_CONSOLE
905 #define BOTH_EMPTY (PORT98->txemp | PORT98->txrdy)
908 * Wait for transmitter & holding register to empty
910 static inline void wait_for_xmitr(struct uart_port *port)
912 unsigned int status, tmout = 10000;
914 /* Wait up to 10ms for the character(s) to be sent. */
915 do {
916 status = inb(PORT.iobase + 2);
918 if (status & PORT98->brk)
919 PORT98->lsr_break_flag = PORT98->brk;
921 if (--tmout == 0)
922 break;
923 udelay(1);
924 } while ((status & BOTH_EMPTY) != BOTH_EMPTY);
926 /* Wait up to 1s for flow control if necessary */
927 if (PORT.flags & UPF_CONS_FLOW) {
928 tmout = 1000000;
929 while (--tmout &&
930 ((serial98_msr_in(port) & UART_MSR_CTS) == 0))
931 udelay(1);
936 * Print a string to the serial port trying not to disturb
937 * any possible real use of the port...
939 * The console_lock must be held when we get here.
941 static void
942 serial98_console_write(struct console *co, const char *s, unsigned int count)
944 struct uart_port *port = (struct uart_port *)&serial98_ports[co->index];
945 unsigned int ier1, ier2;
946 int i;
949 * First save the UER then disable the interrupts
951 ier1 = inb(IER1_8251F);
952 ier2 = inb(IER2_8251F);
953 /* disnable all modem status interrupt */
954 outb(0x80, IER2_8251F);
956 /* disnable TX/RX interrupt */
957 outb(0x00, IER2_8251F);
958 outb(DIS_RXR_INT, IER1_CTL);
959 outb(DIS_TXE_INT, IER1_CTL);
960 outb(DIS_TXR_INT, IER1_CTL);
963 * Now, do each character
965 for (i = 0; i < count; i++, s++) {
966 wait_for_xmitr(port);
969 * Send the character out.
970 * If a LF, also do CR...
972 outb(*s, PORT.iobase);
973 if (*s == 10) {
974 wait_for_xmitr(port);
975 outb(13, PORT.iobase);
980 * Finally, wait for transmitter to become empty
981 * and restore the IER
983 wait_for_xmitr(port);
985 /* restore TX/RX interrupt */
986 outb(0x00, IER2_8251F);
987 if (ier1 & 0x01)
988 outb(ENA_RXR_INT, IER1_CTL);
989 if (ier1 & 0x02)
990 outb(ENA_TXE_INT, IER1_CTL);
991 if (ier1 & 0x04)
992 outb(ENA_TXR_INT, IER1_CTL);
994 /* restore modem status interrupt */
995 outb(ier2, IER2_8251F);
998 static int __init serial98_console_setup(struct console *co, char *options)
1000 struct uart_port *port;
1001 int baud = 9600;
1002 int bits = 8;
1003 int parity = 'n';
1004 int flow = 'n';
1007 * Check whether an invalid uart number has been specified, and
1008 * if so, search for the first available port that does have
1009 * console support.
1011 if (co->index >= SERIAL98_NR)
1012 co->index = 0;
1013 port = &serial98_ports[co->index].port;
1016 * Temporary fix.
1018 spin_lock_init(&port->lock);
1020 if (options)
1021 uart_parse_options(options, &baud, &parity, &bits, &flow);
1023 return uart_set_options(port, co, baud, parity, bits, flow);
1026 void __init serial98_console_init(void)
1028 register_console(&serial98_console);
1031 #endif /* CONFIG_SERIAL98_CONSOLE */
1034 static int __init serial98_init(void)
1036 int ret;
1037 unsigned char iir1, iir2;
1039 if (PC9800_8MHz_P()) {
1040 serial98_clk = 8;
1041 serial98_ports[0].port.uartclk = 374400 * 16;
1042 } else {
1043 serial98_clk = 5;
1044 serial98_ports[0].port.uartclk = 460800 * 16;
1047 printk(KERN_INFO "serial98: PC-9801 standard serial port driver Version 0.1alpha\n");
1048 serial98_ports[0].type = PORT_8251_PC98;
1049 /* Check FIFO exist */
1050 iir1 = inb(IIR_8251F);
1051 iir2 = inb(IIR_8251F);
1052 if ((iir1 & 0x40) != (iir2 & 0x40) && (iir1 & 0x20) == (iir2 & 0x20)) {
1053 serial98_ports[0].port.iobase = 0x130;
1054 serial98_ports[0].port.fifosize = 16;
1055 serial98_ports[0].rxchk = STAT_8251F_DSR;
1056 serial98_ports[0].txemp = STAT_8251F_TXEMP;
1057 serial98_ports[0].txrdy = STAT_8251F_TXRDY;
1058 serial98_ports[0].rxrdy = STAT_8251F_RXRDY;
1059 serial98_ports[0].brk = STAT_8251F_BRK;
1060 serial98_ports[0].fe = STAT_8251F_FER;
1061 serial98_ports[0].oe = STAT_8251F_OER;
1062 serial98_ports[0].pe = STAT_8251F_PER;
1063 serial98_ports[0].dr = STAT_8251F_DSR;
1065 if (*(unsigned char*)__va(PC9821SCA_RSFLAGS) & 0x10)
1066 serial98_ports[0].type = PORT_VFAST_PC98;
1067 else {
1068 outb(serial98_ports[0].ext | 0x40, SERIAL98_EXT);
1069 serial98_ports[0].port.uartclk *= 4;
1070 serial98_ports[0].type = PORT_FIFO_PC98;
1072 } else if ((serial98_ports[0].ext = inb(SERIAL98_EXT)) != 0xff) {
1073 outb(serial98_ports[0].ext | 0x40, SERIAL98_EXT);
1074 if (inb(SERIAL98_EXT) == (serial98_ports[0].ext | 0x40)) {
1075 serial98_ports[0].port.uartclk *= 4;
1076 serial98_ports[0].type = PORT_19K_PC98;
1077 } else {
1078 serial98_ops.enable_ms = NULL;
1079 outb(serial98_ports[0].ext, SERIAL98_EXT);
1083 if (serial98_request_region(serial98_ports[0].type))
1084 return -EBUSY;
1086 ret = uart_register_driver(&serial98_reg);
1087 if (ret == 0) {
1088 int i;
1090 for (i = 0; i < SERIAL98_NR; i++) {
1091 uart_add_one_port(&serial98_reg,
1092 (struct uart_port *)&serial98_ports[i]);
1096 return ret;
1099 static void __exit serial98_exit(void)
1101 int i;
1103 if (serial98_ports[0].type == PORT_19K_PC98
1104 || serial98_ports[0].type == PORT_FIFO_PC98)
1105 outb(serial98_ports[0].ext, SERIAL98_EXT);
1107 for (i = 0; i < SERIAL98_NR; i++) {
1108 uart_remove_one_port(&serial98_reg,
1109 (struct uart_port *)&serial98_ports[i]);
1112 uart_unregister_driver(&serial98_reg);
1115 module_init(serial98_init);
1116 module_exit(serial98_exit);
1118 MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
1119 MODULE_DESCRIPTION("PC-9801 standard serial port driver Version 0.1alpha");
1120 MODULE_LICENSE("GPL");