patch-2.3.41 linux/drivers/usb/hid.c

Next file: linux/drivers/usb/hid.h
Previous file: linux/drivers/usb/graphire.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.40/linux/drivers/usb/hid.c linux/drivers/usb/hid.c
@@ -742,7 +742,11 @@
 			switch (device->application) {
 				case HID_GD_GAMEPAD:  usage->code += 0x10;
 				case HID_GD_JOYSTICK: usage->code += 0x10;
-				case HID_GD_MOUSE:    usage->code += 0x10;
+				case HID_GD_MOUSE:    usage->code += 0x10; break;
+				default:
+					if (field->physical == HID_GD_POINTER)
+						usage->code += 0x10;
+					break;
 			}
 			break;
 
@@ -769,7 +773,49 @@
 			usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; 
 			break;
 
+		case HID_UP_DIGITIZER:
+
+			switch (usage->hid & 0xff) {
+
+				case 0x30: /* TipPressure */
+
+					usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; 
+					usage->code = ABS_PRESSURE;
+					clear_bit(usage->code, bit);
+					break;
+
+				case 0x32: /* InRange */
+
+					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+					switch (field->physical & 0xff) {	
+						case 0x21: usage->code = BTN_TOOL_MOUSE; break;
+						case 0x22: usage->code = BTN_TOOL_FINGER; break;
+						default: usage->code = BTN_TOOL_PEN; break;
+					}
+					break;
+
+				case 0x33: /* Touch */
+				case 0x42: /* TipSwitch */
+				case 0x43: /* TipSwitch2 */
+
+					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+					usage->code = BTN_TOUCH;
+					clear_bit(usage->code, bit);
+					break;
+
+				case 0x44: /* BarrelSwitch */
+
+					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+					usage->code = BTN_STYLUS;
+					clear_bit(usage->code, bit);
+					break;
+
+				default:  goto unknown;
+			}
+			break;
+
 		default:
+		unknown:
 
 			if (field->flags & HID_MAIN_ITEM_RELATIVE) {
 				usage->code = REL_MISC;
@@ -777,7 +823,7 @@
 				break;
 			}
 
-			if (field->logical_minimum == 0 && field->logical_maximum == 1) {
+			if (field->report_size == 1) {
 				usage->code = BTN_MISC;
 				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
 				break;
@@ -959,7 +1005,7 @@
 static void hid_read_report(struct hid_device *hid, struct hid_report *report)
 {
 #if 0
-	int rlen = ((report->size - 1) >> 3) + 1 +  hid->report_enum[HID_INPUT_REPORT].numbered;
+	int rlen = ((report->size - 1) >> 3) + 1;
 	char rdata[rlen];
 	struct urb urb;
 	int read, j;
@@ -973,7 +1019,7 @@
 
 	dbg("getting report type %d id %d len %d", report->type + 1, report->id, rlen);
 
-	if ((read = usb_get_report(hid->dev, report->type + 1, report->id, hid->ifnum, rdata, rlen)) != rlen) {
+	if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, rdata, rlen)) != rlen) {
 		dbg("reading report failed rlen %d read %d", rlen, read);
 #ifdef DEBUG
 		printk(KERN_DEBUG __FILE__ ": report = ");
@@ -1013,13 +1059,6 @@
 void hid_output_report(struct hid_report *report, __u8 *data)
 {
 	unsigned n;
-
-#if 0
-	/* skip the ID if we have a single report */
-	if (report->device->report_enum[report->type].numbered)
-		*data++ = report->id;
-#endif
-
 	for (n = 0; n < report->maxfield; n++)
 		hid_output_field(report->field[n], data);
 };
@@ -1142,7 +1181,7 @@
 					hid_configure_usage(hid, report->field[i], report->field[i]->usage + j);
 
 			if (k == HID_INPUT_REPORT)  {
-				usb_set_idle(hid->dev, 0, report->id);
+				usb_set_idle(hid->dev, hid->ifnum, report->id, 0);
 				hid_read_report(hid, report);
 			}
 		}
@@ -1151,7 +1190,7 @@
 
 static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
 {
-	struct usb_interface_descriptor *interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
 	struct hid_descriptor *hdesc;
 	struct hid_device *hid;
 	unsigned rsize = 0;
@@ -1178,7 +1217,7 @@
 	{
 		__u8 rdesc[rsize];
 
-		if ((n = usb_get_class_descriptor(dev, USB_DT_REPORT, 0, ifnum, rdesc, rsize)) < 0) {
+		if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) {
 			dbg("reading report descriptor failed");
 			return NULL;
 		}
@@ -1226,19 +1265,22 @@
 		return NULL;
 	}
 
+	hid->version = hdesc->bcdHID;
+	hid->country = hdesc->bCountryCode;
+	hid->dev = dev;
+	hid->ifnum = interface->bInterfaceNumber;
+
 	hid->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
 	hid->dr.request = USB_REQ_SET_REPORT;
 	hid->dr.value = 0x200;
-	hid->dr.index = interface->bInterfaceNumber;
+	hid->dr.index = hid->ifnum;
 	hid->dr.length = 1;
 
 	FILL_CONTROL_URB(&hid->urbout, dev, usb_sndctrlpipe(dev, 0),
 		(void*) &hid->dr, hid->bufout, 1, hid_ctrl, hid);
 
-	hid->version = hdesc->bcdHID;
-	hid->country = hdesc->bCountryCode;
-	hid->dev = dev;
-	hid->ifnum = ifnum;
+	if (interface->bInterfaceSubClass == 1)
+        	usb_set_protocol(dev, hid->ifnum, 1);
 
 	return hid;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)