diff mbox

[v6] staging: ste_rmi4: Convert to Type-B support

Message ID 20121113201212.8550fb074e1f7cce78f29d97@tw.synaptics.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alexandra Chin Nov. 13, 2012, 12:12 p.m. UTC
Convert to MT-B because Synaptics touch devices are capable
of tracking identifiable fingers.
 
Signed-off-by: Alexandra Chin <alexandra.chin@tw.synaptics.com>
---
This patch was tested on Pandaboard.

Changes from v6:
        - Incorporated Henrik's review comments
          *remove irrelevant changes within the patch

Changes from v5:
        - Incorporated Henrik's review comments
          *rollback to v3 from v4
          *fix odd line break in v3

Changes from v4:
        - Incorporated Henrik's review comments
          *split function synpatics_rmi4_touchscreen_report
          *split function synaptics_rmi4_i2c_query_device

Changes from v3:
	- Incorporated Henrik's review comments
	  *remove 'else' after an error path return
	  *add input_mt_sync_frame() for pointer emulation effects
	  *correct names of touchscreen
	- Replace printk with dev_err

Changes from v2:
	- Incorporated Henrik's review comments
	  *directly report finger state with Type-B
	- Against 3.7-rcX
	  *call input_mt_init_slots with INPUT_MT_DIRECT flag
---
 drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c |   76 +++++++++++--------------
 1 files changed, 33 insertions(+), 43 deletions(-)

Comments

Henrik Rydberg Nov. 13, 2012, 5:53 p.m. UTC | #1
Hi Alexandra,

> Convert to MT-B because Synaptics touch devices are capable
> of tracking identifiable fingers.
>  
> Signed-off-by: Alexandra Chin <alexandra.chin@tw.synaptics.com>
> ---
> This patch was tested on Pandaboard.

Thank you for making changes. One minor comment inline, but I am ok
with the patch as is.  Looks like we have finally arrived. :-)

    Reviewed-by: Henrik Rydberg <rydberg@euromail.se>

Thanks,
Henrik

> ---
>  drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c |   76 +++++++++++--------------
>  1 files changed, 33 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
> index 277491a..ed304e0 100644
> --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
> +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
> @@ -31,6 +31,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/module.h>
> +#include <linux/input/mt.h>
>  #include "synaptics_i2c_rmi4.h"
>  
>  /* TODO: for multiple device support will need a per-device mutex */
> @@ -67,7 +68,6 @@
>  #define PDT_START_SCAN_LOCATION (0x00E9)
>  #define PDT_END_SCAN_LOCATION	(0x000A)
>  #define PDT_ENTRY_SIZE		(0x0006)
> -#define RMI4_NUMBER_OF_MAX_FINGERS		(8)
>  #define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM	(0x11)
>  #define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM	(0x01)
>  
> @@ -164,6 +164,7 @@ struct synaptics_rmi4_device_info {
>   * @regulator: pointer to the regulator structure
>   * @wait: wait queue structure variable
>   * @touch_stopped: flag to stop the thread function
> + * @fingers_supported: maximum supported fingers
>   *
>   * This structure gives the device data information.
>   */
> @@ -184,6 +185,7 @@ struct synaptics_rmi4_data {
>  	struct regulator	*regulator;
>  	wait_queue_head_t	wait;
>  	bool			touch_stopped;
> +	unsigned char		fingers_supported;
>  };
>  
>  /**
> @@ -303,22 +305,21 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
>  	/* number of touch points - fingers down in this case */
>  	int	touch_count = 0;
>  	int	finger;
> -	int	fingers_supported;
>  	int	finger_registers;
>  	int	reg;
>  	int	finger_shift;
>  	int	finger_status;
>  	int	retval;
> +	int	x, y;
> +	int	wx, wy;
>  	unsigned short	data_base_addr;
>  	unsigned short	data_offset;
>  	unsigned char	data_reg_blk_size;
>  	unsigned char	values[2];
>  	unsigned char	data[DATA_LEN];
> -	int	x[RMI4_NUMBER_OF_MAX_FINGERS];
> -	int	y[RMI4_NUMBER_OF_MAX_FINGERS];
> -	int	wx[RMI4_NUMBER_OF_MAX_FINGERS];
> -	int	wy[RMI4_NUMBER_OF_MAX_FINGERS];
> +	unsigned char	fingers_supported = pdata->fingers_supported;
>  	struct	i2c_client *client = pdata->i2c_client;
> +	struct	input_dev *input_dev = pdata->input_dev;
>  
>  	/* get 2D sensor finger data */
>  	/*
> @@ -333,7 +334,6 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
>  	 *	10 = finger present but data may not be accurate,
>  	 *	11 = reserved for product use.
>  	 */
> -	fingers_supported	= rfi->num_of_data_points;
>  	finger_registers	= (fingers_supported + 3)/4;
>  	data_base_addr		= rfi->fn_desc.data_base_addr;
>  	retval = synaptics_rmi4_i2c_block_read(pdata, data_base_addr, values,
> @@ -358,7 +358,11 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
>  		 * if finger status indicates a finger is present then
>  		 * read the finger data and report it
>  		 */
> -		if (finger_status == 1 || finger_status == 2) {
> +		input_mt_slot(input_dev, finger);
> +		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
> +							finger_status != 0);
> +
> +		if (finger_status) {
>  			/* Read the finger data */
>  			data_offset = data_base_addr +
>  					((finger * data_reg_blk_size) +
> @@ -367,50 +371,33 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
>  						data_offset, data,
>  						data_reg_blk_size);
>  			if (retval != data_reg_blk_size) {
> -				printk(KERN_ERR "%s:read data failed\n",
> +				dev_err(&client->dev, "%s:read data failed\n",

Still not needed for this patch. Please try to refrain from making
unnecessary changes in the future.

>  								__func__);
>  				return 0;
> -			} else {
> -				x[touch_count]	=
> -					(data[0] << 4) | (data[2] & MASK_4BIT);
> -				y[touch_count]	=
> -					(data[1] << 4) |
> -					((data[2] >> 4) & MASK_4BIT);
> -				wy[touch_count]	=
> -						(data[3] >> 4) & MASK_4BIT;
> -				wx[touch_count]	=
> -						(data[3] & MASK_4BIT);
> -
> -				if (pdata->board->x_flip)
> -					x[touch_count] =
> -						pdata->sensor_max_x -
> -								x[touch_count];
> -				if (pdata->board->y_flip)
> -					y[touch_count] =
> -						pdata->sensor_max_y -
> -								y[touch_count];
>  			}
> +			x = (data[0] << 4) | (data[2] & MASK_4BIT);
> +			y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
> +			wy = (data[3] >> 4) & MASK_4BIT;
> +			wx = (data[3] & MASK_4BIT);
> +
> +			if (pdata->board->x_flip)
> +				x = pdata->sensor_max_x - x;
> +			if (pdata->board->y_flip)
> +				y = pdata->sensor_max_y - y;
> +
> +			input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
> +								max(wx, wy));
> +			input_report_abs(input_dev, ABS_MT_POSITION_X, x);
> +			input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
> +
>  			/* number of active touch points */
>  			touch_count++;
>  		}
>  	}
>  
> -	/* report to input subsystem */
> -	if (touch_count) {
> -		for (finger = 0; finger < touch_count; finger++) {
> -			input_report_abs(pdata->input_dev, ABS_MT_TOUCH_MAJOR,
> -						max(wx[finger] , wy[finger]));
> -			input_report_abs(pdata->input_dev, ABS_MT_POSITION_X,
> -								x[finger]);
> -			input_report_abs(pdata->input_dev, ABS_MT_POSITION_Y,
> -								y[finger]);
> -			input_mt_sync(pdata->input_dev);
> -		}
> -	} else
> -		input_mt_sync(pdata->input_dev);
> -
>  	/* sync after groups of events */
> -	input_sync(pdata->input_dev);
> +	input_mt_sync_frame(input_dev);
> +	input_sync(input_dev);
>  	/* return the number of touch points */
>  	return touch_count;
>  }
> @@ -575,6 +562,7 @@ static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata,
>  		if ((queries[1] & MASK_3BIT) == 5)
>  			rfi->num_of_data_points = 10;
>  	}
> +	pdata->fingers_supported = rfi->num_of_data_points;
>  	/* Need to get interrupt info for handling interrupts */
>  	rfi->index_to_intr_reg = (interruptcount + 7)/8;
>  	if (rfi->index_to_intr_reg != 0)
> @@ -988,6 +976,8 @@ static int __devinit synaptics_rmi4_probe
>  					rmi4_data->sensor_max_y, 0, 0);
>  	input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0,
>  						MAX_TOUCH_MAJOR, 0, 0);
> +	input_mt_init_slots(rmi4_data->input_dev,
> +				rmi4_data->fingers_supported, 0);
>  
>  	/* Clear interrupts */
>  	synaptics_rmi4_i2c_block_read(rmi4_data,
> -- 
> 1.7.5.4
> 
--
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
Alexandra Chin Nov. 14, 2012, 5:33 p.m. UTC | #2
Hi Henrik,

> > @@ -367,50 +371,33 @@ static int synpatics_rmi4_touchpad_report(struct
> synaptics_rmi4_data *pdata,
> >  						data_offset, data,
> >  						data_reg_blk_size);
> >  			if (retval != data_reg_blk_size) {
> > -				printk(KERN_ERR "%s:read data failed\n",
> > +				dev_err(&client->dev, "%s:read data failed\n",
> 
> Still not needed for this patch. Please try to refrain from making
> unnecessary changes in the future.
> 

Thanks for your acceptance!
And I will remember that do not put irrelevant changes in the same patch.
I will follow the rule to keep updating changes of v4 in future patch.
Thanks you.

Alexandra Chin
--
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
Alexandra Chin Nov. 14, 2012, 5:40 p.m. UTC | #3
Hi Henrik and all,

As I know, currently there is no synaptics RMI4 touchscreen driver in the
main tree. In order to support our customers effectively, is it able to merge
staging ste_rmi4 driver into the main kernel.org tree? If it is accepted, should
I send a patch for this change?

Any advice is greatly appreciated!

Alexandra Chin
--
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 Nov. 14, 2012, 6:04 p.m. UTC | #4
Hi Alexandra,

On Wed, Nov 14, 2012 at 05:40:12PM +0000, Alexandra Chin wrote:
> Hi Henrik and all,
> 
> As I know, currently there is no synaptics RMI4 touchscreen driver in the
> main tree. In order to support our customers effectively, is it able to merge
> staging ste_rmi4 driver into the main kernel.org tree? If it is accepted, should
> I send a patch for this change?

I believe that we should keep ste_rmi4 in staging, not as reflection of
its code quality, but rather because it is a temporary solution until
full-fledged RMI4 driver is merged.

Please have Greg commit the patch that Henrik reviewed to staging and
then work with Christopher Heiny group on getting the full featured
driver into mainline.

Thanks.
Alexandra Chin Nov. 15, 2012, 2:56 a.m. UTC | #5
Hi Dmitry,

> > As I know, currently there is no synaptics RMI4 touchscreen driver in the
> > main tree. In order to support our customers effectively, is it able to merge
> > staging ste_rmi4 driver into the main kernel.org tree? If it is accepted, should
> > I send a patch for this change?
> 
> I believe that we should keep ste_rmi4 in staging, not as reflection of
> its code quality, but rather because it is a temporary solution until
> full-fledged RMI4 driver is merged.
> 
> Please have Greg commit the patch that Henrik reviewed to staging and
> then work with Christopher Heiny group on getting the full featured
> driver into mainline.

Thank you for the prompt reply. The ste_rmi4 driver is actually not intended to be
a temporary solution for the full-fledged driver. We have requests from a number
of our customers and partners (Qualcomm, Samsung, Intel etc.) urging us to have
a driver available in the kernel mainline that is specific to touchscreen with simple
architecture and supporting our S3200 family of Touch Controllers and above. We
are committing resources to continue to maintain this driver and provide updates
to support future touch controller revisions from Synaptics.
It would be greatly appreciated if this driver can be considered for inclusion in the
kernel mainline.

Thank you.

Alexandra Chin
--
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 Nov. 15, 2012, 6:43 a.m. UTC | #6
On Thu, Nov 15, 2012 at 02:56:45AM +0000, Alexandra Chin wrote:
> Hi Dmitry,
> 
> > > As I know, currently there is no synaptics RMI4 touchscreen driver in the
> > > main tree. In order to support our customers effectively, is it able to merge
> > > staging ste_rmi4 driver into the main kernel.org tree? If it is accepted, should
> > > I send a patch for this change?
> > 
> > I believe that we should keep ste_rmi4 in staging, not as reflection of
> > its code quality, but rather because it is a temporary solution until
> > full-fledged RMI4 driver is merged.
> > 
> > Please have Greg commit the patch that Henrik reviewed to staging and
> > then work with Christopher Heiny group on getting the full featured
> > driver into mainline.
> 
> Thank you for the prompt reply. The ste_rmi4 driver is actually not intended to be
> a temporary solution for the full-fledged driver. We have requests from a number
> of our customers and partners (Qualcomm, Samsung, Intel etc.) urging us to have
> a driver available in the kernel mainline that is specific to touchscreen with simple
> architecture and supporting our S3200 family of Touch Controllers and above. We
> are committing resources to continue to maintain this driver and provide updates
> to support future touch controller revisions from Synaptics.
> It would be greatly appreciated if this driver can be considered for inclusion in the
> kernel mainline.

In this case you need to enumerate the benefits of this driver over
unified driver and show why the unified driver can't be fixed.

Currently the driver is in mainline (even though the directory is
staging) and nobody will remove it until another driver is fully
functional and ready for prime time. But once this happens I do not see
the benefits of maintaining 2 drivers for the same hardware.

Thank you.
Linus Walleij Nov. 15, 2012, 5:41 p.m. UTC | #7
On Thu, Nov 15, 2012 at 7:43 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:

> In this case you need to enumerate the benefits of this driver over
> unified driver and show why the unified driver can't be fixed.

The benefit is that the ugliness in
drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c
can be avoided, as today we're unable to pass the compulsory
platform data in any sane way. I'm being told that this weak symbol
override actually does not really work... especially if there are more
than 1 I2C device on the bus :-P

Another way of fixing the staging driver usable is to add device tree
support, of course, that would decopule it completely from the
platform using it.

Yours,
Linus Walleij
--
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 Nov. 15, 2012, 6:55 p.m. UTC | #8
Hi Linus,

On Thu, Nov 15, 2012 at 06:41:26PM +0100, Linus Walleij wrote:
> On Thu, Nov 15, 2012 at 7:43 AM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> 
> > In this case you need to enumerate the benefits of this driver over
> > unified driver and show why the unified driver can't be fixed.
> 
> The benefit is that the ugliness in
> drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c
> can be avoided, as today we're unable to pass the compulsory
> platform data in any sane way. I'm being told that this weak symbol
> override actually does not really work... especially if there are more
> than 1 I2C device on the bus :-P

I am confused as to why this would be a benefit of ste_rmi4 over full
RMI4 implementation from Christopher's group?

I think what we really need is to accelerate work on the full driver so
it is in mainline in 3.9ish.

Thanks.
Linus Walleij Nov. 15, 2012, 7:05 p.m. UTC | #9
On Thu, Nov 15, 2012 at 7:55 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Thu, Nov 15, 2012 at 06:41:26PM +0100, Linus Walleij wrote:
>>
>> The benefit is that the ugliness in
>> drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c
>> can be avoided, as today we're unable to pass the compulsory
>> platform data in any sane way. I'm being told that this weak symbol
>> override actually does not really work... especially if there are more
>> than 1 I2C device on the bus :-P
>
> I am confused as to why this would be a benefit of ste_rmi4 over full
> RMI4 implementation from Christopher's group?

So we don't need to keep our real platform data and board files
out-of-tree like we've done for the last 2 years or so.

But I only said it's a benefit, not that I think it's a good idea.

> I think what we really need is to accelerate work on the full driver so
> it is in mainline in 3.9ish.

Yep, agreed.

Yours,
Linus Walleij
--
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
Alexandra Chin Nov. 16, 2012, 9:02 a.m. UTC | #10
Hi Dmitry,

> > > Please have Greg commit the patch that Henrik reviewed to staging and
> > > then work with Christopher Heiny group on getting the full featured
> > > driver into mainline.

Thanks for your reminding, final patch has been re-sent to staging
maintainer.

> In this case you need to enumerate the benefits of this driver over
> unified driver and show why the unified driver can't be fixed.
> 
> Currently the driver is in mainline (even though the directory is
> staging) and nobody will remove it until another driver is fully
> functional and ready for prime time. But once this happens I do not see
> the benefits of maintaining 2 drivers for the same hardware.

I see. Given that the driver will remain in mainline before generic driver
is ready, currently I will continue to maintain the driver in staging.

Appreciate your response.

Alexandra
--
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 Nov. 16, 2012, 7:24 p.m. UTC | #11
On Friday, November 16, 2012 09:02:30 AM Alexandra Chin wrote:
> Hi Dmitry,
> 
> > > > Please have Greg commit the patch that Henrik reviewed to staging and
> > > > then work with Christopher Heiny group on getting the full featured
> > > > driver into mainline.
> 
> Thanks for your reminding, final patch has been re-sent to staging
> maintainer.
> 
> > In this case you need to enumerate the benefits of this driver over
> > unified driver and show why the unified driver can't be fixed.
> > 
> > Currently the driver is in mainline (even though the directory is
> > staging) and nobody will remove it until another driver is fully
> > functional and ready for prime time. But once this happens I do not see
> > the benefits of maintaining 2 drivers for the same hardware.
> 
> I see. Given that the driver will remain in mainline before generic driver
> is ready, currently I will continue to maintain the driver in staging.

Sounds like a plan.

Thanks!
diff mbox

Patch

diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
index 277491a..ed304e0 100644
--- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
@@ -31,6 +31,7 @@ 
 #include <linux/interrupt.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
+#include <linux/input/mt.h>
 #include "synaptics_i2c_rmi4.h"
 
 /* TODO: for multiple device support will need a per-device mutex */
@@ -67,7 +68,6 @@ 
 #define PDT_START_SCAN_LOCATION (0x00E9)
 #define PDT_END_SCAN_LOCATION	(0x000A)
 #define PDT_ENTRY_SIZE		(0x0006)
-#define RMI4_NUMBER_OF_MAX_FINGERS		(8)
 #define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM	(0x11)
 #define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM	(0x01)
 
@@ -164,6 +164,7 @@  struct synaptics_rmi4_device_info {
  * @regulator: pointer to the regulator structure
  * @wait: wait queue structure variable
  * @touch_stopped: flag to stop the thread function
+ * @fingers_supported: maximum supported fingers
  *
  * This structure gives the device data information.
  */
@@ -184,6 +185,7 @@  struct synaptics_rmi4_data {
 	struct regulator	*regulator;
 	wait_queue_head_t	wait;
 	bool			touch_stopped;
+	unsigned char		fingers_supported;
 };
 
 /**
@@ -303,22 +305,21 @@  static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
 	/* number of touch points - fingers down in this case */
 	int	touch_count = 0;
 	int	finger;
-	int	fingers_supported;
 	int	finger_registers;
 	int	reg;
 	int	finger_shift;
 	int	finger_status;
 	int	retval;
+	int	x, y;
+	int	wx, wy;
 	unsigned short	data_base_addr;
 	unsigned short	data_offset;
 	unsigned char	data_reg_blk_size;
 	unsigned char	values[2];
 	unsigned char	data[DATA_LEN];
-	int	x[RMI4_NUMBER_OF_MAX_FINGERS];
-	int	y[RMI4_NUMBER_OF_MAX_FINGERS];
-	int	wx[RMI4_NUMBER_OF_MAX_FINGERS];
-	int	wy[RMI4_NUMBER_OF_MAX_FINGERS];
+	unsigned char	fingers_supported = pdata->fingers_supported;
 	struct	i2c_client *client = pdata->i2c_client;
+	struct	input_dev *input_dev = pdata->input_dev;
 
 	/* get 2D sensor finger data */
 	/*
@@ -333,7 +334,6 @@  static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
 	 *	10 = finger present but data may not be accurate,
 	 *	11 = reserved for product use.
 	 */
-	fingers_supported	= rfi->num_of_data_points;
 	finger_registers	= (fingers_supported + 3)/4;
 	data_base_addr		= rfi->fn_desc.data_base_addr;
 	retval = synaptics_rmi4_i2c_block_read(pdata, data_base_addr, values,
@@ -358,7 +358,11 @@  static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
 		 * if finger status indicates a finger is present then
 		 * read the finger data and report it
 		 */
-		if (finger_status == 1 || finger_status == 2) {
+		input_mt_slot(input_dev, finger);
+		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+							finger_status != 0);
+
+		if (finger_status) {
 			/* Read the finger data */
 			data_offset = data_base_addr +
 					((finger * data_reg_blk_size) +
@@ -367,50 +371,33 @@  static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
 						data_offset, data,
 						data_reg_blk_size);
 			if (retval != data_reg_blk_size) {
-				printk(KERN_ERR "%s:read data failed\n",
+				dev_err(&client->dev, "%s:read data failed\n",
 								__func__);
 				return 0;
-			} else {
-				x[touch_count]	=
-					(data[0] << 4) | (data[2] & MASK_4BIT);
-				y[touch_count]	=
-					(data[1] << 4) |
-					((data[2] >> 4) & MASK_4BIT);
-				wy[touch_count]	=
-						(data[3] >> 4) & MASK_4BIT;
-				wx[touch_count]	=
-						(data[3] & MASK_4BIT);
-
-				if (pdata->board->x_flip)
-					x[touch_count] =
-						pdata->sensor_max_x -
-								x[touch_count];
-				if (pdata->board->y_flip)
-					y[touch_count] =
-						pdata->sensor_max_y -
-								y[touch_count];
 			}
+			x = (data[0] << 4) | (data[2] & MASK_4BIT);
+			y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
+			wy = (data[3] >> 4) & MASK_4BIT;
+			wx = (data[3] & MASK_4BIT);
+
+			if (pdata->board->x_flip)
+				x = pdata->sensor_max_x - x;
+			if (pdata->board->y_flip)
+				y = pdata->sensor_max_y - y;
+
+			input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
+								max(wx, wy));
+			input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+			input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+
 			/* number of active touch points */
 			touch_count++;
 		}
 	}
 
-	/* report to input subsystem */
-	if (touch_count) {
-		for (finger = 0; finger < touch_count; finger++) {
-			input_report_abs(pdata->input_dev, ABS_MT_TOUCH_MAJOR,
-						max(wx[finger] , wy[finger]));
-			input_report_abs(pdata->input_dev, ABS_MT_POSITION_X,
-								x[finger]);
-			input_report_abs(pdata->input_dev, ABS_MT_POSITION_Y,
-								y[finger]);
-			input_mt_sync(pdata->input_dev);
-		}
-	} else
-		input_mt_sync(pdata->input_dev);
-
 	/* sync after groups of events */
-	input_sync(pdata->input_dev);
+	input_mt_sync_frame(input_dev);
+	input_sync(input_dev);
 	/* return the number of touch points */
 	return touch_count;
 }
@@ -575,6 +562,7 @@  static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata,
 		if ((queries[1] & MASK_3BIT) == 5)
 			rfi->num_of_data_points = 10;
 	}
+	pdata->fingers_supported = rfi->num_of_data_points;
 	/* Need to get interrupt info for handling interrupts */
 	rfi->index_to_intr_reg = (interruptcount + 7)/8;
 	if (rfi->index_to_intr_reg != 0)
@@ -988,6 +976,8 @@  static int __devinit synaptics_rmi4_probe
 					rmi4_data->sensor_max_y, 0, 0);
 	input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0,
 						MAX_TOUCH_MAJOR, 0, 0);
+	input_mt_init_slots(rmi4_data->input_dev,
+				rmi4_data->fingers_supported, 0);
 
 	/* Clear interrupts */
 	synaptics_rmi4_i2c_block_read(rmi4_data,