summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c')
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c562
1 files changed, 0 insertions, 562 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c
deleted file mode 100644
index 6a3f8551b4..0000000000
--- a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * linux/drivers/char/pc_keyb.c
- * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
- * See keyboard.c for the whole history.
- * Major cleanup by Martin Mares, May 1997
- * Combined the keyboard and PS/2 mouse handling into one file,
- * because they share the same hardware.
- * Johan Myreen <jem@iki.fi> 1998-10-08.
- * Code fixes to handle mouse ACKs properly.
- * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
- *
- * RTEMS port: by Rosimildo da Silva.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <assert.h>
-
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <rtems/libio.h>
-#include <termios.h>
-#include <i386_io.h>
-#include <rtems/mw_uid.h>
-#include <rtems/mouse_parser.h>
-
-#define INITIALIZE_MOUSE
-/* Some configuration switches are present in the include file... */
-#include <rtems/ps2_drv.h>
-#include "ps2_mouse.h"
-
-static void kbd_write_command_w(int data);
-#if 0
-static void kbd_write_output_w(int data);
-#endif
-
-static unsigned char handle_kbd_event(void);
-static void ps2_set_driver_handler(int port, mouse_parser_enqueue_handler handler);
-
-/* used only by send_data - set by keyboard_interrupt */
-static volatile unsigned char reply_expected = 0;
-static volatile unsigned char acknowledge = 0;
-static volatile unsigned char resend = 0;
-
-/*
- * PS/2 Auxiliary Device
- */
-static int psaux_init(void);
-
-static struct aux_queue *queue; /* Mouse data buffer. */
-static int aux_count = 0;
-/* used when we send commands to the mouse that expect an ACK. */
-static unsigned char mouse_reply_expected = 0;
-
-#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
-#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
-#define MAX_RETRIES 60 /* some aux operations take long time*/
-
-static void ps2_mouse_interrupt(void *);
-static mouse_parser_enqueue_handler driver_input_handler_ps2 = NULL;
-
-/*
- * This routine sets the handler to handle the characters received
- * from the serial port.
- */
-static void ps2_set_driver_handler(
- int port,
- mouse_parser_enqueue_handler handler
-)
-{
- driver_input_handler_ps2 = handler;
-}
-
-static void mdelay( unsigned long t )
-{
- Wait_X_ms( t );
-}
-
-static void* termios_ttyp_paux = NULL;
-
-/*
- * Wait for keyboard controller input buffer to drain.
- *
- * Don't use 'jiffies' so that we don't depend on
- * interrupts..
- *
- * Quote from PS/2 System Reference Manual:
- *
- * "Address hex 0060 and address hex 0064 should be written only when
- * the input-buffer-full bit and output-buffer-full bit in the
- * Controller Status register are set 0."
- */
-
-static void kb_wait(void)
-{
- unsigned long timeout = KBC_TIMEOUT;
-
- do {
- /*
- * "handle_kbd_event()" will handle any incoming events
- * while we wait - keypresses or mouse movement.
- */
- unsigned char status = handle_kbd_event();
-
- if (! (status & KBD_STAT_IBF))
- return;
-
- mdelay(1);
- timeout--;
- } while (timeout);
-
- #ifdef KBD_REPORT_TIMEOUTS
- printk( "Keyboard timed out[1]\n");
- #endif
-}
-
-static int do_acknowledge(unsigned char scancode)
-{
- if (reply_expected) {
-
- /* Unfortunately, we must recognise these codes only if we know they
- * are known to be valid (i.e., after sending a command), because there
- * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
- * keys with such codes :(
- */
- if (scancode == KBD_REPLY_ACK) {
- acknowledge = 1;
- reply_expected = 0;
- return 0;
- } else if (scancode == KBD_REPLY_RESEND) {
- resend = 1;
- reply_expected = 0;
- return 0;
- }
-
- /* Should not happen... */
- #if 0
- printk( "keyboard reply expected - got %02x\n", scancode);
- #endif
- }
- return 1;
-}
-
-static inline void handle_mouse_event(unsigned char scancode)
-{
- if (mouse_reply_expected) {
- if (scancode == AUX_ACK) {
- mouse_reply_expected--;
- return;
- }
- mouse_reply_expected = 0;
- }
-
- if (aux_count) {
- int head = queue->head;
- queue->buf[head] = scancode;
- head = (head + 1) & (AUX_BUF_SIZE-1);
- if (head != queue->tail) {
- queue->head = head;
- }
-
- /* if the input queue is active, add to it */
- if( driver_input_handler_ps2 ) {
- driver_input_handler_ps2( &scancode, 1 );
- } else {
- /* post this byte to termios */
- rtems_termios_enqueue_raw_characters( termios_ttyp_paux, (char *)&scancode, 1 );
- }
- }
-}
-
-/*
- * This reads the keyboard status port, and does the
- * appropriate action.
- *
- * It requires that we hold the keyboard controller
- * spinlock.
- */
-static unsigned char handle_kbd_event(void)
-{
- unsigned char status = kbd_read_status();
- unsigned int work = 10000;
-
- while (status & KBD_STAT_OBF) {
- unsigned char scancode;
- scancode = kbd_read_input();
- if (status & KBD_STAT_MOUSE_OBF) {
- handle_mouse_event(scancode);
- } else {
- do_acknowledge(scancode);
- printk("pc_keyb: %X ", scancode );
- }
- status = kbd_read_status();
- if(!work--) {
- printk("pc_keyb: controller jammed (0x%02X).\n", status);
- break;
- }
- }
- return status;
-}
-
-static void ps2_mouse_interrupt(void * unused)
-{
- handle_kbd_event();
-}
-
-static void kbd_write_command_w(int data)
-{
- kb_wait();
- kbd_write_command(data);
-}
-
-static void kbd_write_cmd(int cmd)
-{
- kb_wait();
- kbd_write_command(KBD_CCMD_WRITE_MODE);
- kb_wait();
- kbd_write_output(cmd);
-}
-
-/*
- * Check if this is a dual port controller.
- */
-static int detect_auxiliary_port(void)
-{
- int loops = 10;
- int retval = 0;
-
- /* Put the value 0x5A in the output buffer using the "Write
- * Auxiliary Device Output Buffer" command (0xD3). Poll the
- * Status Register for a while to see if the value really
- * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
- * bit is also set to 1 in the Status Register, we assume this
- * controller has an Auxiliary Port (a.k.a. Mouse Port).
- */
- kb_wait();
- kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
-
- kb_wait();
- kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
-
- do {
- unsigned char status = kbd_read_status();
- if (status & KBD_STAT_OBF) {
- kbd_read_input();
- if (status & KBD_STAT_MOUSE_OBF) {
- printk( "Detected PS/2 Mouse Port.\n");
- retval = 1;
- }
- break;
- }
- mdelay(1);
- } while (--loops);
- return retval;
-}
-
-/*
- * Send a byte to the mouse.
- */
-static void aux_write_dev(int val)
-{
- kb_wait();
- kbd_write_command(KBD_CCMD_WRITE_MOUSE);
- kb_wait();
- kbd_write_output(val);
-}
-
-/*
- * Send a byte to the mouse & handle returned ack
- */
-static void aux_write_ack(int val)
-{
- kb_wait();
- kbd_write_command(KBD_CCMD_WRITE_MOUSE);
- kb_wait();
- kbd_write_output(val);
- /* we expect an ACK in response. */
- mouse_reply_expected++;
- kb_wait();
-}
-
-static unsigned char get_from_queue(void)
-{
- unsigned char result;
- result = queue->buf[queue->tail];
- queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
- return result;
-}
-
-static int queue_empty(void)
-{
- return queue->head == queue->tail;
-}
-
-/*
- * Random magic cookie for the aux device
- */
-#define AUX_DEV ((void *)queue)
-
-static int release_aux(void)
-{
- rtems_status_code status;
- if (--aux_count)
- return 0;
- kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
- kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
- status = rtems_interrupt_handler_remove(
- AUX_IRQ,
- ps2_mouse_interrupt,
- NULL
- );
- assert(status == RTEMS_SUCCESSFUL);
- return 0;
-}
-
-/*
- * Install interrupt handler.
- * Enable auxiliary device.
- */
-
-static int open_aux(void)
-{
- rtems_status_code status;
-
- if (aux_count++) {
- return 0;
- }
- queue->head = queue->tail = 0; /* Flush input queue */
-
- status = rtems_interrupt_handler_install(
- AUX_IRQ,
- "ps2_mouse",
- RTEMS_INTERRUPT_UNIQUE,
- ps2_mouse_interrupt,
- NULL
- );
- assert(status == RTEMS_SUCCESSFUL);
-
- kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on
- controller. */
- aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
- kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
- return 0;
-}
-
-/*
- * Put bytes from input queue to buffer.
- */
-size_t read_aux(char * buffer, size_t count )
-{
- size_t i = count;
- unsigned char c;
-
- if (queue_empty()) {
- return 0;
- }
- while (i > 0 && !queue_empty()) {
- c = get_from_queue();
- *buffer++ = c;
- i--;
- }
- return count-i;
-}
-
-/*
- * Write to the aux device.
- */
-static int write_aux( int minor, const char * buffer, int count )
-{
- int retval = 0;
-
- if (count) {
- int written = 0;
- if (count > 32)
- count = 32; /* Limit to 32 bytes. */
- do {
- char c;
- c = *buffer++;
- aux_write_dev(c);
- written++;
- } while (--count);
- retval = -EIO;
- if (written) {
- retval = written;
- }
- }
- return retval;
-}
-
-static int psaux_init( void )
-{
- if( !detect_auxiliary_port() ) {
- printk( "PS/2 - mouse not found.\n" );
- return -EIO;
- }
- queue = (struct aux_queue *)malloc( sizeof(*queue) );
- memset(queue, 0, sizeof(*queue));
- queue->head = queue->tail = 0;
- queue->proc_list = NULL;
-
- #ifdef INITIALIZE_MOUSE
- kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
- aux_write_ack(AUX_SET_SAMPLE);
- aux_write_ack(100); /* 100 samples/sec */
- aux_write_ack(AUX_SET_RES);
- aux_write_ack(3); /* 8 counts per mm */
- aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
- #endif /* INITIALIZE_MOUSE */
- kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
- kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
- return 0;
-}
-
-/*
- * paux device driver INITIALIZE entry point.
- */
-rtems_device_driver paux_initialize(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
-{
- rtems_status_code status;
-
- /*
- * Set up TERMIOS
- */
- rtems_termios_initialize();
-
- printk( "PS/2 mouse probe.\n" );
- if( psaux_init() < 0 ) {
- printk("Error detecting PS/2 mouse --\n");
- /* we might want to finish the application here !!! */
- }
- open_aux();
-
- /*
- * Register the device
- */
- status = rtems_io_register_name ("/dev/mouse", major, 0);
- if (status != RTEMS_SUCCESSFUL) {
- printk("Error registering paux device!\n");
- rtems_fatal_error_occurred (status);
- }
- return RTEMS_SUCCESSFUL;
-} /* tty_initialize */
-
-static int paux_last_close(int major, int minor, void *arg)
-{
- release_aux();
- return 0;
-}
-
-/*
- * Write to the aux device. This routine is invoked by the
- * termios framework whenever the "ECHO" feature is on.
- * It does nothing write now.
- */
-static ssize_t write_aux_echo( int minor, const char * buffer, size_t count )
-{
- return 0;
-}
-
-/*
- * paux device driver OPEN entry point
- */
-rtems_device_driver paux_open(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
-{
- rtems_status_code status;
- static rtems_termios_callbacks cb =
- {
- NULL, /* firstOpen */
- paux_last_close, /* lastClose */
- NULL, /* poll read */
- write_aux_echo, /* write */
- NULL, /* setAttributes */
- NULL, /* stopRemoteTx */
- NULL, /* startRemoteTx */
- 0 /* outputUsesInterrupts */
- };
-
- status = rtems_termios_open (major, minor, arg, &cb );
- termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1;
- return status;
-}
-
-/*
- * paux device driver CLOSE entry point
- */
-rtems_device_driver paux_close(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
-{
- return (rtems_termios_close (arg));
-}
-
-/*
- * paux device driver READ entry point.
- * Read characters from the PS/2 mouse.
- */
-rtems_device_driver paux_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
-{
- return rtems_termios_read (arg);
-} /* tty_read */
-
-/*
- * paux device driver WRITE entry point.
- * Write characters to the PS/2 mouse.
- */
-rtems_device_driver paux_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
-{
- rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
- char *buffer = rw_args->buffer;
- int maximum = rw_args->count;
- rw_args->bytes_moved = write_aux( minor, buffer, maximum );
- return RTEMS_SUCCESSFUL;
-} /* tty_write */
-
-/*
- * Handle ioctl request.
- */
-rtems_device_driver paux_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_libio_ioctl_args_t *args = arg;
-
- switch( args->command ) {
- default:
- return rtems_termios_ioctl (arg);
- break;
-
- case MW_UID_REGISTER_DEVICE:
- printk( "PS2 Mouse: registering\n" );
- mouse_parser_initialize( "ps2" );
- ps2_set_driver_handler( minor, mouse_parser_enqueue );
- break;
-
- case MW_UID_UNREGISTER_DEVICE:
-/*
- unregister_mou_msg_queue( -1 );
-*/
- ps2_set_driver_handler( minor, NULL );
- break;
- }
- args->ioctl_return = 0;
- return RTEMS_SUCCESSFUL;
-}