Skip to contentSkip to conversation

Canonical has own Ubuntu driver for ALPS 73 03 28 devices

PATCH Pali Rohár 5 participants 7 messages Jun 18, 2016 – Jun 21, 2016 HID

lore
Share & tools
lore
#0 lore raw

I did not know about it since I found:

http://oem.archive.canonical.com/pool/public/o/oem-alps-touchpad-1521052-dkms/oem-alps-touchpad-1521052-dkms_1oem7_all.deb

If you are interested extracted patch is in attachment.

I do not understand it... Why Canonical is hidden and don't communicate with rest of world? Otherwise touchpads could work out-of-box on non Ubuntu systems too with mainline kernel.

Signature · 2 lines
Pali Rohár
[email protected]
alps.c +229 -2
@@ -159,6 +159,10 @@ static const struct alps_protocol_info a
 	ALPS_PROTO_V8, 0x18, 0x18, 0
 };
 
+static const struct alps_protocol_info alps_flare_protocol_data = {
+	ALPS_PROTO_FLARE, 0x18, 0x18, 0
+};
+
 /*
  * Some v2 models report the stick buttons in separate bits
  */
@@ -509,7 +513,7 @@ static void alps_report_mt_data(struct p
 	struct alps_fields *f = &priv->f;
 	int i, slot[MAX_TOUCHES];
 
-	input_mt_assign_slots(dev, slot, f->mt, n, 0);
+	input_mt_assign_slots(dev, slot, f->mt, n);
 	for (i = 0; i < n; i++)
 		alps_set_slot(dev, slot[i], f->mt[i].x, f->mt[i].y);
 
@@ -716,6 +720,84 @@ static int alps_decode_dolphin(struct al
 	return 0;
 }
 
+static int alps_decode_flare_standard(struct alps_fields *f, unsigned char *p,
+				struct psmouse *psmouse)
+{
+	if (FLARE_IS_1F_PACKET(p)) {
+		f->fingers = 1;
+		f->st.x = FLARE_1F_X(p);
+		f->st.y = FLARE_1F_Y(p);
+		f->pressure = FLARE_1F_Z(p);
+		f->mt[0].x = f->st.x;
+		f->mt[0].y = f->st.y;
+
+		f->middle = !!(FLARE_STD_BTN(p) & 0x04);
+		f->right = !!(FLARE_STD_BTN(p) & 0x02);
+		f->left = !!(FLARE_STD_BTN(p) & 0x01);
+
+		/* Guard */
+		if (f->pressure == 0) {
+			f->fingers = 0;
+		}
+	} else if (FLARE_IS_2F_PACKET(p)) {
+		f->fingers = 2;
+		if (FLARE_MF_Z(p, 0) == 1) {
+			f->pressure = 64;
+		} else if (FLARE_MF_Z(p, 0) == 2) {
+			f->pressure = 127;
+		}
+
+		f->mt[0].x = FLARE_STD_MF_X(p, 0);
+		f->mt[0].y = FLARE_STD_MF_Y(p, 0);
+		f->mt[1].x = FLARE_STD_MF_X(p, 1);
+		f->mt[1].y = FLARE_STD_MF_Y(p, 1);
+
+		f->st.x = f->mt[0].x;
+		f->st.y = f->mt[0].y;
+	}
+
+	return 0;
+}
+
+static int alps_decode_flare_buttonless(struct alps_fields *f, unsigned char *p,
+				struct psmouse *psmouse)
+{
+	if (FLARE_IS_1F_PACKET(p)) {
+		f->fingers = 1;
+		f->st.x = FLARE_1F_X(p);
+		f->st.y = FLARE_1F_Y(p);
+		f->pressure = FLARE_1F_LFB(p) ? 127 : 64;
+		f->mt[0].x = f->st.x;
+		f->mt[0].y = f->st.y;
+
+		/* Guard.
+		 * How the Z value is calculated is arbitrary. :-) */
+		if (FLARE_1F_Z(p) == 0) {
+			f->fingers = 0;
+			f->pressure = 0;
+		} else if (FLARE_1F_Z(p) < 6) {
+			f->pressure = FLARE_1F_Z(p) * 12;
+		}
+	} else if (FLARE_IS_2F_PACKET(p)) {
+		f->fingers = 2;
+		if (FLARE_MF_Z(p, 0) == 1) {
+			f->pressure = 64;
+		} else if (FLARE_MF_Z(p, 0) == 2) {
+			f->pressure = 127;
+		}
+
+		f->mt[0].x = FLARE_BTL_MF_X(p, 0);
+		f->mt[0].y = FLARE_BTL_MF_Y(p, 0);
+		f->mt[1].x = FLARE_BTL_MF_X(p, 1);
+		f->mt[1].y = FLARE_BTL_MF_Y(p, 1);
+
+		f->st.x = f->mt[0].x;
+		f->st.y = f->mt[0].y;
+	}
+
+	return 0;
+}
+
 static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
@@ -793,6 +875,66 @@ static void alps_process_touchpad_packet
 		input_sync(dev2);
 	}
 }
+static void alps_process_touchpad_packet_flare(struct psmouse *psmouse)
+{
+	struct alps_data *priv = psmouse->private;
+	unsigned char *packet = psmouse->packet;
+	struct input_dev *dev = psmouse->dev;
+	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+	int fingers = 0;
+	struct alps_fields *f = &priv->f;
+
+	priv->decode_fields(f, packet, psmouse);
+
+	fingers = f->fingers;
+	x1 = f->mt[0].x;
+	y1 = f->mt[0].y;
+	x2 = f->mt[1].x;
+	y2 = f->mt[1].y;
+
+	/*
+	 * Sometimes the hardware sends a single packet with z = 0
+	 * in the middle of a stream. Real releases generate packets
+	 * with x, y, and z all zero, so these seem to be flukes.
+	 * Ignore them.
+	 */
+	if (f->st.x && f->st.y && !f->pressure)
+		return;
+
+	if (f->pressure > 0)
+		input_report_key(dev, BTN_TOUCH, 1);
+	else
+		input_report_key(dev, BTN_TOUCH, 0);
+
+
+	input_mt_slot(dev, 0);
+	input_mt_report_slot_state(dev, MT_TOOL_FINGER, fingers != 0);
+	if (fingers != 0) {
+		input_report_abs(dev, ABS_MT_POSITION_X, x1);
+		input_report_abs(dev, ABS_MT_POSITION_Y, y1);
+	}
+
+	input_mt_slot(dev, 1);
+	input_mt_report_slot_state(dev, MT_TOOL_FINGER, fingers == 2);
+	if (fingers == 2) {
+		input_report_abs(dev, ABS_MT_POSITION_X, x2);
+		input_report_abs(dev, ABS_MT_POSITION_Y, y2);
+	}
+
+	input_mt_report_finger_count(dev, fingers);
+
+	input_report_key(dev, BTN_LEFT, f->left);
+	input_report_key(dev, BTN_RIGHT, f->right);
+	input_report_key(dev, BTN_MIDDLE, f->middle);
+
+	if (f->pressure > 0) {
+		input_report_abs(dev, ABS_X, f->st.x);
+		input_report_abs(dev, ABS_Y, f->st.y);
+	}
+	input_report_abs(dev, ABS_PRESSURE, f->pressure);
+
+	input_sync(dev);
+}
 
 static void alps_process_packet_v3(struct psmouse *psmouse)
 {
@@ -1545,6 +1687,7 @@ static psmouse_ret_t alps_process_byte(s
 	 * Can not distinguish V8's first byte from PS/2 packet's
 	 */
 	if (priv->proto_version != ALPS_PROTO_V8 &&
+	    priv->proto_version != ALPS_PROTO_FLARE && /* Ss5 use absolute mode */
 	    !psmouse->out_of_sync_cnt &&
 	    (psmouse->packet[0] & 0xc8) == 0x08) {
 
@@ -2518,6 +2661,24 @@ static int alps_hw_init_dolphin_v1(struc
 	return 0;
 }
 
+static int alps_hw_init_flare(struct psmouse *psmouse)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[2];
+
+	/* This is dolphin "v1" as empirically defined by florin9doi */
+	param[0] = 0x64;
+	param[1] = 0x28;
+
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
+	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
+		return -1;
+
+	return 0;
+}
+
 static int alps_hw_init_v7(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
@@ -2576,10 +2737,29 @@ error:
 	return ret;
 }
 
+static void alps_set_abs_params_mt(struct alps_data *priv,
+				   struct input_dev *dev1)
+{
+	set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
+	input_mt_init_slots(dev1, 2, 0);
+	input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
+	input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
+
+	set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
+	set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
+	set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
+
+	input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
+	input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
+}
+
 static int alps_set_protocol(struct psmouse *psmouse,
 			     struct alps_data *priv,
 			     const struct alps_protocol_info *protocol)
 {
+	unsigned char flare_config_page[3];
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+
 	psmouse->private = priv;
 
 	setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
@@ -2654,6 +2834,52 @@ static int alps_set_protocol(struct psmo
 
 		break;
 
+	case ALPS_PROTO_FLARE:
+		priv->hw_init = alps_hw_init_flare;
+		priv->process_packet = alps_process_touchpad_packet_flare;
+		priv->set_abs_params = alps_set_abs_params_mt;
+		priv->nibble_commands = alps_v3_nibble_commands;
+		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
+		priv->x_bits = 12;
+		priv->y_bits = 12;
+
+		/* Read configure page 0 */
+		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
+		    ps2_command(ps2dev, flare_config_page, PSMOUSE_CMD_GETINFO) ||
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+		    ps2_command(ps2dev, flare_config_page, PSMOUSE_CMD_GETINFO)) {
+			return -EIO;
+		}
+
+		priv->x_max = (flare_config_page[2] & 0x0f) + 16 - 1;
+		priv->y_max = ((flare_config_page[2] >> 4) & 0x0f) + 5 - 1;
+
+		/* Read configure page 1 */
+		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
+		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
+		    ps2_command(ps2dev, flare_config_page, PSMOUSE_CMD_GETINFO)) {
+			return -EIO;
+		}
+
+		/* b1 of byte0 of configure page 1: Pad Button Emulation
+		 * 	0: No,  standard mode
+		 * 	1: Yes, buttonless(or force) mode */
+		if ((flare_config_page[0] & 0x02)) {
+			priv->decode_fields = alps_decode_flare_buttonless;
+			priv->x_max <<= 6;
+			priv->y_max <<= 6;
+
+		} else {
+			priv->decode_fields = alps_decode_flare_standard;
+			priv->x_max <<= 7;
+			priv->y_max <<= 7;
+		}
+
+		break;
+
 	case ALPS_PROTO_V6:
 		priv->hw_init = alps_hw_init_v6;
 		priv->process_packet = alps_process_packet_v6;
@@ -2744,7 +2970,6 @@ static int alps_identify(struct psmouse
 			 PSMOUSE_CMD_RESET_WRAP, ec) ||
 	    alps_exit_command_mode(psmouse))
 		return -EIO;
-
 	protocol = alps_match_table(e7, ec);
 	if (!protocol) {
 		if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
@@ -2761,6 +2986,8 @@ static int alps_identify(struct psmouse
 		} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
 			   e7[2] == 0x14 && ec[1] == 0x02) {
 			protocol = &alps_v8_protocol_data;
+		} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x28) {
+			protocol = &alps_flare_protocol_data;
 		} else {
 			psmouse_dbg(psmouse,
 				    "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
alps.h +53 -0

65 lines not on this page · raw message

#1 lore raw
Quoted 3 lines · Pali Roh??r

I do not understand it... Why Canonical is hidden and don't communicate with rest of world? Otherwise touchpads could work out-of-box on non Ubuntu systems too with mainline kernel.

Because Canonical doesn't collaborate with the upstream community in any meaninful way. They've been a bad player since day 1 and will always be.

#2 lore raw
Quoted 8 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 3 lines · Pali Roh??r

I do not understand it... Why Canonical is hidden and don't communicate with rest of world? Otherwise touchpads could work out-of-box on non Ubuntu systems too with mainline kernel.

Because Canonical doesn't collaborate with the upstream community in any meaninful way. They've been a bad player since day 1 and will always be.

It must be really frustrating for Ben and other people (me too) who in last months working on ALPS patches to support that touchpad as we know that Canonical already had some working code for that touchpad...

Signature · 6 lines
Pali Rohár
[email protected]
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw
Quoted 11 lines · Pali Rohár
Quoted 5 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 3 lines · Pali Roh??r

I do not understand it... Why Canonical is hidden and don't communicate with rest of world? Otherwise touchpads could work out-of-box on non Ubuntu systems too with mainline kernel.

It must be really frustrating for Ben and other people (me too) who in last months working on ALPS patches to support that touchpad as we know that Canonical already had some working code for that touchpad...

Hi Pali,

The fix in the DKMS package you referenced was not written by Canonical but by ALPS, as it came from them I think it is reasonable they send it to upstream, isn't it? As you can see the patch is non-trivial.

After we got the patch from ALPS, we had follow-up conversation a few times with our contacts at Taiwan and asked if they would upstream it, but unfortunately to no avail. I am as desperate as you if the fix cannot land in mainline, which means many Linux users will not benefit from it. We also had opened this bug [1] for this particular issue, there is nothing to hide. If there is any code written by us, we happily submit them upstream.

[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1571530

Quoted 4 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 3 lines

Because Canonical doesn't collaborate with the upstream community in any meaninful way. They've been a bad player since day 1 and will always be.

This reminded me of this old thread [2]. How hard is it to run this command in your kernel git tree?

    $ git log --pretty=oneline --author=canonical

[2] https://www.spinics.net/lists/linux-bluetooth/msg47286.html

Thanks,
Anthony
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw
Quoted 19 lines · Anthony Wong
Quoted 11 lines · Pali Rohár
Quoted 5 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 3 lines · Pali Roh??r

I do not understand it... Why Canonical is hidden and don't communicate with rest of world? Otherwise touchpads could work out-of-box on non Ubuntu systems too with mainline kernel.

It must be really frustrating for Ben and other people (me too) who in last months working on ALPS patches to support that touchpad as we know that Canonical already had some working code for that touchpad...

Hi Pali,

The fix in the DKMS package you referenced was not written by Canonical but by ALPS, as it came from them I think it is reasonable they send it to upstream, isn't it? As you can see the patch is non-trivial.

Quoted 7 lines

After we got the patch from ALPS, we had follow-up conversation a few times with our contacts at Taiwan and asked if they would upstream it, but unfortunately to no avail. I am as desperate as you if the fix cannot land in mainline, which means many Linux users will not benefit from it. We also had opened this bug [1] for this particular issue, there is nothing to hide. If there is any code written by us, we happily submit them upstream.

Why couldn't you guys send it upstream yourselves?

Quoted 17 lines

[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1571530

Quoted 4 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 3 lines

Because Canonical doesn't collaborate with the upstream community in any meaninful way. They've been a bad player since day 1 and will always be.

This reminded me of this old thread [2]. How hard is it to run this command in your kernel git tree?

    $ git log --pretty=oneline --author=canonical

[2] https://www.spinics.net/lists/linux-bluetooth/msg47286.html

Thanks,
Anthony

Signature · 5 lines
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#5 lore raw
Quoted 29 lines · On Monday 20 June 2016 19:37:57 Dmitry Torokhov wrote:
Quoted 20 lines · Anthony Wong
Quoted 11 lines · Pali Rohár
Quoted 5 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 4 lines · Pali Roh??r

I do not understand it... Why Canonical is hidden and don't communicate with rest of world? Otherwise touchpads could work out-of-box on non Ubuntu systems too with mainline kernel.

It must be really frustrating for Ben and other people (me too) who in last months working on ALPS patches to support that touchpad as we know that Canonical already had some working code for that touchpad...

Hi Pali,

The fix in the DKMS package you referenced was not written by Canonical but by ALPS, as it came from them I think it is reasonable they send it to upstream, isn't it? As you can see the patch is non-trivial.

Quoted 7 lines

After we got the patch from ALPS, we had follow-up conversation a few times with our contacts at Taiwan and asked if they would upstream it, but unfortunately to no avail. I am as desperate as you if the fix cannot land in mainline, which means many Linux users will not benefit from it. We also had opened this bug [1] for this particular issue, there is nothing to hide. If there is any code written by us, we happily submit them upstream.

Quoted 1 line

Why couldn't you guys send it upstream yourselves?

For ALPS 73 03 28 touchpad it is probably too late now, see:
http://thread.gmane.org/gmane.linux.kernel.input/49651

Quoted 16 lines
Quoted 16 lines

[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1571530

Quoted 4 lines · On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
Quoted 3 lines

Because Canonical doesn't collaborate with the upstream community in any meaninful way. They've been a bad player since day 1 and will always be.

This reminded me of this old thread [2]. How hard is it to run this command in your kernel git tree?

    $ git log --pretty=oneline --author=canonical

[2] https://www.spinics.net/lists/linux-bluetooth/msg47286.html

Thanks,
Anthony

Signature · 2 lines
Pali Rohár
[email protected]
#6 lore raw
In reply to Anthony Wong
Quoted 3 lines

The fix in the DKMS package you referenced was not written by Canonical but by ALPS, as it came from them I think it is reasonable they send it to upstream, isn't it? As you can see the patch is non-trivial.

You published it on to milliosn of users, you'd think also mentioning its existence upstream would have been easy enough.

Quoted 7 lines

After we got the patch from ALPS, we had follow-up conversation a few times with our contacts at Taiwan and asked if they would upstream it, but unfortunately to no avail. I am as desperate as you if the fix cannot land in mainline, which means many Linux users will not benefit from it. We also had opened this bug [1] for this particular issue, there is nothing to hide. If there is any code written by us, we happily submit them upstream.

Other vendors and users regularly upstream driver code that lurks in third party repositories or amidst the grues in the dark smelly corners of the Android underworld. (and contrary to Christoph's comment Canonical are angels compared with a lot of the Android world)

I can see why you wouldn't want to submit it if ALPS were going to, but really - not even mentioning it upstream when there was other work going on was unfortunate. A single Canonical email saying "You might want to look at the ALPS driver at URL" would have saved all the wasted effort.

It's also good common sense behaviour - in this case there is no API difference but vendors who sit on stuff get burned when we merge an alternative piece of code.

Alan