started mouse and keyboard device abstraction as ps2_dev

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15948 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2006-01-15 17:08:34 +00:00
parent ecc5f8d78c
commit e0ad7cc913
7 changed files with 199 additions and 43 deletions

View File

@ -10,5 +10,6 @@ KernelAddon ps2_hid_new : kernel drivers bin :
keyboard.c
mouse.c
packet_buffer.cpp
ps2_dev.c
ps2_service.c
;

View File

@ -10,19 +10,15 @@
*/
#include <Drivers.h>
#include <string.h>
#include "common.h"
#include "ps2_service.h"
#define DEVICE_MOUSE_NAME "input/mouse/ps2/0"
#define DEVICE_KEYBOARD_NAME "input/keyboard/at/0"
#include "ps2_dev.h"
int32 api_version = B_CUR_DRIVER_API_VERSION;
static device_hooks sKeyboardDeviceHooks = {
device_hooks sKeyboardDeviceHooks = {
keyboard_open,
keyboard_close,
keyboard_freecookie,
@ -35,7 +31,7 @@ static device_hooks sKeyboardDeviceHooks = {
NULL
};
static device_hooks sMouseDeviceHooks = {
device_hooks sMouseDeviceHooks = {
mouse_open,
mouse_close,
mouse_freecookie,
@ -54,6 +50,7 @@ sem_id gDeviceOpenSemaphore;
static sem_id sKbcSem;
static int32 sIgnoreInterrupts = 0;
static bool sMultiplexingActive = false;
inline uint8
@ -208,6 +205,7 @@ ps2_interrupt(void* cookie)
{
uint8 ctrl;
uint8 data;
ps2_dev *dev;
ctrl = ps2_read_ctrl();
if (!(ctrl & PS2_STATUS_OUTPUT_BUFFER_FULL))
@ -222,16 +220,18 @@ ps2_interrupt(void* cookie)
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (%s)\n", ctrl, data, (ctrl & PS2_STATUS_MOUSE_DATA) ? "mouse" : "keyb"));
if (ctrl & PS2_STATUS_MOUSE_DATA)
return mouse_handle_int(data);
else
return keyboard_handle_int(data);
if (ctrl & PS2_STATUS_MOUSE_DATA) {
uint8 idx = 0;
dev = &ps2_device[PS2_DEVICE_MOUSE + idx];
} else {
dev = &ps2_device[PS2_DEVICE_KEYB];
}
return ps2_dev_handle_int(dev, data);
}
// #pragma mark -
// driver interface
// #pragma mark - driver interface
status_t
@ -244,29 +244,13 @@ init_hardware(void)
const char **
publish_devices(void)
{
static char *kDevices[3];
int index = 0;
kDevices[index++] = DEVICE_MOUSE_NAME;
kDevices[index++] = DEVICE_KEYBOARD_NAME;
kDevices[index++] = NULL;
//status_t devfs_publish_device(const char *path, NULL, device_hooks *calls);
return (const char **)kDevices;
return NULL;
}
device_hooks *
find_device(const char *name)
{
if (!strcmp(name, DEVICE_MOUSE_NAME))
return &sMouseDeviceHooks;
else if (!strcmp(name, DEVICE_KEYBOARD_NAME))
return &sKeyboardDeviceHooks;
return NULL;
}
@ -296,7 +280,6 @@ init_driver(void)
if (status)
goto err_4;
{
uint8 d;
status_t res;
@ -309,18 +292,14 @@ init_driver(void)
res = ps2_set_command_byte(d);
dprintf("ps2_set_command_byte: res 0x%08x, d 0x%02x\n", res, d);
res = ps2_command(0xae, NULL, 0, NULL, 0);
dprintf("KBD enable: res 0x%08x\n", res);
}
res = ps2_command(0xa8, NULL, 0, NULL, 0);
dprintf("AUX enable: res 0x%08x\n", res);
res = ps2_command(0xab, NULL, 0, &d, 1);
dprintf("KBD test: res 0x%08x, d 0x%02x\n", res, d);
res = ps2_command(0xa9, NULL, 0, &d, 1);
dprintf("AUX test: res 0x%08x, d 0x%02x\n", res, d);
ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_KEYB]);
ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE]);
if (sMultiplexingActive) {
ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE + 1]);
ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE + 2]);
ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE + 3]);
}
//goto err_5;

View File

@ -14,6 +14,7 @@
#include <ISA.h>
#include <Drivers.h>
#include <KernelExport.h>
#include <OS.h>
@ -31,6 +32,9 @@
extern isa_module_info *gIsa;
extern sem_id gDeviceOpenSemaphore;
extern device_hooks sKeyboardDeviceHooks;
extern device_hooks sMouseDeviceHooks;
// prototypes from common.c
extern status_t ps2_wait_read();

View File

@ -0,0 +1,86 @@
/*
* Copyright 2005 Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* PS/2 hid device driver
*
* Authors (in chronological order):
* Marcus Overhagen (marcus@overhagen.de)
*/
#include "ps2_dev.h"
#include "ps2_service.h"
ps2_dev ps2_device[5] =
{
{ .name = "input/mouse/ps2/0", .active = false },
{ .name = "input/mouse/ps2/1", .active = false },
{ .name = "input/mouse/ps2/2", .active = false },
{ .name = "input/mouse/ps2/3", .active = false },
{ .name = "input/keyboard/at/0", .active = false, .flags = PS2_FLAG_KEYB }
};
void
ps2_dev_publish(ps2_dev *dev)
{
status_t status;
if (dev->active)
return;
TRACE(("ps2_dev_publish %s\n", dev->name));
dev->result_sem = create_sem(0, "ps2 result");
dev->result_buf = NULL;
dev->result_buf_idx = 0;
dev->result_buf_cnt = 0;
dev->flags &= ~PS2_FLAG_KEYB;
dev->active = true;
status = devfs_publish_device(dev->name, NULL,
(dev->flags & PS2_FLAG_KEYB) ? sKeyboardDeviceHooks : sMouseDeviceHooks);
TRACE(("devfs_publish_device %s, status = 0x%08x\n", dev->name, status));
}
void
ps2_dev_unpublish(ps2_dev *dev)
{
if (!dev->active)
return;
TRACE(("ps2_dev_unpublish %s\n", dev->name));
dev->active = false;
delete_sem(dev->result_sem);
}
int32
ps2_dev_handle_int(ps2_dev *dev, uint8 data)
{
if (!dev->active) {
ps2_service_handle_device_added(dev);
return B_HANDLED_INTERRUPT;
}
if (dev->result_buf_cnt) {
dev->result_buf[dev->result_buf_idx] = data;
dev->result_buf_idx++;
dev->result_buf_cnt--;
if (dev->result_buf_cnt == 0) {
release_sem_etc(dev->result_sem, 0, B_DO_NOT_RESCHEDULE);
return B_INVOKE_SCHEDULER;
}
return B_HANDLED_INTERRUPT;
}
// temporary hack...
if (dev->flags & PS2_FLAG_KEYB)
return keyboard_handle_int(data);
else
return mouse_handle_int(data);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2005 Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* PS/2 hid device driver
*
* Authors (in chronological order):
* Marcus Overhagen (marcus@overhagen.de)
*/
#ifndef __PS2_DEV_H
#define __PS2_DEV_H
#include "common.h"
typedef struct
{
const char * name;
bool active;
uint32 flags;
sem_id result_sem;
uint8 * result_buf;
int result_buf_idx;
int result_buf_cnt;
} ps2_dev;
extern ps2_dev ps2_device[5];
#define PS2_DEVICE_MOUSE 0
#define PS2_DEVICE_KEYB 4
#define PS2_FLAG_KEYB 1
void ps2_dev_publish(ps2_dev *dev);
void ps2_dev_unpublish(ps2_dev *dev);
int32 ps2_dev_handle_int(ps2_dev *dev, uint8 data);
#endif

View File

@ -15,6 +15,50 @@ static thread_id sServiceThread;
static volatile bool sServiceTerminate;
void
ps2_service_handle_device_added(ps2_dev *dev)
{
TRACE(("ps2_service_handle_device_added %s\n", dev->name));
}
void
ps2_service_handle_device_removed(ps2_dev *dev)
{
TRACE(("ps2_service_handle_device_removed %s\n", dev->name));
}
static status_t
ps2_service_probe_device(ps2_dev *dev)
{
uint8 d;
status_t res;
TRACE(("ps2_service_probe_device %s\n", dev->name));
if (dev->flags & PS2_FLAG_KEYB) {
res = ps2_command(0xae, NULL, 0, NULL, 0);
dprintf("KBD enable: res 0x%08x\n", res);
res = ps2_command(0xab, NULL, 0, &d, 1);
dprintf("KBD test: res 0x%08x, d 0x%02x\n", res, d);
} else {
res = ps2_command(0xa8, NULL, 0, NULL, 0);
dprintf("AUX enable: res 0x%08x\n", res);
res = ps2_command(0xa9, NULL, 0, &d, 1);
dprintf("AUX test: res 0x%08x, d 0x%02x\n", res, d);
}
return B_OK;
}
static int32
ps2_service_thread(void *arg)
{

View File

@ -11,8 +11,12 @@
#define __PS2_SERVICE_H
#include "common.h"
#include "ps2_dev.h"
status_t ps2_service_init(void);
void ps2_service_exit(void);
void ps2_service_handle_device_added(ps2_dev *dev);
void ps2_service_handle_device_removed(ps2_dev *dev);
#endif