diff options
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.patch | 398 |
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 + |