Esempio n. 1
0
static status_t
set_typematic(int32 rate, bigtime_t delay)
{
	uint8 value;

	TRACE("ps2: set_typematic rate %ld, delay %Ld\n", rate, delay);

	// input server and keyboard preferences *seem* to use a range of 20-300
	if (rate < 20)
		rate = 20;
	if (rate > 300)
		rate = 300;

	// map this into range 0-31
	rate = ((rate - 20) * 31) / (300 - 20);

	// keyboard uses 0 == fast, 31 == slow
	value = 31 - rate;

	if (delay >= 875000)
		value |= 3 << 5;
	else if (delay >= 625000)
		value |= 2 << 5;
	else if (delay >= 375000)
		value |= 1 << 5;
	else
		value |= 0 << 5;

	return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB],
		PS2_CMD_KEYBOARD_SET_TYPEMATIC, &value, 1, NULL, 0);
}
Esempio n. 2
0
static status_t
set_leds(led_info *ledInfo)
{
	uint8 leds = 0;

	TRACE("ps2: set keyboard LEDs\n");

	if (ledInfo->scroll_lock)
		leds |= LED_SCROLL;
	if (ledInfo->num_lock)
		leds |= LED_NUM;
	if (ledInfo->caps_lock)
		leds |= LED_CAPS;

	return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB],
		PS2_CMD_KEYBOARD_SET_LEDS, &leds, 1, NULL, 0);
}
Esempio n. 3
0
status_t
probe_trackpoint(ps2_dev* dev)
{
	uint8 val[2];

	TRACE("TRACKPOINT: probe\n");
	ps2_dev_command(dev, 0xE1, NULL, 0, val, 2);

	if (val[0] != 0x01) {
		TRACE("TRACKPOINT: not found\n");
		return B_ERROR;
	}
	dev->name = kTrackpointPath[dev->idx];
	dev->packet_size = 3;
	TRACE("TRACKPOINT: version 0x%x found\n", val[1]);

	return B_OK;
}
Esempio n. 4
0
status_t
probe_keyboard(void)
{
	uint8 data;
	status_t status;

//  This test doesn't work relyable on some notebooks (it reports 0x03)
//	status = ps2_command(PS2_CTRL_KEYBOARD_TEST, NULL, 0, &data, 1);
//	if (status != B_OK || data != 0x00) {
//		INFO("ps2: keyboard test failed, status 0x%08lx, data 0x%02x\n", status, data);
//		return B_ERROR;
//	}

	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL,
		0, &data, 1);
	if (status != B_OK || data != 0xaa) {
		INFO("ps2: keyboard reset failed, status 0x%08lx, data 0x%02x\n",
			status, data);
		return B_ERROR;
	}

	// default settings after keyboard reset: delay = 0x01 (500 ms),
	// rate = 0x0b (10.9 chr/sec)
	sKeyboardRepeatRate = ((31 - 0x0b) * 280) / 31 + 20;
	sKeyboardRepeatDelay = 500000;

//	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_ENABLE_KEYBOARD, NULL, 0, NULL, 0);

//  On my notebook, the keyboard controller does NACK the echo command.
//	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_ECHO, NULL, 0, &data, 1);
//	if (status != B_OK || data != 0xee) {
//		INFO("ps2: keyboard echo test failed, status 0x%08lx, data 0x%02x\n", status, data);
//		return B_ERROR;
//	}

	return B_OK;
}
Esempio n. 5
0
static status_t
keyboard_ioctl(void *_cookie, uint32 op, void *buffer, size_t length)
{
	keyboard_cookie *cookie = (keyboard_cookie *)_cookie;

	switch (op) {
		case KB_READ:
		{
			if (!sHasKeyboardReader && !cookie->is_debugger) {
				cookie->is_reader = true;
				sHasKeyboardReader = true;
			} else if (!cookie->is_debugger && !cookie->is_reader)
				return B_BUSY;

			raw_key_info packet;
			status_t status = read_keyboard_packet(&packet,
				cookie->is_debugger);
			TRACE("ps2: ioctl KB_READ: %s\n", strerror(status));
			if (status != B_OK)
				return status;

			return user_memcpy(buffer, &packet, sizeof(packet));
		}

		case KB_SET_LEDS:
		{
			led_info info;
			TRACE("ps2: ioctl KB_SET_LEDS\n");
			if (user_memcpy(&info, buffer, sizeof(led_info)) < B_OK)
				return B_BAD_ADDRESS;
			return set_leds(&info);
		}

		case KB_SET_KEY_REPEATING:
		{
			TRACE("ps2: ioctl KB_SET_KEY_REPEATING\n");
			// 0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds
			// with "ack" (0xFA).
			return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xfa, NULL, 0,
				NULL, 0);
		}

		case KB_SET_KEY_NONREPEATING:
		{
			TRACE("ps2: ioctl KB_SET_KEY_NONREPEATING\n");
			// 0xF8 (Set All Keys Make/Break) - Keyboard responds with "ack"
			// (0xFA).
			return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xf8, NULL, 0,
				NULL, 0);
		}

		case KB_SET_KEY_REPEAT_RATE:
		{
			int32 key_repeat_rate;
			TRACE("ps2: ioctl KB_SET_KEY_REPEAT_RATE\n");
			if (user_memcpy(&key_repeat_rate, buffer, sizeof(key_repeat_rate))
					!= B_OK)
				return B_BAD_ADDRESS;
			if (set_typematic(key_repeat_rate, sKeyboardRepeatDelay) != B_OK)
				return B_ERROR;
			sKeyboardRepeatRate = key_repeat_rate;
			return B_OK;
		}

		case KB_GET_KEY_REPEAT_RATE:
		{
			TRACE("ps2: ioctl KB_GET_KEY_REPEAT_RATE\n");
			return user_memcpy(buffer, &sKeyboardRepeatRate,
				sizeof(sKeyboardRepeatRate));
		}

		case KB_SET_KEY_REPEAT_DELAY:
		{
			bigtime_t key_repeat_delay;
			TRACE("ps2: ioctl KB_SET_KEY_REPEAT_DELAY\n");
			if (user_memcpy(&key_repeat_delay, buffer, sizeof(key_repeat_delay))
					!= B_OK)
				return B_BAD_ADDRESS;
			if (set_typematic(sKeyboardRepeatRate, key_repeat_delay) != B_OK)
				return B_ERROR;
			sKeyboardRepeatDelay = key_repeat_delay;
			return B_OK;

		}

		case KB_GET_KEY_REPEAT_DELAY:
		{
			TRACE("ps2: ioctl KB_GET_KEY_REPEAT_DELAY\n");
			return user_memcpy(buffer, &sKeyboardRepeatDelay,
				sizeof(sKeyboardRepeatDelay));
		}

		case KB_GET_KEYBOARD_ID:
		case KB_SET_CONTROL_ALT_DEL_TIMEOUT:
		case KB_CANCEL_CONTROL_ALT_DEL:
		case KB_DELAY_CONTROL_ALT_DEL:
			INFO("ps2: ioctl 0x%lx not implemented yet, returning B_OK\n", op);
			return B_OK;

		case KB_SET_DEBUG_READER:
			if (sHasDebugReader)
				return B_BUSY;

			cookie->is_debugger = true;
			sHasDebugReader = true;
			return B_OK;

		default:
			INFO("ps2: invalid ioctl 0x%lx\n", op);
			return B_DEV_INVALID_IOCTL;
	}
}
Esempio n. 6
0
status_t
probe_keyboard(void)
{
	uint8 data;
	status_t status;

//  This test doesn't work relyable on some notebooks (it reports 0x03)
//	status = ps2_command(PS2_CTRL_KEYBOARD_TEST, NULL, 0, &data, 1);
//	if (status != B_OK || data != 0x00) {
//		INFO("ps2: keyboard test failed, status 0x%08lx, data 0x%02x\n", status, data);
//		return B_ERROR;
//	}

	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL,
		0, &data, 1);
	if (status != B_OK || data != 0xaa) {
		INFO("ps2: keyboard reset failed, status 0x%08lx, data 0x%02x\n",
			status, data);
		return B_ERROR;
	}

	// default settings after keyboard reset: delay = 0x01 (500 ms),
	// rate = 0x0b (10.9 chr/sec)
	sKeyboardRepeatRate = ((31 - 0x0b) * 280) / 31 + 20;
	sKeyboardRepeatDelay = 500000;

//	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_ENABLE_KEYBOARD, NULL, 0, NULL, 0);

//  On my notebook, the keyboard controller does NACK the echo command.
//	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_ECHO, NULL, 0, &data, 1);
//	if (status != B_OK || data != 0xee) {
//		INFO("ps2: keyboard echo test failed, status 0x%08lx, data 0x%02x\n", status, data);
//		return B_ERROR;
//	}

// Some controllers set the disble keyboard command bit to "on" after resetting
// the keyboard device. Read #7973 #6313 for more details.
// So check the command byte now and re-enable the keyboard if it is the case.
	uint8 cmdbyte = 0;
	status = ps2_command(PS2_CTRL_READ_CMD, NULL, 0, &cmdbyte, 1);

	if (status != B_OK) {
		INFO("ps2: cannot read CMD byte on kbd probe:0x%#08lx\n", status);
	} else
	if ((cmdbyte & PS2_BITS_KEYBOARD_DISABLED) == PS2_BITS_KEYBOARD_DISABLED) {
		cmdbyte &= ~PS2_BITS_KEYBOARD_DISABLED;
		status = ps2_command(PS2_CTRL_WRITE_CMD, &cmdbyte, 1, NULL, 0);
		if (status != B_OK) {
			INFO("ps2: cannot write 0x%02x to CMD byte on kbd probe:0x%08lx\n",
					cmdbyte, status);
		}
	}
	
	status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB],
			PS2_CMD_GET_DEVICE_ID, NULL, 0, sKeyboardIds, sizeof(sKeyboardIds));
	
	if (status != B_OK) {
		INFO("ps2: cannot read keyboard device id:0x%#08lx\n", status);
	}

	return B_OK;
}