Esempio n. 1
0
int
ums_match(device_t parent, cfdata_t match, void *aux)
{
	struct uhidev_attach_arg *uha = aux;
	int size;
	void *desc;

	/*
	 * Some (older) Griffin PowerMate knobs may masquerade as a
	 * mouse, avoid treating them as such, they have only one axis.
	 */
	if (uha->uiaa->uiaa_vendor == USB_VENDOR_GRIFFIN &&
	    uha->uiaa->uiaa_product == USB_PRODUCT_GRIFFIN_POWERMATE)
		return UMATCH_NONE;

	uhidev_get_report_desc(uha->parent, &desc, &size);
	if (!hid_is_collection(desc, size, uha->reportid,
			       HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)) &&
	    !hid_is_collection(desc, size, uha->reportid,
			       HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_POINTER)) &&
	    !hid_is_collection(desc, size, uha->reportid,
			       HID_USAGE2(HUP_DIGITIZERS, 0x0002)))
		return UMATCH_NONE;

	return UMATCH_IFACECLASS;
}
Esempio n. 2
0
File: uts.c Progetto: ryo/netbsd-src
Static int
uts_match(device_t parent, cfdata_t match, void *aux)
{
	struct uhidev_attach_arg *uha = aux;
	int size;
	void *desc;

	uhidev_get_report_desc(uha->parent, &desc, &size);
	if (!hid_is_collection(desc, size, uha->reportid,
	    HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCH_SCREEN)) &&
	    !hid_is_collection(desc, size, uha->reportid,
	    HID_USAGE2(HUP_DIGITIZERS, HUD_FINGER)))
		return UMATCH_NONE;

	return UMATCH_IFACECLASS;
}
Esempio n. 3
0
static int
btms_match(device_t parent, cfdata_t match, void *aux)
{
	struct bthidev_attach_args *ba = aux;

	if (hid_is_collection(ba->ba_desc, ba->ba_dlen, ba->ba_id,
			    HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
		return 1;

	return 0;
}
Esempio n. 4
0
static int
btkbd_match(device_t self, cfdata_t cfdata, void *aux)
{
	struct bthidev_attach_args *ba = aux;

	if (hid_is_collection(ba->ba_desc, ba->ba_dlen, ba->ba_id,
			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
		return 1;

	return 0;
}
Esempio n. 5
0
int
ums_match(struct device *parent, void *match, void *aux)
{
    struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
    int size;
    void *desc;

    uhidev_get_report_desc(uha->parent, &desc, &size);

    if (hid_is_collection(desc, size, uha->reportid,
                          HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
        return (UMATCH_IFACECLASS);

    if (hid_is_collection(desc, size, uha->reportid,
                          HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN)))
        return (UMATCH_IFACECLASS);

    if (hid_is_collection(desc, size, uha->reportid,
                          HID_USAGE2(HUP_DIGITIZERS, HUD_PEN)))
        return (UMATCH_IFACECLASS);

    return (UMATCH_NONE);
}
Esempio n. 6
0
int
ukbd_match(device_t parent, cfdata_t match, void *aux)
{
	struct uhidev_attach_arg *uha = aux;
	int size;
	void *desc;

	uhidev_get_report_desc(uha->parent, &desc, &size);
	if (!hid_is_collection(desc, size, uha->reportid,
			       HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
		return (UMATCH_NONE);

	return (UMATCH_IFACECLASS);
}
Esempio n. 7
0
void
ums_attach(device_t parent, device_t self, void *aux)
{
	struct ums_softc *sc = device_private(self);
	struct uhidev_attach_arg *uha = aux;
	struct wsmousedev_attach_args a;
	int size;
	void *desc;
	uint32_t flags, quirks;
	int i, hl;
	struct hid_location *zloc;
	bool isdigitizer;

	aprint_naive("\n");

	sc->sc_hdev.sc_dev = self;
	sc->sc_hdev.sc_intr = ums_intr;
	sc->sc_hdev.sc_parent = uha->parent;
	sc->sc_hdev.sc_report_id = uha->reportid;

	quirks = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
	if (quirks & UQ_MS_REVZ)
		sc->flags |= UMS_REVZ;
	if (quirks & UQ_SPUR_BUT_UP)
		sc->flags |= UMS_SPUR_BUT_UP;

	uhidev_get_report_desc(uha->parent, &desc, &size);

	isdigitizer = hid_is_collection(desc, size, uha->reportid,
	    HID_USAGE2(HUP_DIGITIZERS, 0x0002));

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");

	if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
	       uha->reportid, hid_input, &sc->sc_loc_x, &flags)) {
		aprint_error("\n%s: mouse has no X report\n",
		       device_xname(sc->sc_hdev.sc_dev));
		return;
	}
	switch (flags & MOUSE_FLAGS_MASK) {
	case 0:
		sc->flags |= UMS_ABS;
		break;
	case HIO_RELATIVE:
		break;
	default:
		aprint_error("\n%s: X report 0x%04x not supported\n",
		       device_xname(sc->sc_hdev.sc_dev), flags);
		return;
	}

	if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
	       uha->reportid, hid_input, &sc->sc_loc_y, &flags)) {
		aprint_error("\n%s: mouse has no Y report\n",
		       device_xname(sc->sc_hdev.sc_dev));
		return;
	}
	switch (flags & MOUSE_FLAGS_MASK) {
	case 0:
		sc->flags |= UMS_ABS;
		break;
	case HIO_RELATIVE:
		break;
	default:
		aprint_error("\n%s: Y report 0x%04x not supported\n",
		       device_xname(sc->sc_hdev.sc_dev), flags);
		return;
	}

	/* Try the wheel first as the Z activator since it's tradition. */
	hl = hid_locate(desc,
			size,
			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
			uha->reportid,
			hid_input,
			&sc->sc_loc_z,
			&flags);

	zloc = &sc->sc_loc_z;
	if (hl) {
		if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
			aprint_verbose("\n%s: Wheel report 0x%04x not "
			    "supported\n", device_xname(sc->sc_hdev.sc_dev),
			    flags);
			sc->sc_loc_z.size = 0;	/* Bad Z coord, ignore it */
		} else {
			sc->flags |= UMS_Z;
			/* Wheels need the Z axis reversed. */
			sc->flags ^= UMS_REVZ;
			/* Put Z on the W coordinate */
			zloc = &sc->sc_loc_w;
		}
	}

	hl = hid_locate(desc,
			size,
			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
			uha->reportid,
			hid_input,
			zloc,
			&flags);

	/*
	 * The horizontal component of the scrollball can also be given by
	 * Application Control Pan in the Consumer page, so if we didnt see
	 * any Z then check that.
	 */
	if (!hl) {
		hl = hid_locate(desc,
				size,
				HID_USAGE2(HUP_CONSUMER, HUC_AC_PAN),
				uha->reportid,
				hid_input,
				zloc,
				&flags);
	}

	if (hl) {
		if ((flags & MOUSE_FLAGS_MASK) != HIO_RELATIVE) {
			aprint_verbose("\n%s: Z report 0x%04x not supported\n",
			       device_xname(sc->sc_hdev.sc_dev), flags);
			zloc->size = 0;	/* Bad Z coord, ignore it */
		} else {
			if (sc->flags & UMS_Z)
				sc->flags |= UMS_W;
			else
				sc->flags |= UMS_Z;
		}
	}

	if (uha->uiaa->uiaa_vendor == USB_VENDOR_MICROSOFT) {
		int fixpos;
		/*
		 * The Microsoft Wireless Laser Mouse 6000 v2.0 and the
		 * Microsoft Comfort Mouse 2.0 report a bad position for
		 * the wheel and wheel tilt controls -- should be in bytes
		 * 3 & 4 of the report. Fix this if necessary.
		 */
		switch (uha->uiaa->uiaa_product) {
		case USB_PRODUCT_MICROSOFT_24GHZ_XCVR10:
		case USB_PRODUCT_MICROSOFT_24GHZ_XCVR20:
			fixpos = 24;
			break;
		case USB_PRODUCT_MICROSOFT_CM6000:
			fixpos = 40;
			break;
		default:
			fixpos = 0;
			break;
		}
		if (fixpos) {
			if ((sc->flags & UMS_Z) && sc->sc_loc_z.pos == 0)
				sc->sc_loc_z.pos = fixpos;
			if ((sc->flags & UMS_W) && sc->sc_loc_w.pos == 0)
				sc->sc_loc_w.pos = sc->sc_loc_z.pos + 8;
		}
	}

	/* figure out the number of buttons */
	for (i = 1; i <= MAX_BUTTONS; i++)
		if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
		    uha->reportid, hid_input, &sc->sc_loc_btn[i - 1], 0))
			break;

	if (isdigitizer) {
		for (size_t j = 0; j < __arraycount(digbut); j++) {
			if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS,
			    digbut[j].feature), uha->reportid, hid_input,
			    &sc->sc_loc_btn[i - 1], 0)) {
				if (i <= MAX_BUTTONS) {
					i++;
					sc->flags |= digbut[j].flag;
				} else
					aprint_error_dev(self,
					    "ran out of buttons\n");
			}
		}
	}
	sc->nbuttons = i - 1;

	aprint_normal(": %d button%s%s%s%s%s%s%s%s%s\n",
	    sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
	    sc->flags & UMS_W ? ", W" : "",
	    sc->flags & UMS_Z ? " and Z dir" : "",
	    sc->flags & UMS_W ? "s" : "",
	    isdigitizer ? " digitizer"  : "",
	    sc->flags & UMS_TIP_SWITCH ? ", tip" : "",
	    sc->flags & UMS_SEC_TIP_SWITCH ? ", sec tip" : "",
	    sc->flags & UMS_BARREL_SWITCH ? ", barrel" : "",
	    sc->flags & UMS_ERASER ? ", eraser" : "");

#ifdef UMS_DEBUG
	DPRINTF(("ums_attach: sc=%p\n", sc));
	DPRINTF(("ums_attach: X\t%d/%d\n",
		 sc->sc_loc_x.pos, sc->sc_loc_x.size));
	DPRINTF(("ums_attach: Y\t%d/%d\n",
		 sc->sc_loc_y.pos, sc->sc_loc_y.size));
	if (sc->flags & UMS_Z)
		DPRINTF(("ums_attach: Z\t%d/%d\n",
			 sc->sc_loc_z.pos, sc->sc_loc_z.size));
	if (sc->flags & UMS_W)
		DPRINTF(("ums_attach: W\t%d/%d\n",
			 sc->sc_loc_w.pos, sc->sc_loc_w.size));
	for (i = 1; i <= sc->nbuttons; i++) {
		DPRINTF(("ums_attach: B%d\t%d/%d\n",
			 i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));
	}
#endif

	a.accessops = &ums_accessops;
	a.accesscookie = sc;

	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);

	return;
}