예제 #1
0
static int
adb_tapping_sysctl(SYSCTL_HANDLER_ARGS)
{
	struct adb_mouse_softc *sc = arg1;
	device_t dev;
        int error;
	u_char r2[8];
	u_int tapping;

	dev = sc->sc_dev;
	tapping = sc->sc_tapping;

	error = sysctl_handle_int(oidp, &tapping, 0, req);

	if (error || !req->newptr)
		return (error);

	if (tapping == 1) {
		adb_read_register(dev, 2, r2);
		r2[0] = 0x99; /* enable tapping. */
		adb_write_register(dev, 2, 8, r2);
                sc->sc_tapping = 1;
	} else if (tapping == 0) {
		adb_read_register(dev, 2, r2);
		r2[0] = 0x19; /* disable tapping. */
		adb_write_register(dev, 2, 8, r2);
		sc->sc_tapping = 0;
	}
        else
		return (EINVAL);

	return (0);
}
예제 #2
0
static int
adb_fn_keys(SYSCTL_HANDLER_ARGS)
{
	struct adb_kbd_softc *sc = arg1;
	int error;
	uint16_t is_fn_enabled;
	unsigned int is_fn_enabled_sysctl;

	adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
	is_fn_enabled &= 1;
	is_fn_enabled_sysctl = is_fn_enabled;
	error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);

	if (error || !req->newptr)
		return (error);

	is_fn_enabled = is_fn_enabled_sysctl;
	if (is_fn_enabled != 1 && is_fn_enabled != 0)
		return (EINVAL);

	adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
	return (0);
}
예제 #3
0
static void
adb_init_trackpad(device_t dev)
{
	struct adb_mouse_softc *sc;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid *tree;

	size_t r1_len;
	u_char r1[8];
	u_char r2[8];

	sc = device_get_softc(dev);

	r1_len = adb_read_register(dev, 1, r1);

	/* An Extended Mouse register1 must return 8 bytes. */
	if (r1_len != 8)
		return;

	if((r1[6] != 0x0d))
	{
		r1[6] = 0x0d;
		
		adb_write_register(dev, 1, 8, r1); 
      
		r1_len = adb_read_register(dev, 1, r1);
      
		if (r1[6] != 0x0d)
		{
			device_printf(dev, "ADB Mouse = 0x%x "
				      "(non-Extended Mode)\n", r1[6]);
			return;
		} else {
			device_printf(dev, "ADB Mouse = 0x%x "
				      "(Extended Mode)\n", r1[6]);
			
			/* Set ADB Extended Features to default values,
			   enabled. */
			r2[0] = 0x19; /* Clicking: 0x19 disabled 0x99 enabled */
			r2[1] = 0x94; /* Dragging: 0x14 disabled 0x94 enabled */
			r2[2] = 0x19;
			r2[3] = 0xff; /* DragLock: 0xff disabled 0xb2 enabled */
			r2[4] = 0xb2;
			r2[5] = 0x8a;
			r2[6] = 0x1b;
		       
			r2[7] = 0x57;  /* 0x57 bits 3:0 for W mode */
			
			adb_write_register(dev, 2, 8, r2);
			
		}
	}

	/*
	 * Set up sysctl
	 */
	ctx = device_get_sysctl_ctx(dev);
	tree = device_get_sysctl_tree(dev);
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tapping",
			CTLTYPE_INT | CTLFLAG_RW, sc, 0, adb_tapping_sysctl,
			"I", "Tapping the pad causes button events");
	return;
}
예제 #4
0
static int 
adb_mouse_attach(device_t dev) 
{
	struct adb_mouse_softc *sc;
	char *description = "Unknown Pointing Device";

	size_t r1_len;
	u_char r1[8];

	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	mtx_init(&sc->sc_mtx, "ams", NULL, MTX_DEF);
	cv_init(&sc->sc_cv,"ams");

	sc->flags = 0;

	sc->hw.buttons = 2;
	sc->hw.iftype = MOUSE_IF_UNKNOWN;
	sc->hw.type = MOUSE_UNKNOWN;
	sc->hw.model = sc->hw.hwid = 0;

	sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;
	sc->mode.rate = -1;
	sc->mode.resolution = 100;
	sc->mode.accelfactor = 0;
	sc->mode.level = 0;
	sc->mode.packetsize = 5;

	sc->buttons = 0;
	sc->sc_tapping = 0;
	sc->button_buf = 0;
	sc->last_buttons = 0;
	sc->packet_read_len = 0;

	/* Try to switch to extended protocol */
	adb_set_device_handler(dev,4);

	switch(adb_get_device_handler(dev)) {
	case 1:
		sc->mode.resolution = 100;
		break;
	case 2:
		sc->mode.resolution = 200;
		break;
	case 4:
		r1_len = adb_read_register(dev,1,r1);
		if (r1_len < 8)
			break;

		sc->flags |= AMS_EXTENDED;
		memcpy(&sc->hw.hwid,r1,4);
		sc->mode.resolution = (r1[4] << 8) | r1[5];

		switch (r1[6]) {
		case 0:
			sc->hw.type = MOUSE_PAD;
			description = "Tablet";
			break;
		case 1:
			sc->hw.type = MOUSE_MOUSE;
			description = "Mouse";
			break;
		case 2:
			sc->hw.type = MOUSE_TRACKBALL;
			description = "Trackball";
			break;
		case 3:
			sc->flags |= AMS_TOUCHPAD;
			sc->hw.type = MOUSE_PAD;
			adb_init_trackpad(dev);
			description = "Touchpad";
			break;
		}

		sc->hw.buttons = r1[7];

		device_printf(dev,"%d-button %d-dpi %s\n",
		    sc->hw.buttons, sc->mode.resolution,description);

		/*
		 * Check for one of MacAlly's non-compliant 2-button mice.
		 * These claim to speak the extended mouse protocol, but
		 * instead speak the standard protocol and only when their
		 * handler is set to 0x42.
		 */

		if (sc->hw.hwid == 0x4b4f4954) {
			adb_set_device_handler(dev,0x42);

			if (adb_get_device_handler(dev) == 0x42) {
				device_printf(dev, "MacAlly 2-Button Mouse\n");
				sc->flags &= ~AMS_EXTENDED;
			}
		}
			
		break;
	}

	sc->cdev = make_dev(&ams_cdevsw, device_get_unit(dev),
		       UID_ROOT, GID_OPERATOR, 0644, "ams%d", 
		       device_get_unit(dev));
	sc->cdev->si_drv1 = sc;

	adb_set_autopoll(dev,1);

	return (0);
}
예제 #5
0
static int 
adb_kbd_attach(device_t dev) 
{
	struct adb_kbd_softc *sc;
	keyboard_switch_t *sw;
	uint32_t fkeys;
	phandle_t handle;

	sw = kbd_get_switch(KBD_DRIVER_NAME);
	if (sw == NULL) {
		return ENXIO;
	}

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_mode = K_RAW;
	sc->sc_state = 0;
	sc->have_led_control = 0;
	sc->buffers = 0;

	/* Try stepping forward to the extended keyboard protocol */
	adb_set_device_handler(dev,3);

	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
	callout_init(&sc->sc_repeater, 0);

#ifdef AKBD_EMULATE_ATKBD
	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
            sizeof(fkey_tab) / sizeof(fkey_tab[0]));
#else
	#error ADB raw mode not implemented
#endif

	KBD_FOUND_DEVICE(&sc->sc_kbd);
	KBD_PROBE_DONE(&sc->sc_kbd);
	KBD_INIT_DONE(&sc->sc_kbd);
	KBD_CONFIG_DONE(&sc->sc_kbd);

	(*sw->enable)(&sc->sc_kbd);

	kbd_register(&sc->sc_kbd);

#ifdef KBD_INSTALL_CDEV
	if (kbd_attach(&sc->sc_kbd)) {
		adb_kbd_detach(dev);
		return ENXIO;
	}
#endif

	/* Check if we can read out the LED state from 
	   this keyboard by reading the key state register */
	if (adb_read_register(dev, 2, NULL) == 2)
		sc->have_led_control = 1;

	adb_set_autopoll(dev,1);

	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
	    &fkeys, sizeof(fkeys)) != -1) {
		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
		struct sysctl_ctx_list *ctx;
		struct sysctl_oid *tree;
		int i;

		if (bootverbose)
			device_printf(dev, "Keyboard has embedded Fn keys\n");

		for (i = 0; i < 12; i++) {
			uint32_t keyval;
			char buf[3];
			if (OF_getprop(handle, key_names[i], &keyval,
			    sizeof(keyval)) < 0)
				continue;
			buf[0] = 1;
			buf[1] = i+1;
			buf[2] = keyval;
			adb_write_register(dev, 0, 3, buf);
		}
		adb_write_register(dev, 1, 2, &(uint16_t){0});

		ctx = device_get_sysctl_ctx(dev);
		tree = device_get_sysctl_tree(dev);

		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, adb_fn_keys, "I",
		    "Set the Fn keys to be their F-key type as default");
	}

	return (0);
}