#include <linux/module.h> // For module specific items #include <linux/moduleparam.h> // For new moduleparam's #include <linux/types.h> // For standard types (like size_t) #include <linux/errno.h> // For the -ENODEV/... values #include <linux/kernel.h> // For dbmsg/panic/... #include <linux/fs.h> // For file operations #include <linux/ioport.h> // For io-port access #include <linux/platform_device.h> // For platform_driver framework #include <linux/init.h> // For __init/__exit/... #include <linux/uaccess.h> // For copy_to_user/put_user/... #include <linux/io.h> // For inb/outb/... #include <linux/gpio.h> // GPIO #include <linux/device.h> #include <linux/cdev.h> #include <linux/slab.h> //kamlloc #include <linux/string.h> #include <linux/mutex.h> #include <linux/kmod.h> #include <linux/mm.h> #include <asm/system.h> #include <linux/hrtimer.h> #include <linux/err.h> #include <linux/spinlock.h> #include <linux/jiffies.h> #include <linux/timer.h> #include <mach/mt_pwm.h> #include <mach/mt_typedefs.h> //#include <mach/mt_clock_manager.h> #include <mach/mt_reg_base.h> #include <mach/mt_boot.h> #include <mtk_kpd.h> /* custom file */ #include <mach/mt_gpio.h> #include <linux/kthread.h> #include <cust_alsps.h> #define CURSOR_SET_DATA 0x5810 #define CURSOR_GET_DATA 0x5811 //#include <mach/irqs.h> //#include <mach/eint.h> //#include <mach/mt_gpio.h> /**************gpio_config_start*********************/ //#include <linux/gpio.h> #define BUFFERSIZE 1024 struct estar_gesture_t { struct cdev cdev; struct class * estar_class; dev_t devno; int device_major; int flag_cam3d; //CAMERA_3D or CAMERA_2D unsigned char mem[BUFFERSIZE]; }; struct estar_gesture_t *estar_gesturep; /* 设备结构体指针*/ struct input_dev *pixart_input_dev = 0; static struct task_struct *thread = NULL; struct cursors { s32 x1,y1; s32 x2,y2; s32 x3,y3; s32 x4,y4; }; typedef struct cursors CURSOR; static CURSOR coord; CURSOR test[1000]={{1,2},{10,20},{10,20},{10,20}},*cursor_p; static int cursor_halt = 0;/*updata flag*/ //static int cursor_flag = 0;/*interrupt flag*/ #define DEBUG 1 #if DEBUG #define dbmsg(fmt, args ...) printk(KERN_NOTICE "gesture: %s[%d]: "fmt"\n", __FUNCTION__, __LINE__,##args) #else #define dbmsg(fmt, args ...) #endif //static int gesture_major = 252; // gesture_major = 0; static int gesture_major = 0; static int cursor_event_handler(void *unused); static void cursor_down(s32 x, s32 y) { /* Report relative coordinates via the event interface */ #if 1 input_report_abs(pixart_input_dev, ABS_MT_PRESSURE, 100); input_report_abs(pixart_input_dev, ABS_MT_TOUCH_MAJOR, 100); input_report_key(pixart_input_dev, BTN_TOUCH, 1); input_report_abs(pixart_input_dev, ABS_MT_POSITION_X, x); input_report_abs(pixart_input_dev, ABS_MT_POSITION_Y, y); input_mt_sync(pixart_input_dev); input_sync(pixart_input_dev); #else input_report_key(pixart_input_dev, BTN_LEFT, 1); input_report_rel(pixart_input_dev, REL_X, x); input_report_rel(pixart_input_dev, REL_Y, y); input_sync(pixart_input_dev); #endif } static void cursor_up(s32 x, s32 y, s32 id) { //input_report_key(pixart_input_dev, BTN_TOUCH, 0); //input_mt_sync(pixart_input_dev); } /*Coordination mapping*/ static void cursor_calibrate_driver(CURSOR *cursor_p) { if(cursor_p->x1 > 1080)cursor_p->x1 = 500; if(cursor_p->y1 > 1920)cursor_p->x1 = 900; } static int cursor_event_handler(void *unused) { int cnt = 1000; int x = 0,y = 0; struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };/*优先级*/ sched_setscheduler(current, SCHED_RR, ¶m); cursor_p = test; do { set_current_state(TASK_INTERRUPTIBLE); cursor_p = &test[cnt]; if(--cnt == 0)cnt =1000; cursor_calibrate_driver(cursor_p); //if (cursor_halt) { cursor_halt = 0; //wait_event_interruptible(waiter, cursor_flag != 0); //cursor_flag = 0; //set_current_state(TASK_RUNNING); dbmsg("x1 = %d,y1= %d",x,y); //dbmsg("x2 = %d,y2= %d",coord.x2,coord.y2); //dbmsg("x3 = %d,y3= %d",coord.x3,coord.y3); //dbmsg("x4 = %d,y4= %d",coord.x4,coord.y4); if(++x > 1080) x = 0; if(++y > 1920) y = 0; cursor_down(x,y); msleep(20); cursor_up(0,0,0); msleep(30); } } while(!kthread_should_stop()); return 0; } static long gesture_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret; // cmd = (unsigned int)file; //解决与2.3版本兼容问题 dbmsg("cmd=0x%x, arg=0x%x", cmd, (unsigned int)arg); switch ( cmd ) { case CURSOR_SET_DATA: ret = copy_from_user(&coord, (int *)arg, sizeof(coord)); cursor_halt = 1; dbmsg("ret=0x%x",ret); break; case CURSOR_GET_DATA: ret = copy_to_user((int *)arg, &coord, sizeof(coord)); //memset(&coord,0,sizeof(coord)); dbmsg("ret=0x%x",ret); break; default: { break; } } return 0; } int gesture_open (struct inode *inode, struct file *filp) { dbmsg("cam3d_open_flag: open"); return 0; } ssize_t gesture_read(struct file *filp, char __user *buff, size_t count, loff_t *ppos) { int ret = 0; struct estar_gesture_t *dev = filp->private_data; /*通过文件私有数据指针得到设备结构体,和前面的open对应*/ if ( count > BUFFERSIZE ) count = BUFFERSIZE; /*内核空间->用户空间*/ if ( copy_to_user(buff, (void *)(dev->mem), count) ) { ret = -EFAULT; } memset(dev->mem, 0, BUFFERSIZE); return count; } ssize_t gesture_write(struct file *filp, const char __user *buff, size_t count, loff_t *ppos) { int ret = 0; struct estar_gesture_t *dev = filp->private_data; /*通过文件私有数据指针得到设备结构体,和前面?膐pen对应*/ if (count > BUFFERSIZE) count = BUFFERSIZE; //dbmsg("write: copy_from_user: buf=%s", buff); if ( copy_from_user( dev->mem , buff, count)) { ret = -EFAULT; return ret; } return count; } static int gesture_release(struct inode *node, struct file *file) { return 0; } static struct file_operations gesture_remap_ops = { .owner = THIS_MODULE, .open = gesture_open, .release = gesture_release, .read = gesture_read, .write = gesture_write, .unlocked_ioctl = gesture_ioctl, //ioctl }; static void gesture_setup_cdev(struct cdev *dev, int minor, struct file_operations *fops) { int err; cdev_init(dev, fops); dev->owner = THIS_MODULE; dev->ops = fops; err = cdev_add (dev, estar_gesturep->devno, 1); if (err) dbmsg (KERN_NOTICE "Error %d adding gesture %d", err, minor); } static int __init gesture_init(void) { int result,err; dbmsg("gesture init"); estar_gesturep = kmalloc(sizeof(struct estar_gesture_t), GFP_KERNEL); if(NULL == estar_gesturep) { dbmsg("NO Memory!"); return -1; } memset(estar_gesturep, 0, sizeof(struct estar_gesture_t)); estar_gesturep->devno = MKDEV(gesture_major, 0); result = alloc_chrdev_region(&estar_gesturep->devno, 0, 1, "gesture"); estar_gesturep->device_major= MAJOR(estar_gesturep->devno); if (result < 0) { dbmsg(KERN_WARNING "gesture: unable to get major %d\n", estar_gesturep->device_major); return result; } if (estar_gesturep->device_major== 0) estar_gesturep->device_major= result; gesture_setup_cdev(&estar_gesturep->cdev, 0, &gesture_remap_ops); estar_gesturep->estar_class= class_create(THIS_MODULE, "gesture"); device_create(estar_gesturep->estar_class, NULL, estar_gesturep->devno, NULL, "gesture"); /* allocate input device */ pixart_input_dev = input_allocate_device(); if (!pixart_input_dev) { dbmsg("Bad input_alloc_device()\n"); } /* Announce that the virtual mouse will generate relative coordinates */ #if 1 /*********** register input device **************/ set_bit(EV_ABS, pixart_input_dev->evbit); set_bit(EV_KEY, pixart_input_dev->evbit); set_bit(ABS_X, pixart_input_dev->absbit); set_bit(ABS_Y, pixart_input_dev->absbit); set_bit(ABS_PRESSURE, pixart_input_dev->absbit); set_bit(BTN_TOUCH, pixart_input_dev->keybit); set_bit(INPUT_PROP_DIRECT, pixart_input_dev->propbit); set_bit(ABS_DISTANCE, pixart_input_dev->absbit); set_bit(ABS_MT_TRACKING_ID, pixart_input_dev->absbit); set_bit(ABS_MT_TOUCH_MAJOR, pixart_input_dev->absbit); set_bit(ABS_MT_TOUCH_MINOR, pixart_input_dev->absbit); set_bit(ABS_MT_POSITION_X, pixart_input_dev->absbit); set_bit(ABS_MT_POSITION_Y, pixart_input_dev->absbit); input_set_abs_params(pixart_input_dev, ABS_DISTANCE, 0, 1, 0, 0); input_set_abs_params(pixart_input_dev, ABS_MT_POSITION_X, 0, 1080, 0, 0); input_set_abs_params(pixart_input_dev, ABS_MT_POSITION_Y, 0, 1920, 0, 0); input_set_abs_params(pixart_input_dev, ABS_MT_TOUCH_MAJOR, 0, 100, 0, 0); input_set_abs_params(pixart_input_dev, ABS_MT_TOUCH_MINOR, 0, 100, 0, 0); input_set_abs_params(pixart_input_dev, ABS_X, 0, 1080, 0, 0); input_set_abs_params(pixart_input_dev, ABS_Y, 0, 1920, 0, 0); input_abs_set_res(pixart_input_dev, ABS_X, 1080); input_abs_set_res(pixart_input_dev, ABS_Y, 1920); input_set_abs_params(pixart_input_dev, ABS_PRESSURE, 0, 255, 0, 0); #else //Announce that the virtual mouse will generate set_bit(BTN_LEFT, pixart_input_dev->keybit); set_bit(EV_REL, pixart_input_dev->evbit); set_bit(REL_X, pixart_input_dev->relbit); set_bit(REL_Y, pixart_input_dev->relbit); #endif /* Register with the input subsystem */ result = input_register_device(pixart_input_dev); if (result < 0) { dbmsg( "Virtual Mouse Driver Initialized fail\n"); return result; } dbmsg("Virtual Mouse Driver Initialized.\n"); //cursor_event_handler(); thread = kthread_run(cursor_event_handler, 0, "GESTURE"); if (IS_ERR(thread)) { err = PTR_ERR(thread); dbmsg("GESTURE" " failed to create kernel thread: %d", err); } return 0; } static void __exit gesture_cleanup(void) { /* Unregister from the input subsystem */ input_unregister_device(pixart_input_dev); device_destroy(estar_gesturep->estar_class,estar_gesturep->devno); class_destroy(estar_gesturep->estar_class); cdev_del(&estar_gesturep->cdev); unregister_chrdev_region(estar_gesturep->devno, 1); dbmsg("gesture device uninstalled\n"); } module_init(gesture_init); module_exit(gesture_cleanup); MODULE_AUTHOR("www.estar.cn"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION("1.0");
虚拟鼠标TP设备驱动
猜你喜欢
转载自blog.csdn.net/touxiong/article/details/34413059
今日推荐
周排行