Commit bfc7f7b6 authored by Jiri Kosina's avatar Jiri Kosina
Browse files

Merge branch 'for-6.17/multitouch' into for-linus

- support for Touch Bars on x86 MacBook Pros (Kerem Karabay)
parents b46d740f 2c31ec92
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -771,6 +771,7 @@ config HID_MULTITOUCH
	  Say Y here if you have one of the following devices:
	  - 3M PCT touch screens
	  - ActionStar dual touch panels
	  - Apple Touch Bar on x86 MacBook Pros
	  - Atmel panels
	  - Cando dual touch panels
	  - Chunghwa panels
+57 −5
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_FORCE_MULTI_INPUT	BIT(20)
#define MT_QUIRK_DISABLE_WAKEUP		BIT(21)
#define MT_QUIRK_ORIENTATION_INVERT	BIT(22)
#define MT_QUIRK_APPLE_TOUCHBAR		BIT(23)

#define MT_INPUTMODE_TOUCHSCREEN	0x02
#define MT_INPUTMODE_TOUCHPAD		0x03
@@ -220,6 +221,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
#define MT_CLS_GOOGLE				0x0111
#define MT_CLS_RAZER_BLADE_STEALTH		0x0112
#define MT_CLS_SMART_TECH			0x0113
#define MT_CLS_APPLE_TOUCHBAR			0x0114
#define MT_CLS_SIS				0x0457

#define MT_DEFAULT_MAXCONTACT	10
@@ -405,6 +407,12 @@ static const struct mt_class mt_classes[] = {
			MT_QUIRK_CONTACT_CNT_ACCURATE |
			MT_QUIRK_SEPARATE_APP_REPORT,
	},
	{ .name = MT_CLS_APPLE_TOUCHBAR,
		.quirks = MT_QUIRK_HOVERING |
			MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE |
			MT_QUIRK_APPLE_TOUCHBAR,
		.maxcontacts = 11,
	},
	{ .name = MT_CLS_SIS,
		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
			MT_QUIRK_ALWAYS_VALID |
@@ -625,6 +633,7 @@ static struct mt_application *mt_find_application(struct mt_device *td,
static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
						      struct hid_report *report)
{
	struct mt_class *cls = &td->mtclass;
	struct mt_report_data *rdata;
	struct hid_field *field;
	int r, n;
@@ -649,7 +658,11 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,

		if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) {
			for (n = 0; n < field->report_count; n++) {
				if (field->usage[n].hid == HID_DG_CONTACTID) {
				unsigned int hid = field->usage[n].hid;

				if (hid == HID_DG_CONTACTID ||
				   (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR &&
				   hid == HID_DG_TRANSDUCER_INDEX)) {
					rdata->is_mt_collection = true;
					break;
				}
@@ -821,12 +834,31 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,

			MT_STORE_FIELD(confidence_state);
			return 1;
		case HID_DG_TOUCH:
			/*
			 * Legacy devices use TIPSWITCH and not TOUCH.
			 * One special case here is of the Apple Touch Bars.
			 * In these devices, the tip state is contained in
			 * fields with the HID_DG_TOUCH usage.
			 * Let's just ignore this field for other devices.
			 */
			if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR))
				return -1;
			fallthrough;
		case HID_DG_TIPSWITCH:
			if (field->application != HID_GD_SYSTEM_MULTIAXIS)
				input_set_capability(hi->input,
						     EV_KEY, BTN_TOUCH);
			MT_STORE_FIELD(tip_state);
			return 1;
		case HID_DG_TRANSDUCER_INDEX:
			/*
			 * Contact ID in case of Apple Touch Bars is contained
			 * in fields with HID_DG_TRANSDUCER_INDEX usage.
			 */
			if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR))
				return 0;
			fallthrough;
		case HID_DG_CONTACTID:
			MT_STORE_FIELD(contactid);
			app->touches_by_report++;
@@ -883,10 +915,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
		case HID_DG_CONTACTMAX:
			/* contact max are global to the report */
			return -1;
		case HID_DG_TOUCH:
			/* Legacy devices use TIPSWITCH and not TOUCH.
			 * Let's just ignore this field. */
			return -1;
		}
		/* let hid-input decide for the others */
		return 0;
@@ -1314,6 +1342,13 @@ static int mt_touch_input_configured(struct hid_device *hdev,
	struct input_dev *input = hi->input;
	int ret;

	/*
	 * HID_DG_CONTACTMAX field is not present on Apple Touch Bars,
	 * but the maximum contact count is greater than the default.
	 */
	if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && cls->maxcontacts)
		td->maxcontacts = cls->maxcontacts;

	if (!td->maxcontacts)
		td->maxcontacts = MT_DEFAULT_MAXCONTACT;

@@ -1321,6 +1356,13 @@ static int mt_touch_input_configured(struct hid_device *hdev,
	if (td->serial_maybe)
		mt_post_parse_default_settings(td, app);

	/*
	 * The application for Apple Touch Bars is HID_DG_TOUCHPAD,
	 * but these devices are direct.
	 */
	if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)
		app->mt_flags |= INPUT_MT_DIRECT;

	if (cls->is_indirect)
		app->mt_flags |= INPUT_MT_POINTER;

@@ -1823,6 +1865,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
	if (ret != 0)
		return ret;

	if (mtclass->name == MT_CLS_APPLE_TOUCHBAR &&
	    !hid_find_field(hdev, HID_INPUT_REPORT,
			    HID_DG_TOUCHPAD, HID_DG_TRANSDUCER_INDEX))
		return -ENODEV;

	if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID)
		mt_fix_const_fields(hdev, HID_DG_CONTACTID);

@@ -2320,6 +2367,11 @@ static const struct hid_device_id mt_devices[] = {
		MT_USB_DEVICE(USB_VENDOR_ID_XIROKU,
			USB_DEVICE_ID_XIROKU_CSR2) },

	/* Apple Touch Bar */
	{ .driver_data = MT_CLS_APPLE_TOUCHBAR,
		HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
			USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },

	/* Google MT devices */
	{ .driver_data = MT_CLS_GOOGLE,
		HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,