msg2033触摸屏驱动可模拟KEY_HOME KEY_BACK KEY_MENU

来源:互联网 发布:战舰世界苏驱数据 编辑:程序博客网 时间:2024/06/10 00:16
#include <mach/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <mach/clock.h>#include <linux/slab.h>#include "os.h"#include "tscr.h"#include "tsc.h"#include <linux/interrupt.h>#include <asm/gpio.h>#include <mach/clock.h>#include "i2c.h"#include <linux/timer.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/serio.h>#include <linux/delay.h>#include <linux/hwmon.h>#include <linux/timer.h>#include <linux/platform_device.h>#include <mach/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <linux/irq.h>#include <linux/interrupt.h>#include <asm/gpio.h>#include <mach/clock.h>#define u8 unsigned char#define u32 unsigned int#define s32 signed int//#define KEY_HOME 102//#define KEY_BACK 158//#define KEY_MENU 139#define TP_I2C_DEVICE_ID      0xc0#define REPORT_PACKET_LENGTH  8#define X_MAX 2047#define Y_MAX 2047#define AUO_INT_LOW         1  #define TOUCH_INT_PIN  GPIO_NUM(3,17)#define down0#define up1static int lx,ly,lx1,ly1;int ON_TOUCH_INT;int resx=0,resy=0;static int pendown = 0;static int penup=0;static uint32_t irq;/* struct of touch information to the middleware or applications */typedef struct{    u32 u32X;       /* X coordinate, 0~2047 */    u32 u32Y;       /* Y coordinate, 0~2047 */    u8  u8Finger;   /* Number of fingers in the touch event */    u32 u32Dis_X;   /* X distance between two fingers */    u32 u32Dis_Y;   /* Y distance between two fingers. This value could be negative */} TOUCH_DATA_st;/* Structure for Input Type*/struct auo_tp2_ts{struct input_dev * dev;int xpos;int ypos;char phys[32]; //for raw data or others  };static struct auo_tp2_ts *mic_ts;static struct work_struct work;static struct workqueue_struct *wq;static void microwell_tsc_work(struct work_struct *work);#if 1struct timer_list CY_timer;void Delay(int ms){   unsigned long j,stamp_1;    j=jiffies;    stamp_1=j+ ms*HZ/1000;    while(1)    {          j=jiffies;          if(j>=stamp_1)          return ;      }}//////////////////////////////////////////////////////////////////////// @brief  Calculate the 8-bit checksum of the given data array/// @author Chao-Cheng Wen/// @param[in] msg the pointer to the data/// @param[in] s32Length the length of the data in bytes////// Calculate the 8-bit checksum of the given data array. This is a/// simple algorithm to make the sum of data and checksum to be zero./// The porblem of zero-lossage exists in this algorithm./////////////////////////////////////////////////////////////////////u8 Calculate_8BitsChecksum( u8 *msg, s32 s32Length ){    s32 s32Checksum = 0;    s32 i;    for ( i = 0 ; i < s32Length; i++ )    {        s32Checksum += msg[i];    }//printk("_in Calculate_8BitsChecksum____________calc_checksum=0x%x\n___________",( -s32Checksum ) & 0xFF );    return (u8)( ( -s32Checksum ) & 0xFF );}int Msctpc_getData(struct input_dev *inputp, TOUCH_DATA_st *touchData);void timer_callback(){CY_timer.expires = jiffies + 1000;add_timer(&CY_timer);printk("i am in: timer_callback\n");}static int timer_start(void){init_timer(&CY_timer);CY_timer.expires = 1000;add_timer(&CY_timer);return 0;}static int timer_init(void){init_timer(&CY_timer);CY_timer.expires = 1000;CY_timer.function = timer_callback;add_timer(&CY_timer);return 0;}#endifvoid delay(){int i,j;for(i=0;i<1000;i++)for(j=0;j<1000;j++);}#define BH_TIMER// added by andely 2009-12-29#include <linux/spinlock.h>// added by andely 2010-03-08// CONFIG_SSLTSC_FOR_BATTERY defined in kernel configure file#ifdef CONFIG_SSLTSC_FOR_BATTERY#warning "ssltsc.ko only define for Battery detect!!!"#else #warning "ssltsc.ko define for Battery detect and TSC function!!!"#endif#define PRESSURE_SUPPORT 1#define TSC_RST_TIMEOUT 0x100#define TSC_MSR_VAL 0x80#define TSC_WUR_VAL 0x100#define TSC_MASK_VAL 0x00FF00FF#define SUPPLY      3347#define MMT_VBAT    (0x00 << 4)#define MMT_AUX     (0x03 << 4)#define MMT_AUX1    (0x04 << 4)#define TSC_EN      (0x01 << 0)#define TSC_RST     (0x01 << 1)#define TSC_GO      (0x01 << 2)#define  ISR_DR     (0x01 << 0)#define TSC_CAL_RESET"reset"#define TSC_CAL_SHOW"show"#define PT_BUF_LEN3#define TSC_X_MAX0x3FF#define TSC_Y_MAX0x3FFtsc_t buf[PT_BUF_LEN];int pt_out=0,pt_shift=0;static tsc_cal_t calibrate ={1,0,0,0,1,0,1};typedef struct{tsc_t hw;uint32_t xpos;uint32_t ypos;uint32_t xold;uint32_t yold;uint32_t xup;uint32_t yup;char phys[32];TOUCH_DATA_st *touchData;uint32_t irq;    spinlock_t spin_lock;struct input_dev *input_dev;/* n us delay between samples. */uint32_t poll_period;/* TSC bottom half. */#ifdef BH_TIMERstruct hrtimer timer;#elif defined BH_WQstruct workqueue_struct *wq;struct work_struct work;#endif    uint32_t pen_touch;//Last pen state: 1> pen down, 0>pen up.uint32_t count;/* debounce fliter */uint32_t read_cnt;uint32_t read_rep;uint32_t debounce_max;int32_t last_read_x, last_read_y;int32_t debounce_tol_x, debounce_tol_y;uint32_t debounce_tol_p;uint32_t debounce_rep;uint32_t filter_en;int (*filter) (void *data, int32_t * val_x, int32_t * val_y,   uint32_t * val_p);} ssltsc_ctx;#define ADC_TIMEOUT 1000   #define ADC_TIMES   100#define sample_period(10*1000000)uint32_t g_vbat_val;static ssltsc_ctx ts;static tsc_cfg_p cfg;/* TSC configuration. */int Msctpc_getData(struct input_dev *inputp, TOUCH_DATA_st *touchData){    u8 val[REPORT_PACKET_LENGTH] = {0};int i=0;int key=0;int errnum=0;   u8 Checksum = 0;    touchData->u32X = 0;    touchData->u32Y = 0;    touchData->u32Dis_X = 0;    touchData->u32Dis_Y = 0;    touchData->u8Finger = 0;penup=0;pendown=0;while(errnum<5){ lx=2048;ly=2048;    /* Read 8-bytes data from the TP controller. */    /* By default, the TP controller supports 120k SCL rate and duty cycle is 50% */   // Msctpc_ReadI2C( TP_I2C_DEVICE_ID, &val[0], REPORT_PACKET_LENGTH );    Msctpc_ReadI2C_Seq(TP_I2C_DEVICE_ID, &val[0], REPORT_PACKET_LENGTH );    Checksum = Calculate_8BitsChecksum( val, (REPORT_PACKET_LENGTH-1) );     if ( ( Checksum == val[7] && val[0] == 0x52 ) )   // Check the packet ID(0x52)and checksum    {printk("***********************\n");for(i=0;i<REPORT_PACKET_LENGTH ;i++){if(i%8==0)printk("\n");printk("*0x%x\t",val[i]);}printk("***********************\n");// key=0;if(val[5]==0x1)//menu{if(key==0){key=KEY_MENU;input_report_key (inputp, KEY_MENU, 1);printk("menu\n");input_sync(inputp);}continue;}else if(val[5]==0x2)//home{if(key==0){key=KEY_HOME;input_report_key (inputp, KEY_HOME, 1);printk("home\n");input_sync(inputp);}continue;}else if(val[5]==0x4)//back{if(key==0){key=KEY_BACK;input_report_key (inputp, KEY_BACK, 1);printk("back\n");input_sync(inputp);}continue;}        /* parsing the coordinate report packet */        /* MSG20XX EVK report format */        /*         *            +---------------------------------+         *   byte[0]  |       Packet ID ( 0x52 )        |         *            +----------------+----------------+         *   byte[1]  |   u32X[11:8]   |   u32Y[11:8]   |         *            +---------------------------------+         *   byte[2]  |            u32X[7:0]            |         *            +---------------------------------+         *   byte[3]  |            u32Y[7:0]            |         *            +----------------+----------------+         *   byte[4]  | u32Dis_X[11:8] | u32Dis_Y[11:8] |         *            +----------------+----------------+         *   byte[5]  |          u32Dis_X[7:0]          |         *            +---------------------------------+         *   byte[6]  |          u32Dis_Y[7:0]          |         *            +---------------------------------+         *   byte[7]  |            Checksum             |         *            +---------------------------------+         */      touchData->u32X = ( val[1] & 0xF0 ) << 4 | val[2];        touchData->u32Y = ( val[1] & 0x0F )<< 8 | val[3];        touchData->u32Dis_X = ( val[4] & 0xF0 ) << 4 | val[5];        touchData->u32Dis_Y = ( val[4] & 0x0F ) << 8 | val[6];     if ( touchData->u32X == 0xFFF && touchData->u32Y == 0xFFF && touchData->u32Dis_X == 0x000&& touchData->u32Dis_Y == 0xFF )        {        penup=1;input_report_abs(inputp, ABS_X,-100);input_report_abs(inputp, ABS_Y, 0);input_report_abs (inputp, ABS_PRESSURE, 1);input_report_key (inputp, BTN_TOUCH, 0);printk("one  report:x=%d,y=%d\, up\n",lx,ly);input_report_abs(inputp, ABS_PRESSURE, 0);printk("<<<<<<<<<<<pen up!!!!!!!!!,btn=0,pressure=0,sync\n");input_sync(inputp);printk(" >in Msctpc_getData >>>>>>>>>>Touch-End event\n"); return 0;           /* The coordinate report stands for a Touch-End event */            /* Inform the OS or system mailbox that the Touch-End event happened */        }        else        {//printk(" >>in Msctpc_getData >>>>>>>>>Touch-On-Panel event\n");lx=touchData->u32X;ly=touchData->u32Y;printk("read one : x=%d,y=%d\n",lx,ly);errnum=0;            /* The coordinate report stands for Touch-On-Panel event */            if ( touchData->u32Dis_X == 0 && touchData->u32Dis_Y == 0 )            {                /* If the distance values are zero, the TP detects one-finger-touch event *///printk(">>>>in Msctpc_getData >>>>>>>>>>>>one finger\n");                touchData->u8Finger = 1;if(X_MAX==1023){lx=1023-(lx>>1);ly=ly>>1;}else if(X_MAX==2047){lx=2047-lx;} if(pendown==0){input_report_key (inputp, BTN_TOUCH, 1);printk("<<<<<<<<<<<pen down!!!!!!!!!,btn_touch=1\n");}input_report_abs(inputp, ABS_X,(lx));input_report_abs(inputp, ABS_Y, ly);pendown=1;input_report_abs (inputp, ABS_PRESSURE, 1);input_sync(inputp);printk("<x,y,pressure=1,sync\n"); printk("after calibrate and report down: x=%d,y=%d\n",lx,ly);continue;//Msctpc_getData(inputp, touchData);            }            else if ( touchData->u32Dis_X <= 2047 && touchData->u32Dis_Y <= 2047 )            {                /* If the distance values are valid, the TP detects two-finger-touch event *///printk(">>>>in Msctpc_getData >>>>>>>two finger\n");                touchData->u8Finger = 2;/*lx1=touchData->u32X+touchData->u32Dis_X;ly1=touchData->u32Y+touchData->u32Dis_Y;input_report_abs(inputp, ABS_MT_POSITION_X,1023-(lx>>1));input_report_abs(inputp, ABS_MT_POSITION_Y, ly>>1);input_report_abs(inputp,ABS_MT_TOUCH_MAJOR, 1);printk("two mulit report1:x=%d,y=%d\,finger=1\n",1023-(lx>>1),ly>>1);input_mt_sync(inputp);input_report_abs(inputp, ABS_MT_POSITION_X,1023-(lx1>>1));input_report_abs(inputp, ABS_MT_POSITION_Y, ly1>>1);printk("two mulit report2:x=%d,y=%d\,finger=1\n",1023-(lx1>>1),ly1>>1);input_report_abs(inputp,ABS_MT_TOUCH_MAJOR, 1);input_mt_sync(inputp);input_sync(inputp);printk("two -r\n");continue;*///Msctpc_getData(inputp, touchData);            }            else            {                /* Fetal error */printk("in Msctpc_getData  :Fetal error,discard the data\n");return -1;                /* Discard the invalid coordinate reports due to fetal error. */            }        }    }    else    {    printk("in Msctpc_getData :Packet error happened. \n");errnum++;//        /* Packet error happened. */        /* Check I2C signal quality and I2C master codes */    }}if(pendown==1){input_report_key (inputp, BTN_TOUCH, 0);input_report_abs (inputp, ABS_PRESSURE, 0);input_sync(inputp);printk("<<<<<<<<<<<pen up!!!!!!!!!,btn_touch=0,pressure=0,sync\n");}if(key>0){input_report_key (inputp, key, 0);printk("%d release\n",key);input_sync(inputp);}//enable_irq(ts.irq);return -2;}static char *ssltsc_name = "SSL TouchScreen";static int pen_up_flg=0;static float ax = 4.3268f;static float bx = 29.3883f;static float ay = 3.86444f;static float by = 32.08083f;static int use_flag = 0;#if (defined CONFIG_ARCH_OPTIMUS_REPLOID || defined CONFIG_ARCH_OPTIMUS_REPLOID3)/* debounce fliter */#define X_LIMIT     0x3#define Y_LIMIT     0x3#define P_LIMIT     0x144//#define P_LIMIT     0xFFFF // Disable the Pressure filter.#define TSC_DEBUNCE_MAX10#define TSC_DEBUNCE_REP2#define TS_POLL_PERIOD  (10 * 1000)/* us delay between samples */#else/* debounce fliter */#define X_LIMIT     0xA#define Y_LIMIT     0xA#define P_LIMIT     0x1cc//#define P_LIMIT     0xFFFF // Disable the Pressure filter.#define TSC_DEBUNCE_MAX10#define TSC_DEBUNCE_REP2#define TS_POLL_PERIOD  (20 * 1000)/* us delay between samples */#endif//#define TS_POLL_PERIOD  (5 * 1000)/* us delay between samples */#define IRQ_TSC OPTIMUS_IRQ_TSC#define SSL_TSC_REG_ADDR OPTIMUS_IO_TSC#define TSC_GET_CLK_IN() optimus_get_pclk();//OPTIMUS_CLK_PER1#ifndef CONFIG_SSLTSC_FOR_BATTERYstatic int ssltsc_debounce (void *ads, int *val_x, int *val_y,uint32_t * val_p);static int ssltsc_no_filter (void *ads, int *val_x, int *val_y, uint32_t * val_p); static ssize_t ssltsc_parameter_show (struct device *dev,  struct device_attribute *attr, char *buf);static ssize_t ssltsc_parameter_store (struct device *dev,   struct device_attribute *attr,   const char *buf, size_t count);static DEVICE_ATTR (parameter, 0664, ssltsc_parameter_show,ssltsc_parameter_store);#endifstatic ssize_t ssltsc_vbat_show (struct device *dev,  struct device_attribute *attr, char *buf);static DEVICE_ATTR (vbat, 0664, ssltsc_vbat_show, NULL);static ssize_t ssltsc_calibrate_set (struct device *dev,  struct device_attribute *attr, char *buf);static DEVICE_ATTR (calibrate, 0664, NULL, ssltsc_calibrate_set);static struct attribute_group ssltsc_attr_group = {.attrs = ssltsc_attributes,};EXPORT_SYMBOL(ssltsc_vbat);static ssize_t ssltsc_vbat_show (struct device *dev,      struct device_attribute *attr, char *buf){uint32_t voltage = ssltsc_vbat();    return sprintf (buf, "%d\n", voltage);}void ssl_calibrate_for_Android(int32_t *x, int32_t *y){int32_t tx,ty;tx=*x;ty=*y;*x=(calibrate.a*tx + calibrate.b *ty +calibrate.c) / calibrate.div;*y=(calibrate.d*tx + calibrate.e *ty +calibrate.f) / calibrate.div;if ( *x < 0 ) *x = 0;if ( *y < 0 ) *y = 0;if ( *x > TSC_X_MAX ) *x = TSC_X_MAX;if ( *y > TSC_Y_MAX ) *y = TSC_Y_MAX;}static ssize_t ssltsc_calibrate_set (struct device *dev,  struct device_attribute *attr, char *buf){int32_t a,b,c,d,e,f,div;uint32_t x,y;db_tsc("get the argument: %s\n", buf);if (strncmp(buf,TSC_CAL_RESET,sizeof(TSC_CAL_RESET)-1)==0){db_tsc("will reset the calibration data\n");calibrate.a=1;calibrate.b=0;calibrate.c=0;calibrate.d=0;calibrate.e=1;calibrate.f=0;calibrate.div=1;goto _exit;}if (strncmp(buf,TSC_CAL_SHOW,sizeof(TSC_CAL_SHOW)-1)==0){x=100;y=200;ssl_calibrate_for_Android(&x, &y);printk("(100,200) -> (%d, %d)\n", x,y);x=900;y=200;ssl_calibrate_for_Android(&x, &y);printk("(900,200) -> (%d, %d)\n", x,y);x=100;y=800;ssl_calibrate_for_Android(&x, &y);printk("(100,800) -> (%d, %d)\n", x,y);x=900;y=800;ssl_calibrate_for_Android(&x, &y);printk("(900,800) -> (%d, %d)\n", x,y);goto _exit;}sscanf(buf,"%d %d %d %d %d %d %d",&a,&b,&c,&d,&e,&f,&div);if (0==div) {db_err("canot set the div to 0!\n");goto _exit;}calibrate.a=a;calibrate.b=b;calibrate.c=c;calibrate.d=d;calibrate.e=e;calibrate.f=f;calibrate.div=div;_exit:printk("calibration data:\n %d %d %d %d %d %d %d\n",calibrate.a, calibrate.b,\calibrate.c,calibrate.d, calibrate.e,calibrate.f,calibrate.div);return -1;}#ifndef CONFIG_SSLTSC_FOR_BATTERY   static ssize_t ssltsc_parameter_show (struct device *dev,  struct device_attribute *attr, char *buf){uint32_t clk, pclk;pclk = TSC_GET_CLK_IN ();db_tsc ("parameter show. pclk=%d Hz\n", pclk);clk = TSC_FROM_DIV (pclk, cfg->div);return sprintf (buf,"<SSL TSC parameter 1>\n<debounce>\n filter: %s,(x/y/p): %d/%d/%d/,repeat:%d,max:%d\n<sampling>\n clk:%d Hz,poll:%d us,power mode:0x%x\n",ts.filter_en ? "yes" : "no", ts.debounce_tol_x,ts.debounce_tol_y, ts.debounce_tol_p, ts.debounce_rep,ts.debounce_max, clk, ts.poll_period, cfg->pmd);}static int ssltsc_no_filter (void *ads, int *val_x, int *val_y, uint32_t * val_p){return TSC_FILTER_OK;}/* *This function have these feature: *1. while the first data is ready, that means pen down. *2. while data action, that means need to sync event handler. *3. while pen up, sync pen up event. And wait for pen down even.   * **/#ifdef BH_TIMERstatic enum hrtimer_restart ssltsc_timer (struct hrtimer *handle){ssltsc_ctx *ts_dev = container_of(handle, ssltsc_ctx, timer);//struct input_dev *dev;uint32_t delay;int touchstate;//high is releaseprintk("in ssltsc_timer\n");spin_lock_irq(ts_dev->spin_lock);printk("0s\n");ts_dev->touchData=kzalloc(sizeof(TOUCH_DATA_st), GFP_KERNEL);Msctpc_getData( ts_dev->input_dev,ts_dev->touchData );spin_unlock_irq(ts_dev->spin_lock);return HRTIMER_NORESTART;}#elif defined BH_WQstatic void ssltsc_worker (struct work_struct *work){uint32_t delay;    ssltsc_bottom_half ();/* Delay each even. If not, the interrupt come up frequently. At least it will delay 10 ms as 1 jiffes=10ms */delay = ts.poll_period / 1000000 * HZ;// us to jiffes. if (!delay)delay = 1;schedule_timeout_uninterruptible (delay);enable_irq (ts.irq);if (pen_up_flg) {queue_work (ts.wq, &ts.work);schedule_timeout_uninterruptible (delay);}}#endif#endifstatic tsc_err tsc_isr_cy (tsc_p t){//disable_irq(ON_TOUCH_INT);int i;int sumx=0,sumy=0;return TSC_ERR_NONE;}static irqreturn_t ssltsc_irq (int irq, void *dev_id){uint32_t ret, bf_en;debounce_ret deb_ret;uint32_t    irq_flags;    printk(">>>>>>>>>enter irq...........\n");spin_lock_irq(&ts.spin_lock);hrtimer_start (&ts.timer, ktime_set(0,sample_period),HRTIMER_MODE_REL);    spin_unlock_irq(&ts.spin_lock);return IRQ_HANDLED;}/** The functions for inserting/removing us as a module.*/static int __init ssltsc_probe (struct platform_device *dev){int err;struct input_dev *input_dev;/* Initialise tsc_t structure. */memset (&ts, 0, sizeof (tsc_t));printk("in ssltsc_probe,%d\n",gpio_get_value(TOUCH_INT_PIN));ts.hw.reg =(void __iomem *) ioremap_nocache (SSL_TSC_REG_ADDR, sizeof (tscr_t));if (ts.hw.reg == NULL){db_err ("Failed to remap register block \n");err = -ENOMEM;goto l_iomap;}/* Initial TSC module */err = (int) tsc_init (&ts.hw);if (err){db_err ("init tsc failed.\n");goto l_tsc_init;}pendown = 0;#ifndef CONFIG_SSLTSC_FOR_BATTERY#ifdef BH_TIMER#warning "timer bottom half."/*initial timer. */hrtimer_init (&ts.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);ts.timer.function = ssltsc_timer;db_tsc ("timer bottom half.\n");#elif defined BH_WQ#warning "work queue bottom half."/*initial work queue. */INIT_WORK (&ts.work, ssltsc_worker);ts.wq = create_singlethread_workqueue (dev->name);db_tsc ("work queue bottom half.\n");if (!ts.wq){db_err ("create wq fail.\n");err = -EBUSY;goto l_wq_err;}#elif defined BH_NONE#warning "NO bottom half."db_tsc ("no bottom half.\n");#else#error "****** NO define bottom half.********"#endif#endifplatform_set_drvdata(dev, &ts);#ifndef CONFIG_SSLTSC_FOR_BATTERY/*initial input system. */input_dev = input_allocate_device ();if (!input_dev){printk (KERN_ERR "Unable to allocate the input device !!\n");err = -ENOMEM;goto l_input_dev;}ts.input_dev = input_dev;ts.input_dev->evbit[0] =BIT_MASK (EV_SYN) | BIT_MASK (EV_KEY) | BIT_MASK (EV_ABS);ts.input_dev->keybit[BIT_WORD (BTN_TOUCH)] = BIT_MASK (BTN_TOUCH);ts.input_dev->keybit[BIT_WORD (KEY_HOME)] = BIT_MASK (KEY_HOME);ts.input_dev->keybit[BIT_WORD (KEY_BACK)] = BIT_MASK(KEY_BACK)|BIT_MASK(KEY_MENU);ts.input_dev->name = ssltsc_name;snprintf(ts.phys,sizeof(ts.phys),"%s/input0",dev_name(dev));ts.input_dev->phys = ts.phys;input_set_abs_params (ts.input_dev, ABS_X, 0, X_MAX, 0, 0);input_set_abs_params (ts.input_dev, ABS_Y, 0, Y_MAX, 0, 0);input_set_abs_params (ts.input_dev, ABS_PRESSURE, 0, 1, 0, 0);//input_set_abs_params(ts.input_dev, ABS_HAT0X, 0, X_MAX, 0, 0);//input_set_abs_params(ts.input_dev, ABS_HAT0Y, 0,Y_MAX, 0, 0);/* All went ok, so register to the input system */err = input_register_device (ts.input_dev);if (err){db_err ("register input system failed (%d).\n", err);goto l_reg_input;}/* Initial debounce paramter */ts.debounce_max = TSC_DEBUNCE_MAX;ts.debounce_tol_x = X_LIMIT;ts.debounce_tol_y = Y_LIMIT;ts.debounce_tol_p = P_LIMIT;ts.debounce_rep = TSC_DEBUNCE_REP;ts.filter_en = 1;ts.filter = ssltsc_debounce;ts.poll_period = TS_POLL_PERIOD;cfg = &ssltsc_default_cfg;#else/* Initial debounce paramter */ts.debounce_max = 10;ts.debounce_tol_x = X_LIMIT;ts.debounce_tol_y = Y_LIMIT;ts.debounce_tol_p = P_LIMIT;ts.debounce_rep = 4;//ts.debounce_rep = 2;ts.filter_en = 1;ts.filter = NULL;ts.poll_period = TS_POLL_PERIOD;cfg = &ssltsc_default_cfg;ts.input_dev = NULL;#endiferr = (int) tsc_cfg (&ts.hw, cfg);if (err){db_err ("cfg tsc failed.\n");goto l_tsc_cfg;}    spin_lock_init(&ts.spin_lock);ON_TOUCH_INT = gpio_to_irq(TOUCH_INT_PIN);if (AUO_INT_LOW)  {set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);}else {set_irq_type(irq, IRQ_TYPE_EDGE_RISING);}  if (request_irq(ON_TOUCH_INT, ssltsc_irq, IRQF_DISABLED|IRQF_TRIGGER_FALLING, "ssltsc", ts.input_dev)){printk("request_irq erro\n");return -1;}else{printk(">>>>>end request_irq\n");}/* Create sysfs attributes to monitor TSC. */err = sysfs_create_group (&dev->dev.kobj, &ssltsc_attr_group);if (err){db_err ("Can't create sysfs attributes!\n ");goto l_sysfs;}printk (KERN_INFO "%s successfully loaded \n", ssltsc_name);return 0;/*Error */  l_sysfs:free_irq (IRQ_TSC, ts.input_dev);  l_irq:  l_tsc_cfg:input_unregister_device (ts.input_dev);  l_reg_input://input_free_device (ts.input_dev);  l_input_dev:#ifdef BH_WQdestroy_workqueue (ts.wq);  l_wq_err:#endiftsc_exit (&ts.hw);  l_tsc_init:iounmap (ts.hw.reg);  l_iomap:db_err ("loaded fail.(%d)\n", err);return err;}static int ssltsc_remove (struct platform_device *dev){/* Remove sysfs attributes */sysfs_remove_group (&dev->dev.kobj, &ssltsc_attr_group);/* free irq. */free_irq (IRQ_TSC, ts.input_dev);/* free timer. */#ifdef BH_WQflush_workqueue (ts.wq);destroy_workqueue (ts.wq);#endif/* free module. */tsc_exit (&ts.hw);#ifndef CONFIG_SSLTSC_FOR_BATTERY/* free input system. */input_unregister_device (ts.input_dev);//input_free_device (ts.input_dev);#endif/* free memory. */iounmap (ts.hw.reg);return 0;}void ssltsc_device_release (struct device *dev){return;}static struct platform_device ssltsc_device = {.name = "ssltsc",.id = -1,.dev = {.release = ssltsc_device_release,}};static struct platform_driver ssltsc_driver = {.driver = {.name = "ssltsc",.owner = THIS_MODULE,},.probe = ssltsc_probe,.remove = ssltsc_remove,};int __init ssltsc_init (void){int ret;db_tsc ("insmod ssltsc.\n");#if 1//deviceret = platform_device_register (&ssltsc_device);if (ret)return ret;#endifreturn platform_driver_register (&ssltsc_driver);}void __exit ssltsc_exit (void){platform_driver_unregister (&ssltsc_driver);#if 1//deviceplatform_device_unregister (&ssltsc_device);#endifdb_tsc ("rmmod ssltsc.\n");}module_init (ssltsc_init);module_exit (ssltsc_exit);MODULE_AUTHOR ("Spiritwen@solomon-systech.com");MODULE_DESCRIPTION ("Optimus TSC Device Driver");MODULE_LICENSE ("GPL");

原创粉丝点击