Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1534865 > unrolled thread

[PATCH v2 0/7] RMI4 cleanups and switch hid-rmi to rmi_core

Started byBenjamin Tissoires <benjamin.tissoires@redhat.com>
First post2016-12-02 12:50 +0100
Last post2016-12-03 19:40 +0100
Articles 11 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/7] RMI4 cleanups and switch hid-rmi to rmi_core Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2016-12-02 12:50 +0100
    [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2016-12-02 12:50 +0100
      Re: [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the  driver Andrew Duggan <aduggan@synaptics.com> - 2016-12-03 01:50 +0100
        Re: [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in  the driver Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2016-12-03 19:30 +0100
    [PATCH v2 5/7] HID: rmi: Make hid-rmi a transport driver for synaptics-rmi4 Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2016-12-02 12:50 +0100
    [PATCH v2 2/7] Input: synaptics-rmi4 - F03: grab data passed by transport device Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2016-12-02 12:50 +0100
    [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2016-12-02 12:50 +0100
      Re: [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention  data Andrew Duggan <aduggan@synaptics.com> - 2016-12-03 01:50 +0100
        Re: [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention  data Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2016-12-03 19:30 +0100
    Re: [PATCH v2 0/7] RMI4 cleanups and switch hid-rmi to rmi_core Andrew Duggan <aduggan@synaptics.com> - 2016-12-03 01:50 +0100
    Re: [PATCH v2 0/7] RMI4 cleanups and switch hid-rmi to rmi_core Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2016-12-03 19:40 +0100

#1534865 — [PATCH v2 0/7] RMI4 cleanups and switch hid-rmi to rmi_core

FromBenjamin Tissoires <benjamin.tissoires@redhat.com>
Date2016-12-02 12:50 +0100
Subject[PATCH v2 0/7] RMI4 cleanups and switch hid-rmi to rmi_core
Message-ID<sJUvL-3hJ-3@gated-at.bofh.it>
Hi,

Well, the cleanup part of the series has already been applied, so
I guess this is just "switch hid-rmi to rmi_core".

The series applies on top of Dmitri's synaptics-rmi4 branch

However, as mentioned in v1, I'd like to get some testings from actually
integrated devices befor we flip the switch for HID. Andrew, Dennis?

Function f03 has been tested in the rmi4-smbus, and the attn data API
on a test synaptics board.

Cheers,
Benjamin

Andrew Duggan (3):
  HID: rmi: Make hid-rmi a transport driver for synaptics-rmi4
  HID: rmi: Handle all Synaptics touchpads using hid-rmi
  HID: rmi: Support the Lenovo Thinkpad X1 Tablet dock using hid-rmi

Benjamin Tissoires (2):
  Input: synaptics-rmi4 - allow to add attention data
  Input: synaptics-rmi4 - store the attn data in the driver

Dennis Wassenberg (1):
  Input: synaptics-rmi4 - F03: grab data passed by transport device

Lyude Paul (1):
  Input: synaptics-rmi4 - add support for F03

 drivers/hid/Kconfig             |   4 +
 drivers/hid/hid-core.c          |   4 +-
 drivers/hid/hid-ids.h           |   1 +
 drivers/hid/hid-rmi.c           | 974 ++++++----------------------------------
 drivers/input/rmi4/Kconfig      |   9 +
 drivers/input/rmi4/Makefile     |   1 +
 drivers/input/rmi4/rmi_bus.c    |   3 +
 drivers/input/rmi4/rmi_driver.c |  50 ++-
 drivers/input/rmi4/rmi_driver.h |   1 +
 drivers/input/rmi4/rmi_f03.c    | 251 +++++++++++
 drivers/input/rmi4/rmi_f11.c    |  12 +-
 drivers/input/rmi4/rmi_f12.c    |  43 +-
 drivers/input/rmi4/rmi_f30.c    |  11 +-
 include/linux/rmi.h             |  16 +-
 14 files changed, 508 insertions(+), 872 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f03.c

-- 
2.9.3

[toc] | [next] | [standalone]


#1534866 — [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver

FromBenjamin Tissoires <benjamin.tissoires@redhat.com>
Date2016-12-02 12:50 +0100
Subject[PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver
Message-ID<sJUvM-3hJ-17@gated-at.bofh.it>
In reply to#1534865
Now that we have a proper API to set the attention data, there is
no point in keeping it in the transport driver.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

no changes in v2
---
 drivers/input/rmi4/rmi_driver.c |  5 ++---
 drivers/input/rmi4/rmi_f03.c    | 13 +++++++------
 drivers/input/rmi4/rmi_f11.c    | 12 ++++++------
 drivers/input/rmi4/rmi_f12.c    | 43 +++++++++++++++++++++--------------------
 drivers/input/rmi4/rmi_f30.c    | 11 ++++++-----
 include/linux/rmi.h             |  5 ++---
 6 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 85062e4..05a3c4b 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -155,7 +155,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
 	if (!data)
 		return 0;
 
-	if (!rmi_dev->xport->attn_data) {
+	if (!data->attn_data.data) {
 		error = rmi_read_block(rmi_dev,
 				data->f01_container->fd.data_base_addr + 1,
 				data->irq_status, data->num_of_irq_regs);
@@ -223,8 +223,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
 	count = kfifo_get(&drvdata->attn_fifo, &attn_data);
 	if (count) {
 		*(drvdata->irq_status) = attn_data.irq_status;
-		rmi_dev->xport->attn_data = attn_data.data;
-		rmi_dev->xport->attn_size = attn_data.size;
+		drvdata->attn_data = attn_data;
 	}
 
 	ret = rmi_process_interrupt_requests(rmi_dev);
diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
index 06279cd..996dcbb 100644
--- a/drivers/input/rmi4/rmi_f03.c
+++ b/drivers/input/rmi4/rmi_f03.c
@@ -166,6 +166,7 @@ static int rmi_f03_config(struct rmi_function *fn)
 static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
 {
 	struct rmi_device *rmi_dev = fn->rmi_dev;
+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
 	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
 	u16 data_addr = fn->fd.data_base_addr;
 	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
@@ -176,20 +177,20 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
 	int i;
 	int ret;
 
-	if (!rmi_dev || !rmi_dev->xport)
+	if (!rmi_dev)
 		return -ENODEV;
 
-	if (rmi_dev->xport->attn_data) {
+	if (drvdata->attn_data.data) {
 		/* First grab the data passed by the transport device */
-		if (rmi_dev->xport->attn_size < ob_len) {
+		if (drvdata->attn_data.size < ob_len) {
 			dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
 			return 0;
 		}
 
-		memcpy(obs, rmi_dev->xport->attn_data, ob_len);
+		memcpy(obs, drvdata->attn_data.data, ob_len);
 
-		rmi_dev->xport->attn_data += ob_len;
-		rmi_dev->xport->attn_size -= ob_len;
+		drvdata->attn_data.data += ob_len;
+		drvdata->attn_data.size -= ob_len;
 	} else {
 		/* Grab all of the data registers, and check them for data */
 		ret = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 44fc275..bc5e37f 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1284,19 +1284,19 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
 	int error;
 	int valid_bytes = f11->sensor.pkt_size;
 
-	if (rmi_dev->xport->attn_data) {
+	if (drvdata->attn_data.data) {
 		/*
 		 * The valid data in the attention report is less then
 		 * expected. Only process the complete fingers.
 		 */
-		if (f11->sensor.attn_size > rmi_dev->xport->attn_size)
-			valid_bytes = rmi_dev->xport->attn_size;
+		if (f11->sensor.attn_size > drvdata->attn_data.size)
+			valid_bytes = drvdata->attn_data.size;
 		else
 			valid_bytes = f11->sensor.attn_size;
-		memcpy(f11->sensor.data_pkt, rmi_dev->xport->attn_data,
+		memcpy(f11->sensor.data_pkt, drvdata->attn_data.data,
 			valid_bytes);
-		rmi_dev->xport->attn_data += f11->sensor.attn_size;
-		rmi_dev->xport->attn_size -= f11->sensor.attn_size;
+		drvdata->attn_data.data += f11->sensor.attn_size;
+		drvdata->attn_data.size -= f11->sensor.attn_size;
 	} else {
 		error = rmi_read_block(rmi_dev,
 				data_base_addr, f11->sensor.data_pkt,
diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
index 82a4964..8c5360c 100644
--- a/drivers/input/rmi4/rmi_f12.c
+++ b/drivers/input/rmi4/rmi_f12.c
@@ -208,19 +208,20 @@ static int rmi_f12_attention(struct rmi_function *fn,
 {
 	int retval;
 	struct rmi_device *rmi_dev = fn->rmi_dev;
+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
 	struct f12_data *f12 = dev_get_drvdata(&fn->dev);
 	struct rmi_2d_sensor *sensor = &f12->sensor;
 	int valid_bytes = sensor->pkt_size;
 
-	if (rmi_dev->xport->attn_data) {
-		if (sensor->attn_size > rmi_dev->xport->attn_size)
-			valid_bytes = rmi_dev->xport->attn_size;
+	if (drvdata->attn_data.data) {
+		if (sensor->attn_size > drvdata->attn_data.size)
+			valid_bytes = drvdata->attn_data.size;
 		else
 			valid_bytes = sensor->attn_size;
-		memcpy(sensor->data_pkt, rmi_dev->xport->attn_data,
+		memcpy(sensor->data_pkt, drvdata->attn_data.data,
 			valid_bytes);
-		rmi_dev->xport->attn_data += sensor->attn_size;
-		rmi_dev->xport->attn_size -= sensor->attn_size;
+		drvdata->attn_data.data += sensor->attn_size;
+		drvdata->attn_data.size -= sensor->attn_size;
 	} else {
 		retval = rmi_read_block(rmi_dev, f12->data_addr,
 					sensor->data_pkt, sensor->pkt_size);
@@ -323,7 +324,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
 	const struct rmi_register_desc_item *item;
 	struct rmi_2d_sensor *sensor;
 	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
-	struct rmi_transport_dev *xport = rmi_dev->xport;
+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
 	u16 data_offset = 0;
 
 	rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__);
@@ -422,7 +423,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
 	 * HID attention reports.
 	 */
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 0);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 1);
@@ -436,15 +437,15 @@ static int rmi_f12_probe(struct rmi_function *fn)
 	}
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 2);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 3);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 4);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 5);
@@ -456,22 +457,22 @@ static int rmi_f12_probe(struct rmi_function *fn)
 	}
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 6);
-	if (item && !xport->attn_data) {
+	if (item && !drvdata->attn_data.data) {
 		f12->data6 = item;
 		f12->data6_offset = data_offset;
 		data_offset += item->reg_size;
 	}
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 7);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 8);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 9);
-	if (item && !xport->attn_data) {
+	if (item && !drvdata->attn_data.data) {
 		f12->data9 = item;
 		f12->data9_offset = data_offset;
 		data_offset += item->reg_size;
@@ -480,27 +481,27 @@ static int rmi_f12_probe(struct rmi_function *fn)
 	}
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 10);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 11);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 12);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 13);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 14);
-	if (item && !xport->attn_data)
+	if (item && !drvdata->attn_data.data)
 		data_offset += item->reg_size;
 
 	item = rmi_get_register_desc_item(&f12->data_reg_desc, 15);
-	if (item && !xport->attn_data) {
+	if (item && !drvdata->attn_data.data) {
 		f12->data15 = item;
 		f12->data15_offset = data_offset;
 		data_offset += item->reg_size;
diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
index f696137..f4b491e 100644
--- a/drivers/input/rmi4/rmi_f30.c
+++ b/drivers/input/rmi4/rmi_f30.c
@@ -99,6 +99,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
 {
 	struct f30_data *f30 = dev_get_drvdata(&fn->dev);
 	struct rmi_device *rmi_dev = fn->rmi_dev;
+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
 	int retval;
 	int gpiled = 0;
 	int value = 0;
@@ -109,15 +110,15 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
 		return 0;
 
 	/* Read the gpi led data. */
-	if (rmi_dev->xport->attn_data) {
-		if (rmi_dev->xport->attn_size < f30->register_count) {
+	if (drvdata->attn_data.data) {
+		if (drvdata->attn_data.size < f30->register_count) {
 			dev_warn(&fn->dev, "F30 interrupted, but data is missing\n");
 			return 0;
 		}
-		memcpy(f30->data_regs, rmi_dev->xport->attn_data,
+		memcpy(f30->data_regs, drvdata->attn_data.data,
 			f30->register_count);
-		rmi_dev->xport->attn_data += f30->register_count;
-		rmi_dev->xport->attn_size -= f30->register_count;
+		drvdata->attn_data.data += f30->register_count;
+		drvdata->attn_data.size -= f30->register_count;
 	} else {
 		retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
 			f30->data_regs, f30->register_count);
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 1d48656..ac910f7 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -272,9 +272,6 @@ struct rmi_transport_dev {
 	struct rmi_device_platform_data pdata;
 
 	struct input_dev *input;
-
-	void *attn_data;
-	int attn_size;
 };
 
 /**
@@ -364,6 +361,8 @@ struct rmi_driver_data {
 
 	bool enabled;
 	struct mutex enabled_mutex;
+
+	struct rmi4_attn_data attn_data;
 	DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
 };
 
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1535284 — Re: [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver

FromAndrew Duggan <aduggan@synaptics.com>
Date2016-12-03 01:50 +0100
SubjectRe: [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver
Message-ID<sK6GB-2yg-5@gated-at.bofh.it>
In reply to#1534866
On 12/02/2016 03:41 AM, Benjamin Tissoires wrote:
> Now that we have a proper API to set the attention data, there is
> no point in keeping it in the transport driver.
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Reviewed-by: Andrew Duggan <aduggan@synaptics.com>

> ---
>
> no changes in v2
> ---
>   drivers/input/rmi4/rmi_driver.c |  5 ++---
>   drivers/input/rmi4/rmi_f03.c    | 13 +++++++------
>   drivers/input/rmi4/rmi_f11.c    | 12 ++++++------
>   drivers/input/rmi4/rmi_f12.c    | 43 +++++++++++++++++++++--------------------
>   drivers/input/rmi4/rmi_f30.c    | 11 ++++++-----
>   include/linux/rmi.h             |  5 ++---
>   6 files changed, 45 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index 85062e4..05a3c4b 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -155,7 +155,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
>   	if (!data)
>   		return 0;
>   
> -	if (!rmi_dev->xport->attn_data) {
> +	if (!data->attn_data.data) {
>   		error = rmi_read_block(rmi_dev,
>   				data->f01_container->fd.data_base_addr + 1,
>   				data->irq_status, data->num_of_irq_regs);
> @@ -223,8 +223,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
>   	count = kfifo_get(&drvdata->attn_fifo, &attn_data);
>   	if (count) {
>   		*(drvdata->irq_status) = attn_data.irq_status;
> -		rmi_dev->xport->attn_data = attn_data.data;
> -		rmi_dev->xport->attn_size = attn_data.size;
> +		drvdata->attn_data = attn_data;
>   	}
>   
>   	ret = rmi_process_interrupt_requests(rmi_dev);
> diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
> index 06279cd..996dcbb 100644
> --- a/drivers/input/rmi4/rmi_f03.c
> +++ b/drivers/input/rmi4/rmi_f03.c
> @@ -166,6 +166,7 @@ static int rmi_f03_config(struct rmi_function *fn)
>   static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
>   {
>   	struct rmi_device *rmi_dev = fn->rmi_dev;
> +	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
>   	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
>   	u16 data_addr = fn->fd.data_base_addr;
>   	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
> @@ -176,20 +177,20 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
>   	int i;
>   	int ret;
>   
> -	if (!rmi_dev || !rmi_dev->xport)
> +	if (!rmi_dev)
>   		return -ENODEV;
>   
> -	if (rmi_dev->xport->attn_data) {
> +	if (drvdata->attn_data.data) {
>   		/* First grab the data passed by the transport device */
> -		if (rmi_dev->xport->attn_size < ob_len) {
> +		if (drvdata->attn_data.size < ob_len) {
>   			dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
>   			return 0;
>   		}
>   
> -		memcpy(obs, rmi_dev->xport->attn_data, ob_len);
> +		memcpy(obs, drvdata->attn_data.data, ob_len);
>   
> -		rmi_dev->xport->attn_data += ob_len;
> -		rmi_dev->xport->attn_size -= ob_len;
> +		drvdata->attn_data.data += ob_len;
> +		drvdata->attn_data.size -= ob_len;
>   	} else {
>   		/* Grab all of the data registers, and check them for data */
>   		ret = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
> diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
> index 44fc275..bc5e37f 100644
> --- a/drivers/input/rmi4/rmi_f11.c
> +++ b/drivers/input/rmi4/rmi_f11.c
> @@ -1284,19 +1284,19 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
>   	int error;
>   	int valid_bytes = f11->sensor.pkt_size;
>   
> -	if (rmi_dev->xport->attn_data) {
> +	if (drvdata->attn_data.data) {
>   		/*
>   		 * The valid data in the attention report is less then
>   		 * expected. Only process the complete fingers.
>   		 */
> -		if (f11->sensor.attn_size > rmi_dev->xport->attn_size)
> -			valid_bytes = rmi_dev->xport->attn_size;
> +		if (f11->sensor.attn_size > drvdata->attn_data.size)
> +			valid_bytes = drvdata->attn_data.size;
>   		else
>   			valid_bytes = f11->sensor.attn_size;
> -		memcpy(f11->sensor.data_pkt, rmi_dev->xport->attn_data,
> +		memcpy(f11->sensor.data_pkt, drvdata->attn_data.data,
>   			valid_bytes);
> -		rmi_dev->xport->attn_data += f11->sensor.attn_size;
> -		rmi_dev->xport->attn_size -= f11->sensor.attn_size;
> +		drvdata->attn_data.data += f11->sensor.attn_size;
> +		drvdata->attn_data.size -= f11->sensor.attn_size;
>   	} else {
>   		error = rmi_read_block(rmi_dev,
>   				data_base_addr, f11->sensor.data_pkt,
> diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
> index 82a4964..8c5360c 100644
> --- a/drivers/input/rmi4/rmi_f12.c
> +++ b/drivers/input/rmi4/rmi_f12.c
> @@ -208,19 +208,20 @@ static int rmi_f12_attention(struct rmi_function *fn,
>   {
>   	int retval;
>   	struct rmi_device *rmi_dev = fn->rmi_dev;
> +	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
>   	struct f12_data *f12 = dev_get_drvdata(&fn->dev);
>   	struct rmi_2d_sensor *sensor = &f12->sensor;
>   	int valid_bytes = sensor->pkt_size;
>   
> -	if (rmi_dev->xport->attn_data) {
> -		if (sensor->attn_size > rmi_dev->xport->attn_size)
> -			valid_bytes = rmi_dev->xport->attn_size;
> +	if (drvdata->attn_data.data) {
> +		if (sensor->attn_size > drvdata->attn_data.size)
> +			valid_bytes = drvdata->attn_data.size;
>   		else
>   			valid_bytes = sensor->attn_size;
> -		memcpy(sensor->data_pkt, rmi_dev->xport->attn_data,
> +		memcpy(sensor->data_pkt, drvdata->attn_data.data,
>   			valid_bytes);
> -		rmi_dev->xport->attn_data += sensor->attn_size;
> -		rmi_dev->xport->attn_size -= sensor->attn_size;
> +		drvdata->attn_data.data += sensor->attn_size;
> +		drvdata->attn_data.size -= sensor->attn_size;
>   	} else {
>   		retval = rmi_read_block(rmi_dev, f12->data_addr,
>   					sensor->data_pkt, sensor->pkt_size);
> @@ -323,7 +324,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
>   	const struct rmi_register_desc_item *item;
>   	struct rmi_2d_sensor *sensor;
>   	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
> -	struct rmi_transport_dev *xport = rmi_dev->xport;
> +	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
>   	u16 data_offset = 0;
>   
>   	rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__);
> @@ -422,7 +423,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
>   	 * HID attention reports.
>   	 */
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 0);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 1);
> @@ -436,15 +437,15 @@ static int rmi_f12_probe(struct rmi_function *fn)
>   	}
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 2);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 3);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 4);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 5);
> @@ -456,22 +457,22 @@ static int rmi_f12_probe(struct rmi_function *fn)
>   	}
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 6);
> -	if (item && !xport->attn_data) {
> +	if (item && !drvdata->attn_data.data) {
>   		f12->data6 = item;
>   		f12->data6_offset = data_offset;
>   		data_offset += item->reg_size;
>   	}
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 7);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 8);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 9);
> -	if (item && !xport->attn_data) {
> +	if (item && !drvdata->attn_data.data) {
>   		f12->data9 = item;
>   		f12->data9_offset = data_offset;
>   		data_offset += item->reg_size;
> @@ -480,27 +481,27 @@ static int rmi_f12_probe(struct rmi_function *fn)
>   	}
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 10);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 11);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 12);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 13);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 14);
> -	if (item && !xport->attn_data)
> +	if (item && !drvdata->attn_data.data)
>   		data_offset += item->reg_size;
>   
>   	item = rmi_get_register_desc_item(&f12->data_reg_desc, 15);
> -	if (item && !xport->attn_data) {
> +	if (item && !drvdata->attn_data.data) {
>   		f12->data15 = item;
>   		f12->data15_offset = data_offset;
>   		data_offset += item->reg_size;
> diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
> index f696137..f4b491e 100644
> --- a/drivers/input/rmi4/rmi_f30.c
> +++ b/drivers/input/rmi4/rmi_f30.c
> @@ -99,6 +99,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
>   {
>   	struct f30_data *f30 = dev_get_drvdata(&fn->dev);
>   	struct rmi_device *rmi_dev = fn->rmi_dev;
> +	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
>   	int retval;
>   	int gpiled = 0;
>   	int value = 0;
> @@ -109,15 +110,15 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
>   		return 0;
>   
>   	/* Read the gpi led data. */
> -	if (rmi_dev->xport->attn_data) {
> -		if (rmi_dev->xport->attn_size < f30->register_count) {
> +	if (drvdata->attn_data.data) {
> +		if (drvdata->attn_data.size < f30->register_count) {
>   			dev_warn(&fn->dev, "F30 interrupted, but data is missing\n");
>   			return 0;
>   		}
> -		memcpy(f30->data_regs, rmi_dev->xport->attn_data,
> +		memcpy(f30->data_regs, drvdata->attn_data.data,
>   			f30->register_count);
> -		rmi_dev->xport->attn_data += f30->register_count;
> -		rmi_dev->xport->attn_size -= f30->register_count;
> +		drvdata->attn_data.data += f30->register_count;
> +		drvdata->attn_data.size -= f30->register_count;
>   	} else {
>   		retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
>   			f30->data_regs, f30->register_count);
> diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> index 1d48656..ac910f7 100644
> --- a/include/linux/rmi.h
> +++ b/include/linux/rmi.h
> @@ -272,9 +272,6 @@ struct rmi_transport_dev {
>   	struct rmi_device_platform_data pdata;
>   
>   	struct input_dev *input;
> -
> -	void *attn_data;
> -	int attn_size;
>   };
>   
>   /**
> @@ -364,6 +361,8 @@ struct rmi_driver_data {
>   
>   	bool enabled;
>   	struct mutex enabled_mutex;
> +
> +	struct rmi4_attn_data attn_data;
>   	DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
>   };
>   

[toc] | [prev] | [next] | [standalone]


#1535477 — Re: [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2016-12-03 19:30 +0100
SubjectRe: [PATCH v2 4/7] Input: synaptics-rmi4 - store the attn data in the driver
Message-ID<sKneq-4OU-19@gated-at.bofh.it>
In reply to#1535284
On Fri, Dec 02, 2016 at 04:34:01PM -0800, Andrew Duggan wrote:
> On 12/02/2016 03:41 AM, Benjamin Tissoires wrote:
> >Now that we have a proper API to set the attention data, there is
> >no point in keeping it in the transport driver.
> >
> >Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> 
> Reviewed-by: Andrew Duggan <aduggan@synaptics.com>

Applied, thank you.


> 
> >---
> >
> >no changes in v2
> >---
> >  drivers/input/rmi4/rmi_driver.c |  5 ++---
> >  drivers/input/rmi4/rmi_f03.c    | 13 +++++++------
> >  drivers/input/rmi4/rmi_f11.c    | 12 ++++++------
> >  drivers/input/rmi4/rmi_f12.c    | 43 +++++++++++++++++++++--------------------
> >  drivers/input/rmi4/rmi_f30.c    | 11 ++++++-----
> >  include/linux/rmi.h             |  5 ++---
> >  6 files changed, 45 insertions(+), 44 deletions(-)
> >
> >diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> >index 85062e4..05a3c4b 100644
> >--- a/drivers/input/rmi4/rmi_driver.c
> >+++ b/drivers/input/rmi4/rmi_driver.c
> >@@ -155,7 +155,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
> >  	if (!data)
> >  		return 0;
> >-	if (!rmi_dev->xport->attn_data) {
> >+	if (!data->attn_data.data) {
> >  		error = rmi_read_block(rmi_dev,
> >  				data->f01_container->fd.data_base_addr + 1,
> >  				data->irq_status, data->num_of_irq_regs);
> >@@ -223,8 +223,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
> >  	count = kfifo_get(&drvdata->attn_fifo, &attn_data);
> >  	if (count) {
> >  		*(drvdata->irq_status) = attn_data.irq_status;
> >-		rmi_dev->xport->attn_data = attn_data.data;
> >-		rmi_dev->xport->attn_size = attn_data.size;
> >+		drvdata->attn_data = attn_data;
> >  	}
> >  	ret = rmi_process_interrupt_requests(rmi_dev);
> >diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
> >index 06279cd..996dcbb 100644
> >--- a/drivers/input/rmi4/rmi_f03.c
> >+++ b/drivers/input/rmi4/rmi_f03.c
> >@@ -166,6 +166,7 @@ static int rmi_f03_config(struct rmi_function *fn)
> >  static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
> >  {
> >  	struct rmi_device *rmi_dev = fn->rmi_dev;
> >+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> >  	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> >  	u16 data_addr = fn->fd.data_base_addr;
> >  	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
> >@@ -176,20 +177,20 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
> >  	int i;
> >  	int ret;
> >-	if (!rmi_dev || !rmi_dev->xport)
> >+	if (!rmi_dev)
> >  		return -ENODEV;
> >-	if (rmi_dev->xport->attn_data) {
> >+	if (drvdata->attn_data.data) {
> >  		/* First grab the data passed by the transport device */
> >-		if (rmi_dev->xport->attn_size < ob_len) {
> >+		if (drvdata->attn_data.size < ob_len) {
> >  			dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
> >  			return 0;
> >  		}
> >-		memcpy(obs, rmi_dev->xport->attn_data, ob_len);
> >+		memcpy(obs, drvdata->attn_data.data, ob_len);
> >-		rmi_dev->xport->attn_data += ob_len;
> >-		rmi_dev->xport->attn_size -= ob_len;
> >+		drvdata->attn_data.data += ob_len;
> >+		drvdata->attn_data.size -= ob_len;
> >  	} else {
> >  		/* Grab all of the data registers, and check them for data */
> >  		ret = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
> >diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
> >index 44fc275..bc5e37f 100644
> >--- a/drivers/input/rmi4/rmi_f11.c
> >+++ b/drivers/input/rmi4/rmi_f11.c
> >@@ -1284,19 +1284,19 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
> >  	int error;
> >  	int valid_bytes = f11->sensor.pkt_size;
> >-	if (rmi_dev->xport->attn_data) {
> >+	if (drvdata->attn_data.data) {
> >  		/*
> >  		 * The valid data in the attention report is less then
> >  		 * expected. Only process the complete fingers.
> >  		 */
> >-		if (f11->sensor.attn_size > rmi_dev->xport->attn_size)
> >-			valid_bytes = rmi_dev->xport->attn_size;
> >+		if (f11->sensor.attn_size > drvdata->attn_data.size)
> >+			valid_bytes = drvdata->attn_data.size;
> >  		else
> >  			valid_bytes = f11->sensor.attn_size;
> >-		memcpy(f11->sensor.data_pkt, rmi_dev->xport->attn_data,
> >+		memcpy(f11->sensor.data_pkt, drvdata->attn_data.data,
> >  			valid_bytes);
> >-		rmi_dev->xport->attn_data += f11->sensor.attn_size;
> >-		rmi_dev->xport->attn_size -= f11->sensor.attn_size;
> >+		drvdata->attn_data.data += f11->sensor.attn_size;
> >+		drvdata->attn_data.size -= f11->sensor.attn_size;
> >  	} else {
> >  		error = rmi_read_block(rmi_dev,
> >  				data_base_addr, f11->sensor.data_pkt,
> >diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
> >index 82a4964..8c5360c 100644
> >--- a/drivers/input/rmi4/rmi_f12.c
> >+++ b/drivers/input/rmi4/rmi_f12.c
> >@@ -208,19 +208,20 @@ static int rmi_f12_attention(struct rmi_function *fn,
> >  {
> >  	int retval;
> >  	struct rmi_device *rmi_dev = fn->rmi_dev;
> >+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> >  	struct f12_data *f12 = dev_get_drvdata(&fn->dev);
> >  	struct rmi_2d_sensor *sensor = &f12->sensor;
> >  	int valid_bytes = sensor->pkt_size;
> >-	if (rmi_dev->xport->attn_data) {
> >-		if (sensor->attn_size > rmi_dev->xport->attn_size)
> >-			valid_bytes = rmi_dev->xport->attn_size;
> >+	if (drvdata->attn_data.data) {
> >+		if (sensor->attn_size > drvdata->attn_data.size)
> >+			valid_bytes = drvdata->attn_data.size;
> >  		else
> >  			valid_bytes = sensor->attn_size;
> >-		memcpy(sensor->data_pkt, rmi_dev->xport->attn_data,
> >+		memcpy(sensor->data_pkt, drvdata->attn_data.data,
> >  			valid_bytes);
> >-		rmi_dev->xport->attn_data += sensor->attn_size;
> >-		rmi_dev->xport->attn_size -= sensor->attn_size;
> >+		drvdata->attn_data.data += sensor->attn_size;
> >+		drvdata->attn_data.size -= sensor->attn_size;
> >  	} else {
> >  		retval = rmi_read_block(rmi_dev, f12->data_addr,
> >  					sensor->data_pkt, sensor->pkt_size);
> >@@ -323,7 +324,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
> >  	const struct rmi_register_desc_item *item;
> >  	struct rmi_2d_sensor *sensor;
> >  	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
> >-	struct rmi_transport_dev *xport = rmi_dev->xport;
> >+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> >  	u16 data_offset = 0;
> >  	rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__);
> >@@ -422,7 +423,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
> >  	 * HID attention reports.
> >  	 */
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 0);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 1);
> >@@ -436,15 +437,15 @@ static int rmi_f12_probe(struct rmi_function *fn)
> >  	}
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 2);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 3);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 4);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 5);
> >@@ -456,22 +457,22 @@ static int rmi_f12_probe(struct rmi_function *fn)
> >  	}
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 6);
> >-	if (item && !xport->attn_data) {
> >+	if (item && !drvdata->attn_data.data) {
> >  		f12->data6 = item;
> >  		f12->data6_offset = data_offset;
> >  		data_offset += item->reg_size;
> >  	}
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 7);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 8);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 9);
> >-	if (item && !xport->attn_data) {
> >+	if (item && !drvdata->attn_data.data) {
> >  		f12->data9 = item;
> >  		f12->data9_offset = data_offset;
> >  		data_offset += item->reg_size;
> >@@ -480,27 +481,27 @@ static int rmi_f12_probe(struct rmi_function *fn)
> >  	}
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 10);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 11);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 12);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 13);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 14);
> >-	if (item && !xport->attn_data)
> >+	if (item && !drvdata->attn_data.data)
> >  		data_offset += item->reg_size;
> >  	item = rmi_get_register_desc_item(&f12->data_reg_desc, 15);
> >-	if (item && !xport->attn_data) {
> >+	if (item && !drvdata->attn_data.data) {
> >  		f12->data15 = item;
> >  		f12->data15_offset = data_offset;
> >  		data_offset += item->reg_size;
> >diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
> >index f696137..f4b491e 100644
> >--- a/drivers/input/rmi4/rmi_f30.c
> >+++ b/drivers/input/rmi4/rmi_f30.c
> >@@ -99,6 +99,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
> >  {
> >  	struct f30_data *f30 = dev_get_drvdata(&fn->dev);
> >  	struct rmi_device *rmi_dev = fn->rmi_dev;
> >+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> >  	int retval;
> >  	int gpiled = 0;
> >  	int value = 0;
> >@@ -109,15 +110,15 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
> >  		return 0;
> >  	/* Read the gpi led data. */
> >-	if (rmi_dev->xport->attn_data) {
> >-		if (rmi_dev->xport->attn_size < f30->register_count) {
> >+	if (drvdata->attn_data.data) {
> >+		if (drvdata->attn_data.size < f30->register_count) {
> >  			dev_warn(&fn->dev, "F30 interrupted, but data is missing\n");
> >  			return 0;
> >  		}
> >-		memcpy(f30->data_regs, rmi_dev->xport->attn_data,
> >+		memcpy(f30->data_regs, drvdata->attn_data.data,
> >  			f30->register_count);
> >-		rmi_dev->xport->attn_data += f30->register_count;
> >-		rmi_dev->xport->attn_size -= f30->register_count;
> >+		drvdata->attn_data.data += f30->register_count;
> >+		drvdata->attn_data.size -= f30->register_count;
> >  	} else {
> >  		retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
> >  			f30->data_regs, f30->register_count);
> >diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> >index 1d48656..ac910f7 100644
> >--- a/include/linux/rmi.h
> >+++ b/include/linux/rmi.h
> >@@ -272,9 +272,6 @@ struct rmi_transport_dev {
> >  	struct rmi_device_platform_data pdata;
> >  	struct input_dev *input;
> >-
> >-	void *attn_data;
> >-	int attn_size;
> >  };
> >  /**
> >@@ -364,6 +361,8 @@ struct rmi_driver_data {
> >  	bool enabled;
> >  	struct mutex enabled_mutex;
> >+
> >+	struct rmi4_attn_data attn_data;
> >  	DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
> >  };
> 
> 

-- 
Dmitry

[toc] | [prev] | [next] | [standalone]


#1534867 — [PATCH v2 5/7] HID: rmi: Make hid-rmi a transport driver for synaptics-rmi4

FromBenjamin Tissoires <benjamin.tissoires@redhat.com>
Date2016-12-02 12:50 +0100
Subject[PATCH v2 5/7] HID: rmi: Make hid-rmi a transport driver for synaptics-rmi4
Message-ID<sJUvL-3hJ-5@gated-at.bofh.it>
In reply to#1534865
From: Andrew Duggan <aduggan@synaptics.com>

The Synaptics RMI4 driver provides support for RMI4 devices. Instead of
duplicating the RMI4 processing code, make hid-rmi a transport driver
and register it with the Synaptics RMI4 core.

Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

no changes in v2
---
 drivers/hid/Kconfig   |   4 +
 drivers/hid/hid-rmi.c | 973 ++++++++------------------------------------------
 2 files changed, 144 insertions(+), 833 deletions(-)

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 69f2b2f..d9847f2 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -786,6 +786,10 @@ config HID_SUNPLUS
 config HID_RMI
 	tristate "Synaptics RMI4 device support"
 	depends on HID
+	select RMI4_CORE
+	select RMI4_F11
+	select RMI4_F12
+	select RMI4_F30
 	---help---
 	Support for Synaptics RMI4 touchpads.
 	Say Y here if you have a Synaptics RMI4 touchpads over i2c-hid or usbhid
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index be89bcb..57ed592 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -14,11 +14,13 @@
 #include <linux/hid.h>
 #include <linux/input.h>
 #include <linux/input/mt.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
+#include <linux/rmi.h>
 #include "hid-ids.h"
 
 #define RMI_MOUSE_REPORT_ID		0x01 /* Mouse emulation Report */
@@ -33,9 +35,6 @@
 #define RMI_READ_DATA_PENDING		1
 #define RMI_STARTED			2
 
-#define RMI_SLEEP_NORMAL		0x0
-#define RMI_SLEEP_DEEP_SLEEP		0x1
-
 /* device flags */
 #define RMI_DEVICE			BIT(0)
 #define RMI_DEVICE_HAS_PHYS_BUTTONS	BIT(1)
@@ -54,25 +53,12 @@ enum rmi_mode_type {
 	RMI_MODE_NO_PACKED_ATTN_REPORTS	= 2,
 };
 
-struct rmi_function {
-	unsigned page;			/* page of the function */
-	u16 query_base_addr;		/* base address for queries */
-	u16 command_base_addr;		/* base address for commands */
-	u16 control_base_addr;		/* base address for controls */
-	u16 data_base_addr;		/* base address for datas */
-	unsigned int interrupt_base;	/* cross-function interrupt number
-					 * (uniq in the device)*/
-	unsigned int interrupt_count;	/* number of interrupts */
-	unsigned int report_size;	/* size of a report */
-	unsigned long irq_mask;		/* mask of the interrupts
-					 * (to be applied against ATTN IRQ) */
-};
-
 /**
  * struct rmi_data - stores information for hid communication
  *
  * @page_mutex: Locks current page to avoid changing pages in unexpected ways.
  * @page: Keeps track of the current virtual page
+ * @xport: transport device to be registered with the RMI4 core.
  *
  * @wait: Used for waiting for read data
  *
@@ -84,26 +70,18 @@ struct rmi_function {
  *
  * @flags: flags for the current device (started, reading, etc...)
  *
- * @f11: placeholder of internal RMI function F11 description
- * @f30: placeholder of internal RMI function F30 description
- *
- * @max_fingers: maximum finger count reported by the device
- * @max_x: maximum x value reported by the device
- * @max_y: maximum y value reported by the device
- *
- * @gpio_led_count: count of GPIOs + LEDs reported by F30
- * @button_count: actual physical buttons count
- * @button_mask: button mask used to decode GPIO ATTN reports
- * @button_state_mask: pull state of the buttons
- *
- * @input: pointer to the kernel input device
- *
  * @reset_work: worker which will be called in case of a mouse report
  * @hdev: pointer to the struct hid_device
+ *
+ * @device_flags: flags which describe the device
+ *
+ * @domain: the IRQ domain allocated for this RMI4 device
+ * @rmi_irq: the irq that will be used to generate events to rmi-core
  */
 struct rmi_data {
 	struct mutex page_mutex;
 	int page;
+	struct rmi_transport_dev xport;
 
 	wait_queue_head_t wait;
 
@@ -115,34 +93,13 @@ struct rmi_data {
 
 	unsigned long flags;
 
-	struct rmi_function f01;
-	struct rmi_function f11;
-	struct rmi_function f30;
-
-	unsigned int max_fingers;
-	unsigned int max_x;
-	unsigned int max_y;
-	unsigned int x_size_mm;
-	unsigned int y_size_mm;
-	bool read_f11_ctrl_regs;
-	u8 f11_ctrl_regs[RMI_F11_CTRL_REG_COUNT];
-
-	unsigned int gpio_led_count;
-	unsigned int button_count;
-	unsigned long button_mask;
-	unsigned long button_state_mask;
-
-	struct input_dev *input;
-
 	struct work_struct reset_work;
 	struct hid_device *hdev;
 
 	unsigned long device_flags;
-	unsigned long firmware_id;
 
-	u8 f01_ctrl0;
-	u8 interrupt_enable_mask;
-	bool restore_interrupt_mask;
+	struct irq_domain *domain;
+	int rmi_irq;
 };
 
 #define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
@@ -220,10 +177,11 @@ static int rmi_write_report(struct hid_device *hdev, u8 *report, int len)
 	return ret;
 }
 
-static int rmi_read_block(struct hid_device *hdev, u16 addr, void *buf,
-		const int len)
+static int rmi_hid_read_block(struct rmi_transport_dev *xport, u16 addr,
+		void *buf, size_t len)
 {
-	struct rmi_data *data = hid_get_drvdata(hdev);
+	struct rmi_data *data = container_of(xport, struct rmi_data, xport);
+	struct hid_device *hdev = data->hdev;
 	int ret;
 	int bytes_read;
 	int bytes_needed;
@@ -292,15 +250,11 @@ static int rmi_read_block(struct hid_device *hdev, u16 addr, void *buf,
 	return ret;
 }
 
-static inline int rmi_read(struct hid_device *hdev, u16 addr, void *buf)
-{
-	return rmi_read_block(hdev, addr, buf, 1);
-}
-
-static int rmi_write_block(struct hid_device *hdev, u16 addr, void *buf,
-		const int len)
+static int rmi_hid_write_block(struct rmi_transport_dev *xport, u16 addr,
+		const void *buf, size_t len)
 {
-	struct rmi_data *data = hid_get_drvdata(hdev);
+	struct rmi_data *data = container_of(xport, struct rmi_data, xport);
+	struct hid_device *hdev = data->hdev;
 	int ret;
 
 	mutex_lock(&data->page_mutex);
@@ -332,62 +286,20 @@ static int rmi_write_block(struct hid_device *hdev, u16 addr, void *buf,
 	return ret;
 }
 
-static inline int rmi_write(struct hid_device *hdev, u16 addr, void *buf)
-{
-	return rmi_write_block(hdev, addr, buf, 1);
-}
-
-static void rmi_f11_process_touch(struct rmi_data *hdata, int slot,
-		u8 finger_state, u8 *touch_data)
-{
-	int x, y, wx, wy;
-	int wide, major, minor;
-	int z;
-
-	input_mt_slot(hdata->input, slot);
-	input_mt_report_slot_state(hdata->input, MT_TOOL_FINGER,
-			finger_state == 0x01);
-	if (finger_state == 0x01) {
-		x = (touch_data[0] << 4) | (touch_data[2] & 0x0F);
-		y = (touch_data[1] << 4) | (touch_data[2] >> 4);
-		wx = touch_data[3] & 0x0F;
-		wy = touch_data[3] >> 4;
-		wide = (wx > wy);
-		major = max(wx, wy);
-		minor = min(wx, wy);
-		z = touch_data[4];
-
-		/* y is inverted */
-		y = hdata->max_y - y;
-
-		input_event(hdata->input, EV_ABS, ABS_MT_POSITION_X, x);
-		input_event(hdata->input, EV_ABS, ABS_MT_POSITION_Y, y);
-		input_event(hdata->input, EV_ABS, ABS_MT_ORIENTATION, wide);
-		input_event(hdata->input, EV_ABS, ABS_MT_PRESSURE, z);
-		input_event(hdata->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
-		input_event(hdata->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
-	}
-}
-
 static int rmi_reset_attn_mode(struct hid_device *hdev)
 {
 	struct rmi_data *data = hid_get_drvdata(hdev);
+	struct rmi_device *rmi_dev = data->xport.rmi_dev;
 	int ret;
 
 	ret = rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS);
 	if (ret)
 		return ret;
 
-	if (data->restore_interrupt_mask) {
-		ret = rmi_write(hdev, data->f01.control_base_addr + 1,
-				&data->interrupt_enable_mask);
-		if (ret) {
-			hid_err(hdev, "can not write F01 control register\n");
-			return ret;
-		}
-	}
+	if (test_bit(RMI_STARTED, &data->flags))
+		ret = rmi_dev->driver->reset_handler(rmi_dev);
 
-	return 0;
+	return ret;
 }
 
 static void rmi_reset_work(struct work_struct *work)
@@ -399,102 +311,22 @@ static void rmi_reset_work(struct work_struct *work)
 	rmi_reset_attn_mode(hdata->hdev);
 }
 
-static inline int rmi_schedule_reset(struct hid_device *hdev)
-{
-	struct rmi_data *hdata = hid_get_drvdata(hdev);
-	return schedule_work(&hdata->reset_work);
-}
-
-static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
-		int size)
-{
-	struct rmi_data *hdata = hid_get_drvdata(hdev);
-	int offset;
-	int i;
-
-	if (!(irq & hdata->f11.irq_mask) || size <= 0)
-		return 0;
-
-	offset = (hdata->max_fingers >> 2) + 1;
-	for (i = 0; i < hdata->max_fingers; i++) {
-		int fs_byte_position = i >> 2;
-		int fs_bit_position = (i & 0x3) << 1;
-		int finger_state = (data[fs_byte_position] >> fs_bit_position) &
-					0x03;
-		int position = offset + 5 * i;
-
-		if (position + 5 > size) {
-			/* partial report, go on with what we received */
-			printk_once(KERN_WARNING
-				"%s %s: Detected incomplete finger report. Finger reports may occasionally get dropped on this platform.\n",
-				 dev_driver_string(&hdev->dev),
-				 dev_name(&hdev->dev));
-			hid_dbg(hdev, "Incomplete finger report\n");
-			break;
-		}
-
-		rmi_f11_process_touch(hdata, i, finger_state, &data[position]);
-	}
-	input_mt_sync_frame(hdata->input);
-	input_sync(hdata->input);
-	return hdata->f11.report_size;
-}
-
-static int rmi_f30_input_event(struct hid_device *hdev, u8 irq, u8 *data,
-		int size)
+static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
 {
 	struct rmi_data *hdata = hid_get_drvdata(hdev);
-	int i;
-	int button = 0;
-	bool value;
+	struct rmi_device *rmi_dev = hdata->xport.rmi_dev;
+	unsigned long flags;
 
-	if (!(irq & hdata->f30.irq_mask))
+	if (!(test_bit(RMI_STARTED, &hdata->flags)))
 		return 0;
 
-	if (size < (int)hdata->f30.report_size) {
-		hid_warn(hdev, "Click Button pressed, but the click data is missing\n");
-		return 0;
-	}
+	local_irq_save(flags);
 
-	for (i = 0; i < hdata->gpio_led_count; i++) {
-		if (test_bit(i, &hdata->button_mask)) {
-			value = (data[i / 8] >> (i & 0x07)) & BIT(0);
-			if (test_bit(i, &hdata->button_state_mask))
-				value = !value;
-			input_event(hdata->input, EV_KEY, BTN_LEFT + button++,
-					value);
-		}
-	}
-	return hdata->f30.report_size;
-}
-
-static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
-{
-	struct rmi_data *hdata = hid_get_drvdata(hdev);
-	unsigned long irq_mask = 0;
-	unsigned index = 2;
+	rmi_set_attn_data(rmi_dev, data[1], &data[2], size - 2);
 
-	if (!(test_bit(RMI_STARTED, &hdata->flags)))
-		return 0;
+	generic_handle_irq(hdata->rmi_irq);
 
-	irq_mask |= hdata->f11.irq_mask;
-	irq_mask |= hdata->f30.irq_mask;
-
-	if (data[1] & ~irq_mask)
-		hid_dbg(hdev, "unknown intr source:%02lx %s:%d\n",
-			data[1] & ~irq_mask, __FILE__, __LINE__);
-
-	if (hdata->f11.interrupt_base < hdata->f30.interrupt_base) {
-		index += rmi_f11_input_event(hdev, data[1], &data[index],
-				size - index);
-		index += rmi_f30_input_event(hdev, data[1], &data[index],
-				size - index);
-	} else {
-		index += rmi_f30_input_event(hdev, data[1], &data[index],
-				size - index);
-		index += rmi_f11_input_event(hdev, data[1], &data[index],
-				size - index);
-	}
+	local_irq_restore(flags);
 
 	return 1;
 }
@@ -568,7 +400,7 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field,
 				return 1;
 		}
 
-		rmi_schedule_reset(hdev);
+		schedule_work(&data->reset_work);
 		return 1;
 	}
 
@@ -576,637 +408,71 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field,
 }
 
 #ifdef CONFIG_PM
-static int rmi_set_sleep_mode(struct hid_device *hdev, int sleep_mode)
-{
-	struct rmi_data *data = hid_get_drvdata(hdev);
-	int ret;
-	u8 f01_ctrl0;
-
-	f01_ctrl0 = (data->f01_ctrl0 & ~0x3) | sleep_mode;
-
-	ret = rmi_write(hdev, data->f01.control_base_addr,
-			&f01_ctrl0);
-	if (ret) {
-		hid_err(hdev, "can not write sleep mode\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 static int rmi_suspend(struct hid_device *hdev, pm_message_t message)
 {
 	struct rmi_data *data = hid_get_drvdata(hdev);
-	int ret;
-	u8 buf[RMI_F11_CTRL_REG_COUNT];
-
-	if (!(data->device_flags & RMI_DEVICE))
-		return 0;
-
-	ret = rmi_read_block(hdev, data->f11.control_base_addr, buf,
-				RMI_F11_CTRL_REG_COUNT);
-	if (ret)
-		hid_warn(hdev, "can not read F11 control registers\n");
-	else
-		memcpy(data->f11_ctrl_regs, buf, RMI_F11_CTRL_REG_COUNT);
-
-
-	if (!device_may_wakeup(hdev->dev.parent))
-		return rmi_set_sleep_mode(hdev, RMI_SLEEP_DEEP_SLEEP);
-
-	return 0;
-}
-
-static int rmi_post_reset(struct hid_device *hdev)
-{
-	struct rmi_data *data = hid_get_drvdata(hdev);
+	struct rmi_device *rmi_dev = data->xport.rmi_dev;
 	int ret;
 
 	if (!(data->device_flags & RMI_DEVICE))
 		return 0;
 
-	ret = rmi_reset_attn_mode(hdev);
+	ret = rmi_driver_suspend(rmi_dev, false);
 	if (ret) {
-		hid_err(hdev, "can not set rmi mode\n");
+		hid_warn(hdev, "Failed to suspend device: %d\n", ret);
 		return ret;
 	}
 
-	if (data->read_f11_ctrl_regs) {
-		ret = rmi_write_block(hdev, data->f11.control_base_addr,
-				data->f11_ctrl_regs, RMI_F11_CTRL_REG_COUNT);
-		if (ret)
-			hid_warn(hdev,
-				"can not write F11 control registers after reset\n");
-	}
-
-	if (!device_may_wakeup(hdev->dev.parent)) {
-		ret = rmi_set_sleep_mode(hdev, RMI_SLEEP_NORMAL);
-		if (ret) {
-			hid_err(hdev, "can not write sleep mode\n");
-			return ret;
-		}
-	}
-
-	return ret;
+	return 0;
 }
 
 static int rmi_post_resume(struct hid_device *hdev)
 {
 	struct rmi_data *data = hid_get_drvdata(hdev);
+	struct rmi_device *rmi_dev = data->xport.rmi_dev;
+	int ret;
 
 	if (!(data->device_flags & RMI_DEVICE))
 		return 0;
 
-	return rmi_reset_attn_mode(hdev);
-}
-#endif /* CONFIG_PM */
-
-#define RMI4_MAX_PAGE 0xff
-#define RMI4_PAGE_SIZE 0x0100
-
-#define PDT_START_SCAN_LOCATION 0x00e9
-#define PDT_END_SCAN_LOCATION	0x0005
-#define RMI4_END_OF_PDT(id) ((id) == 0x00 || (id) == 0xff)
-
-struct pdt_entry {
-	u8 query_base_addr:8;
-	u8 command_base_addr:8;
-	u8 control_base_addr:8;
-	u8 data_base_addr:8;
-	u8 interrupt_source_count:3;
-	u8 bits3and4:2;
-	u8 function_version:2;
-	u8 bit7:1;
-	u8 function_number:8;
-} __attribute__((__packed__));
-
-static inline unsigned long rmi_gen_mask(unsigned irq_base, unsigned irq_count)
-{
-	return GENMASK(irq_count + irq_base - 1, irq_base);
-}
-
-static void rmi_register_function(struct rmi_data *data,
-	struct pdt_entry *pdt_entry, int page, unsigned interrupt_count)
-{
-	struct rmi_function *f = NULL;
-	u16 page_base = page << 8;
-
-	switch (pdt_entry->function_number) {
-	case 0x01:
-		f = &data->f01;
-		break;
-	case 0x11:
-		f = &data->f11;
-		break;
-	case 0x30:
-		f = &data->f30;
-		break;
-	}
-
-	if (f) {
-		f->page = page;
-		f->query_base_addr = page_base | pdt_entry->query_base_addr;
-		f->command_base_addr = page_base | pdt_entry->command_base_addr;
-		f->control_base_addr = page_base | pdt_entry->control_base_addr;
-		f->data_base_addr = page_base | pdt_entry->data_base_addr;
-		f->interrupt_base = interrupt_count;
-		f->interrupt_count = pdt_entry->interrupt_source_count;
-		f->irq_mask = rmi_gen_mask(f->interrupt_base,
-						f->interrupt_count);
-		data->interrupt_enable_mask |= f->irq_mask;
-	}
-}
-
-static int rmi_scan_pdt(struct hid_device *hdev)
-{
-	struct rmi_data *data = hid_get_drvdata(hdev);
-	struct pdt_entry entry;
-	int page;
-	bool page_has_function;
-	int i;
-	int retval;
-	int interrupt = 0;
-	u16 page_start, pdt_start , pdt_end;
-
-	hid_info(hdev, "Scanning PDT...\n");
-
-	for (page = 0; (page <= RMI4_MAX_PAGE); page++) {
-		page_start = RMI4_PAGE_SIZE * page;
-		pdt_start = page_start + PDT_START_SCAN_LOCATION;
-		pdt_end = page_start + PDT_END_SCAN_LOCATION;
-
-		page_has_function = false;
-		for (i = pdt_start; i >= pdt_end; i -= sizeof(entry)) {
-			retval = rmi_read_block(hdev, i, &entry, sizeof(entry));
-			if (retval) {
-				hid_err(hdev,
-					"Read of PDT entry at %#06x failed.\n",
-					i);
-				goto error_exit;
-			}
-
-			if (RMI4_END_OF_PDT(entry.function_number))
-				break;
-
-			page_has_function = true;
-
-			hid_info(hdev, "Found F%02X on page %#04x\n",
-					entry.function_number, page);
-
-			rmi_register_function(data, &entry, page, interrupt);
-			interrupt += entry.interrupt_source_count;
-		}
-
-		if (!page_has_function)
-			break;
-	}
-
-	hid_info(hdev, "%s: Done with PDT scan.\n", __func__);
-	retval = 0;
-
-error_exit:
-	return retval;
-}
-
-#define RMI_DEVICE_F01_BASIC_QUERY_LEN	11
-
-static int rmi_populate_f01(struct hid_device *hdev)
-{
-	struct rmi_data *data = hid_get_drvdata(hdev);
-	u8 basic_queries[RMI_DEVICE_F01_BASIC_QUERY_LEN];
-	u8 info[3];
-	int ret;
-	bool has_query42;
-	bool has_lts;
-	bool has_sensor_id;
-	bool has_ds4_queries = false;
-	bool has_build_id_query = false;
-	bool has_package_id_query = false;
-	u16 query_offset = data->f01.query_base_addr;
-	u16 prod_info_addr;
-	u8 ds4_query_len;
-
-	ret = rmi_read_block(hdev, query_offset, basic_queries,
-				RMI_DEVICE_F01_BASIC_QUERY_LEN);
-	if (ret) {
-		hid_err(hdev, "Can not read basic queries from Function 0x1.\n");
-		return ret;
-	}
-
-	has_lts = !!(basic_queries[0] & BIT(2));
-	has_sensor_id = !!(basic_queries[1] & BIT(3));
-	has_query42 = !!(basic_queries[1] & BIT(7));
-
-	query_offset += 11;
-	prod_info_addr = query_offset + 6;
-	query_offset += 10;
-
-	if (has_lts)
-		query_offset += 20;
-
-	if (has_sensor_id)
-		query_offset++;
-
-	if (has_query42) {
-		ret = rmi_read(hdev, query_offset, info);
-		if (ret) {
-			hid_err(hdev, "Can not read query42.\n");
-			return ret;
-		}
-		has_ds4_queries = !!(info[0] & BIT(0));
-		query_offset++;
-	}
-
-	if (has_ds4_queries) {
-		ret = rmi_read(hdev, query_offset, &ds4_query_len);
-		if (ret) {
-			hid_err(hdev, "Can not read DS4 Query length.\n");
-			return ret;
-		}
-		query_offset++;
-
-		if (ds4_query_len > 0) {
-			ret = rmi_read(hdev, query_offset, info);
-			if (ret) {
-				hid_err(hdev, "Can not read DS4 query.\n");
-				return ret;
-			}
-
-			has_package_id_query = !!(info[0] & BIT(0));
-			has_build_id_query = !!(info[0] & BIT(1));
-		}
-	}
-
-	if (has_package_id_query)
-		prod_info_addr++;
-
-	if (has_build_id_query) {
-		ret = rmi_read_block(hdev, prod_info_addr, info, 3);
-		if (ret) {
-			hid_err(hdev, "Can not read product info.\n");
-			return ret;
-		}
-
-		data->firmware_id = info[1] << 8 | info[0];
-		data->firmware_id += info[2] * 65536;
-	}
-
-	ret = rmi_read_block(hdev, data->f01.control_base_addr, info,
-				2);
-
-	if (ret) {
-		hid_err(hdev, "can not read f01 ctrl registers\n");
-		return ret;
-	}
-
-	data->f01_ctrl0 = info[0];
-
-	if (!info[1]) {
-		/*
-		 * Do to a firmware bug in some touchpads the F01 interrupt
-		 * enable control register will be cleared on reset.
-		 * This will stop the touchpad from reporting data, so
-		 * if F01 CTRL1 is 0 then we need to explicitly enable
-		 * interrupts for the functions we want data for.
-		 */
-		data->restore_interrupt_mask = true;
-
-		ret = rmi_write(hdev, data->f01.control_base_addr + 1,
-				&data->interrupt_enable_mask);
-		if (ret) {
-			hid_err(hdev, "can not write to control reg 1: %d.\n",
-				ret);
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int rmi_populate_f11(struct hid_device *hdev)
-{
-	struct rmi_data *data = hid_get_drvdata(hdev);
-	u8 buf[20];
-	int ret;
-	bool has_query9;
-	bool has_query10 = false;
-	bool has_query11;
-	bool has_query12;
-	bool has_query27;
-	bool has_query28;
-	bool has_query36 = false;
-	bool has_physical_props;
-	bool has_gestures;
-	bool has_rel;
-	bool has_data40 = false;
-	bool has_dribble = false;
-	bool has_palm_detect = false;
-	unsigned x_size, y_size;
-	u16 query_offset;
-
-	if (!data->f11.query_base_addr) {
-		hid_err(hdev, "No 2D sensor found, giving up.\n");
-		return -ENODEV;
-	}
-
-	/* query 0 contains some useful information */
-	ret = rmi_read(hdev, data->f11.query_base_addr, buf);
-	if (ret) {
-		hid_err(hdev, "can not get query 0: %d.\n", ret);
-		return ret;
-	}
-	has_query9 = !!(buf[0] & BIT(3));
-	has_query11 = !!(buf[0] & BIT(4));
-	has_query12 = !!(buf[0] & BIT(5));
-	has_query27 = !!(buf[0] & BIT(6));
-	has_query28 = !!(buf[0] & BIT(7));
-
-	/* query 1 to get the max number of fingers */
-	ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf);
-	if (ret) {
-		hid_err(hdev, "can not get NumberOfFingers: %d.\n", ret);
-		return ret;
-	}
-	data->max_fingers = (buf[0] & 0x07) + 1;
-	if (data->max_fingers > 5)
-		data->max_fingers = 10;
-
-	data->f11.report_size = data->max_fingers * 5 +
-				DIV_ROUND_UP(data->max_fingers, 4);
-
-	if (!(buf[0] & BIT(4))) {
-		hid_err(hdev, "No absolute events, giving up.\n");
-		return -ENODEV;
-	}
-
-	has_rel = !!(buf[0] & BIT(3));
-	has_gestures = !!(buf[0] & BIT(5));
-
-	ret = rmi_read(hdev, data->f11.query_base_addr + 5, buf);
-	if (ret) {
-		hid_err(hdev, "can not get absolute data sources: %d.\n", ret);
+	ret = rmi_reset_attn_mode(hdev);
+	if (ret)
 		return ret;
-	}
-
-	has_dribble = !!(buf[0] & BIT(4));
-
-	/*
-	 * At least 4 queries are guaranteed to be present in F11
-	 * +1 for query 5 which is present since absolute events are
-	 * reported and +1 for query 12.
-	 */
-	query_offset = 6;
-
-	if (has_rel)
-		++query_offset; /* query 6 is present */
-
-	if (has_gestures) {
-		/* query 8 to find out if query 10 exists */
-		ret = rmi_read(hdev,
-			data->f11.query_base_addr + query_offset + 1, buf);
-		if (ret) {
-			hid_err(hdev, "can not read gesture information: %d.\n",
-				ret);
-			return ret;
-		}
-		has_palm_detect = !!(buf[0] & BIT(0));
-		has_query10 = !!(buf[0] & BIT(2));
-
-		query_offset += 2; /* query 7 and 8 are present */
-	}
-
-	if (has_query9)
-		++query_offset;
-
-	if (has_query10)
-		++query_offset;
-
-	if (has_query11)
-		++query_offset;
-
-	/* query 12 to know if the physical properties are reported */
-	if (has_query12) {
-		ret = rmi_read(hdev, data->f11.query_base_addr
-				+ query_offset, buf);
-		if (ret) {
-			hid_err(hdev, "can not get query 12: %d.\n", ret);
-			return ret;
-		}
-		has_physical_props = !!(buf[0] & BIT(5));
-
-		if (has_physical_props) {
-			query_offset += 1;
-			ret = rmi_read_block(hdev,
-					data->f11.query_base_addr
-						+ query_offset, buf, 4);
-			if (ret) {
-				hid_err(hdev, "can not read query 15-18: %d.\n",
-					ret);
-				return ret;
-			}
-
-			x_size = buf[0] | (buf[1] << 8);
-			y_size = buf[2] | (buf[3] << 8);
-
-			data->x_size_mm = DIV_ROUND_CLOSEST(x_size, 10);
-			data->y_size_mm = DIV_ROUND_CLOSEST(y_size, 10);
-
-			hid_info(hdev, "%s: size in mm: %d x %d\n",
-				 __func__, data->x_size_mm, data->y_size_mm);
-
-			/*
-			 * query 15 - 18 contain the size of the sensor
-			 * and query 19 - 26 contain bezel dimensions
-			 */
-			query_offset += 12;
-		}
-	}
-
-	if (has_query27)
-		++query_offset;
 
-	if (has_query28) {
-		ret = rmi_read(hdev, data->f11.query_base_addr
-				+ query_offset, buf);
-		if (ret) {
-			hid_err(hdev, "can not get query 28: %d.\n", ret);
-			return ret;
-		}
-
-		has_query36 = !!(buf[0] & BIT(6));
-	}
-
-	if (has_query36) {
-		query_offset += 2;
-		ret = rmi_read(hdev, data->f11.query_base_addr
-				+ query_offset, buf);
-		if (ret) {
-			hid_err(hdev, "can not get query 36: %d.\n", ret);
-			return ret;
-		}
-
-		has_data40 = !!(buf[0] & BIT(5));
-	}
-
-
-	if (has_data40)
-		data->f11.report_size += data->max_fingers * 2;
-
-	ret = rmi_read_block(hdev, data->f11.control_base_addr,
-			data->f11_ctrl_regs, RMI_F11_CTRL_REG_COUNT);
+	ret = rmi_driver_resume(rmi_dev, false);
 	if (ret) {
-		hid_err(hdev, "can not read ctrl block of size 11: %d.\n", ret);
+		hid_warn(hdev, "Failed to resume device: %d\n", ret);
 		return ret;
 	}
 
-	/* data->f11_ctrl_regs now contains valid register data */
-	data->read_f11_ctrl_regs = true;
-
-	data->max_x = data->f11_ctrl_regs[6] | (data->f11_ctrl_regs[7] << 8);
-	data->max_y = data->f11_ctrl_regs[8] | (data->f11_ctrl_regs[9] << 8);
-
-	if (has_dribble) {
-		data->f11_ctrl_regs[0] = data->f11_ctrl_regs[0] & ~BIT(6);
-		ret = rmi_write(hdev, data->f11.control_base_addr,
-				data->f11_ctrl_regs);
-		if (ret) {
-			hid_err(hdev, "can not write to control reg 0: %d.\n",
-				ret);
-			return ret;
-		}
-	}
-
-	if (has_palm_detect) {
-		data->f11_ctrl_regs[11] = data->f11_ctrl_regs[11] & ~BIT(0);
-		ret = rmi_write(hdev, data->f11.control_base_addr + 11,
-				&data->f11_ctrl_regs[11]);
-		if (ret) {
-			hid_err(hdev, "can not write to control reg 11: %d.\n",
-				ret);
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int rmi_populate_f30(struct hid_device *hdev)
-{
-	struct rmi_data *data = hid_get_drvdata(hdev);
-	u8 buf[20];
-	int ret;
-	bool has_gpio, has_led;
-	unsigned bytes_per_ctrl;
-	u8 ctrl2_addr;
-	int ctrl2_3_length;
-	int i;
-
-	/* function F30 is for physical buttons */
-	if (!data->f30.query_base_addr) {
-		hid_err(hdev, "No GPIO/LEDs found, giving up.\n");
-		return -ENODEV;
-	}
-
-	ret = rmi_read_block(hdev, data->f30.query_base_addr, buf, 2);
-	if (ret) {
-		hid_err(hdev, "can not get F30 query registers: %d.\n", ret);
-		return ret;
-	}
-
-	has_gpio = !!(buf[0] & BIT(3));
-	has_led = !!(buf[0] & BIT(2));
-	data->gpio_led_count = buf[1] & 0x1f;
-
-	/* retrieve ctrl 2 & 3 registers */
-	bytes_per_ctrl = (data->gpio_led_count + 7) / 8;
-	/* Ctrl0 is present only if both has_gpio and has_led are set*/
-	ctrl2_addr = (has_gpio && has_led) ? bytes_per_ctrl : 0;
-	/* Ctrl1 is always be present */
-	ctrl2_addr += bytes_per_ctrl;
-	ctrl2_3_length = 2 * bytes_per_ctrl;
-
-	data->f30.report_size = bytes_per_ctrl;
-
-	ret = rmi_read_block(hdev, data->f30.control_base_addr + ctrl2_addr,
-				buf, ctrl2_3_length);
-	if (ret) {
-		hid_err(hdev, "can not read ctrl 2&3 block of size %d: %d.\n",
-			ctrl2_3_length, ret);
-		return ret;
-	}
-
-	for (i = 0; i < data->gpio_led_count; i++) {
-		int byte_position = i >> 3;
-		int bit_position = i & 0x07;
-		u8 dir_byte = buf[byte_position];
-		u8 data_byte = buf[byte_position + bytes_per_ctrl];
-		bool dir = (dir_byte >> bit_position) & BIT(0);
-		bool dat = (data_byte >> bit_position) & BIT(0);
-
-		if (dir == 0) {
-			/* input mode */
-			if (dat) {
-				/* actual buttons have pull up resistor */
-				data->button_count++;
-				set_bit(i, &data->button_mask);
-				set_bit(i, &data->button_state_mask);
-			}
-		}
-
-	}
-
 	return 0;
 }
+#endif /* CONFIG_PM */
 
-static int rmi_populate(struct hid_device *hdev)
+static int rmi_hid_reset(struct rmi_transport_dev *xport, u16 reset_addr)
 {
-	struct rmi_data *data = hid_get_drvdata(hdev);
-	int ret;
-
-	ret = rmi_scan_pdt(hdev);
-	if (ret) {
-		hid_err(hdev, "PDT scan failed with code %d.\n", ret);
-		return ret;
-	}
-
-	ret = rmi_populate_f01(hdev);
-	if (ret) {
-		hid_err(hdev, "Error while initializing F01 (%d).\n", ret);
-		return ret;
-	}
-
-	ret = rmi_populate_f11(hdev);
-	if (ret) {
-		hid_err(hdev, "Error while initializing F11 (%d).\n", ret);
-		return ret;
-	}
-
-	if (!(data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS)) {
-		ret = rmi_populate_f30(hdev);
-		if (ret)
-			hid_warn(hdev, "Error while initializing F30 (%d).\n", ret);
-	}
+	struct rmi_data *data = container_of(xport, struct rmi_data, xport);
+	struct hid_device *hdev = data->hdev;
 
-	return 0;
+	return rmi_reset_attn_mode(hdev);
 }
 
 static int rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
 {
 	struct rmi_data *data = hid_get_drvdata(hdev);
 	struct input_dev *input = hi->input;
-	int ret;
-	int res_x, res_y, i;
+	int ret = 0;
+
+	if (!(data->device_flags & RMI_DEVICE))
+		return 0;
 
-	data->input = input;
+	data->xport.input = input;
 
 	hid_dbg(hdev, "Opening low level driver\n");
 	ret = hid_hw_open(hdev);
 	if (ret)
 		return ret;
 
-	if (!(data->device_flags & RMI_DEVICE))
-		return 0;
-
 	/* Allow incoming hid reports */
 	hid_device_io_start(hdev);
 
@@ -1222,40 +488,10 @@ static int rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
 		goto exit;
 	}
 
-	ret = rmi_populate(hdev);
-	if (ret)
-		goto exit;
-
-	hid_info(hdev, "firmware id: %ld\n", data->firmware_id);
-
-	__set_bit(EV_ABS, input->evbit);
-	input_set_abs_params(input, ABS_MT_POSITION_X, 1, data->max_x, 0, 0);
-	input_set_abs_params(input, ABS_MT_POSITION_Y, 1, data->max_y, 0, 0);
-
-	if (data->x_size_mm && data->y_size_mm) {
-		res_x = (data->max_x - 1) / data->x_size_mm;
-		res_y = (data->max_y - 1) / data->y_size_mm;
-
-		input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
-		input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
-	}
-
-	input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
-	input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
-	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
-	input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
-
-	ret = input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER);
-	if (ret < 0)
+	ret = rmi_register_transport_device(&data->xport);
+	if (ret < 0) {
+		dev_err(&hdev->dev, "failed to register transport driver\n");
 		goto exit;
-
-	if (data->button_count) {
-		__set_bit(EV_KEY, input->evbit);
-		for (i = 0; i < data->button_count; i++)
-			__set_bit(BTN_LEFT + i, input->keybit);
-
-		if (data->button_count == 1)
-			__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 	}
 
 	set_bit(RMI_STARTED, &data->flags);
@@ -1304,6 +540,71 @@ static int rmi_check_valid_report_id(struct hid_device *hdev, unsigned type,
 	return 0;
 }
 
+static struct rmi_device_platform_data rmi_hid_pdata = {
+	.sensor_pdata = {
+		.sensor_type = rmi_sensor_touchpad,
+		.axis_align.flip_y = true,
+		.dribble = RMI_REG_STATE_ON,
+		.palm_detect = RMI_REG_STATE_OFF,
+	},
+};
+
+static const struct rmi_transport_ops hid_rmi_ops = {
+	.write_block	= rmi_hid_write_block,
+	.read_block	= rmi_hid_read_block,
+	.reset		= rmi_hid_reset,
+};
+
+static void rmi_irq_teardown(void *data)
+{
+	struct rmi_data *hdata = data;
+	struct irq_domain *domain = hdata->domain;
+
+	if (!domain)
+		return;
+
+	irq_dispose_mapping(irq_find_mapping(domain, 0));
+
+	irq_domain_remove(domain);
+	hdata->domain = NULL;
+	hdata->rmi_irq = 0;
+}
+
+static int rmi_irq_map(struct irq_domain *h, unsigned int virq,
+		       irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq);
+
+	return 0;
+}
+
+static const struct irq_domain_ops rmi_irq_ops = {
+	.map = rmi_irq_map,
+};
+
+static int rmi_setup_irq_domain(struct hid_device *hdev)
+{
+	struct rmi_data *hdata = hid_get_drvdata(hdev);
+	int ret;
+
+	hdata->domain = irq_domain_create_linear(hdev->dev.fwnode, 1,
+						 &rmi_irq_ops, hdata);
+	if (!hdata->domain)
+		return -ENOMEM;
+
+	ret = devm_add_action_or_reset(&hdev->dev, &rmi_irq_teardown, hdata);
+	if (ret)
+		return ret;
+
+	hdata->rmi_irq = irq_create_mapping(hdata->domain, 0);
+	if (hdata->rmi_irq <= 0) {
+		hid_err(hdev, "Can't allocate an IRQ\n");
+		return hdata->rmi_irq < 0 ? hdata->rmi_irq : -ENXIO;
+	}
+
+	return 0;
+}
+
 static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	struct rmi_data *data = NULL;
@@ -1365,8 +666,8 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL);
 	if (!data->writeReport) {
-		ret = -ENOMEM;
-		return ret;
+		hid_err(hdev, "failed to allocate buffer for HID reports\n");
+		return -ENOMEM;
 	}
 
 	data->readReport = data->writeReport + data->output_report_size;
@@ -1375,6 +676,21 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	mutex_init(&data->page_mutex);
 
+	ret = rmi_setup_irq_domain(hdev);
+	if (ret) {
+		hid_err(hdev, "failed to allocate IRQ domain\n");
+		return ret;
+	}
+
+	if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS)
+		rmi_hid_pdata.f30_data.disable = true;
+
+	data->xport.dev = hdev->dev.parent;
+	data->xport.pdata = rmi_hid_pdata;
+	data->xport.pdata.irq = data->rmi_irq;
+	data->xport.proto_name = "hid";
+	data->xport.ops = &hid_rmi_ops;
+
 start:
 	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 	if (ret) {
@@ -1382,17 +698,6 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		return ret;
 	}
 
-	if ((data->device_flags & RMI_DEVICE) &&
-	    !test_bit(RMI_STARTED, &data->flags))
-		/*
-		 * The device maybe in the bootloader if rmi_input_configured
-		 * failed to find F11 in the PDT. Print an error, but don't
-		 * return an error from rmi_probe so that hidraw will be
-		 * accessible from userspace. That way a userspace tool
-		 * can be used to reload working firmware on the touchpad.
-		 */
-		hid_err(hdev, "Device failed to be properly configured\n");
-
 	return 0;
 }
 
@@ -1401,6 +706,8 @@ static void rmi_remove(struct hid_device *hdev)
 	struct rmi_data *hdata = hid_get_drvdata(hdev);
 
 	clear_bit(RMI_STARTED, &hdata->flags);
+	cancel_work_sync(&hdata->reset_work);
+	rmi_unregister_transport_device(&hdata->xport);
 
 	hid_hw_stop(hdev);
 }
@@ -1425,7 +732,7 @@ static struct hid_driver rmi_driver = {
 #ifdef CONFIG_PM
 	.suspend		= rmi_suspend,
 	.resume			= rmi_post_resume,
-	.reset_resume		= rmi_post_reset,
+	.reset_resume		= rmi_post_resume,
 #endif
 };
 
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1534869 — [PATCH v2 2/7] Input: synaptics-rmi4 - F03: grab data passed by transport device

FromBenjamin Tissoires <benjamin.tissoires@redhat.com>
Date2016-12-02 12:50 +0100
Subject[PATCH v2 2/7] Input: synaptics-rmi4 - F03: grab data passed by transport device
Message-ID<sJUvM-3hJ-29@gated-at.bofh.it>
In reply to#1534865
From: Dennis Wassenberg <dennis.wassenberg@secunet.com>

First check if there are data available passed by the transport device.
If data available use these data. If there are no data available
try to read the rmi block if dsata are passed this way.

This is the way the other rmi function handlers will do this.

This patch is needed on HID devices because the firmware reads F03 data
registers and adds them to the HID attention report. Reading those
registers from the driver after the firmware read them will result in
invalid data.

Reviewed-by: Andrew Duggan <aduggan@synaptics.com>
Signed-off-by: Dennis Wassenberg <dennis.wassenberg@secunet.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

no changes in v2
---
 drivers/input/rmi4/rmi_f03.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
index fd8f6e5..06279cd 100644
--- a/drivers/input/rmi4/rmi_f03.c
+++ b/drivers/input/rmi4/rmi_f03.c
@@ -165,6 +165,7 @@ static int rmi_f03_config(struct rmi_function *fn)
 
 static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
 {
+	struct rmi_device *rmi_dev = fn->rmi_dev;
 	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
 	u16 data_addr = fn->fd.data_base_addr;
 	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
@@ -173,16 +174,32 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
 	u8 ob_data;
 	unsigned int serio_flags;
 	int i;
-	int retval;
-
-	/* Grab all of the data registers, and check them for data */
-	retval = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
-				&obs, ob_len);
-	if (retval) {
-		dev_err(&fn->dev, "%s: Failed to read F03 output buffers.\n",
-			__func__);
-		serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
-		return retval;
+	int ret;
+
+	if (!rmi_dev || !rmi_dev->xport)
+		return -ENODEV;
+
+	if (rmi_dev->xport->attn_data) {
+		/* First grab the data passed by the transport device */
+		if (rmi_dev->xport->attn_size < ob_len) {
+			dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
+			return 0;
+		}
+
+		memcpy(obs, rmi_dev->xport->attn_data, ob_len);
+
+		rmi_dev->xport->attn_data += ob_len;
+		rmi_dev->xport->attn_size -= ob_len;
+	} else {
+		/* Grab all of the data registers, and check them for data */
+		ret = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
+				     &obs, ob_len);
+		if (ret) {
+			dev_err(&fn->dev, "%s: Failed to read F03 output buffers.\n",
+				__func__);
+			serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
+			return ret;
+		}
 	}
 
 	for (i = 0; i < ob_len; i += RMI_F03_OB_SIZE) {
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1534871 — [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data

FromBenjamin Tissoires <benjamin.tissoires@redhat.com>
Date2016-12-02 12:50 +0100
Subject[PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data
Message-ID<sJUvM-3hJ-33@gated-at.bofh.it>
In reply to#1534865
The HID implementation of RMI4 provides the data during
the interrupt (in the input report). We need to provide
a way for this transport driver to provide the attention
data while calling an IRQ.

We use a fifo in rmi_core to not lose any incoming event.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

no changes in v2
---
 drivers/input/rmi4/rmi_driver.c | 49 +++++++++++++++++++++++++++++++++++++++--
 include/linux/rmi.h             | 11 +++++++++
 2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index a718e51..85062e4 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -191,16 +191,53 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
 	return 0;
 }
 
+void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
+		       void *data, size_t size)
+{
+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
+	struct rmi4_attn_data attn_data;
+	void *fifo_data;
+
+	if (!drvdata->enabled)
+		return;
+
+	fifo_data = kmemdup(data, size, GFP_ATOMIC);
+	if (!fifo_data)
+		return;
+
+	attn_data.irq_status = irq_status;
+	attn_data.size = size;
+	attn_data.data = fifo_data;
+
+	kfifo_put(&drvdata->attn_fifo, attn_data);
+}
+EXPORT_SYMBOL_GPL(rmi_set_attn_data);
+
 static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
 {
 	struct rmi_device *rmi_dev = dev_id;
-	int ret;
+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
+	struct rmi4_attn_data attn_data = {0};
+	int ret, count;
+
+	count = kfifo_get(&drvdata->attn_fifo, &attn_data);
+	if (count) {
+		*(drvdata->irq_status) = attn_data.irq_status;
+		rmi_dev->xport->attn_data = attn_data.data;
+		rmi_dev->xport->attn_size = attn_data.size;
+	}
 
 	ret = rmi_process_interrupt_requests(rmi_dev);
 	if (ret)
 		rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
 			"Failed to process interrupt request: %d\n", ret);
 
+	if (count)
+		kfree(attn_data.data);
+
+	if (!kfifo_is_empty(&drvdata->attn_fifo))
+		return rmi_irq_fn(irq, dev_id);
+
 	return IRQ_HANDLED;
 }
 
@@ -880,8 +917,9 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
 {
 	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
 	struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
+	struct rmi4_attn_data attn_data = {0};
 	int irq = pdata->irq;
-	int retval;
+	int retval, count;
 
 	mutex_lock(&data->enabled_mutex);
 
@@ -898,6 +936,13 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
 				 retval);
 	}
 
+	/* make sure the fifo is clean */
+	while (!kfifo_is_empty(&data->attn_fifo)) {
+		count = kfifo_get(&data->attn_fifo, &attn_data);
+		if (count)
+			kfree(attn_data.data);
+	}
+
 out:
 	mutex_unlock(&data->enabled_mutex);
 }
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 7780e40..1d48656 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/kfifo.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -331,6 +332,12 @@ struct rmi_device {
 
 };
 
+struct rmi4_attn_data {
+	unsigned long irq_status;
+	size_t size;
+	void *data;
+};
+
 struct rmi_driver_data {
 	struct list_head function_list;
 
@@ -357,11 +364,15 @@ struct rmi_driver_data {
 
 	bool enabled;
 	struct mutex enabled_mutex;
+	DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
 };
 
 int rmi_register_transport_device(struct rmi_transport_dev *xport);
 void rmi_unregister_transport_device(struct rmi_transport_dev *xport);
 
+void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
+		       void *data, size_t size);
+
 int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake);
 int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake);
 #endif
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1535282 — Re: [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data

FromAndrew Duggan <aduggan@synaptics.com>
Date2016-12-03 01:50 +0100
SubjectRe: [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data
Message-ID<sK6GB-2yg-11@gated-at.bofh.it>
In reply to#1534871
On 12/02/2016 03:41 AM, Benjamin Tissoires wrote:
> The HID implementation of RMI4 provides the data during
> the interrupt (in the input report). We need to provide
> a way for this transport driver to provide the attention
> data while calling an IRQ.
>
> We use a fifo in rmi_core to not lose any incoming event.
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Reviewed-by: Andrew Duggan <aduggan@synaptics.com>

> ---
>
> no changes in v2
> ---
>   drivers/input/rmi4/rmi_driver.c | 49 +++++++++++++++++++++++++++++++++++++++--
>   include/linux/rmi.h             | 11 +++++++++
>   2 files changed, 58 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index a718e51..85062e4 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -191,16 +191,53 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
>   	return 0;
>   }
>   
> +void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
> +		       void *data, size_t size)
> +{
> +	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> +	struct rmi4_attn_data attn_data;
> +	void *fifo_data;
> +
> +	if (!drvdata->enabled)
> +		return;
> +
> +	fifo_data = kmemdup(data, size, GFP_ATOMIC);
> +	if (!fifo_data)
> +		return;
> +
> +	attn_data.irq_status = irq_status;
> +	attn_data.size = size;
> +	attn_data.data = fifo_data;
> +
> +	kfifo_put(&drvdata->attn_fifo, attn_data);
> +}
> +EXPORT_SYMBOL_GPL(rmi_set_attn_data);
> +
>   static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
>   {
>   	struct rmi_device *rmi_dev = dev_id;
> -	int ret;
> +	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> +	struct rmi4_attn_data attn_data = {0};
> +	int ret, count;
> +
> +	count = kfifo_get(&drvdata->attn_fifo, &attn_data);
> +	if (count) {
> +		*(drvdata->irq_status) = attn_data.irq_status;
> +		rmi_dev->xport->attn_data = attn_data.data;
> +		rmi_dev->xport->attn_size = attn_data.size;
> +	}
>   
>   	ret = rmi_process_interrupt_requests(rmi_dev);
>   	if (ret)
>   		rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
>   			"Failed to process interrupt request: %d\n", ret);
>   
> +	if (count)
> +		kfree(attn_data.data);
> +
> +	if (!kfifo_is_empty(&drvdata->attn_fifo))
> +		return rmi_irq_fn(irq, dev_id);
> +
>   	return IRQ_HANDLED;
>   }
>   
> @@ -880,8 +917,9 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
>   {
>   	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
>   	struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> +	struct rmi4_attn_data attn_data = {0};
>   	int irq = pdata->irq;
> -	int retval;
> +	int retval, count;
>   
>   	mutex_lock(&data->enabled_mutex);
>   
> @@ -898,6 +936,13 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
>   				 retval);
>   	}
>   
> +	/* make sure the fifo is clean */
> +	while (!kfifo_is_empty(&data->attn_fifo)) {
> +		count = kfifo_get(&data->attn_fifo, &attn_data);
> +		if (count)
> +			kfree(attn_data.data);
> +	}
> +
>   out:
>   	mutex_unlock(&data->enabled_mutex);
>   }
> diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> index 7780e40..1d48656 100644
> --- a/include/linux/rmi.h
> +++ b/include/linux/rmi.h
> @@ -13,6 +13,7 @@
>   #include <linux/device.h>
>   #include <linux/interrupt.h>
>   #include <linux/input.h>
> +#include <linux/kfifo.h>
>   #include <linux/list.h>
>   #include <linux/module.h>
>   #include <linux/types.h>
> @@ -331,6 +332,12 @@ struct rmi_device {
>   
>   };
>   
> +struct rmi4_attn_data {
> +	unsigned long irq_status;
> +	size_t size;
> +	void *data;
> +};
> +
>   struct rmi_driver_data {
>   	struct list_head function_list;
>   
> @@ -357,11 +364,15 @@ struct rmi_driver_data {
>   
>   	bool enabled;
>   	struct mutex enabled_mutex;
> +	DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
>   };
>   
>   int rmi_register_transport_device(struct rmi_transport_dev *xport);
>   void rmi_unregister_transport_device(struct rmi_transport_dev *xport);
>   
> +void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
> +		       void *data, size_t size);
> +
>   int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake);
>   int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake);
>   #endif

[toc] | [prev] | [next] | [standalone]


#1535479 — Re: [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2016-12-03 19:30 +0100
SubjectRe: [PATCH v2 3/7] Input: synaptics-rmi4 - allow to add attention data
Message-ID<sKneq-4OU-17@gated-at.bofh.it>
In reply to#1535282
On Fri, Dec 02, 2016 at 04:33:56PM -0800, Andrew Duggan wrote:
> On 12/02/2016 03:41 AM, Benjamin Tissoires wrote:
> >The HID implementation of RMI4 provides the data during
> >the interrupt (in the input report). We need to provide
> >a way for this transport driver to provide the attention
> >data while calling an IRQ.
> >
> >We use a fifo in rmi_core to not lose any incoming event.
> >
> >Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> 
> Reviewed-by: Andrew Duggan <aduggan@synaptics.com>

Applied, thank you.

> 
> >---
> >
> >no changes in v2
> >---
> >  drivers/input/rmi4/rmi_driver.c | 49 +++++++++++++++++++++++++++++++++++++++--
> >  include/linux/rmi.h             | 11 +++++++++
> >  2 files changed, 58 insertions(+), 2 deletions(-)
> >
> >diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> >index a718e51..85062e4 100644
> >--- a/drivers/input/rmi4/rmi_driver.c
> >+++ b/drivers/input/rmi4/rmi_driver.c
> >@@ -191,16 +191,53 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
> >  	return 0;
> >  }
> >+void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
> >+		       void *data, size_t size)
> >+{
> >+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> >+	struct rmi4_attn_data attn_data;
> >+	void *fifo_data;
> >+
> >+	if (!drvdata->enabled)
> >+		return;
> >+
> >+	fifo_data = kmemdup(data, size, GFP_ATOMIC);
> >+	if (!fifo_data)
> >+		return;
> >+
> >+	attn_data.irq_status = irq_status;
> >+	attn_data.size = size;
> >+	attn_data.data = fifo_data;
> >+
> >+	kfifo_put(&drvdata->attn_fifo, attn_data);
> >+}
> >+EXPORT_SYMBOL_GPL(rmi_set_attn_data);
> >+
> >  static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
> >  {
> >  	struct rmi_device *rmi_dev = dev_id;
> >-	int ret;
> >+	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
> >+	struct rmi4_attn_data attn_data = {0};
> >+	int ret, count;
> >+
> >+	count = kfifo_get(&drvdata->attn_fifo, &attn_data);
> >+	if (count) {
> >+		*(drvdata->irq_status) = attn_data.irq_status;
> >+		rmi_dev->xport->attn_data = attn_data.data;
> >+		rmi_dev->xport->attn_size = attn_data.size;
> >+	}
> >  	ret = rmi_process_interrupt_requests(rmi_dev);
> >  	if (ret)
> >  		rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
> >  			"Failed to process interrupt request: %d\n", ret);
> >+	if (count)
> >+		kfree(attn_data.data);
> >+
> >+	if (!kfifo_is_empty(&drvdata->attn_fifo))
> >+		return rmi_irq_fn(irq, dev_id);
> >+
> >  	return IRQ_HANDLED;
> >  }
> >@@ -880,8 +917,9 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
> >  {
> >  	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
> >  	struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> >+	struct rmi4_attn_data attn_data = {0};
> >  	int irq = pdata->irq;
> >-	int retval;
> >+	int retval, count;
> >  	mutex_lock(&data->enabled_mutex);
> >@@ -898,6 +936,13 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
> >  				 retval);
> >  	}
> >+	/* make sure the fifo is clean */
> >+	while (!kfifo_is_empty(&data->attn_fifo)) {
> >+		count = kfifo_get(&data->attn_fifo, &attn_data);
> >+		if (count)
> >+			kfree(attn_data.data);
> >+	}
> >+
> >  out:
> >  	mutex_unlock(&data->enabled_mutex);
> >  }
> >diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> >index 7780e40..1d48656 100644
> >--- a/include/linux/rmi.h
> >+++ b/include/linux/rmi.h
> >@@ -13,6 +13,7 @@
> >  #include <linux/device.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/input.h>
> >+#include <linux/kfifo.h>
> >  #include <linux/list.h>
> >  #include <linux/module.h>
> >  #include <linux/types.h>
> >@@ -331,6 +332,12 @@ struct rmi_device {
> >  };
> >+struct rmi4_attn_data {
> >+	unsigned long irq_status;
> >+	size_t size;
> >+	void *data;
> >+};
> >+
> >  struct rmi_driver_data {
> >  	struct list_head function_list;
> >@@ -357,11 +364,15 @@ struct rmi_driver_data {
> >  	bool enabled;
> >  	struct mutex enabled_mutex;
> >+	DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
> >  };
> >  int rmi_register_transport_device(struct rmi_transport_dev *xport);
> >  void rmi_unregister_transport_device(struct rmi_transport_dev *xport);
> >+void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
> >+		       void *data, size_t size);
> >+
> >  int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake);
> >  int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake);
> >  #endif
> 
> 

-- 
Dmitry

[toc] | [prev] | [next] | [standalone]


#1535285

FromAndrew Duggan <aduggan@synaptics.com>
Date2016-12-03 01:50 +0100
Message-ID<sK6GB-2yg-3@gated-at.bofh.it>
In reply to#1534865
Hi Benjamin,

Thanks for adding the irq handling to hid-rmi and fifo support in the core.

On 12/02/2016 03:41 AM, Benjamin Tissoires wrote:
> Hi,
>
> Well, the cleanup part of the series has already been applied, so
> I guess this is just "switch hid-rmi to rmi_core".
>
> The series applies on top of Dmitri's synaptics-rmi4 branch
>
> However, as mentioned in v1, I'd like to get some testings from actually
> integrated devices befor we flip the switch for HID. Andrew, Dennis?

Tested on a Dell XPS 13 9343 and a Lenovo S21e. That covers the two 
generations of our HID touchpads which have gone into production.

Andrew

> Function f03 has been tested in the rmi4-smbus, and the attn data API
> on a test synaptics board.
>
> Cheers,
> Benjamin
>
> Andrew Duggan (3):
>    HID: rmi: Make hid-rmi a transport driver for synaptics-rmi4
>    HID: rmi: Handle all Synaptics touchpads using hid-rmi
>    HID: rmi: Support the Lenovo Thinkpad X1 Tablet dock using hid-rmi
>
> Benjamin Tissoires (2):
>    Input: synaptics-rmi4 - allow to add attention data
>    Input: synaptics-rmi4 - store the attn data in the driver
>
> Dennis Wassenberg (1):
>    Input: synaptics-rmi4 - F03: grab data passed by transport device
>
> Lyude Paul (1):
>    Input: synaptics-rmi4 - add support for F03
>
>   drivers/hid/Kconfig             |   4 +
>   drivers/hid/hid-core.c          |   4 +-
>   drivers/hid/hid-ids.h           |   1 +
>   drivers/hid/hid-rmi.c           | 974 ++++++----------------------------------
>   drivers/input/rmi4/Kconfig      |   9 +
>   drivers/input/rmi4/Makefile     |   1 +
>   drivers/input/rmi4/rmi_bus.c    |   3 +
>   drivers/input/rmi4/rmi_driver.c |  50 ++-
>   drivers/input/rmi4/rmi_driver.h |   1 +
>   drivers/input/rmi4/rmi_f03.c    | 251 +++++++++++
>   drivers/input/rmi4/rmi_f11.c    |  12 +-
>   drivers/input/rmi4/rmi_f12.c    |  43 +-
>   drivers/input/rmi4/rmi_f30.c    |  11 +-
>   include/linux/rmi.h             |  16 +-
>   14 files changed, 508 insertions(+), 872 deletions(-)
>   create mode 100644 drivers/input/rmi4/rmi_f03.c
>

[toc] | [prev] | [next] | [standalone]


#1535485

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2016-12-03 19:40 +0100
Message-ID<sKno6-4RX-33@gated-at.bofh.it>
In reply to#1534865
On Fri, Dec 02, 2016 at 12:41:49PM +0100, Benjamin Tissoires wrote:
> Hi,
> 
> Well, the cleanup part of the series has already been applied, so
> I guess this is just "switch hid-rmi to rmi_core".
> 
> The series applies on top of Dmitri's synaptics-rmi4 branch
> 
> However, as mentioned in v1, I'd like to get some testings from actually
> integrated devices befor we flip the switch for HID. Andrew, Dennis?
> 
> Function f03 has been tested in the rmi4-smbus, and the attn data API
> on a test synaptics board.

So I applied all Synaptics changes to my synaptics-rmi4 branch, but what
do we do with HID changes? Jiri, do you want to pull this branch or do
you want me to apply HID changes? Or wait for the next cycle?

Thanks.

-- 
Dmitry

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web