コード例 #1
0
ファイル: akbd.c プロジェクト: sofuture/bitrig
/*
 * Set the keyboard LED's.
 *
 * Automatically translates from ioctl/softc format to the
 * actual keyboard register format
 */
int
setleds(struct akbd_softc *sc, u_char leds)
{
	int addr;
	short cmd;
	u_char buffer[9];

	addr = sc->adbaddr;
	buffer[0] = 0;

	cmd = ADBTALK(addr, 2);
	if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
		return (EIO);

	leds = ~leds & 0x07;
	buffer[2] &= 0xf8;
	buffer[2] |= leds;

	cmd = ADBLISTEN(addr, 2);
	adb_op_sync((Ptr)buffer, cmd);

	/* talk R2 */
	cmd = ADBTALK(addr, 2);
	if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
		return (EIO);

	if ((buffer[2] & 0xf8) != leds)
		return (EIO);
	else
		return (0);
}
コード例 #2
0
/*
 * Set the keyboard LED's.
 * 
 * Automatically translates from ioctl/softc format to the
 * actual keyboard register format
 */
static void
adbkbd_set_leds(void *cookie, int leds)
{
	struct adbkbd_softc *sc = cookie;
	int aleds;
	short cmd;
	uint8_t buffer[2];

	DPRINTF("adbkbd_set_leds: %02x\n", leds);
	if ((leds & 0x07) == (sc->sc_leds & 0x07))
		return;

 	if (sc->sc_have_led_control) {

		aleds = (~leds & 0x04) | 3;
		if (leds & 1)
			aleds &= ~2;
		if (leds & 2)
			aleds &= ~1;

		buffer[0] = 0xff;
		buffer[1] = aleds | 0xf8;
	
		cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 2);
		sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, 
		    buffer);
	}

	sc->sc_leds = leds & 7;
}
コード例 #3
0
ファイル: adbsys.c プロジェクト: lacombar/netbsd-alc
/*
 * initialize extended mouse - probes devices as
 * described in _Inside Macintosh, Devices_.
 */
void
extdms_init(int totaladbs)
{
	ADBDataBlock adbdata;
	int adbindex, adbaddr, count;
	short cmd;
	u_char buffer[9];

	for (adbindex = 1; adbindex <= totaladbs; adbindex++) {
		/* Get the ADB information */
		adbaddr = GetIndADB(&adbdata, adbindex);
		if (adbdata.origADBAddr == ADBADDR_MS &&
		    (adbdata.devType == ADBMS_USPEED ||
		     adbdata.devType == ADBMS_UCONTOUR)) {
			/* Found MicroSpeed Mouse Deluxe Mac or Contour Mouse */
			cmd = ADBLISTEN(adbaddr, 1);

			/*
			 * To setup the MicroSpeed or the Contour, it appears
			 * that we can send the following command to the mouse
			 * and then expect data back in the form:
			 *  buffer[0] = 4 (bytes)
			 *  buffer[1], buffer[2] as std. mouse
			 *  buffer[3] = buffer[4] = 0xff when no buttons
			 *   are down.  When button N down, bit N is clear.
			 * buffer[4]'s locking mask enables a
			 * click to toggle the button down state--sort of
			 * like the "Easy Access" shift/control/etc. keys.
			 * buffer[3]'s alternative speed mask enables using 
			 * different speed when the corr. button is down
			 */
			buffer[0] = 4;
			buffer[1] = 0x00;	/* Alternative speed */
			buffer[2] = 0x00;	/* speed = maximum */
			buffer[3] = 0x10;	/* enable extended protocol,
						 * lower bits = alt. speed mask
						 *            = 0000b
						 */
			buffer[4] = 0x07;	/* Locking mask = 0000b,
						 * enable buttons = 0111b
						 */
			extdms_done = 0;
			ADBOp((Ptr)buffer, (Ptr)extdms_complete,
				(Ptr)&extdms_done, cmd);
			while (!extdms_done)
				/* busy wait until done */;
		}
		if (adbdata.origADBAddr == ADBADDR_MS &&
		    (adbdata.devType == ADBMS_100DPI ||
		    adbdata.devType == ADBMS_200DPI)) {
			/* found a mouse */
			cmd = ADBTALK(adbaddr, 3);
			extdms_done = 0;
			ADBOp((Ptr)buffer, (Ptr)extdms_complete,
			      (Ptr)&extdms_done, cmd);

			/* Wait until done, but no more than 2 secs */
			count = 40000;
			while (!extdms_done && count-- > 0)
				delay(50);

			if (!extdms_done) {
#ifdef ADB_DEBUG
				if (adb_debug)
					printf("adb: extdms_init timed out\n");
#endif
				return;
			}

			/* Attempt to initialize Extended Mouse Protocol */
			buffer[2] = '\004'; /* make handler ID 4 */
			extdms_done = 0;
			cmd = ADBLISTEN(adbaddr, 3);
			ADBOp((Ptr)buffer, (Ptr)extdms_complete,
			      (Ptr)&extdms_done, cmd);
			while (!extdms_done)
				/* busy wait until done */;

			/*
			 * Check to see if successful, if not
			 * try to initialize it as other types
			 */
			cmd = ADBTALK(adbaddr, 3);
			extdms_done = 0;
			ADBOp((Ptr)buffer, (Ptr)extdms_complete,
			      (Ptr)&extdms_done, cmd);
			while (!extdms_done)
				/* busy wait until done */;
				
			if (buffer[2] != ADBMS_EXTENDED) {
				/* Attempt to initialize as an A3 mouse */
				buffer[2] = 0x03; /* make handler ID 3 */
				extdms_done = 0;
				cmd = ADBLISTEN(adbaddr, 3);
				ADBOp((Ptr)buffer, (Ptr)extdms_complete,
				      (Ptr)&extdms_done, cmd);
				while (!extdms_done)
					/* busy wait until done */;
		
				/*
				 * Check to see if successful, if not
				 * try to initialize it as other types
				 */
				cmd = ADBTALK(adbaddr, 3);
				extdms_done = 0;
				ADBOp((Ptr)buffer, (Ptr)extdms_complete,
				      (Ptr)&extdms_done, cmd);
				while (!extdms_done)
					/* busy wait until done */;
					
				if (buffer[2] == ADBMS_MSA3) {
					/* Initialize as above */
					cmd = ADBLISTEN(adbaddr, 2);
					/* listen 2 */
					buffer[0] = 3;
					buffer[1] = 0x00;
					/* Irrelevant, buffer has 0x77 */
					buffer[2] = 0x07;
					/*
					 * enable 3 button mode = 0111b,
					 * speed = normal
					 */
					extdms_done = 0;
					ADBOp((Ptr)buffer, (Ptr)extdms_complete,
					      (Ptr)&extdms_done, cmd);
					while (!extdms_done)
						/* busy wait until done */;
				} else {
					/* No special support for this mouse */
				}
			}
		}
	}
}
コード例 #4
0
static void
adbkbd_attach(device_t parent, device_t self, void *aux)
{
	struct adbkbd_softc *sc = device_private(self);
	struct adb_attach_args *aaa = aux;
	short cmd;
	struct wskbddev_attach_args a;
#if NWSMOUSE > 0
	struct wsmousedev_attach_args am;
#endif
	uint8_t buffer[2];

	sc->sc_dev = self;
	sc->sc_ops = aaa->ops;
	sc->sc_adbdev = aaa->dev;
	sc->sc_adbdev->cookie = sc;
	sc->sc_adbdev->handler = adbkbd_handler;
	sc->sc_us = ADBTALK(sc->sc_adbdev->current_addr, 0);

	sc->sc_leds = 0;	/* initially off */
	sc->sc_have_led_control = 0;

	/*
	 * If this is != 0 then pushing the power button will not immadiately
	 * send a shutdown event to sysmon but instead require another key
	 * press within 5 seconds with a gap of at least two seconds. The 
	 * reason to do this is the fact that some PowerBook keyboards,
	 * like the 2400, 3400 and original G3 have their power buttons
	 * right next to the backspace key and it's extremely easy to hit
	 * it by accident.
	 * On most other keyboards the power button is sufficiently far out
	 * of the way so we don't need this.
	 */
	sc->sc_power_button_delay = 0;
	sc->sc_msg_len = 0;
	sc->sc_poll = 0;
	sc->sc_capslock = 0;
	sc->sc_trans[1] = 103;	/* F11 */
	sc->sc_trans[2] = 111;	/* F12 */
	
	/*
	 * Most ADB keyboards send 0x7f 0x7f when the power button is pressed.
	 * Some older PowerBooks, like the 3400c, will send a single scancode
	 * 0x7e instead. Unfortunately Fn-Command on some more recent *Books
	 * sends the same scancode, so by default sc_power is set to a value
	 * that can't occur as a scancode and only set to 0x7e on hardware that
	 * needs it
	 */
	sc->sc_power = 0xffff;
	sc->sc_timestamp = 0;
	sc->sc_emul_usb = FALSE;

	aprint_normal(" addr %d: ", sc->sc_adbdev->current_addr);

	switch (sc->sc_adbdev->handler_id) {
	case ADB_STDKBD:
		aprint_normal("standard keyboard\n");
		break;
	case ADB_ISOKBD:
		aprint_normal("standard keyboard (ISO layout)\n");
		break;
	case ADB_EXTKBD:
		cmd = ADBTALK(sc->sc_adbdev->current_addr, 1);
		sc->sc_msg_len = 0;
		sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL);
		adbkbd_wait(sc, 10);

		/* Ignore Logitech MouseMan/Trackman pseudo keyboard */
		/* XXX needs testing */
		if (sc->sc_buffer[2] == 0x9a && sc->sc_buffer[3] == 0x20) {
			aprint_normal("Mouseman (non-EMP) pseudo keyboard\n");
			return;
		} else if (sc->sc_buffer[2] == 0x9a && 
		    sc->sc_buffer[3] == 0x21) {
			aprint_normal("Trackman (non-EMP) pseudo keyboard\n");
			return;
		} else {
			aprint_normal("extended keyboard\n");
			adbkbd_initleds(sc);
		}
		break;
	case ADB_EXTISOKBD:
		aprint_normal("extended keyboard (ISO layout)\n");
		adbkbd_initleds(sc);
		break;
	case ADB_KBDII:
		aprint_normal("keyboard II\n");
		break;
	case ADB_ISOKBDII:
		aprint_normal("keyboard II (ISO layout)\n");
		break;
	case ADB_PBKBD:
		aprint_normal("PowerBook keyboard\n");
		sc->sc_power = 0x7e;
		sc->sc_power_button_delay = 1;
		break;
	case ADB_PBISOKBD:
		aprint_normal("PowerBook keyboard (ISO layout)\n");
		sc->sc_power = 0x7e;
		sc->sc_power_button_delay = 1;
		break;
	case ADB_ADJKPD:
		aprint_normal("adjustable keypad\n");
		break;
	case ADB_ADJKBD:
		aprint_normal("adjustable keyboard\n");
		break;
	case ADB_ADJISOKBD:
		aprint_normal("adjustable keyboard (ISO layout)\n");
		break;
	case ADB_ADJJAPKBD:
		aprint_normal("adjustable keyboard (Japanese layout)\n");
		break;
	case ADB_PBEXTISOKBD:
		aprint_normal("PowerBook extended keyboard (ISO layout)\n");
		sc->sc_power_button_delay = 1;
		sc->sc_power = 0x7e;
		break;
	case ADB_PBEXTJAPKBD:
		aprint_normal("PowerBook extended keyboard (Japanese layout)\n");
		sc->sc_power_button_delay = 1;
		sc->sc_power = 0x7e;
		break;
	case ADB_JPKBDII:
		aprint_normal("keyboard II (Japanese layout)\n");
		break;
	case ADB_PBEXTKBD:
		aprint_normal("PowerBook extended keyboard\n");
		sc->sc_power_button_delay = 1;
		sc->sc_power = 0x7e;
		break;
	case ADB_DESIGNKBD:
		aprint_normal("extended keyboard\n");
		adbkbd_initleds(sc);
		break;
	case ADB_PBJPKBD:
		aprint_normal("PowerBook keyboard (Japanese layout)\n");
		sc->sc_power_button_delay = 1;
		sc->sc_power = 0x7e;
		break;
	case ADB_PBG3KBD:
		aprint_normal("PowerBook G3 keyboard\n");
		break;
	case ADB_PBG3JPKBD:
		aprint_normal("PowerBook G3 keyboard (Japanese layout)\n");
		break;
	case ADB_IBOOKKBD:
		aprint_normal("iBook keyboard\n");
		break;
	default:
		aprint_normal("mapped device (%d)\n", sc->sc_adbdev->handler_id);
		break;
	}

	/*
	 * try to switch to extended protocol
	 * as in, tell the keyboard to distinguish between left and right
	 * Shift, Control and Alt keys
	 */
	cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 3);
	buffer[0] = sc->sc_adbdev->current_addr;
	buffer[1] = 3;
	sc->sc_msg_len = 0;
	sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, buffer);
	adbkbd_wait(sc, 10);

	cmd = ADBTALK(sc->sc_adbdev->current_addr, 3);
	sc->sc_msg_len = 0;
	sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL);
	adbkbd_wait(sc, 10);
	if ((sc->sc_msg_len == 4) && (sc->sc_buffer[3] == 3)) {
		aprint_verbose_dev(sc->sc_dev, "extended protocol enabled\n");
	}

	if (adbkbd_is_console && (adbkbd_console_attached == 0)) {
		wskbd_cnattach(&adbkbd_consops, sc, &adbkbd_keymapdata);
		adbkbd_console_attached = 1;
		a.console = 1;
	} else {
		a.console = 0;
	}
	a.keymap = &adbkbd_keymapdata;
	a.accessops = &adbkbd_accessops;
	a.accesscookie = sc;

	sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint);
#ifdef ADBKBD_EMUL_USB
	sc->sc_emul_usb = TRUE;
	wskbd_set_evtrans(sc->sc_wskbddev, adb_to_usb, 128);
#endif /* ADBKBD_EMUL_USB */

#if NWSMOUSE > 0
	/* attach the mouse device */
	am.accessops = &adbkms_accessops;
	am.accesscookie = sc;
	sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &am, 
	    wsmousedevprint);

#endif
	adbkbd_setup_sysctl(sc);

	/* finally register the power button */
	sysmon_task_queue_init();
	memset(&sc->sc_sm_pbutton, 0, sizeof(struct sysmon_pswitch));
	sc->sc_sm_pbutton.smpsw_name = device_xname(sc->sc_dev);
	sc->sc_sm_pbutton.smpsw_type = PSWITCH_TYPE_POWER;
	if (sysmon_pswitch_register(&sc->sc_sm_pbutton) != 0)
		aprint_error_dev(sc->sc_dev,
		    "unable to register power button with sysmon\n");
}