Not sure which MultiTouch or MultiPoint protocol standard you are aligning 
with? How about its comparison with 
linux-2.6-mid-ref/Documentation/input/multi-touch-protocol.txt? How about your 
test result on latest MeeGo trunk at AAVA SC?

Regards
jw

-----Original Message-----
From: James [mailto:jketr...@linux.intel.com] 
Sent: Friday, August 20, 2010 7:29 AM
To: meego-dev@meego.com
Cc: Zhang, Lei A; Van De Ven, Arjan; Yang, Jianwei
Subject: [PATCH 4/4] cy8ctmg110: Add multi-touch capabilities

This patch optionally provides a mode of multitouch that works with
Qt 4.7's approach of taking input from multiple /dev/input/event
interfaces.  It does so by creating one input device for each supported
contact point (2 in this case)

If there is another way to create mulitiple event interfaces on
a single input device, please point me to them.

Once the new multi-touch protocol is supported up the entire vertical
stack, I expect this would shift to support that mechanism of exposing
multitouch data.

The above is enabled via CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
with the default set to 'Y' (to enable current Qt 4.7 based applications
to leverage this capability)

Signed-off-by: James Ketrenos <jketr...@linux.intel.com>
---
  drivers/input/touchscreen/Kconfig         |   13 +++++
  drivers/input/touchscreen/cy8ctmg110_ts.c |   76 
+++++++++++++++++++++++++++--
  2 files changed, 85 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 6f08b10..a103384 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -615,6 +615,19 @@ config TOUCHSCREEN_CY8CTMG110
        To compile this driver as a module, choose M here: the
        module will be called cy8ctmg110_ts.

+config TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    bool "cy8ctmg110 multiple interface support"
+    default y
+    depends on TOUCHSCREEN_CY8CTMG110
+    help
+      Say Y here if you want each contact point (up to 2) supported by
+      the cy8ctmg110 capacitive touchscreen to be exposed as a
+      seperate input device.
+
+      This enables MPX and some multi-touch applications to work.
+
+      If unsure, say Y.
+
  config TOUCHSCREEN_CLEARPAD_TM1217
      tristate "Synaptics Clearpad TM1217"
      depends on I2C
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c 
b/drivers/input/touchscreen/cy8ctmg110_ts.c
index e8c499a..9221d80 100644
--- a/drivers/input/touchscreen/cy8ctmg110_ts.c
+++ b/drivers/input/touchscreen/cy8ctmg110_ts.c
@@ -81,8 +81,13 @@ struct ts_event {
   * The touch driver structure.
   */
  struct cy8ctmg110 {
+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    struct input_dev *input[MAX_FINGERS];
+    char phys[MAX_FINGERS][32];
+#else
      struct input_dev *input;
      char phys[32];
+#endif
      struct ts_event tc;
      struct i2c_client *client;
      spinlock_t lock;
@@ -203,6 +208,30 @@ static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc)
      if (tsc->tc.fingers > MAX_FINGERS)
          tsc->tc.fingers = 0;

+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    /*
+     * Set/Clear BTN_TOUCH bit based on if there is an active contact
+     * point on that input device.
+     */
+    input_event(tsc->input[0], EV_KEY, BTN_TOUCH, tsc->tc.fingers > 0);
+    input_event(tsc->input[1], EV_KEY, BTN_TOUCH, tsc->tc.fingers > 1);
+
+    /*
+     * Track the '1st' finger; this might need to be improved as it
+     * could result in a borken experience when the user presses
+     * with contact 1, presses contact 2, then releases contact 1.
+     */
+    if (tsc->tc.fingers > 0) {
+        input_report_abs(tsc->input[0], ABS_X, tsc->tc.x1);
+        input_report_abs(tsc->input[0], ABS_Y, tsc->tc.y1);
+    }
+    input_sync(tsc->input[0]);
+    if (tsc->tc.fingers > 1) {
+        input_report_abs(tsc->input[1], ABS_X, tsc->tc.x2);
+        input_report_abs(tsc->input[1], ABS_Y, tsc->tc.y2);
+    }
+    input_sync(tsc->input[1]);
+#else
      /* Set/Clear BTN_TOUCH bit based on if any contact points */
      input_event(tsc->input, EV_KEY, BTN_TOUCH, tsc->tc.fingers);

@@ -216,7 +245,7 @@ static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc)
          input_report_abs(tsc->input, ABS_Y, tsc->tc.y1);
      }
      input_sync(tsc->input);
-
+#endif
      return 0;
  }

@@ -272,6 +301,9 @@ static int cy8ctmg110_probe(struct i2c_client *client,
  {
      struct cy8ctmg110 *ts;
      struct input_dev *input_dev;
+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    int contact;
+#endif
      int err;

      if (!i2c_check_functionality(client->adapter,
@@ -372,7 +404,29 @@ failed_irq:
      if (ts->polling)
          hrtimer_start(&ts->timer, ktime_set(10, 0), HRTIMER_MODE_REL);

-    err = input_register_device(input_dev);
+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    for (contact = 0; contact < MAX_FINGERS; contact++) {
+        err = input_register_device(ts->input[contact]);
+        if (err) {
+            /*
+             * For the input devices that have successfully
+             * registered before this failure, call
+             * input_unregister_device() and clear the input[]
+             * value so the err_free_mem code path doesn't call
+             * input_free_device on it
+             */
+            while (contact) {
+                input_unregister_device(ts->input[contact]);
+                ts->input[contact] = NULL;
+                contact--;
+            }
+            break;
+        }
+    }
+#else
+    err = input_register_device(ts->input);
+#endif
+
      if (!err)
          return 0;

@@ -383,7 +437,14 @@ failed_irq:
      gpio_free(CY8CTMG110_IRQ_PIN_GPIO);
      gpio_free(CY8CTMG110_RESET_PIN_GPIO);
  err_free_mem:
-    input_free_device(input_dev);
+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    for (contact = 0; contact < MAX_FINGERS; contact++) {
+        if (ts->input[contact])
+            input_free_device(ts->input[contact]);
+    }
+#else
+    input_free_device(ts->input);
+#endif
      kfree(ts);
      return err;
  }
@@ -437,13 +498,20 @@ static int cy8ctmg110_resume(struct i2c_client 
*client)
  static int cy8ctmg110_remove(struct i2c_client *client)
  {
      struct cy8ctmg110 *ts = i2c_get_clientdata(client);
-
+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    int contact;
+#endif
      cy8ctmg110_power(0);

      if (ts->polling)
          hrtimer_cancel(&ts->timer);
      free_irq(client->irq, ts);
+#ifdef CONFIG_TOUCHSCREEN_CY8CTMG110_MULTIPLE_INPUT
+    for (contact = 0; contact < MAX_FINGERS; contact++)
+        input_unregister_device(ts->input[contact]);
+#else
      input_unregister_device(ts->input);
+#endif
      gpio_free(CY8CTMG110_IRQ_PIN_GPIO);
      gpio_free(CY8CTMG110_RESET_PIN_GPIO);
      kfree(ts);
-- 
1.7.1

_______________________________________________
MeeGo-dev mailing list
MeeGo-dev@meego.com
http://lists.meego.com/listinfo/meego-dev

Reply via email to