linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] Input: penmount - add PenMount 6000 support
@ 2011-09-09  8:07 John Sung
  2011-09-09  8:07 ` [PATCH 2/3] Input: penmount - add PenMount 3000 support John Sung
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: John Sung @ 2011-09-09  8:07 UTC (permalink / raw)
  To: linux-input, linux-kernel; +Cc: Dmitry Torokhov, John Sung

Add support for PenMount 6000 touch controller.

Signed-off-by: John Sung <penmount.touch@gmail.com>
---
 drivers/input/touchscreen/penmount.c |   64 +++++++++++++++++++++++++++++----
 1 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 3342c6d..240f6a2 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -33,7 +33,7 @@ MODULE_LICENSE("GPL");
  * Definitions & global arrays.
  */
 
-#define	PM_MAX_LENGTH	5
+#define	PM_MAX_LENGTH	6
 
 /*
  * Per-touchscreen data.
@@ -45,8 +45,25 @@ struct pm {
 	int idx;
 	unsigned char data[PM_MAX_LENGTH];
 	char phys[32];
+	unsigned char packetsize;
 };
 
+/*
+ * pm_checkpacket() checks if data packet is valid
+ */
+
+static int pm_checkpacket(unsigned char *packet) {
+	int i = 0;
+	int total = 0;
+	for (i = 0; i < 5; i++)
+		total += packet[i];
+
+	if (packet[5] == (unsigned char)~(total & 0xff))
+		return 1;
+
+	return 0;
+}
+
 static irqreturn_t pm_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags)
 {
@@ -55,14 +72,33 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 
 	pm->data[pm->idx] = data;
 
-	if (pm->data[0] & 0x80) {
-		if (PM_MAX_LENGTH == ++pm->idx) {
-			input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
-			input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
-			input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
-			input_sync(dev);
-			pm->idx = 0;
+	switch (pm->dev->id.product) {
+	case 0x9000:
+		if (pm->data[0] & 0x80) {
+			if (pm->packetsize == ++pm->idx) {
+				input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
+				input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
+				input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+				input_sync(dev);
+				pm->idx = 0;
+			}
+		}
+		break;
+	case 0x6000:
+		if ((pm->data[0] & 0xbf) == 0x30) {
+			if (pm->packetsize == ++pm->idx) {
+				if (pm_checkpacket(pm->data)) {
+					input_report_abs(dev, ABS_X,
+							pm->data[2] * 256 + pm->data[1]);
+					input_report_abs(dev, ABS_Y,
+							pm->data[4] * 256 + pm->data[3]);
+					input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+					input_sync(dev);
+				}
+				pm->idx = 0;
+			}
 		}
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -120,6 +156,18 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
         input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
         input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
 
+	switch (serio->id.id) {
+	default:
+	case 0:
+		pm->packetsize = 5;
+		input_dev->id.product = 0x9000;
+		break;
+	case 1:
+		pm->packetsize = 6;
+		input_dev->id.product = 0x6000;
+		break;
+	}
+
 	serio_set_drvdata(serio, pm);
 
 	err = serio_open(serio, drv);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3] Input: penmount - add PenMount 3000 support
  2011-09-09  8:07 [PATCH 1/3] Input: penmount - add PenMount 6000 support John Sung
@ 2011-09-09  8:07 ` John Sung
  2011-09-09 18:03   ` Dmitry Torokhov
  2011-09-09  8:07 ` [PATCH 3/3] Input: penmount - add PenMount 6250 support John Sung
  2011-09-09 18:00 ` [PATCH 1/3] Input: penmount - add PenMount 6000 support Dmitry Torokhov
  2 siblings, 1 reply; 8+ messages in thread
From: John Sung @ 2011-09-09  8:07 UTC (permalink / raw)
  To: linux-input, linux-kernel; +Cc: Dmitry Torokhov, John Sung

Add dual touch support for PenMount 3000 touch controller.

Signed-off-by: John Sung <penmount.touch@gmail.com>
---
 drivers/input/touchscreen/penmount.c |   61 ++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 240f6a2..e4f953e 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/serio.h>
 #include <linux/init.h>
 
@@ -34,6 +35,17 @@ MODULE_LICENSE("GPL");
  */
 
 #define	PM_MAX_LENGTH	6
+#define	PM_MAX_MTSLOT	16
+#define	PM_3000_MTSLOT	2
+
+/*
+ * Multi-touch slot
+ */
+
+struct mt_slot {
+	unsigned short x, y;
+	unsigned char state; /* is the touch valid? */
+};
 
 /*
  * Per-touchscreen data.
@@ -46,9 +58,33 @@ struct pm {
 	unsigned char data[PM_MAX_LENGTH];
 	char phys[32];
 	unsigned char packetsize;
+	unsigned char maxcontacts;
+	struct mt_slot slots[PM_MAX_MTSLOT];
 };
 
 /*
+ * pm_mtevent() sends mt events and also emulates pointer movement
+ */
+
+static void pm_mtevent(struct pm *pm, struct input_dev *input)
+{
+	int i;
+
+	for (i = 0; i < pm->maxcontacts; ++i) {
+		input_mt_slot(input, i);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER,
+				pm->slots[i].state);
+		if (pm->slots[i].state) {
+			input_event(input, EV_ABS, ABS_MT_POSITION_X, pm->slots[i].x);
+			input_event(input, EV_ABS, ABS_MT_POSITION_Y, pm->slots[i].y);
+		}
+	}
+
+	input_mt_report_pointer_emulation(input, true);
+	input_sync(input);
+}
+
+/*
  * pm_checkpacket() checks if data packet is valid
  */
 
@@ -99,6 +135,20 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 			}
 		}
 		break;
+	case 0x3000:
+		if ((pm->data[0] & 0xce) == 0x40) {
+			if (pm->packetsize == ++pm->idx) {
+				if (pm_checkpacket(pm->data)) {
+					int slotnum = pm->data[0] & 0x0f;
+					pm->slots[slotnum].state = !!(pm->data[0] & 0x30);
+					pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
+					pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
+					pm_mtevent(pm, dev);
+				}
+				pm->idx = 0;
+			}
+		}
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -142,6 +192,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 	pm->serio = serio;
 	pm->dev = input_dev;
 	snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
+	pm->maxcontacts = 1;
 
 	input_dev->name = "PenMount Serial TouchScreen";
 	input_dev->phys = pm->phys;
@@ -166,6 +217,16 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 		pm->packetsize = 6;
 		input_dev->id.product = 0x6000;
 		break;
+	case 2:
+		pm->packetsize = 6;
+		input_dev->id.product = 0x3000;
+		input_set_abs_params(pm->dev, ABS_X, 0, 0x7ff, 0, 0);
+		input_set_abs_params(pm->dev, ABS_Y, 0, 0x7ff, 0, 0);
+		pm->maxcontacts = PM_3000_MTSLOT;
+		input_mt_init_slots(pm->dev, PM_3000_MTSLOT);
+		input_set_abs_params(pm->dev, ABS_MT_POSITION_X, 0, 0x7ff, 0, 0);
+		input_set_abs_params(pm->dev, ABS_MT_POSITION_Y, 0, 0x7ff, 0, 0);
+		break;
 	}
 
 	serio_set_drvdata(serio, pm);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3] Input: penmount - add PenMount 6250 support
  2011-09-09  8:07 [PATCH 1/3] Input: penmount - add PenMount 6000 support John Sung
  2011-09-09  8:07 ` [PATCH 2/3] Input: penmount - add PenMount 3000 support John Sung
@ 2011-09-09  8:07 ` John Sung
  2011-09-09 18:04   ` Dmitry Torokhov
  2011-09-09 18:00 ` [PATCH 1/3] Input: penmount - add PenMount 6000 support Dmitry Torokhov
  2 siblings, 1 reply; 8+ messages in thread
From: John Sung @ 2011-09-09  8:07 UTC (permalink / raw)
  To: linux-input, linux-kernel; +Cc: Dmitry Torokhov, John Sung

Add multi touch support for PenMount 6250 touch controller.

Signed-off-by: John Sung <penmount.touch@gmail.com>
---
 drivers/input/touchscreen/penmount.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index e4f953e..68da847 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -37,6 +37,7 @@ MODULE_LICENSE("GPL");
 #define	PM_MAX_LENGTH	6
 #define	PM_MAX_MTSLOT	16
 #define	PM_3000_MTSLOT	2
+#define	PM_6250_MTSLOT	12
 
 /*
  * Multi-touch slot
@@ -149,6 +150,20 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 			}
 		}
 		break;
+	case 0x6250:
+		if ((pm->data[0] & 0xb0) == 0x30) {
+			if (pm->packetsize == ++pm->idx) {
+				if (pm_checkpacket(pm->data)) {
+					int slotnum = pm->data[0] & 0x0f;
+					pm->slots[slotnum].state = !!(pm->data[0] & 0x40);
+					pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
+					pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
+					pm_mtevent(pm, dev);
+				}
+				pm->idx = 0;
+			}
+		}
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -227,6 +242,14 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 		input_set_abs_params(pm->dev, ABS_MT_POSITION_X, 0, 0x7ff, 0, 0);
 		input_set_abs_params(pm->dev, ABS_MT_POSITION_Y, 0, 0x7ff, 0, 0);
 		break;
+	case 3:
+		pm->packetsize = 6;
+		input_dev->id.product = 0x6250;
+		pm->maxcontacts = PM_6250_MTSLOT;
+		input_mt_init_slots(pm->dev, PM_6250_MTSLOT);
+		input_set_abs_params(pm->dev, ABS_MT_POSITION_X, 0, 0x3ff, 0, 0);
+		input_set_abs_params(pm->dev, ABS_MT_POSITION_Y, 0, 0x3ff, 0, 0);
+		break;
 	}
 
 	serio_set_drvdata(serio, pm);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3] Input: penmount - add PenMount 6000 support
  2011-09-09  8:07 [PATCH 1/3] Input: penmount - add PenMount 6000 support John Sung
  2011-09-09  8:07 ` [PATCH 2/3] Input: penmount - add PenMount 3000 support John Sung
  2011-09-09  8:07 ` [PATCH 3/3] Input: penmount - add PenMount 6250 support John Sung
@ 2011-09-09 18:00 ` Dmitry Torokhov
  2 siblings, 0 replies; 8+ messages in thread
From: Dmitry Torokhov @ 2011-09-09 18:00 UTC (permalink / raw)
  To: John Sung; +Cc: linux-input, linux-kernel

Hi John,

On Fri, Sep 09, 2011 at 04:07:45PM +0800, John Sung wrote:
> Add support for PenMount 6000 touch controller.
> 
> Signed-off-by: John Sung <penmount.touch@gmail.com>
> ---
>  drivers/input/touchscreen/penmount.c |   64 +++++++++++++++++++++++++++++----
>  1 files changed, 56 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
> index 3342c6d..240f6a2 100644
> --- a/drivers/input/touchscreen/penmount.c
> +++ b/drivers/input/touchscreen/penmount.c
> @@ -33,7 +33,7 @@ MODULE_LICENSE("GPL");
>   * Definitions & global arrays.
>   */
>  
> -#define	PM_MAX_LENGTH	5
> +#define	PM_MAX_LENGTH	6
>  
>  /*
>   * Per-touchscreen data.
> @@ -45,8 +45,25 @@ struct pm {
>  	int idx;
>  	unsigned char data[PM_MAX_LENGTH];
>  	char phys[32];
> +	unsigned char packetsize;
>  };
>  
> +/*
> + * pm_checkpacket() checks if data packet is valid
> + */
> +
> +static int pm_checkpacket(unsigned char *packet) {
> +	int i = 0;
> +	int total = 0;
> +	for (i = 0; i < 5; i++)
> +		total += packet[i];

This violates our coding standards: open brace for functions should be
on a new line, there should be an empty line between variable
declarations and the code.

Also, since the function returns, in effect, a boolean value, we should
declare it that way.

I've adjusted the patch as follows.

Thanks.

-- 
Dmitry

Input: penmount - add PenMount 6000 support

From: John Sung <penmount.touch@gmail.com>

Add support for PenMount 6000 touch controller.

Signed-off-by: John Sung <penmount.touch@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/touchscreen/penmount.c |   65 ++++++++++++++++++++++++++++++----
 1 files changed, 57 insertions(+), 8 deletions(-)


diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 3342c6d..e9117ad 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -33,7 +33,7 @@ MODULE_LICENSE("GPL");
  * Definitions & global arrays.
  */
 
-#define	PM_MAX_LENGTH	5
+#define	PM_MAX_LENGTH	6
 
 /*
  * Per-touchscreen data.
@@ -45,8 +45,24 @@ struct pm {
 	int idx;
 	unsigned char data[PM_MAX_LENGTH];
 	char phys[32];
+	unsigned char packetsize;
 };
 
+/*
+ * pm_checkpacket() checks if data packet is valid
+ */
+
+static bool pm_checkpacket(unsigned char *packet)
+{
+	int total = 0;
+	int i;
+
+	for (i = 0; i < 5; i++)
+		total += packet[i];
+
+	return packet[5] == (unsigned char)~(total & 0xff);
+}
+
 static irqreturn_t pm_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags)
 {
@@ -55,14 +71,34 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 
 	pm->data[pm->idx] = data;
 
-	if (pm->data[0] & 0x80) {
-		if (PM_MAX_LENGTH == ++pm->idx) {
-			input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
-			input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
-			input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
-			input_sync(dev);
-			pm->idx = 0;
+	switch (pm->dev->id.product) {
+	case 0x9000:
+		if (pm->data[0] & 0x80) {
+			if (pm->packetsize == ++pm->idx) {
+				input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
+				input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
+				input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+				input_sync(dev);
+				pm->idx = 0;
+			}
+		}
+		break;
+
+	case 0x6000:
+		if ((pm->data[0] & 0xbf) == 0x30) {
+			if (pm->packetsize == ++pm->idx) {
+				if (pm_checkpacket(pm->data)) {
+					input_report_abs(dev, ABS_X,
+							pm->data[2] * 256 + pm->data[1]);
+					input_report_abs(dev, ABS_Y,
+							pm->data[4] * 256 + pm->data[3]);
+					input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+					input_sync(dev);
+				}
+				pm->idx = 0;
+			}
 		}
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -120,6 +156,19 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
         input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
         input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
 
+	switch (serio->id.id) {
+	default:
+	case 0:
+		pm->packetsize = 5;
+		input_dev->id.product = 0x9000;
+		break;
+
+	case 1:
+		pm->packetsize = 6;
+		input_dev->id.product = 0x6000;
+		break;
+	}
+
 	serio_set_drvdata(serio, pm);
 
 	err = serio_open(serio, drv);

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] Input: penmount - add PenMount 3000 support
  2011-09-09  8:07 ` [PATCH 2/3] Input: penmount - add PenMount 3000 support John Sung
@ 2011-09-09 18:03   ` Dmitry Torokhov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Torokhov @ 2011-09-09 18:03 UTC (permalink / raw)
  To: John Sung; +Cc: linux-input, linux-kernel

On Fri, Sep 09, 2011 at 04:07:46PM +0800, John Sung wrote:
> @@ -166,6 +217,16 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
>  		pm->packetsize = 6;
>  		input_dev->id.product = 0x6000;
>  		break;
> +	case 2:
> +		pm->packetsize = 6;
> +		input_dev->id.product = 0x3000;
> +		input_set_abs_params(pm->dev, ABS_X, 0, 0x7ff, 0, 0);
> +		input_set_abs_params(pm->dev, ABS_Y, 0, 0x7ff, 0, 0);
> +		pm->maxcontacts = PM_3000_MTSLOT;
> +		input_mt_init_slots(pm->dev, PM_3000_MTSLOT);
> +		input_set_abs_params(pm->dev, ABS_MT_POSITION_X, 0, 0x7ff, 0, 0);
> +		input_set_abs_params(pm->dev, ABS_MT_POSITION_Y, 0, 0x7ff, 0, 0);
> +		break;
>  	}
>  

I do not like how we set up input device with default values for ranges and then we are
overriding for some protocols. How about we do it like the patch below?

Thanks.

-- 
Dmitry

Input: penmount - add PenMount 3000 support

From: John Sung <penmount.touch@gmail.com>

Add dual touch support for PenMount 3000 touch controller.

Signed-off-by: John Sung <penmount.touch@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/touchscreen/penmount.c |   79 ++++++++++++++++++++++++++++++++--
 1 files changed, 75 insertions(+), 4 deletions(-)


diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index dd882eb..86e0612 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/serio.h>
 #include <linux/init.h>
 
@@ -34,6 +35,17 @@ MODULE_LICENSE("GPL");
  */
 
 #define	PM_MAX_LENGTH	6
+#define	PM_MAX_MTSLOT	16
+#define	PM_3000_MTSLOT	2
+
+/*
+ * Multi-touch slot
+ */
+
+struct mt_slot {
+	unsigned short x, y;
+	bool active; /* is the touch valid? */
+};
 
 /*
  * Per-touchscreen data.
@@ -46,9 +58,33 @@ struct pm {
 	unsigned char data[PM_MAX_LENGTH];
 	char phys[32];
 	unsigned char packetsize;
+	unsigned char maxcontacts;
+	struct mt_slot slots[PM_MAX_MTSLOT];
 };
 
 /*
+ * pm_mtevent() sends mt events and also emulates pointer movement
+ */
+
+static void pm_mtevent(struct pm *pm, struct input_dev *input)
+{
+	int i;
+
+	for (i = 0; i < pm->maxcontacts; ++i) {
+		input_mt_slot(input, i);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER,
+				pm->slots[i].active);
+		if (pm->slots[i].active) {
+			input_event(input, EV_ABS, ABS_MT_POSITION_X, pm->slots[i].x);
+			input_event(input, EV_ABS, ABS_MT_POSITION_Y, pm->slots[i].y);
+		}
+	}
+
+	input_mt_report_pointer_emulation(input, true);
+	input_sync(input);
+}
+
+/*
  * pm_checkpacket() checks if data packet is valid
  */
 
@@ -99,6 +135,21 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 			}
 		}
 		break;
+
+	case 0x3000:
+		if ((pm->data[0] & 0xce) == 0x40) {
+			if (pm->packetsize == ++pm->idx) {
+				if (pm_checkpacket(pm->data)) {
+					int slotnum = pm->data[0] & 0x0f;
+					pm->slots[slotnum].active = pm->data[0] & 0x30;
+					pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
+					pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
+					pm_mtevent(pm, dev);
+				}
+				pm->idx = 0;
+			}
+		}
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -130,6 +181,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct pm *pm;
 	struct input_dev *input_dev;
+	int max_x, max_y;
 	int err;
 
 	pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
@@ -142,6 +194,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 	pm->serio = serio;
 	pm->dev = input_dev;
 	snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
+	pm->maxcontacts = 1;
 
 	input_dev->name = "PenMount Serial TouchScreen";
 	input_dev->phys = pm->phys;
@@ -151,24 +204,42 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-        input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-        input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
-        input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	switch (serio->id.id) {
 	default:
 	case 0:
 		pm->packetsize = 5;
 		input_dev->id.product = 0x9000;
+		max_x = max_y = 0x3ff;
 		break;
 
 	case 1:
 		pm->packetsize = 6;
 		input_dev->id.product = 0x6000;
+		max_x = max_y = 0x3ff;
+		break;
+
+	case 2:
+		pm->packetsize = 6;
+		input_dev->id.product = 0x3000;
+		max_x = max_y = 0x7ff;
+		pm->maxcontacts = PM_3000_MTSLOT;
 		break;
 	}
 
+	input_set_abs_params(pm->dev, ABS_X, 0, max_x, 0, 0);
+	input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0);
+
+	if (pm->maxcontacts > 1) {
+		input_mt_init_slots(pm->dev, pm->maxcontacts);
+		input_set_abs_params(pm->dev,
+				     ABS_MT_POSITION_X, 0, max_x, 0, 0);
+		input_set_abs_params(pm->dev,
+				     ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+	}
+
 	serio_set_drvdata(serio, pm);
 
 	err = serio_open(serio, drv);

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] Input: penmount - add PenMount 6250 support
  2011-09-09  8:07 ` [PATCH 3/3] Input: penmount - add PenMount 6250 support John Sung
@ 2011-09-09 18:04   ` Dmitry Torokhov
  2011-09-09 18:06     ` Dmitry Torokhov
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Torokhov @ 2011-09-09 18:04 UTC (permalink / raw)
  To: John Sung; +Cc: linux-input, linux-kernel

On Fri, Sep 09, 2011 at 04:07:47PM +0800, John Sung wrote:
> Add multi touch support for PenMount 6250 touch controller.
> 

Given the changes to previous patches, this one turns into:


Input: penmount - add PenMount 6250 support

From: John Sung <penmount.touch@gmail.com>

Add multi touch support for PenMount 6250 touch controller.

Signed-off-by: John Sung <penmount.touch@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/touchscreen/penmount.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)


diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 86e0612..df42519 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -37,6 +37,7 @@ MODULE_LICENSE("GPL");
 #define	PM_MAX_LENGTH	6
 #define	PM_MAX_MTSLOT	16
 #define	PM_3000_MTSLOT	2
+#define	PM_6250_MTSLOT	12
 
 /*
  * Multi-touch slot
@@ -150,6 +151,21 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 			}
 		}
 		break;
+
+	case 0x6250:
+		if ((pm->data[0] & 0xb0) == 0x30) {
+			if (pm->packetsize == ++pm->idx) {
+				if (pm_checkpacket(pm->data)) {
+					int slotnum = pm->data[0] & 0x0f;
+					pm->slots[slotnum].active = pm->data[0] & 0x40;
+					pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
+					pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
+					pm_mtevent(pm, dev);
+				}
+				pm->idx = 0;
+			}
+		}
+		break;
 	}
 
 	return IRQ_HANDLED;
@@ -227,6 +243,13 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 		max_x = max_y = 0x7ff;
 		pm->maxcontacts = PM_3000_MTSLOT;
 		break;
+
+	case 3:
+		pm->packetsize = 6;
+		input_dev->id.product = 0x6250;
+		max_x = max_y = 0x3ff;
+		pm->maxcontacts = PM_6250_MTSLOT;
+		break;
 	}
 
 	input_set_abs_params(pm->dev, ABS_X, 0, max_x, 0, 0);

Thanks.

-- 
Dmitry

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] Input: penmount - add PenMount 6250 support
  2011-09-09 18:04   ` Dmitry Torokhov
@ 2011-09-09 18:06     ` Dmitry Torokhov
  2011-09-09 18:07       ` Dmitry Torokhov
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Torokhov @ 2011-09-09 18:06 UTC (permalink / raw)
  To: John Sung; +Cc: linux-input, linux-kernel

On Fri, Sep 09, 2011 at 11:04:19AM -0700, Dmitry Torokhov wrote:
> On Fri, Sep 09, 2011 at 04:07:47PM +0800, John Sung wrote:
> > Add multi touch support for PenMount 6250 touch controller.
> > 
> 
> Given the changes to previous patches, this one turns into:
> 

Also, I wonder if we should do something like this:

Input: penmount - rework handling of different protocols

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Instead of having one large switch based on product ID use pointer to
function actually doing protocol decoding.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/touchscreen/penmount.c |  120 ++++++++++++++++++----------------
 1 files changed, 64 insertions(+), 56 deletions(-)


diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index df42519..7ebed38 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -61,6 +61,7 @@ struct pm {
 	unsigned char packetsize;
 	unsigned char maxcontacts;
 	struct mt_slot slots[PM_MAX_MTSLOT];
+	void (*parse_packet)(struct pm *);
 };
 
 /*
@@ -100,73 +101,76 @@ static int pm_checkpacket(unsigned char *packet)
 	return packet[5] == (unsigned char)~(total & 0xff);
 }
 
-static irqreturn_t pm_interrupt(struct serio *serio,
-		unsigned char data, unsigned int flags)
+static void pm_parse_9000(struct pm *pm)
 {
-	struct pm *pm = serio_get_drvdata(serio);
 	struct input_dev *dev = pm->dev;
 
-	pm->data[pm->idx] = data;
+	if ((pm->data[0] & 0x80) && pm->packetsize == ++pm->idx) {
+		input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
+		input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
+		input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+		input_sync(dev);
+		pm->idx = 0;
+	}
+}
 
-	switch (pm->dev->id.product) {
-	case 0x9000:
-		if (pm->data[0] & 0x80) {
-			if (pm->packetsize == ++pm->idx) {
-				input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
-				input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
-				input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
-				input_sync(dev);
-				pm->idx = 0;
-			}
-		}
-		break;
+static void pm_parse_6000(struct pm *pm)
+{
+	struct input_dev *dev = pm->dev;
 
-	case 0x6000:
-		if ((pm->data[0] & 0xbf) == 0x30) {
-			if (pm->packetsize == ++pm->idx) {
-				if (pm_checkpacket(pm->data)) {
-					input_report_abs(dev, ABS_X,
-							pm->data[2] * 256 + pm->data[1]);
-					input_report_abs(dev, ABS_Y,
-							pm->data[4] * 256 + pm->data[3]);
-					input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
-					input_sync(dev);
-				}
-				pm->idx = 0;
-			}
+	if ((pm->data[0] & 0xbf) == 0x30 && pm->packetsize == ++pm->idx) {
+		if (pm_checkpacket(pm->data)) {
+			input_report_abs(dev, ABS_X,
+					pm->data[2] * 256 + pm->data[1]);
+			input_report_abs(dev, ABS_Y,
+					pm->data[4] * 256 + pm->data[3]);
+			input_report_key(dev, BTN_TOUCH, pm->data[0] & 0x40);
+			input_sync(dev);
 		}
-		break;
+		pm->idx = 0;
+	}
+}
+
+static void pm_parse_3000(struct pm *pm)
+{
+	struct input_dev *dev = pm->dev;
 
-	case 0x3000:
-		if ((pm->data[0] & 0xce) == 0x40) {
-			if (pm->packetsize == ++pm->idx) {
-				if (pm_checkpacket(pm->data)) {
-					int slotnum = pm->data[0] & 0x0f;
-					pm->slots[slotnum].active = pm->data[0] & 0x30;
-					pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
-					pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
-					pm_mtevent(pm, dev);
-				}
-				pm->idx = 0;
-			}
+	if ((pm->data[0] & 0xce) == 0x40 && pm->packetsize == ++pm->idx) {
+		if (pm_checkpacket(pm->data)) {
+			int slotnum = pm->data[0] & 0x0f;
+			pm->slots[slotnum].active = pm->data[0] & 0x30;
+			pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
+			pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
+			pm_mtevent(pm, dev);
 		}
-		break;
+		pm->idx = 0;
+	}
+}
+
+static void pm_parse_6250(struct pm *pm)
+{
+	struct input_dev *dev = pm->dev;
 
-	case 0x6250:
-		if ((pm->data[0] & 0xb0) == 0x30) {
-			if (pm->packetsize == ++pm->idx) {
-				if (pm_checkpacket(pm->data)) {
-					int slotnum = pm->data[0] & 0x0f;
-					pm->slots[slotnum].active = pm->data[0] & 0x40;
-					pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
-					pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
-					pm_mtevent(pm, dev);
-				}
-				pm->idx = 0;
-			}
+	if ((pm->data[0] & 0xb0) == 0x30 && pm->packetsize == ++pm->idx) {
+		if (pm_checkpacket(pm->data)) {
+			int slotnum = pm->data[0] & 0x0f;
+			pm->slots[slotnum].active = pm->data[0] & 0x40;
+			pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
+			pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
+			pm_mtevent(pm, dev);
 		}
-		break;
+		pm->idx = 0;
 	}
+}
+
+static irqreturn_t pm_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags)
+{
+	struct pm *pm = serio_get_drvdata(serio);
+
+	pm->data[pm->idx] = data;
+
+	pm->parse_packet(pm);
 
 	return IRQ_HANDLED;
 }
@@ -227,18 +231,21 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 	default:
 	case 0:
 		pm->packetsize = 5;
+		pm->parse_packet = pm_parse_9000;
 		input_dev->id.product = 0x9000;
 		max_x = max_y = 0x3ff;
 		break;
 
 	case 1:
 		pm->packetsize = 6;
+		pm->parse_packet = pm_parse_6000;
 		input_dev->id.product = 0x6000;
 		max_x = max_y = 0x3ff;
 		break;
 
 	case 2:
 		pm->packetsize = 6;
+		pm->parse_packet = pm_parse_3000;
 		input_dev->id.product = 0x3000;
 		max_x = max_y = 0x7ff;
 		pm->maxcontacts = PM_3000_MTSLOT;
@@ -246,6 +253,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
 
 	case 3:
 		pm->packetsize = 6;
+		pm->parse_packet = pm_parse_6250;
 		input_dev->id.product = 0x6250;
 		max_x = max_y = 0x3ff;
 		pm->maxcontacts = PM_6250_MTSLOT;

-- 
Dmitry

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] Input: penmount - add PenMount 6250 support
  2011-09-09 18:06     ` Dmitry Torokhov
@ 2011-09-09 18:07       ` Dmitry Torokhov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Torokhov @ 2011-09-09 18:07 UTC (permalink / raw)
  To: John Sung; +Cc: linux-input, linux-kernel

On Fri, Sep 09, 2011 at 11:06:37AM -0700, Dmitry Torokhov wrote:
> On Fri, Sep 09, 2011 at 11:04:19AM -0700, Dmitry Torokhov wrote:
> > On Fri, Sep 09, 2011 at 04:07:47PM +0800, John Sung wrote:
> > > Add multi touch support for PenMount 6250 touch controller.
> > > 
> > 
> > Given the changes to previous patches, this one turns into:
> > 
> 
> Also, I wonder if we should do something like this:
> 

And if you could give this patch a try that would be great.

Thank you.

-- 
Dmitry


Input: penmount - simplify unregister procedure

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Since touchscreen driver does not handle any events to be sent to the
device we can close serio port first and then unregister the input device.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/touchscreen/penmount.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)


diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 7ebed38..618385e 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -183,12 +183,12 @@ static void pm_disconnect(struct serio *serio)
 {
 	struct pm *pm = serio_get_drvdata(serio);
 
-	input_get_device(pm->dev);
-	input_unregister_device(pm->dev);
 	serio_close(serio);
-	serio_set_drvdata(serio, NULL);
-	input_put_device(pm->dev);
+
+	input_unregister_device(pm->dev);
 	kfree(pm);
+
+	serio_set_drvdata(serio, NULL);
 }
 
 /*

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-09-09 18:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-09  8:07 [PATCH 1/3] Input: penmount - add PenMount 6000 support John Sung
2011-09-09  8:07 ` [PATCH 2/3] Input: penmount - add PenMount 3000 support John Sung
2011-09-09 18:03   ` Dmitry Torokhov
2011-09-09  8:07 ` [PATCH 3/3] Input: penmount - add PenMount 6250 support John Sung
2011-09-09 18:04   ` Dmitry Torokhov
2011-09-09 18:06     ` Dmitry Torokhov
2011-09-09 18:07       ` Dmitry Torokhov
2011-09-09 18:00 ` [PATCH 1/3] Input: penmount - add PenMount 6000 support Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).