diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 74 | 
1 files changed, 51 insertions, 23 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ecd4d2db9e8..62cac4dc3b6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -64,6 +64,7 @@ struct mt_device {  	struct mt_class *mtclass;	/* our mt device class */  	unsigned last_field_index;	/* last field index of the report */  	unsigned last_slot_field;	/* the last field of a slot */ +	int last_mt_collection;	/* last known mt-related collection */  	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */  	__u8 num_received;	/* how many contacts we received */  	__u8 num_expected;	/* expected last contact index */ @@ -225,8 +226,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,  				cls->sn_move);  			/* touchscreen emulation */  			set_abs(hi->input, ABS_X, field, cls->sn_move); -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_GD_Y:  			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) @@ -237,8 +240,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,  				cls->sn_move);  			/* touchscreen emulation */  			set_abs(hi->input, ABS_Y, field, cls->sn_move); -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		}  		return 0; @@ -246,31 +251,42 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,  	case HID_UP_DIGITIZER:  		switch (usage->hid) {  		case HID_DG_INRANGE: -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_DG_CONFIDENCE: -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_DG_TIPSWITCH:  			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);  			input_set_capability(hi->input, EV_KEY, BTN_TOUCH); -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_DG_CONTACTID: +			if (!td->maxcontacts) +				td->maxcontacts = MT_DEFAULT_MAXCONTACT;  			input_mt_init_slots(hi->input, td->maxcontacts);  			td->last_slot_field = usage->hid;  			td->last_field_index = field->index; +			td->last_mt_collection = usage->collection_index;  			return 1;  		case HID_DG_WIDTH:  			hid_map_usage(hi, usage, bit, max,  					EV_ABS, ABS_MT_TOUCH_MAJOR);  			set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,  				cls->sn_width); -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_DG_HEIGHT:  			hid_map_usage(hi, usage, bit, max, @@ -279,8 +295,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,  				cls->sn_height);  			input_set_abs_params(hi->input,  					ABS_MT_ORIENTATION, 0, 1, 0, 0); -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_DG_TIPPRESSURE:  			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) @@ -292,16 +310,20 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,  			/* touchscreen emulation */  			set_abs(hi->input, ABS_PRESSURE, field,  				cls->sn_pressure); -			td->last_slot_field = usage->hid; -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) { +				td->last_slot_field = usage->hid; +				td->last_field_index = field->index; +			}  			return 1;  		case HID_DG_CONTACTCOUNT: -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) +				td->last_field_index = field->index;  			return 1;  		case HID_DG_CONTACTMAX:  			/* we don't set td->last_slot_field as contactcount and  			 * contact max are global to the report */ -			td->last_field_index = field->index; +			if (td->last_mt_collection == usage->collection_index) +				td->last_field_index = field->index;  			return -1;  		}  		/* let hid-input decide for the others */ @@ -516,6 +538,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)  	}  	td->mtclass = mtclass;  	td->inputmode = -1; +	td->last_mt_collection = -1;  	hid_set_drvdata(hdev, td);  	ret = hid_parse(hdev); @@ -526,9 +549,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)  	if (ret)  		goto fail; -	if (!td->maxcontacts) -		td->maxcontacts = MT_DEFAULT_MAXCONTACT; -  	td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),  				GFP_KERNEL);  	if (!td->slots) { @@ -593,6 +613,11 @@ static const struct hid_device_id mt_devices[] = {  		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,  			USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, +	/* Chunghwa Telecom touch panels */ +	{  .driver_data = MT_CLS_DEFAULT, +		HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, +			USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, +  	/* CVTouch panels */  	{ .driver_data = MT_CLS_DEFAULT,  		HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, @@ -651,6 +676,9 @@ static const struct hid_device_id mt_devices[] = {  	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,  		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,  			USB_DEVICE_ID_CRYSTALTOUCH) }, +	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, +		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, +			USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },  	/* MosArt panels */  	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, @@ -681,10 +709,10 @@ static const struct hid_device_id mt_devices[] = {  		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,  			USB_DEVICE_ID_MTP)},  	{ .driver_data = MT_CLS_CONFIDENCE, -		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, +		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,  			USB_DEVICE_ID_MTP_STM)},  	{ .driver_data = MT_CLS_CONFIDENCE, -		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, +		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,  			USB_DEVICE_ID_MTP_SITRONIX)},  	/* Touch International panels */  |