Re: [PATCH V2 07/10] input: touchscreen: ili210x: Rework the touchscreen sample processing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Dec 20, 2018 at 09:43:02PM +0100, Marek Vasut wrote:
> Get rid of the packed structures for representing data as that does not
> apply to other similar Ilitek touchscreens. Instead, implement a function
> which parses the data and reports touch events and coordinates.
> 
> Signed-off-by: Marek Vasut <marex@xxxxxxx>
> Cc: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
> Cc: Henrik Rydberg <rydberg@xxxxxxxxxxx>
> Cc: Olivier Sobrie <olivier@xxxxxxxxx>
> Cc: Philipp Puschmann <pp@xxxxxxxxx>
> To: linux-input@xxxxxxxxxxxxxxx
> ---
> V2: Replace touchdata.status with touchdata[0] and move it into
>     ili210x_report_events() in anticipation of ILI251x specific changes,
>     and to to synchronize the patch with changes in
>     "input: touchscreen: ili210x: Convert to devm_ functions"
> ---
>  drivers/input/touchscreen/ili210x.c | 59 +++++++++++++++++------------
>  1 file changed, 34 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
> index a84ca555829e..ab0e6c9a614c 100644
> --- a/drivers/input/touchscreen/ili210x.c
> +++ b/drivers/input/touchscreen/ili210x.c
> @@ -16,20 +16,11 @@
>  #define REG_FIRMWARE_VERSION	0x40
>  #define REG_CALIBRATE		0xcc
>  
> -struct finger {
> +struct panel_info {
>  	u8 x_low;
>  	u8 x_high;
>  	u8 y_low;
>  	u8 y_high;
> -} __packed;
> -
> -struct touchdata {
> -	u8 status;
> -	struct finger finger[MAX_TOUCHES];
> -} __packed;
> -
> -struct panel_info {
> -	struct finger finger_max;
>  	u8 xchannel_num;
>  	u8 ychannel_num;
>  } __packed;
> @@ -74,25 +65,40 @@ static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf,
>  	return 0;
>  }
>  
> -static void ili210x_report_events(struct input_dev *input,
> -				  const struct touchdata *touchdata)
> +static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata,
> +					unsigned int finger,
> +					unsigned int *x, unsigned int *y)
> +{
> +	u8 x_low, x_high, y_low, y_high;
> +
> +	if (finger >= MAX_TOUCHES)
> +		return false;
> +
> +	if (touchdata[0] & BIT(finger))
> +		return false;
> +
> +	x_high = touchdata[1 + (finger * 4) + 0];
> +	x_low = touchdata[1 + (finger * 4) + 1];

Sounds like get_unaligned_be16().

> +	y_high = touchdata[1 + (finger * 4) + 2];
> +	y_low = touchdata[1 + (finger * 4) + 3];
> +	*x = x_low | (x_high << 8);
> +	*y = y_low | (y_high << 8);
> +
> +	return true;
> +}
> +
> +static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
>  {
>  	int i;
>  	bool touch;
>  	unsigned int x, y;
> -	const struct finger *finger;
>  
>  	for (i = 0; i < MAX_TOUCHES; i++) {
>  		input_mt_slot(input, i);
>  
> -		finger = &touchdata->finger[i];
> -
> -		touch = touchdata->status & (1 << i);
> +		touch = ili210x_touchdata_to_coords(priv, touchdata, i, &x, &y);
>  		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
>  		if (touch) {
> -			x = finger->x_low | (finger->x_high << 8);
> -			y = finger->y_low | (finger->y_high << 8);
> -
>  			input_report_abs(input, ABS_MT_POSITION_X, x);
>  			input_report_abs(input, ABS_MT_POSITION_Y, y);
>  		}
> @@ -100,6 +106,8 @@ static void ili210x_report_events(struct input_dev *input,
>  
>  	input_mt_report_pointer_emulation(input, false);
>  	input_sync(input);
> +
> +	return touchdata[0] & 0xf3;
>  }
>  
>  static void ili210x_work(struct work_struct *work)
> @@ -107,20 +115,21 @@ static void ili210x_work(struct work_struct *work)
>  	struct ili210x *priv = container_of(work, struct ili210x,
>  					    dwork.work);
>  	struct i2c_client *client = priv->client;
> -	struct touchdata touchdata;
> +	u8 touchdata[1 + 4 * MAX_TOUCHES];

Would it make sense to make the buffer part of struct ili210x and mark
it ____cacheline_aligned so that we can use dmasafe I2C APIs?

> +	bool touch;
>  	int error;
>  
>  	error = ili210x_read_reg(client, REG_TOUCHDATA,
> -				 &touchdata, sizeof(touchdata));
> +				 touchdata, sizeof(touchdata));
>  	if (error) {
>  		dev_err(&client->dev,
>  			"Unable to get touchdata, err = %d\n", error);
>  		return;
>  	}
>  
> -	ili210x_report_events(priv->input, &touchdata);
> +	touch = ili210x_report_events(priv, touchdata);
>  
> -	if (touchdata.status & 0xf3)
> +	if (touch)
>  		schedule_delayed_work(&priv->dwork,
>  				      msecs_to_jiffies(priv->poll_period));
>  }
> @@ -216,8 +225,8 @@ static int ili210x_i2c_probe(struct i2c_client *client,
>  		return error;
>  	}
>  
> -	xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8);
> -	ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8);
> +	xmax = panel.x_low | (panel.x_high << 8);
> +	ymax = panel.y_low | (panel.y_high << 8);
>  
>  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>  	input = devm_input_allocate_device(dev);
> -- 
> 2.19.2
> 

Thanks.

-- 
Dmitry



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux