summaryrefslogtreecommitdiff
path: root/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-multi-touch-input-driver-for-event-devices.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-multi-touch-input-driver-for-event-devices.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-multi-touch-input-driver-for-event-devices.patch398
1 files changed, 398 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-multi-touch-input-driver-for-event-devices.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-multi-touch-input-driver-for-event-devices.patch
new file mode 100644
index 000000000..483862ae2
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-multi-touch-input-driver-for-event-devices.patch
@@ -0,0 +1,398 @@
+From 6317c631cb1fd32f34da98a945747781d5a8906d Mon Sep 17 00:00:00 2001
+From: Priya Vijayan <priya.vijayan@intel.com>
+Date: Tue, 4 May 2010 14:21:37 -0700
+Subject: [PATCH] Add mtdev driver and configs
+
+Add multi-touch driver and configs for event devices.
+This module is from He Min <min.he@intel.com>
+Code modifications and configs from Priya Vijayan <priya.vijayan@intel.com>
+
+Patch-mainline: 2.6.34
+
+Signed-off-by: Priya Vijayan <priya.vijayan@intel.com>
+---
+ drivers/input/Kconfig | 9 ++
+ drivers/input/Makefile | 1 +
+ drivers/input/input.c | 1 +
+ drivers/input/mtdev.c | 307 ++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/input.h | 1 +
+ 5 files changed, 319 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/mtdev.c
+
+diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
+index 07c2cd4..0264508 100644
+--- a/drivers/input/Kconfig
++++ b/drivers/input/Kconfig
+@@ -135,6 +135,15 @@ config INPUT_EVDEV
+ To compile this driver as a module, choose M here: the
+ module will be called evdev.
+
++config INPUT_MTDEV
++ tristate "Multitouch interface"
++ help
++ Say Y here if you want to enable Multi-touch input driver for event devices
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here:the
++ module will be called mtdev.
++
+ config INPUT_EVBUG
+ tristate "Event debugging"
+ help
+diff --git a/drivers/input/Makefile b/drivers/input/Makefile
+index 7ad212d..96a4d94 100644
+--- a/drivers/input/Makefile
++++ b/drivers/input/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
+ obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
+ obj-$(CONFIG_INPUT_EVDEV) += evdev.o
+ obj-$(CONFIG_INPUT_EVBUG) += evbug.o
++obj-$(CONFIG_INPUT_MTDEV) += mtdev.o
+
+ obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/
+ obj-$(CONFIG_INPUT_MOUSE) += mouse/
+diff --git a/drivers/input/input.c b/drivers/input/input.c
+index 86cb2d2..b589dec 100644
+--- a/drivers/input/input.c
++++ b/drivers/input/input.c
+@@ -47,6 +47,7 @@ static unsigned int input_abs_bypass_init_data[] __initdata = {
+ ABS_MT_BLOB_ID,
+ ABS_MT_TRACKING_ID,
+ ABS_MT_PRESSURE,
++ ABS_MT_CONTACT_COUNT,
+ 0
+ };
+ static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
+diff --git a/drivers/input/mtdev.c b/drivers/input/mtdev.c
+new file mode 100644
+index 0000000..8b01220
+--- /dev/null
++++ b/drivers/input/mtdev.c
+@@ -0,0 +1,312 @@
++#include <linux/module.h>
++#include <linux/input.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/hid.h>
++#include <linux/wait.h>
++#include <linux/kthread.h>
++
++#define MTDEV_MAX_POINTERS 5
++
++#ifndef ABS_MT_PRESSURE
++#define ABS_MT_PRESSURE 0x3a
++#endif
++#ifndef ABS_MT_CONTACT_COUNT
++#define ABS_MT_CONTACT_COUNT 0x3b
++#endif
++
++struct mtdev_input_dev
++{
++ struct input_dev* input_dev;
++ int id;
++ bool ready;
++ int x;
++ int y;
++ int z;
++ int touch;
++};
++
++struct mtdev_dev
++{
++ int count;
++ int last_count;
++ wait_queue_head_t wq;
++ struct input_handle handle;
++ struct mtdev_input_dev devs[MTDEV_MAX_POINTERS];
++};
++
++//id==-1 means to find an empty slot
++static int find_match_id(struct mtdev_dev * mtdev,int id)
++{
++ int i=0;
++
++ for (i=0;i<MTDEV_MAX_POINTERS;i++)
++ {
++ if(mtdev->devs[i].id==id)
++ {
++ return i;
++ }
++ }
++ return -1;
++}
++
++
++static int mtdev_kt(void *data)
++{
++ struct mtdev_dev *mtdev=(struct mtdev_dev*)data;
++ int i=0;
++ int err=0;
++ printk("mtdev_kt entered\n");
++ if(!mtdev)
++ return -1;
++ //wait_event_interruptible(mtdev->wq,kthread_should_stop());
++ for(;i<MTDEV_MAX_POINTERS;i++)
++ {
++ struct input_dev *pdev=NULL;
++ pdev=mtdev->devs[i].input_dev;
++
++ err=input_register_device(pdev);
++ if(err)
++ {
++ printk("error in register mtdev %d\n",err);
++ return err;
++ }
++ else
++ printk("successfully registered input %d\n",i);
++ mtdev->devs[i].ready=true;
++
++ }
++ return 0;
++}
++
++static void mtdev_event(struct input_handle * handle,
++ unsigned int type, unsigned int code, int value)
++{
++ static int i=0;
++ //int err=0;
++ int j=0;
++ struct mtdev_dev *mtdev=handle->private;
++ //printk("mtdev_event %x %x %x\n",type,code,value);
++ if(!mtdev->devs[1].ready||!mtdev->devs[0].ready)
++ return;
++ if(type==EV_ABS)
++ {
++ switch(code)
++ {
++ case ABS_MT_CONTACT_COUNT:
++ if(value!=0)
++ {
++ //we start from the first point
++ i=0;
++ //printk("mtdev:contact count is %d\n",value);
++ }
++ else if(value>MTDEV_MAX_POINTERS)
++ {
++ value=MTDEV_MAX_POINTERS;
++ }
++
++ //found last release fingers and send release event
++ for(j=0;j<MTDEV_MAX_POINTERS;j++)
++ {
++ if(mtdev->devs[j].touch==0
++ &&mtdev->devs[j].id!=-1)
++ {
++ input_report_key(mtdev->devs[j].input_dev,BTN_TOUCH,0);
++ input_sync(mtdev->devs[j].input_dev);
++ printk("%d id %d released\n",j,mtdev->devs[j].id);
++ mtdev->devs[j].id=-1;
++ }
++ mtdev->devs[j].touch=0;
++ }
++ mtdev->count=value;
++
++ mtdev->last_count=value;
++
++ break;
++ case ABS_MT_TRACKING_ID:
++ {
++ i=find_match_id(mtdev,value);
++ if(i==-1||i>=MTDEV_MAX_POINTERS)
++ {
++ i=find_match_id(mtdev,-1);
++ if(i==-1||i>=MTDEV_MAX_POINTERS)
++ {
++ printk("no empty slot for id %d\n",value);
++ break;
++ }
++ else
++ {
++ //newly pressed
++ mtdev->devs[i].touch=2;
++ mtdev->devs[i].id=value;
++ printk("found slot %d for id %d\n",i,value);
++ break;
++ }
++ }
++ //printk("found slot %d for id%d\n",i,value);
++ //keep the point
++ mtdev->devs[i].touch=1;
++
++ }
++ break;
++ case ABS_MT_POSITION_X:
++ if(i<MTDEV_MAX_POINTERS&&i!=-1)
++ mtdev->devs[i].x=value;
++ //printk("mt x :%d\n",value);
++ break;
++ case ABS_MT_POSITION_Y:
++ if(i<MTDEV_MAX_POINTERS&&i!=-1)
++ mtdev->devs[i].y=value;
++ //printk("mt y :%d\n",value);
++ break;
++ case ABS_MT_PRESSURE:
++ if(i<MTDEV_MAX_POINTERS&&i!=-1)
++ mtdev->devs[i].z=value;
++ break;
++ default:
++ break;
++ }
++ }
++ else if(type == EV_SYN && code == SYN_MT_REPORT)
++ {
++ if(i<MTDEV_MAX_POINTERS&&i!=-1)
++ {
++ if(mtdev->devs[i].touch==2)
++ {
++ input_report_key(mtdev->devs[i].input_dev,BTN_TOUCH,1);
++
++ }
++ input_report_abs(mtdev->devs[i].input_dev,ABS_X,mtdev->devs[i].x);
++ input_report_abs(mtdev->devs[i].input_dev,ABS_Y,mtdev->devs[i].y);
++ input_report_abs(mtdev->devs[i].input_dev,ABS_PRESSURE,mtdev->devs[i].z);
++ input_sync(mtdev->devs[i].input_dev);
++ //printk("mtdev_event %d id %d (%d,%d,%d)\n",i,mtdev->devs[i].id,mtdev->devs[i].x,mtdev->devs[i].y,mtdev->devs[i].z);
++ //i++;
++ }
++ }
++
++}
++/*
++ * grab all the input of mt device, create new single touch input devices
++ *
++ */
++static int mtdev_connect(struct input_handler *handler, struct input_dev *dev,
++ const struct input_device_id *id)
++{
++ struct mtdev_dev* mtdev;
++ struct task_struct * task=NULL;
++ int i=0;
++ int err=0;
++ printk("mtdev_connect\n");
++ mtdev=kzalloc(sizeof(struct mtdev_dev),GFP_KERNEL);
++ if(!mtdev)
++ return -ENOMEM;
++ mtdev->handle.dev=input_get_device(dev);
++ mtdev->handle.name="mtdev";
++ mtdev->handle.handler=handler;
++ mtdev->handle.private=mtdev;
++ mtdev->count=0;
++ mtdev->last_count=0;
++ init_waitqueue_head(&mtdev->wq);
++ for(;i<MTDEV_MAX_POINTERS;i++)
++ {
++ //we just store the data here, and will register it
++ //when the first event comes
++ struct input_dev *pdev=NULL;
++ mtdev->devs[i].ready=false;
++ mtdev->devs[i].id=-1;
++ mtdev->devs[i].touch=-1;
++ mtdev->devs[i].input_dev=input_allocate_device();
++ if(!mtdev->devs[i].input_dev)
++ return -ENOMEM;
++ pdev=mtdev->devs[i].input_dev;
++ memcpy(pdev->evbit,dev->evbit,sizeof(pdev->evbit));
++ memcpy(pdev->keybit,dev->keybit,sizeof(pdev->keybit));
++ memcpy(pdev->absbit,dev->absbit,sizeof(pdev->absbit));
++
++ memcpy(pdev->abs,dev->abs,sizeof(pdev->abs));
++ memcpy(pdev->absmax,dev->absmax,sizeof(pdev->absmax));
++ memcpy(pdev->absmin,dev->absmin,sizeof(pdev->absmin));
++
++ pdev->name="mtdev virtual input";
++ }
++
++ //create a thread to create the new input devices
++ //because there's a mutex,which may cause dead lock
++ task=kthread_run(mtdev_kt,mtdev,"mtdev thread");
++ if(!task)
++ printk("error !!!!\n");
++ else
++ printk("kthread created OK\n");
++
++
++ err=input_grab_device(&mtdev->handle);
++ if(err)
++ {
++ printk("error in grab device %d\n",err);
++ return err;
++ }
++ else
++ printk("successfully grab device \n");
++
++ wake_up_all(&mtdev->wq);
++ return 0;
++}
++
++static void mtdev_disconnect(struct input_handle *handle)
++{
++ printk("mtdev_disconnect\n");
++ input_release_device(handle);
++}
++
++static const struct input_device_id mtdev_ids[] = {
++ {
++ .flags=INPUT_DEVICE_ID_MATCH_VENDOR|INPUT_DEVICE_ID_MATCH_PRODUCT,
++ .vendor=0x1f87,
++ .product=0x0002,
++ },
++ {
++ .flags=INPUT_DEVICE_ID_MATCH_VENDOR|INPUT_DEVICE_ID_MATCH_PRODUCT,
++ .vendor=0x1f87,
++ .product=0x0001,
++ },
++ {
++ .flags=INPUT_DEVICE_ID_MATCH_VENDOR|INPUT_DEVICE_ID_MATCH_PRODUCT,
++ .vendor=0x0483,
++ .product=0x3261,
++ },
++ {
++ .flags=INPUT_DEVICE_ID_MATCH_VENDOR|INPUT_DEVICE_ID_MATCH_PRODUCT,
++ .vendor=0x2087,
++ .product=0x0a01,
++ },
++ {},
++};
++
++MODULE_DEVICE_TABLE(input,mtdev_ids);
++
++static struct input_handler mtdev_handler = {
++ .event = mtdev_event,
++ .connect = mtdev_connect,
++ .disconnect = mtdev_disconnect,
++ .name = "mtdev",
++ .id_table = mtdev_ids,
++};
++
++
++static int __init mtdev_init(void)
++{
++ return input_register_handler(&mtdev_handler);
++}
++
++static void __exit mtdev_exit(void)
++{
++ input_unregister_handler(&mtdev_handler);
++}
++
++module_init(mtdev_init);
++module_exit(mtdev_exit);
++
++MODULE_AUTHOR("He Min <min.he@intel.com>");
++MODULE_DESCRIPTION("Multi-touch input driver event devices");
++MODULE_LICENSE("GPL");
+diff --git a/include/linux/input.h b/include/linux/input.h
+index 663208a..55bf8bc 100644
+--- a/include/linux/input.h
++++ b/include/linux/input.h
+@@ -662,6 +662,7 @@ struct input_absinfo {
+ #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
+ #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
+ #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
++#define ABS_MT_CONTACT_COUNT 0x3b /* Contact count */
+
+ #define ABS_MAX 0x3f
+ #define ABS_CNT (ABS_MAX+1)
+--
+1.6.2.2
+