Canonical has own Ubuntu driver for ALPS 73 03 28 devices
diff mbox

Message ID 201606190143.46444@pali
State New, archived
Headers show

Commit Message

Pali Rohár June 18, 2016, 11:43 p.m. UTC
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.

Comments

Christoph Hellwig June 20, 2016, 10:16 a.m. UTC | #1
On Sun, Jun 19, 2016 at 01:43:46AM +0200, Pali Roh??r wrote:
> 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.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pali Rohár June 20, 2016, 10:20 a.m. UTC | #2
On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> On Sun, Jun 19, 2016 at 01:43:46AM +0200, Pali Roh??r wrote:
> > 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...
Anthony Wong June 20, 2016, 5:29 p.m. UTC | #3
On 20 June 2016 at 18:20, Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> > On Sun, Jun 19, 2016 at 01:43:46AM +0200, Pali Roh??r wrote:
> > > 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

> On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> > 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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Torokhov June 20, 2016, 5:37 p.m. UTC | #4
On Tue, Jun 21, 2016 at 01:29:41AM +0800, Anthony Wong wrote:
> On 20 June 2016 at 18:20, Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> > > On Sun, Jun 19, 2016 at 01:43:46AM +0200, Pali Roh??r wrote:
> > > > 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.

Why couldn't you guys send it upstream yourselves?

> 
> [1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1571530
> 
> > On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> > > 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
Pali Rohár June 20, 2016, 5:47 p.m. UTC | #5
On Monday 20 June 2016 19:37:57 Dmitry Torokhov wrote:
> On Tue, Jun 21, 2016 at 01:29:41AM +0800, Anthony Wong wrote:
> > On 20 June 2016 at 18:20, Pali Rohár <pali.rohar@gmail.com> wrote:
> > > On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> > > > On Sun, Jun 19, 2016 at 01:43:46AM +0200, Pali Roh??r wrote:
> > > > > 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.
> 
> 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

> > [1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1571530
> > 
> > > On Monday 20 June 2016 03:16:36 Christoph Hellwig wrote:
> > > > 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
Alan Cox June 21, 2016, 1:42 p.m. UTC | #6
> 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.

> 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
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

--- alps.c	2016-06-19 01:26:34.755016680 +0200
+++ alps.c	2016-02-03 07:09:04.000000000 +0100
@@ -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	2016-06-19 01:34:46.745006525 +0200
+++ alps.h	2016-02-03 07:09:04.000000000 +0100
@@ -20,6 +20,7 @@ 
 #define ALPS_PROTO_V3_RUSHMORE	0x310
 #define ALPS_PROTO_V4		0x400
 #define ALPS_PROTO_V5		0x500
+#define ALPS_PROTO_FLARE	0x510
 #define ALPS_PROTO_V6		0x600
 #define ALPS_PROTO_V7		0x700	/* t3btl t4s */
 #define ALPS_PROTO_V8		0x800	/* SS4btl SS4s */
@@ -122,6 +123,58 @@  enum V7_PACKET_ID {
 	 V7_PACKET_ID_UNKNOWN,
 };
 
+/* Packet identification Macros for Flare Version2               */
+/* ------------------------------------------------------------- */
+/* FLARE_IS_1F_PACKET	= Recognizes 1-finger packet from others */
+/* FLARE_IS_2F_PACKET	= Recognizes 2-finger packet from others */
+#define	FLARE_IS_1F_PACKET(_b) ((((_b[3] >> 4) & 0x01) == 0) && (((_b[3] >> 5) & 0x01) == 0))
+#define	FLARE_IS_2F_PACKET(_b) ((((_b[3] >> 4) & 0x01) == 0x01) && (((_b[3] >> 5) & 0x01) == 0))
+#define	FLARE_1F_Z(_b) (((_b[5]     ) & 0x0F) |		\
+			((_b[5] >> 1) & 0x70) |		\
+			((_b[4]     ) & 0x80)		\
+			)
+
+
+#define	FLARE_1F_X(_b) ((_b[0] & 0x0007) |	  \
+			((_b[1] << 3) & 0x0078) | \
+			((_b[1] << 2) & 0x0380) | \
+			((_b[2] << 5) & 0x0C00)	  \
+			)
+#define	FLARE_1F_Y(_b) (((_b[2]     ) & 0x000F) |		\
+			((_b[3] >> 2) & 0x0030) |		\
+			((_b[4] << 6) & 0x03C0) |		\
+			((_b[4] << 5) & 0x0C00)			\
+			)
+
+#define	FLARE_1F_LFB(_b) (((_b[2] >> 4) & 0x01) == 0x01)
+#define	FLARE_MF_Z(_b, _i) (((_b[1 + _i * 3]     ) & 0x0001) |	\
+			    ((_b[1 + _i * 3] >> 1) & 0x0002)	\
+			    )
+#define	FLARE_MF_LF(_b, _i) ((_b[1 + _i * 3] & 0x0004) == 0x0004)
+
+/* Packet decoding macros of - Normal HW composition      */
+/* ------------------------------------------------------ */
+/* FLARE_STD_BTN	= 3-bit (; ---- ---- ---- -210 )  */
+/* FLARE_STD_MF_X	= 8-bit	(; ---- BA98 7654 ---- )  */
+/* FLARE_STD_MF_Y	= 8-bit	(; ---- BA98 7654 ---- )  */
+#define	FLARE_STD_BTN(_b) ((_b[0] >> 5 ) & 0x07)
+#define	FLARE_STD_MF_X(_b, _i) (((_b[0 + _i * 3] << 4) & 0x0070) |	\
+				((_b[1 + _i * 3] << 4) & 0x0F80)	\
+				)
+#define	FLARE_STD_MF_Y(_b, _i) (((_b[1 + _i * 3] << 3) & 0x0010) |	\
+				((_b[2 + _i * 3] << 5) & 0x01E0) |	\
+				((_b[2 + _i * 3] << 4) & 0x0E00)	\
+				)
+
+/* Packet decoding macros of  - Buttonless HW composition   */
+/* -------------------------------------------------------- */
+/* FLARE_BTL_MF_X	= 9-bit	(; ---- BA98 7654 3--- )    */
+/* FLARE_BTL_MF_Y	= 9-bit	(; ---- BA98 7654 3--- )    */
+#define	FLARE_BTL_MF_X(_b, _i) (FLARE_STD_MF_X(_b, _i) | ((_b[0 + _i * 3] >> 4) & 0x0008))
+#define	FLARE_BTL_MF_Y(_b, _i) (FLARE_STD_MF_Y(_b, _i) | ((_b[0 + _i * 3] >> 3) & 0x0008))
+
+
+
 /**
  * struct alps_protocol_info - information about protocol used by a device
  * @version: Indicates V1/V2/V3/...