* [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).