Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / xpt2046_cbn_ts.c
old mode 100644 (file)
new mode 100755 (executable)
index 8a6b9b8..99712d6
@@ -1,7 +1,7 @@
 /*
- * drivers/input/touchscreen/xpt2046_cbn_ts.c - driver for rk2818 spi xpt2046 calibration device and console
+ * drivers/input/touchscreen/xpt2046_ts.c - driver for rk29 spi xpt2046 device and console
  *
- * Copyright (C) 2010 ROCKCHIP, Inc.
+ * Copyright (C) 2011 ROCKCHIP, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <asm/irq.h>
-
+#include <mach/iomux.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
 #include "xpt2046_cbn_ts.h"
 #include "calibration_ts.h"
 /*
        #define xpt2046printk(msg...)
 #endif
 
-//#define TS_POLL_DELAY        (15 * 1000000)  /* ns delay before the first sample */
-//#define TS_POLL_PERIOD       (15 * 1000000)  /* ns delay between samples */
 #define TS_POLL_DELAY  (10 * 1000000)  /* ns delay before the first sample */
 #define TS_POLL_PERIOD (20 * 1000000)  /* ns delay between samples */
 
-
-#define DEBOUNCE_REPTIME  3
 /* this driver doesn't aim at the peak continuous sample rate */
 #define        SAMPLE_BITS     (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
 
@@ -87,32 +86,33 @@ struct xpt2046_packet {
 
 struct xpt2046 {
        struct input_dev        *input;
-       char                    phys[32];
-       char                    name[32];
-
+       char    phys[32];
+       char    name[32];
+       char    pendown_iomux_name[IOMUX_NAME_SIZE];    
        struct spi_device       *spi;
 
-       u16                     model;
-       bool                    swap_xy;
-       
+       u16             model;
+       u16             x_min, x_max;   
+       u16             y_min, y_max; 
+       u16             debounce_max;
+       u16             debounce_tol;
+       u16             debounce_rep;
+       u16             penirq_recheck_delay_usecs;
+       bool    swap_xy;
+
        struct xpt2046_packet   *packet;
 
        struct spi_transfer     xfer[18];
        struct spi_message      msg[5];
        struct spi_message      *last_msg;
-       int                     msg_idx;
-       int                     read_cnt;
-       int                     read_rep;
-       int                     last_read;
-
-       u16                     debounce_max;
-       u16                     debounce_tol;
-       u16                     debounce_rep;
-
-       u16                     penirq_recheck_delay_usecs;
-
+       int             msg_idx;
+       int             read_cnt;
+       int             read_rep;
+       int             last_read;
+       int             pendown_iomux_mode;     
+       int     touch_virtualkey_length;
        spinlock_t              lock;
-       struct hrtimer          timer;
+       struct hrtimer  timer;
        unsigned                pendown:1;      /* P: lock */
        unsigned                pending:1;      /* P: lock */
 // FIXME remove "irq_disabled"
@@ -121,12 +121,15 @@ struct xpt2046 {
        unsigned                is_suspended:1;
 
        int                     (*filter)(void *data, int data_idx, int *val);
-       void                    *filter_data;
-       void                    (*filter_cleanup)(void *data);
+       void            *filter_data;
+       void            (*filter_cleanup)(void *data);
        int                     (*get_pendown_state)(void);
        int                     gpio_pendown;
 
-       void                    (*wait_for_sync)(void);
+       void            (*wait_for_sync)(void);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       struct early_suspend early_suspend;
+#endif
 };
 
 /* leave chip selected when we're done, for quicker re-select? */
@@ -195,117 +198,24 @@ struct dfr_req {
        struct spi_message      msg;
        struct spi_transfer     xfer[4];
 };
-typedef struct
-{
-    s16 x;
-    s16 y;
-}POINT;
-
-#if (0)
-static struct xpt2046_platform_data xpt2046_info = {
-       .model                  = 2046,
-       .keep_vref_on   = 1,
-       .swap_xy                = 0,
-       .x_min                  = 0,
-       .x_max                  = 800,
-       .y_min                  = 0,
-       .y_max                  = 480,
-       .debounce_max           = 7,
-       .debounce_rep           = DEBOUNCE_REPTIME,
-       .debounce_tol           = 20,
-       .gpio_pendown           = RK2818_PIN_PE3,
-       .penirq_recheck_delay_usecs = 1,
 
-};
-#endif /* (0) */
+volatile struct adc_point gADPoint;
+
 static void xpt2046_enable(struct xpt2046 *ts);
 static void xpt2046_disable(struct xpt2046 *ts);
-
-static POINT gADPoint;
-int screen_x[] = { 50,  750,   50,  750,  400};
-int screen_y[] = { 40,   40,  440,  440,  240};
-int uncali_x[] = {329, 3750,  331, 3757, 2046};
-int uncali_y[] = {593,  532, 3675, 3655, 2121};
-
-// This code is touch check
-static ssize_t xpt2046_mode_show(struct device_driver *drv,char *buf)
+static int xpt2046_verifyAndConvert(struct xpt2046 *ts,int adx, int ady,int *x, int *y)
 {
-    int count;
-    
-       count = sprintf(buf,"xpt2046_mode_show:%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
-                       uncali_x[0], uncali_y[0],
-                       uncali_x[1], uncali_y[1],
-                       uncali_x[2], uncali_y[2],
-                       uncali_x[3], uncali_y[3],
-                       uncali_x[4], uncali_y[4]);
-
-       printk("buf: %s", buf);
+       xpt2046printk("%s:(%d/%d)\n",__FUNCTION__,*x, *y);
        
-       return count;
-}
+       if((*x< ts->x_min) || (*x > ts->x_max))
+               return 1;
 
-static ssize_t xpt2046_mode_store(struct device_driver * drv, const char * buf, size_t count)
-{
-    int i, j = 0;
-    char temp[5];
+       if((*y< ts->y_min) || (*y > ts->y_max + ts->touch_virtualkey_length))
+               return 1;
 
-    printk("xpt2046_mode_store: %s\n", buf);
-    
-    for (i = 0; i < 5; i++)
-    {
-        strncpy(temp, buf + 5 * (j++), 4);
-        uncali_x[i] = simple_strtol(temp, NULL, 10);
-        strncpy(temp, buf + 5 * (j++), 4);
-        uncali_y[i] = simple_strtol(temp, NULL, 10);
-        printk("SN=%d uncali_x=%d uncali_y=%d\n", 
-                i, uncali_x[i], uncali_y[i]);
-    }
 
-       return count; 
-}
-
-//This code is Touch adc simple value
-static ssize_t xpt2046_adc_show(struct device_driver *drv,char *buf)
-{
-    printk("xpt2046_adc_show: x=%d y=%d\n", gADPoint.x, gADPoint.y);
-    
-       return sprintf(buf, "%d,%d\n", gADPoint.x, gADPoint.y);
-}
-
-static ssize_t xpt2046_cali_status(struct device_driver *drv, char *buf)
-{
-    int ret;
-    
-    ret = TouchPanelSetCalibration(4, screen_x, screen_y, uncali_x, uncali_y);
-    if (ret == 1)
-        ret = sprintf(buf, "successful\n");
-    else
-        ret = sprintf(buf, "fail\n");
-    
-    printk("xpt2046_cali_status: buf=<%s", buf);
-    
-       return ret;
+       return 0;
 }
-
-//static DEVICE_ATTR(adc, 0666, xpt2046_adc_show, NULL);
-//static DEVICE_ATTR(calistatus, 0666, xpt2046_cali_status, NULL);
-//static DEVICE_ATTR(mode, 0666, xpt2046_mode_show, xpt2046_mode_store);
-static DRIVER_ATTR(touchadc, 0666, xpt2046_adc_show, NULL);
-static DRIVER_ATTR(calistatus, 0666, xpt2046_cali_status, NULL);
-static DRIVER_ATTR(touchcheck, 0666, xpt2046_mode_show, xpt2046_mode_store);
-#if (0)
-static struct attribute *xpt2046_attributes[] = {
-       &dev_attr_touchadc.attr,
-       &dev_attr_calistatus.attr,
-       &dev_attr_touchcheck.attr,
-       NULL,
-};
-
-static struct attribute_group xpt2046_attr_group = {
-       .attrs = xpt2046_attributes,
-};
-#endif /* (0) */
-
 static int device_suspended(struct device *dev)
 {
        struct xpt2046 *ts = dev_get_drvdata(dev);
@@ -387,14 +297,13 @@ static void null_wait_for_sync(void)
  * The SPI transfer completion callback does the real work.  It reports
  * touchscreen events and reactivates the timer (or IRQ) as appropriate.
  */
-
 static void xpt2046_rx(void *xpt)
 {
        struct xpt2046          *ts = xpt;
        struct xpt2046_packet   *packet = ts->packet;
        unsigned                Rt = 1;
        u16                     x, y;
-       int             xd,yd;
+       int             cal_x,cal_y;
        /* xpt2046_rx_val() did in-place conversion (including byteswap) from
         * on-the-wire format as part of debouncing to get stable readings.
         */
@@ -442,30 +351,36 @@ static void xpt2046_rx(void *xpt)
         */
        if (Rt) {
                struct input_dev *input = ts->input;
-               if (!ts->pendown) {
-                       input_report_key(input, BTN_TOUCH, 1);
-                       ts->pendown = 1;
-                       xpt2046printk("***>%s:input_report_key(pen down)\n",__FUNCTION__);
-               }
                
-               TouchPanelCalibrateAPoint(x, y, &xd, &yd);
+               TouchPanelCalibrateAPoint(x, y, &cal_x, &cal_y);
     
-       xd = xd / 4;
-       yd = yd / 4;
+       cal_x = cal_x / 4;
+       cal_y = cal_y / 4;
                gADPoint.x = x;
         gADPoint.y = y;
                
                if (ts->swap_xy)
-                       swap(x, y);     
+                       swap(cal_x, cal_y);     
                
+               if(xpt2046_verifyAndConvert(ts,cal_x,cal_y,&cal_x,&cal_y))
+               {
+                       xpt2046printk("***>%s:xpt2046_verifyAndConvert fail\n",__FUNCTION__);
+                       goto out;
+               }
                
-               input_report_abs(input, ABS_X, xd);
-               input_report_abs(input, ABS_Y, yd);
+               if (!ts->pendown) {
+                       input_report_key(input, BTN_TOUCH, 1);
+                       ts->pendown = 1;
+                       xpt2046printk("***>%s:input_report_key(pen down)\n",__FUNCTION__);
+               }       
+               
+               input_report_abs(input, ABS_X, cal_x);
+               input_report_abs(input, ABS_Y, cal_y);
 
                input_sync(input);
-               xpt2046printk("***>%s:input_report_abs(%4d/%4d)\n",__FUNCTION__,xd, yd);
+               xpt2046printk("***>%s:input_report_abs(%4d/%4d)\n",__FUNCTION__,cal_x, cal_y);
        }
-
+out:
        hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
                        HRTIMER_MODE_REL);
 }
@@ -482,6 +397,14 @@ static int xpt2046_debounce(void *xpt, int data_idx, int *val)
                abs(ts->last_read - *val),ts->debounce_tol,
                ts->read_rep,ts->debounce_rep);
        
+       /* discard the first sample. */
+        //on info_it50, the top-left area(1cmx1cm top-left square ) is not responding cause the first sample is invalid, @sep 17th
+       if(!ts->read_cnt)
+       {
+               //udelay(100);
+               ts->read_cnt++;
+               return XPT2046_FILTER_REPEAT;
+       }
        if(*val == 4095 || *val == 0)
        {
                ts->read_cnt = 0;
@@ -490,13 +413,7 @@ static int xpt2046_debounce(void *xpt, int data_idx, int *val)
                xpt2046printk("***>%s:*val == 4095 || *val == 0\n",__FUNCTION__);
                return XPT2046_FILTER_IGNORE;
        }
-       /* discard the first sample. */
-       if(!ts->read_cnt)
-       {
-               //udelay(100);
-               ts->read_cnt++;
-               return XPT2046_FILTER_REPEAT;
-       }
+
 
        if (ts->read_cnt==1 || (abs(ts->last_read - *val) > ts->debounce_tol)) {
                /* Start over collecting consistent readings. */
@@ -598,7 +515,7 @@ static enum hrtimer_restart xpt2046_timer(struct hrtimer *handle)
        int             status = 0;
        
        spin_lock(&ts->lock);
-       
+
        if (unlikely(!get_pendown_state(ts) ||
                     device_suspended(&ts->spi->dev))) {
                if (ts->pendown) {
@@ -701,10 +618,8 @@ static void xpt2046_enable(struct xpt2046 *ts)
        enable_irq(ts->spi->irq);
 }
 
-static int xpt2046_suspend(struct spi_device *spi, pm_message_t message)
+static int xpt2046_pSuspend(struct xpt2046 *ts)
 {
-       struct xpt2046 *ts = dev_get_drvdata(&spi->dev);
-
        spin_lock_irq(&ts->lock);
 
        ts->is_suspended = 1;
@@ -713,13 +628,10 @@ static int xpt2046_suspend(struct spi_device *spi, pm_message_t message)
        spin_unlock_irq(&ts->lock);
 
        return 0;
-
 }
 
-static int xpt2046_resume(struct spi_device *spi)
+static int xpt2046_pResume(struct xpt2046 *ts)
 {
-       struct xpt2046 *ts = dev_get_drvdata(&spi->dev);
-
        spin_lock_irq(&ts->lock);
 
        ts->is_suspended = 0;
@@ -730,6 +642,55 @@ static int xpt2046_resume(struct spi_device *spi)
        return 0;
 }
 
+#if !defined(CONFIG_HAS_EARLYSUSPEND)
+static int xpt2046_suspend(struct spi_device *spi, pm_message_t message)
+{
+       struct xpt2046 *ts = dev_get_drvdata(&spi->dev);
+       
+       printk("xpt2046_suspend\n");
+       
+       xpt2046_pSuspend(ts);
+       
+       return 0;
+}
+
+static int xpt2046_resume(struct spi_device *spi)
+{
+       struct xpt2046 *ts = dev_get_drvdata(&spi->dev);
+       
+       printk("xpt2046_resume\n");
+       
+       xpt2046_pResume(ts);
+
+       return 0;
+}
+
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+static void xpt2046_early_suspend(struct early_suspend *h)
+{
+       struct xpt2046  *ts;
+    ts = container_of(h, struct xpt2046, early_suspend);
+       
+       printk("xpt2046_suspend early\n");
+       
+       xpt2046_pSuspend(ts);
+       
+       return;
+}
+
+static void xpt2046_late_resume(struct early_suspend *h)
+{
+       struct xpt2046  *ts;
+    ts = container_of(h, struct xpt2046, early_suspend);
+       
+       printk("xpt2046_resume late\n");
+       
+       xpt2046_pResume(ts);
+
+       return;
+}
+#endif
+
 static int __devinit setup_pendown(struct spi_device *spi, struct xpt2046 *ts)
 {
        struct xpt2046_platform_data *pdata = spi->dev.platform_data;
@@ -749,19 +710,30 @@ static int __devinit setup_pendown(struct spi_device *spi, struct xpt2046 *ts)
                return 0;
        }
        
-       if (pdata->io_init) {
+    if (pdata->io_init) {
         err = pdata->io_init();
         if (err)
             dev_err(&spi->dev, "xpt2046 io_init fail\n");
     }
        
+       ts->gpio_pendown = pdata->gpio_pendown;
+       strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name);
+       ts->pendown_iomux_mode = pdata->pendown_iomux_mode;
+       
+    rk29_mux_api_set(ts->pendown_iomux_name,pdata->pendown_iomux_mode);
        err = gpio_request(pdata->gpio_pendown, "xpt2046_pendown");
        if (err) {
                dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
                                pdata->gpio_pendown);
                return err;
        }
-
+       
+       err = gpio_pull_updown(pdata->gpio_pendown, GPIOPullUp);
+       if (err) {
+               dev_err(&spi->dev, "failed to pullup pendown GPIO%d\n",
+                               pdata->gpio_pendown);
+               return err;
+       }
        ts->gpio_pendown = pdata->gpio_pendown;
        return 0;
 }
@@ -777,8 +749,6 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
        int                             vref;
        int                             err;
        
-
-       
        if (!spi->irq) {
                dev_dbg(&spi->dev, "no IRQ?\n");
                return -ENODEV;
@@ -787,12 +757,12 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
                spi->irq = gpio_to_irq(spi->irq);
                dev_dbg(&spi->dev, "no IRQ?\n");
        }
-       
-       if (!pdata) {
+           
+    if (!pdata) {
                dev_err(&spi->dev, "empty platform_data\n");
                return -EFAULT;
-       }
-
+    }
+    
        /* don't exceed max specified sample rate */
        if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
                dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
@@ -831,7 +801,7 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
        spin_lock_init(&ts->lock);
 
        ts->model = pdata->model ? : 2046;
-
+       
        if (pdata->filter != NULL) {
                if (pdata->filter_init != NULL) {
                        err = pdata->filter_init(pdata, &ts->filter_data);
@@ -860,9 +830,16 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
                                pdata->penirq_recheck_delay_usecs;
 
        ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
+       ts->x_min = pdata->x_min;
+       ts->x_max = pdata->x_max;
+       ts->y_min = pdata->y_min;
+       ts->y_max = pdata->y_max;
+       
 
+       ts->touch_virtualkey_length = pdata->touch_virtualkey_length;
+       
        snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
-       snprintf(ts->name, sizeof(ts->name), "XPT%d Touchscreen", ts->model);
+       snprintf(ts->name, sizeof(ts->name), "xpt%d-touchscreen", ts->model);
 
        input_dev->name = ts->name;
        input_dev->phys = ts->phys;
@@ -871,16 +848,17 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
        input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X,
-                       pdata->x_min ? : 0,
-                       pdata->x_max ? : MAX_12BIT,
+                       ts->x_min ? : 0,
+                       ts->x_max ? : MAX_12BIT,
                        0, 0);
        input_set_abs_params(input_dev, ABS_Y,
-                       pdata->y_min ? : 0,
-                       pdata->y_max ? : MAX_12BIT,
+                       ts->y_min ? : 0,
+                       ts->y_max ? : MAX_12BIT,
                        0, 0);
        
        vref = pdata->keep_vref_on;
 
+       tp_calib_iface_init(pdata->screen_x,pdata->screen_y,pdata->uncali_x_default,pdata->uncali_y_default);
        /* set up the transfers to read touchscreen state; this assumes we
         * use formula #2 for pressure, not #3.
         */
@@ -944,7 +922,7 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
 
        if (request_irq(spi->irq, xpt2046_irq, IRQF_TRIGGER_FALLING,
                        spi->dev.driver->name, ts)) {
-               printk("%s:trying pin change workaround on irq %d\n",__FUNCTION__,spi->irq);
+               xpt2046printk("%s:trying pin change workaround on irq %d\n",__FUNCTION__,spi->irq);
                err = request_irq(spi->irq, xpt2046_irq,
                                  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                                  spi->dev.driver->name, ts);
@@ -960,19 +938,21 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
         */
        xpt2046_read12_dfr(&spi->dev,READ_X(1));
 
-       //err = sysfs_create_group(&spi->dev.kobj, &xpt2046_attr_group);
-       if (err)
-               goto err_remove_hwmon;
-
        err = input_register_device(input_dev);
        if (err)
                goto err_remove_attr_group;
-  printk("xpt2046_ts: driver initialized\n");
+       
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       ts->early_suspend.suspend = xpt2046_early_suspend;
+       ts->early_suspend.resume = xpt2046_late_resume;
+       ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+       register_early_suspend(&ts->early_suspend);
+#endif
+
+    xpt2046printk("xpt2046_ts: driver initialized\n");
        return 0;
 
  err_remove_attr_group:
-       //sysfs_remove_group(&spi->dev.kobj, &xpt2046_attr_group);
- err_remove_hwmon:
        free_irq(spi->irq, ts);
  err_free_gpio:
        if (ts->gpio_pendown != -1)
@@ -987,15 +967,19 @@ static int __devinit xpt2046_probe(struct spi_device *spi)
        return err;
 }
 
+
 static int __devexit xpt2046_remove(struct spi_device *spi)
 {
        struct xpt2046          *ts = dev_get_drvdata(&spi->dev);
 
        input_unregister_device(ts->input);
-
+       
+#if !defined(CONFIG_HAS_EARLYSUSPEND)
        xpt2046_suspend(spi, PMSG_SUSPEND);
-
-       //sysfs_remove_group(&spi->dev.kobj, &xpt2046_attr_group);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+       xpt2046_early_suspend(&ts->early_suspend);
+       unregister_early_suspend(&ts->early_suspend);
+#endif
 
        free_irq(ts->spi->irq, ts);
        /* suspend left the IRQ disabled */
@@ -1009,7 +993,9 @@ static int __devexit xpt2046_remove(struct spi_device *spi)
 
        kfree(ts->packet);
        kfree(ts);
-
+       
+       tp_calib_iface_exit();
+       
        dev_dbg(&spi->dev, "unregistered touchscreen\n");
        return 0;
 }
@@ -1022,39 +1008,39 @@ static struct spi_driver xpt2046_driver = {
        },
        .probe          = xpt2046_probe,
        .remove         = __devexit_p(xpt2046_remove),
+#ifndef CONFIG_HAS_EARLYSUSPEND
        .suspend        = xpt2046_suspend,
        .resume         = xpt2046_resume,
+#endif
 };
 
 static int __init xpt2046_init(void)
 {
-       //return spi_register_driver(&xpt2046_driver);
-       int ret = spi_register_driver(&xpt2046_driver);
+       int ret;
+       gADPoint.x = 0;
+       gADPoint.y = 0;
 
-    if (ret == 0)
+       xpt2046printk("Touch panel drive XPT2046 driver init...\n");
+       ret = spi_register_driver(&xpt2046_driver);
+    if (ret)
     {
-           gADPoint.x = 0;
-           gADPoint.y = 0;
-           ret = driver_create_file(&xpt2046_driver.driver, &driver_attr_touchcheck);
-           ret += driver_create_file(&xpt2046_driver.driver, &driver_attr_touchadc);
-           ret += driver_create_file(&xpt2046_driver.driver, &driver_attr_calistatus);
+               printk("Register XPT2046 driver failed.\n");
+           return ret;
        }
-       
-       return ret;
+
+       return 0;
+
 }
-module_init(xpt2046_init);
+
 
 static void __exit xpt2046_exit(void)
 {
-       //spi_unregister_driver(&xpt2046_driver);
-       driver_remove_file(&xpt2046_driver.driver, &driver_attr_touchcheck);
-    driver_remove_file(&xpt2046_driver.driver, &driver_attr_touchadc);
-    driver_remove_file(&xpt2046_driver.driver, &driver_attr_calistatus);
-    
+       xpt2046printk("Touch panel drive XPT2046 driver exit...\n");
        spi_unregister_driver(&xpt2046_driver);
 }
+module_init(xpt2046_init);
 module_exit(xpt2046_exit);
 
-MODULE_DESCRIPTION("rk2818 spi xpt2046 TouchScreen Driver");
+MODULE_DESCRIPTION("rk29xx spi xpt2046 TouchScreen Driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("spi:xpt2046");