All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Input: synaptics - add support for reporting x/y resolution
@ 2009-05-04 18:06 Tero Saarni
  2009-05-04 18:19 ` Tero Saarni
  0 siblings, 1 reply; 8+ messages in thread
From: Tero Saarni @ 2009-05-04 18:06 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input

Synaptics uses anisotropic coordinate system.  On wide touchpads
vertical coordinate resolution can be twice as high as horizontal
leading to unequal sensitivity.  Make x and y coordinate resolution
available so that differences can be compensated.

Signed-off-by: Tero Saarni <tero.saarni@gmail.com>

---
 drivers/input/mouse/synaptics.c |   27 +++++++++++++++++++++++++++
 drivers/input/mouse/synaptics.h |    2 ++
 include/linux/input.h           |    2 ++
 3 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/drivers/input/mouse/synaptics.c
b/drivers/input/mouse/synaptics.c
index f3e4f7b..9363953 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -180,6 +180,29 @@ static int synaptics_identify(struct psmouse
*psmouse)
 	return -1;
 }
 
+/*
+ * Read touchpad resolution
+ * Resolution is left zero if touchpad does not support the query
+ */
+static int synaptics_resolution(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv = psmouse->private;
+	unsigned char res[3];
+
+	if (SYN_ID_MAJOR(priv->identity) < 4)
+		return 0;
+
+	if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res))
+		return 0;
+
+	if (res[1] == 0x80) {
+		priv->x_res = res[0];
+		priv->y_res = res[2];
+	}
+
+	return 0;
+}
+
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
 	if (synaptics_identify(psmouse))
@@ -188,6 +211,8 @@ static int synaptics_query_hardware(struct psmouse
*psmouse)
 		return -1;
 	if (synaptics_capability(psmouse))
 		return -1;
+	if (synaptics_resolution(psmouse))
+		return -1;
 
 	return 0;
 }
@@ -534,6 +559,8 @@ static void set_input_params(struct input_dev *dev,
struct synaptics_data *priv)
 	set_bit(EV_ABS, dev->evbit);
 	input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
 	input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+	input_set_abs_params(dev, ABS_RESX, 0, priv->x_res, 0, 0);
+	input_set_abs_params(dev, ABS_RESY, 0, priv->y_res, 0, 0);
 	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 	set_bit(ABS_TOOL_WIDTH, dev->absbit);
 
diff --git a/drivers/input/mouse/synaptics.h
b/drivers/input/mouse/synaptics.h
index 02aa4cf..e9a69c9 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -101,6 +101,8 @@ struct synaptics_data {
 	unsigned char pkt_type;			/* packet type - old, new, etc */
 	unsigned char mode;			/* current mode byte */
 	int scroll;
+	int x_res;                              /* x resolution in units/mm */
+	int y_res;                              /* y resolution in units/mm */
 };
 
 int synaptics_detect(struct psmouse *psmouse, int set_properties);
diff --git a/include/linux/input.h b/include/linux/input.h
index 0e6ff5d..53db780 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -645,6 +645,8 @@ struct input_absinfo {
 #define ABS_TILT_Y		0x1b
 #define ABS_TOOL_WIDTH		0x1c
 #define ABS_VOLUME		0x20
+#define ABS_RESX                0x26
+#define ABS_RESY                0x27
 #define ABS_MISC		0x28
 
 #define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
-- 
1.6.0.4



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

* [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-04 18:06 [PATCH] Input: synaptics - add support for reporting x/y resolution Tero Saarni
@ 2009-05-04 18:19 ` Tero Saarni
  2009-05-05  7:20   ` Tero Saarni
  2009-05-07 16:49   ` Dmitry Torokhov
  0 siblings, 2 replies; 8+ messages in thread
From: Tero Saarni @ 2009-05-04 18:19 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input

Synaptics uses anisotropic coordinate system.  On wide touchpads
vertical coordinate resolution can be twice as high as horizontal
leading to unequal sensitivity.  Make x and y coordinate resolution
available so that differences can be compensated.

Signed-off-by: Tero Saarni <tero.saarni@gmail.com>

---

I'm reposting this to fix the line wrapping problems, sorry!

 drivers/input/mouse/synaptics.c |   27 +++++++++++++++++++++++++++
 drivers/input/mouse/synaptics.h |    2 ++
 include/linux/input.h           |    2 ++
 3 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f3e4f7b..9363953 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -180,6 +180,29 @@ static int synaptics_identify(struct psmouse *psmouse)
 	return -1;
 }
 
+/*
+ * Read touchpad resolution
+ * Resolution is left zero if touchpad does not support the query
+ */
+static int synaptics_resolution(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv = psmouse->private;
+	unsigned char res[3];
+
+	if (SYN_ID_MAJOR(priv->identity) < 4)
+		return 0;
+
+	if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res))
+		return 0;
+
+	if (res[1] == 0x80) {
+		priv->x_res = res[0];
+		priv->y_res = res[2];
+	}
+
+	return 0;
+}
+
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
 	if (synaptics_identify(psmouse))
@@ -188,6 +211,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
 		return -1;
 	if (synaptics_capability(psmouse))
 		return -1;
+	if (synaptics_resolution(psmouse))
+		return -1;
 
 	return 0;
 }
@@ -534,6 +559,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 	set_bit(EV_ABS, dev->evbit);
 	input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
 	input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+	input_set_abs_params(dev, ABS_RESX, 0, priv->x_res, 0, 0);
+	input_set_abs_params(dev, ABS_RESY, 0, priv->y_res, 0, 0);
 	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 	set_bit(ABS_TOOL_WIDTH, dev->absbit);
 
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 02aa4cf..e9a69c9 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -101,6 +101,8 @@ struct synaptics_data {
 	unsigned char pkt_type;			/* packet type - old, new, etc */
 	unsigned char mode;			/* current mode byte */
 	int scroll;
+	int x_res;                              /* x resolution in units/mm */
+	int y_res;                              /* y resolution in units/mm */
 };
 
 int synaptics_detect(struct psmouse *psmouse, int set_properties);
diff --git a/include/linux/input.h b/include/linux/input.h
index 0e6ff5d..53db780 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -645,6 +645,8 @@ struct input_absinfo {
 #define ABS_TILT_Y		0x1b
 #define ABS_TOOL_WIDTH		0x1c
 #define ABS_VOLUME		0x20
+#define ABS_RESX                0x26
+#define ABS_RESY                0x27
 #define ABS_MISC		0x28
 
 #define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
-- 
1.6.0.4




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

* [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-04 18:19 ` Tero Saarni
@ 2009-05-05  7:20   ` Tero Saarni
  2009-05-07 16:49   ` Dmitry Torokhov
  1 sibling, 0 replies; 8+ messages in thread
From: Tero Saarni @ 2009-05-05  7:20 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input

Synaptics uses anisotropic coordinate system.  On some wide touchpads
vertical resolution can be twice as high as horizontal leading to
unequal sensitivity.  To allow compensation add support for reading
the resolution.

Signed-off-by: Tero Saarni <tero.saarni@gmail.com>
---

This is revision 2 of the patch.

Added more validity checks for resolution query, according to 
chapter 3.5.1 in Synaptics TouchPad Interfacing Guide [1].

[1] http://www.synaptics.com/sites/default/files/ACF126.pdf


 drivers/input/mouse/synaptics.c |   27 +++++++++++++++++++++++++++
 drivers/input/mouse/synaptics.h |    2 ++
 include/linux/input.h           |    2 ++
 3 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f3e4f7b..1afbb49 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -180,6 +180,29 @@ static int synaptics_identify(struct psmouse *psmouse)
 	return -1;
 }
 
+/*
+ * Read touchpad resolution
+ * Resolution is left zero if touchpad does not support the query
+ */
+static int synaptics_resolution(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv = psmouse->private;
+	unsigned char res[3];
+
+	if (SYN_ID_MAJOR(priv->identity) < 4)
+		return 0;
+
+	if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res))
+		return 0;
+
+	if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) {
+		priv->x_res = res[0];
+		priv->y_res = res[2];
+	}
+
+	return 0;
+}
+
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
 	if (synaptics_identify(psmouse))
@@ -188,6 +211,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
 		return -1;
 	if (synaptics_capability(psmouse))
 		return -1;
+	if (synaptics_resolution(psmouse))
+		return -1;
 
 	return 0;
 }
@@ -534,6 +559,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 	set_bit(EV_ABS, dev->evbit);
 	input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
 	input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+	input_set_abs_params(dev, ABS_RESX, 0, priv->x_res, 0, 0);
+	input_set_abs_params(dev, ABS_RESY, 0, priv->y_res, 0, 0);
 	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 	set_bit(ABS_TOOL_WIDTH, dev->absbit);
 
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 02aa4cf..e9a69c9 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -101,6 +101,8 @@ struct synaptics_data {
 	unsigned char pkt_type;			/* packet type - old, new, etc */
 	unsigned char mode;			/* current mode byte */
 	int scroll;
+	int x_res;                              /* x resolution in units/mm */
+	int y_res;                              /* y resolution in units/mm */
 };
 
 int synaptics_detect(struct psmouse *psmouse, int set_properties);
diff --git a/include/linux/input.h b/include/linux/input.h
index 0e6ff5d..029cece 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -645,6 +645,8 @@ struct input_absinfo {
 #define ABS_TILT_Y		0x1b
 #define ABS_TOOL_WIDTH		0x1c
 #define ABS_VOLUME		0x20
+#define ABS_RESX		0x26
+#define ABS_RESY		0x27
 #define ABS_MISC		0x28
 
 #define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
-- 
1.6.0.4




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

* Re: [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-04 18:19 ` Tero Saarni
  2009-05-05  7:20   ` Tero Saarni
@ 2009-05-07 16:49   ` Dmitry Torokhov
  2009-05-07 18:59     ` Tero Saarni
  1 sibling, 1 reply; 8+ messages in thread
From: Dmitry Torokhov @ 2009-05-07 16:49 UTC (permalink / raw)
  To: Tero Saarni; +Cc: linux-input

Hi Tero,

On Mon, May 04, 2009 at 09:19:05PM +0300, Tero Saarni wrote:
> Synaptics uses anisotropic coordinate system.  On wide touchpads
> vertical coordinate resolution can be twice as high as horizontal
> leading to unequal sensitivity.  Make x and y coordinate resolution
> available so that differences can be compensated.
> 

Thank you for the patch.

> +#define ABS_RESX                0x26
> +#define ABS_RESY                0x27

This data is not part of dynamic state of the device but rather
describes it's physical characteristics and as such should not be
transmitted as input events. We should consider extending input_absinfo
and making this data available via EVIOCGABS ioctl but we need to be
careful with keeping compatibility with existing clients.

-- 
Dmitry

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

* Re: [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-07 16:49   ` Dmitry Torokhov
@ 2009-05-07 18:59     ` Tero Saarni
  2009-05-08  3:03       ` Dmitry Torokhov
  0 siblings, 1 reply; 8+ messages in thread
From: Tero Saarni @ 2009-05-07 18:59 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

On Thu, May 7, 2009 at 19:49, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
>> +#define ABS_RESX                0x26
>> +#define ABS_RESY                0x27
>
> This data is not part of dynamic state of the device but rather
> describes it's physical characteristics and as such should not be
> transmitted as input events. We should consider extending input_absinfo
> and making this data available via EVIOCGABS ioctl but we need to be
> careful with keeping compatibility with existing clients.

Thanks for your reply!

What kind of extension do you mean?

Making it available via EVIOCGABS ioctl was my intention too but
extending by adding new ABS_nnn was the only obvious way I came up
with.  All the other similar uses of input_absinfo seem to describe
static limits of dynamic parameters (like max and min y coordinates)
so I agree that resolution is not a perfect fit into the group,  For
resolution I never need to call input_report_abs().

I'm very new to the area so please bear with me! :-)

-- 
Tero
--
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

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

* Re: [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-07 18:59     ` Tero Saarni
@ 2009-05-08  3:03       ` Dmitry Torokhov
  2009-05-16  8:08         ` Tero Saarni
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Torokhov @ 2009-05-08  3:03 UTC (permalink / raw)
  To: Tero Saarni; +Cc: linux-input

On Thu, May 07, 2009 at 09:59:36PM +0300, Tero Saarni wrote:
> On Thu, May 7, 2009 at 19:49, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> >> +#define ABS_RESX                0x26
> >> +#define ABS_RESY                0x27
> >
> > This data is not part of dynamic state of the device but rather
> > describes it's physical characteristics and as such should not be
> > transmitted as input events. We should consider extending input_absinfo
> > and making this data available via EVIOCGABS ioctl but we need to be
> > careful with keeping compatibility with existing clients.
> 
> Thanks for your reply!
> 
> What kind of extension do you mean?
> 
> Making it available via EVIOCGABS ioctl was my intention too but
> extending by adding new ABS_nnn was the only obvious way I came up
> with.  All the other similar uses of input_absinfo seem to describe
> static limits of dynamic parameters (like max and min y coordinates)
> so I agree that resolution is not a perfect fit into the group,  For
> resolution I never need to call input_report_abs().
> 

Well, we could add '__u32 resolution;' field to struct input_absinfo but
we need to be really careful not to break applications using old
(smaller) structures with newer kernels.

-- 
Dmitry
--
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

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

* [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-08  3:03       ` Dmitry Torokhov
@ 2009-05-16  8:08         ` Tero Saarni
  2009-06-02 15:35           ` Tero Saarni
  0 siblings, 1 reply; 8+ messages in thread
From: Tero Saarni @ 2009-05-16  8:08 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

Synaptics uses anisotropic coordinate system.  On some wide touchpads
vertical resolution can be twice as high as horizontal which causes
unequal sensitivity on x/y directions.  Add support for reading the
resolution with EVIOCGABS ioctl.

Signed-off-by: Tero Saarni <tero.saarni@gmail.com>
---

Here's a new version of the patch I posted last week.  I've revised
it according to comments from Dmitry.  Please comment if I got the
idea completely wrong or if there's something I could fine tune.

I had some doubts regarding my change in set_input_params() where the
parameters generally seemed to be set to input_dev by calling
input_set_abs_params() helper function.  I did not add new resolution
parameter to this function since its use was so wide spread.  I just
assign the resolution parameters directly which seemed more practical
for me.

 drivers/input/evdev.c           |    8 ++++++--
 drivers/input/mouse/synaptics.c |   28 ++++++++++++++++++++++++++++
 drivers/input/mouse/synaptics.h |    2 ++
 include/linux/input.h           |    2 ++
 4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 7a7a026..f2df97f 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -626,8 +626,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 				abs.maximum = dev->absmax[t];
 				abs.fuzz = dev->absfuzz[t];
 				abs.flat = dev->absflat[t];
+				abs.resolution = dev->absres[t];
 
-				if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
+				if (copy_to_user(p, &abs,
+						min(_IOC_SIZE(cmd), sizeof(struct input_absinfo))))
 					return -EFAULT;
 
 				return 0;
@@ -655,7 +657,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 				t = _IOC_NR(cmd) & ABS_MAX;
 
 				if (copy_from_user(&abs, p,
-						sizeof(struct input_absinfo)))
+						min(_IOC_SIZE(cmd), sizeof(struct input_absinfo))))
 					return -EFAULT;
 
 				/*
@@ -670,6 +672,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 				dev->absmax[t] = abs.maximum;
 				dev->absfuzz[t] = abs.fuzz;
 				dev->absflat[t] = abs.flat;
+				dev->absres[t] = (_IOC_SIZE(cmd) < sizeof(struct input_absinfo)) ?
+					0 : abs.resolution;
 
 				spin_unlock_irq(&dev->event_lock);
 
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f3e4f7b..19984bf 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -180,6 +180,29 @@ static int synaptics_identify(struct psmouse *psmouse)
 	return -1;
 }
 
+/*
+ * Read touchpad resolution
+ * Resolution is left zero if touchpad does not support the query
+ */
+static int synaptics_resolution(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv = psmouse->private;
+	unsigned char res[3];
+
+	if (SYN_ID_MAJOR(priv->identity) < 4)
+		return 0;
+
+	if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res))
+		return 0;
+
+	if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) {
+		priv->x_res = res[0]; /* x resolution in units/mm */
+		priv->y_res = res[2]; /* y resolution in units/mm */
+	}
+
+	return 0;
+}
+
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
 	if (synaptics_identify(psmouse))
@@ -188,6 +211,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
 		return -1;
 	if (synaptics_capability(psmouse))
 		return -1;
+	if (synaptics_resolution(psmouse))
+		return -1;
 
 	return 0;
 }
@@ -563,6 +588,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 	clear_bit(EV_REL, dev->evbit);
 	clear_bit(REL_X, dev->relbit);
 	clear_bit(REL_Y, dev->relbit);
+
+	dev->absres[ABS_X] = priv->x_res;
+	dev->absres[ABS_Y] = priv->y_res;
 }
 
 static void synaptics_disconnect(struct psmouse *psmouse)
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 02aa4cf..3023821 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -97,6 +97,8 @@ struct synaptics_data {
 	unsigned long int capabilities;		/* Capabilities */
 	unsigned long int ext_cap;		/* Extended Capabilities */
 	unsigned long int identity;		/* Identification */
+	int x_res;				/* X resolution in units/mm */
+	int y_res;				/* Y resolution in units/mm */
 
 	unsigned char pkt_type;			/* packet type - old, new, etc */
 	unsigned char mode;			/* current mode byte */
diff --git a/include/linux/input.h b/include/linux/input.h
index 0e6ff5d..351638d 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -53,6 +53,7 @@ struct input_absinfo {
 	__s32 maximum;
 	__s32 fuzz;
 	__s32 flat;
+	__s32 resolution;
 };
 
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
@@ -1108,6 +1109,7 @@ struct input_dev {
 	int absmin[ABS_MAX + 1];
 	int absfuzz[ABS_MAX + 1];
 	int absflat[ABS_MAX + 1];
+	int absres[ABS_MAX + 1];
 
 	int (*open)(struct input_dev *dev);
 	void (*close)(struct input_dev *dev);
-- 
1.6.0.4




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

* [PATCH] Input: synaptics - add support for reporting x/y resolution
  2009-05-16  8:08         ` Tero Saarni
@ 2009-06-02 15:35           ` Tero Saarni
  0 siblings, 0 replies; 8+ messages in thread
From: Tero Saarni @ 2009-06-02 15:35 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

Synaptics uses anisotropic coordinate system.  On some wide touchpads
vertical resolution can be twice as high as horizontal which causes
unequal sensitivity on x/y directions.  Add support for reading the
resolution with EVIOCGABS ioctl.

Signed-off-by: Tero Saarni <tero.saarni@gmail.com>
---

Hi again, 
I'm reposting this patch in case it got lost or buried somewhere!

-------
Here's a new version of the patch I posted last week.  I've revised
it according to comments from Dmitry.  Please comment if I got the
idea completely wrong or if there's something I could fine tune.

I had some doubts regarding my change in set_input_params() where the
parameters generally seemed to be set to input_dev by calling
input_set_abs_params() helper function.  I did not add new resolution
parameter to this function since its use was so wide spread.  I just
assign the resolution parameters directly which seemed more practical
for me.

 drivers/input/evdev.c           |    8 ++++++--
 drivers/input/mouse/synaptics.c |   28 ++++++++++++++++++++++++++++
 drivers/input/mouse/synaptics.h |    2 ++
 include/linux/input.h           |    2 ++
 4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 7a7a026..f2df97f 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -626,8 +626,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 				abs.maximum = dev->absmax[t];
 				abs.fuzz = dev->absfuzz[t];
 				abs.flat = dev->absflat[t];
+				abs.resolution = dev->absres[t];
 
-				if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
+				if (copy_to_user(p, &abs,
+						min(_IOC_SIZE(cmd), sizeof(struct input_absinfo))))
 					return -EFAULT;
 
 				return 0;
@@ -655,7 +657,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 				t = _IOC_NR(cmd) & ABS_MAX;
 
 				if (copy_from_user(&abs, p,
-						sizeof(struct input_absinfo)))
+						min(_IOC_SIZE(cmd), sizeof(struct input_absinfo))))
 					return -EFAULT;
 
 				/*
@@ -670,6 +672,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 				dev->absmax[t] = abs.maximum;
 				dev->absfuzz[t] = abs.fuzz;
 				dev->absflat[t] = abs.flat;
+				dev->absres[t] = (_IOC_SIZE(cmd) < sizeof(struct input_absinfo)) ?
+					0 : abs.resolution;
 
 				spin_unlock_irq(&dev->event_lock);
 
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f3e4f7b..19984bf 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -180,6 +180,29 @@ static int synaptics_identify(struct psmouse *psmouse)
 	return -1;
 }
 
+/*
+ * Read touchpad resolution
+ * Resolution is left zero if touchpad does not support the query
+ */
+static int synaptics_resolution(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv = psmouse->private;
+	unsigned char res[3];
+
+	if (SYN_ID_MAJOR(priv->identity) < 4)
+		return 0;
+
+	if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res))
+		return 0;
+
+	if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) {
+		priv->x_res = res[0]; /* x resolution in units/mm */
+		priv->y_res = res[2]; /* y resolution in units/mm */
+	}
+
+	return 0;
+}
+
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
 	if (synaptics_identify(psmouse))
@@ -188,6 +211,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
 		return -1;
 	if (synaptics_capability(psmouse))
 		return -1;
+	if (synaptics_resolution(psmouse))
+		return -1;
 
 	return 0;
 }
@@ -563,6 +588,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 	clear_bit(EV_REL, dev->evbit);
 	clear_bit(REL_X, dev->relbit);
 	clear_bit(REL_Y, dev->relbit);
+
+	dev->absres[ABS_X] = priv->x_res;
+	dev->absres[ABS_Y] = priv->y_res;
 }
 
 static void synaptics_disconnect(struct psmouse *psmouse)
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 02aa4cf..3023821 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -97,6 +97,8 @@ struct synaptics_data {
 	unsigned long int capabilities;		/* Capabilities */
 	unsigned long int ext_cap;		/* Extended Capabilities */
 	unsigned long int identity;		/* Identification */
+	int x_res;				/* X resolution in units/mm */
+	int y_res;				/* Y resolution in units/mm */
 
 	unsigned char pkt_type;			/* packet type - old, new, etc */
 	unsigned char mode;			/* current mode byte */
diff --git a/include/linux/input.h b/include/linux/input.h
index 0e6ff5d..351638d 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -53,6 +53,7 @@ struct input_absinfo {
 	__s32 maximum;
 	__s32 fuzz;
 	__s32 flat;
+	__s32 resolution;
 };
 
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
@@ -1108,6 +1109,7 @@ struct input_dev {
 	int absmin[ABS_MAX + 1];
 	int absfuzz[ABS_MAX + 1];
 	int absflat[ABS_MAX + 1];
+	int absres[ABS_MAX + 1];
 
 	int (*open)(struct input_dev *dev);
 	void (*close)(struct input_dev *dev);
-- 
1.6.0.4




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

end of thread, other threads:[~2009-06-02 15:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-04 18:06 [PATCH] Input: synaptics - add support for reporting x/y resolution Tero Saarni
2009-05-04 18:19 ` Tero Saarni
2009-05-05  7:20   ` Tero Saarni
2009-05-07 16:49   ` Dmitry Torokhov
2009-05-07 18:59     ` Tero Saarni
2009-05-08  3:03       ` Dmitry Torokhov
2009-05-16  8:08         ` Tero Saarni
2009-06-02 15:35           ` Tero Saarni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.