All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Input: pixcir_i2c_ts: Add Type-B Multi-touch and DT support
@ 2014-02-26 15:27 ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:27 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Hi,

This series does the following

- use devres managed resource allocations
- convert to Type-B multi touch protocol
- support upto 5 fingers with hardware supplied tracking IDs
- device tree support

Changelog:

v2:
- Addressed review comments and re-arranged patch order

v1:
- http://article.gmane.org/gmane.linux.kernel/1616417

cheers,
-roger

---
Roger Quadros (8):
  Input: pixcir_i2c_ts: Use devres managed resource allocations
  Input: pixcir_i2c_ts: Initialize interrupt mode and power mode
  Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
  Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided
    tracking IDs
  Input: pixcir_i2c_ts: Implement wakeup from suspend
  Input: pixcir_i2c_ts: Add device tree support
  ARM: dts: am43x-epos-evm: Correct Touch controller info

 .../bindings/input/touchscreen/pixcir_i2c_ts.txt   |  26 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/boot/dts/am43x-epos-evm.dts               |  13 +-
 drivers/input/touchscreen/pixcir_i2c_ts.c          | 510 ++++++++++++++++++---
 include/linux/input/pixcir_ts.h                    |  56 ++-
 5 files changed, 545 insertions(+), 61 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt

-- 
1.8.3.2


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

* [PATCH v2 0/8] Input: pixcir_i2c_ts: Add Type-B Multi-touch and DT support
@ 2014-02-26 15:27 ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:27 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Hi,

This series does the following

- use devres managed resource allocations
- convert to Type-B multi touch protocol
- support upto 5 fingers with hardware supplied tracking IDs
- device tree support

Changelog:

v2:
- Addressed review comments and re-arranged patch order

v1:
- http://article.gmane.org/gmane.linux.kernel/1616417

cheers,
-roger

---
Roger Quadros (8):
  Input: pixcir_i2c_ts: Use devres managed resource allocations
  Input: pixcir_i2c_ts: Initialize interrupt mode and power mode
  Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
  Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided
    tracking IDs
  Input: pixcir_i2c_ts: Implement wakeup from suspend
  Input: pixcir_i2c_ts: Add device tree support
  ARM: dts: am43x-epos-evm: Correct Touch controller info

 .../bindings/input/touchscreen/pixcir_i2c_ts.txt   |  26 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/boot/dts/am43x-epos-evm.dts               |  13 +-
 drivers/input/touchscreen/pixcir_i2c_ts.c          | 510 ++++++++++++++++++---
 include/linux/input/pixcir_ts.h                    |  56 ++-
 5 files changed, 545 insertions(+), 61 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt

-- 
1.8.3.2

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

* [PATCH v2 1/8] Input: pixcir_i2c_ts: Use devres managed resource allocations
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:27   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:27 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Use devm_() and friends for allocating memory, input device
and IRQ.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 34 ++++++++++++-------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 02392d2..38e83a2 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -130,6 +130,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 {
 	const struct pixcir_ts_platform_data *pdata =
 			dev_get_platdata(&client->dev);
+	struct device *dev = &client->dev;
 	struct pixcir_i2c_ts_data *tsdata;
 	struct input_dev *input;
 	int error;
@@ -139,12 +140,14 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
-	input = input_allocate_device();
-	if (!tsdata || !input) {
-		dev_err(&client->dev, "Failed to allocate driver data!\n");
-		error = -ENOMEM;
-		goto err_free_mem;
+	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
+	if (!tsdata)
+		return -ENOMEM;
+
+	input = devm_input_allocate_device(dev);
+	if (!input) {
+		dev_err(&client->dev, "Failed to allocate input device\n");
+		return -ENOMEM;
 	}
 
 	tsdata->client = client;
@@ -165,29 +168,22 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 
 	input_set_drvdata(input, tsdata);
 
-	error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr,
+	error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
 				     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 				     client->name, tsdata);
 	if (error) {
-		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
-		goto err_free_mem;
+		dev_err(dev, "failed to request irq %d\n", client->irq);
+		return error;
 	}
 
 	error = input_register_device(input);
 	if (error)
-		goto err_free_irq;
+		return error;
 
 	i2c_set_clientdata(client, tsdata);
 	device_init_wakeup(&client->dev, 1);
 
 	return 0;
-
-err_free_irq:
-	free_irq(client->irq, tsdata);
-err_free_mem:
-	input_free_device(input);
-	kfree(tsdata);
-	return error;
 }
 
 static int pixcir_i2c_ts_remove(struct i2c_client *client)
@@ -198,10 +194,6 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 	tsdata->exiting = true;
 	mb();
-	free_irq(client->irq, tsdata);
-
-	input_unregister_device(tsdata->input);
-	kfree(tsdata);
 
 	return 0;
 }
-- 
1.8.3.2


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

* [PATCH v2 1/8] Input: pixcir_i2c_ts: Use devres managed resource allocations
@ 2014-02-26 15:27   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:27 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Use devm_() and friends for allocating memory, input device
and IRQ.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 34 ++++++++++++-------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 02392d2..38e83a2 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -130,6 +130,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 {
 	const struct pixcir_ts_platform_data *pdata =
 			dev_get_platdata(&client->dev);
+	struct device *dev = &client->dev;
 	struct pixcir_i2c_ts_data *tsdata;
 	struct input_dev *input;
 	int error;
@@ -139,12 +140,14 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
-	input = input_allocate_device();
-	if (!tsdata || !input) {
-		dev_err(&client->dev, "Failed to allocate driver data!\n");
-		error = -ENOMEM;
-		goto err_free_mem;
+	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
+	if (!tsdata)
+		return -ENOMEM;
+
+	input = devm_input_allocate_device(dev);
+	if (!input) {
+		dev_err(&client->dev, "Failed to allocate input device\n");
+		return -ENOMEM;
 	}
 
 	tsdata->client = client;
@@ -165,29 +168,22 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 
 	input_set_drvdata(input, tsdata);
 
-	error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr,
+	error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
 				     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 				     client->name, tsdata);
 	if (error) {
-		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
-		goto err_free_mem;
+		dev_err(dev, "failed to request irq %d\n", client->irq);
+		return error;
 	}
 
 	error = input_register_device(input);
 	if (error)
-		goto err_free_irq;
+		return error;
 
 	i2c_set_clientdata(client, tsdata);
 	device_init_wakeup(&client->dev, 1);
 
 	return 0;
-
-err_free_irq:
-	free_irq(client->irq, tsdata);
-err_free_mem:
-	input_free_device(input);
-	kfree(tsdata);
-	return error;
 }
 
 static int pixcir_i2c_ts_remove(struct i2c_client *client)
@@ -198,10 +194,6 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 	tsdata->exiting = true;
 	mb();
-	free_irq(client->irq, tsdata);
-
-	input_unregister_device(tsdata->input);
-	kfree(tsdata);
 
 	return 0;
 }
-- 
1.8.3.2


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

* [PATCH v2 2/8] Input: pixcir_i2c_ts: Initialize interrupt mode and power mode
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:28   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Introduce helper functions to configure power and interrupt
registers. Default to IDLE mode on probe as device supports
auto wakeup to ACVIE mode on detecting finger touch.

Configure interrupt mode and polarity on start up.
Power down on device closure or module removal.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 173 +++++++++++++++++++++++++++++-
 include/linux/input/pixcir_ts.h           |  42 ++++++++
 2 files changed, 213 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 38e83a2..cce3740 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -100,6 +100,161 @@ static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts,
+						enum pixcir_power_mode mode)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't read reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_POWER_MODE, ret);
+		return ret;
+	}
+
+	ret &= ~PIXCIR_POWER_MODE_MASK;
+	ret |= mode;
+
+	/* Always AUTO_IDLE */
+	ret |= PIXCIR_POWER_ALLOW_IDLE;
+
+	ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't write reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_POWER_MODE, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Set the interrupt mode for the device i.e. ATTB line behaviour
+ *
+ * @polarity : 1 for active high, 0 for active low.
+ */
+static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts,
+						enum pixcir_int_mode mode,
+					bool polarity)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't read reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	ret &= ~PIXCIR_INT_MODE_MASK;
+	ret |= mode;
+
+	if (polarity)
+		ret |= PIXCIR_INT_POL_HIGH;
+	else
+		ret &= ~PIXCIR_INT_POL_HIGH;
+
+	ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't write reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Enable/disable interrupt generation
+ */
+static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't read reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	if (enable)
+		ret |= PIXCIR_INT_ENABLE;
+	else
+		ret &= ~PIXCIR_INT_ENABLE;
+
+	ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't write reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int pixcir_start(struct pixcir_i2c_ts_data *ts)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	/* LEVEL_TOUCH interrupt with active low polarity */
+	ret = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0);
+	if (ret) {
+		dev_err(dev, "Failed to set interrupt mode\n");
+		return ret;
+	}
+
+	ts->exiting = false;
+	mb();	/* Update status before IRQ can fire */
+
+	/* enable interrupt generation */
+	ret = pixcir_int_enable(ts, 1);
+	if (ret) {
+		dev_err(dev, "Failed to enable interrupt generation\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int pixcir_stop(struct pixcir_i2c_ts_data *ts)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	/* disable interrupt generation */
+	ret = pixcir_int_enable(ts, 0);
+	if (ret) {
+		dev_err(dev, "Failed to disable interrupt generation\n");
+		return ret;
+	}
+
+	synchronize_irq(ts->client->irq);
+	mb();	/* Update status after pending IRQ is complete */
+	ts->exiting = true;
+
+	return 0;
+}
+
+static int pixcir_input_open(struct input_dev *dev)
+{
+	struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
+
+	return pixcir_start(ts);
+}
+
+static void pixcir_input_close(struct input_dev *dev)
+{
+	struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
+
+	pixcir_stop(ts);
+}
+
+
 #ifdef CONFIG_PM_SLEEP
 static int pixcir_i2c_ts_suspend(struct device *dev)
 {
@@ -157,6 +312,8 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	input->name = client->name;
 	input->id.bustype = BUS_I2C;
 	input->dev.parent = &client->dev;
+	input->open = pixcir_input_open;
+	input->close = pixcir_input_close;
 
 	__set_bit(EV_KEY, input->evbit);
 	__set_bit(EV_ABS, input->evbit);
@@ -176,6 +333,18 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 		return error;
 	}
 
+	/* Always be in IDLE mode to save power, device supports auto wake */
+	error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE);
+	if (error) {
+		dev_err(dev, "Failed to set IDLE mode\n");
+		return error;
+	}
+
+	/* Stop device till opened */
+	error = pixcir_stop(tsdata);
+	if (error)
+		return error;
+
 	error = input_register_device(input);
 	if (error)
 		return error;
@@ -192,8 +361,8 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 	device_init_wakeup(&client->dev, 0);
 
-	tsdata->exiting = true;
-	mb();
+	if (!tsdata->exiting)
+		pixcir_stop(tsdata);
 
 	return 0;
 }
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 7163d91..7942804 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -1,6 +1,48 @@
 #ifndef	_PIXCIR_I2C_TS_H
 #define	_PIXCIR_I2C_TS_H
 
+/*
+ * Register map
+ */
+#define PIXCIR_REG_POWER_MODE	51
+#define PIXCIR_REG_INT_MODE	52
+
+/*
+ * Power modes:
+ * active: max scan speed
+ * idle: lower scan speed with automatic transition to active on touch
+ * halt: datasheet says sleep but this is more like halt as the chip
+ *       clocks are cut and it can only be brought out of this mode
+ *	 using the RESET pin.
+ */
+enum pixcir_power_mode {
+	PIXCIR_POWER_ACTIVE,
+	PIXCIR_POWER_IDLE,
+	PIXCIR_POWER_HALT,
+};
+
+#define PIXCIR_POWER_MODE_MASK	0x03
+#define PIXCIR_POWER_ALLOW_IDLE (1UL << 2)
+
+/*
+ * Interrupt modes:
+ * periodical: interrupt is asserted periodicaly
+ * diff coordinates: interrupt is asserted when coordinates change
+ * level on touch: interrupt level asserted during touch
+ * pulse on touch: interrupt pulse asserted druing touch
+ *
+ */
+enum pixcir_int_mode {
+	PIXCIR_INT_PERIODICAL,
+	PIXCIR_INT_DIFF_COORD,
+	PIXCIR_INT_LEVEL_TOUCH,
+	PIXCIR_INT_PULSE_TOUCH,
+};
+
+#define PIXCIR_INT_MODE_MASK	0x03
+#define PIXCIR_INT_ENABLE	(1UL << 3)
+#define PIXCIR_INT_POL_HIGH	(1UL << 2)
+
 struct pixcir_ts_platform_data {
 	int (*attb_read_val)(void);
 	int x_max;
-- 
1.8.3.2


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

* [PATCH v2 2/8] Input: pixcir_i2c_ts: Initialize interrupt mode and power mode
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Introduce helper functions to configure power and interrupt
registers. Default to IDLE mode on probe as device supports
auto wakeup to ACVIE mode on detecting finger touch.

Configure interrupt mode and polarity on start up.
Power down on device closure or module removal.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 173 +++++++++++++++++++++++++++++-
 include/linux/input/pixcir_ts.h           |  42 ++++++++
 2 files changed, 213 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 38e83a2..cce3740 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -100,6 +100,161 @@ static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts,
+						enum pixcir_power_mode mode)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't read reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_POWER_MODE, ret);
+		return ret;
+	}
+
+	ret &= ~PIXCIR_POWER_MODE_MASK;
+	ret |= mode;
+
+	/* Always AUTO_IDLE */
+	ret |= PIXCIR_POWER_ALLOW_IDLE;
+
+	ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't write reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_POWER_MODE, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Set the interrupt mode for the device i.e. ATTB line behaviour
+ *
+ * @polarity : 1 for active high, 0 for active low.
+ */
+static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts,
+						enum pixcir_int_mode mode,
+					bool polarity)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't read reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	ret &= ~PIXCIR_INT_MODE_MASK;
+	ret |= mode;
+
+	if (polarity)
+		ret |= PIXCIR_INT_POL_HIGH;
+	else
+		ret &= ~PIXCIR_INT_POL_HIGH;
+
+	ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't write reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Enable/disable interrupt generation
+ */
+static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't read reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	if (enable)
+		ret |= PIXCIR_INT_ENABLE;
+	else
+		ret &= ~PIXCIR_INT_ENABLE;
+
+	ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
+	if (ret < 0) {
+		dev_err(dev, "%s: can't write reg 0x%x : %d\n",
+			__func__, PIXCIR_REG_INT_MODE, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int pixcir_start(struct pixcir_i2c_ts_data *ts)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	/* LEVEL_TOUCH interrupt with active low polarity */
+	ret = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0);
+	if (ret) {
+		dev_err(dev, "Failed to set interrupt mode\n");
+		return ret;
+	}
+
+	ts->exiting = false;
+	mb();	/* Update status before IRQ can fire */
+
+	/* enable interrupt generation */
+	ret = pixcir_int_enable(ts, 1);
+	if (ret) {
+		dev_err(dev, "Failed to enable interrupt generation\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int pixcir_stop(struct pixcir_i2c_ts_data *ts)
+{
+	struct device *dev = &ts->client->dev;
+	int ret;
+
+	/* disable interrupt generation */
+	ret = pixcir_int_enable(ts, 0);
+	if (ret) {
+		dev_err(dev, "Failed to disable interrupt generation\n");
+		return ret;
+	}
+
+	synchronize_irq(ts->client->irq);
+	mb();	/* Update status after pending IRQ is complete */
+	ts->exiting = true;
+
+	return 0;
+}
+
+static int pixcir_input_open(struct input_dev *dev)
+{
+	struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
+
+	return pixcir_start(ts);
+}
+
+static void pixcir_input_close(struct input_dev *dev)
+{
+	struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
+
+	pixcir_stop(ts);
+}
+
+
 #ifdef CONFIG_PM_SLEEP
 static int pixcir_i2c_ts_suspend(struct device *dev)
 {
@@ -157,6 +312,8 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	input->name = client->name;
 	input->id.bustype = BUS_I2C;
 	input->dev.parent = &client->dev;
+	input->open = pixcir_input_open;
+	input->close = pixcir_input_close;
 
 	__set_bit(EV_KEY, input->evbit);
 	__set_bit(EV_ABS, input->evbit);
@@ -176,6 +333,18 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 		return error;
 	}
 
+	/* Always be in IDLE mode to save power, device supports auto wake */
+	error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE);
+	if (error) {
+		dev_err(dev, "Failed to set IDLE mode\n");
+		return error;
+	}
+
+	/* Stop device till opened */
+	error = pixcir_stop(tsdata);
+	if (error)
+		return error;
+
 	error = input_register_device(input);
 	if (error)
 		return error;
@@ -192,8 +361,8 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 	device_init_wakeup(&client->dev, 0);
 
-	tsdata->exiting = true;
-	mb();
+	if (!tsdata->exiting)
+		pixcir_stop(tsdata);
 
 	return 0;
 }
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 7163d91..7942804 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -1,6 +1,48 @@
 #ifndef	_PIXCIR_I2C_TS_H
 #define	_PIXCIR_I2C_TS_H
 
+/*
+ * Register map
+ */
+#define PIXCIR_REG_POWER_MODE	51
+#define PIXCIR_REG_INT_MODE	52
+
+/*
+ * Power modes:
+ * active: max scan speed
+ * idle: lower scan speed with automatic transition to active on touch
+ * halt: datasheet says sleep but this is more like halt as the chip
+ *       clocks are cut and it can only be brought out of this mode
+ *	 using the RESET pin.
+ */
+enum pixcir_power_mode {
+	PIXCIR_POWER_ACTIVE,
+	PIXCIR_POWER_IDLE,
+	PIXCIR_POWER_HALT,
+};
+
+#define PIXCIR_POWER_MODE_MASK	0x03
+#define PIXCIR_POWER_ALLOW_IDLE (1UL << 2)
+
+/*
+ * Interrupt modes:
+ * periodical: interrupt is asserted periodicaly
+ * diff coordinates: interrupt is asserted when coordinates change
+ * level on touch: interrupt level asserted during touch
+ * pulse on touch: interrupt pulse asserted druing touch
+ *
+ */
+enum pixcir_int_mode {
+	PIXCIR_INT_PERIODICAL,
+	PIXCIR_INT_DIFF_COORD,
+	PIXCIR_INT_LEVEL_TOUCH,
+	PIXCIR_INT_PULSE_TOUCH,
+};
+
+#define PIXCIR_INT_MODE_MASK	0x03
+#define PIXCIR_INT_ENABLE	(1UL << 3)
+#define PIXCIR_INT_POL_HIGH	(1UL << 2)
+
 struct pixcir_ts_platform_data {
 	int (*attb_read_val)(void);
 	int x_max;
-- 
1.8.3.2

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

* [PATCH v2 3/8] Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:28   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Get rid of the attb_read_val() platform hook. Instead,
read the ATTB gpio directly from the driver.

Fail if valid ATTB gpio is not provided by patform data.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 16 +++++++++++++++-
 include/linux/input/pixcir_ts.h           |  2 +-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index cce3740..fe17b41 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -24,6 +24,7 @@
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/input/pixcir_ts.h>
+#include <linux/gpio.h>
 
 struct pixcir_i2c_ts_data {
 	struct i2c_client *client;
@@ -87,11 +88,12 @@ static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
 static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 {
 	struct pixcir_i2c_ts_data *tsdata = dev_id;
+	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
 
 	while (!tsdata->exiting) {
 		pixcir_ts_poscheck(tsdata);
 
-		if (tsdata->chip->attb_read_val())
+		if (gpio_get_value(pdata->gpio_attb))
 			break;
 
 		msleep(20);
@@ -293,6 +295,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	if (!pdata) {
 		dev_err(&client->dev, "platform data not defined\n");
 		return -EINVAL;
+	} else {
+		if (!gpio_is_valid(pdata->gpio_attb)) {
+			dev_err(dev, "Invalid gpio_attb in pdata\n");
+			return -EINVAL;
+		}
 	}
 
 	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
@@ -325,6 +332,13 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 
 	input_set_drvdata(input, tsdata);
 
+	error = devm_gpio_request_one(dev, pdata->gpio_attb,
+			GPIOF_DIR_IN, "pixcir_i2c_attb");
+	if (error) {
+		dev_err(dev, "Failed to request ATTB gpio\n");
+		return error;
+	}
+
 	error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
 				     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 				     client->name, tsdata);
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 7942804..160cf35 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -44,9 +44,9 @@ enum pixcir_int_mode {
 #define PIXCIR_INT_POL_HIGH	(1UL << 2)
 
 struct pixcir_ts_platform_data {
-	int (*attb_read_val)(void);
 	int x_max;
 	int y_max;
+	int gpio_attb;		/* GPIO connected to ATTB line */
 };
 
 #endif
-- 
1.8.3.2


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

* [PATCH v2 3/8] Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Get rid of the attb_read_val() platform hook. Instead,
read the ATTB gpio directly from the driver.

Fail if valid ATTB gpio is not provided by patform data.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 16 +++++++++++++++-
 include/linux/input/pixcir_ts.h           |  2 +-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index cce3740..fe17b41 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -24,6 +24,7 @@
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/input/pixcir_ts.h>
+#include <linux/gpio.h>
 
 struct pixcir_i2c_ts_data {
 	struct i2c_client *client;
@@ -87,11 +88,12 @@ static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
 static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 {
 	struct pixcir_i2c_ts_data *tsdata = dev_id;
+	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
 
 	while (!tsdata->exiting) {
 		pixcir_ts_poscheck(tsdata);
 
-		if (tsdata->chip->attb_read_val())
+		if (gpio_get_value(pdata->gpio_attb))
 			break;
 
 		msleep(20);
@@ -293,6 +295,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	if (!pdata) {
 		dev_err(&client->dev, "platform data not defined\n");
 		return -EINVAL;
+	} else {
+		if (!gpio_is_valid(pdata->gpio_attb)) {
+			dev_err(dev, "Invalid gpio_attb in pdata\n");
+			return -EINVAL;
+		}
 	}
 
 	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
@@ -325,6 +332,13 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 
 	input_set_drvdata(input, tsdata);
 
+	error = devm_gpio_request_one(dev, pdata->gpio_attb,
+			GPIOF_DIR_IN, "pixcir_i2c_attb");
+	if (error) {
+		dev_err(dev, "Failed to request ATTB gpio\n");
+		return error;
+	}
+
 	error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
 				     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 				     client->name, tsdata);
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 7942804..160cf35 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -44,9 +44,9 @@ enum pixcir_int_mode {
 #define PIXCIR_INT_POL_HIGH	(1UL << 2)
 
 struct pixcir_ts_platform_data {
-	int (*attb_read_val)(void);
 	int x_max;
 	int y_max;
+	int gpio_attb;		/* GPIO connected to ATTB line */
 };
 
 #endif
-- 
1.8.3.2

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

* [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Switch to using the Type-B Multi-Touch protocol.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 125 ++++++++++++++++++++++--------
 1 file changed, 94 insertions(+), 31 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index fe17b41..8736f71 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -23,9 +23,12 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
 
+#define PIXCIR_MAX_SLOTS       2
+
 struct pixcir_i2c_ts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
@@ -33,12 +36,25 @@ struct pixcir_i2c_ts_data {
 	bool exiting;
 };
 
-static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
+struct pixcir_touch {
+	int x;
+	int y;
+};
+
+struct pixcir_report_data {
+	int num_touches;
+	struct pixcir_touch touches[PIXCIR_MAX_SLOTS];
+};
+
+static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
+			    struct pixcir_report_data *report)
 {
-	struct pixcir_i2c_ts_data *tsdata = data;
 	u8 rdbuf[10], wrbuf[1] = { 0 };
+	u8 *bufptr;
 	u8 touch;
-	int ret;
+	int ret, i;
+
+	memset(report, 0, sizeof(struct pixcir_report_data));
 
 	ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
 	if (ret != sizeof(wrbuf)) {
@@ -56,45 +72,85 @@ static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
 		return;
 	}
 
-	touch = rdbuf[0];
-	if (touch) {
-		u16 posx1 = (rdbuf[3] << 8) | rdbuf[2];
-		u16 posy1 = (rdbuf[5] << 8) | rdbuf[4];
-		u16 posx2 = (rdbuf[7] << 8) | rdbuf[6];
-		u16 posy2 = (rdbuf[9] << 8) | rdbuf[8];
-
-		input_report_key(tsdata->input, BTN_TOUCH, 1);
-		input_report_abs(tsdata->input, ABS_X, posx1);
-		input_report_abs(tsdata->input, ABS_Y, posy1);
-
-		input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1);
-		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1);
-		input_mt_sync(tsdata->input);
-
-		if (touch == 2) {
-			input_report_abs(tsdata->input,
-					 ABS_MT_POSITION_X, posx2);
-			input_report_abs(tsdata->input,
-					 ABS_MT_POSITION_Y, posy2);
-			input_mt_sync(tsdata->input);
-		}
-	} else {
-		input_report_key(tsdata->input, BTN_TOUCH, 0);
+	touch = rdbuf[0] & 0x7;
+	if (touch > PIXCIR_MAX_SLOTS)
+		touch = PIXCIR_MAX_SLOTS;
+
+	report->num_touches = touch;
+	bufptr = &rdbuf[2];
+
+	for (i = 0; i < touch; i++) {
+		report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
+		report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
+
+		bufptr = &bufptr[4];
 	}
+}
+
+static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
+			     struct pixcir_report_data *report)
+{
+	struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
+	int slots[PIXCIR_MAX_SLOTS];
+	struct pixcir_touch *touch;
+	int n, i, slot;
+	struct device *dev = &ts->client->dev;
 
-	input_sync(tsdata->input);
+	n = report->num_touches;
+	if (n > PIXCIR_MAX_SLOTS)
+		n = PIXCIR_MAX_SLOTS;
+
+	for (i = 0; i < n; i++) {
+		touch = &report->touches[i];
+		pos[i].x = touch->x;
+		pos[i].y = touch->y;
+	}
+
+	input_mt_assign_slots(ts->input, slots, pos, n);
+
+	for (i = 0; i < n; i++) {
+		touch = &report->touches[i];
+		slot = slots[i];
+
+		input_mt_slot(ts->input, slot);
+		input_mt_report_slot_state(ts->input,
+					   MT_TOOL_FINGER, true);
+
+		input_event(ts->input, EV_ABS, ABS_MT_POSITION_X, touch->x);
+		input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y, touch->y);
+
+		dev_dbg(dev, "%d: slot %d, x %d, y %d\n",
+			i, slot, touch->x, touch->y);
+	}
+
+	input_mt_sync_frame(ts->input);
+	input_sync(ts->input);
 }
 
 static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 {
 	struct pixcir_i2c_ts_data *tsdata = dev_id;
 	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
+	struct pixcir_report_data report;
 
 	while (!tsdata->exiting) {
-		pixcir_ts_poscheck(tsdata);
-
-		if (gpio_get_value(pdata->gpio_attb))
+		/* parse packet */
+		pixcir_ts_parse(tsdata, &report);
+
+		/* report it */
+		pixcir_ts_report(tsdata, &report);
+
+		if (gpio_get_value(pdata->gpio_attb)) {
+			if (report.num_touches) {
+				/*
+				 * Last report with no finger up?
+				 * Do it now then.
+				 */
+				input_mt_sync_frame(tsdata->input);
+				input_sync(tsdata->input);
+			}
 			break;
+		}
 
 		msleep(20);
 	}
@@ -330,6 +386,13 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
 	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
 
+	error = input_mt_init_slots(input, PIXCIR_MAX_SLOTS,
+			INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	if (error) {
+		dev_err(dev, "Error initializing Multi-Touch slots\n");
+		return error;
+	}
+
 	input_set_drvdata(input, tsdata);
 
 	error = devm_gpio_request_one(dev, pdata->gpio_attb,
-- 
1.8.3.2


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

* [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w
  Cc: rydberg-Hk7bIW8heu4wFerOooGFRg, jcbian-mY6CKx1T+M6Pt1CcHtbs0g,
	balbi-l0cyMroinI0, dmurphy-l0cyMroinI0, mugunthanvnm-l0cyMroinI0,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Roger Quadros

Switch to using the Type-B Multi-Touch protocol.

Signed-off-by: Roger Quadros <rogerq-l0cyMroinI0@public.gmane.org>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 125 ++++++++++++++++++++++--------
 1 file changed, 94 insertions(+), 31 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index fe17b41..8736f71 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -23,9 +23,12 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
 
+#define PIXCIR_MAX_SLOTS       2
+
 struct pixcir_i2c_ts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
@@ -33,12 +36,25 @@ struct pixcir_i2c_ts_data {
 	bool exiting;
 };
 
-static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
+struct pixcir_touch {
+	int x;
+	int y;
+};
+
+struct pixcir_report_data {
+	int num_touches;
+	struct pixcir_touch touches[PIXCIR_MAX_SLOTS];
+};
+
+static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
+			    struct pixcir_report_data *report)
 {
-	struct pixcir_i2c_ts_data *tsdata = data;
 	u8 rdbuf[10], wrbuf[1] = { 0 };
+	u8 *bufptr;
 	u8 touch;
-	int ret;
+	int ret, i;
+
+	memset(report, 0, sizeof(struct pixcir_report_data));
 
 	ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
 	if (ret != sizeof(wrbuf)) {
@@ -56,45 +72,85 @@ static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
 		return;
 	}
 
-	touch = rdbuf[0];
-	if (touch) {
-		u16 posx1 = (rdbuf[3] << 8) | rdbuf[2];
-		u16 posy1 = (rdbuf[5] << 8) | rdbuf[4];
-		u16 posx2 = (rdbuf[7] << 8) | rdbuf[6];
-		u16 posy2 = (rdbuf[9] << 8) | rdbuf[8];
-
-		input_report_key(tsdata->input, BTN_TOUCH, 1);
-		input_report_abs(tsdata->input, ABS_X, posx1);
-		input_report_abs(tsdata->input, ABS_Y, posy1);
-
-		input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1);
-		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1);
-		input_mt_sync(tsdata->input);
-
-		if (touch == 2) {
-			input_report_abs(tsdata->input,
-					 ABS_MT_POSITION_X, posx2);
-			input_report_abs(tsdata->input,
-					 ABS_MT_POSITION_Y, posy2);
-			input_mt_sync(tsdata->input);
-		}
-	} else {
-		input_report_key(tsdata->input, BTN_TOUCH, 0);
+	touch = rdbuf[0] & 0x7;
+	if (touch > PIXCIR_MAX_SLOTS)
+		touch = PIXCIR_MAX_SLOTS;
+
+	report->num_touches = touch;
+	bufptr = &rdbuf[2];
+
+	for (i = 0; i < touch; i++) {
+		report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
+		report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
+
+		bufptr = &bufptr[4];
 	}
+}
+
+static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
+			     struct pixcir_report_data *report)
+{
+	struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
+	int slots[PIXCIR_MAX_SLOTS];
+	struct pixcir_touch *touch;
+	int n, i, slot;
+	struct device *dev = &ts->client->dev;
 
-	input_sync(tsdata->input);
+	n = report->num_touches;
+	if (n > PIXCIR_MAX_SLOTS)
+		n = PIXCIR_MAX_SLOTS;
+
+	for (i = 0; i < n; i++) {
+		touch = &report->touches[i];
+		pos[i].x = touch->x;
+		pos[i].y = touch->y;
+	}
+
+	input_mt_assign_slots(ts->input, slots, pos, n);
+
+	for (i = 0; i < n; i++) {
+		touch = &report->touches[i];
+		slot = slots[i];
+
+		input_mt_slot(ts->input, slot);
+		input_mt_report_slot_state(ts->input,
+					   MT_TOOL_FINGER, true);
+
+		input_event(ts->input, EV_ABS, ABS_MT_POSITION_X, touch->x);
+		input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y, touch->y);
+
+		dev_dbg(dev, "%d: slot %d, x %d, y %d\n",
+			i, slot, touch->x, touch->y);
+	}
+
+	input_mt_sync_frame(ts->input);
+	input_sync(ts->input);
 }
 
 static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 {
 	struct pixcir_i2c_ts_data *tsdata = dev_id;
 	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
+	struct pixcir_report_data report;
 
 	while (!tsdata->exiting) {
-		pixcir_ts_poscheck(tsdata);
-
-		if (gpio_get_value(pdata->gpio_attb))
+		/* parse packet */
+		pixcir_ts_parse(tsdata, &report);
+
+		/* report it */
+		pixcir_ts_report(tsdata, &report);
+
+		if (gpio_get_value(pdata->gpio_attb)) {
+			if (report.num_touches) {
+				/*
+				 * Last report with no finger up?
+				 * Do it now then.
+				 */
+				input_mt_sync_frame(tsdata->input);
+				input_sync(tsdata->input);
+			}
 			break;
+		}
 
 		msleep(20);
 	}
@@ -330,6 +386,13 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
 	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
 
+	error = input_mt_init_slots(input, PIXCIR_MAX_SLOTS,
+			INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	if (error) {
+		dev_err(dev, "Error initializing Multi-Touch slots\n");
+		return error;
+	}
+
 	input_set_drvdata(input, tsdata);
 
 	error = devm_gpio_request_one(dev, pdata->gpio_attb,
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 5/8] Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided tracking IDs
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:28   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Some variants of the Pixcir touch controller support upto 5
simultaneous fingers and hardware tracking IDs. Prepare the driver
for that.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 74 ++++++++++++++++++++++++-------
 include/linux/input/pixcir_ts.h           | 12 +++++
 2 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8736f71..b1e92f6 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -27,18 +27,20 @@
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
 
-#define PIXCIR_MAX_SLOTS       2
+#define PIXCIR_MAX_SLOTS       5 /* Max fingers supported by driver */
 
 struct pixcir_i2c_ts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
-	const struct pixcir_ts_platform_data *chip;
+	const struct pixcir_ts_platform_data *pdata;
 	bool exiting;
+	int max_fingers;	/* Max fingers supported in this instance */
 };
 
 struct pixcir_touch {
 	int x;
 	int y;
+	int id;
 };
 
 struct pixcir_report_data {
@@ -49,13 +51,21 @@ struct pixcir_report_data {
 static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 			    struct pixcir_report_data *report)
 {
-	u8 rdbuf[10], wrbuf[1] = { 0 };
+	u8 rdbuf[2 + PIXCIR_MAX_SLOTS * 5];
+	u8 wrbuf[1] = { 0 };
 	u8 *bufptr;
 	u8 touch;
 	int ret, i;
+	int readsize;
+	const struct pixcir_i2c_chip_data *chip = &tsdata->pdata->chip;
 
 	memset(report, 0, sizeof(struct pixcir_report_data));
 
+	i = chip->has_hw_ids ? 1 : 0;
+	readsize = 2 + tsdata->max_fingers * (4 + i);
+	if (readsize > sizeof(rdbuf))
+		readsize = sizeof(rdbuf);
+
 	ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
 	if (ret != sizeof(wrbuf)) {
 		dev_err(&tsdata->client->dev,
@@ -64,7 +74,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 		return;
 	}
 
-	ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf));
+	ret = i2c_master_recv(tsdata->client, rdbuf, readsize);
 	if (ret != sizeof(rdbuf)) {
 		dev_err(&tsdata->client->dev,
 			"%s: i2c_master_recv failed(), ret=%d\n",
@@ -73,8 +83,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 	}
 
 	touch = rdbuf[0] & 0x7;
-	if (touch > PIXCIR_MAX_SLOTS)
-		touch = PIXCIR_MAX_SLOTS;
+	if (touch > tsdata->max_fingers)
+		touch = tsdata->max_fingers;
 
 	report->num_touches = touch;
 	bufptr = &rdbuf[2];
@@ -83,7 +93,12 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 		report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
 		report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
 
-		bufptr = &bufptr[4];
+		if (chip->has_hw_ids) {
+			report->touches[i].id = bufptr[4];
+			bufptr = &bufptr[5];
+		} else {
+			bufptr = &bufptr[4];
+		}
 	}
 }
 
@@ -95,22 +110,35 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
 	struct pixcir_touch *touch;
 	int n, i, slot;
 	struct device *dev = &ts->client->dev;
+	const struct pixcir_i2c_chip_data *chip = &ts->pdata->chip;
 
 	n = report->num_touches;
 	if (n > PIXCIR_MAX_SLOTS)
 		n = PIXCIR_MAX_SLOTS;
 
-	for (i = 0; i < n; i++) {
-		touch = &report->touches[i];
-		pos[i].x = touch->x;
-		pos[i].y = touch->y;
-	}
+	if (!chip->has_hw_ids) {
+		for (i = 0; i < n; i++) {
+			touch = &report->touches[i];
+			pos[i].x = touch->x;
+			pos[i].y = touch->y;
+		}
 
-	input_mt_assign_slots(ts->input, slots, pos, n);
+		input_mt_assign_slots(ts->input, slots, pos, n);
+	}
 
 	for (i = 0; i < n; i++) {
 		touch = &report->touches[i];
-		slot = slots[i];
+
+		if (chip->has_hw_ids) {
+			slot = input_mt_get_slot_by_key(ts->input, touch->id);
+			if (slot < 0) {
+				dev_dbg(dev, "no free slot for id 0x%x\n",
+					touch->id);
+				continue;
+			}
+		} else {
+			slot = slots[i];
+		}
 
 		input_mt_slot(ts->input, slot);
 		input_mt_report_slot_state(ts->input,
@@ -130,7 +158,7 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
 static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 {
 	struct pixcir_i2c_ts_data *tsdata = dev_id;
-	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
+	const struct pixcir_ts_platform_data *pdata = tsdata->pdata;
 	struct pixcir_report_data report;
 
 	while (!tsdata->exiting) {
@@ -356,6 +384,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 			dev_err(dev, "Invalid gpio_attb in pdata\n");
 			return -EINVAL;
 		}
+
+		if (pdata->chip.max_fingers <= 0) {
+			dev_err(dev, "Invalid max_fingers in pdata\n");
+			return -EINVAL;
+		}
 	}
 
 	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
@@ -370,7 +403,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 
 	tsdata->client = client;
 	tsdata->input = input;
-	tsdata->chip = pdata;
+	tsdata->pdata = pdata;
 
 	input->name = client->name;
 	input->id.bustype = BUS_I2C;
@@ -386,7 +419,14 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
 	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
 
-	error = input_mt_init_slots(input, PIXCIR_MAX_SLOTS,
+	tsdata->max_fingers = tsdata->pdata->chip.max_fingers;
+	if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) {
+		tsdata->max_fingers = PIXCIR_MAX_SLOTS;
+		dev_info(dev, "Limiting maximum fingers to %d\n",
+			 tsdata->max_fingers);
+	}
+
+	error = input_mt_init_slots(input, tsdata->max_fingers,
 			INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
 	if (error) {
 		dev_err(dev, "Error initializing Multi-Touch slots\n");
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 160cf35..7bae83b 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -43,10 +43,22 @@ enum pixcir_int_mode {
 #define PIXCIR_INT_ENABLE	(1UL << 3)
 #define PIXCIR_INT_POL_HIGH	(1UL << 2)
 
+/**
+ * struct pixcir_irc_chip_data - chip related data
+ * @max_fingers:	Max number of fingers reported simultaneously by h/w
+ * @has_hw_ids:		Hardware supports finger tracking IDs
+ *
+ */
+struct pixcir_i2c_chip_data {
+	u8 max_fingers;
+	bool has_hw_ids;
+};
+
 struct pixcir_ts_platform_data {
 	int x_max;
 	int y_max;
 	int gpio_attb;		/* GPIO connected to ATTB line */
+	struct pixcir_i2c_chip_data chip;
 };
 
 #endif
-- 
1.8.3.2


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

* [PATCH v2 5/8] Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided tracking IDs
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Some variants of the Pixcir touch controller support upto 5
simultaneous fingers and hardware tracking IDs. Prepare the driver
for that.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 74 ++++++++++++++++++++++++-------
 include/linux/input/pixcir_ts.h           | 12 +++++
 2 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8736f71..b1e92f6 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -27,18 +27,20 @@
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
 
-#define PIXCIR_MAX_SLOTS       2
+#define PIXCIR_MAX_SLOTS       5 /* Max fingers supported by driver */
 
 struct pixcir_i2c_ts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
-	const struct pixcir_ts_platform_data *chip;
+	const struct pixcir_ts_platform_data *pdata;
 	bool exiting;
+	int max_fingers;	/* Max fingers supported in this instance */
 };
 
 struct pixcir_touch {
 	int x;
 	int y;
+	int id;
 };
 
 struct pixcir_report_data {
@@ -49,13 +51,21 @@ struct pixcir_report_data {
 static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 			    struct pixcir_report_data *report)
 {
-	u8 rdbuf[10], wrbuf[1] = { 0 };
+	u8 rdbuf[2 + PIXCIR_MAX_SLOTS * 5];
+	u8 wrbuf[1] = { 0 };
 	u8 *bufptr;
 	u8 touch;
 	int ret, i;
+	int readsize;
+	const struct pixcir_i2c_chip_data *chip = &tsdata->pdata->chip;
 
 	memset(report, 0, sizeof(struct pixcir_report_data));
 
+	i = chip->has_hw_ids ? 1 : 0;
+	readsize = 2 + tsdata->max_fingers * (4 + i);
+	if (readsize > sizeof(rdbuf))
+		readsize = sizeof(rdbuf);
+
 	ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
 	if (ret != sizeof(wrbuf)) {
 		dev_err(&tsdata->client->dev,
@@ -64,7 +74,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 		return;
 	}
 
-	ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf));
+	ret = i2c_master_recv(tsdata->client, rdbuf, readsize);
 	if (ret != sizeof(rdbuf)) {
 		dev_err(&tsdata->client->dev,
 			"%s: i2c_master_recv failed(), ret=%d\n",
@@ -73,8 +83,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 	}
 
 	touch = rdbuf[0] & 0x7;
-	if (touch > PIXCIR_MAX_SLOTS)
-		touch = PIXCIR_MAX_SLOTS;
+	if (touch > tsdata->max_fingers)
+		touch = tsdata->max_fingers;
 
 	report->num_touches = touch;
 	bufptr = &rdbuf[2];
@@ -83,7 +93,12 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 		report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
 		report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
 
-		bufptr = &bufptr[4];
+		if (chip->has_hw_ids) {
+			report->touches[i].id = bufptr[4];
+			bufptr = &bufptr[5];
+		} else {
+			bufptr = &bufptr[4];
+		}
 	}
 }
 
@@ -95,22 +110,35 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
 	struct pixcir_touch *touch;
 	int n, i, slot;
 	struct device *dev = &ts->client->dev;
+	const struct pixcir_i2c_chip_data *chip = &ts->pdata->chip;
 
 	n = report->num_touches;
 	if (n > PIXCIR_MAX_SLOTS)
 		n = PIXCIR_MAX_SLOTS;
 
-	for (i = 0; i < n; i++) {
-		touch = &report->touches[i];
-		pos[i].x = touch->x;
-		pos[i].y = touch->y;
-	}
+	if (!chip->has_hw_ids) {
+		for (i = 0; i < n; i++) {
+			touch = &report->touches[i];
+			pos[i].x = touch->x;
+			pos[i].y = touch->y;
+		}
 
-	input_mt_assign_slots(ts->input, slots, pos, n);
+		input_mt_assign_slots(ts->input, slots, pos, n);
+	}
 
 	for (i = 0; i < n; i++) {
 		touch = &report->touches[i];
-		slot = slots[i];
+
+		if (chip->has_hw_ids) {
+			slot = input_mt_get_slot_by_key(ts->input, touch->id);
+			if (slot < 0) {
+				dev_dbg(dev, "no free slot for id 0x%x\n",
+					touch->id);
+				continue;
+			}
+		} else {
+			slot = slots[i];
+		}
 
 		input_mt_slot(ts->input, slot);
 		input_mt_report_slot_state(ts->input,
@@ -130,7 +158,7 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
 static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
 {
 	struct pixcir_i2c_ts_data *tsdata = dev_id;
-	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
+	const struct pixcir_ts_platform_data *pdata = tsdata->pdata;
 	struct pixcir_report_data report;
 
 	while (!tsdata->exiting) {
@@ -356,6 +384,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 			dev_err(dev, "Invalid gpio_attb in pdata\n");
 			return -EINVAL;
 		}
+
+		if (pdata->chip.max_fingers <= 0) {
+			dev_err(dev, "Invalid max_fingers in pdata\n");
+			return -EINVAL;
+		}
 	}
 
 	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
@@ -370,7 +403,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 
 	tsdata->client = client;
 	tsdata->input = input;
-	tsdata->chip = pdata;
+	tsdata->pdata = pdata;
 
 	input->name = client->name;
 	input->id.bustype = BUS_I2C;
@@ -386,7 +419,14 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
 	input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
 	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
 
-	error = input_mt_init_slots(input, PIXCIR_MAX_SLOTS,
+	tsdata->max_fingers = tsdata->pdata->chip.max_fingers;
+	if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) {
+		tsdata->max_fingers = PIXCIR_MAX_SLOTS;
+		dev_info(dev, "Limiting maximum fingers to %d\n",
+			 tsdata->max_fingers);
+	}
+
+	error = input_mt_init_slots(input, tsdata->max_fingers,
 			INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
 	if (error) {
 		dev_err(dev, "Error initializing Multi-Touch slots\n");
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 160cf35..7bae83b 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -43,10 +43,22 @@ enum pixcir_int_mode {
 #define PIXCIR_INT_ENABLE	(1UL << 3)
 #define PIXCIR_INT_POL_HIGH	(1UL << 2)
 
+/**
+ * struct pixcir_irc_chip_data - chip related data
+ * @max_fingers:	Max number of fingers reported simultaneously by h/w
+ * @has_hw_ids:		Hardware supports finger tracking IDs
+ *
+ */
+struct pixcir_i2c_chip_data {
+	u8 max_fingers;
+	bool has_hw_ids;
+};
+
 struct pixcir_ts_platform_data {
 	int x_max;
 	int y_max;
 	int gpio_attb;		/* GPIO connected to ATTB line */
+	struct pixcir_i2c_chip_data chip;
 };
 
 #endif
-- 
1.8.3.2


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

* [PATCH v2 6/8] Input: pixcir_i2c_ts: Implement wakeup from suspend
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:28   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Improve the suspend and resume handlers to allow the device
to wakeup the system from suspend.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 46 ++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index b1e92f6..8ca258b 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -345,21 +345,59 @@ static void pixcir_input_close(struct input_dev *dev)
 static int pixcir_i2c_ts_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
+	struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
+	struct input_dev *input = ts->input;
+	int ret = 0;
+
+	mutex_lock(&input->mutex);
+
+	if (device_may_wakeup(&client->dev)) {
+		/* need to start device if not open, to be wakeup source */
+		if (!input->users) {
+			ret = pixcir_start(ts);
+			if (ret)
+				goto unlock;
+		}
 
-	if (device_may_wakeup(&client->dev))
 		enable_irq_wake(client->irq);
 
-	return 0;
+	} else if (input->users) {
+		ret = pixcir_stop(ts);
+	}
+
+unlock:
+	mutex_unlock(&input->mutex);
+
+	return ret;
 }
 
 static int pixcir_i2c_ts_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
+	struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
+	struct input_dev *input = ts->input;
+	int ret = 0;
+
+	mutex_lock(&input->mutex);
 
-	if (device_may_wakeup(&client->dev))
+	if (device_may_wakeup(&client->dev)) {
 		disable_irq_wake(client->irq);
 
-	return 0;
+		/* need to stop device if it was not open on suspend */
+		if (!input->users) {
+			ret = pixcir_stop(ts);
+			if (ret)
+				goto unlock;
+		}
+
+	} else if (input->users) {
+		ret = pixcir_start(ts);
+	}
+
+unlock:
+	mutex_unlock(&input->mutex);
+
+	return ret;
 }
 #endif
 
-- 
1.8.3.2


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

* [PATCH v2 6/8] Input: pixcir_i2c_ts: Implement wakeup from suspend
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Improve the suspend and resume handlers to allow the device
to wakeup the system from suspend.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/input/touchscreen/pixcir_i2c_ts.c | 46 ++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index b1e92f6..8ca258b 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -345,21 +345,59 @@ static void pixcir_input_close(struct input_dev *dev)
 static int pixcir_i2c_ts_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
+	struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
+	struct input_dev *input = ts->input;
+	int ret = 0;
+
+	mutex_lock(&input->mutex);
+
+	if (device_may_wakeup(&client->dev)) {
+		/* need to start device if not open, to be wakeup source */
+		if (!input->users) {
+			ret = pixcir_start(ts);
+			if (ret)
+				goto unlock;
+		}
 
-	if (device_may_wakeup(&client->dev))
 		enable_irq_wake(client->irq);
 
-	return 0;
+	} else if (input->users) {
+		ret = pixcir_stop(ts);
+	}
+
+unlock:
+	mutex_unlock(&input->mutex);
+
+	return ret;
 }
 
 static int pixcir_i2c_ts_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
+	struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
+	struct input_dev *input = ts->input;
+	int ret = 0;
+
+	mutex_lock(&input->mutex);
 
-	if (device_may_wakeup(&client->dev))
+	if (device_may_wakeup(&client->dev)) {
 		disable_irq_wake(client->irq);
 
-	return 0;
+		/* need to stop device if it was not open on suspend */
+		if (!input->users) {
+			ret = pixcir_stop(ts);
+			if (ret)
+				goto unlock;
+		}
+
+	} else if (input->users) {
+		ret = pixcir_start(ts);
+	}
+
+unlock:
+	mutex_unlock(&input->mutex);
+
+	return ret;
 }
 #endif
 
-- 
1.8.3.2

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

* [PATCH v2 7/8] Input: pixcir_i2c_ts: Add device tree support
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:28   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Provide device tree support and binding information.
Also provide support for a new chip "pixcir_tangoc".

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 .../bindings/input/touchscreen/pixcir_i2c_ts.txt   | 26 ++++++++
 .../devicetree/bindings/vendor-prefixes.txt        |  1 +
 drivers/input/touchscreen/pixcir_i2c_ts.c          | 78 ++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
new file mode 100644
index 0000000..0ab9505
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
@@ -0,0 +1,26 @@
+* Pixcir I2C touchscreen controllers
+
+Required properties:
+- compatible: must be "pixcir,pixcir_ts" or "pixcir,pixcir_tangoc"
+- reg: I2C address of the chip
+- interrupts: interrupt to which the chip is connected
+- attb-gpio: GPIO connected to the ATTB line of the chip
+- x-size: horizontal resolution of touchscreen
+- y-size: vertical resolution of touchscreen
+
+Example:
+
+	i2c@00000000 {
+		/* ... */
+
+		pixcir_ts@5c {
+			compatible = "pixcir,pixcir_ts";
+			reg = <0x5c>;
+			interrupts = <2 0>;
+			attb-gpio = <&gpf 2 0 2>;
+			x-size = <800>;
+			y-size = <600>;
+		};
+
+		/* ... */
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 40ce2df..d2324b7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -65,6 +65,7 @@ onnn	ON Semiconductor Corp.
 panasonic	Panasonic Corporation
 phytec	PHYTEC Messtechnik GmbH
 picochip	Picochip Ltd
+pixcir  PIXCIR MICROELECTRONICS Co., Ltd
 powervr	PowerVR (deprecated, use img)
 qca	Qualcomm Atheros, Inc.
 qcom	Qualcomm Technologies, Inc
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8ca258b..bb6b42a 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -26,6 +26,9 @@
 #include <linux/input/mt.h>
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 
 #define PIXCIR_MAX_SLOTS       5 /* Max fingers supported by driver */
 
@@ -404,16 +407,70 @@ unlock:
 static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
 			 pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
 
+#ifdef CONFIG_OF
+static const struct of_device_id pixcir_of_match[];
+
+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev)
+{
+	struct pixcir_ts_platform_data *pdata;
+	struct device_node *np = dev->of_node;
+
+	const struct of_device_id *match;
+
+	match = of_match_device(of_match_ptr(pixcir_of_match), dev);
+	if (!match)
+		return ERR_PTR(-EINVAL);
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->chip = *(const struct pixcir_i2c_chip_data *)match->data;
+
+	pdata->gpio_attb = of_get_named_gpio(np, "attb-gpio", 0);
+	/* gpio_attb validity is checked in probe */
+
+	if (of_property_read_u32(np, "x-size", &pdata->x_max)) {
+		dev_err(dev, "Failed to get x-size property\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->x_max -= 1;
+
+	if (of_property_read_u32(np, "y-size", &pdata->y_max)) {
+		dev_err(dev, "Failed to get y-size property\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->y_max -= 1;
+
+	dev_dbg(dev, "%s: x %d, y %d, gpio %d\n", __func__,
+		pdata->x_max + 1, pdata->y_max + 1, pdata->gpio_attb);
+
+	return pdata;
+}
+#else
+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int pixcir_i2c_ts_probe(struct i2c_client *client,
 					 const struct i2c_device_id *id)
 {
 	const struct pixcir_ts_platform_data *pdata =
 			dev_get_platdata(&client->dev);
 	struct device *dev = &client->dev;
+	struct device_node *np = dev->of_node;
 	struct pixcir_i2c_ts_data *tsdata;
 	struct input_dev *input;
 	int error;
 
+	if (np && !pdata) {
+		pdata = pixcir_parse_dt(dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	}
+
 	if (!pdata) {
 		dev_err(&client->dev, "platform data not defined\n");
 		return -EINVAL;
@@ -524,15 +581,36 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 static const struct i2c_device_id pixcir_i2c_ts_id[] = {
 	{ "pixcir_ts", 0 },
+	{ "pixcir_tangoc", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
 
+#ifdef CONFIG_OF
+static const struct pixcir_i2c_chip_data pixcir_ts_data = {
+	.max_fingers = 2,
+	/* no hw id support */
+};
+
+static const struct pixcir_i2c_chip_data pixcir_tangoc_data = {
+	.max_fingers = 5,
+	.has_hw_ids = true,
+};
+
+static const struct of_device_id pixcir_of_match[] = {
+	{ .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data },
+	{ .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pixcir_of_match);
+#endif
+
 static struct i2c_driver pixcir_i2c_ts_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
 		.name	= "pixcir_ts",
 		.pm	= &pixcir_dev_pm_ops,
+		.of_match_table = of_match_ptr(pixcir_of_match),
 	},
 	.probe		= pixcir_i2c_ts_probe,
 	.remove		= pixcir_i2c_ts_remove,
-- 
1.8.3.2


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

* [PATCH v2 7/8] Input: pixcir_i2c_ts: Add device tree support
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros

Provide device tree support and binding information.
Also provide support for a new chip "pixcir_tangoc".

Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 .../bindings/input/touchscreen/pixcir_i2c_ts.txt   | 26 ++++++++
 .../devicetree/bindings/vendor-prefixes.txt        |  1 +
 drivers/input/touchscreen/pixcir_i2c_ts.c          | 78 ++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
new file mode 100644
index 0000000..0ab9505
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
@@ -0,0 +1,26 @@
+* Pixcir I2C touchscreen controllers
+
+Required properties:
+- compatible: must be "pixcir,pixcir_ts" or "pixcir,pixcir_tangoc"
+- reg: I2C address of the chip
+- interrupts: interrupt to which the chip is connected
+- attb-gpio: GPIO connected to the ATTB line of the chip
+- x-size: horizontal resolution of touchscreen
+- y-size: vertical resolution of touchscreen
+
+Example:
+
+	i2c@00000000 {
+		/* ... */
+
+		pixcir_ts@5c {
+			compatible = "pixcir,pixcir_ts";
+			reg = <0x5c>;
+			interrupts = <2 0>;
+			attb-gpio = <&gpf 2 0 2>;
+			x-size = <800>;
+			y-size = <600>;
+		};
+
+		/* ... */
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 40ce2df..d2324b7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -65,6 +65,7 @@ onnn	ON Semiconductor Corp.
 panasonic	Panasonic Corporation
 phytec	PHYTEC Messtechnik GmbH
 picochip	Picochip Ltd
+pixcir  PIXCIR MICROELECTRONICS Co., Ltd
 powervr	PowerVR (deprecated, use img)
 qca	Qualcomm Atheros, Inc.
 qcom	Qualcomm Technologies, Inc
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 8ca258b..bb6b42a 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -26,6 +26,9 @@
 #include <linux/input/mt.h>
 #include <linux/input/pixcir_ts.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 
 #define PIXCIR_MAX_SLOTS       5 /* Max fingers supported by driver */
 
@@ -404,16 +407,70 @@ unlock:
 static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
 			 pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
 
+#ifdef CONFIG_OF
+static const struct of_device_id pixcir_of_match[];
+
+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev)
+{
+	struct pixcir_ts_platform_data *pdata;
+	struct device_node *np = dev->of_node;
+
+	const struct of_device_id *match;
+
+	match = of_match_device(of_match_ptr(pixcir_of_match), dev);
+	if (!match)
+		return ERR_PTR(-EINVAL);
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->chip = *(const struct pixcir_i2c_chip_data *)match->data;
+
+	pdata->gpio_attb = of_get_named_gpio(np, "attb-gpio", 0);
+	/* gpio_attb validity is checked in probe */
+
+	if (of_property_read_u32(np, "x-size", &pdata->x_max)) {
+		dev_err(dev, "Failed to get x-size property\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->x_max -= 1;
+
+	if (of_property_read_u32(np, "y-size", &pdata->y_max)) {
+		dev_err(dev, "Failed to get y-size property\n");
+		return ERR_PTR(-EINVAL);
+	}
+	pdata->y_max -= 1;
+
+	dev_dbg(dev, "%s: x %d, y %d, gpio %d\n", __func__,
+		pdata->x_max + 1, pdata->y_max + 1, pdata->gpio_attb);
+
+	return pdata;
+}
+#else
+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int pixcir_i2c_ts_probe(struct i2c_client *client,
 					 const struct i2c_device_id *id)
 {
 	const struct pixcir_ts_platform_data *pdata =
 			dev_get_platdata(&client->dev);
 	struct device *dev = &client->dev;
+	struct device_node *np = dev->of_node;
 	struct pixcir_i2c_ts_data *tsdata;
 	struct input_dev *input;
 	int error;
 
+	if (np && !pdata) {
+		pdata = pixcir_parse_dt(dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	}
+
 	if (!pdata) {
 		dev_err(&client->dev, "platform data not defined\n");
 		return -EINVAL;
@@ -524,15 +581,36 @@ static int pixcir_i2c_ts_remove(struct i2c_client *client)
 
 static const struct i2c_device_id pixcir_i2c_ts_id[] = {
 	{ "pixcir_ts", 0 },
+	{ "pixcir_tangoc", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
 
+#ifdef CONFIG_OF
+static const struct pixcir_i2c_chip_data pixcir_ts_data = {
+	.max_fingers = 2,
+	/* no hw id support */
+};
+
+static const struct pixcir_i2c_chip_data pixcir_tangoc_data = {
+	.max_fingers = 5,
+	.has_hw_ids = true,
+};
+
+static const struct of_device_id pixcir_of_match[] = {
+	{ .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data },
+	{ .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pixcir_of_match);
+#endif
+
 static struct i2c_driver pixcir_i2c_ts_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
 		.name	= "pixcir_ts",
 		.pm	= &pixcir_dev_pm_ops,
+		.of_match_table = of_match_ptr(pixcir_of_match),
 	},
 	.probe		= pixcir_i2c_ts_probe,
 	.remove		= pixcir_i2c_ts_remove,
-- 
1.8.3.2


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

* [PATCH v2 8/8] ARM: dts: am43x-epos-evm: Correct Touch controller info
  2014-02-26 15:27 ` Roger Quadros
@ 2014-02-26 15:28   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros, Benoit Cousson,
	Tony Lindgren

Fixup Y resolution and add default pin state. Also update
the compatible id.

CC: Benoit Cousson <bcousson@baylibre.com>
CC: Tony Lindgren <tony@atomide.com>
CC: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 arch/arm/boot/dts/am43x-epos-evm.dts | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index fbf9c4c..6c8efcf 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -79,6 +79,13 @@
 				0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
 			>;
 		};
+
+		pixcir_ts_pins: pixcir_ts_pins {
+			pinctrl-single,pins = <
+				0x44 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_a1.gpio1_17 */
+			>;
+		};
+
 	};
 
 	matrix_keypad: matrix_keypad@0 {
@@ -157,7 +164,9 @@
 	};
 
 	pixcir_ts@5c {
-		compatible = "pixcir,pixcir_ts";
+		compatible = "pixcir,pixcir_tangoc";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pixcir_ts_pins>;
 		reg = <0x5c>;
 		interrupt-parent = <&gpio1>;
 		interrupts = <17 0>;
@@ -165,7 +174,7 @@
 		attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
 
 		x-size = <1024>;
-		y-size = <768>;
+		y-size = <600>;
 	};
 };
 
-- 
1.8.3.2


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

* [PATCH v2 8/8] ARM: dts: am43x-epos-evm: Correct Touch controller info
@ 2014-02-26 15:28   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-02-26 15:28 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree, Roger Quadros, Benoit Cousson,
	Tony Lindgren

Fixup Y resolution and add default pin state. Also update
the compatible id.

CC: Benoit Cousson <bcousson@baylibre.com>
CC: Tony Lindgren <tony@atomide.com>
CC: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 arch/arm/boot/dts/am43x-epos-evm.dts | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index fbf9c4c..6c8efcf 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -79,6 +79,13 @@
 				0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
 			>;
 		};
+
+		pixcir_ts_pins: pixcir_ts_pins {
+			pinctrl-single,pins = <
+				0x44 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_a1.gpio1_17 */
+			>;
+		};
+
 	};
 
 	matrix_keypad: matrix_keypad@0 {
@@ -157,7 +164,9 @@
 	};
 
 	pixcir_ts@5c {
-		compatible = "pixcir,pixcir_ts";
+		compatible = "pixcir,pixcir_tangoc";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pixcir_ts_pins>;
 		reg = <0x5c>;
 		interrupt-parent = <&gpio1>;
 		interrupts = <17 0>;
@@ -165,7 +174,7 @@
 		attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
 
 		x-size = <1024>;
-		y-size = <768>;
+		y-size = <600>;
 	};
 };
 
-- 
1.8.3.2

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

* Re: [PATCH v2 3/8] Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
  2014-02-26 15:28   ` Roger Quadros
@ 2014-02-26 15:41     ` Felipe Balbi
  -1 siblings, 0 replies; 31+ messages in thread
From: Felipe Balbi @ 2014-02-26 15:41 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dmitry.torokhov, rydberg, jcbian, balbi, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 271 bytes --]

On Wed, Feb 26, 2014 at 05:28:01PM +0200, Roger Quadros wrote:
> Get rid of the attb_read_val() platform hook. Instead,
> read the ATTB gpio directly from the driver.
> 
> Fail if valid ATTB gpio is not provided by patform data.

s/patform/platform/

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 3/8] Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
@ 2014-02-26 15:41     ` Felipe Balbi
  0 siblings, 0 replies; 31+ messages in thread
From: Felipe Balbi @ 2014-02-26 15:41 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dmitry.torokhov, rydberg, jcbian, balbi, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 271 bytes --]

On Wed, Feb 26, 2014 at 05:28:01PM +0200, Roger Quadros wrote:
> Get rid of the attb_read_val() platform hook. Instead,
> read the ATTB gpio directly from the driver.
> 
> Fail if valid ATTB gpio is not provided by patform data.

s/patform/platform/

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 0/8] Input: pixcir_i2c_ts: Add Type-B Multi-touch and DT support
  2014-02-26 15:27 ` Roger Quadros
@ 2014-03-04 11:24   ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-04 11:24 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree

Hi Dmitry,

Gentle reminder to comment on this series. Thanks.

cheers,
-roger

On 02/26/2014 05:27 PM, Roger Quadros wrote:
> Hi,
> 
> This series does the following
> 
> - use devres managed resource allocations
> - convert to Type-B multi touch protocol
> - support upto 5 fingers with hardware supplied tracking IDs
> - device tree support
> 
> Changelog:
> 
> v2:
> - Addressed review comments and re-arranged patch order
> 
> v1:
> - http://article.gmane.org/gmane.linux.kernel/1616417
> 
> cheers,
> -roger
> 
> ---
> Roger Quadros (8):
>   Input: pixcir_i2c_ts: Use devres managed resource allocations
>   Input: pixcir_i2c_ts: Initialize interrupt mode and power mode
>   Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
>   Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
>   Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided
>     tracking IDs
>   Input: pixcir_i2c_ts: Implement wakeup from suspend
>   Input: pixcir_i2c_ts: Add device tree support
>   ARM: dts: am43x-epos-evm: Correct Touch controller info
> 
>  .../bindings/input/touchscreen/pixcir_i2c_ts.txt   |  26 ++
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  arch/arm/boot/dts/am43x-epos-evm.dts               |  13 +-
>  drivers/input/touchscreen/pixcir_i2c_ts.c          | 510 ++++++++++++++++++---
>  include/linux/input/pixcir_ts.h                    |  56 ++-
>  5 files changed, 545 insertions(+), 61 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
> 


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

* Re: [PATCH v2 0/8] Input: pixcir_i2c_ts: Add Type-B Multi-touch and DT support
@ 2014-03-04 11:24   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-04 11:24 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: rydberg, jcbian, balbi, dmurphy, mugunthanvnm, linux-input,
	linux-kernel, devicetree

Hi Dmitry,

Gentle reminder to comment on this series. Thanks.

cheers,
-roger

On 02/26/2014 05:27 PM, Roger Quadros wrote:
> Hi,
> 
> This series does the following
> 
> - use devres managed resource allocations
> - convert to Type-B multi touch protocol
> - support upto 5 fingers with hardware supplied tracking IDs
> - device tree support
> 
> Changelog:
> 
> v2:
> - Addressed review comments and re-arranged patch order
> 
> v1:
> - http://article.gmane.org/gmane.linux.kernel/1616417
> 
> cheers,
> -roger
> 
> ---
> Roger Quadros (8):
>   Input: pixcir_i2c_ts: Use devres managed resource allocations
>   Input: pixcir_i2c_ts: Initialize interrupt mode and power mode
>   Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val()
>   Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
>   Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided
>     tracking IDs
>   Input: pixcir_i2c_ts: Implement wakeup from suspend
>   Input: pixcir_i2c_ts: Add device tree support
>   ARM: dts: am43x-epos-evm: Correct Touch controller info
> 
>  .../bindings/input/touchscreen/pixcir_i2c_ts.txt   |  26 ++
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  arch/arm/boot/dts/am43x-epos-evm.dts               |  13 +-
>  drivers/input/touchscreen/pixcir_i2c_ts.c          | 510 ++++++++++++++++++---
>  include/linux/input/pixcir_ts.h                    |  56 ++-
>  5 files changed, 545 insertions(+), 61 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt
> 


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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  2014-02-26 15:28   ` Roger Quadros
  (?)
@ 2014-03-08 15:11   ` Henrik Rydberg
  2014-03-10  8:57       ` Roger Quadros
  -1 siblings, 1 reply; 31+ messages in thread
From: Henrik Rydberg @ 2014-03-08 15:11 UTC (permalink / raw)
  To: Roger Quadros, dmitry.torokhov
  Cc: jcbian, balbi, dmurphy, mugunthanvnm, linux-input, linux-kernel,
	devicetree

Hi Roger,

the MT implementation seems mostly fine, just one curiosity:

>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>  {
>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
> +	struct pixcir_report_data report;
>  
>  	while (!tsdata->exiting) {
> -		pixcir_ts_poscheck(tsdata);
> -
> -		if (gpio_get_value(pdata->gpio_attb))
> +		/* parse packet */
> +		pixcir_ts_parse(tsdata, &report);
> +
> +		/* report it */
> +		pixcir_ts_report(tsdata, &report);
> +
> +		if (gpio_get_value(pdata->gpio_attb)) {
> +			if (report.num_touches) {
> +				/*
> +				 * Last report with no finger up?
> +				 * Do it now then.
> +				 */
> +				input_mt_sync_frame(tsdata->input);
> +				input_sync(tsdata->input);

Why is this special handling needed?

Thanks,
Henrik


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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  2014-03-08 15:11   ` Henrik Rydberg
@ 2014-03-10  8:57       ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-10  8:57 UTC (permalink / raw)
  To: Henrik Rydberg, dmitry.torokhov
  Cc: jcbian, balbi, dmurphy, mugunthanvnm, linux-input, linux-kernel,
	devicetree

Hi Henrik,

On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
> Hi Roger,
> 
> the MT implementation seems mostly fine, just one curiosity:
> 
>>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>>  {
>>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
>> +	struct pixcir_report_data report;
>>  
>>  	while (!tsdata->exiting) {
>> -		pixcir_ts_poscheck(tsdata);
>> -
>> -		if (gpio_get_value(pdata->gpio_attb))
>> +		/* parse packet */
>> +		pixcir_ts_parse(tsdata, &report);
>> +
>> +		/* report it */
>> +		pixcir_ts_report(tsdata, &report);
>> +
>> +		if (gpio_get_value(pdata->gpio_attb)) {
>> +			if (report.num_touches) {
>> +				/*
>> +				 * Last report with no finger up?
>> +				 * Do it now then.
>> +				 */
>> +				input_mt_sync_frame(tsdata->input);
>> +				input_sync(tsdata->input);
> 
> Why is this special handling needed?

This is needed because the controller doesn't always report when all fingers
have left the screen. e.g. report might contain 3 fingers touched and then
gpio_attb line is de-asserted. There's no report with 0 fingers touched even
if the user's fingers have left the screen. So we never detect a BUTTON_UP.

Without this s/w workaround we observe side effects like buttons being pressed
but not released. To me it looks like a bug in the controller.

cheers,
-roger

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
@ 2014-03-10  8:57       ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-10  8:57 UTC (permalink / raw)
  To: Henrik Rydberg, dmitry.torokhov
  Cc: jcbian, balbi, dmurphy, mugunthanvnm, linux-input, linux-kernel,
	devicetree

Hi Henrik,

On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
> Hi Roger,
> 
> the MT implementation seems mostly fine, just one curiosity:
> 
>>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>>  {
>>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
>> +	struct pixcir_report_data report;
>>  
>>  	while (!tsdata->exiting) {
>> -		pixcir_ts_poscheck(tsdata);
>> -
>> -		if (gpio_get_value(pdata->gpio_attb))
>> +		/* parse packet */
>> +		pixcir_ts_parse(tsdata, &report);
>> +
>> +		/* report it */
>> +		pixcir_ts_report(tsdata, &report);
>> +
>> +		if (gpio_get_value(pdata->gpio_attb)) {
>> +			if (report.num_touches) {
>> +				/*
>> +				 * Last report with no finger up?
>> +				 * Do it now then.
>> +				 */
>> +				input_mt_sync_frame(tsdata->input);
>> +				input_sync(tsdata->input);
> 
> Why is this special handling needed?

This is needed because the controller doesn't always report when all fingers
have left the screen. e.g. report might contain 3 fingers touched and then
gpio_attb line is de-asserted. There's no report with 0 fingers touched even
if the user's fingers have left the screen. So we never detect a BUTTON_UP.

Without this s/w workaround we observe side effects like buttons being pressed
but not released. To me it looks like a bug in the controller.

cheers,
-roger

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  2014-03-10  8:57       ` Roger Quadros
@ 2014-03-10 16:37         ` Felipe Balbi
  -1 siblings, 0 replies; 31+ messages in thread
From: Felipe Balbi @ 2014-03-10 16:37 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Henrik Rydberg, dmitry.torokhov, jcbian, balbi, dmurphy,
	mugunthanvnm, linux-input, linux-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 1676 bytes --]

On Mon, Mar 10, 2014 at 10:57:10AM +0200, Roger Quadros wrote:
> Hi Henrik,
> 
> On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
> > Hi Roger,
> > 
> > the MT implementation seems mostly fine, just one curiosity:
> > 
> >>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
> >>  {
> >>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
> >>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
> >> +	struct pixcir_report_data report;
> >>  
> >>  	while (!tsdata->exiting) {
> >> -		pixcir_ts_poscheck(tsdata);
> >> -
> >> -		if (gpio_get_value(pdata->gpio_attb))
> >> +		/* parse packet */
> >> +		pixcir_ts_parse(tsdata, &report);
> >> +
> >> +		/* report it */
> >> +		pixcir_ts_report(tsdata, &report);
> >> +
> >> +		if (gpio_get_value(pdata->gpio_attb)) {
> >> +			if (report.num_touches) {
> >> +				/*
> >> +				 * Last report with no finger up?
> >> +				 * Do it now then.
> >> +				 */
> >> +				input_mt_sync_frame(tsdata->input);
> >> +				input_sync(tsdata->input);
> > 
> > Why is this special handling needed?
> 
> This is needed because the controller doesn't always report when all fingers
> have left the screen. e.g. report might contain 3 fingers touched and then
> gpio_attb line is de-asserted. There's no report with 0 fingers touched even
> if the user's fingers have left the screen. So we never detect a BUTTON_UP.
> 
> Without this s/w workaround we observe side effects like buttons being pressed
> but not released. To me it looks like a bug in the controller.

the other way would be to *also* use IRQF_TRIGGER_RISING, then you get
an IRQ when fingers leave the screen. No ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
@ 2014-03-10 16:37         ` Felipe Balbi
  0 siblings, 0 replies; 31+ messages in thread
From: Felipe Balbi @ 2014-03-10 16:37 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Henrik Rydberg, dmitry.torokhov, jcbian, balbi, dmurphy,
	mugunthanvnm, linux-input, linux-kernel, devicetree

[-- Attachment #1: Type: text/plain, Size: 1676 bytes --]

On Mon, Mar 10, 2014 at 10:57:10AM +0200, Roger Quadros wrote:
> Hi Henrik,
> 
> On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
> > Hi Roger,
> > 
> > the MT implementation seems mostly fine, just one curiosity:
> > 
> >>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
> >>  {
> >>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
> >>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
> >> +	struct pixcir_report_data report;
> >>  
> >>  	while (!tsdata->exiting) {
> >> -		pixcir_ts_poscheck(tsdata);
> >> -
> >> -		if (gpio_get_value(pdata->gpio_attb))
> >> +		/* parse packet */
> >> +		pixcir_ts_parse(tsdata, &report);
> >> +
> >> +		/* report it */
> >> +		pixcir_ts_report(tsdata, &report);
> >> +
> >> +		if (gpio_get_value(pdata->gpio_attb)) {
> >> +			if (report.num_touches) {
> >> +				/*
> >> +				 * Last report with no finger up?
> >> +				 * Do it now then.
> >> +				 */
> >> +				input_mt_sync_frame(tsdata->input);
> >> +				input_sync(tsdata->input);
> > 
> > Why is this special handling needed?
> 
> This is needed because the controller doesn't always report when all fingers
> have left the screen. e.g. report might contain 3 fingers touched and then
> gpio_attb line is de-asserted. There's no report with 0 fingers touched even
> if the user's fingers have left the screen. So we never detect a BUTTON_UP.
> 
> Without this s/w workaround we observe side effects like buttons being pressed
> but not released. To me it looks like a bug in the controller.

the other way would be to *also* use IRQF_TRIGGER_RISING, then you get
an IRQ when fingers leave the screen. No ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  2014-03-10 16:37         ` Felipe Balbi
@ 2014-03-11  9:35           ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-11  9:35 UTC (permalink / raw)
  To: balbi
  Cc: Henrik Rydberg, dmitry.torokhov, jcbian, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree

On 03/10/2014 06:37 PM, Felipe Balbi wrote:
> On Mon, Mar 10, 2014 at 10:57:10AM +0200, Roger Quadros wrote:
>> Hi Henrik,
>>
>> On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
>>> Hi Roger,
>>>
>>> the MT implementation seems mostly fine, just one curiosity:
>>>
>>>>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>>>>  {
>>>>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>>>>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
>>>> +	struct pixcir_report_data report;
>>>>  
>>>>  	while (!tsdata->exiting) {
>>>> -		pixcir_ts_poscheck(tsdata);
>>>> -
>>>> -		if (gpio_get_value(pdata->gpio_attb))
>>>> +		/* parse packet */
>>>> +		pixcir_ts_parse(tsdata, &report);
>>>> +
>>>> +		/* report it */
>>>> +		pixcir_ts_report(tsdata, &report);
>>>> +
>>>> +		if (gpio_get_value(pdata->gpio_attb)) {
>>>> +			if (report.num_touches) {
>>>> +				/*
>>>> +				 * Last report with no finger up?
>>>> +				 * Do it now then.
>>>> +				 */
>>>> +				input_mt_sync_frame(tsdata->input);
>>>> +				input_sync(tsdata->input);
>>>
>>> Why is this special handling needed?
>>
>> This is needed because the controller doesn't always report when all fingers
>> have left the screen. e.g. report might contain 3 fingers touched and then
>> gpio_attb line is de-asserted. There's no report with 0 fingers touched even
>> if the user's fingers have left the screen. So we never detect a BUTTON_UP.
>>
>> Without this s/w workaround we observe side effects like buttons being pressed
>> but not released. To me it looks like a bug in the controller.
> 
> the other way would be to *also* use IRQF_TRIGGER_RISING, then you get
> an IRQ when fingers leave the screen. No ?
> 

Yes that is also possible but it involves an additional interrupt context switch.
Sometimes the controller does report 0 finger touches before de-asserting the ATTB line and so
this additional interrupt is not needed by the approach I used.

cheers,
-roger

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
@ 2014-03-11  9:35           ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-11  9:35 UTC (permalink / raw)
  To: balbi
  Cc: Henrik Rydberg, dmitry.torokhov, jcbian, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree

On 03/10/2014 06:37 PM, Felipe Balbi wrote:
> On Mon, Mar 10, 2014 at 10:57:10AM +0200, Roger Quadros wrote:
>> Hi Henrik,
>>
>> On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
>>> Hi Roger,
>>>
>>> the MT implementation seems mostly fine, just one curiosity:
>>>
>>>>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>>>>  {
>>>>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>>>>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
>>>> +	struct pixcir_report_data report;
>>>>  
>>>>  	while (!tsdata->exiting) {
>>>> -		pixcir_ts_poscheck(tsdata);
>>>> -
>>>> -		if (gpio_get_value(pdata->gpio_attb))
>>>> +		/* parse packet */
>>>> +		pixcir_ts_parse(tsdata, &report);
>>>> +
>>>> +		/* report it */
>>>> +		pixcir_ts_report(tsdata, &report);
>>>> +
>>>> +		if (gpio_get_value(pdata->gpio_attb)) {
>>>> +			if (report.num_touches) {
>>>> +				/*
>>>> +				 * Last report with no finger up?
>>>> +				 * Do it now then.
>>>> +				 */
>>>> +				input_mt_sync_frame(tsdata->input);
>>>> +				input_sync(tsdata->input);
>>>
>>> Why is this special handling needed?
>>
>> This is needed because the controller doesn't always report when all fingers
>> have left the screen. e.g. report might contain 3 fingers touched and then
>> gpio_attb line is de-asserted. There's no report with 0 fingers touched even
>> if the user's fingers have left the screen. So we never detect a BUTTON_UP.
>>
>> Without this s/w workaround we observe side effects like buttons being pressed
>> but not released. To me it looks like a bug in the controller.
> 
> the other way would be to *also* use IRQF_TRIGGER_RISING, then you get
> an IRQ when fingers leave the screen. No ?
> 

Yes that is also possible but it involves an additional interrupt context switch.
Sometimes the controller does report 0 finger touches before de-asserting the ATTB line and so
this additional interrupt is not needed by the approach I used.

cheers,
-roger

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
  2014-03-10 16:37         ` Felipe Balbi
@ 2014-03-19 11:27           ` Roger Quadros
  -1 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-19 11:27 UTC (permalink / raw)
  To: Henrik Rydberg
  Cc: balbi, dmitry.torokhov, jcbian, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree

Henrik,

On 03/10/2014 06:37 PM, Felipe Balbi wrote:
> On Mon, Mar 10, 2014 at 10:57:10AM +0200, Roger Quadros wrote:
>> Hi Henrik,
>>
>> On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
>>> Hi Roger,
>>>
>>> the MT implementation seems mostly fine, just one curiosity:
>>>
>>>>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>>>>  {
>>>>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>>>>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
>>>> +	struct pixcir_report_data report;
>>>>  
>>>>  	while (!tsdata->exiting) {
>>>> -		pixcir_ts_poscheck(tsdata);
>>>> -
>>>> -		if (gpio_get_value(pdata->gpio_attb))
>>>> +		/* parse packet */
>>>> +		pixcir_ts_parse(tsdata, &report);
>>>> +
>>>> +		/* report it */
>>>> +		pixcir_ts_report(tsdata, &report);
>>>> +
>>>> +		if (gpio_get_value(pdata->gpio_attb)) {
>>>> +			if (report.num_touches) {
>>>> +				/*
>>>> +				 * Last report with no finger up?
>>>> +				 * Do it now then.
>>>> +				 */
>>>> +				input_mt_sync_frame(tsdata->input);
>>>> +				input_sync(tsdata->input);
>>>
>>> Why is this special handling needed?
>>
>> This is needed because the controller doesn't always report when all fingers
>> have left the screen. e.g. report might contain 3 fingers touched and then
>> gpio_attb line is de-asserted. There's no report with 0 fingers touched even
>> if the user's fingers have left the screen. So we never detect a BUTTON_UP.
>>
>> Without this s/w workaround we observe side effects like buttons being pressed
>> but not released. To me it looks like a bug in the controller.
> 
> the other way would be to *also* use IRQF_TRIGGER_RISING, then you get
> an IRQ when fingers leave the screen. No ?
> 

If you are OK with my explanation and the patches, could you please Ack them? Thanks.

cheers,
-roger

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

* Re: [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol
@ 2014-03-19 11:27           ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2014-03-19 11:27 UTC (permalink / raw)
  To: Henrik Rydberg
  Cc: balbi, dmitry.torokhov, jcbian, dmurphy, mugunthanvnm,
	linux-input, linux-kernel, devicetree

Henrik,

On 03/10/2014 06:37 PM, Felipe Balbi wrote:
> On Mon, Mar 10, 2014 at 10:57:10AM +0200, Roger Quadros wrote:
>> Hi Henrik,
>>
>> On 03/08/2014 05:11 PM, Henrik Rydberg wrote:
>>> Hi Roger,
>>>
>>> the MT implementation seems mostly fine, just one curiosity:
>>>
>>>>  static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
>>>>  {
>>>>  	struct pixcir_i2c_ts_data *tsdata = dev_id;
>>>>  	const struct pixcir_ts_platform_data *pdata = tsdata->chip;
>>>> +	struct pixcir_report_data report;
>>>>  
>>>>  	while (!tsdata->exiting) {
>>>> -		pixcir_ts_poscheck(tsdata);
>>>> -
>>>> -		if (gpio_get_value(pdata->gpio_attb))
>>>> +		/* parse packet */
>>>> +		pixcir_ts_parse(tsdata, &report);
>>>> +
>>>> +		/* report it */
>>>> +		pixcir_ts_report(tsdata, &report);
>>>> +
>>>> +		if (gpio_get_value(pdata->gpio_attb)) {
>>>> +			if (report.num_touches) {
>>>> +				/*
>>>> +				 * Last report with no finger up?
>>>> +				 * Do it now then.
>>>> +				 */
>>>> +				input_mt_sync_frame(tsdata->input);
>>>> +				input_sync(tsdata->input);
>>>
>>> Why is this special handling needed?
>>
>> This is needed because the controller doesn't always report when all fingers
>> have left the screen. e.g. report might contain 3 fingers touched and then
>> gpio_attb line is de-asserted. There's no report with 0 fingers touched even
>> if the user's fingers have left the screen. So we never detect a BUTTON_UP.
>>
>> Without this s/w workaround we observe side effects like buttons being pressed
>> but not released. To me it looks like a bug in the controller.
> 
> the other way would be to *also* use IRQF_TRIGGER_RISING, then you get
> an IRQ when fingers leave the screen. No ?
> 

If you are OK with my explanation and the patches, could you please Ack them? Thanks.

cheers,
-roger

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

end of thread, other threads:[~2014-03-19 11:27 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-26 15:27 [PATCH v2 0/8] Input: pixcir_i2c_ts: Add Type-B Multi-touch and DT support Roger Quadros
2014-02-26 15:27 ` Roger Quadros
2014-02-26 15:27 ` [PATCH v2 1/8] Input: pixcir_i2c_ts: Use devres managed resource allocations Roger Quadros
2014-02-26 15:27   ` Roger Quadros
2014-02-26 15:28 ` [PATCH v2 2/8] Input: pixcir_i2c_ts: Initialize interrupt mode and power mode Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-02-26 15:28 ` [PATCH v2 3/8] Input: pixcir_i2c_ts: Get rid of pdata->attb_read_val() Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-02-26 15:41   ` Felipe Balbi
2014-02-26 15:41     ` Felipe Balbi
2014-02-26 15:28 ` [PATCH v2 4/8] Input: pixcir_i2c_ts: Use Type-B Multi-Touch protocol Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-03-08 15:11   ` Henrik Rydberg
2014-03-10  8:57     ` Roger Quadros
2014-03-10  8:57       ` Roger Quadros
2014-03-10 16:37       ` Felipe Balbi
2014-03-10 16:37         ` Felipe Balbi
2014-03-11  9:35         ` Roger Quadros
2014-03-11  9:35           ` Roger Quadros
2014-03-19 11:27         ` Roger Quadros
2014-03-19 11:27           ` Roger Quadros
2014-02-26 15:28 ` [PATCH v2 5/8] Input: pixcir_i2c_ts: support upto 5 fingers and hardware provided tracking IDs Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-02-26 15:28 ` [PATCH v2 6/8] Input: pixcir_i2c_ts: Implement wakeup from suspend Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-02-26 15:28 ` [PATCH v2 7/8] Input: pixcir_i2c_ts: Add device tree support Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-02-26 15:28 ` [PATCH v2 8/8] ARM: dts: am43x-epos-evm: Correct Touch controller info Roger Quadros
2014-02-26 15:28   ` Roger Quadros
2014-03-04 11:24 ` [PATCH v2 0/8] Input: pixcir_i2c_ts: Add Type-B Multi-touch and DT support Roger Quadros
2014-03-04 11:24   ` Roger Quadros

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